<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/feedback1970/">
    <title>feedback1970 @ ウィキ</title>
    <link>http://w.atwiki.jp/feedback1970/</link>
    <atom:link href="https://w.atwiki.jp/feedback1970/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>feedback1970 @ ウィキ</description>

    <dc:language>ja</dc:language>
    <dc:date>2009-03-04T01:12:48+09:00</dc:date>
    <utime>1236096768</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/71.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/70.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/13.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/69.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/68.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/61.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/67.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/66.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/65.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/feedback1970/pages/63.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/71.html">
    <title>vsftpd_1.2.1_twoprocess.c_common_do_login</title>
    <link>https://w.atwiki.jp/feedback1970/pages/71.html</link>
    <description>
      **source
twoprocess.c

**line
243 - 315

**概要

 static void common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str, int do_chroot, int anon)

**処理の流れ

    246 {
    247   int was_anon = anon;
    248   const struct mystr* p_orig_user_str = p_user_str;
    249   int newpid;

    250   vsf_sysutil_install_null_sighandler(kVSFSysUtilSigCHLD);
    251   /* Asks the pre-login child to go away (by exiting) */

    252   priv_sock_send_result(p_sess, PRIV_SOCK_RESULT_OK);
    253   (void) vsf_sysutil_wait();

    254   /* Absorb the SIGCHLD */
    255   vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD);

    256   /* Handle loading per-user config options */
    257   handle_per_user_config(p_user_str);

    258   /* Set this before we fork */
    259   p_sess-&gt;is_anonymous = anon;

    260   vsf_sysutil_install_async_sighandler(kVSFSysUtilSigCHLD, handle_sigchld);

    261   newpid = vsf_sysutil_fork();
    262   if (newpid == 0)
    263   {
    264     struct mystr guest_user_str = INIT_MYSTR;
    265     struct mystr chroot_str = INIT_MYSTR;
    266     struct mystr chdir_str = INIT_MYSTR;
    267     struct mystr userdir_str = INIT_MYSTR;
    268     unsigned int secutil_option = VSF_SECUTIL_OPTION_USE_GROUPS;
    269     /* Child - drop privs and start proper FTP! */
    270     if (tunable_guest_enable &amp;&amp; !anon)

    271     {
    272       /* Remap to the guest user */
    273       str_alloc_text(&amp;guest_user_str, tunable_guest_username);
    274       p_user_str = &amp;guest_user_str;

    275       if (!tunable_virtual_use_local_privs)
    276       {
    277         anon = 1;
    278         do_chroot = 1;
    279       }
    280     }

    281     if (do_chroot)
    282     {
    283       secutil_option |= VSF_SECUTIL_OPTION_CHROOT;
    284     }

    285     if (!anon)
    286     {
    287       secutil_option |= VSF_SECUTIL_OPTION_CHANGE_EUID;
    288     }

    289     calculate_chdir_dir(was_anon, &amp;userdir_str, &amp;chroot_str, &amp;chdir_str,
    290                         p_user_str, p_orig_user_str);

    291     vsf_secutil_change_credentials(p_user_str, &amp;userdir_str, &amp;chroot_str,
    292                                    0, secutil_option);

    293     if (!str_isempty(&amp;chdir_str))
    294     {
    295       (void) str_chdir(&amp;chdir_str);
    296     }

    297     str_free(&amp;guest_user_str);
    298     str_free(&amp;chroot_str);
    299     str_free(&amp;chdir_str);
    300     str_free(&amp;userdir_str);

    301     /* Guard against the config error of having the anonymous ftp tree owned
    302      * by the user we are running as
    303      */
    304     if (was_anon &amp;&amp; vsf_sysutil_write_access(&quot;/&quot;))
    305     {
    306       die(&quot;vsftpd: refusing to run with writable anonymous root&quot;);
    307     }

    308     p_sess-&gt;is_anonymous = anon;
    309     process_post_login(p_sess);
    310     bug(&quot;should not get here: common_do_login&quot;);
    311   }

    312   /* Parent */
    313   vsf_priv_parent_postlogin(p_sess);
    314   bug(&quot;should not get here in common_do_login&quot;);
    315 }


**function 

    243 static void
    244 common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str,
    245                 int do_chroot, int anon)
    246 {
    247   int was_anon = anon;
    248   const struct mystr* p_orig_user_str = p_user_str;
    249   int newpid;
    250   vsf_sysutil_install_null_sighandler(kVSFSysUtilSigCHLD);
    251   /* Asks the pre-login child to go away (by exiting) */
    252   priv_sock_send_result(p_sess, PRIV_SOCK_RESULT_OK);
    253   (void) vsf_sysutil_wait();
    254   /* Absorb the SIGCHLD */
    255   vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD);
    256   /* Handle loading per-user config options */
    257   handle_per_user_config(p_user_str);
    258   /* Set this before we fork */
    259   p_sess-&gt;is_anonymous = anon;
    260   vsf_sysutil_install_async_sighandler(kVSFSysUtilSigCHLD, handle_sigchld);
    261   newpid = vsf_sysutil_fork();
    262   if (newpid == 0)
    263   {
    264     struct mystr guest_user_str = INIT_MYSTR;
    265     struct mystr chroot_str = INIT_MYSTR;
    266     struct mystr chdir_str = INIT_MYSTR;
    267     struct mystr userdir_str = INIT_MYSTR;
    268     unsigned int secutil_option = VSF_SECUTIL_OPTION_USE_GROUPS;
    269     /* Child - drop privs and start proper FTP! */
    270     if (tunable_guest_enable &amp;&amp; !anon)
    271     {
    272       /* Remap to the guest user */
    273       str_alloc_text(&amp;guest_user_str, tunable_guest_username);
    274       p_user_str = &amp;guest_user_str;
    275       if (!tunable_virtual_use_local_privs)
    276       {
    277         anon = 1;
    278         do_chroot = 1;
    279       }
    280     }
    281     if (do_chroot)
    282     {
    283       secutil_option |= VSF_SECUTIL_OPTION_CHROOT;
    284     }
    285     if (!anon)
    286     {
    287       secutil_option |= VSF_SECUTIL_OPTION_CHANGE_EUID;
    288     }
    289     calculate_chdir_dir(was_anon, &amp;userdir_str, &amp;chroot_str, &amp;chdir_str,
    290                         p_user_str, p_orig_user_str);
    291     vsf_secutil_change_credentials(p_user_str, &amp;userdir_str, &amp;chroot_str,
    292                                    0, secutil_option);
    293     if (!str_isempty(&amp;chdir_str))
    294     {
    295       (void) str_chdir(&amp;chdir_str);
    296     }
    297     str_free(&amp;guest_user_str);
    298     str_free(&amp;chroot_str);
    299     str_free(&amp;chdir_str);
    300     str_free(&amp;userdir_str);
    301     /* Guard against the config error of having the anonymous ftp tree owned
    302      * by the user we are running as
    303      */
    304     if (was_anon &amp;&amp; vsf_sysutil_write_access(&quot;/&quot;))
    305     {
    306       die(&quot;vsftpd: refusing to run with writable anonymous root&quot;);
    307     }
    308     p_sess-&gt;is_anonymous = anon;
    309     process_post_login(p_sess);
    310     bug(&quot;should not get here: common_do_login&quot;);
    311   }
    312   /* Parent */
    313   vsf_priv_parent_postlogin(p_sess);
    314   bug(&quot;should not get here in common_do_login&quot;);
    315 }    </description>
    <dc:date>2009-03-04T01:12:48+09:00</dc:date>
    <utime>1236096768</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/70.html">
    <title>vsftpd_1.2.1_twoprocess.c_process_login_req</title>
    <link>https://w.atwiki.jp/feedback1970/pages/70.html</link>
    <description>
      **source
