00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "lwip/opt.h"
00053
00054 #if PPP_SUPPORT
00055
00056 #if PAP_SUPPORT
00057
00058 #include "ppp_impl.h"
00059 #include "pppdebug.h"
00060
00061 #include "auth.h"
00062 #include "pap.h"
00063
00064 #include <string.h>
00065
00066 #if 0
00067 static bool hide_password = 1;
00068
00069
00070
00071
00072 static option_t pap_option_list[] = {
00073 { "hide-password", o_bool, &hide_password,
00074 "Don't output passwords to log", 1 },
00075 { "show-password", o_bool, &hide_password,
00076 "Show password string in debug log messages", 0 },
00077 { "pap-restart", o_int, &upap[0].us_timeouttime,
00078 "Set retransmit timeout for PAP" },
00079 { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
00080 "Set max number of transmissions for auth-reqs" },
00081 { "pap-timeout", o_int, &upap[0].us_reqtimeout,
00082 "Set time limit for peer PAP authentication" },
00083 { NULL }
00084 };
00085 #endif
00086
00087
00088
00089
00090 static void upap_init (int);
00091 static void upap_lowerup (int);
00092 static void upap_lowerdown (int);
00093 static void upap_input (int, u_char *, int);
00094 static void upap_protrej (int);
00095 #if PPP_ADDITIONAL_CALLBACKS
00096 static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
00097 #endif
00098
00099 struct protent pap_protent = {
00100 PPP_PAP,
00101 upap_init,
00102 upap_input,
00103 upap_protrej,
00104 upap_lowerup,
00105 upap_lowerdown,
00106 NULL,
00107 NULL,
00108 #if PPP_ADDITIONAL_CALLBACKS
00109 upap_printpkt,
00110 NULL,
00111 #endif
00112 1,
00113 "PAP",
00114 #if PPP_ADDITIONAL_CALLBACKS
00115 NULL,
00116 NULL,
00117 NULL
00118 #endif
00119 };
00120
00121 upap_state upap[NUM_PPP];
00122
00123 static void upap_timeout (void *);
00124 static void upap_reqtimeout(void *);
00125 static void upap_rauthreq (upap_state *, u_char *, u_char, int);
00126 static void upap_rauthack (upap_state *, u_char *, int, int);
00127 static void upap_rauthnak (upap_state *, u_char *, int, int);
00128 static void upap_sauthreq (upap_state *);
00129 static void upap_sresp (upap_state *, u_char, u_char, char *, int);
00130
00131
00132
00133
00134
00135 static void
00136 upap_init(int unit)
00137 {
00138 upap_state *u = &upap[unit];
00139
00140 UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
00141 u->us_unit = unit;
00142 u->us_user = NULL;
00143 u->us_userlen = 0;
00144 u->us_passwd = NULL;
00145 u->us_passwdlen = 0;
00146 u->us_clientstate = UPAPCS_INITIAL;
00147 u->us_serverstate = UPAPSS_INITIAL;
00148 u->us_id = 0;
00149 u->us_timeouttime = UPAP_DEFTIMEOUT;
00150 u->us_maxtransmits = 10;
00151 u->us_reqtimeout = UPAP_DEFREQTIME;
00152 }
00153
00154
00155
00156
00157
00158
00159 void
00160 upap_authwithpeer(int unit, char *user, char *password)
00161 {
00162 upap_state *u = &upap[unit];
00163
00164 UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
00165 unit, user, password, u->us_clientstate));
00166
00167
00168 u->us_user = user;
00169 u->us_userlen = (int)strlen(user);
00170 u->us_passwd = password;
00171 u->us_passwdlen = (int)strlen(password);
00172
00173 u->us_transmits = 0;
00174
00175
00176 if (u->us_clientstate == UPAPCS_INITIAL ||
00177 u->us_clientstate == UPAPCS_PENDING) {
00178 u->us_clientstate = UPAPCS_PENDING;
00179 return;
00180 }
00181
00182 upap_sauthreq(u);
00183 }
00184
00185
00186
00187
00188
00189
00190
00191 void
00192 upap_authpeer(int unit)
00193 {
00194 upap_state *u = &upap[unit];
00195
00196
00197 if (u->us_serverstate == UPAPSS_INITIAL ||
00198 u->us_serverstate == UPAPSS_PENDING) {
00199 u->us_serverstate = UPAPSS_PENDING;
00200 return;
00201 }
00202
00203 u->us_serverstate = UPAPSS_LISTEN;
00204 if (u->us_reqtimeout > 0) {
00205 TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
00206 }
00207 }
00208
00209
00210
00211
00212 static void
00213 upap_timeout(void *arg)
00214 {
00215 upap_state *u = (upap_state *) arg;
00216
00217 UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n",
00218 u->us_unit, u->us_timeouttime, u->us_clientstate));
00219
00220 if (u->us_clientstate != UPAPCS_AUTHREQ) {
00221 UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
00222 return;
00223 }
00224
00225 if (u->us_transmits >= u->us_maxtransmits) {
00226
00227 UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
00228 u->us_clientstate = UPAPCS_BADAUTH;
00229 auth_withpeer_fail(u->us_unit, PPP_PAP);
00230 return;
00231 }
00232
00233 upap_sauthreq(u);
00234 }
00235
00236
00237
00238
00239
00240 static void
00241 upap_reqtimeout(void *arg)
00242 {
00243 upap_state *u = (upap_state *) arg;
00244
00245 if (u->us_serverstate != UPAPSS_LISTEN) {
00246 return;
00247 }
00248
00249 auth_peer_fail(u->us_unit, PPP_PAP);
00250 u->us_serverstate = UPAPSS_BADAUTH;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 static void
00260 upap_lowerup(int unit)
00261 {
00262 upap_state *u = &upap[unit];
00263
00264 UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
00265
00266 if (u->us_clientstate == UPAPCS_INITIAL) {
00267 u->us_clientstate = UPAPCS_CLOSED;
00268 } else if (u->us_clientstate == UPAPCS_PENDING) {
00269 upap_sauthreq(u);
00270
00271 }
00272
00273 if (u->us_serverstate == UPAPSS_INITIAL) {
00274 u->us_serverstate = UPAPSS_CLOSED;
00275 } else if (u->us_serverstate == UPAPSS_PENDING) {
00276 u->us_serverstate = UPAPSS_LISTEN;
00277 if (u->us_reqtimeout > 0) {
00278 TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
00279 }
00280 }
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 static void
00290 upap_lowerdown(int unit)
00291 {
00292 upap_state *u = &upap[unit];
00293
00294 UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
00295
00296 if (u->us_clientstate == UPAPCS_AUTHREQ) {
00297 UNTIMEOUT(upap_timeout, u);
00298 }
00299 if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) {
00300 UNTIMEOUT(upap_reqtimeout, u);
00301 }
00302
00303 u->us_clientstate = UPAPCS_INITIAL;
00304 u->us_serverstate = UPAPSS_INITIAL;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313 static void
00314 upap_protrej(int unit)
00315 {
00316 upap_state *u = &upap[unit];
00317
00318 if (u->us_clientstate == UPAPCS_AUTHREQ) {
00319 UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
00320 auth_withpeer_fail(unit, PPP_PAP);
00321 }
00322 if (u->us_serverstate == UPAPSS_LISTEN) {
00323 UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
00324 auth_peer_fail(unit, PPP_PAP);
00325 }
00326 upap_lowerdown(unit);
00327 }
00328
00329
00330
00331
00332
00333 static void
00334 upap_input(int unit, u_char *inpacket, int l)
00335 {
00336 upap_state *u = &upap[unit];
00337 u_char *inp;
00338 u_char code, id;
00339 int len;
00340
00341
00342
00343
00344
00345 inp = inpacket;
00346 if (l < (int)UPAP_HEADERLEN) {
00347 UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
00348 return;
00349 }
00350 GETCHAR(code, inp);
00351 GETCHAR(id, inp);
00352 GETSHORT(len, inp);
00353 if (len < (int)UPAP_HEADERLEN) {
00354 UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
00355 return;
00356 }
00357 if (len > l) {
00358 UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
00359 return;
00360 }
00361 len -= UPAP_HEADERLEN;
00362
00363
00364
00365
00366 switch (code) {
00367 case UPAP_AUTHREQ:
00368 upap_rauthreq(u, inp, id, len);
00369 break;
00370
00371 case UPAP_AUTHACK:
00372 upap_rauthack(u, inp, id, len);
00373 break;
00374
00375 case UPAP_AUTHNAK:
00376 upap_rauthnak(u, inp, id, len);
00377 break;
00378
00379 default:
00380 UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
00381 break;
00382 }
00383 }
00384
00385
00386
00387
00388
00389 static void
00390 upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
00391 {
00392 u_char ruserlen, rpasswdlen;
00393 char *ruser, *rpasswd;
00394 u_char retcode;
00395 char *msg;
00396 int msglen;
00397
00398 UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
00399
00400 if (u->us_serverstate < UPAPSS_LISTEN) {
00401 return;
00402 }
00403
00404
00405
00406
00407
00408 if (u->us_serverstate == UPAPSS_OPEN) {
00409 upap_sresp(u, UPAP_AUTHACK, id, "", 0);
00410 return;
00411 }
00412 if (u->us_serverstate == UPAPSS_BADAUTH) {
00413 upap_sresp(u, UPAP_AUTHNAK, id, "", 0);
00414 return;
00415 }
00416
00417
00418
00419
00420 if (len < (int)sizeof (u_char)) {
00421 UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
00422 return;
00423 }
00424 GETCHAR(ruserlen, inp);
00425 len -= sizeof (u_char) + ruserlen + sizeof (u_char);
00426 if (len < 0) {
00427 UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
00428 return;
00429 }
00430 ruser = (char *) inp;
00431 INCPTR(ruserlen, inp);
00432 GETCHAR(rpasswdlen, inp);
00433 if (len < rpasswdlen) {
00434 UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
00435 return;
00436 }
00437 rpasswd = (char *) inp;
00438
00439
00440
00441
00442 retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
00443
00444 BZERO(rpasswd, rpasswdlen);
00445
00446 upap_sresp(u, retcode, id, msg, msglen);
00447
00448 if (retcode == UPAP_AUTHACK) {
00449 u->us_serverstate = UPAPSS_OPEN;
00450 auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
00451 } else {
00452 u->us_serverstate = UPAPSS_BADAUTH;
00453 auth_peer_fail(u->us_unit, PPP_PAP);
00454 }
00455
00456 if (u->us_reqtimeout > 0) {
00457 UNTIMEOUT(upap_reqtimeout, u);
00458 }
00459 }
00460
00461
00462
00463
00464
00465 static void
00466 upap_rauthack(upap_state *u, u_char *inp, int id, int len)
00467 {
00468 u_char msglen;
00469 char *msg;
00470
00471 LWIP_UNUSED_ARG(id);
00472
00473 UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
00474
00475 if (u->us_clientstate != UPAPCS_AUTHREQ) {
00476 UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
00477 return;
00478 }
00479
00480
00481
00482
00483 if (len < (int)sizeof (u_char)) {
00484 UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
00485 } else {
00486 GETCHAR(msglen, inp);
00487 if (msglen > 0) {
00488 len -= sizeof (u_char);
00489 if (len < msglen) {
00490 UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
00491 return;
00492 }
00493 msg = (char *) inp;
00494 PRINTMSG(msg, msglen);
00495 }
00496 }
00497 UNTIMEOUT(upap_timeout, u);
00498 u->us_clientstate = UPAPCS_OPEN;
00499
00500 auth_withpeer_success(u->us_unit, PPP_PAP);
00501 }
00502
00503
00504
00505
00506
00507 static void
00508 upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
00509 {
00510 u_char msglen;
00511 char *msg;
00512
00513 LWIP_UNUSED_ARG(id);
00514
00515 UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
00516
00517 if (u->us_clientstate != UPAPCS_AUTHREQ) {
00518 return;
00519 }
00520
00521
00522
00523
00524 if (len < sizeof (u_char)) {
00525 UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
00526 } else {
00527 GETCHAR(msglen, inp);
00528 if(msglen > 0) {
00529 len -= sizeof (u_char);
00530 if (len < msglen) {
00531 UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
00532 return;
00533 }
00534 msg = (char *) inp;
00535 PRINTMSG(msg, msglen);
00536 }
00537 }
00538
00539 u->us_clientstate = UPAPCS_BADAUTH;
00540
00541 UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
00542 auth_withpeer_fail(u->us_unit, PPP_PAP);
00543 }
00544
00545
00546
00547
00548
00549 static void
00550 upap_sauthreq(upap_state *u)
00551 {
00552 u_char *outp;
00553 int outlen;
00554
00555 outlen = UPAP_HEADERLEN + 2 * sizeof (u_char)
00556 + u->us_userlen + u->us_passwdlen;
00557 outp = outpacket_buf[u->us_unit];
00558
00559 MAKEHEADER(outp, PPP_PAP);
00560
00561 PUTCHAR(UPAP_AUTHREQ, outp);
00562 PUTCHAR(++u->us_id, outp);
00563 PUTSHORT(outlen, outp);
00564 PUTCHAR(u->us_userlen, outp);
00565 BCOPY(u->us_user, outp, u->us_userlen);
00566 INCPTR(u->us_userlen, outp);
00567 PUTCHAR(u->us_passwdlen, outp);
00568 BCOPY(u->us_passwd, outp, u->us_passwdlen);
00569
00570 pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
00571
00572 UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
00573
00574 TIMEOUT(upap_timeout, u, u->us_timeouttime);
00575 ++u->us_transmits;
00576 u->us_clientstate = UPAPCS_AUTHREQ;
00577 }
00578
00579
00580
00581
00582
00583 static void
00584 upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
00585 {
00586 u_char *outp;
00587 int outlen;
00588
00589 outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
00590 outp = outpacket_buf[u->us_unit];
00591 MAKEHEADER(outp, PPP_PAP);
00592
00593 PUTCHAR(code, outp);
00594 PUTCHAR(id, outp);
00595 PUTSHORT(outlen, outp);
00596 PUTCHAR(msglen, outp);
00597 BCOPY(msg, outp, msglen);
00598 pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
00599
00600 UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
00601 }
00602
00603 #if PPP_ADDITIONAL_CALLBACKS
00604 static char *upap_codenames[] = {
00605 "AuthReq", "AuthAck", "AuthNak"
00606 };
00607
00608
00609
00610
00611 static int upap_printpkt(
00612 u_char *p,
00613 int plen,
00614 void (*printer) (void *, char *, ...),
00615 void *arg
00616 )
00617 {
00618 LWIP_UNUSED_ARG(p);
00619 LWIP_UNUSED_ARG(plen);
00620 LWIP_UNUSED_ARG(printer);
00621 LWIP_UNUSED_ARG(arg);
00622 return 0;
00623 }
00624 #endif
00625
00626 #endif
00627
00628 #endif