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