Logo Search packages:      
Sourcecode: g2ipmsg version File versions  Download package

static int check_secure_directory ( const unsigned char *  dir  )  [static]

ディレクトリが安全であることを確認する

Parameters:
[in] dir 確認対象のディレクトリへのパス
Return values:
0 正常終了
-EINVAL 引数異常(fd_pまたはfileがNULLである).
-EPERM 以下のいずれかが発生した.
  • ディレクトリへの移動に失敗した
  • rootまたは自分自身以外に書き込めるディレクトリが 指定されたパス上に存在する.
  • rootが所有するディレクトリである,
  • root以外の他ユーザが所有するディレクトリが指定された パス上に存在する
  • シンボリックリンクが指定されたパス上に存在する
Attention:
内部リンケージ

Definition at line 299 of file pubcrypt.c.

References dir_check_mutex.

Referenced by pcrypt_load_rsa_key(), and pcrypt_store_rsa_key().

                                                 {
      DIR    *fd = NULL;
      DIR *start = NULL;
      int     rc = 0;
      uid_t  uid = 0;
      void  *ref = NULL;
      struct stat fbuff,lbuff;
      char new_dir[PATH_MAX + 1];

      g_static_mutex_lock(&dir_check_mutex); /* 厳密にいえば不要 */

      start = opendir(".");
      if (start == NULL) {
            rc = -errno;
            goto unlock_out;
      }
      
      rc = lstat(dir, &lbuff);
      if (rc < 0) {
            rc = -errno;
            goto close_dir_out;
      }

      uid = geteuid();

      do {
            rc = chdir(dir);
            if (rc != 0) {
                  rc = -errno;
                  goto ret_to_work_dir_out;
            }

            fd = opendir(".");
            if (fd == 0)
                  goto ret_to_work_dir_out;

            rc = fstat(dirfd(fd), &fbuff);
            closedir(fd);

            if (rc < 0) {
                  rc = -errno;
                  goto ret_to_work_dir_out;
            }

            /*
             * 偏執的ではあるが, リンクでないことを確認する
             */
            rc = -EPERM;
            if ( (lbuff.st_mode != fbuff.st_mode) ||
                (lbuff.st_ino != fbuff.st_ino) ||
                (lbuff.st_dev != fbuff.st_dev) )
                  goto ret_to_work_dir_out;


            /*
             * 本人以外に書き込めないことを確認する
             */
            if ( ((fbuff.st_mode) & RSA_DIR_INVALID_FLAGS))
                  goto ret_to_work_dir_out;


            /*
             * 他者が所有するディレクトリがある場合には, 書き込まない
             */
            if ( (fbuff.st_uid > 0) && (fbuff.st_uid != uid) ) 
                  goto ret_to_work_dir_out;

            /*
             *1つ上のディレクトリを探査する
             */
            dir="..";
            rc = lstat(dir, &lbuff);
            if (rc < 0) {
                  rc = -errno;
                  goto ret_to_work_dir_out;
            }

            memset(new_dir, 0, PATH_MAX + 1);
            ref = getcwd(new_dir, PATH_MAX + 1); /* 次に調査するディレクトリの
                                          *  親ディレクトリを獲得
                                          */
            if (ref == NULL)
                  goto ret_to_work_dir_out;

      } while (new_dir[1] != '\0');

      if (new_dir[1] == '\0')
            rc = 0;
      else
            rc = -EPERM;

ret_to_work_dir_out:
      fchdir(dirfd(start));

close_dir_out:
      closedir(start);

unlock_out:
      g_static_mutex_unlock(&dir_check_mutex); /* 厳密にいえば不要 */

      return rc;
}


Generated by  Doxygen 1.6.0   Back to index