twoprocess.c

**line
171 - 241

**処理の流れ

    171 static void
    172 process_login_req(struct vsf_session* p_sess)
    173 {
    174   enum EVSFPrivopLoginResult e_login_result = kVSFLoginNull;
    175   char cmd;
    176   vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD);
    177   /* Blocks */
    178   cmd = priv_sock_get_cmd(p_sess);
    179   vsf_sysutil_block_sig(kVSFSysUtilSigCHLD);
    180   if (cmd != PRIV_SOCK_LOGIN)
    181   {
    182     die(&quot;bad request&quot;);
    183   }
    184   /* Get username and password - we must distrust these */
    185   {
    186     struct mystr password_str = INIT_MYSTR;
    187     priv_sock_get_str(p_sess, &amp;p_sess-&gt;user_str);
    188     priv_sock_get_str(p_sess, &amp;password_str);
    189     e_login_result = vsf_privop_do_login(p_sess, &amp;password_str);
    190     str_free(&amp;password_str);
    191   }
    192   switch (e_login_result)
    193   {
    194     case kVSFLoginFail:
    195       priv_sock_send_result(p_sess, PRIV_SOCK_RESULT_BAD);
    196       return;
    197       break;
    198     case kVSFLoginAnon:
    199       str_alloc_text(&amp;p_sess-&gt;user_str, tunable_ftp_username);
    200       common_do_login(p_sess, &amp;p_sess-&gt;user_str, 1, 1);
    201       break;
    202     case kVSFLoginReal:
    203       {
    204         int do_chroot = 0;
    205         if (tunable_chroot_local_user)
    206         {
    207           do_chroot = 1;
    208         }
    209         if (tunable_chroot_list_enable)
    210         {
    211           struct mystr chroot_list_file = INIT_MYSTR;
    212           int retval = str_fileread(&amp;chroot_list_file,
    213                                     tunable_chroot_list_file,
    214                                     VSFTP_CONF_FILE_MAX);
    215           if (vsf_sysutil_retval_is_error(retval))
    216           {
    217             die2(&quot;could not open chroot() list file:&quot;,
    218                  tunable_chroot_list_file);
    219           }
    220           if (str_contains_line(&amp;chroot_list_file, &amp;p_sess-&gt;user_str))
    221           {
    222             if (do_chroot)
    223             {
    224               do_chroot = 0;
    225             }
    226             else
    227             {
    228               do_chroot = 1;
    229             }
    230           }
    231           str_free(&amp;chroot_list_file);
    232         }
    233         common_do_login(p_sess, &amp;p_sess-&gt;user_str, do_chroot, 0);
    234       }
    235       break;
    236     default:
    237       bug(&quot;weird state in process_login_request&quot;);
    238       break;
    239   }
    240   /* NOTREACHED */
    241 }


**function 

    171 static void
    172 process_login_req(struct vsf_session* p_sess)
    173 {
    174   enum EVSFPrivopLoginResult e_login_result = kVSFLoginNull;
    175   char cmd;
    176   vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD);
    177   /* Blocks */
    178   cmd = priv_sock_get_cmd(p_sess);
    179   vsf_sysutil_block_sig(kVSFSysUtilSigCHLD);
    180   if (cmd != PRIV_SOCK_LOGIN)
    181   {
    182     die(&quot;bad request&quot;);
    183   }
    184   /* Get username and password - we must distrust these */
    185   {
    186     struct mystr password_str = INIT_MYSTR;
    187     priv_sock_get_str(p_sess, &amp;p_sess-&gt;user_str);
    188     priv_sock_get_str(p_sess, &amp;password_str);
    189     e_login_result = vsf_privop_do_login(p_sess, &amp;password_str);
    190     str_free(&amp;password_str);
    191   }
    192   switch (e_login_result)
    193   {
    194     case kVSFLoginFail:
    195       priv_sock_send_result(p_sess, PRIV_SOCK_RESULT_BAD);
    196       return;
    197       break;
    198     case kVSFLoginAnon:
    199       str_alloc_text(&amp;p_sess-&gt;user_str, tunable_ftp_username);
    200       common_do_login(p_sess, &amp;p_sess-&gt;user_str, 1, 1);
    201       break;
    202     case kVSFLoginReal:
    203       {
    204         int do_chroot = 0;
    205         if (tunable_chroot_local_user)
    206         {
    207           do_chroot = 1;
    208         }
    209         if (tunable_chroot_list_enable)
    210         {
    211           struct mystr chroot_list_file = INIT_MYSTR;
    212           int retval = str_fileread(&amp;chroot_list_file,
    213                                     tunable_chroot_list_file,
    214                                     VSFTP_CONF_FILE_MAX);
    215           if (vsf_sysutil_retval_is_error(retval))
    216           {
    217             die2(&quot;could not open chroot() list file:&quot;,
    218                  tunable_chroot_list_file);
    219           }
    220           if (str_contains_line(&amp;chroot_list_file, &amp;p_sess-&gt;user_str))
    221           {
    222             if (do_chroot)
    223             {
    224               do_chroot = 0;
    225             }
    226             else
    227             {
    228               do_chroot = 1;
    229             }
    230           }
    231           str_free(&amp;chroot_list_file);
    232         }
    233         common_do_login(p_sess, &amp;p_sess-&gt;user_str, do_chroot, 0);
    234       }
    235       break;
    236     default:
    237       bug(&quot;weird state in process_login_request&quot;);
    238       break;
    239   }
    240   /* NOTREACHED */
    241 }    </description>
    <dc:date>2009-03-04T01:04:24+09:00</dc:date>
    <utime>1236096264</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/13.html">
    <title>vsftpd_1.2.1_main.c</title>
    <link>https://w.atwiki.jp/feedback1970/pages/13.html</link>
    <description>
      **memo

