* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Cedar / Sam.c
1 // SoftEther UT-VPN SourceCode\r
2 // \r
3 // Copyright (C) 2004-2010 SoftEther Corporation.\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.\r
6 // All Rights Reserved.\r
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \r
10 // This program is free software; you can redistribute it and/or\r
11 // modify it under the terms of the GNU General Public License\r
12 // version 2 as published by the Free Software Foundation.\r
13 // \r
14 // This program is distributed in the hope that it will be useful,\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
17 // GNU General Public License for more details.\r
18 // \r
19 // You should have received a copy of the GNU General Public License version 2\r
20 // along with this program; if not, write to the Free Software\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって\r
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // Sam.c\r
79 // セキュリティアカウントマネージャ\r
80 \r
81 // Windows NT の SAM を真似してかっこいい名前を付けてみたが、\r
82 // 実装してみると結局大した処理はしていない。\r
83 \r
84 #include "CedarPch.h"\r
85 \r
86 // パスワードの暗号化\r
87 void SecurePassword(void *secure_password, void *password, void *random)\r
88 {\r
89         BUF *b;\r
90         // 引数チェック\r
91         if (secure_password == NULL || password == NULL || random == NULL)\r
92         {\r
93                 return;\r
94         }\r
95 \r
96         b = NewBuf();\r
97         WriteBuf(b, password, SHA1_SIZE);\r
98         WriteBuf(b, random, SHA1_SIZE);\r
99         Hash(secure_password, b->Buf, b->Size, true);\r
100 \r
101         FreeBuf(b);\r
102 }\r
103 \r
104 // 160bit 乱数の生成\r
105 void GenRamdom(void *random)\r
106 {\r
107         // 引数チェック\r
108         if (random == NULL)\r
109         {\r
110                 return;\r
111         }\r
112 \r
113         Rand(random, SHA1_SIZE);\r
114 }\r
115 \r
116 // ユーザーの匿名認証\r
117 bool SamAuthUserByAnonymous(HUB *h, char *username)\r
118 {\r
119         bool b = false;\r
120         // 引数チェック\r
121         if (h == NULL || username == NULL)\r
122         {\r
123                 return false;\r
124         }\r
125 \r
126         AcLock(h);\r
127         {\r
128                 USER *u = AcGetUser(h, username);\r
129                 if (u)\r
130                 {\r
131                         Lock(u->lock);\r
132                         {\r
133                                 if (u->AuthType == AUTHTYPE_ANONYMOUS)\r
134                                 {\r
135                                         b = true;\r
136                                 }\r
137                         }\r
138                         Unlock(u->lock);\r
139                 }\r
140                 ReleaseUser(u);\r
141         }\r
142         AcUnlock(h);\r
143 \r
144         return b;\r
145 }\r
146 \r
147 // 指定した証明書を署名したルート証明書をリストから取得する\r
148 X *GetIssuerFromList(LIST *cert_list, X *cert)\r
149 {\r
150         UINT i;\r
151         X *ret = NULL;\r
152         // 引数チェック\r
153         if (cert_list == NULL || cert == NULL)\r
154         {\r
155                 return NULL;\r
156         }\r
157 \r
158         for (i = 0;i < LIST_NUM(cert_list);i++)\r
159         {\r
160                 X *x = LIST_DATA(cert_list, i);\r
161                 // 名前の比較\r
162                 if (CheckXDateNow(x))\r
163                 {\r
164                         if (CompareName(x->subject_name, cert->issuer_name))\r
165                         {\r
166                                 // ルート証明書の公開鍵を取得\r
167                                 K *k = GetKFromX(x);\r
168 \r
169                                 if (k != NULL)\r
170                                 {\r
171                                         // 署名のチェック\r
172                                         if (CheckSignature(cert, k))\r
173                                         {\r
174                                                 ret = x;\r
175                                         }\r
176                                         FreeK(k);\r
177                                 }\r
178                         }\r
179                 }\r
180                 if (CompareX(x, cert))\r
181                 {\r
182                         // 完全同一\r
183                         ret = x;\r
184                 }\r
185         }\r
186 \r
187         return ret;\r
188 }\r
189 \r
190 // ユーザーに適用されるべきポリシーを取得\r
191 POLICY *SamGetUserPolicy(HUB *h, char *username)\r
192 {\r
193         POLICY *ret = NULL;\r
194         // 引数チェック\r
195         if (h == NULL || username == NULL)\r
196         {\r
197                 return NULL;\r
198         }\r
199 \r
200         AcLock(h);\r
201         {\r
202                 USER *u;\r
203                 u = AcGetUser(h, username);\r
204                 if (u)\r
205                 {\r
206                         USERGROUP *g = NULL;\r
207                         Lock(u->lock);\r
208                         {\r
209                                 if (u->Policy != NULL)\r
210                                 {\r
211                                         ret = ClonePolicy(u->Policy);\r
212                                 }\r
213 \r
214                                 g = u->Group;\r
215 \r
216                                 if (g != NULL)\r
217                                 {\r
218                                         AddRef(g->ref);\r
219                                 }\r
220                         }\r
221                         Unlock(u->lock);\r
222 \r
223                         ReleaseUser(u);\r
224                         u = NULL;\r
225 \r
226                         if (ret == NULL)\r
227                         {\r
228                                 if (g != NULL)\r
229                                 {\r
230                                         Lock(g->lock);\r
231                                         {\r
232                                                 ret = ClonePolicy(g->Policy);\r
233                                         }\r
234                                         Unlock(g->lock);\r
235                                 }\r
236                         }\r
237 \r
238                         if (g != NULL)\r
239                         {\r
240                                 ReleaseGroup(g);\r
241                         }\r
242                 }\r
243         }\r
244         AcUnlock(h);\r
245 \r
246         return ret;\r
247 }\r
248 \r
249 // ユーザーのパスワード認証\r
250 bool SamAuthUserByPassword(HUB *h, char *username, void *random, void *secure_password)\r
251 {\r
252         bool b = false;\r
253         UCHAR secure_password_check[SHA1_SIZE];\r
254         // 引数チェック\r
255         if (h == NULL || username == NULL || secure_password == NULL)\r
256         {\r
257                 return false;\r
258         }\r
259 \r
260         if (StrCmpi(username, ADMINISTRATOR_USERNAME) == 0)\r
261         {\r
262                 // Administrator モード\r
263                 SecurePassword(secure_password_check, h->SecurePassword, random);\r
264                 if (Cmp(secure_password_check, secure_password, SHA1_SIZE) == 0)\r
265                 {\r
266                         return true;\r
267                 }\r
268                 else\r
269                 {\r
270                         return false;\r
271                 }\r
272         }\r
273 \r
274         AcLock(h);\r
275         {\r
276                 USER *u;\r
277                 u = AcGetUser(h, username);\r
278                 if (u)\r
279                 {\r
280                         Lock(u->lock);\r
281                         {\r
282                                 if (u->AuthType == AUTHTYPE_PASSWORD)\r
283                                 {\r
284                                         AUTHPASSWORD *auth = (AUTHPASSWORD *)u->AuthData;\r
285                                         SecurePassword(secure_password_check, auth->HashedKey, random);\r
286                                         if (Cmp(secure_password_check, secure_password, SHA1_SIZE) == 0)\r
287                                         {\r
288                                                 b = true;\r
289                                         }\r
290                                 }\r
291                         }\r
292                         Unlock(u->lock);\r
293                         ReleaseUser(u);\r
294                 }\r
295         }\r
296         AcUnlock(h);\r
297 \r
298         return b;\r
299 }\r
300 \r
301 // ユーザーが存在することを確認\r
302 bool SamIsUser(HUB *h, char *username)\r
303 {\r
304         bool b;\r
305         // 引数チェック\r
306         if (h == NULL || username == NULL)\r
307         {\r
308                 return false;\r
309         }\r
310 \r
311         AcLock(h);\r
312         {\r
313                 b = AcIsUser(h, username);\r
314         }\r
315         AcUnlock(h);\r
316 \r
317         return b;\r
318 }\r
319 \r
320 // ユーザーが使用する認証の種類を取得\r
321 UINT SamGetUserAuthType(HUB *h, char *username)\r
322 {\r
323         UINT authtype;\r
324         // 引数チェック\r
325         if (h == NULL || username == NULL)\r
326         {\r
327                 return INFINITE;\r
328         }\r
329 \r
330         AcLock(h);\r
331         {\r
332                 USER *u = AcGetUser(h, username);\r
333                 if (u == NULL)\r
334                 {\r
335                         authtype = INFINITE;\r
336                 }\r
337                 else\r
338                 {\r
339                         authtype = u->AuthType;\r
340                         ReleaseUser(u);\r
341                 }\r
342         }\r
343         AcUnlock(h);\r
344 \r
345         return authtype;\r
346 }\r
347 \r