/**
   * Split the password property into file password and user password if necessary, and convert them
   * to the internal hash format.
   */
  private void convertPasswords() {
    char[] password = removePassword();
    boolean passwordHash =
        removeProperty("PASSWORD_HASH", false); // 如果PASSWORD_HASH参数是true那么不再进行SHA256

    // 如果配置了CIPHER,则password包含两部份,用一个空格分开这两部份,第一部份是filePassword,第二部份是userPassword。
    // 如果PASSWORD_HASH参数是true那么不再进行SHA256,此时必须使用16进制字符,字符个数是偶数。
    // 如果PASSWORD_HASH参数是false,不必是16进制字符,会按SHA256算法进行hash
    if (getProperty("CIPHER", null) != null) {
      // split password into (filePassword+' '+userPassword)
      int space = -1;
      for (int i = 0, len = password.length; i < len; i++) {
        if (password[i] == ' ') {
          space = i;
          break;
        }
      }
      if (space < 0) {
        throw DbException.get(ErrorCode.WRONG_PASSWORD_FORMAT);
      }
      char[] np = new char[password.length - space - 1];
      char[] filePassword = new char[space];
      System.arraycopy(password, space + 1, np, 0, np.length);
      System.arraycopy(password, 0, filePassword, 0, space);
      Arrays.fill(password, (char) 0);
      password = np;
      // filePasswordHash用"file"进行hash
      fileEncryptionKey = FilePathEncrypt.getPasswordBytes(filePassword);
      filePasswordHash = hashPassword(passwordHash, "file", filePassword);
    }
    // userPasswordHash用用户名进行hash
    userPasswordHash = hashPassword(passwordHash, user, password);
  }
Exemple #2
0
 /**
  * Try to open the file.
  *
  * @param fileName the file name
  * @param readOnly whether the file should only be opened in read-only mode, even if the file is
  *     writable
  * @param encryptionKey the encryption key, or null if encryption is not used
  */
 public void open(String fileName, boolean readOnly, char[] encryptionKey) {
   if (file != null) {
     return;
   }
   if (fileName != null) {
     FilePath p = FilePath.get(fileName);
     // if no explicit scheme was specified, NIO is used
     if (p instanceof FilePathDisk && !fileName.startsWith(p.getScheme() + ":")) {
       // ensure the NIO file system is registered
       FilePathNio.class.getName();
       fileName = "nio:" + fileName;
     }
   }
   this.fileName = fileName;
   FilePath f = FilePath.get(fileName);
   FilePath parent = f.getParent();
   if (parent != null && !parent.exists()) {
     throw DataUtils.newIllegalArgumentException("Directory does not exist: {0}", parent);
   }
   if (f.exists() && !f.canWrite()) {
     readOnly = true;
   }
   this.readOnly = readOnly;
   try {
     file = f.open(readOnly ? "r" : "rw");
     if (encryptionKey != null) {
       byte[] key = FilePathEncrypt.getPasswordBytes(encryptionKey);
       encryptedFile = file;
       file = new FilePathEncrypt.FileEncrypt(fileName, key, file);
     }
     file = FilePathCache.wrap(file);
     try {
       if (readOnly) {
         fileLock = file.tryLock(0, Long.MAX_VALUE, true);
       } else {
         fileLock = file.tryLock();
       }
     } catch (OverlappingFileLockException e) {
       throw DataUtils.newIllegalStateException(
           DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName, e);
     }
     if (fileLock == null) {
       throw DataUtils.newIllegalStateException(
           DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName);
     }
     fileSize = file.size();
   } catch (IOException e) {
     throw DataUtils.newIllegalStateException(
         DataUtils.ERROR_READING_FAILED, "Could not open file {0}", fileName, e);
   }
 }