為Serv-U提供線上修改密碼功能

來源:互聯網
上載者:User
serv-u|線上

  由於日常工作的需要,單位使用Serv-U架設了一個FTP伺服器,可是自從接手之後發現存在著一個非常嚴重的問題,這個FTP伺服器是對外公開的,居然很多使用者都沒有設定密碼。如果強制要求所有人設定密碼又必須在伺服器上設,這樣豈不是要所有人都把自己的密碼告訴管理員嗎,畢竟很多人習慣於用同一個密碼的。怎麼辦呢?最好的辦法當然是能夠提供一個Web頁面來提供密碼的修改功能。

  說幹就幹,在網上查了一下,有一種方法是使用Serv-U自身提供的ODBC功能,用資料庫來儲存密碼,通過直接對資料庫進行操作來實現密碼的修改功能,但經過考試這種方法並不太可行。因為這個FTP伺服器已經運行了一年之久,裡面已有將近六十個使用者,要將這些使用者從Ini檔案移植到資料庫出現錯誤的幾率還是比較高的,還不如直接對INI檔案進行操作來得乾脆。

  首先是要搞清楚Serv-U的使用者資訊在INI檔案中是如何儲存的,密碼又是如何加密的。INI檔案的結構比較簡單,修改密碼的話只要找到以[User=@UserID|1]節,並修改其下的Password鍵的值即可。@UserID指的是使用者的登入ID。
 1[GLOBAL]
 2Version=6.1.0.5
 3PacketTimeOut=300
 4
 5
 6
 7[Domain1]
 8User1=
 9User2=
10User3=
11
12
13
14[USER=abc|1]
15Password=niE383DC3710266ECAE04A6B3A18A2966D
16HomeDir=D:\
17AlwaysAllowLogin=1
18ChangePassword=1
19TimeOut=600
20Note1="Wizard generated account"
21Access1=D:\
22
23

  使用者密碼的加密方法可以在Ser-U官方網站的知識庫查到

  http://rhinosoft.com/KBArticle.asp?RefNo=1177&prod=su
Manually Entering Encrypted Passwords into the ServUDaemon.ini File
To generate an encrypted password, first two random characters (the 'salt' - in the range a..z, A..Z) are added to the beginning of the clear-text password. This is then hashed using MD5 and the resulting hash is hex-encoded. The result of this is written as plain-text starting with the 2 salt characters followed by the hex-encoded hash.

For a user account in the .ini file, this will look like:

Password=cb644FB1F31184F8D3D169B54B3D46AB1A

The salt is the string "cb", the MD5 hash is "644FB1F31184F8D3D169B54B3D46AB1A".