***処理の流れ

+die_unless_privileged(); /* Just get out unless we start with requisite privilege */
+番号リスト

+コンフィグ読み出し(?)
-vsf_sysutil_map_anon_pages_init();

  /* This might need to open /dev/zero on systems lacking MAP_ANON. Needs
   * to be done early (i.e. before config file parse, which may use
   * anonymous pages
   */
  これは、MAP_ANONを欠きながらシステムの上で/dev/zeroを開く必要があるかもしれません。 
  早くされるべき必要性、(すなわち、コンフィグファイルが分析される前に、どれが匿名のページを使用するかもしれないか。

-コンフィグファイルの状態確認?
    int retval = vsf_sysutil_stat(p_config_name, &amp;p_statbuf);

-コンフィグ読み出し
--if (!vsf_sysutil_retval_is_error(retval))　→　vsf_parseconf_load_file(p_config_name, 1);   
--コンフィグを読み込めない場合はエラー
---else if (config_specified) →　die2(&quot;vsftpd: cannot open config file:&quot;, p_config_name);
　　　　　　　　　　　　　　　　　　   vsf_sysutil_free(p_statbuf);

+わからん
--tunable_setproctitle_enable が設定されている場合（デフォルトは 0

 tunable_setproctitle_enable
 有効にした場合、システムのプロセスリスト(例えば ps aux コマンド)にセッションの状態に関する情報を表示する。
 つまり、表示されるプロセス名が vsftpd のセッションがどうなっているか (idle, downloading など)に応じて変化する。
 セキュリティ上、これを off のままにしておきたいと思うのが普通である。 

    　　/* Warning -- warning -- may nuke argv, environ */
 
vsf_sysutil_setproctitle_init(argc, argv);

+Standalone Mode (inetd を使用しない)で起動するか

どちらかが設定されていれば、Standalone モードで起動する
./tunables.h:extern int tunable_listen; (デフォルトは0)
./tunables.h:extern int tunable_listen_ipv6; (デフォルトは0)

 tunable_listen
 YES に設定した場合、スタンドアロンモードで起動する。
 これは inetd などのスーパーサーバから起動してはいけないということを意味する。
 その代わりに、vsftpd プログラムを一度だけ直接実行すればよい。 
 vsftpd 自身が、入ってくる接続を待ち、処理する面倒をみる。 

 tunable_listen_ipv6
 IPv4 ソケットの代わりに IPv6 ソケットを待ち受ける点を除けば、 listen オプションと同じである。
 このオプションと listen オプションは、どちらか一方しか指定することができない。 

    struct vsf_client_launch ret = vsf_standalone_main();
    the_session.num_clients = ret.num_children;
    the_session.num_this_ip = ret.num_this_ip;

+健全性チェック
-do_sanity_checks();

  /* Sanity checks - exit with a graceful error message if our STDIN is not
   * a socket. Also check various config options don&#039;t collide.
   */
  健全度チェック--私たちのSTDINがソケットでないなら優雅なエラーメッセージと共に出てください。 
  また、チェックの様々なコンフィグオプションは衝突しません。

+セッション初期化
-session_init(&amp;the_session);

 /* Initializes session globals - e.g. IP addr&#039;s etc. */

+環境初期化
-env_init();

 /* Set up &quot;environment&quot;, e.g. process group etc. */
  
+ロギング設定
-  vsf_log_init(&amp;the_session);

 /* Set up logging - must come after global init because we need the remote
  * address to convert into text
  */
 伐採--私たちがテキストに変換するためにリモートアドレスを必要とするのでグローバルなイニットに続かなければならないのをセットアップしてください。

+str_alloc_text(&amp;the_session.remote_ip_str,
                 vsf_sysutil_inet_ntop(the_session.p_remote_addr));
  
+/* Set up options on the command socket */
-vsf_cmdio_sock_setup();
-if (tunable_setproctitle_enable)
--vsf_sysutil_set_proctitle_prefix(&amp;the_session.remote_ip_str);vsf_sysutil_setproctitle(&quot;connected&quot;);

- /* We might chroot() very soon (one process model), so we need to open
   * any required config files here.
   */

+TCP-Wrapper を使用するか

 tunable_tcp_wrappers が設定されている場合、（デフォルトは0）

 tunable_tcp_wrappers
 有効にした場合、 vsftpd を tcp_wrappers をサポートしてコンパイルしてあれば、外から来る接続は tcp_wrappers のアクセス制御が適用される。
 さらに IP ごとの設定のための仕組みがある。 
 tcp_wrappers で環境変数 VSFTPD_LOAD_CONF をセットした場合 (訳注: /etc/hosts.allow で指定することが可能)、その環境変数で指定したファイルを vsftpd の設定ファイルとして読み込む。 

     the_session.tcp_wrapper_ok = vsf_tcp_wrapper_ok(VSFTP_COMMAND_FD);
     const char* p_load_conf = vsf_sysutil_getenv(&quot;VSFTPD_LOAD_CONF&quot;);

+if (p_load_conf)
      vsf_parseconf_load_file(p_load_conf, 1);

+tunable_deny_email_enable が設定されている場合（デフォルトは0）

 tunable_deny_email_enable
 YES に設定した場合、anonymous ユーザのパスワード(e-mail アドレス)のうち、ログインを拒否したいもののリストを設定できる。
 デフォルトでは、このリストは /etc/vsftpd.banned_emails ファイルであるが、 banned_email_file 設定によってこれを変更することができる。 

     int retval = str_fileread(&amp;the_session.banned_email_str,
                              tunable_banned_email_file, VSFTP_CONF_FILE_MAX);

+if (vsf_sysutil_retval_is_error(retval))
      die2(&quot;cannot open anon e-mail list file:&quot;, tunable_banned_email_file);

+バナーファイルがあるか
-ある場合

 tunable_banner_file
 誰かがサーバに接続したときに表示するテキストを格納するファイル名を指定する。
 このオプションが設定された場合、 ftpd_banner で指定される文字列よりも優先される。 

　　if (tunable_banner_file)
     int retval = str_fileread(&amp;the_session.banner_str, tunable_banner_file,
                              VSFTP_CONF_FILE_MAX);
   
-無い場合
　　if (vsf_sysutil_retval_is_error(retval))
     die2(&quot;cannot open banner file:&quot;, tunable_banner_file);

+

 tunable_secure_email_list_enable（デフォルトは0）
 匿名ログインで許可する e-mail パスワードのリストを指定したい場合にだけ YES に設定すること。
 仮想的なユーザーを必要とせずに、低セキュリティなコンテンツへのアクセスを制限する、面倒の少ないやり方として便利である。 
 YES に設定した場合には、 email_password_file で指定されるファイルに書かれているパスワードが与えられない限り、匿名ログインを許可しない。
 このファイルのフォーマットは 1 行に 1 パスワードで、余分な空白があってはいけない。デフォルトのファイルはは /etc/vsftpd.email_passwords である。 

 if (tunable_secure_email_list_enable)
     int retval = str_fileread(&amp;the_session.email_passwords_str,
                              tunable_email_password_file,
                              VSFTP_CONF_FILE_MAX);
+if (vsf_sysutil_retval_is_error(retval))
      die2(&quot;cannot open email passwords file:&quot;, tunable_email_password_file);

 /* Special case - can force one process model if we&#039;ve got a setup
   * needing _no_ privs
   */
+ Process Model(?)の確認

-以下の条件にマッチする場合は、One Process Model(?)で起動する

ローカルログインを許可しない
Port20で接続しない
匿名ユーザーで?

if (!tunable_local_enable &amp;&amp; !tunable_connect_from_port_20 &amp;&amp;!tunable_chown_uploads)
   tunable_one_proess_model = 1;

./tunables.h:extern int tunable_local_enable;              /* Allow local logins */
./tunables.h:extern int tunable_connect_from_port_20;      /* PORT connects from port 20 */
./tunables.h:extern int tunable_chown_uploads;             /* chown() anon uploaded files */
./tunables.h:extern int tunable_one_process_model;         /* Go faster stripes ;-) */

 tunable_local_enable（デフォルトは0）
 ローカルユーザのログインを許可するかどうかを制御する。 
 YES に設定した場合、/etc/passwd にある普通のユーザアカウントをログインに使う。

 tunable_connect_from_port_20（デフォルトは0）
 PORT でのデータ接続において、サーバが(送信元)ポートに 20(ftp-data) を使うかどうか制御する。
 セキュリティ上の理由から、いくつかのクライアントはポート 20 を要求する。
 逆に言えば、このオプションを無効にすることで、わずかではあるが vsftpd をより少ない特権で動作させることができる。 

 tunable_chown_uploads（デフォルトは0）
 YES に設定した場合、anonymous でアップロードされたファイルの所有者を chown_username で設定したユーザにする。
 管理上、そして多分セキュリティの観点から便利である。

 tunable_one_process_model（デフォルトは0）
 もし Linux 2.4 カーネルを使用しているならば、一つの接続に一つのプロセスを使用するという、異なったセキュリティモデルを使用することができる。
 これは純粋なセキュリティモデルから少し外れるが、性能を得ることができる。
 自サイトで非常に多いユーザの同時接続をサポートし、自分が何をしているか知っている人だけが、このオプションを有効にしたくなる。 

if (tunable_one_process_model)
     vsf_one_process_start(&amp;the_session);

-条件にマッチしない場合は、Two Process Model(?)で起動する
     vsf_two_process_start(&amp;the_session);

+ /* NOTREACHED */
  bug(&quot;should not get here: main&quot;);
  return 1;

** source

 /*
  * Part of Very Secure FTPd
  * Licence: GPL
  * Author: Chris Evans
  * main.c
  */

 #include &quot;session.h&quot;
 #include &quot;utility.h&quot;
 #include &quot;tunables.h&quot;
 #include &quot;logging.h&quot;
 #include &quot;str.h&quot;
 #include &quot;filestr.h&quot;
 #include &quot;ftpcmdio.h&quot;
 #include &quot;sysutil.h&quot;
 #include &quot;sysdeputil.h&quot;
 #include &quot;defs.h&quot;
 #include &quot;parseconf.h&quot;
 #include &quot;oneprocess.h&quot;
 #include &quot;twoprocess.h&quot;
 #include &quot;standalone.h&quot;
 #include &quot;tcpwrap.h&quot;

 /*
  * Forward decls of helper functions
  */
 static void die_unless_privileged(void);
 static void do_sanity_checks(void);
 static void session_init(struct vsf_session* p_sess);
 static void env_init(void);

int
main(int argc, const char* argv[])
{
  struct vsf_session the_session =
  {
    /* Control connection */
    0, 0,
    /* Data connection */
    -1, 0, -1, 0, 0, 0, 0,
    /* Login */
    1, INIT_MYSTR, INIT_MYSTR,
    /* Protocol state */
    0, 1, INIT_MYSTR, 0, 0,
    /* Session state */
    0,
    /* Userids */
    -1, -1, -1,
    /* Pre-chroot() cache */
    INIT_MYSTR, INIT_MYSTR, INIT_MYSTR, INIT_MYSTR, 1,
    /* Logging */
    -1, -1, INIT_MYSTR, 0, 0, 0, INIT_MYSTR, 0,
    /* Buffers */
    INIT_MYSTR, INIT_MYSTR,
    /* Parent &lt;-&gt; child comms */
    0, -1, -1,
    /* Number of clients */
    0, 0
  };
  int config_specified = 0;
  const char* p_config_name = VSFTP_DEFAULT_CONFIG;
  /* Zero or one argument supported. If one argument is passed, it is the
   * path to the config file
   */
  if (argc &gt; 2)
  {
    die(&quot;vsftpd: too many arguments (I take an optional config file only)&quot;);
  }
  else if (argc == 0)
  {
    die(&quot;vsftpd: missing argv[0]&quot;);
  }
  if (argc == 2)
  {
    p_config_name = argv[1];
    config_specified = 1;
  }
  /* Just get out unless we start with requisite privilege */
  die_unless_privileged();
  /* This might need to open /dev/zero on systems lacking MAP_ANON. Needs
   * to be done early (i.e. before config file parse, which may use
   * anonymous pages
   */
  vsf_sysutil_map_anon_pages_init();
  /* Parse config file if it&#039;s there */
  {
    struct vsf_sysutil_statbuf* p_statbuf = 0;
    int retval = vsf_sysutil_stat(p_config_name, &amp;p_statbuf);
    if (!vsf_sysutil_retval_is_error(retval))
    {
      vsf_parseconf_load_file(p_config_name, 1);
    }
    else if (config_specified)
    {
      die2(&quot;vsftpd: cannot open config file:&quot;, p_config_name);
    }
    vsf_sysutil_free(p_statbuf);
  }
  if (tunable_setproctitle_enable)
  {
    /* Warning -- warning -- may nuke argv, environ */
    vsf_sysutil_setproctitle_init(argc, argv);
  }
  if (tunable_listen || tunable_listen_ipv6)
  {
    /* Standalone mode */
    struct vsf_client_launch ret = vsf_standalone_main();
    the_session.num_clients = ret.num_children;
    the_session.num_this_ip = ret.num_this_ip;
  }
  /* Sanity checks - exit with a graceful error message if our STDIN is not
   * a socket. Also check various config options don&#039;t collide.
   */
  do_sanity_checks();
  /* Initializes session globals - e.g. IP addr&#039;s etc. */
  session_init(&amp;the_session);
  /* Set up &quot;environment&quot;, e.g. process group etc. */
  env_init();
  /* Set up logging - must come after global init because we need the remote
   * address to convert into text
   */
  vsf_log_init(&amp;the_session);
  str_alloc_text(&amp;the_session.remote_ip_str,
                 vsf_sysutil_inet_ntop(the_session.p_remote_addr));
  /* Set up options on the command socket */
  vsf_cmdio_sock_setup();
  if (tunable_setproctitle_enable)
  {
    vsf_sysutil_set_proctitle_prefix(&amp;the_session.remote_ip_str);
    vsf_sysutil_setproctitle(&quot;connected&quot;);
  }
  /* We might chroot() very soon (one process model), so we need to open
   * any required config files here.
   */
  if (tunable_tcp_wrappers)
  {
    the_session.tcp_wrapper_ok = vsf_tcp_wrapper_ok(VSFTP_COMMAND_FD);
  }
  {
    const char* p_load_conf = vsf_sysutil_getenv(&quot;VSFTPD_LOAD_CONF&quot;);
    if (p_load_conf)
    {
      vsf_parseconf_load_file(p_load_conf, 1);
    }
  }
  if (tunable_deny_email_enable)
  {
    int retval = str_fileread(&amp;the_session.banned_email_str,
                              tunable_banned_email_file, VSFTP_CONF_FILE_MAX);
    if (vsf_sysutil_retval_is_error(retval))
    {
      die2(&quot;cannot open anon e-mail list file:&quot;, tunable_banned_email_file);
    }
  }
  if (tunable_banner_file)
  {
    int retval = str_fileread(&amp;the_session.banner_str, tunable_banner_file,
                              VSFTP_CONF_FILE_MAX);
    if (vsf_sysutil_retval_is_error(retval))
    {
      die2(&quot;cannot open banner file:&quot;, tunable_banner_file);
    }
  }
  if (tunable_secure_email_list_enable)
  {
    int retval = str_fileread(&amp;the_session.email_passwords_str,
                              tunable_email_password_file,
                              VSFTP_CONF_FILE_MAX);
    if (vsf_sysutil_retval_is_error(retval))
    {
      die2(&quot;cannot open email passwords file:&quot;, tunable_email_password_file);
    }
  }
  /* Special case - can force one process model if we&#039;ve got a setup
   * needing _no_ privs
   */
  if (!tunable_local_enable &amp;&amp; !tunable_connect_from_port_20 &amp;&amp;
      !tunable_chown_uploads)
  {
    tunable_one_process_model = 1;
  }
  if (tunable_one_process_model)
  {
    vsf_one_process_start(&amp;the_session);
  }
  else
  {
    vsf_two_process_start(&amp;the_session);
  }
  /* NOTREACHED */
  bug(&quot;should not get here: main&quot;);
  return 1;
}

static void
die_unless_privileged(void)
{
  if (!vsf_sysutil_running_as_root())
  {
    die(&quot;vsftpd: must be started as root&quot;);
  }
}

static void
do_sanity_checks(void)
{
  {
    struct vsf_sysutil_statbuf* p_statbuf = 0;
    vsf_sysutil_fstat(VSFTP_COMMAND_FD, &amp;p_statbuf);
    if (!vsf_sysutil_statbuf_is_socket(p_statbuf))
    {
      die(&quot;vsftpd: does not run standalone, must be started from inetd&quot;);
    }
    vsf_sysutil_free(p_statbuf);
  }
  if (tunable_one_process_model)
  {
    if (tunable_local_enable)
    {
      die(&quot;vsftpd: security: &#039;one_process_model&#039; is anonymous only&quot;);
    }
    if (!vsf_sysdep_has_capabilities_as_non_root())
    {
      die(&quot;vsftpd: security: &#039;one_process_model&#039; needs a better OS&quot;);
    }
  }
  if (!tunable_local_enable &amp;&amp; !tunable_anonymous_enable)
  {
    die(&quot;vsftpd: both local and anonymous access disabled!&quot;);
  }
}

static void
env_init(void)
{
  vsf_sysutil_make_session_leader();
  /* Set up a secure umask - we&#039;ll set the proper one after login */
  vsf_sysutil_set_umask(VSFTP_SECURE_UMASK);
  /* Fire up libc&#039;s timezone initialisation, before we chroot()! */
  vsf_sysutil_tzset();
  /* Signals. We&#039;ll always take -EPIPE rather than a rude signal, thanks */
  vsf_sysutil_install_null_sighandler(kVSFSysUtilSigPIPE);
}

static void
session_init(struct vsf_session* p_sess)
{
  /* Get the addresses of the control connection */
&amp;space(8)[[vsf_sysutil_getpeername&gt;vsftpd_1.2.1_sysutil.c_vsf_sysutil_getpeername]](VSFTP_COMMAND_FD, &amp;p_sess-&gt;p_remote_addr);
&amp;space(8)[[vsf_sysutil_getsockname&gt;vsftpd_1.2.1_sysutil.c_vsf_sysutil_getsockname]](VSFTP_COMMAND_FD, &amp;p_sess-&gt;p_local_addr);
  /* If anonymous mode is active, fetch the uid of the anonymous user */
  if (tunable_anonymous_enable)
  {
    const struct vsf_sysutil_user* p_user =
&amp;space(20)[[vsf_sysutil_getpwnam&gt;vsftpd_1.2.1_sysutil.c_vsf_sysutil_getpwnam]](tunable_ftp_username);
    if (p_user == 0)
    {
&amp;space(18)[[die2&gt;vsftpd_1.2.1_utility.c_die2]](&quot;vsftpd: cannot locate user specified in &#039;ftp_username&#039;:&quot;,
           tunable_ftp_username);
    }
    p_sess-&gt;anon_ftp_uid = vsf_sysutil_user_getuid(p_user);
  }
  if (tunable_guest_enable)
  {
    const struct vsf_sysutil_user* p_user =
&amp;space(20)[[vsf_sysutil_getpwnam&gt;vsftpd_1.2.1_sysutil.c_vsf_sysutil_getpwnam]](tunable_ftp_username);
    if (p_user == 0)
    {
&amp;space(18)[[die2&gt;vsftpd_1.2.1_utility.c_die2]](&quot;vsftpd: cannot locate user specified in &#039;guest_username&#039;:&quot;,
           tunable_guest_username);
    }
    p_sess-&gt;guest_user_uid = vsf_sysutil_user_getuid(p_user);
  }
  if (tunable_chown_uploads)
  {
    const struct vsf_sysutil_user* p_user =
&amp;space(20)[[vsf_sysutil_getpwnam&gt;vsftpd_1.2.1_sysutil.c_vsf_sysutil_getpwnam]](tunable_chown_userna);
    if (p_user == 0)
    {
&amp;space(18)[[die2&gt;vsftpd_1.2.1_utility.c_die2]](&quot;vsftpd: cannot locate user specified in &#039;chown_username&#039;:&quot;,
           tunable_chown_username);
    }
    p_sess-&gt;anon_upload_chown_uid = vsf_sysutil_user_getuid(p_user);
  }
}    </description>
    <dc:date>2009-03-03T23:45:15+09:00</dc:date>
    <utime>1236091515</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/69.html">
    <title>vsftpd_1.2.1_sysutil.c_vsf_sysutil_make_session_leader</title>
    <link>https://w.atwiki.jp/feedback1970/pages/69.html</link>
    <description>
      **source
sysutil.c

**line
2329 - 2339

**処理の流れ 

   2329 void
   2330 vsf_sysutil_make_session_leader(void)
   2331 {
   2332   /* This makes us the leader if we are not already */
   2333   (void) setsid();
   2334   /* Check we&#039;re the leader */
   2335   if (getpid() != getpgrp())
   2336   {
   2337     die(&quot;not session leader&quot;);
   2338   }
   2339 }

**function 

   2329 void
   2330 vsf_sysutil_make_session_leader(void)
   2331 {
   2332   /* This makes us the leader if we are not already */
   2333   (void) setsid();
   2334   /* Check we&#039;re the leader */
   2335   if (getpid() != getpgrp())
   2336   {
   2337     die(&quot;not session leader&quot;);
   2338   }
   2339 }    </description>
    <dc:date>2009-03-01T22:30:13+09:00</dc:date>
    <utime>1235914213</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/68.html">
    <title>vsftpd_1.2.1_main.c_env_init</title>
    <link>https://w.atwiki.jp/feedback1970/pages/68.html</link>
    <description>
      **source
main.c

**line
233 - 243

**概要

static void env_init(void)

**処理の流れ 

     233 static void
    234 env_init(void)
    235 {
    236   vsf_sysutil_make_session_leader();
    237   /* Set up a secure umask - we&#039;ll set the proper one after login */
    238   vsf_sysutil_set_umask(VSFTP_SECURE_UMASK);
    239   /* Fire up libc&#039;s timezone initialisation, before we chroot()! */
    240   vsf_sysutil_tzset();
    241   /* Signals. We&#039;ll always take -EPIPE rather than a rude signal, thanks */
    242   vsf_sysutil_install_null_sighandler(kVSFSysUtilSigPIPE);
    243 }


**function 

    233 static void
    234 env_init(void)
    235 {
    236   vsf_sysutil_make_session_leader();
    237   /* Set up a secure umask - we&#039;ll set the proper one after login */
    238   vsf_sysutil_set_umask(VSFTP_SECURE_UMASK);
    239   /* Fire up libc&#039;s timezone initialisation, before we chroot()! */
    240   vsf_sysutil_tzset();
    241   /* Signals. We&#039;ll always take -EPIPE rather than a rude signal, thanks */
    242   vsf_sysutil_install_null_sighandler(kVSFSysUtilSigPIPE);
    243 }    </description>
    <dc:date>2009-03-01T22:23:09+09:00</dc:date>
    <utime>1235913789</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/61.html">
    <title>vsftpd_1.2.1_main.c_session_init</title>
    <link>https://w.atwiki.jp/feedback1970/pages/61.html</link>
    <description>
      *session_init

**source
main.c

**line
245 - 285

**概要

static void session_init(struct vsf_session* p_sess)

**処理の流れ

--コントロールコネクションのアドレス取得
    248   /* Get the addresses of the control connection */
    249   vsf_sysutil_getpeername(VSFTP_COMMAND_FD, &amp;p_sess-&gt;p_remote_addr);
    250   vsf_sysutil_getsockname(VSFTP_COMMAND_FD, &amp;p_sess-&gt;p_local_addr);

--tunable_anonymous_enableが有効な場合の処理

 tunable_anonymous_enable (デフォルトは1)
 Anonymous（匿名）ログインを許可するか否かのコントロールをします。有効にした場合、ユーザ名&quot;ftp&quot;も&quot;anonymous&quot;も共にAnonymous（匿名）ログインとして承認されます。

    253   {
    254     const struct vsf_sysutil_user* p_user =
    255       vsf_sysutil_getpwnam(tunable_ftp_username);
    256     if (p_user == 0)
    257     {
    258       die2(&quot;vsftpd: cannot locate user specified in &#039;ftp_username&#039;:&quot;,
    259            tunable_ftp_username);
    260     }
    261     p_sess-&gt;anon_ftp_uid = vsf_sysutil_user_getuid(p_user);
    262   }

--tunable_guest_enableが有効の場合の処理

 tunable_guest_enable (デフォルトは0)
 If enabled, all non-anonymous logins are classed as &quot;guest&quot; logins. 
 A guest login is remapped to the user specified in the guest_username setting. 
 可能にされるなら、すべての非匿名のログインが「お客様」ログインとして分類されます。 
 お客様ログインはお客様_ユーザ名設定で指定されたユーザに再写像されます。

    264   {
    265     const struct vsf_sysutil_user* p_user =
    266       vsf_sysutil_getpwnam(tunable_guest_username);
    267     if (p_user == 0)
    268     {
    269       die2(&quot;vsftpd: cannot locate user specified in &#039;guest_username&#039;:&quot;,
    270            tunable_guest_username);
    271     }
    272     p_sess-&gt;guest_user_uid = vsf_sysutil_user_getuid(p_user);
    273   }

--tunable_chown_uploadsが有効な場合の処理

 tunable_chown_uploads (デフォルトは0)
 有効にすると、全ての匿名によるアップロードファイルはchown_usernameオプションで指定された所有者に変更されるようになります。
 これは管理の、そして恐らくセキュリティの、見地から役立つといえます。

    275   {
    276     const struct vsf_sysutil_user* p_user =
    277       vsf_sysutil_getpwnam(tunable_chown_username);
    278     if (p_user == 0)
    279     {
    280       die2(&quot;vsftpd: cannot locate user specified in &#039;chown_username&#039;:&quot;,
    281            tunable_chown_username);
    282     }
    283     p_sess-&gt;anon_upload_chown_uid = vsf_sysutil_user_getuid(p_user);
    284   }
    285 }

**function 

    245 static void
    246 session_init(struct vsf_session* p_sess)
    247 {
    248   /* Get the addresses of the control connection */
    249   vsf_sysutil_getpeername(VSFTP_COMMAND_FD, &amp;p_sess-&gt;p_remote_addr);
    250   vsf_sysutil_getsockname(VSFTP_COMMAND_FD, &amp;p_sess-&gt;p_local_addr);
    251   /* If anonymous mode is active, fetch the uid of the anonymous user */
    252   if (tunable_anonymous_enable)
    253   {
    254     const struct vsf_sysutil_user* p_user =
    255       vsf_sysutil_getpwnam(tunable_ftp_username);
    256     if (p_user == 0)
    257     {
    258       die2(&quot;vsftpd: cannot locate user specified in &#039;ftp_username&#039;:&quot;,
    259            tunable_ftp_username);
    260     }
    261     p_sess-&gt;anon_ftp_uid = vsf_sysutil_user_getuid(p_user);
    262   }
    263   if (tunable_guest_enable)
    264   {
    265     const struct vsf_sysutil_user* p_user =
    266       vsf_sysutil_getpwnam(tunable_guest_username);
    267     if (p_user == 0)
    268     {
    269       die2(&quot;vsftpd: cannot locate user specified in &#039;guest_username&#039;:&quot;,
    270            tunable_guest_username);
    271     }
    272     p_sess-&gt;guest_user_uid = vsf_sysutil_user_getuid(p_user);
    273   }
    274   if (tunable_chown_uploads)
    275   {
    276     const struct vsf_sysutil_user* p_user =
    277       vsf_sysutil_getpwnam(tunable_chown_username);
    278     if (p_user == 0)
    279     {
    280       die2(&quot;vsftpd: cannot locate user specified in &#039;chown_username&#039;:&quot;,
    281            tunable_chown_username);
    282     }
    283     p_sess-&gt;anon_upload_chown_uid = vsf_sysutil_user_getuid(p_user);
    284   }
    285 }    </description>
    <dc:date>2009-03-01T22:15:00+09:00</dc:date>
    <utime>1235913300</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/67.html">
    <title>vsftpd_1.2.1_prelogin.c_parse_username_password</title>
    <link>https://w.atwiki.jp/feedback1970/pages/67.html</link>
    <description>
      **source
prelogin.c

**line
95 - 121

**概要

static void parse_username_password(struct vsf_session* p_sess)


**処理の流れ 

      95 static void
     96 parse_username_password(struct vsf_session* p_sess)
     97 {
     98   while (1)
     99   {


    100     vsf_cmdio_get_cmd_and_arg(p_sess, &amp;p_sess-&gt;ftp_cmd_str,
    101                               &amp;p_sess-&gt;ftp_arg_str, 1);

-
    102     if (str_equal_text(&amp;p_sess-&gt;ftp_cmd_str, &quot;USER&quot;))
    103     {
    104       handle_user_command(p_sess);
    105     }

-
    106     else if (str_equal_text(&amp;p_sess-&gt;ftp_cmd_str, &quot;PASS&quot;))
    107     {
    108       handle_pass_command(p_sess);
    109     }

-
    110     else if (str_equal_text(&amp;p_sess-&gt;ftp_cmd_str, &quot;QUIT&quot;))
    111     {
    112       vsf_cmdio_write(p_sess, FTP_GOODBYE, &quot;Goodbye.&quot;);
    113       vsf_sysutil_exit(0);
    114     }

-
    115     else
    116     {
    117       vsf_cmdio_write(p_sess, FTP_LOGINERR,
    118                       &quot;Please login with USER and PASS.&quot;);
    119     }
    120   }
    121 }


**function 

     95 static void
     96 parse_username_password(struct vsf_session* p_sess)
     97 {
     98   while (1)
     99   {
    100     vsf_cmdio_get_cmd_and_arg(p_sess, &amp;p_sess-&gt;ftp_cmd_str,
    101                               &amp;p_sess-&gt;ftp_arg_str, 1);
    102     if (str_equal_text(&amp;p_sess-&gt;ftp_cmd_str, &quot;USER&quot;))
    103     {
    104       handle_user_command(p_sess);
    105     }
    106     else if (str_equal_text(&amp;p_sess-&gt;ftp_cmd_str, &quot;PASS&quot;))
    107     {
    108       handle_pass_command(p_sess);
    109     }
    110     else if (str_equal_text(&amp;p_sess-&gt;ftp_cmd_str, &quot;QUIT&quot;))
    111     {
    112       vsf_cmdio_write(p_sess, FTP_GOODBYE, &quot;Goodbye.&quot;);
    113       vsf_sysutil_exit(0);
    114     }
    115     else
    116     {
    117       vsf_cmdio_write(p_sess, FTP_LOGINERR,
    118                       &quot;Please login with USER and PASS.&quot;);
    119     }
    120   }
    121 }    </description>
    <dc:date>2009-03-01T16:35:52+09:00</dc:date>
    <utime>1235892952</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/66.html">
    <title>vsftpd_1.2.1_prelogin.c_handle_pass_command</title>
    <link>https://w.atwiki.jp/feedback1970/pages/66.html</link>
    <description>
      **source
prelogin.c

**line
28 - 43

**概要

static void handle_pass_command(struct vsf_session* p_sess)

**処理の流れ 

      28 static void handle_pass_command(struct vsf_session* p_sess);
     29
     30 void
     31 init_connection(struct vsf_session* p_sess)
     32 {
     33   if (tunable_setproctitle_enable)
     34   {
     35     vsf_sysutil_setproctitle(&quot;not logged in&quot;);
     36   }
     37   /* Before we talk to the remote, make sure an alarm is set up in case
     38    * writing the initial greetings should block.
     39    */
     40   vsf_cmdio_set_alarm(p_sess);
     41   emit_greeting(p_sess);
     42   parse_username_password(p_sess);
     43 }


**function 

     28 static void handle_pass_command(struct vsf_session* p_sess);
     29
     30 void
     31 init_connection(struct vsf_session* p_sess)
     32 {
     33   if (tunable_setproctitle_enable)
     34   {
     35     vsf_sysutil_setproctitle(&quot;not logged in&quot;);
     36   }
     37   /* Before we talk to the remote, make sure an alarm is set up in case
     38    * writing the initial greetings should block.
     39    */
     40   vsf_cmdio_set_alarm(p_sess);
     41   emit_greeting(p_sess);
     42   parse_username_password(p_sess);
     43 }    </description>
    <dc:date>2009-03-01T16:34:59+09:00</dc:date>
    <utime>1235892899</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/65.html">
    <title>vsftpd_1.2.1_prelogin.c_handle_user_command</title>
    <link>https://w.atwiki.jp/feedback1970/pages/65.html</link>
    <description>
      **source
prelogin.c

**line
123 - 166

**概要

static void handle_user_command(struct vsf_session* p_sess)

**処理の流れ 

     123 static void
    124 handle_user_command(struct vsf_session* p_sess)
    125 {
    126   /* SECURITY: If we&#039;re in anonymous only-mode, immediately reject
    127    * non-anonymous usernames in the hope we save passwords going plaintext
    128    * over the network
    129    */
    130   int is_anon = 1;
    131   str_copy(&amp;p_sess-&gt;user_str, &amp;p_sess-&gt;ftp_arg_str);
    132   str_upper(&amp;p_sess-&gt;ftp_arg_str);
    133   if (!str_equal_text(&amp;p_sess-&gt;ftp_arg_str, &quot;FTP&quot;) &amp;&amp;
    134       !str_equal_text(&amp;p_sess-&gt;ftp_arg_str, &quot;ANONYMOUS&quot;))
    135   {
    136     is_anon = 0;
    137   }
    138   if (!tunable_local_enable &amp;&amp; !is_anon)
    139   {
    140     vsf_cmdio_write(p_sess, FTP_LOGINERR,
    141                     &quot;This FTP server is anonymous only.&quot;);
    142     str_empty(&amp;p_sess-&gt;user_str);
    143     return;
    144   }
    145   if (!str_isempty(&amp;p_sess-&gt;userlist_str))
    146   {
    147     int located = str_contains_line(&amp;p_sess-&gt;userlist_str, &amp;p_sess-&gt;user_str);
    148     if ((located &amp;&amp; tunable_userlist_deny) ||
    149         (!located &amp;&amp; !tunable_userlist_deny))
    150     {
    151       vsf_cmdio_write(p_sess, FTP_LOGINERR, &quot;Permission denied.&quot;);
    152       str_empty(&amp;p_sess-&gt;user_str);
    153       return;
    154     }
    155   }
    156   if (is_anon &amp;&amp; tunable_no_anon_password)
    157   {
    158     /* Fake a password */
    159     str_alloc_text(&amp;p_sess-&gt;ftp_arg_str, &quot;&lt;no password&gt;&quot;);
    160     handle_pass_command(p_sess);
    161   }
    162   else
    163   {
    164     vsf_cmdio_write(p_sess, FTP_GIVEPWORD, &quot;Please specify the password.&quot;);
    165   }
    166 }

**function 

    123 static void
    124 handle_user_command(struct vsf_session* p_sess)
    125 {
    126   /* SECURITY: If we&#039;re in anonymous only-mode, immediately reject
    127    * non-anonymous usernames in the hope we save passwords going plaintext
    128    * over the network
    129    */
    130   int is_anon = 1;
    131   str_copy(&amp;p_sess-&gt;user_str, &amp;p_sess-&gt;ftp_arg_str);
    132   str_upper(&amp;p_sess-&gt;ftp_arg_str);
    133   if (!str_equal_text(&amp;p_sess-&gt;ftp_arg_str, &quot;FTP&quot;) &amp;&amp;
    134       !str_equal_text(&amp;p_sess-&gt;ftp_arg_str, &quot;ANONYMOUS&quot;))
    135   {
    136     is_anon = 0;
    137   }
    138   if (!tunable_local_enable &amp;&amp; !is_anon)
    139   {
    140     vsf_cmdio_write(p_sess, FTP_LOGINERR,
    141                     &quot;This FTP server is anonymous only.&quot;);
    142     str_empty(&amp;p_sess-&gt;user_str);
    143     return;
    144   }
    145   if (!str_isempty(&amp;p_sess-&gt;userlist_str))
    146   {
    147     int located = str_contains_line(&amp;p_sess-&gt;userlist_str, &amp;p_sess-&gt;user_str);
    148     if ((located &amp;&amp; tunable_userlist_deny) ||
    149         (!located &amp;&amp; !tunable_userlist_deny))
    150     {
    151       vsf_cmdio_write(p_sess, FTP_LOGINERR, &quot;Permission denied.&quot;);
    152       str_empty(&amp;p_sess-&gt;user_str);
    153       return;
    154     }
    155   }
    156   if (is_anon &amp;&amp; tunable_no_anon_password)
    157   {
    158     /* Fake a password */
    159     str_alloc_text(&amp;p_sess-&gt;ftp_arg_str, &quot;&lt;no password&gt;&quot;);
    160     handle_pass_command(p_sess);
    161   }
    162   else
    163   {
    164     vsf_cmdio_write(p_sess, FTP_GIVEPWORD, &quot;Please specify the password.&quot;);
    165   }
    166 }    </description>
    <dc:date>2009-03-01T16:31:03+09:00</dc:date>
    <utime>1235892663</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/feedback1970/pages/63.html">
    <title>vsftpd_1.2.1_prelogin.c_init_connection</title>
    <link>https://w.atwiki.jp/feedback1970/pages/63.html</link>
    <description>
      **source
prelogin.c

**line
30 - 93

**概要

void init_connection(struct vsf_session* p_sess)

**処理の流れ 


-tunable_setproctitle_enable が有効の場合

  tunable_setproctitle_enable が設定されている場合（デフォルトは 0）

 tunable_setproctitle_enable
 可能にされると、vsftpdは、システムプロセスのセッション状態情報がリストアップされているのを示してみるでしょう。 
 言い換えれば、プロセスの報告された名前は、vsftpdセッションがしていることを反映するために変化するでしょう(怠けてください、などをダウンロードして)。 
 あなたはセキュリティ目的のためにたぶんこれをやめたがっています。 

     35     vsf_sysutil_setproctitle(&quot;not logged in&quot;);
     36   }

-/* Before we talk to the remote, make sure an alarm is set up in case * writing the initial greetings should block.

     40   vsf_cmdio_set_alarm(p_sess);

-

     41   emit_greeting(p_sess);

-username と password 処理

     42   parse_username_password(p_sess);


**function 

     30 void
     31 init_connection(struct vsf_session* p_sess)
     32 {
     33   if (tunable_setproctitle_enable)
     34   {
     35     vsf_sysutil_setproctitle(&quot;not logged in&quot;);
     36   }
     37   /* Before we talk to the remote, make sure an alarm is set up in case
     38    * writing the initial greetings should block.
     39    */
     40   vsf_cmdio_set_alarm(p_sess);
     41   emit_greeting(p_sess);
     42   parse_username_password(p_sess);
     43 }    </description>
    <dc:date>2009-03-01T16:14:00+09:00</dc:date>
    <utime>1235891640</utime>
  </item>
  </rdf:RDF>
