일상 업무의 필요로 인해 Serv-U를 사용하여 FTP 서버를 설정했지만 인수 후 이 FTP 서버가 대중에게 공개되었으며 많은 사용자가 있다는 사실이 발견되었습니다. 비밀번호를 설정하지 않았습니다. 모든 사람이 비밀번호를 설정하는 것이 필수이고 이를 서버에 설정해야 한다면 결국 모든 사람이 관리자에게 비밀번호를 알려주어야 한다는 뜻이 아니겠습니까? 무엇을 해야 할까요? 물론 가장 좋은 방법은 비밀번호 수정 기능을 제공하는 웹 페이지를 제공하는 것입니다.
일단 온라인으로 확인해 보세요. Serv-U 자체에서 제공하는 ODBC 기능을 사용하고, 데이터베이스를 이용하여 비밀번호를 저장하고, 데이터베이스를 직접 조작하여 비밀번호 수정 기능을 구현하는 방법도 있습니다. 실행할 수 있는. 이 FTP 서버는 1년 동안 운영되었으며 거의 60명의 사용자가 있기 때문에 이러한 사용자를 INI 파일에서 데이터베이스로 이식할 때 오류가 발생할 가능성은 여전히 상대적으로 높습니다. INI 파일을 직접 조작하는 것이 더 쉽습니다.
먼저 INI 파일에 Serv-U의 사용자 정보가 어떻게 저장되는지, 비밀번호가 어떻게 암호화되는지를 파악하는 것입니다. INI 파일의 구조는 비교적 간단합니다. 비밀번호를 수정하려면 [User=@UserID|1]로 시작하는 섹션을 찾아 그 아래의 비밀번호 키 값을 수정하면 됩니다. @UserID는 사용자의 로그인 ID를 나타냅니다.
1[글로벌]
2버전=6.1.0.5
3PacketTimeOut=300
4
5
6
7[도메인1]
8사용자1=
9사용자2=
10사용자3=
11
12
13
14[사용자=abc|1]
15비밀번호=niE383DC3710266ECAE04A6B3A18A2966D
16홈디렉터리=D:
17AlwaysAllowLogin=1
18비밀번호 변경=1
19타임아웃=600
20Note1="마법사 생성 계정"
21액세스1=D:
스물 둘
스물셋
사용자 비밀번호의 암호화 방법은 Ser-U 공식 홈페이지 지식베이스에서 확인하실 수 있습니다.
http://rhinosoft.com/KBArticle.asp?RefNo=1177&prod=su
ServUDaemon.ini 파일에 암호화된 암호를 수동으로 입력
암호화된 비밀번호를 생성하려면 처음 두 개의 임의 문자(a..z, A..Z 범위의 'salt')가 일반 텍스트 비밀번호의 시작 부분에 추가된 다음 MD5를 사용하여 해시되고 결과가 생성됩니다. 해시는 16진수로 인코딩됩니다. 이 결과는 2개의 솔트 문자로 시작하고 그 뒤에 16진수로 인코딩된 해시가 오는 일반 텍스트로 작성됩니다.
.ini
파일
의 사용자 계정은 다음과 같습니다.
문자열은 "cb"이고 MD5 해시는 "644FB1F31184F8D3D169B54B3D46AB1A"입니다.
사용자의 비밀번호를 확인할 때 Serv-U는 사용자의 저장된 비밀번호(예: 이 경우 "cb")에서 솔트를 구문 분석하고 앞에 추가합니다. 이는 클라이언트가 사용자에게 보낸 비밀번호이며, MD5는 이를 해시하고 그 결과를 저장된 해시와 비교합니다. 값이 동일하면 입력한 비밀번호가 올바른 것입니다.
암호화 방법은 두 글자를 무작위로 생성한 뒤, 그 글자와 비밀번호를 이어붙여 해당 MD5 값을 찾는 것이다. 마지막으로 MD5 값 앞에 무작위 문자를 넣어 암호화된 비밀번호를 얻는다.
다음으로, 위의 분석을 기반으로 온라인 수정을 구현하는 프로그램을 작성할 수 있습니다.
1 /**//// <요약>
2 /// 지정된 문자열의 MD5 값을 가져옵니다.
3 /// </summary>
4 /// <param name="strContent"></param>
5 /// <반환></반환>
6 공개 문자열 MD5(문자열 strContent)
7 {
8 System.Security.Cryptography.MD5 md5 = 새로운 System.Security.Cryptography.MD5CryptoServiceProvider();
9바이트[]바이트 = System.Text.Encoding.UTF8.GetBytes( strContent );
10바이트 = md5.ComputeHash(바이트);
11 md5.Clear();
12 문자열 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 /**//// <요약>
22 /// 임의의 문자열을 생성합니다. 문자열의 길이는 2입니다.
23 /// </summary>
24 /// <반환></반환>
25 공개 문자열 GetRandomString()
26 {
27 문자열 strReturn = "";
28 무작위 실행 = new Random();
29 strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
30 strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
31 반환 strReturn;
32}
33
34 //지정된 임의의 문자와 로그인 비밀번호로 암호화된 비밀번호를 생성합니다.
35 공개 문자열 CreateCryPassword( 문자열 strFrontChars, 문자열 strPassword)
36 {
37 return strFrontChars + MD5( strFrontChars + strPassword ).ToUpper().Trim();
38 }
39
40 /**//// <요약>
41 /// 비밀번호가 변경되는 "비밀번호 변경" 이벤트를 클릭합니다.
42 /// </summary>
43 /// <param name="sender"></param>
44 /// <param name="e"></param>
45 개인 무효 btnModifyPwd_Click(개체 전송자, System.EventArgs e)
46 {
47 문자열 strUserID = txtLoginID.Text;
48 if(strUserID == 문자열.Empty)
49 {
50 controlMessage.InnerHtml = "사용자 이름은 비워둘 수 없습니다.";
51 반환;
52 }
53
54 //두 개의 비밀번호 입력이 동일한지 확인
55 if( txtNewPassword.Text != txtConfirmPassword.Text )
56 {
57 controlMessage.InnerHtml = "두 번 입력한 비밀번호가 일치하지 않습니다. 다시 입력하십시오.";
58 반환;
59 }
60
61 IniFile ini = 새 IniFile( _strServUDaemonPath );
62 문자열 strSectionValue = "USER=" + strUserID.Trim() + "|1";
63
64 //지정된 사용자의 HomeDir을 읽어 해당 사용자가 존재하는지 확인
65 if( ini.ReadString( strSectionValue, "HomeDir", "" ) == "" )
66 {
67 controlMessage.InnerHtml = "지정된 사용자가 존재하지 않습니다.";
68 반환;
69 }
70
71 //비밀번호가 올바른지 확인하기 시작합니다.
72 문자열 strPassword = ini.ReadString( strSectionValue, "Password", "" );
73
74 문자열 strPasswordFrontTwoChars;
75 bool bPasswordRight = false;
76 if(strPassword.길이 > 2)
77 {
78 //비밀번호에 포함된 임의의 문자를 읽습니다.
79 strPasswordFrontTwoChars = strPassword.Substring(0, 2);
80 if( CreateCryPassword( strPasswordFrontTwoChars, txtOldPassword.Text ) == strPassword )
81 {//비밀번호 일치
82 bPasswordRight = true;
83}
그 외 84개
85 {//비밀번호가 일치하지 않습니다
86 bPasswordRight = 거짓;
87 }
88}
89 else if( strPassword == txtOldPassword.Text) //원래 비밀번호가 비어 있습니다.
90 {
91 bPasswordRight = true;
92 }
그 외 93개
94 {
95 bPasswordRight = 거짓;
96 }
97
98 if( bPasswordRight )
99 {
100 //비밀번호가 정확합니다. 새 비밀번호를 입력하고, 다음에 변경해도 여전히 유효하도록 새 설정을 자동으로 로드하도록 설정하세요.
101 ini.WriteString( strSectionValue, "Password", CreateCryPassword( GetRandomString(), txtNewPassword.Text ) );
102 controlMessage.InnerHtml = "비밀번호 변경 완료";
103}
그 외 104개
105 {
106 controlMessage.InnerHtml = "원래 비밀번호가 잘못되었습니다.";
107 }
108
109 }
위 코드의 _strServUDaemonPath 변수는 ServUDaemon.ini 파일이 있는 경로를 저장하는 데 사용됩니다. 이 값은 PageLoad 이벤트의 Web.Config 설정을 통해 얻을 수 있습니다.
하지만 거기서 끝나지 않았습니다. 테스트 결과 심각한 문제가 있는 것으로 확인되었습니다. 비밀번호를 변경한 후 Serv-U를 다시 시작해야만 변경된 비밀번호가 적용됩니다. 이것이 쓸모없다는 뜻이 아닌가요? 관리자가 비밀번호 변경 사항을 적용하기 위해 항상 서버를 다시 시작할 수는 없습니다.
다시 Serv-U의 공식 지식 베이스로 돌아가서 다음 내용을 발견했습니다.
ServUDaemon.ini 파일 수동 업데이트
ServUDaemon.ini 파일을 직접 변경할 때마다 INI 파일의 전역 영역 아래에 다음 줄을 추가합니다.
ReloadSettings=True
Serv-U는 INI 파일에 이 설정이 있는지 정기적으로 확인합니다. 이를 통해 Serv-U는 다시 시작하지 않고도 변경 사항을 인식할 수 있으며
, "ReloadSettings=True" 항목을 제거합니다. 다음에 변경사항이 있을 때
즉, INI 파일의 GLOBAL 섹션에 ReloadSettings 키를 추가하고 해당 값을 True로 설정하면 비밀번호를 변경한 후 자동으로 비밀번호를 업데이트할 수 있습니다. 따라서 원래 코드를 수정하고 101행과 102행 사이에 다음 코드를 삽입하십시오.
ini.WriteString( "GLOBAL", "ReloadSettings", "True" );
이제 Serv-U 비밀번호를 온라인으로 변경할 수 있는 웹페이지가 완성되었습니다.
프로그램의 IniFile은 INI 파일에 대한 API 작업을 캡슐화하는 클래스입니다. 문자열 읽기 및 쓰기만 구현하면 됩니다.