Dependents:   TimeZoneDemo EthernetJackTestCode MMEx_Challenge ntp_mem ... more

Committer:
segundo
Date:
Wed Dec 15 18:01:30 2010 +0000
Revision:
7:4e2468d7d5cb
Parent:
0:ac1725ba162c

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:ac1725ba162c 1 /*****************************************************************************
segundo 0:ac1725ba162c 2 * pap.c - Network Password Authentication Protocol program file.
segundo 0:ac1725ba162c 3 *
segundo 0:ac1725ba162c 4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
segundo 0:ac1725ba162c 5 * portions Copyright (c) 1997 by Global Election Systems Inc.
segundo 0:ac1725ba162c 6 *
segundo 0:ac1725ba162c 7 * The authors hereby grant permission to use, copy, modify, distribute,
segundo 0:ac1725ba162c 8 * and license this software and its documentation for any purpose, provided
segundo 0:ac1725ba162c 9 * that existing copyright notices are retained in all copies and that this
segundo 0:ac1725ba162c 10 * notice and the following disclaimer are included verbatim in any
segundo 0:ac1725ba162c 11 * distributions. No written agreement, license, or royalty fee is required
segundo 0:ac1725ba162c 12 * for any of the authorized uses.
segundo 0:ac1725ba162c 13 *
segundo 0:ac1725ba162c 14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
segundo 0:ac1725ba162c 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
segundo 0:ac1725ba162c 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
segundo 0:ac1725ba162c 17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
segundo 0:ac1725ba162c 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
segundo 0:ac1725ba162c 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
segundo 0:ac1725ba162c 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
segundo 0:ac1725ba162c 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
segundo 0:ac1725ba162c 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
segundo 0:ac1725ba162c 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
segundo 0:ac1725ba162c 24 *
segundo 0:ac1725ba162c 25 ******************************************************************************
segundo 0:ac1725ba162c 26 * REVISION HISTORY
segundo 0:ac1725ba162c 27 *
segundo 0:ac1725ba162c 28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
segundo 0:ac1725ba162c 29 * Ported to lwIP.
segundo 0:ac1725ba162c 30 * 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
segundo 0:ac1725ba162c 31 * Original.
segundo 0:ac1725ba162c 32 *****************************************************************************/
segundo 0:ac1725ba162c 33 /*
segundo 0:ac1725ba162c 34 * upap.c - User/Password Authentication Protocol.
segundo 0:ac1725ba162c 35 *
segundo 0:ac1725ba162c 36 * Copyright (c) 1989 Carnegie Mellon University.
segundo 0:ac1725ba162c 37 * All rights reserved.
segundo 0:ac1725ba162c 38 *
segundo 0:ac1725ba162c 39 * Redistribution and use in source and binary forms are permitted
segundo 0:ac1725ba162c 40 * provided that the above copyright notice and this paragraph are
segundo 0:ac1725ba162c 41 * duplicated in all such forms and that any documentation,
segundo 0:ac1725ba162c 42 * advertising materials, and other materials related to such
segundo 0:ac1725ba162c 43 * distribution and use acknowledge that the software was developed
segundo 0:ac1725ba162c 44 * by Carnegie Mellon University. The name of the
segundo 0:ac1725ba162c 45 * University may not be used to endorse or promote products derived
segundo 0:ac1725ba162c 46 * from this software without specific prior written permission.
segundo 0:ac1725ba162c 47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
segundo 0:ac1725ba162c 48 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
segundo 0:ac1725ba162c 49 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
segundo 0:ac1725ba162c 50 */
segundo 0:ac1725ba162c 51
segundo 0:ac1725ba162c 52 #include "lwip/opt.h"
segundo 0:ac1725ba162c 53
segundo 0:ac1725ba162c 54 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
segundo 0:ac1725ba162c 55
segundo 0:ac1725ba162c 56 #if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
segundo 0:ac1725ba162c 57
segundo 0:ac1725ba162c 58 #include "ppp.h"
segundo 0:ac1725ba162c 59 #include "pppdebug.h"
segundo 0:ac1725ba162c 60
segundo 0:ac1725ba162c 61 #include "auth.h"
segundo 0:ac1725ba162c 62 #include "pap.h"
segundo 0:ac1725ba162c 63
segundo 0:ac1725ba162c 64 #include <string.h>
segundo 0:ac1725ba162c 65
segundo 0:ac1725ba162c 66 #if 0 /* UNUSED */
segundo 0:ac1725ba162c 67 static bool hide_password = 1;
segundo 0:ac1725ba162c 68
segundo 0:ac1725ba162c 69 /*
segundo 0:ac1725ba162c 70 * Command-line options.
segundo 0:ac1725ba162c 71 */
segundo 0:ac1725ba162c 72 static option_t pap_option_list[] = {
segundo 0:ac1725ba162c 73 { "hide-password", o_bool, &hide_password,
segundo 0:ac1725ba162c 74 "Don't output passwords to log", 1 },
segundo 0:ac1725ba162c 75 { "show-password", o_bool, &hide_password,
segundo 0:ac1725ba162c 76 "Show password string in debug log messages", 0 },
segundo 0:ac1725ba162c 77 { "pap-restart", o_int, &upap[0].us_timeouttime,
segundo 0:ac1725ba162c 78 "Set retransmit timeout for PAP" },
segundo 0:ac1725ba162c 79 { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
segundo 0:ac1725ba162c 80 "Set max number of transmissions for auth-reqs" },
segundo 0:ac1725ba162c 81 { "pap-timeout", o_int, &upap[0].us_reqtimeout,
segundo 0:ac1725ba162c 82 "Set time limit for peer PAP authentication" },
segundo 0:ac1725ba162c 83 { NULL }
segundo 0:ac1725ba162c 84 };
segundo 0:ac1725ba162c 85 #endif
segundo 0:ac1725ba162c 86
segundo 0:ac1725ba162c 87 /*
segundo 0:ac1725ba162c 88 * Protocol entry points.
segundo 0:ac1725ba162c 89 */
segundo 0:ac1725ba162c 90 static void upap_init (int);
segundo 0:ac1725ba162c 91 static void upap_lowerup (int);
segundo 0:ac1725ba162c 92 static void upap_lowerdown (int);
segundo 0:ac1725ba162c 93 static void upap_input (int, u_char *, int);
segundo 0:ac1725ba162c 94 static void upap_protrej (int);
segundo 0:ac1725ba162c 95 #if PPP_ADDITIONAL_CALLBACKS
segundo 0:ac1725ba162c 96 static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
segundo 0:ac1725ba162c 97 #endif /* PPP_ADDITIONAL_CALLBACKS */
segundo 0:ac1725ba162c 98
segundo 0:ac1725ba162c 99 struct protent pap_protent = {
segundo 0:ac1725ba162c 100 PPP_PAP,
segundo 0:ac1725ba162c 101 upap_init,
segundo 0:ac1725ba162c 102 upap_input,
segundo 0:ac1725ba162c 103 upap_protrej,
segundo 0:ac1725ba162c 104 upap_lowerup,
segundo 0:ac1725ba162c 105 upap_lowerdown,
segundo 0:ac1725ba162c 106 NULL,
segundo 0:ac1725ba162c 107 NULL,
segundo 0:ac1725ba162c 108 #if PPP_ADDITIONAL_CALLBACKS
segundo 0:ac1725ba162c 109 upap_printpkt,
segundo 0:ac1725ba162c 110 NULL,
segundo 0:ac1725ba162c 111 #endif /* PPP_ADDITIONAL_CALLBACKS */
segundo 0:ac1725ba162c 112 1,
segundo 0:ac1725ba162c 113 "PAP",
segundo 0:ac1725ba162c 114 #if PPP_ADDITIONAL_CALLBACKS
segundo 0:ac1725ba162c 115 NULL,
segundo 0:ac1725ba162c 116 NULL,
segundo 0:ac1725ba162c 117 NULL
segundo 0:ac1725ba162c 118 #endif /* PPP_ADDITIONAL_CALLBACKS */
segundo 0:ac1725ba162c 119 };
segundo 0:ac1725ba162c 120
segundo 0:ac1725ba162c 121 upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
segundo 0:ac1725ba162c 122
segundo 0:ac1725ba162c 123 static void upap_timeout (void *);
segundo 0:ac1725ba162c 124 static void upap_reqtimeout(void *);
segundo 0:ac1725ba162c 125 static void upap_rauthreq (upap_state *, u_char *, u_char, int);
segundo 0:ac1725ba162c 126 static void upap_rauthack (upap_state *, u_char *, int, int);
segundo 0:ac1725ba162c 127 static void upap_rauthnak (upap_state *, u_char *, int, int);
segundo 0:ac1725ba162c 128 static void upap_sauthreq (upap_state *);
segundo 0:ac1725ba162c 129 static void upap_sresp (upap_state *, u_char, u_char, char *, int);
segundo 0:ac1725ba162c 130
segundo 0:ac1725ba162c 131
segundo 0:ac1725ba162c 132 /*
segundo 0:ac1725ba162c 133 * upap_init - Initialize a UPAP unit.
segundo 0:ac1725ba162c 134 */
segundo 0:ac1725ba162c 135 static void
segundo 0:ac1725ba162c 136 upap_init(int unit)
segundo 0:ac1725ba162c 137 {
segundo 0:ac1725ba162c 138 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 139
segundo 0:ac1725ba162c 140 UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
segundo 0:ac1725ba162c 141 u->us_unit = unit;
segundo 0:ac1725ba162c 142 u->us_user = NULL;
segundo 0:ac1725ba162c 143 u->us_userlen = 0;
segundo 0:ac1725ba162c 144 u->us_passwd = NULL;
segundo 0:ac1725ba162c 145 u->us_passwdlen = 0;
segundo 0:ac1725ba162c 146 u->us_clientstate = UPAPCS_INITIAL;
segundo 0:ac1725ba162c 147 u->us_serverstate = UPAPSS_INITIAL;
segundo 0:ac1725ba162c 148 u->us_id = 0;
segundo 0:ac1725ba162c 149 u->us_timeouttime = UPAP_DEFTIMEOUT;
segundo 0:ac1725ba162c 150 u->us_maxtransmits = 10;
segundo 0:ac1725ba162c 151 u->us_reqtimeout = UPAP_DEFREQTIME;
segundo 0:ac1725ba162c 152 }
segundo 0:ac1725ba162c 153
segundo 0:ac1725ba162c 154 /*
segundo 0:ac1725ba162c 155 * upap_authwithpeer - Authenticate us with our peer (start client).
segundo 0:ac1725ba162c 156 *
segundo 0:ac1725ba162c 157 * Set new state and send authenticate's.
segundo 0:ac1725ba162c 158 */
segundo 0:ac1725ba162c 159 void
segundo 0:ac1725ba162c 160 upap_authwithpeer(int unit, char *user, char *password)
segundo 0:ac1725ba162c 161 {
segundo 0:ac1725ba162c 162 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 163
segundo 0:ac1725ba162c 164 UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
segundo 0:ac1725ba162c 165 unit, user, password, u->us_clientstate));
segundo 0:ac1725ba162c 166
segundo 0:ac1725ba162c 167 /* Save the username and password we're given */
segundo 0:ac1725ba162c 168 u->us_user = user;
segundo 0:ac1725ba162c 169 u->us_userlen = (int)strlen(user);
segundo 0:ac1725ba162c 170 u->us_passwd = password;
segundo 0:ac1725ba162c 171 u->us_passwdlen = (int)strlen(password);
segundo 0:ac1725ba162c 172
segundo 0:ac1725ba162c 173 u->us_transmits = 0;
segundo 0:ac1725ba162c 174
segundo 0:ac1725ba162c 175 /* Lower layer up yet? */
segundo 0:ac1725ba162c 176 if (u->us_clientstate == UPAPCS_INITIAL ||
segundo 0:ac1725ba162c 177 u->us_clientstate == UPAPCS_PENDING) {
segundo 0:ac1725ba162c 178 u->us_clientstate = UPAPCS_PENDING;
segundo 0:ac1725ba162c 179 return;
segundo 0:ac1725ba162c 180 }
segundo 0:ac1725ba162c 181
segundo 0:ac1725ba162c 182 upap_sauthreq(u); /* Start protocol */
segundo 0:ac1725ba162c 183 }
segundo 0:ac1725ba162c 184
segundo 0:ac1725ba162c 185
segundo 0:ac1725ba162c 186 /*
segundo 0:ac1725ba162c 187 * upap_authpeer - Authenticate our peer (start server).
segundo 0:ac1725ba162c 188 *
segundo 0:ac1725ba162c 189 * Set new state.
segundo 0:ac1725ba162c 190 */
segundo 0:ac1725ba162c 191 void
segundo 0:ac1725ba162c 192 upap_authpeer(int unit)
segundo 0:ac1725ba162c 193 {
segundo 0:ac1725ba162c 194 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 195
segundo 0:ac1725ba162c 196 /* Lower layer up yet? */
segundo 0:ac1725ba162c 197 if (u->us_serverstate == UPAPSS_INITIAL ||
segundo 0:ac1725ba162c 198 u->us_serverstate == UPAPSS_PENDING) {
segundo 0:ac1725ba162c 199 u->us_serverstate = UPAPSS_PENDING;
segundo 0:ac1725ba162c 200 return;
segundo 0:ac1725ba162c 201 }
segundo 0:ac1725ba162c 202
segundo 0:ac1725ba162c 203 u->us_serverstate = UPAPSS_LISTEN;
segundo 0:ac1725ba162c 204 if (u->us_reqtimeout > 0) {
segundo 0:ac1725ba162c 205 TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
segundo 0:ac1725ba162c 206 }
segundo 0:ac1725ba162c 207 }
segundo 0:ac1725ba162c 208
segundo 0:ac1725ba162c 209 /*
segundo 0:ac1725ba162c 210 * upap_timeout - Retransmission timer for sending auth-reqs expired.
segundo 0:ac1725ba162c 211 */
segundo 0:ac1725ba162c 212 static void
segundo 0:ac1725ba162c 213 upap_timeout(void *arg)
segundo 0:ac1725ba162c 214 {
segundo 0:ac1725ba162c 215 upap_state *u = (upap_state *) arg;
segundo 0:ac1725ba162c 216
segundo 0:ac1725ba162c 217 UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n",
segundo 0:ac1725ba162c 218 u->us_unit, u->us_timeouttime, u->us_clientstate));
segundo 0:ac1725ba162c 219
segundo 0:ac1725ba162c 220 if (u->us_clientstate != UPAPCS_AUTHREQ) {
segundo 0:ac1725ba162c 221 UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
segundo 0:ac1725ba162c 222 return;
segundo 0:ac1725ba162c 223 }
segundo 0:ac1725ba162c 224
segundo 0:ac1725ba162c 225 if (u->us_transmits >= u->us_maxtransmits) {
segundo 0:ac1725ba162c 226 /* give up in disgust */
segundo 0:ac1725ba162c 227 UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
segundo 0:ac1725ba162c 228 u->us_clientstate = UPAPCS_BADAUTH;
segundo 0:ac1725ba162c 229 auth_withpeer_fail(u->us_unit, PPP_PAP);
segundo 0:ac1725ba162c 230 return;
segundo 0:ac1725ba162c 231 }
segundo 0:ac1725ba162c 232
segundo 0:ac1725ba162c 233 upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/
segundo 0:ac1725ba162c 234 }
segundo 0:ac1725ba162c 235
segundo 0:ac1725ba162c 236
segundo 0:ac1725ba162c 237 /*
segundo 0:ac1725ba162c 238 * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
segundo 0:ac1725ba162c 239 */
segundo 0:ac1725ba162c 240 static void
segundo 0:ac1725ba162c 241 upap_reqtimeout(void *arg)
segundo 0:ac1725ba162c 242 {
segundo 0:ac1725ba162c 243 upap_state *u = (upap_state *) arg;
segundo 0:ac1725ba162c 244
segundo 0:ac1725ba162c 245 if (u->us_serverstate != UPAPSS_LISTEN) {
segundo 0:ac1725ba162c 246 return; /* huh?? */
segundo 0:ac1725ba162c 247 }
segundo 0:ac1725ba162c 248
segundo 0:ac1725ba162c 249 auth_peer_fail(u->us_unit, PPP_PAP);
segundo 0:ac1725ba162c 250 u->us_serverstate = UPAPSS_BADAUTH;
segundo 0:ac1725ba162c 251 }
segundo 0:ac1725ba162c 252
segundo 0:ac1725ba162c 253
segundo 0:ac1725ba162c 254 /*
segundo 0:ac1725ba162c 255 * upap_lowerup - The lower layer is up.
segundo 0:ac1725ba162c 256 *
segundo 0:ac1725ba162c 257 * Start authenticating if pending.
segundo 0:ac1725ba162c 258 */
segundo 0:ac1725ba162c 259 static void
segundo 0:ac1725ba162c 260 upap_lowerup(int unit)
segundo 0:ac1725ba162c 261 {
segundo 0:ac1725ba162c 262 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 263
segundo 0:ac1725ba162c 264 UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
segundo 0:ac1725ba162c 265
segundo 0:ac1725ba162c 266 if (u->us_clientstate == UPAPCS_INITIAL) {
segundo 0:ac1725ba162c 267 u->us_clientstate = UPAPCS_CLOSED;
segundo 0:ac1725ba162c 268 } else if (u->us_clientstate == UPAPCS_PENDING) {
segundo 0:ac1725ba162c 269 upap_sauthreq(u); /* send an auth-request */
segundo 0:ac1725ba162c 270 /* now client state is UPAPCS__AUTHREQ */
segundo 0:ac1725ba162c 271 }
segundo 0:ac1725ba162c 272
segundo 0:ac1725ba162c 273 if (u->us_serverstate == UPAPSS_INITIAL) {
segundo 0:ac1725ba162c 274 u->us_serverstate = UPAPSS_CLOSED;
segundo 0:ac1725ba162c 275 } else if (u->us_serverstate == UPAPSS_PENDING) {
segundo 0:ac1725ba162c 276 u->us_serverstate = UPAPSS_LISTEN;
segundo 0:ac1725ba162c 277 if (u->us_reqtimeout > 0) {
segundo 0:ac1725ba162c 278 TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
segundo 0:ac1725ba162c 279 }
segundo 0:ac1725ba162c 280 }
segundo 0:ac1725ba162c 281 }
segundo 0:ac1725ba162c 282
segundo 0:ac1725ba162c 283
segundo 0:ac1725ba162c 284 /*
segundo 0:ac1725ba162c 285 * upap_lowerdown - The lower layer is down.
segundo 0:ac1725ba162c 286 *
segundo 0:ac1725ba162c 287 * Cancel all timeouts.
segundo 0:ac1725ba162c 288 */
segundo 0:ac1725ba162c 289 static void
segundo 0:ac1725ba162c 290 upap_lowerdown(int unit)
segundo 0:ac1725ba162c 291 {
segundo 0:ac1725ba162c 292 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 293
segundo 0:ac1725ba162c 294 UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
segundo 0:ac1725ba162c 295
segundo 0:ac1725ba162c 296 if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */
segundo 0:ac1725ba162c 297 UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
segundo 0:ac1725ba162c 298 }
segundo 0:ac1725ba162c 299 if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) {
segundo 0:ac1725ba162c 300 UNTIMEOUT(upap_reqtimeout, u);
segundo 0:ac1725ba162c 301 }
segundo 0:ac1725ba162c 302
segundo 0:ac1725ba162c 303 u->us_clientstate = UPAPCS_INITIAL;
segundo 0:ac1725ba162c 304 u->us_serverstate = UPAPSS_INITIAL;
segundo 0:ac1725ba162c 305 }
segundo 0:ac1725ba162c 306
segundo 0:ac1725ba162c 307
segundo 0:ac1725ba162c 308 /*
segundo 0:ac1725ba162c 309 * upap_protrej - Peer doesn't speak this protocol.
segundo 0:ac1725ba162c 310 *
segundo 0:ac1725ba162c 311 * This shouldn't happen. In any case, pretend lower layer went down.
segundo 0:ac1725ba162c 312 */
segundo 0:ac1725ba162c 313 static void
segundo 0:ac1725ba162c 314 upap_protrej(int unit)
segundo 0:ac1725ba162c 315 {
segundo 0:ac1725ba162c 316 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 317
segundo 0:ac1725ba162c 318 if (u->us_clientstate == UPAPCS_AUTHREQ) {
segundo 0:ac1725ba162c 319 UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
segundo 0:ac1725ba162c 320 auth_withpeer_fail(unit, PPP_PAP);
segundo 0:ac1725ba162c 321 }
segundo 0:ac1725ba162c 322 if (u->us_serverstate == UPAPSS_LISTEN) {
segundo 0:ac1725ba162c 323 UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
segundo 0:ac1725ba162c 324 auth_peer_fail(unit, PPP_PAP);
segundo 0:ac1725ba162c 325 }
segundo 0:ac1725ba162c 326 upap_lowerdown(unit);
segundo 0:ac1725ba162c 327 }
segundo 0:ac1725ba162c 328
segundo 0:ac1725ba162c 329
segundo 0:ac1725ba162c 330 /*
segundo 0:ac1725ba162c 331 * upap_input - Input UPAP packet.
segundo 0:ac1725ba162c 332 */
segundo 0:ac1725ba162c 333 static void
segundo 0:ac1725ba162c 334 upap_input(int unit, u_char *inpacket, int l)
segundo 0:ac1725ba162c 335 {
segundo 0:ac1725ba162c 336 upap_state *u = &upap[unit];
segundo 0:ac1725ba162c 337 u_char *inp;
segundo 0:ac1725ba162c 338 u_char code, id;
segundo 0:ac1725ba162c 339 int len;
segundo 0:ac1725ba162c 340
segundo 0:ac1725ba162c 341 /*
segundo 0:ac1725ba162c 342 * Parse header (code, id and length).
segundo 0:ac1725ba162c 343 * If packet too short, drop it.
segundo 0:ac1725ba162c 344 */
segundo 0:ac1725ba162c 345 inp = inpacket;
segundo 0:ac1725ba162c 346 if (l < (int)UPAP_HEADERLEN) {
segundo 0:ac1725ba162c 347 UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
segundo 0:ac1725ba162c 348 return;
segundo 0:ac1725ba162c 349 }
segundo 0:ac1725ba162c 350 GETCHAR(code, inp);
segundo 0:ac1725ba162c 351 GETCHAR(id, inp);
segundo 0:ac1725ba162c 352 GETSHORT(len, inp);
segundo 0:ac1725ba162c 353 if (len < (int)UPAP_HEADERLEN) {
segundo 0:ac1725ba162c 354 UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
segundo 0:ac1725ba162c 355 return;
segundo 0:ac1725ba162c 356 }
segundo 0:ac1725ba162c 357 if (len > l) {
segundo 0:ac1725ba162c 358 UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
segundo 0:ac1725ba162c 359 return;
segundo 0:ac1725ba162c 360 }
segundo 0:ac1725ba162c 361 len -= UPAP_HEADERLEN;
segundo 0:ac1725ba162c 362
segundo 0:ac1725ba162c 363 /*
segundo 0:ac1725ba162c 364 * Action depends on code.
segundo 0:ac1725ba162c 365 */
segundo 0:ac1725ba162c 366 switch (code) {
segundo 0:ac1725ba162c 367 case UPAP_AUTHREQ:
segundo 0:ac1725ba162c 368 upap_rauthreq(u, inp, id, len);
segundo 0:ac1725ba162c 369 break;
segundo 0:ac1725ba162c 370
segundo 0:ac1725ba162c 371 case UPAP_AUTHACK:
segundo 0:ac1725ba162c 372 upap_rauthack(u, inp, id, len);
segundo 0:ac1725ba162c 373 break;
segundo 0:ac1725ba162c 374
segundo 0:ac1725ba162c 375 case UPAP_AUTHNAK:
segundo 0:ac1725ba162c 376 upap_rauthnak(u, inp, id, len);
segundo 0:ac1725ba162c 377 break;
segundo 0:ac1725ba162c 378
segundo 0:ac1725ba162c 379 default: /* XXX Need code reject */
segundo 0:ac1725ba162c 380 UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
segundo 0:ac1725ba162c 381 break;
segundo 0:ac1725ba162c 382 }
segundo 0:ac1725ba162c 383 }
segundo 0:ac1725ba162c 384
segundo 0:ac1725ba162c 385
segundo 0:ac1725ba162c 386 /*
segundo 0:ac1725ba162c 387 * upap_rauth - Receive Authenticate.
segundo 0:ac1725ba162c 388 */
segundo 0:ac1725ba162c 389 static void
segundo 0:ac1725ba162c 390 upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
segundo 0:ac1725ba162c 391 {
segundo 0:ac1725ba162c 392 u_char ruserlen, rpasswdlen;
segundo 0:ac1725ba162c 393 char *ruser, *rpasswd;
segundo 0:ac1725ba162c 394 u_char retcode;
segundo 0:ac1725ba162c 395 char *msg;
segundo 0:ac1725ba162c 396 int msglen;
segundo 0:ac1725ba162c 397
segundo 0:ac1725ba162c 398 UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
segundo 0:ac1725ba162c 399
segundo 0:ac1725ba162c 400 if (u->us_serverstate < UPAPSS_LISTEN) {
segundo 0:ac1725ba162c 401 return;
segundo 0:ac1725ba162c 402 }
segundo 0:ac1725ba162c 403
segundo 0:ac1725ba162c 404 /*
segundo 0:ac1725ba162c 405 * If we receive a duplicate authenticate-request, we are
segundo 0:ac1725ba162c 406 * supposed to return the same status as for the first request.
segundo 0:ac1725ba162c 407 */
segundo 0:ac1725ba162c 408 if (u->us_serverstate == UPAPSS_OPEN) {
segundo 0:ac1725ba162c 409 upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
segundo 0:ac1725ba162c 410 return;
segundo 0:ac1725ba162c 411 }
segundo 0:ac1725ba162c 412 if (u->us_serverstate == UPAPSS_BADAUTH) {
segundo 0:ac1725ba162c 413 upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
segundo 0:ac1725ba162c 414 return;
segundo 0:ac1725ba162c 415 }
segundo 0:ac1725ba162c 416
segundo 0:ac1725ba162c 417 /*
segundo 0:ac1725ba162c 418 * Parse user/passwd.
segundo 0:ac1725ba162c 419 */
segundo 0:ac1725ba162c 420 if (len < (int)sizeof (u_char)) {
segundo 0:ac1725ba162c 421 UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
segundo 0:ac1725ba162c 422 return;
segundo 0:ac1725ba162c 423 }
segundo 0:ac1725ba162c 424 GETCHAR(ruserlen, inp);
segundo 0:ac1725ba162c 425 len -= sizeof (u_char) + ruserlen + sizeof (u_char);
segundo 0:ac1725ba162c 426 if (len < 0) {
segundo 0:ac1725ba162c 427 UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
segundo 0:ac1725ba162c 428 return;
segundo 0:ac1725ba162c 429 }
segundo 0:ac1725ba162c 430 ruser = (char *) inp;
segundo 0:ac1725ba162c 431 INCPTR(ruserlen, inp);
segundo 0:ac1725ba162c 432 GETCHAR(rpasswdlen, inp);
segundo 0:ac1725ba162c 433 if (len < rpasswdlen) {
segundo 0:ac1725ba162c 434 UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
segundo 0:ac1725ba162c 435 return;
segundo 0:ac1725ba162c 436 }
segundo 0:ac1725ba162c 437 rpasswd = (char *) inp;
segundo 0:ac1725ba162c 438
segundo 0:ac1725ba162c 439 /*
segundo 0:ac1725ba162c 440 * Check the username and password given.
segundo 0:ac1725ba162c 441 */
segundo 0:ac1725ba162c 442 retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
segundo 0:ac1725ba162c 443 /* lwip: currently retcode is always UPAP_AUTHACK */
segundo 0:ac1725ba162c 444 BZERO(rpasswd, rpasswdlen);
segundo 0:ac1725ba162c 445
segundo 0:ac1725ba162c 446 upap_sresp(u, retcode, id, msg, msglen);
segundo 0:ac1725ba162c 447
segundo 0:ac1725ba162c 448 if (retcode == UPAP_AUTHACK) {
segundo 0:ac1725ba162c 449 u->us_serverstate = UPAPSS_OPEN;
segundo 0:ac1725ba162c 450 auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
segundo 0:ac1725ba162c 451 } else {
segundo 0:ac1725ba162c 452 u->us_serverstate = UPAPSS_BADAUTH;
segundo 0:ac1725ba162c 453 auth_peer_fail(u->us_unit, PPP_PAP);
segundo 0:ac1725ba162c 454 }
segundo 0:ac1725ba162c 455
segundo 0:ac1725ba162c 456 if (u->us_reqtimeout > 0) {
segundo 0:ac1725ba162c 457 UNTIMEOUT(upap_reqtimeout, u);
segundo 0:ac1725ba162c 458 }
segundo 0:ac1725ba162c 459 }
segundo 0:ac1725ba162c 460
segundo 0:ac1725ba162c 461
segundo 0:ac1725ba162c 462 /*
segundo 0:ac1725ba162c 463 * upap_rauthack - Receive Authenticate-Ack.
segundo 0:ac1725ba162c 464 */
segundo 0:ac1725ba162c 465 static void
segundo 0:ac1725ba162c 466 upap_rauthack(upap_state *u, u_char *inp, int id, int len)
segundo 0:ac1725ba162c 467 {
segundo 0:ac1725ba162c 468 u_char msglen;
segundo 0:ac1725ba162c 469 char *msg;
segundo 0:ac1725ba162c 470
segundo 0:ac1725ba162c 471 LWIP_UNUSED_ARG(id);
segundo 0:ac1725ba162c 472
segundo 0:ac1725ba162c 473 UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
segundo 0:ac1725ba162c 474
segundo 0:ac1725ba162c 475 if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
segundo 0:ac1725ba162c 476 UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
segundo 0:ac1725ba162c 477 return;
segundo 0:ac1725ba162c 478 }
segundo 0:ac1725ba162c 479
segundo 0:ac1725ba162c 480 /*
segundo 0:ac1725ba162c 481 * Parse message.
segundo 0:ac1725ba162c 482 */
segundo 0:ac1725ba162c 483 if (len < (int)sizeof (u_char)) {
segundo 0:ac1725ba162c 484 UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
segundo 0:ac1725ba162c 485 } else {
segundo 0:ac1725ba162c 486 GETCHAR(msglen, inp);
segundo 0:ac1725ba162c 487 if (msglen > 0) {
segundo 0:ac1725ba162c 488 len -= sizeof (u_char);
segundo 0:ac1725ba162c 489 if (len < msglen) {
segundo 0:ac1725ba162c 490 UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
segundo 0:ac1725ba162c 491 return;
segundo 0:ac1725ba162c 492 }
segundo 0:ac1725ba162c 493 msg = (char *) inp;
segundo 0:ac1725ba162c 494 PRINTMSG(msg, msglen);
segundo 0:ac1725ba162c 495 }
segundo 0:ac1725ba162c 496 }
segundo 0:ac1725ba162c 497 UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
segundo 0:ac1725ba162c 498 u->us_clientstate = UPAPCS_OPEN;
segundo 0:ac1725ba162c 499
segundo 0:ac1725ba162c 500 auth_withpeer_success(u->us_unit, PPP_PAP);
segundo 0:ac1725ba162c 501 }
segundo 0:ac1725ba162c 502
segundo 0:ac1725ba162c 503
segundo 0:ac1725ba162c 504 /*
segundo 0:ac1725ba162c 505 * upap_rauthnak - Receive Authenticate-Nak.
segundo 0:ac1725ba162c 506 */
segundo 0:ac1725ba162c 507 static void
segundo 0:ac1725ba162c 508 upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
segundo 0:ac1725ba162c 509 {
segundo 0:ac1725ba162c 510 u_char msglen;
segundo 0:ac1725ba162c 511 char *msg;
segundo 0:ac1725ba162c 512
segundo 0:ac1725ba162c 513 LWIP_UNUSED_ARG(id);
segundo 0:ac1725ba162c 514
segundo 0:ac1725ba162c 515 UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
segundo 0:ac1725ba162c 516
segundo 0:ac1725ba162c 517 if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
segundo 0:ac1725ba162c 518 return;
segundo 0:ac1725ba162c 519 }
segundo 0:ac1725ba162c 520
segundo 0:ac1725ba162c 521 /*
segundo 0:ac1725ba162c 522 * Parse message.
segundo 0:ac1725ba162c 523 */
segundo 0:ac1725ba162c 524 if (len < sizeof (u_char)) {
segundo 0:ac1725ba162c 525 UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
segundo 0:ac1725ba162c 526 } else {
segundo 0:ac1725ba162c 527 GETCHAR(msglen, inp);
segundo 0:ac1725ba162c 528 if(msglen > 0) {
segundo 0:ac1725ba162c 529 len -= sizeof (u_char);
segundo 0:ac1725ba162c 530 if (len < msglen) {
segundo 0:ac1725ba162c 531 UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
segundo 0:ac1725ba162c 532 return;
segundo 0:ac1725ba162c 533 }
segundo 0:ac1725ba162c 534 msg = (char *) inp;
segundo 0:ac1725ba162c 535 PRINTMSG(msg, msglen);
segundo 0:ac1725ba162c 536 }
segundo 0:ac1725ba162c 537 }
segundo 0:ac1725ba162c 538
segundo 0:ac1725ba162c 539 u->us_clientstate = UPAPCS_BADAUTH;
segundo 0:ac1725ba162c 540
segundo 0:ac1725ba162c 541 UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
segundo 0:ac1725ba162c 542 auth_withpeer_fail(u->us_unit, PPP_PAP);
segundo 0:ac1725ba162c 543 }
segundo 0:ac1725ba162c 544
segundo 0:ac1725ba162c 545
segundo 0:ac1725ba162c 546 /*
segundo 0:ac1725ba162c 547 * upap_sauthreq - Send an Authenticate-Request.
segundo 0:ac1725ba162c 548 */
segundo 0:ac1725ba162c 549 static void
segundo 0:ac1725ba162c 550 upap_sauthreq(upap_state *u)
segundo 0:ac1725ba162c 551 {
segundo 0:ac1725ba162c 552 u_char *outp;
segundo 0:ac1725ba162c 553 int outlen;
segundo 0:ac1725ba162c 554
segundo 0:ac1725ba162c 555 outlen = UPAP_HEADERLEN + 2 * sizeof (u_char)
segundo 0:ac1725ba162c 556 + u->us_userlen + u->us_passwdlen;
segundo 0:ac1725ba162c 557 outp = outpacket_buf[u->us_unit];
segundo 0:ac1725ba162c 558
segundo 0:ac1725ba162c 559 MAKEHEADER(outp, PPP_PAP);
segundo 0:ac1725ba162c 560
segundo 0:ac1725ba162c 561 PUTCHAR(UPAP_AUTHREQ, outp);
segundo 0:ac1725ba162c 562 PUTCHAR(++u->us_id, outp);
segundo 0:ac1725ba162c 563 PUTSHORT(outlen, outp);
segundo 0:ac1725ba162c 564 PUTCHAR(u->us_userlen, outp);
segundo 0:ac1725ba162c 565 BCOPY(u->us_user, outp, u->us_userlen);
segundo 0:ac1725ba162c 566 INCPTR(u->us_userlen, outp);
segundo 0:ac1725ba162c 567 PUTCHAR(u->us_passwdlen, outp);
segundo 0:ac1725ba162c 568 BCOPY(u->us_passwd, outp, u->us_passwdlen);
segundo 0:ac1725ba162c 569
segundo 0:ac1725ba162c 570 pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
segundo 0:ac1725ba162c 571
segundo 0:ac1725ba162c 572 UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
segundo 0:ac1725ba162c 573
segundo 0:ac1725ba162c 574 TIMEOUT(upap_timeout, u, u->us_timeouttime);
segundo 0:ac1725ba162c 575 ++u->us_transmits;
segundo 0:ac1725ba162c 576 u->us_clientstate = UPAPCS_AUTHREQ;
segundo 0:ac1725ba162c 577 }
segundo 0:ac1725ba162c 578
segundo 0:ac1725ba162c 579
segundo 0:ac1725ba162c 580 /*
segundo 0:ac1725ba162c 581 * upap_sresp - Send a response (ack or nak).
segundo 0:ac1725ba162c 582 */
segundo 0:ac1725ba162c 583 static void
segundo 0:ac1725ba162c 584 upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
segundo 0:ac1725ba162c 585 {
segundo 0:ac1725ba162c 586 u_char *outp;
segundo 0:ac1725ba162c 587 int outlen;
segundo 0:ac1725ba162c 588
segundo 0:ac1725ba162c 589 outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
segundo 0:ac1725ba162c 590 outp = outpacket_buf[u->us_unit];
segundo 0:ac1725ba162c 591 MAKEHEADER(outp, PPP_PAP);
segundo 0:ac1725ba162c 592
segundo 0:ac1725ba162c 593 PUTCHAR(code, outp);
segundo 0:ac1725ba162c 594 PUTCHAR(id, outp);
segundo 0:ac1725ba162c 595 PUTSHORT(outlen, outp);
segundo 0:ac1725ba162c 596 PUTCHAR(msglen, outp);
segundo 0:ac1725ba162c 597 BCOPY(msg, outp, msglen);
segundo 0:ac1725ba162c 598 pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
segundo 0:ac1725ba162c 599
segundo 0:ac1725ba162c 600 UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
segundo 0:ac1725ba162c 601 }
segundo 0:ac1725ba162c 602
segundo 0:ac1725ba162c 603 #if PPP_ADDITIONAL_CALLBACKS
segundo 0:ac1725ba162c 604 static char *upap_codenames[] = {
segundo 0:ac1725ba162c 605 "AuthReq", "AuthAck", "AuthNak"
segundo 0:ac1725ba162c 606 };
segundo 0:ac1725ba162c 607
segundo 0:ac1725ba162c 608 /*
segundo 0:ac1725ba162c 609 * upap_printpkt - print the contents of a PAP packet.
segundo 0:ac1725ba162c 610 */
segundo 0:ac1725ba162c 611 static int upap_printpkt(
segundo 0:ac1725ba162c 612 u_char *p,
segundo 0:ac1725ba162c 613 int plen,
segundo 0:ac1725ba162c 614 void (*printer) (void *, char *, ...),
segundo 0:ac1725ba162c 615 void *arg
segundo 0:ac1725ba162c 616 )
segundo 0:ac1725ba162c 617 {
segundo 0:ac1725ba162c 618 LWIP_UNUSED_ARG(p);
segundo 0:ac1725ba162c 619 LWIP_UNUSED_ARG(plen);
segundo 0:ac1725ba162c 620 LWIP_UNUSED_ARG(printer);
segundo 0:ac1725ba162c 621 LWIP_UNUSED_ARG(arg);
segundo 0:ac1725ba162c 622 return 0;
segundo 0:ac1725ba162c 623 }
segundo 0:ac1725ba162c 624 #endif /* PPP_ADDITIONAL_CALLBACKS */
segundo 0:ac1725ba162c 625
segundo 0:ac1725ba162c 626 #endif /* PAP_SUPPORT */
segundo 0:ac1725ba162c 627
segundo 0:ac1725ba162c 628 #endif /* PPP_SUPPORT */