В связи с необходимостью повседневной работы подразделение использовало Serv-U для настройки FTP-сервера. Однако после вступления в должность было обнаружено, что существует очень серьезная проблема. Этот FTP-сервер был открыт для публики и многих пользователей. пароли не ставил. Если установка пароля обязательна для всех и он должен быть установлен на сервере, не означает ли это, что каждый должен сообщить администратору свой пароль? Ведь многие люди привыкли использовать один и тот же пароль? Что делать? Лучше всего, конечно, предоставить веб-страницу с функцией изменения пароля.
Просто проверьте это в Интернете.Один из методов — использовать функцию ODBC, предоставляемую самим Serv-U, использовать базу данных для хранения паролей и напрямую управлять базой данных для реализации функции изменения пароля. Однако после тестирования этого метода не очень. достижимый. Поскольку этот FTP-сервер работает уже год и на нем работает около 60 пользователей, вероятность ошибок при переносе этих пользователей из файла INI в базу данных все еще относительно высока. Проще работать с файлом INI напрямую.
Первым делом нужно разобраться, как информация о пользователе Serv-U сохраняется в INI-файле и как шифруется пароль. Структура INI-файла относительно проста. Чтобы изменить пароль, просто найдите раздел, начинающийся с [User=@UserID|1], и измените значение ключа пароля под ним. @UserID относится к идентификатору входа пользователя.
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
16HomeDir=D:
17AlwaysAllowLogin=1
18ИзменитьПароль=1
19TimeOut=600
20Note1="Учетная запись, созданная мастером"
21Access1=D:
двадцать два
двадцать три
Способ шифрования пароля пользователя можно найти в базе знаний официального сайта Ser-U.
http://rhinosoft.com/KBArticle.asp?RefNo=1177&prod=su
Ввод зашифрованных паролей вручную в файл ServUDaemon.ini
Чтобы сгенерировать зашифрованный пароль, первые два случайных символа («соль» — в диапазоне a..z, A..Z) добавляются в начало открытого пароля. Затем он хэшируется с использованием MD5 и полученного результата. Хэш имеет шестнадцатеричную кодировку. Результат записывается в виде обычного текста, начиная с двух символов соли, за которыми следует шестнадцатеричный хэш.
Для учетной записи пользователя в файле .ini это будет выглядеть так:
Пароль
=cb644FB1F31184F8D3D169B54B3D46AB1A
.это строка «cb», хэш MD5 — «644FB1F31184F8D3D169B54B3D46AB1A».
При проверке пароля пользователя Serv-U сделает то же самое. Он анализирует соль из сохраненного пароля пользователя (т. е. «cb» в данном случае), добавляет его в начало. Это пароль, который пользователь отправил ему клиентом, MD5 хэширует его и сравнивает результат с сохраненным хешем. Если значения равны, то введенный пароль правильный.
Метод шифрования состоит в том, чтобы случайным образом сгенерировать две буквы, затем объединить буквы и пароль, а затем найти их значения MD5. Наконец, поместите случайные буквы перед значением MD5, чтобы получить зашифрованный пароль.
Далее вы можете написать программу на основе приведенного выше анализа для реализации онлайн-модификации.
1 /**//// <сводка>
2 /// Получить значение MD5 указанной строки
3 /// </сводка>
4 /// <param name="strContent"></param>
5 /// <возвращается></возвращается>
6 общедоступная строка MD5 (String strContent)
7 {
8 System.Security.Cryptography.MD5 md5 = новый System.Security.Cryptography.MD5CryptoServiceProvider();
9 байт[] байт = System.Text.Encoding.UTF8.GetBytes(strContent);
10 байт = md5.ComputeHash(байты);
11 md5.Очистить();
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 Случайный запуск = новый Random();
29 strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
30 strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
31 возврат стрReturn;
32}
33
34 //Сгенерируем зашифрованный пароль из указанных случайных букв и пароля для входа
35 общедоступная строка CreateCryPassword(строка strFrontChars, строка strPassword)
36 {
37 return strFrontChars + MD5(strFrontChars + strPassword).ToUpper().Trim();
38 }
39
40 /**//// <сводка>
41 /// Нажмите событие «Изменить пароль», при котором пароль будет изменен.
42 /// </сводка>
43 /// <param name="sender"></param>
44 /// <param name="e"></param>
45 Private void btnModifyPwd_Click(отправитель объекта, System.EventArgs e)
46 {
47 строка strUserID = txtLoginID.Text;
48 if(strUserID == String.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, "Пароль", "" );
73
74 строка strPasswordFrontTwoChars;
75 bool bPasswordRight = ложь;
76 if(strPassword.Length > 2)
77 {
78 //Читаем случайные буквы, содержащиеся в пароле
79 strPasswordFrontTwoChars = strPassword.Substring(0, 2);
80 if( CreateCryPassword( strPasswordFrontTwoChars, txtOldPassword.Text ) == strPassword )
81 {//Пароль совпадений
82 bPasswordRight = правда;
83}
еще 84
85 {//Пароль не соответствует
86 bPasswordRight = ложь;
87 }
88}
89 else if( strPassword == txtOldPassword.Text) //Исходный пароль пуст
90 {
91 bPasswordRight = правда;
92 }
еще 93
94 {
95 bPasswordRight = ложь;
96 }
97
98, если (bPasswordRight)
99 {
100 //Пароль правильный, запишите новый пароль и настройте автоматическую загрузку новых настроек, чтобы они оставались действительными при следующем изменении.
101 ini.WriteString( strSectionValue, "Пароль", CreateCryPassword( GetRandomString(), txtNewPassword.Text ) );
102 controlMessage.InnerHtml = "Смена пароля завершена";
103}
еще 104
105 {
106 controlMessage.InnerHtml = «Исходный пароль неправильный»;
107 }
108
109 }
Переменная _strServUDaemonPath в приведенном выше коде используется для сохранения пути к файлу ServUDaemon.ini. Это значение можно получить с помощью параметра Web.Config в событии PageLoad.
Но на этом все не закончилось. После тестирования выяснилось, что существует серьезная проблема: после смены пароля только перезапуск Serv-U может изменить пароль. Не означает ли это, что это бесполезно? Администратор не всегда может перезагрузить сервер, чтобы смена пароля вступила в силу.
Вернувшись снова к официальной базе знаний Serv-U, я обнаружил следующее содержание:
Обновление файла ServUDaemon.ini вручную
Всякий раз, когда изменения вносятся непосредственно в файл ServUDaemon.ini, добавьте следующую строку в область Global в файле INI.
ReloadSettings=True
Serv-U регулярно проверяет файл INI на наличие этого параметра. Если он присутствует, Serv-U обновит его. все сохраненные настройки для каждого домена на сервере. Это позволяет Serv-U распознавать изменения без необходимости перезапуска.
После того, как Serv-U загружает изменения, он удаляет запись «ReloadSettings=True». Это позволяет вам ввести ее снова. в следующий раз, когда будут внесены какие-либо изменения.
Другими словами, если вы добавите ключ ReloadSettings в раздел GLOBAL файла INI и установите для него значение True, вы сможете автоматически обновлять пароль после его изменения. Поэтому просто измените исходный код и вставьте следующий код между строками 101 и 102:
ini.WriteString( "GLOBAL", "ReloadSettings", "True");
На этом веб-страница для онлайн-изменения пароля Serv-U готова.
IniFile в программе — это класс, инкапсулирующий работу API с INI-файлами. Ему нужно только реализовать чтение и запись строк.