フォーラムアカウントのProFTPDでのユーザー認証

最近、FTPサーバー上のすべてのユーザーへのアクセスを禁止する、つまり匿名でのログインをブロックする必要がありました。 ただし、FTPユーザーと別個のデータベースを保持するのは不便であり、さらに非効率的です。 考え、考え、フォーラムアカウント(私の場合はSMF)でユーザーを承認することにしました。 ユーザーはMySQLテーブルsmf_membersに、ユーザー名はmemberNameに、パスワードはpasswdに保存されます。 ProFTPDには、PostgreSQL / MySQLで資格情報を取得するための十分に文書化された機能があります。 しかし問題は、フォーラムのパスワードがSHA1ハッシュに保存され、小文字のユーザー名がパスワードの先頭に追加されることです。 また、ProFTPDは、SQLクエリからデータベースへのMySQL PASSWORD()、Crypt、またはPlaintext形式のパスワードを返すことを想定しています。 もちろん、ユーザー名がまだパスワードに追加されていることは言うまでもなく、SHA1はありません。 毎日グーグルはこれについて文句を言っていますが、既成のソリューションを提供している人はいません。



まあ、私たちのビジネスはトリッキーではありません。 では、何がありますか? パスワードが暗号化される方法を示す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にフォーラムやブログなどの資格情報を使用してユーザーを承認させる方法を簡単に示すことです。



All Articles