Modified version of NetServices. Fixes an issue where connections failed should the HTTP response status line be received in a packet on its own prior to any further headers. Changes are made to the HTTPClient.cpp file's readHeaders method.

Committer:
andrewbonney
Date:
Fri Apr 08 14:39:41 2011 +0000
Revision:
0:ec559500a63f

        

Who changed what in which revision?

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