source: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.7 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
8 * によって公表されている GNU General Public License の Version 2 に記
9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
11 * 利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次の条件を満たすこと.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 *
26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
30 *
31 * @(#) $Id$
32 */
33
34/*
35 * upap.c - User/Password Authentication Protocol.
36 *
37 * Copyright (c) 1989 Carnegie Mellon University.
38 * All rights reserved.
39 *
40 * Redistribution and use in source and binary forms are permitted
41 * provided that the above copyright notice and this paragraph are
42 * duplicated in all such forms and that any documentation,
43 * advertising materials, and other materials related to such
44 * distribution and use acknowledge that the software was developed
45 * by Carnegie Mellon University. The name of the
46 * University may not be used to endorse or promote products derived
47 * from this software without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
49 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
50 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
51 */
52
53/*
54 * PPP PAP Module
55 *
56 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
57 *
58 * Copyright (C) 1993-94, Internet Initiative Japan, Inc.
59 * All rights reserverd.
60 *
61 * Redistribution and use in source and binary forms are permitted
62 * provided that the above copyright notice and this paragraph are
63 * duplicated in all such forms and that any documentation,
64 * advertising materials, and other materials related to such
65 * distribution and use acknowledge that the software was developed
66 * by the Internet Initiative Japan, Inc. The name of the
67 * IIJ may not be used to endorse or promote products derived
68 * from this software without specific prior written permission.
69 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
70 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
71 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
72 *
73 * $FreeBSD: src/usr.sbin/ppp/pap.c,v 1.42.2.1 2000/08/19 09:30:05 brian Exp $
74 *
75 * TODO:
76 */
77
78#include <string.h>
79
80#include <s_services.h>
81#include <t_services.h>
82
83#include <tinet_defs.h>
84#include <tinet_config.h>
85
86#include <net/if.h>
87#include <net/if_ppp.h>
88#include <net/net.h>
89#include <net/net_buf.h>
90#include <net/net_timer.h>
91#include <net/net_count.h>
92#include <net/ppp.h>
93#include <net/ppp_var.h>
94#include <net/ppp_hdlc.h>
95#include <net/ppp_auth.h>
96#include <net/ppp_fsm.h>
97#include <net/ppp_lcp.h>
98#include <net/ppp_upap.h>
99
100#ifdef SUPPORT_PPP
101
102/*
103 * 関数
104 */
105
106static void upap_init (void);
107static void upap_input (T_NET_BUF *input);
108static void upap_protrej (void);
109static void upap_lowerup (void);
110static void upap_lowerdown (void);
111static bool_t compare (uint8_t *rstr, uint8_t *lstr, uint8_t rlen);
112
113#ifdef AUTH_CFG_CLIENT
114
115static void upap_sauthreq (void);
116static void upap_rauthack (void);
117static void upap_rauthnak (void);
118
119#if defined(DEF_PAP_TIMEOUT)
120
121static void upap_timeout(void *arg);
122
123#endif /* of #if defined(DEF_PAP_TIMEOUT) */
124
125#endif /* of #ifdef AUTH_CFG_CLIENT */
126
127#ifdef AUTH_CFG_SERVER
128
129static void upap_rauthreq (T_NET_BUF *input);
130static void upap_sresp (uint8_t code, uint8_t id);
131
132#if defined(DEF_PAP_REQTIME)
133
134static void upap_reqtimeout(void *arg);
135
136#endif /* of #if defined(DEF_PAP_REQTIME) */
137
138#endif /* of #ifdef AUTH_CFG_SERVER */
139
140/*
141 * 全域変数
142 */
143
144T_PPP_PROTENT pap_protent = {
145 PPP_PAP,
146 upap_init, /* 初期化 */
147 upap_input, /* 入力 */
148 upap_protrej, /* Proto-REJ 受信処理 */
149 upap_lowerup, /* 下位層を起動する */
150 upap_lowerdown, /* 下位層を停止する */
151 NULL, /* オープンする */
152 NULL, /* クローズする */
153 NULL, /* データ入力 */
154 };
155
156/*
157 * 変数
158 */
159
160#ifdef AUTH_CFG_CLIENT
161
162static uint8_t client_state;
163static uint8_t client_cp_id;
164
165#if defined(DEF_PAP_TIMEOUT)
166
167static uint8_t client_rexmt = 0;
168
169#endif /* of #if defined(DEF_PAP_TIMEOUT) */
170
171#endif /* of #ifdef AUTH_CFG_CLIENT */
172
173#ifdef AUTH_CFG_SERVER
174
175static uint8_t server_state;
176
177#endif /* of #ifdef AUTH_CFG_SERVER */
178
179/*
180 * upap_init -- UPAP モジュールの初期化
181 */
182
183static void
184upap_init (void)
185{
186#ifdef AUTH_CFG_CLIENT
187
188 client_cp_id = 0;
189 client_state = PAP_CS_INIT;
190
191#endif /* of #ifdef AUTH_CFG_CLIENT */
192
193#ifdef AUTH_CFG_SERVER
194
195 server_state = PAP_SS_INIT;
196
197#endif /* of #ifdef AUTH_CFG_SERVER */
198 }
199
200/*
201 * upap_input -- UPAP 入力
202 */
203
204static void
205upap_input (T_NET_BUF *input)
206{
207 T_PPP_CP_HDR *hdr;
208
209 NET_COUNT_PPP_PAP(net_count_ppp_upap_in_octets, input->len);
210 NET_COUNT_PPP_PAP(net_count_ppp_upap_in_packets, 1);
211
212 /* PPP リンク制御 (CP) ヘッダより短ければエラー */
213 if (input->len < (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))) {
214 syslog(LOG_WARNING, "[PPP/PAP] short hdr: %d.", input->len);
215 return;
216 }
217
218 hdr = GET_PPP_CP_HDR(input);
219
220 /* ヘッダの長さと入力データサイズが一致しなければエラー */
221 if (hdr->len != input->len - sizeof(T_PPP_HDR)) {
222 syslog(LOG_WARNING, "[PPP/PAP] bad len: %d.", hdr->len);
223 return;
224 }
225
226 /*
227 * 制御コードにより適当な関数を呼出す
228 */
229
230 switch (hdr->code) {
231
232#ifdef AUTH_CFG_CLIENT
233
234 case PAP_AUTHACK:
235 upap_rauthack();
236 break;
237
238 case PAP_AUTHNAK:
239 upap_rauthnak();
240 break;
241
242#endif /* of #ifdef AUTH_CFG_CLIENT */
243
244#ifdef AUTH_CFG_SERVER
245
246 case PAP_AUTHREQ:
247 upap_rauthreq(input);
248 break;
249
250#endif /* of #ifdef AUTH_CFG_SERVER */
251
252 }
253 }
254
255/*
256 * upap_protrej -- Proto-REJ を受信したときの処理
257 */
258
259static void
260upap_protrej (void)
261{
262#ifdef AUTH_CFG_CLIENT
263
264 if (client_state == PAP_CS_AUTHREQ)
265 syslog(LOG_WARNING, "[PPP/PAP] proto-rej recved.");
266
267#endif /* of #ifdef AUTH_CFG_CLIENT */
268
269#ifdef AUTH_CFG_SERVER
270
271 if (server_state == PAP_SS_LISTEN) {
272 syslog(LOG_WARNING, "[PPP/PAP] proto-rej recved.");
273 lcp_close();
274 }
275
276#endif /* of #ifdef AUTH_CFG_SERVER */
277
278 upap_lowerdown();
279 }
280
281/*
282 * upap_lowerup -- UPAP 下位層を起動する。
283 */
284
285static void
286upap_lowerup (void)
287{
288#ifdef AUTH_CFG_CLIENT
289
290 if (client_state == PAP_CS_INIT)
291 client_state = PAP_CS_CLOSED;
292 else if (client_state == PAP_CS_PENDING)
293 upap_sauthreq();
294
295#endif /* of #ifdef AUTH_CFG_CLIENT */
296
297#ifdef AUTH_CFG_SERVER
298
299 if (server_state == PAP_SS_INIT)
300 server_state = PAP_SS_CLOSED;
301 else if (server_state == PAP_SS_PENDING) {
302 server_state = PAP_SS_LISTEN;
303
304#if defined(DEF_PAP_REQTIME)
305
306 timeout((FP)upap_reqtimeout, NULL, DEF_PAP_REQTIME);
307
308#endif /* of #if defined(DEF_PAP_REQTIME) */
309
310 }
311
312#endif /* of #ifdef AUTH_CFG_SERVER */
313 }
314
315/*
316 * upap_lowerdown -- UPAP 下位層を停止する。
317 */
318
319static void
320upap_lowerdown (void)
321{
322#ifdef AUTH_CFG_CLIENT
323
324#if defined(DEF_PAP_TIMEOUT)
325
326 if (client_state == PAP_CS_AUTHREQ)
327 untimeout((FP)upap_timeout, NULL);
328
329#endif /* of #if defined(DEF_PAP_TIMEOUT) */
330
331 client_state = PAP_CS_INIT;
332
333#endif /* of #ifdef AUTH_CFG_CLIENT */
334
335#ifdef AUTH_CFG_SERVER
336
337#if defined(DEF_PAP_REQTIME)
338
339 if (server_state == PAP_SS_LISTEN)
340 untimeout((FP)upap_reqtimeout, NULL);
341
342#endif /* of #if defined(DEF_PAP_REQTIME) */
343
344 server_state = PAP_SS_INIT;
345
346#endif /* of #ifdef AUTH_CFG_SERVER */
347 }
348#ifdef AUTH_CFG_CLIENT
349
350/*
351 * クライアントモードで PAP 認証を開始する。
352 */
353
354void
355upap_auth_client (void)
356{
357#if defined(DEF_PAP_TIMEOUT)
358
359 client_rexmt = 0;
360
361#endif /* of #if defined(DEF_PAP_TIMEOUT) */
362
363 if (client_state == PAP_CS_INIT || client_state == PAP_CS_PENDING) {
364 client_state = PAP_CS_PENDING;
365 return;
366 }
367
368 upap_sauthreq();
369 }
370
371/*
372 * upap_rauthack -- 認証 ACK 処理
373 */
374
375static void
376upap_rauthack (void)
377{
378 if (client_state == PAP_CS_AUTHREQ) {
379 client_state = PAP_CS_OPEN;
380 network_phase();
381 }
382 }
383
384/*
385 * upap_rauthnak -- 認証 NAK 処理
386 */
387
388static void
389upap_rauthnak (void)
390{
391 syslog(LOG_WARNING, "[PPP/PAP] auth-req NAKed.");
392 client_state = PAP_CS_BADAUTH;
393 }
394
395/*
396 * upap_sauthreq -- 認証要求処理
397 */
398
399static void
400upap_sauthreq (void)
401{
402 T_NET_BUF *output;
403 uint8_t *data;
404
405 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)
406 + sizeof(AUTH_REMOTE_USER) + sizeof(AUTH_REMOTE_PASSWD)));
407
408 data = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
409
410 /* ユーザ名を設定する。*/
411 *data = sizeof(AUTH_REMOTE_USER) - 1;
412 strcpy(data + 1, AUTH_REMOTE_USER);
413
414 /* パスワードを設定する。*/
415 *(data + sizeof(AUTH_REMOTE_USER)) = sizeof(AUTH_REMOTE_PASSWD) - 1;
416 strcpy(data + sizeof(AUTH_REMOTE_USER) + 1, AUTH_REMOTE_PASSWD);
417
418 /* 送信する */
419 IF_SET_PROTO(output, PPP_PAP);
420 ppp_cp_output(PAP_AUTHREQ, ++ client_cp_id, output);
421
422#if defined(DEF_PAP_TIMEOUT)
423
424 timeout((FP)upap_timeout, NULL, DEF_PAP_TIMEOUT);
425 client_rexmt ++;
426
427#endif /* of #if defined(DEF_PAP_TIMEOUT) */
428
429 client_state = PAP_CS_AUTHREQ;
430 }
431
432#if defined(DEF_PAP_TIMEOUT)
433
434/*
435 * upap_timeout -- タイムアウト処理
436 */
437
438static void
439upap_timeout (void *arg)
440{
441 if (client_state != PAP_CS_AUTHREQ)
442 return;
443
444 if (client_rexmt >= MAX_PAP_REXMT) {
445 syslog(LOG_WARNING, "[PPP/PAP] no reply auth-req.");
446 client_state = PAP_CS_BADAUTH;
447 return;
448 }
449
450 upap_sauthreq();
451 }
452
453#endif /* of #if defined(DEF_PAP_TIMEOUT) */
454
455#endif /* of #ifdef AUTH_CFG_CLIENT */
456
457#ifdef AUTH_CFG_SERVER
458
459/*
460 * サーバモードで PAP 認証を開始する。
461 */
462
463void
464upap_auth_server (void)
465{
466 if (server_state == PAP_SS_INIT || server_state == PAP_SS_PENDING) {
467 server_state = PAP_SS_PENDING;
468 return;
469 }
470
471 server_state = PAP_SS_LISTEN;
472
473#if defined(DEF_PAP_REQTIME)
474
475 timeout((FP)upap_reqtimeout, NULL, DEF_PAP_REQTIME);
476
477#endif /* of #if defined(DEF_PAP_REQTIME) */
478 }
479
480/*
481 * upap_rauthreq -- 認証要求応答処理
482 */
483
484static void
485upap_rauthreq (T_NET_BUF *input)
486{
487 int16_t cplen;
488 uint8_t *data, *user, ulen, plen, code, id;
489
490 if (server_state < PAP_SS_LISTEN)
491 return;
492
493 /*
494 * 再要求があったときの処理
495 */
496 id = GET_PPP_CP_HDR(input)->id;
497 if (server_state == PAP_SS_OPEN) {
498 upap_sresp(PAP_AUTHACK, id);
499 return;
500 }
501
502 if (server_state == PAP_SS_BADAUTH) {
503 upap_sresp(PAP_AUTHNAK, id);
504 return;
505 }
506
507 cplen = GET_PPP_CP_HDR(input)->len;
508 data = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
509
510 /*
511 * ユーザ名を特定する。
512 */
513 ulen = *data;
514 if (cplen < sizeof(T_PPP_CP_HDR) + ulen + sizeof(uint8_t)) {
515 syslog(LOG_WARNING, "[PPP/PAP] bad req len: %d.", cplen);
516 return;
517 }
518 user = ++ data;
519 data += ulen;
520
521 /*
522 * パスワードを特定する。
523 */
524 plen = *data;
525 if (cplen < sizeof(T_PPP_CP_HDR) + ulen + plen + sizeof(uint8_t) * 2) {
526 syslog(LOG_WARNING, "[PPP/PAP] bad req len: %d.", cplen);
527 return;
528 }
529
530 /*
531 * ユーザ名とパスワードをチェックする。
532 */
533 if (compare(user, AUTH_LOCAL_USER, ulen) &&
534 compare(data + 1, AUTH_LOCAL_PASSWD, plen))
535 code = PAP_AUTHACK;
536 else
537 code = PAP_AUTHNAK;
538
539 upap_sresp(code, id);
540
541 if (code == PAP_AUTHACK) {
542 network_phase();
543 server_state = PAP_SS_OPEN;
544 }
545 else {
546 lcp_close();
547 server_state = PAP_SS_BADAUTH;
548 }
549
550#if defined(DEF_PAP_REQTIME)
551
552 untimeout((FP)upap_reqtimeout, NULL);
553
554#endif /* of #if defined(DEF_PAP_REQTIME) */
555 }
556
557/*
558 * upap_sresp -- 応答を返す。
559 */
560
561static void
562upap_sresp (uint8_t code, uint8_t id)
563{
564 T_NET_BUF *output;
565
566 /* 送信する */
567 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
568 IF_SET_PROTO(output, PPP_PAP);
569 ppp_cp_output(code, id, output);
570 }
571
572/*
573 * compare -- ユーザ名とパスワードの比較
574 */
575
576static bool_t
577compare (uint8_t *rstr, uint8_t *lstr, uint8_t rlen)
578{
579 while (rlen -- > 0) {
580 if (*rstr != *lstr)
581 return false;
582 rstr ++;
583 lstr ++;
584 }
585 return *lstr ? false : true;
586 }
587
588#if defined(DEF_PAP_REQTIME)
589
590/*
591 * upap_reqtimeout -- 要求タイムアウト処理
592 */
593
594static void
595upap_reqtimeout (void *arg)
596{
597 if (server_state == PAP_SS_LISTEN) {
598 lcp_close();
599 server_state = PAP_SS_BADAUTH;
600 }
601 }
602
603#endif /* of #if defined(DEF_PAP_REQTIME) */
604
605#endif /* of #ifdef AUTH_CFG_SERVER */
606
607#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.