source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tinet/net/ppp_upap.c@ 337

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

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.8 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2017 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_endian.h>
90#include <net/net_buf.h>
91#include <net/net_timer.h>
92#include <net/net_count.h>
93#include <net/ppp.h>
94#include <net/ppp_var.h>
95#include <net/ppp_hdlc.h>
96#include <net/ppp_auth.h>
97#include <net/ppp_fsm.h>
98#include <net/ppp_lcp.h>
99#include <net/ppp_upap.h>
100
101#ifdef SUPPORT_PPP
102
103/*
104 * 関数
105 */
106
107static void upap_init (void);
108static void upap_input (T_NET_BUF *input);
109static void upap_protrej (void);
110static void upap_lowerup (void);
111static void upap_lowerdown (void);
112static bool_t compare (uint8_t *rstr, uint8_t *lstr, uint8_t rlen);
113
114#ifdef AUTH_CFG_CLIENT
115
116static void upap_sauthreq (void);
117static void upap_rauthack (void);
118static void upap_rauthnak (void);
119
120#if defined(DEF_PAP_TIMEOUT)
121
122static void upap_timeout(void *arg);
123
124#endif /* of #if defined(DEF_PAP_TIMEOUT) */
125
126#endif /* of #ifdef AUTH_CFG_CLIENT */
127
128#ifdef AUTH_CFG_SERVER
129
130static void upap_rauthreq (T_NET_BUF *input);
131static void upap_sresp (uint8_t code, uint8_t id);
132
133#if defined(DEF_PAP_REQTIME)
134
135static void upap_reqtimeout(void *arg);
136
137#endif /* of #if defined(DEF_PAP_REQTIME) */
138
139#endif /* of #ifdef AUTH_CFG_SERVER */
140
141/*
142 * 全域変数
143 */
144
145T_PPP_PROTENT pap_protent = {
146 PPP_PAP,
147 upap_init, /* 初期化 */
148 upap_input, /* 入力 */
149 upap_protrej, /* Proto-REJ 受信処理 */
150 upap_lowerup, /* 下位層を起動する */
151 upap_lowerdown, /* 下位層を停止する */
152 NULL, /* オープンする */
153 NULL, /* クローズする */
154 NULL, /* データ入力 */
155 };
156
157/*
158 * 変数
159 */
160
161#ifdef AUTH_CFG_CLIENT
162
163static uint8_t client_state;
164static uint8_t client_cp_id;
165
166#if defined(DEF_PAP_TIMEOUT)
167
168static uint8_t client_rexmt = 0;
169
170#endif /* of #if defined(DEF_PAP_TIMEOUT) */
171
172#endif /* of #ifdef AUTH_CFG_CLIENT */
173
174#ifdef AUTH_CFG_SERVER
175
176static uint8_t server_state;
177
178#endif /* of #ifdef AUTH_CFG_SERVER */
179
180/*
181 * upap_init -- UPAP モジュールの初期化
182 */
183
184static void
185upap_init (void)
186{
187#ifdef AUTH_CFG_CLIENT
188
189 client_cp_id = 0;
190 client_state = PAP_CS_INIT;
191
192#endif /* of #ifdef AUTH_CFG_CLIENT */
193
194#ifdef AUTH_CFG_SERVER
195
196 server_state = PAP_SS_INIT;
197
198#endif /* of #ifdef AUTH_CFG_SERVER */
199 }
200
201/*
202 * upap_input -- UPAP 入力
203 */
204
205static void
206upap_input (T_NET_BUF *input)
207{
208 T_PPP_CP_HDR *hdr;
209
210 NET_COUNT_PPP_PAP(net_count_ppp_upap_in_octets, input->len);
211 NET_COUNT_PPP_PAP(net_count_ppp_upap_in_packets, 1);
212
213 /* PPP リンク制御 (CP) ヘッダより短ければエラー */
214 if (input->len < (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))) {
215 syslog(LOG_WARNING, "[PPP/PAP] short hdr: %d.", input->len);
216 return;
217 }
218
219 hdr = GET_PPP_CP_HDR(input);
220
221 /* ヘッダの長さと入力データサイズが一致しなければエラー */
222 if (hdr->len != input->len - sizeof(T_PPP_HDR)) {
223 syslog(LOG_WARNING, "[PPP/PAP] bad len: %d.", hdr->len);
224 return;
225 }
226
227 /*
228 * 制御コードにより適当な関数を呼出す
229 */
230
231 switch (hdr->code) {
232
233#ifdef AUTH_CFG_CLIENT
234
235 case PAP_AUTHACK:
236 upap_rauthack();
237 break;
238
239 case PAP_AUTHNAK:
240 upap_rauthnak();
241 break;
242
243#endif /* of #ifdef AUTH_CFG_CLIENT */
244
245#ifdef AUTH_CFG_SERVER
246
247 case PAP_AUTHREQ:
248 upap_rauthreq(input);
249 break;
250
251#endif /* of #ifdef AUTH_CFG_SERVER */
252
253 }
254 }
255
256/*
257 * upap_protrej -- Proto-REJ を受信したときの処理
258 */
259
260static void
261upap_protrej (void)
262{
263#ifdef AUTH_CFG_CLIENT
264
265 if (client_state == PAP_CS_AUTHREQ)
266 syslog(LOG_WARNING, "[PPP/PAP] proto-rej recved.");
267
268#endif /* of #ifdef AUTH_CFG_CLIENT */
269
270#ifdef AUTH_CFG_SERVER
271
272 if (server_state == PAP_SS_LISTEN) {
273 syslog(LOG_WARNING, "[PPP/PAP] proto-rej recved.");
274 lcp_close();
275 }
276
277#endif /* of #ifdef AUTH_CFG_SERVER */
278
279 upap_lowerdown();
280 }
281
282/*
283 * upap_lowerup -- UPAP 下位層を起動する。
284 */
285
286static void
287upap_lowerup (void)
288{
289#ifdef AUTH_CFG_CLIENT
290
291 if (client_state == PAP_CS_INIT)
292 client_state = PAP_CS_CLOSED;
293 else if (client_state == PAP_CS_PENDING)
294 upap_sauthreq();
295
296#endif /* of #ifdef AUTH_CFG_CLIENT */
297
298#ifdef AUTH_CFG_SERVER
299
300 if (server_state == PAP_SS_INIT)
301 server_state = PAP_SS_CLOSED;
302 else if (server_state == PAP_SS_PENDING) {
303 server_state = PAP_SS_LISTEN;
304
305#if defined(DEF_PAP_REQTIME)
306
307 timeout((FP)upap_reqtimeout, NULL, DEF_PAP_REQTIME);
308
309#endif /* of #if defined(DEF_PAP_REQTIME) */
310
311 }
312
313#endif /* of #ifdef AUTH_CFG_SERVER */
314 }
315
316/*
317 * upap_lowerdown -- UPAP 下位層を停止する。
318 */
319
320static void
321upap_lowerdown (void)
322{
323#ifdef AUTH_CFG_CLIENT
324
325#if defined(DEF_PAP_TIMEOUT)
326
327 if (client_state == PAP_CS_AUTHREQ)
328 untimeout((FP)upap_timeout, NULL);
329
330#endif /* of #if defined(DEF_PAP_TIMEOUT) */
331
332 client_state = PAP_CS_INIT;
333
334#endif /* of #ifdef AUTH_CFG_CLIENT */
335
336#ifdef AUTH_CFG_SERVER
337
338#if defined(DEF_PAP_REQTIME)
339
340 if (server_state == PAP_SS_LISTEN)
341 untimeout((FP)upap_reqtimeout, NULL);
342
343#endif /* of #if defined(DEF_PAP_REQTIME) */
344
345 server_state = PAP_SS_INIT;
346
347#endif /* of #ifdef AUTH_CFG_SERVER */
348 }
349#ifdef AUTH_CFG_CLIENT
350
351/*
352 * クライアントモードで PAP 認証を開始する。
353 */
354
355void
356upap_auth_client (void)
357{
358#if defined(DEF_PAP_TIMEOUT)
359
360 client_rexmt = 0;
361
362#endif /* of #if defined(DEF_PAP_TIMEOUT) */
363
364 if (client_state == PAP_CS_INIT || client_state == PAP_CS_PENDING) {
365 client_state = PAP_CS_PENDING;
366 return;
367 }
368
369 upap_sauthreq();
370 }
371
372/*
373 * upap_rauthack -- 認証 ACK 処理
374 */
375
376static void
377upap_rauthack (void)
378{
379 if (client_state == PAP_CS_AUTHREQ) {
380 client_state = PAP_CS_OPEN;
381 network_phase();
382 }
383 }
384
385/*
386 * upap_rauthnak -- 認証 NAK 処理
387 */
388
389static void
390upap_rauthnak (void)
391{
392 syslog(LOG_WARNING, "[PPP/PAP] auth-req NAKed.");
393 client_state = PAP_CS_BADAUTH;
394 }
395
396/*
397 * upap_sauthreq -- 認証要求処理
398 */
399
400static void
401upap_sauthreq (void)
402{
403 T_NET_BUF *output;
404 uint8_t *data;
405
406 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)
407 + sizeof(AUTH_REMOTE_USER) + sizeof(AUTH_REMOTE_PASSWD)));
408
409 data = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
410
411 /* ユーザ名を設定する。*/
412 *data = sizeof(AUTH_REMOTE_USER) - 1;
413 strcpy(data + 1, AUTH_REMOTE_USER);
414
415 /* パスワードを設定する。*/
416 *(data + sizeof(AUTH_REMOTE_USER)) = sizeof(AUTH_REMOTE_PASSWD) - 1;
417 strcpy(data + sizeof(AUTH_REMOTE_USER) + 1, AUTH_REMOTE_PASSWD);
418
419 /* 送信する */
420 IF_SET_PROTO(output, PPP_PAP);
421 ppp_cp_output(PAP_AUTHREQ, ++ client_cp_id, output);
422
423#if defined(DEF_PAP_TIMEOUT)
424
425 timeout((FP)upap_timeout, NULL, DEF_PAP_TIMEOUT);
426 client_rexmt ++;
427
428#endif /* of #if defined(DEF_PAP_TIMEOUT) */
429
430 client_state = PAP_CS_AUTHREQ;
431 }
432
433#if defined(DEF_PAP_TIMEOUT)
434
435/*
436 * upap_timeout -- タイムアウト処理
437 */
438
439static void
440upap_timeout (void *arg)
441{
442 if (client_state != PAP_CS_AUTHREQ)
443 return;
444
445 if (client_rexmt >= MAX_PAP_REXMT) {
446 syslog(LOG_WARNING, "[PPP/PAP] no reply auth-req.");
447 client_state = PAP_CS_BADAUTH;
448 return;
449 }
450
451 upap_sauthreq();
452 }
453
454#endif /* of #if defined(DEF_PAP_TIMEOUT) */
455
456#endif /* of #ifdef AUTH_CFG_CLIENT */
457
458#ifdef AUTH_CFG_SERVER
459
460/*
461 * サーバモードで PAP 認証を開始する。
462 */
463
464void
465upap_auth_server (void)
466{
467 if (server_state == PAP_SS_INIT || server_state == PAP_SS_PENDING) {
468 server_state = PAP_SS_PENDING;
469 return;
470 }
471
472 server_state = PAP_SS_LISTEN;
473
474#if defined(DEF_PAP_REQTIME)
475
476 timeout((FP)upap_reqtimeout, NULL, DEF_PAP_REQTIME);
477
478#endif /* of #if defined(DEF_PAP_REQTIME) */
479 }
480
481/*
482 * upap_rauthreq -- 認証要求応答処理
483 */
484
485static void
486upap_rauthreq (T_NET_BUF *input)
487{
488 int16_t cplen;
489 uint8_t *data, *user, ulen, plen, code, id;
490
491 if (server_state < PAP_SS_LISTEN)
492 return;
493
494 /*
495 * 再要求があったときの処理
496 */
497 id = GET_PPP_CP_HDR(input)->id;
498 if (server_state == PAP_SS_OPEN) {
499 upap_sresp(PAP_AUTHACK, id);
500 return;
501 }
502
503 if (server_state == PAP_SS_BADAUTH) {
504 upap_sresp(PAP_AUTHNAK, id);
505 return;
506 }
507
508 cplen = GET_PPP_CP_HDR(input)->len;
509 data = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
510
511 /*
512 * ユーザ名を特定する。
513 */
514 ulen = *data;
515 if (cplen < sizeof(T_PPP_CP_HDR) + ulen + sizeof(uint8_t)) {
516 syslog(LOG_WARNING, "[PPP/PAP] bad req len: %d.", cplen);
517 return;
518 }
519 user = ++ data;
520 data += ulen;
521
522 /*
523 * パスワードを特定する。
524 */
525 plen = *data;
526 if (cplen < sizeof(T_PPP_CP_HDR) + ulen + plen + sizeof(uint8_t) * 2) {
527 syslog(LOG_WARNING, "[PPP/PAP] bad req len: %d.", cplen);
528 return;
529 }
530
531 /*
532 * ユーザ名とパスワードをチェックする。
533 */
534 if (compare(user, AUTH_LOCAL_USER, ulen) &&
535 compare(data + 1, AUTH_LOCAL_PASSWD, plen))
536 code = PAP_AUTHACK;
537 else
538 code = PAP_AUTHNAK;
539
540 upap_sresp(code, id);
541
542 if (code == PAP_AUTHACK) {
543 network_phase();
544 server_state = PAP_SS_OPEN;
545 }
546 else {
547 lcp_close();
548 server_state = PAP_SS_BADAUTH;
549 }
550
551#if defined(DEF_PAP_REQTIME)
552
553 untimeout((FP)upap_reqtimeout, NULL);
554
555#endif /* of #if defined(DEF_PAP_REQTIME) */
556 }
557
558/*
559 * upap_sresp -- 応答を返す。
560 */
561
562static void
563upap_sresp (uint8_t code, uint8_t id)
564{
565 T_NET_BUF *output;
566
567 /* 送信する */
568 syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
569 IF_SET_PROTO(output, PPP_PAP);
570 ppp_cp_output(code, id, output);
571 }
572
573/*
574 * compare -- ユーザ名とパスワードの比較
575 */
576
577static bool_t
578compare (uint8_t *rstr, uint8_t *lstr, uint8_t rlen)
579{
580 while (rlen -- > 0) {
581 if (*rstr != *lstr)
582 return false;
583 rstr ++;
584 lstr ++;
585 }
586 return *lstr ? false : true;
587 }
588
589#if defined(DEF_PAP_REQTIME)
590
591/*
592 * upap_reqtimeout -- 要求タイムアウト処理
593 */
594
595static void
596upap_reqtimeout (void *arg)
597{
598 if (server_state == PAP_SS_LISTEN) {
599 lcp_close();
600 server_state = PAP_SS_BADAUTH;
601 }
602 }
603
604#endif /* of #if defined(DEF_PAP_REQTIME) */
605
606#endif /* of #ifdef AUTH_CFG_SERVER */
607
608#endif /* fo #ifdef SUPPORT_PPP */
Note: See TracBrowser for help on using the repository browser.