程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 為Serv-U提供在線修改密碼功能

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

編輯:.NET實例教程

 由於日常工作的需要,單位使用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   &
nbsp;    /// </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 str
PassWordFrontTwoChars;
 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文件操作的類,僅需要實現對字符串的讀取和寫入即可。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved