5

最近、PureFTPサーバーのセットアップ作業を開始しました。職場ではPostgresql8.4を使用しています。スキーマは基本的に次のようになります。

username        text
password        character(40)
password_salt   text

はのpasswordハッシュとして保存されsha1( password + salt )ます。Postgresqlのpgcryptoを使用して、を提供しusernamepasswordユーザーが認証を持っているかどうかを確認できます。

SELECT
 encode( digest( $password ||password_salt, 'sha1' ), 'hex' ) = password
   AS password_correct
 , username
 , password
 , password_salt
FROM contact.person;

今私が抱えている問題は、そのような関数では、クエリにパスワードを取得する必要があるということです。これは、Pureftpの現在のauth-postgresqlの実装では不可能のようです。以下の提供のみをサポートします。

\L is replaced by the login of a user trying to authenticate.
\I is replaced by the IP address the client connected to.
\P is replaced by the port number the client connected to.
\R is replaced by the remote IP address the client connected from.
\D is replaced by the remote IPv4 address, as a long decimal number.

これを行う別の方法はありますか?クエリにパスワードを入力するか、ソルトとパスワードを取得して、Pureftpでコードを記述する別の方法を見つける必要があります。

明らかに、カスタム認証モジュールを作成する別のオプションがありますが、この基本的なソルティングはpgモジュールでサポートされると思います。

参考文献

4

1 に答える 1

2

私はまったく同じ問題を抱えていました。ただし、利用可能な pgsql auth は私が望むほとんどすべてのことを行うため、独自のカスタム認証モジュールを作成するのはやり過ぎでした..ここでは、私のニーズに合わせて変更を加えました。

log_pgsql_p.h に and を追加static char *salting;し、 withとstatic char *sqlreq_getsalt;を拡張します。static ConfigKeywords pgsql_config_keywords[]{ "PGSQLSalting", &salting },{ "PGSQLGetSalt", &sqlreq_getsalt },

log_pgsql.h に#define SALT_SQL_APPEND "append"#define SALT_SQL_PREPEND "prepend"およびを追加しまし#define SALT_SQL_NONE "none"た。

log_pgsql.c で、pw_psql_check関数に次の変更を加えました。

宣言const char *salt = NULL;char * salted_password = NULL;てトップに。spwdクエリの結果が割り当てられる直前sqlreq_getpwに追加しました

if (strcasecmp(salting, SALT_SQL_NONE) != 0) {
    salt = pw_pgsql_getquery(id_sql_server, sqlreq_getsalt,
                             escaped_account, escaped_ip,
                             escaped_port, escaped_peer_ip,
                             escaped_decimal_ip);
}

次に、暗号化が行われる前に:

if (salt != NULL) {
    int salted_pw_size = strlen(salt) + strlen(password) + 1;
    salted_password = (char *) malloc(salted_pw_size);
    if (strcasecmp(salting, SALT_SQL_APPEND) == 0) {
        strcpy(salted_password, password);
        strcat(salted_password, salt);            
    } else if (strcasecmp(salting, SALT_SQL_PREPEND) == 0) {
        strcpy(salted_password, salt);
        strcat(salted_password, password);
    }
} else {
    salted_password = (char *) malloc(strlen(password));
    strcpy(salted_password, password);
}

そしてpassword、crypt メソッド (crypt、crypto_hash_md5、crypto_hash_sha1) への後続の呼び出しの引数と、strcasecmp「クリアテキスト」の引数を(const char*)salted_password.

あとは、割り当てたメモリを整理するだけです。特に、追加/前置されたソルトを含むプレーンテキストパスワードはメモリに残すべきではありません-必要に応じてパラノイアと呼んでください。したがって、bye:ラベルを追加した後

free((void *) salt;
if(strcasecmp(salting, SALT_SQL_NONE) != 0) {
    volatile char *salted_password_ = (volatile char *) salted_password;
    while(*salted_password_ != 0) {
        *salted_password_++ = 0;
    }
    free((void *) salted_password);
}

これらの変更により、構成ファイルで 2 つの追加パラメーターを使用できるようになりました。

  • PGSQLSalting: 'append' (salt を pw に追加)、'prepend' および 'none' (アポストロフィなし) を受け入れます。
  • PGSQLGetSalt: ここでは、PGSQLGetPw を介して取得する必要がある暗号化されたパスワードと同様に、salt をフェッチするデータベース内のフィールドを指定します。

編集:ああ、関数の最後に割り当てられたメモリを解放することを忘れないでください!

リリース 1.0.36 で動作する差分ファイルも提供できます注意してください、私は後でsalted_pa​​sswordの解放の周りにifを追加しました(salted_pa​​sswordがパスワードを指している場合、これがエラーにつながる可能性があることに後で気付いたからです)ので、これは差分になく、差分を変更するのが面倒ですファイル :/

于 2012-10-17T19:37:26.513 に答える