When verifying a user's password, Serv-U will do the same. It parses the salt from the user's stored password (ie. "cb" in this case), prepends it the password the user sent to it by the client, MD5 hashes it, and compares the result with the stored hash. If the values are equal, then the entered password is correct.

  加密的方法也就是隨機產生兩個字母,然後將字母和密碼進行拼接,再求它們的MD5值,最後將隨機字母放在MD5值的前面便是加密後的密碼。

  接下來就可以根據以上的分析編寫程式來實現線上修改了。

  1        /**//// <summary>
  2        /// 擷取指定字串的MD5值
  3        /// </summary>
  4        /// <param name="strContent"></param>
  5        /// <returns></returns>
  6        public String MD5( String strContent )
  7        {
  8            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
  9            byte[] bytes = System.Text.Encoding.UTF8.GetBytes( strContent );
 10            bytes = md5.ComputeHash( bytes );
 11            md5.Clear();
 12            string ret = "";
 13            for(int i=0 ; i<bytes.Length ; i++)
 14            {
 15                ret += Convert.ToString(bytes[i],16).PadLeft(2,'0');
 16            }
 17            return ret.PadLeft(32,'0').ToUpper();
 18        }
 19
 20
 21        /**//// <summary>
 22        /// 產生隨便字串,字串長度為2
 23        /// </summary>
 24        /// <returns></returns>
 25        public string GetRandomString()
 26        {           
 27            string strReturn = "";
 28            Random ran = new Random();
 29            strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
 30            strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
 31            return strReturn;           
 32        }
 33
 34        //由指定的隨機字母和登入密碼產生加密後的密碼
 35        public string CreateCryPassword( string strFrontChars, string strPassword )
 36        {
 37            return strFrontChars + MD5( strFrontChars + strPassword ).ToUpper().Trim();
 38        }
 39
 40        /**//// <summary>
 41        /// “修改密碼”的點擊事件,在此事件中對密碼進行修改
 42        /// </summary>
 43        /// <param name="sender"></param>
 44        /// <param name="e"></param>
 45        private void btnModifyPwd_Click(object sender, System.EventArgs e)
 46        {
 47            string strUserID = txtLoginID.Text;
 48            if( strUserID == String.Empty )
 49            {
 50                controlMessage.InnerHtml = "使用者名稱不可為空";
 51                return;
 52            }
 53
 54            //判斷兩次密碼輸入是否相同
 55            if( txtNewPassword.Text != txtConfirmPassword.Text )
 56            {
 57                controlMessage.InnerHtml = "兩次輸入的密碼不一致,請重新輸入";
 58                return;
 59            }
 60
 61            IniFile ini = new IniFile( _strServUDaemonPath );
 62            string strSectionValue = "USER=" + strUserID.Trim() + "|1";
 63
 64            //通過讀取指定使用者的HomeDir來確定是否存在該使用者
 65            if( ini.ReadString( strSectionValue, "HomeDir", "" ) == "" )
 66            {
 67               controlMessage.InnerHtml = "指定的使用者不存在";
 68                return;
 69            }
 70
 71            //開始判斷密碼是否正確
 72            string strPassword = ini.ReadString( strSectionValue, "Password", "" );
 73
 74            string strPasswordFrontTwoChars;
 75            bool bPasswordRight = false;
 76            if( strPassword.Length > 2 )
 77            {
 78                //讀取密碼中包含的隨機字母
 79                strPasswordFrontTwoChars = strPassword.Substring( 0, 2 );
 80                if( CreateCryPassword( strPasswordFrontTwoChars, txtOldPassword.Text ) == strPassword )
 81                {//密碼符合
 82                    bPasswordRight = true;
 83                }
 84                else
 85                {//密碼不符
 86                    bPasswordRight = false;
 87                }
 88            }
 89            else if( strPassword == txtOldPassword.Text )  //原密碼為空白
 90            {
 91                bPasswordRight = true;
 92            }
 93            else
 94            {
 95                bPasswordRight = false;
 96            }
 97
 98            if( bPasswordRight )
 99            {
100                //密碼正確,寫入新的密碼,並設定自動載入新的設定,以便下一次更改時仍有效
101                ini.WriteString( strSectionValue, "Password", CreateCryPassword( GetRandomString(), txtNewPassword.Text ) );
102                            controlMessage.InnerHtml = "完成密碼修改";
103            }
104            else
105            {
106                controlMessage.InnerHtml = "原密碼錯誤";
107            }
108
109        } 

  以上代碼中的_strServUDaemonPath變數用於儲存ServUDaemon.ini檔案所在的路徑,該值可以在PageLoad事件中通過Web.Config設定取得。

  但事情並沒有就此結束。經過測試,發現在存在一個嚴重的問題:修改密碼後只有重啟Serv-U才能使修改後的密碼生效。那不是等於沒什麼用嘛,管理員總不可能沒事老在那裡重啟伺服器來使密碼修改生效吧。

  再次回來Serv-U的官方知識庫,查到了如下一條內容:

Manually Updating the ServUDaemon.ini File
Whenever changes are made directly to the ServUDaemon.ini file, add the following line under the Global area in the INI file.

ReloadSettings=True

Serv-U regularly checks the INI file for this setting. If it is present, Serv-U will refresh all stored settings for every domain on the server. This allows Serv-U to recognize the changes without having to be restarted.

After Serv-U loads the changes, it removes the "ReloadSettings=True" entry. This allows you to enter it again next time any changes are made.

  也就是說,只要在INI檔案的GLOBAL節添加鍵ReloadSettings並設定它的值為True便可以實現修改密碼後自動更新了。於是只要修改原代碼,在101行和102行之間插入如下一句代碼即可:

ini.WriteString( "GLOBAL", "ReloadSettings", "True" );

  到這裡,一個線上修改Serv-U密碼的網頁就全部完成了。

  程式中的IniFile是一個封裝了API對INI檔案操作的類,僅需要實現對字串的讀取和寫入即可。



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。