Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file pap.c
Sergunb 0:8918a71cdbe9 3 * @brief PAP (Password Authentication Protocol)
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneTCP Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 30 #define TRACE_LEVEL PPP_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include "core/net.h"
Sergunb 0:8918a71cdbe9 34 #include "ppp/ppp_debug.h"
Sergunb 0:8918a71cdbe9 35 #include "ppp/lcp.h"
Sergunb 0:8918a71cdbe9 36 #include "ppp/ipcp.h"
Sergunb 0:8918a71cdbe9 37 #include "ppp/ipv6cp.h"
Sergunb 0:8918a71cdbe9 38 #include "ppp/pap.h"
Sergunb 0:8918a71cdbe9 39 #include "debug.h"
Sergunb 0:8918a71cdbe9 40
Sergunb 0:8918a71cdbe9 41 //Check TCP/IP stack configuration
Sergunb 0:8918a71cdbe9 42 #if (PPP_SUPPORT == ENABLED && PAP_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 43
Sergunb 0:8918a71cdbe9 44
Sergunb 0:8918a71cdbe9 45 /**
Sergunb 0:8918a71cdbe9 46 * @brief Start PAP authentication
Sergunb 0:8918a71cdbe9 47 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 48 * @return Error code
Sergunb 0:8918a71cdbe9 49 **/
Sergunb 0:8918a71cdbe9 50
Sergunb 0:8918a71cdbe9 51 error_t papStartAuth(PppContext *context)
Sergunb 0:8918a71cdbe9 52 {
Sergunb 0:8918a71cdbe9 53 //Debug message
Sergunb 0:8918a71cdbe9 54 TRACE_INFO("\r\nStarting PAP authentication...\r\n");
Sergunb 0:8918a71cdbe9 55
Sergunb 0:8918a71cdbe9 56 //Check whether the other end of the PPP link is being authenticated
Sergunb 0:8918a71cdbe9 57 if(context->localConfig.authProtocol == PPP_PROTOCOL_PAP)
Sergunb 0:8918a71cdbe9 58 {
Sergunb 0:8918a71cdbe9 59 //Switch to the Started state
Sergunb 0:8918a71cdbe9 60 context->papFsm.localState = PAP_STATE_1_STARTED;
Sergunb 0:8918a71cdbe9 61 }
Sergunb 0:8918a71cdbe9 62
Sergunb 0:8918a71cdbe9 63 //Check whether the other end of the PPP link is the authenticator
Sergunb 0:8918a71cdbe9 64 if(context->peerConfig.authProtocol == PPP_PROTOCOL_PAP)
Sergunb 0:8918a71cdbe9 65 {
Sergunb 0:8918a71cdbe9 66 //Initialize restart counter
Sergunb 0:8918a71cdbe9 67 context->papFsm.restartCounter = PAP_MAX_REQUESTS;
Sergunb 0:8918a71cdbe9 68 //Send Authenticate-Request packet
Sergunb 0:8918a71cdbe9 69 papSendAuthReq(context);
Sergunb 0:8918a71cdbe9 70 //Switch to the Req-Sent state
Sergunb 0:8918a71cdbe9 71 context->papFsm.peerState = PAP_STATE_2_REQ_SENT;
Sergunb 0:8918a71cdbe9 72 }
Sergunb 0:8918a71cdbe9 73
Sergunb 0:8918a71cdbe9 74 //Successful processing
Sergunb 0:8918a71cdbe9 75 return NO_ERROR;
Sergunb 0:8918a71cdbe9 76 }
Sergunb 0:8918a71cdbe9 77
Sergunb 0:8918a71cdbe9 78
Sergunb 0:8918a71cdbe9 79 /**
Sergunb 0:8918a71cdbe9 80 * @brief Abort PAP authentication
Sergunb 0:8918a71cdbe9 81 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 82 * @return Error code
Sergunb 0:8918a71cdbe9 83 **/
Sergunb 0:8918a71cdbe9 84
Sergunb 0:8918a71cdbe9 85 error_t papAbortAuth(PppContext *context)
Sergunb 0:8918a71cdbe9 86 {
Sergunb 0:8918a71cdbe9 87 //Debug message
Sergunb 0:8918a71cdbe9 88 TRACE_INFO("\r\nAborting PAP authentication...\r\n");
Sergunb 0:8918a71cdbe9 89
Sergunb 0:8918a71cdbe9 90 //Abort PAP authentication process
Sergunb 0:8918a71cdbe9 91 context->papFsm.localState = PAP_STATE_0_INITIAL;
Sergunb 0:8918a71cdbe9 92 context->papFsm.peerState = PAP_STATE_0_INITIAL;
Sergunb 0:8918a71cdbe9 93
Sergunb 0:8918a71cdbe9 94 //Successful processing
Sergunb 0:8918a71cdbe9 95 return NO_ERROR;
Sergunb 0:8918a71cdbe9 96 }
Sergunb 0:8918a71cdbe9 97
Sergunb 0:8918a71cdbe9 98
Sergunb 0:8918a71cdbe9 99 /**
Sergunb 0:8918a71cdbe9 100 * @brief PAP timer handler
Sergunb 0:8918a71cdbe9 101 *
Sergunb 0:8918a71cdbe9 102 * This routine must be periodically called by the TCP/IP stack to
Sergunb 0:8918a71cdbe9 103 * manage retransmissions
Sergunb 0:8918a71cdbe9 104 *
Sergunb 0:8918a71cdbe9 105 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 106 **/
Sergunb 0:8918a71cdbe9 107
Sergunb 0:8918a71cdbe9 108 void papTick(PppContext *context)
Sergunb 0:8918a71cdbe9 109 {
Sergunb 0:8918a71cdbe9 110 //Check whether the restart timer is running
Sergunb 0:8918a71cdbe9 111 if(context->papFsm.peerState == PAP_STATE_2_REQ_SENT)
Sergunb 0:8918a71cdbe9 112 {
Sergunb 0:8918a71cdbe9 113 //Get current time
Sergunb 0:8918a71cdbe9 114 systime_t time = osGetSystemTime();
Sergunb 0:8918a71cdbe9 115
Sergunb 0:8918a71cdbe9 116 //Check restart timer
Sergunb 0:8918a71cdbe9 117 if((time - context->papFsm.timestamp) >= PAP_RESTART_TIMER)
Sergunb 0:8918a71cdbe9 118 {
Sergunb 0:8918a71cdbe9 119 //Debug message
Sergunb 0:8918a71cdbe9 120 TRACE_INFO("\r\nPAP Timeout event\r\n");
Sergunb 0:8918a71cdbe9 121
Sergunb 0:8918a71cdbe9 122 //Check whether the restart counter is greater than zero
Sergunb 0:8918a71cdbe9 123 if(context->papFsm.restartCounter > 0)
Sergunb 0:8918a71cdbe9 124 {
Sergunb 0:8918a71cdbe9 125 //Retransmit the Authenticate-Request packet
Sergunb 0:8918a71cdbe9 126 papSendAuthReq(context);
Sergunb 0:8918a71cdbe9 127 }
Sergunb 0:8918a71cdbe9 128 else
Sergunb 0:8918a71cdbe9 129 {
Sergunb 0:8918a71cdbe9 130 //Abort PAP authentication
Sergunb 0:8918a71cdbe9 131 context->papFsm.peerState = PAP_STATE_0_INITIAL;
Sergunb 0:8918a71cdbe9 132 //Authentication failed
Sergunb 0:8918a71cdbe9 133 lcpClose(context);
Sergunb 0:8918a71cdbe9 134 }
Sergunb 0:8918a71cdbe9 135 }
Sergunb 0:8918a71cdbe9 136 }
Sergunb 0:8918a71cdbe9 137 }
Sergunb 0:8918a71cdbe9 138
Sergunb 0:8918a71cdbe9 139
Sergunb 0:8918a71cdbe9 140 /**
Sergunb 0:8918a71cdbe9 141 * @brief Process an incoming PAP packet
Sergunb 0:8918a71cdbe9 142 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 143 * @param[in] packet PAP packet received from the peer
Sergunb 0:8918a71cdbe9 144 * @param[in] length Length of the packet, in bytes
Sergunb 0:8918a71cdbe9 145 **/
Sergunb 0:8918a71cdbe9 146
Sergunb 0:8918a71cdbe9 147 void papProcessPacket(PppContext *context,
Sergunb 0:8918a71cdbe9 148 const PppPacket *packet, size_t length)
Sergunb 0:8918a71cdbe9 149 {
Sergunb 0:8918a71cdbe9 150 //Ensure the length of the incoming PAP packet is valid
Sergunb 0:8918a71cdbe9 151 if(length < sizeof(PppPacket))
Sergunb 0:8918a71cdbe9 152 return;
Sergunb 0:8918a71cdbe9 153
Sergunb 0:8918a71cdbe9 154 //Check the length field
Sergunb 0:8918a71cdbe9 155 if(ntohs(packet->length) > length)
Sergunb 0:8918a71cdbe9 156 return;
Sergunb 0:8918a71cdbe9 157 if(ntohs(packet->length) < sizeof(PppPacket))
Sergunb 0:8918a71cdbe9 158 return;
Sergunb 0:8918a71cdbe9 159
Sergunb 0:8918a71cdbe9 160 //Save the length of the PAP packet
Sergunb 0:8918a71cdbe9 161 length = ntohs(packet->length);
Sergunb 0:8918a71cdbe9 162
Sergunb 0:8918a71cdbe9 163 //Debug message
Sergunb 0:8918a71cdbe9 164 TRACE_INFO("PAP packet received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 165 //Dump PAP packet contents for debugging purpose
Sergunb 0:8918a71cdbe9 166 pppDumpPacket(packet, length, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 167
Sergunb 0:8918a71cdbe9 168 //Because the Authenticate-Ack might be lost, the authenticator must
Sergunb 0:8918a71cdbe9 169 //allow repeated Authenticate-Request packets after completing the
Sergunb 0:8918a71cdbe9 170 //Authentication phase
Sergunb 0:8918a71cdbe9 171 if(context->pppPhase != PPP_PHASE_AUTHENTICATE &&
Sergunb 0:8918a71cdbe9 172 context->pppPhase != PPP_PHASE_NETWORK)
Sergunb 0:8918a71cdbe9 173 {
Sergunb 0:8918a71cdbe9 174 //Any packets received during any other phase must be silently discarded
Sergunb 0:8918a71cdbe9 175 return;
Sergunb 0:8918a71cdbe9 176 }
Sergunb 0:8918a71cdbe9 177
Sergunb 0:8918a71cdbe9 178 //Check PAP code field
Sergunb 0:8918a71cdbe9 179 switch(packet->code)
Sergunb 0:8918a71cdbe9 180 {
Sergunb 0:8918a71cdbe9 181 //Authenticate-Request packet?
Sergunb 0:8918a71cdbe9 182 case PAP_CODE_AUTH_REQ:
Sergunb 0:8918a71cdbe9 183 //Process Authenticate-Request packet
Sergunb 0:8918a71cdbe9 184 papProcessAuthReq(context, (PapAuthReqPacket *) packet, length);
Sergunb 0:8918a71cdbe9 185 break;
Sergunb 0:8918a71cdbe9 186 //Authenticate-Ack packet?
Sergunb 0:8918a71cdbe9 187 case PAP_CODE_AUTH_ACK:
Sergunb 0:8918a71cdbe9 188 //Process Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 189 papProcessAuthAck(context, (PapAuthAckPacket *) packet, length);
Sergunb 0:8918a71cdbe9 190 break;
Sergunb 0:8918a71cdbe9 191 //Authenticate-Nak packet?
Sergunb 0:8918a71cdbe9 192 case PAP_CODE_AUTH_NAK:
Sergunb 0:8918a71cdbe9 193 //Process Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 194 papProcessAuthNak(context, (PapAuthNakPacket *) packet, length);
Sergunb 0:8918a71cdbe9 195 break;
Sergunb 0:8918a71cdbe9 196 //Unknown code field
Sergunb 0:8918a71cdbe9 197 default:
Sergunb 0:8918a71cdbe9 198 //Silently drop the incoming packet
Sergunb 0:8918a71cdbe9 199 break;
Sergunb 0:8918a71cdbe9 200 }
Sergunb 0:8918a71cdbe9 201 }
Sergunb 0:8918a71cdbe9 202
Sergunb 0:8918a71cdbe9 203
Sergunb 0:8918a71cdbe9 204 /**
Sergunb 0:8918a71cdbe9 205 * @brief Process Authenticate-Request packet
Sergunb 0:8918a71cdbe9 206 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 207 * @param[in] authReqPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 208 * @param[in] length Length of the packet, in bytes
Sergunb 0:8918a71cdbe9 209 * @return Error code
Sergunb 0:8918a71cdbe9 210 **/
Sergunb 0:8918a71cdbe9 211
Sergunb 0:8918a71cdbe9 212 error_t papProcessAuthReq(PppContext *context,
Sergunb 0:8918a71cdbe9 213 const PapAuthReqPacket *authReqPacket, size_t length)
Sergunb 0:8918a71cdbe9 214 {
Sergunb 0:8918a71cdbe9 215 bool_t status;
Sergunb 0:8918a71cdbe9 216 size_t usernameLen;
Sergunb 0:8918a71cdbe9 217 const uint8_t *p;
Sergunb 0:8918a71cdbe9 218
Sergunb 0:8918a71cdbe9 219 //Debug message
Sergunb 0:8918a71cdbe9 220 TRACE_INFO("\r\nPAP Authenticate-Request packet received\r\n");
Sergunb 0:8918a71cdbe9 221
Sergunb 0:8918a71cdbe9 222 //Make sure the Authenticate-Request packet is acceptable
Sergunb 0:8918a71cdbe9 223 if(context->localConfig.authProtocol != PPP_PROTOCOL_PAP)
Sergunb 0:8918a71cdbe9 224 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 225
Sergunb 0:8918a71cdbe9 226 //Check the length of the packet
Sergunb 0:8918a71cdbe9 227 if(length < sizeof(PapAuthReqPacket))
Sergunb 0:8918a71cdbe9 228 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 229
Sergunb 0:8918a71cdbe9 230 //Retrieve the length of the Peer-ID field
Sergunb 0:8918a71cdbe9 231 usernameLen = authReqPacket->peerIdLength;
Sergunb 0:8918a71cdbe9 232
Sergunb 0:8918a71cdbe9 233 //Malformed Authenticate-Request packet?
Sergunb 0:8918a71cdbe9 234 if(length < (sizeof(PapAuthReqPacket) + 1 + usernameLen))
Sergunb 0:8918a71cdbe9 235 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 236
Sergunb 0:8918a71cdbe9 237 //Limit the length of the string
Sergunb 0:8918a71cdbe9 238 usernameLen = MIN(usernameLen, PPP_MAX_USERNAME_LEN);
Sergunb 0:8918a71cdbe9 239 //Copy the name of the peer to be identified
Sergunb 0:8918a71cdbe9 240 memcpy(context->peerName, authReqPacket->peerId, usernameLen);
Sergunb 0:8918a71cdbe9 241 //Properly terminate the string with a NULL character
Sergunb 0:8918a71cdbe9 242 context->peerName[usernameLen] = '\0';
Sergunb 0:8918a71cdbe9 243
Sergunb 0:8918a71cdbe9 244 //Point to the Passwd-Length field
Sergunb 0:8918a71cdbe9 245 p = authReqPacket->peerId + usernameLen;
Sergunb 0:8918a71cdbe9 246
Sergunb 0:8918a71cdbe9 247 //Save the length of Password field
Sergunb 0:8918a71cdbe9 248 context->papFsm.passwordLen = p[0];
Sergunb 0:8918a71cdbe9 249 //Point to the Password field
Sergunb 0:8918a71cdbe9 250 context->papFsm.password = p + 1;
Sergunb 0:8918a71cdbe9 251
Sergunb 0:8918a71cdbe9 252 //Malformed Authenticate-Request packet?
Sergunb 0:8918a71cdbe9 253 if(length < (sizeof(PapAuthReqPacket) + 1 + usernameLen + context->papFsm.passwordLen))
Sergunb 0:8918a71cdbe9 254 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 255
Sergunb 0:8918a71cdbe9 256 //Invoke user-defined callback, if any
Sergunb 0:8918a71cdbe9 257 if(context->settings.authCallback != NULL)
Sergunb 0:8918a71cdbe9 258 {
Sergunb 0:8918a71cdbe9 259 //Perfom username and password verification
Sergunb 0:8918a71cdbe9 260 status = context->settings.authCallback(context->interface,
Sergunb 0:8918a71cdbe9 261 context->peerName);
Sergunb 0:8918a71cdbe9 262 }
Sergunb 0:8918a71cdbe9 263 else
Sergunb 0:8918a71cdbe9 264 {
Sergunb 0:8918a71cdbe9 265 //Unable to perform authentication...
Sergunb 0:8918a71cdbe9 266 status = FALSE;
Sergunb 0:8918a71cdbe9 267 }
Sergunb 0:8918a71cdbe9 268
Sergunb 0:8918a71cdbe9 269 //Successful authentication?
Sergunb 0:8918a71cdbe9 270 if(status)
Sergunb 0:8918a71cdbe9 271 {
Sergunb 0:8918a71cdbe9 272 //If the Peer-ID/Password pair received in the Authenticate-Request
Sergunb 0:8918a71cdbe9 273 //is both recognizable and acceptable, then the authenticator must
Sergunb 0:8918a71cdbe9 274 //transmit an Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 275 papSendAuthAck(context, authReqPacket->identifier);
Sergunb 0:8918a71cdbe9 276
Sergunb 0:8918a71cdbe9 277 //Switch to the Ack-Sent state
Sergunb 0:8918a71cdbe9 278 context->papFsm.localState = PAP_STATE_4_ACK_SENT;
Sergunb 0:8918a71cdbe9 279 //The user has been successfully authenticated
Sergunb 0:8918a71cdbe9 280 context->localAuthDone = TRUE;
Sergunb 0:8918a71cdbe9 281
Sergunb 0:8918a71cdbe9 282 //Check whether PPP authentication is complete
Sergunb 0:8918a71cdbe9 283 if(context->localAuthDone && context->peerAuthDone)
Sergunb 0:8918a71cdbe9 284 {
Sergunb 0:8918a71cdbe9 285 //Check current PPP phase
Sergunb 0:8918a71cdbe9 286 if(context->pppPhase == PPP_PHASE_AUTHENTICATE)
Sergunb 0:8918a71cdbe9 287 {
Sergunb 0:8918a71cdbe9 288 //Advance to the Network phase
Sergunb 0:8918a71cdbe9 289 context->pppPhase = PPP_PHASE_NETWORK;
Sergunb 0:8918a71cdbe9 290
Sergunb 0:8918a71cdbe9 291 #if (IPV4_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 292 //IPCP Open event
Sergunb 0:8918a71cdbe9 293 ipcpOpen(context);
Sergunb 0:8918a71cdbe9 294 #endif
Sergunb 0:8918a71cdbe9 295 #if (IPV6_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 296 //IPV6CP Open event
Sergunb 0:8918a71cdbe9 297 ipv6cpOpen(context);
Sergunb 0:8918a71cdbe9 298 #endif
Sergunb 0:8918a71cdbe9 299 }
Sergunb 0:8918a71cdbe9 300 }
Sergunb 0:8918a71cdbe9 301 }
Sergunb 0:8918a71cdbe9 302 else
Sergunb 0:8918a71cdbe9 303 {
Sergunb 0:8918a71cdbe9 304 //If the Peer-ID/Password pair received in the Authenticate-Request
Sergunb 0:8918a71cdbe9 305 //is not recognizable or acceptable, then the authenticator must
Sergunb 0:8918a71cdbe9 306 //transmit an Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 307 papSendAuthNak(context, authReqPacket->identifier);
Sergunb 0:8918a71cdbe9 308
Sergunb 0:8918a71cdbe9 309 //Switch to the Nak-Sent state
Sergunb 0:8918a71cdbe9 310 context->papFsm.localState = PAP_STATE_6_NAK_SENT;
Sergunb 0:8918a71cdbe9 311 //The authenticator should take action to terminate the link
Sergunb 0:8918a71cdbe9 312 lcpClose(context);
Sergunb 0:8918a71cdbe9 313 }
Sergunb 0:8918a71cdbe9 314
Sergunb 0:8918a71cdbe9 315 //Successful processing
Sergunb 0:8918a71cdbe9 316 return NO_ERROR;
Sergunb 0:8918a71cdbe9 317 }
Sergunb 0:8918a71cdbe9 318
Sergunb 0:8918a71cdbe9 319
Sergunb 0:8918a71cdbe9 320 /**
Sergunb 0:8918a71cdbe9 321 * @brief Process Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 322 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 323 * @param[in] authAckPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 324 * @param[in] length Length of the packet, in bytes
Sergunb 0:8918a71cdbe9 325 * @return Error code
Sergunb 0:8918a71cdbe9 326 **/
Sergunb 0:8918a71cdbe9 327
Sergunb 0:8918a71cdbe9 328 error_t papProcessAuthAck(PppContext *context,
Sergunb 0:8918a71cdbe9 329 const PapAuthAckPacket *authAckPacket, size_t length)
Sergunb 0:8918a71cdbe9 330 {
Sergunb 0:8918a71cdbe9 331 //Debug message
Sergunb 0:8918a71cdbe9 332 TRACE_INFO("\r\nPAP Authenticate-Ack packet received\r\n");
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 //Make sure the Authenticate-Ack packet is acceptable
Sergunb 0:8918a71cdbe9 335 if(context->peerConfig.authProtocol != PPP_PROTOCOL_PAP)
Sergunb 0:8918a71cdbe9 336 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 337
Sergunb 0:8918a71cdbe9 338 //Check the length of the packet
Sergunb 0:8918a71cdbe9 339 if(length < sizeof(PapAuthAckPacket))
Sergunb 0:8918a71cdbe9 340 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 341
Sergunb 0:8918a71cdbe9 342 //When a packet is received with an invalid Identifier field, the
Sergunb 0:8918a71cdbe9 343 //packet is silently discarded without affecting the automaton
Sergunb 0:8918a71cdbe9 344 if(authAckPacket->identifier != context->papFsm.identifier)
Sergunb 0:8918a71cdbe9 345 return ERROR_WRONG_IDENTIFIER;
Sergunb 0:8918a71cdbe9 346
Sergunb 0:8918a71cdbe9 347 //Switch to the Ack-Rcvd state
Sergunb 0:8918a71cdbe9 348 context->papFsm.peerState = PAP_STATE_5_ACK_RCVD;
Sergunb 0:8918a71cdbe9 349 //The user name has been accepted by the authenticator
Sergunb 0:8918a71cdbe9 350 context->peerAuthDone = TRUE;
Sergunb 0:8918a71cdbe9 351
Sergunb 0:8918a71cdbe9 352 //Check whether PPP authentication is complete
Sergunb 0:8918a71cdbe9 353 if(context->localAuthDone && context->peerAuthDone)
Sergunb 0:8918a71cdbe9 354 {
Sergunb 0:8918a71cdbe9 355 //Check current PPP phase
Sergunb 0:8918a71cdbe9 356 if(context->pppPhase == PPP_PHASE_AUTHENTICATE)
Sergunb 0:8918a71cdbe9 357 {
Sergunb 0:8918a71cdbe9 358 //Advance to the Network phase
Sergunb 0:8918a71cdbe9 359 context->pppPhase = PPP_PHASE_NETWORK;
Sergunb 0:8918a71cdbe9 360
Sergunb 0:8918a71cdbe9 361 #if (IPV4_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 362 //IPCP Open event
Sergunb 0:8918a71cdbe9 363 ipcpOpen(context);
Sergunb 0:8918a71cdbe9 364 #endif
Sergunb 0:8918a71cdbe9 365 #if (IPV6_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 366 //IPV6CP Open event
Sergunb 0:8918a71cdbe9 367 ipv6cpOpen(context);
Sergunb 0:8918a71cdbe9 368 #endif
Sergunb 0:8918a71cdbe9 369 }
Sergunb 0:8918a71cdbe9 370 }
Sergunb 0:8918a71cdbe9 371
Sergunb 0:8918a71cdbe9 372 //Successful processing
Sergunb 0:8918a71cdbe9 373 return NO_ERROR;
Sergunb 0:8918a71cdbe9 374 }
Sergunb 0:8918a71cdbe9 375
Sergunb 0:8918a71cdbe9 376
Sergunb 0:8918a71cdbe9 377 /**
Sergunb 0:8918a71cdbe9 378 * @brief Process Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 379 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 380 * @param[in] authNakPacket Packet received from the peer
Sergunb 0:8918a71cdbe9 381 * @param[in] length Length of the packet, in bytes
Sergunb 0:8918a71cdbe9 382 * @return Error code
Sergunb 0:8918a71cdbe9 383 **/
Sergunb 0:8918a71cdbe9 384
Sergunb 0:8918a71cdbe9 385 error_t papProcessAuthNak(PppContext *context,
Sergunb 0:8918a71cdbe9 386 const PapAuthNakPacket *authNakPacket, size_t length)
Sergunb 0:8918a71cdbe9 387 {
Sergunb 0:8918a71cdbe9 388 //Debug message
Sergunb 0:8918a71cdbe9 389 TRACE_INFO("\r\nPAP Authenticate-Nak packet received\r\n");
Sergunb 0:8918a71cdbe9 390
Sergunb 0:8918a71cdbe9 391 //Make sure the Authenticate-Nak packet is acceptable
Sergunb 0:8918a71cdbe9 392 if(context->peerConfig.authProtocol != PPP_PROTOCOL_PAP)
Sergunb 0:8918a71cdbe9 393 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 394
Sergunb 0:8918a71cdbe9 395 //Check the length of the packet
Sergunb 0:8918a71cdbe9 396 if(length < sizeof(PapAuthNakPacket))
Sergunb 0:8918a71cdbe9 397 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 398
Sergunb 0:8918a71cdbe9 399 //When a packet is received with an invalid Identifier field, the
Sergunb 0:8918a71cdbe9 400 //packet is silently discarded without affecting the automaton
Sergunb 0:8918a71cdbe9 401 if(authNakPacket->identifier != context->papFsm.identifier)
Sergunb 0:8918a71cdbe9 402 return ERROR_WRONG_IDENTIFIER;
Sergunb 0:8918a71cdbe9 403
Sergunb 0:8918a71cdbe9 404 //Switch to the Nak-Rcvd state
Sergunb 0:8918a71cdbe9 405 context->papFsm.peerState = PAP_STATE_7_NAK_RCVD;
Sergunb 0:8918a71cdbe9 406 //Authentication failed
Sergunb 0:8918a71cdbe9 407 lcpClose(context);
Sergunb 0:8918a71cdbe9 408
Sergunb 0:8918a71cdbe9 409 //Successful processing
Sergunb 0:8918a71cdbe9 410 return NO_ERROR;
Sergunb 0:8918a71cdbe9 411 }
Sergunb 0:8918a71cdbe9 412
Sergunb 0:8918a71cdbe9 413
Sergunb 0:8918a71cdbe9 414 /**
Sergunb 0:8918a71cdbe9 415 * @brief Send Authenticate-Request packet
Sergunb 0:8918a71cdbe9 416 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 417 * @return Error code
Sergunb 0:8918a71cdbe9 418 **/
Sergunb 0:8918a71cdbe9 419
Sergunb 0:8918a71cdbe9 420 error_t papSendAuthReq(PppContext *context)
Sergunb 0:8918a71cdbe9 421 {
Sergunb 0:8918a71cdbe9 422 error_t error;
Sergunb 0:8918a71cdbe9 423 size_t usernameLen;
Sergunb 0:8918a71cdbe9 424 size_t passwordLen;
Sergunb 0:8918a71cdbe9 425 size_t length;
Sergunb 0:8918a71cdbe9 426 size_t offset;
Sergunb 0:8918a71cdbe9 427 uint8_t *p;
Sergunb 0:8918a71cdbe9 428 NetBuffer *buffer;
Sergunb 0:8918a71cdbe9 429 PapAuthReqPacket *authReqPacket;
Sergunb 0:8918a71cdbe9 430
Sergunb 0:8918a71cdbe9 431 //Get the length of the user name
Sergunb 0:8918a71cdbe9 432 usernameLen = strlen(context->username);
Sergunb 0:8918a71cdbe9 433 //Get the length of the password
Sergunb 0:8918a71cdbe9 434 passwordLen = strlen(context->password);
Sergunb 0:8918a71cdbe9 435
Sergunb 0:8918a71cdbe9 436 //Calculate the length of the Authenticate-Request packet
Sergunb 0:8918a71cdbe9 437 length = sizeof(PapAuthReqPacket) + 1 + usernameLen + passwordLen;
Sergunb 0:8918a71cdbe9 438
Sergunb 0:8918a71cdbe9 439 //Allocate a buffer memory to hold the packet
Sergunb 0:8918a71cdbe9 440 buffer = pppAllocBuffer(length, &offset);
Sergunb 0:8918a71cdbe9 441 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 442 if(buffer == NULL)
Sergunb 0:8918a71cdbe9 443 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 444
Sergunb 0:8918a71cdbe9 445 //Point to the Authenticate-Request packet
Sergunb 0:8918a71cdbe9 446 authReqPacket = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 447
Sergunb 0:8918a71cdbe9 448 //Format packet header
Sergunb 0:8918a71cdbe9 449 authReqPacket->code = PAP_CODE_AUTH_REQ;
Sergunb 0:8918a71cdbe9 450 authReqPacket->identifier = ++context->papFsm.identifier;
Sergunb 0:8918a71cdbe9 451 authReqPacket->length = htons(length);
Sergunb 0:8918a71cdbe9 452
Sergunb 0:8918a71cdbe9 453 //The Peer-ID-Length field indicates the length of Peer-ID field
Sergunb 0:8918a71cdbe9 454 authReqPacket->peerIdLength = usernameLen;
Sergunb 0:8918a71cdbe9 455 //Append Peer-ID
Sergunb 0:8918a71cdbe9 456 memcpy(authReqPacket->peerId, context->username, usernameLen);
Sergunb 0:8918a71cdbe9 457
Sergunb 0:8918a71cdbe9 458 //Point to the Passwd-Length field
Sergunb 0:8918a71cdbe9 459 p = authReqPacket->peerId + usernameLen;
Sergunb 0:8918a71cdbe9 460 //The Passwd-Length field indicates the length of Password field
Sergunb 0:8918a71cdbe9 461 p[0] = passwordLen;
Sergunb 0:8918a71cdbe9 462
Sergunb 0:8918a71cdbe9 463 //Append Password
Sergunb 0:8918a71cdbe9 464 memcpy(p + 1, context->password, passwordLen);
Sergunb 0:8918a71cdbe9 465
Sergunb 0:8918a71cdbe9 466 //Adjust the length of the multi-part buffer
Sergunb 0:8918a71cdbe9 467 netBufferSetLength(buffer, offset + length);
Sergunb 0:8918a71cdbe9 468
Sergunb 0:8918a71cdbe9 469 //Debug message
Sergunb 0:8918a71cdbe9 470 TRACE_INFO("Sending PAP Authenticate-Request packet (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 471 //Dump packet contents for debugging purpose
Sergunb 0:8918a71cdbe9 472 pppDumpPacket((PppPacket *) authReqPacket, length, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 473
Sergunb 0:8918a71cdbe9 474 //Send PPP frame
Sergunb 0:8918a71cdbe9 475 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 476
Sergunb 0:8918a71cdbe9 477 //The restart counter is decremented each time a Authenticate-Request is sent
Sergunb 0:8918a71cdbe9 478 if(context->papFsm.restartCounter > 0)
Sergunb 0:8918a71cdbe9 479 context->papFsm.restartCounter--;
Sergunb 0:8918a71cdbe9 480
Sergunb 0:8918a71cdbe9 481 //Save the time at which the packet was sent
Sergunb 0:8918a71cdbe9 482 context->papFsm.timestamp = osGetSystemTime();
Sergunb 0:8918a71cdbe9 483
Sergunb 0:8918a71cdbe9 484 //Free previously allocated memory block
Sergunb 0:8918a71cdbe9 485 netBufferFree(buffer);
Sergunb 0:8918a71cdbe9 486 //Return status code
Sergunb 0:8918a71cdbe9 487 return error;
Sergunb 0:8918a71cdbe9 488 }
Sergunb 0:8918a71cdbe9 489
Sergunb 0:8918a71cdbe9 490
Sergunb 0:8918a71cdbe9 491 /**
Sergunb 0:8918a71cdbe9 492 * @brief Send Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 493 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 494 * @param[in] identifier Identifier field
Sergunb 0:8918a71cdbe9 495 * @return Error code
Sergunb 0:8918a71cdbe9 496 **/
Sergunb 0:8918a71cdbe9 497
Sergunb 0:8918a71cdbe9 498 error_t papSendAuthAck(PppContext *context, uint8_t identifier)
Sergunb 0:8918a71cdbe9 499 {
Sergunb 0:8918a71cdbe9 500 error_t error;
Sergunb 0:8918a71cdbe9 501 size_t length;
Sergunb 0:8918a71cdbe9 502 size_t offset;
Sergunb 0:8918a71cdbe9 503 NetBuffer *buffer;
Sergunb 0:8918a71cdbe9 504 PapAuthAckPacket *authAckPacket;
Sergunb 0:8918a71cdbe9 505
Sergunb 0:8918a71cdbe9 506 //Retrieve the length of the Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 507 length = sizeof(PapAuthAckPacket);
Sergunb 0:8918a71cdbe9 508
Sergunb 0:8918a71cdbe9 509 //Allocate a buffer memory to hold the Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 510 buffer = pppAllocBuffer(length, &offset);
Sergunb 0:8918a71cdbe9 511 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 512 if(buffer == NULL)
Sergunb 0:8918a71cdbe9 513 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 514
Sergunb 0:8918a71cdbe9 515 //Point to the Authenticate-Ack packet
Sergunb 0:8918a71cdbe9 516 authAckPacket = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 517
Sergunb 0:8918a71cdbe9 518 //Format packet header
Sergunb 0:8918a71cdbe9 519 authAckPacket->code = PAP_CODE_AUTH_ACK;
Sergunb 0:8918a71cdbe9 520 authAckPacket->identifier = identifier;
Sergunb 0:8918a71cdbe9 521 authAckPacket->length = htons(length);
Sergunb 0:8918a71cdbe9 522
Sergunb 0:8918a71cdbe9 523 //The Message field is zero or more octets, and its contents are
Sergunb 0:8918a71cdbe9 524 //implementation dependent
Sergunb 0:8918a71cdbe9 525 authAckPacket->msgLength = 0;
Sergunb 0:8918a71cdbe9 526
Sergunb 0:8918a71cdbe9 527 //Debug message
Sergunb 0:8918a71cdbe9 528 TRACE_INFO("Sending PAP Authenticate-Ack packet (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 529 //Dump packet contents for debugging purpose
Sergunb 0:8918a71cdbe9 530 pppDumpPacket((PppPacket *) authAckPacket, length, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 531
Sergunb 0:8918a71cdbe9 532 //Send PPP frame
Sergunb 0:8918a71cdbe9 533 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 534
Sergunb 0:8918a71cdbe9 535 //Free previously allocated memory block
Sergunb 0:8918a71cdbe9 536 netBufferFree(buffer);
Sergunb 0:8918a71cdbe9 537 //Return status code
Sergunb 0:8918a71cdbe9 538 return error;
Sergunb 0:8918a71cdbe9 539 }
Sergunb 0:8918a71cdbe9 540
Sergunb 0:8918a71cdbe9 541
Sergunb 0:8918a71cdbe9 542 /**
Sergunb 0:8918a71cdbe9 543 * @brief Send Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 544 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 545 * @param[in] identifier Identifier field
Sergunb 0:8918a71cdbe9 546 * @return Error code
Sergunb 0:8918a71cdbe9 547 **/
Sergunb 0:8918a71cdbe9 548
Sergunb 0:8918a71cdbe9 549 error_t papSendAuthNak(PppContext *context, uint8_t identifier)
Sergunb 0:8918a71cdbe9 550 {
Sergunb 0:8918a71cdbe9 551 error_t error;
Sergunb 0:8918a71cdbe9 552 size_t length;
Sergunb 0:8918a71cdbe9 553 size_t offset;
Sergunb 0:8918a71cdbe9 554 NetBuffer *buffer;
Sergunb 0:8918a71cdbe9 555 PapAuthNakPacket *authNakPacket;
Sergunb 0:8918a71cdbe9 556
Sergunb 0:8918a71cdbe9 557 //Retrieve the length of the Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 558 length = sizeof(PapAuthNakPacket);
Sergunb 0:8918a71cdbe9 559
Sergunb 0:8918a71cdbe9 560 //Allocate a buffer memory to hold the Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 561 buffer = pppAllocBuffer(length, &offset);
Sergunb 0:8918a71cdbe9 562 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 563 if(buffer == NULL)
Sergunb 0:8918a71cdbe9 564 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 565
Sergunb 0:8918a71cdbe9 566 //Point to the Authenticate-Nak packet
Sergunb 0:8918a71cdbe9 567 authNakPacket = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 568
Sergunb 0:8918a71cdbe9 569 //Format packet header
Sergunb 0:8918a71cdbe9 570 authNakPacket->code = PAP_CODE_AUTH_NAK;
Sergunb 0:8918a71cdbe9 571 authNakPacket->identifier = identifier;
Sergunb 0:8918a71cdbe9 572 authNakPacket->length = htons(length);
Sergunb 0:8918a71cdbe9 573
Sergunb 0:8918a71cdbe9 574 //The Message field is zero or more octets, and its contents are
Sergunb 0:8918a71cdbe9 575 //implementation dependent
Sergunb 0:8918a71cdbe9 576 authNakPacket->msgLength = 0;
Sergunb 0:8918a71cdbe9 577
Sergunb 0:8918a71cdbe9 578 //Debug message
Sergunb 0:8918a71cdbe9 579 TRACE_INFO("Sending PAP Authenticate-Nak packet (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 580 //Dump packet contents for debugging purpose
Sergunb 0:8918a71cdbe9 581 pppDumpPacket((PppPacket *) authNakPacket, length, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 582
Sergunb 0:8918a71cdbe9 583 //Send PPP frame
Sergunb 0:8918a71cdbe9 584 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_PAP);
Sergunb 0:8918a71cdbe9 585
Sergunb 0:8918a71cdbe9 586 //Free previously allocated memory block
Sergunb 0:8918a71cdbe9 587 netBufferFree(buffer);
Sergunb 0:8918a71cdbe9 588 //Return status code
Sergunb 0:8918a71cdbe9 589 return error;
Sergunb 0:8918a71cdbe9 590 }
Sergunb 0:8918a71cdbe9 591
Sergunb 0:8918a71cdbe9 592
Sergunb 0:8918a71cdbe9 593 /**
Sergunb 0:8918a71cdbe9 594 * @brief Password verification
Sergunb 0:8918a71cdbe9 595 * @param[in] context PPP context
Sergunb 0:8918a71cdbe9 596 * @param[in] password NULL-terminated string containing the password to be checked
Sergunb 0:8918a71cdbe9 597 * @return TRUE if the password is valid, else FALSE
Sergunb 0:8918a71cdbe9 598 **/
Sergunb 0:8918a71cdbe9 599
Sergunb 0:8918a71cdbe9 600 bool_t papCheckPassword(PppContext *context, const char_t *password)
Sergunb 0:8918a71cdbe9 601 {
Sergunb 0:8918a71cdbe9 602 size_t n;
Sergunb 0:8918a71cdbe9 603 bool_t status;
Sergunb 0:8918a71cdbe9 604
Sergunb 0:8918a71cdbe9 605 //This flag tells whether the password is valid
Sergunb 0:8918a71cdbe9 606 status = FALSE;
Sergunb 0:8918a71cdbe9 607
Sergunb 0:8918a71cdbe9 608 //Retrieve the length of the password
Sergunb 0:8918a71cdbe9 609 n = strlen(password);
Sergunb 0:8918a71cdbe9 610
Sergunb 0:8918a71cdbe9 611 //Compare the length of the password against the expected value
Sergunb 0:8918a71cdbe9 612 if(n == context->papFsm.passwordLen)
Sergunb 0:8918a71cdbe9 613 {
Sergunb 0:8918a71cdbe9 614 //Check whether the password is valid
Sergunb 0:8918a71cdbe9 615 if(!memcmp(password, context->papFsm.password, n))
Sergunb 0:8918a71cdbe9 616 status = TRUE;
Sergunb 0:8918a71cdbe9 617 }
Sergunb 0:8918a71cdbe9 618
Sergunb 0:8918a71cdbe9 619 //Return TRUE is the password is valid, else FALSE
Sergunb 0:8918a71cdbe9 620 return status;
Sergunb 0:8918a71cdbe9 621 }
Sergunb 0:8918a71cdbe9 622
Sergunb 0:8918a71cdbe9 623 #endif
Sergunb 0:8918a71cdbe9 624