まあ、私たちのビジネスはトリッキーではありません。 では、何がありますか? パスワードが暗号化される方法を示すSQLAuthTypesパラメーターがあります。 必要なオプションがありません。つまり、ソースを開きます。 最後のRCビルドはProFTPDホームサイトからダウンロードされました。その時点でproftpd-1.3.3rc3です。 contrib / mod_sql.cとcontrib / mod_sql.hをざっと見てみると、認証メソッドを関数に追加するメカニズムがあることがわかりました。
int sql_register_authtype(const char *name, modret_t *(*callback)(cmd_rec *, const char *, const char *));
面白い。 ソースを少し走り回って、この関数を呼び出す十分な例を見つけました(奇妙なことですが、これは適切に文書化されていません。純粋な形式のパスワードとmysqlから取得したハッシュは、パスワードがハッシュと一致するかどうかを確認し、検証の結果を返します。 まあ、それはスナップのように聞こえます。 次の内容のmakeshiftモジュールcontrib / mod_sql_auth_smf.cを作成しました。
#include "conf.h"
#include "mod_sql.h"
#define MOD_SQL_AUTH_SMF_VERSION "mod_sql_smf/0.1"
#if defined(HAVE_OPENSSL) || defined(PR_USE_OPENSSL)
#include <openssl/evp.h>
static modret_t *auth_smf(cmd_rec *cmd, const char *c_clear, const char *c_hash) {
const EVP_MD *md;
EVP_MD_CTX md_ctxt;
unsigned char mdval[EVP_MAX_MD_SIZE];
char hash[EVP_MAX_MD_SIZE * 2];
int mdlen, i;
OpenSSL_add_all_digests();
md = EVP_get_digestbyname("sha1");
if (!md)
return ERROR_INT(cmd, PR_AUTH_BADPWD);
EVP_DigestInit(&md_ctxt, md);
EVP_DigestUpdate(&md_ctxt, c_clear, strlen(c_clear));
EVP_DigestFinal(&md_ctxt, mdval, &mdlen);
for (i=0; i<mdlen; i++) {
sprintf(hash+(i*2), "%02x", mdval[i]);
}
return strcmp(hash, c_hash) ? ERROR_INT(cmd, PR_AUTH_BADPWD) : HANDLED(cmd);
}
static int sql_auth_smf_init(void) {
(void) sql_register_authtype("SMF", auth_smf);
return 0;
}
#endif
module sql_auth_smf_module = {
/* Always NULL */
NULL, NULL,
/* Module API version */
0x20,
/* Module name */
"sql_auth_smf",
/* Module configuration directive table */
NULL,
/* Module command handler table */
NULL,
/* Module auth handler table */
NULL,
/* Module initialization */
sql_auth_smf_init,
/* Session initialization */
NULL,
/* Module Version */
MOD_SQL_AUTH_SMF_VERSION
};
このモジュールでは、OpenSSLを使用して、クリアパスワードのSHA1ハッシュを実装し、受信したハッシュと調整し、検証の結果をmod_sql.cに返しました。 --with-shared = mod_sql_auth_smfを構成するオプションを追加することを忘れずにコンパイルし、proftpd.conf SQLAuthTypesのパラメーターをSMFに変更し、行LoadModule mod_sql_mysql.cを追加しました。 集まって、チェックして、動作します! ただし、パスワードがPassWd22のユーザーUser1がパスワードとしてuser1PassWd22を示している場合のみ。 まあ、それは簡単です。 mod_sql.cで関数のコールバックを見つけたので、このタイプから変更しました。
mr = sah->cb(cmd, plaintext, ciphertext);
これについて:
if(strcmp(sah->name, "SMF")==0) {
int i;
char namepasswd[106];
strncpy(namepasswd, cmd->argv[1], 25);
for(i=0;namepasswd[i];i++) namepasswd[i]=tolower(namepasswd[i]);
strncat(namepasswd, cmd->argv[2], 80);
mr = sah->cb(cmd, namepasswd, ciphertext);
} else
mr = sah->cb(cmd, plaintext, ciphertext);
それだけです、目標は達成されました。 MySQLで作業するためのProFTPDのセットアップの詳細、コンパイルの微妙さに興味がある場合は、コメントで回答します。 この記事の目的は、完全なステップバイステップのガイドをゼロから提供することではなく、Cの知識が少しあれば、ProFTPDにフォーラムやブログなどの資格情報を使用してユーザーを承認させる方法を簡単に示すことです。