Karena kebutuhan pekerjaan sehari-hari, unit menggunakan Serv-U untuk menyiapkan server FTP. Namun setelah diambil alih, ditemukan adanya masalah yang sangat serius. Server FTP ini terbuka untuk umum dan banyak pengguna tidak mengatur kata sandi. Jika setiap orang wajib menyetel kata sandi dan harus disetel di server, bukankah berarti setiap orang harus memberi tahu administrator kata sandinya? Apa yang harus dilakukan? Cara terbaik tentu saja menyediakan halaman Web untuk menyediakan fungsi modifikasi kata sandi.
Silakan saja dan periksa secara online. Salah satu caranya adalah dengan menggunakan fungsi ODBC yang disediakan oleh Serv-U itu sendiri, menggunakan database untuk menyimpan kata sandi, dan langsung mengoperasikan database untuk mewujudkan fungsi modifikasi kata sandi bisa dilakukan. Karena server FTP ini telah berjalan selama satu tahun dan memiliki hampir 60 pengguna di dalamnya, kemungkinan kesalahan saat memindahkan pengguna tersebut dari file INI ke database masih relatif tinggi.
Hal pertama adalah mencari tahu bagaimana informasi pengguna Serv-U disimpan dalam file INI dan bagaimana kata sandi dienkripsi. Struktur file INI relatif sederhana. Untuk mengubah kata sandi, cukup temukan bagian yang dimulai dengan [User=@UserID|1] dan ubah nilai kunci Kata Sandi di bawahnya. @UserID mengacu pada ID login pengguna.
1[GLOBAL]
2Versi=6.1.0.5
3PacketTimeOut=300
4
5
6
7[Domain1]
8Pengguna1=
9Pengguna2=
10Pengguna3=
11
12
13
14[PENGGUNA=abc|1]
15Kata Sandi=niE383DC3710266ECAE04A6B3A18A2966D
16RumahDir=D:
17SelaluIzinkanLogin=1
18Ubah Kata Sandi=1
19Waktu Habis=600
20Note1="Akun yang dibuat oleh Wizard"
21Akses1=D:
dua puluh dua
dua puluh tiga
Metode enkripsi kata sandi pengguna dapat ditemukan di basis pengetahuan situs resmi Ser-U
http://rhinosoft.com/KBArticle.asp?RefNo=1177&prod=su
Memasukkan Kata Sandi Terenkripsi secara Manual ke dalam File ServUDaemon.ini
Untuk menghasilkan kata sandi terenkripsi, dua karakter acak pertama ('garam' - dalam rentang a..z, A..Z) ditambahkan ke awal kata sandi teks biasa. Ini kemudian di-hash menggunakan MD5 dan hasilnya hash dikodekan hex. Hasilnya ditulis sebagai teks biasa yang dimulai dengan 2 karakter garam diikuti dengan hash yang dikodekan hex.
Untuk akun pengguna di file .ini, ini akan terlihat seperti:
Kata Sandi=cb644FB1F31184F8D3D169B54B3D46AB1A
Garamnya. adalah string "cb", hash MD5 adalah "644FB1F31184F8D3D169B54B3D46AB1A".
Saat memverifikasi kata sandi pengguna, Serv-U akan melakukan hal yang sama. Ini mem-parsing garam dari kata sandi yang disimpan pengguna (mis. "cb" dalam kasus ini), ditambahkan di awal itu kata sandi yang dikirimkan pengguna kepadanya oleh klien, MD5 melakukan hash, dan membandingkan hasilnya dengan hash yang disimpan. Jika nilainya sama, maka kata sandi yang dimasukkan benar.
Metode enkripsinya adalah dengan menghasilkan dua huruf secara acak, kemudian menggabungkan huruf dan kata sandinya, lalu mencari nilai MD5-nya, terakhir, letakkan huruf acak tersebut di depan nilai MD5 untuk mendapatkan kata sandi terenkripsi.
Selanjutnya, Anda dapat menulis program berdasarkan analisis di atas untuk mengimplementasikan modifikasi online.
1 /**//// <ringkasan>
2 /// Dapatkan nilai MD5 dari string yang ditentukan
3 /// </ringkasan>
4 /// <param nama="strContent"></param>
5 /// <pengembalian></pengembalian>
6 String publik MD5(String strContent)
7 {
8 Sistem.Keamanan.Kriptografi.MD5 md5 = Sistem.Keamanan.Kriptografi.MD5CryptoServiceProvider() baru;
9 byte[] byte = System.Text.Encoding.UTF8.GetBytes( strContent );
10 byte = md5.ComputeHash( byte );
11 md5.Hapus();
12 senar ret = "";
13 for(int i=0; i<byte.Panjang; i++)
14 {
15 ret += Konversi.ToString(byte[i],16).PadLeft(2,'0');
16}
17 kembali ret.PadLeft(32,'0').ToUpper();
18}
19
20
21 /**//// <ringkasan>
22 /// Hasilkan string acak, panjang string adalah 2
23 /// </ringkasan>
24 /// <pengembalian></pengembalian>
25 string publik GetRandomString()
26 {
27 senar strReturn = "";
28 Lari acak = acak baru();
29 strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
30 strReturn += Convert.ToChar( ran.Next( 26 ) + 'a' ).ToString();
31 kembalikan strKembali;
32}
33
34 //Buat kata sandi terenkripsi dari huruf acak dan kata sandi login yang ditentukan
35 string publik CreateCryPassword( string strFrontChars, string strPassword)
36 {
37 kembalikan strFrontChars + MD5( strFrontChars + strPassword ).ToUpper().Trim();
38 }
39
40 /**//// <ringkasan>
41 /// Klik acara "Ubah Kata Sandi", di mana kata sandi diubah.
42 /// </ringkasan>
43 /// <param nama="pengirim"></param>
44 /// <param nama="e"></param>
45 private void btnModifyPwd_Click(pengirim objek, System.EventArgs e)
46 {
47 string strUserID = txtLoginID.Teks;
48 if(strUserID == String.Kosong)
49 {
50 controlMessage.InnerHtml = "Nama pengguna tidak boleh kosong";
51 kembali;
52 }
53
54 //Tentukan apakah kedua masukan kata sandi itu sama
55 jika( txtNewPassword.Teks != txtConfirmPassword.Teks )
56 {
57 controlMessage.InnerHtml = "Kata sandi yang dimasukkan dua kali tidak konsisten, silakan masukkan kembali";
58 kembali;
59 }
60
61 IniFile ini = IniFile baru( _strServUDaemonPath );
62 string strSectionValue = "USER=" + strUserID.Trim() + "|1";
63
64 //Tentukan apakah pengguna tersebut ada dengan membaca HomeDir dari pengguna yang ditentukan
65 if( ini.ReadString( strSectionValue, "HomeDir", "" ) == "" )
66 {
67 controlMessage.InnerHtml = "Pengguna yang ditentukan tidak ada";
68 kembali;
69 }
70
71 //Mulai menentukan apakah kata sandinya benar
72 string strPassword = ini.ReadString( strSectionValue, "Kata Sandi", "" );
73
74 string strPasswordFrontTwoChars;
75 bool bPasswordRight = salah;
76 if(strPassword.Panjang > 2)
77 {
78 //Baca huruf acak yang terdapat pada kata sandi
79 strPasswordFrontTwoChars = strPassword.Substring(0, 2);
80 jika( CreateCryPassword( strPasswordFrontTwoChars, txtOldPassword.Text ) == strPassword )
81 {//Kata sandi cocok
82 bPasswordKanan = benar;
83}
84 lainnya
85 {//Kata sandi tidak cocok
86 bPasswordKanan = salah;
87 }
88}
89 else if( strPassword == txtOldPassword.Text) //Password asli kosong
90 {
91 bPasswordKanan = benar;
92 }
93 lainnya
94 {
95 bPasswordKanan = salah;
96 }
97
98 jika( bPasswordKanan )
99 {
100 //Kata sandi benar, tulis kata sandi baru, dan atur untuk memuat pengaturan baru secara otomatis sehingga akan tetap valid saat diubah lagi.
101 ini.WriteString( strSectionValue, "Kata Sandi", CreateCryPassword( GetRandomString(), txtNewPassword.Text ) );
102 controlMessage.InnerHtml = "Pengubahan kata sandi selesai";
103}
104 lainnya
105 {
106 controlMessage.InnerHtml = "Kata sandi asli salah";
107 }
108
109 }
Variabel _strServUDaemonPath pada kode di atas digunakan untuk menyimpan path dimana file ServUDaemon.ini berada. Nilai ini dapat diperoleh melalui setting Web.Config pada event PageLoad.
Tapi itu tidak berakhir di situ. Setelah pengujian, ditemukan bahwa ada masalah serius: setelah mengubah kata sandi, hanya dengan memulai ulang Serv-U, kata sandi yang diubah dapat diterapkan. Bukankah itu berarti tidak ada gunanya? Administrator tidak selalu bisa me-restart server agar perubahan kata sandi diterapkan.
Kembali ke basis pengetahuan resmi Serv-U lagi, saya menemukan konten berikut:
Memperbarui File ServUDaemon.ini secara Manual
Setiap kali perubahan dilakukan langsung pada berkas ServUDaemon.ini, tambahkan baris berikut di bawah area Global dalam berkas INI.
ReloadSettings=True
Serv-U secara teratur memeriksa berkas INI untuk pengaturan ini semua pengaturan tersimpan untuk setiap domain di server. Hal ini memungkinkan Serv-U mengenali perubahan tanpa harus di-restart.
Setelah Serv-U memuat perubahan, entri "ReloadSettings=True" akan dihapus lain kali ada perubahan yang dilakukan.
Dengan kata lain, selama Anda menambahkan kunci ReloadSettings di bagian GLOBAL file INI dan menetapkan nilainya ke True, Anda dapat memperbarui kata sandi secara otomatis setelah mengubahnya. Jadi modifikasi saja kode aslinya dan masukkan kode berikut di antara baris 101 dan 102:
ini.WriteString( "GLOBAL", "ReloadSettings", "Benar" );
Sampai di sini, halaman web untuk mengubah kata sandi Serv-U secara online telah selesai.
IniFile dalam program ini adalah kelas yang merangkum operasi API pada file INI. Ia hanya perlu mengimplementasikan pembacaan dan penulisan string.