This library is stripped down version of NetServices library. HTTP server and client function is NOT supported.

Dependents:   imu-daq-eth

Committer:
idinor
Date:
Wed Jul 20 11:45:39 2011 +0000
Revision:
0:dcf3c92487ca

        

Who changed what in which revision?

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