1 /* 2 * Copyright 2003-2006, Waldemar Kornewald <wkornew@gmx.net> 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "Protocol.h" 7 #include <KPPPConfigurePacket.h> 8 #include <KPPPInterface.h> 9 10 #include <cstring> 11 #include <netinet/in.h> 12 #include <core_funcs.h> 13 #include <sys/sockio.h> 14 15 16 static const bigtime_t kPAPTimeout = 3000000; 17 // 3 seconds 18 19 // PAPHandler 20 static const uint8 kAuthenticationType = 0x3; 21 static const char *kAuthenticatorTypeString = "Authenticator"; 22 23 typedef struct authentication_item { 24 uint8 type; 25 uint8 length; 26 uint16 protocolNumber; 27 } _PACKED authentication_item; 28 29 30 PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface) 31 : KPPPOptionHandler("PAP", kAuthenticationType, interface, NULL), 32 fOwner(owner) 33 { 34 } 35 36 37 status_t 38 PAPHandler::AddToRequest(KPPPConfigurePacket& request) 39 { 40 // only local authenticators send requests to peer 41 if(Owner().Side() != PPP_PEER_SIDE) 42 return B_OK; 43 44 authentication_item item; 45 item.type = kAuthenticationType; 46 item.length = sizeof(item); 47 item.protocolNumber = htons(PAP_PROTOCOL); 48 49 request.AddItem((ppp_configure_item*) &item); 50 51 return B_OK; 52 } 53 54 55 status_t 56 PAPHandler::ParseRequest(const KPPPConfigurePacket& request, 57 int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject) 58 { 59 // only local authenticators handle requests from peer 60 if(Owner().Side() != PPP_LOCAL_SIDE) 61 return B_OK; 62 63 // we merely check if the values are correct 64 authentication_item *item = (authentication_item*) request.ItemAt(index); 65 if(item->type != kAuthenticationType 66 || item->length != 4 || ntohs(item->protocolNumber) != PAP_PROTOCOL) 67 return B_ERROR; 68 69 return B_OK; 70 } 71 72 73 // PAP 74 PAP::PAP(KPPPInterface& interface, driver_parameter *settings) 75 : KPPPProtocol("PAP", PPP_AUTHENTICATION_PHASE, PAP_PROTOCOL, PPP_PROTOCOL_LEVEL, 76 AF_UNSPEC, 0, interface, settings, PPP_ALWAYS_ALLOWED, 77 kAuthenticatorTypeString, new PAPHandler(*this, interface)), 78 fState(INITIAL), 79 fID(system_time() & 0xFF), 80 fMaxRequest(3), 81 fRequestID(0), 82 fNextTimeout(0) 83 { 84 } 85 86 87 PAP::~PAP() 88 { 89 } 90 91 92 status_t 93 PAP::InitCheck() const 94 { 95 if(Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE) 96 return B_ERROR; 97 98 return KPPPProtocol::InitCheck(); 99 } 100 101 102 bool 103 PAP::Up() 104 { 105 TRACE("PAP: Up() state=%d\n", State()); 106 107 switch(State()) { 108 case INITIAL: 109 if(Side() == PPP_LOCAL_SIDE) { 110 NewState(REQ_SENT); 111 InitializeRestartCount(); 112 SendRequest(); 113 } else if(Side() == PPP_PEER_SIDE) { 114 NewState(WAITING_FOR_REQ); 115 InitializeRestartCount(); 116 fNextTimeout = system_time() + kPAPTimeout; 117 } else { 118 UpFailedEvent(); 119 return false; 120 } 121 break; 122 123 default: 124 ; 125 } 126 127 return true; 128 } 129 130 131 bool 132 PAP::Down() 133 { 134 TRACE("PAP: Down() state=%d\n", State()); 135 136 switch(Interface().Phase()) { 137 case PPP_DOWN_PHASE: 138 // interface finished terminating 139 case PPP_ESTABLISHED_PHASE: 140 // terminate this NCP individually (block until we finished terminating) 141 NewState(INITIAL); 142 DownEvent(); 143 break; 144 145 /* case PPP_TERMINATION_PHASE: 146 // interface is terminating 147 break; 148 149 case PPP_ESTABLISHMENT_PHASE: 150 // interface is reconfiguring 151 break; 152 */ 153 default: 154 ; 155 } 156 157 return true; 158 } 159 160 161 status_t 162 PAP::Send(struct mbuf *packet, uint16 protocolNumber) 163 { 164 // we do not encapsulate PAP packets 165 m_freem(packet); 166 return B_ERROR; 167 } 168 169 170 status_t 171 PAP::Receive(struct mbuf *packet, uint16 protocolNumber) 172 { 173 if(!packet) 174 return B_ERROR; 175 176 if(protocolNumber != PAP_PROTOCOL) 177 return PPP_UNHANDLED; 178 179 ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); 180 181 // check if the packet is meant for us: 182 // only peer authenticators handle requests 183 if(data->code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE) 184 return PPP_UNHANDLED; 185 // only local authenticators handle acks and naks 186 if((data->code == PPP_CONFIGURE_ACK || data->code == PPP_CONFIGURE_NAK) 187 && Side() != PPP_LOCAL_SIDE) 188 return PPP_UNHANDLED; 189 190 // remove padding 191 int32 length = packet->m_len; 192 if(packet->m_flags & M_PKTHDR) 193 length = packet->m_pkthdr.len; 194 length -= ntohs(data->length); 195 if(length) 196 m_adj(packet, -length); 197 198 if(ntohs(data->length) < 4) 199 return B_ERROR; 200 201 // packet is freed by event methods 202 // code values are the same as for LCP (but very reduced) 203 switch(data->code) { 204 case PPP_CONFIGURE_REQUEST: 205 RREvent(packet); 206 break; 207 208 case PPP_CONFIGURE_ACK: 209 RAEvent(packet); 210 break; 211 212 case PPP_CONFIGURE_NAK: 213 RNEvent(packet); 214 break; 215 216 default: 217 return PPP_UNHANDLED; 218 } 219 220 return B_OK; 221 } 222 223 224 void 225 PAP::Pulse() 226 { 227 if(fNextTimeout == 0 || fNextTimeout > system_time()) 228 return; 229 fNextTimeout = 0; 230 231 switch(State()) { 232 case REQ_SENT: 233 case WAITING_FOR_REQ: 234 if(fRequestCounter <= 0) 235 TOBadEvent(); 236 else 237 TOGoodEvent(); 238 break; 239 240 default: 241 ; 242 } 243 } 244 245 246 uint8 247 PAP::NextID() 248 { 249 return (uint8) atomic_add(&fID, 1); 250 } 251 252 253 void 254 PAP::NewState(pap_state next) 255 { 256 TRACE("PAP: NewState(%d) state=%d\n", next, State()); 257 258 // state changes 259 if(State() == INITIAL && next != State()) { 260 if(Side() == PPP_LOCAL_SIDE) 261 Interface().StateMachine().LocalAuthenticationRequested(); 262 else if(Side() == PPP_PEER_SIDE) 263 Interface().StateMachine().PeerAuthenticationRequested(); 264 265 UpStarted(); 266 } else if(State() == ACCEPTED && next != State()) 267 DownStarted(); 268 269 // maybe we do not need the timer anymore 270 if(next == INITIAL || next == ACCEPTED) 271 fNextTimeout = 0; 272 273 fState = next; 274 } 275 276 277 void 278 PAP::TOGoodEvent() 279 { 280 TRACE("PAP: TOGoodEvent() state=%d\n", State()); 281 282 switch(State()) { 283 case REQ_SENT: 284 SendRequest(); 285 break; 286 287 case WAITING_FOR_REQ: 288 fNextTimeout = system_time() + kPAPTimeout; 289 break; 290 291 default: 292 ; 293 } 294 } 295 296 297 void 298 PAP::TOBadEvent() 299 { 300 TRACE("PAP: TOBadEvent() state=%d\n", State()); 301 302 switch(State()) { 303 case REQ_SENT: 304 case WAITING_FOR_REQ: 305 NewState(INITIAL); 306 if(State() == REQ_SENT) 307 Interface().StateMachine().LocalAuthenticationDenied( 308 Interface().Username()); 309 else 310 Interface().StateMachine().PeerAuthenticationDenied( 311 Interface().Username()); 312 313 UpFailedEvent(); 314 break; 315 316 default: 317 ; 318 } 319 } 320 321 322 void 323 PAP::RREvent(struct mbuf *packet) 324 { 325 TRACE("PAP: RREvent() state=%d\n", State()); 326 327 ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); 328 int32 length = ntohs(request->length); 329 uint8 *data = request->data; 330 uint8 *userLength = data; 331 uint8 *passwordLength = data + 1 + data[0]; 332 333 // make sure the length values are all okay 334 if(6 + *userLength + *passwordLength > length) { 335 m_freem(packet); 336 return; 337 } 338 339 char *peerUsername = (char*) userLength + 1, 340 *peerPassword = (char*) passwordLength + 1; 341 const char *username = Interface().Username(), *password = Interface().Password(); 342 343 if(*userLength == strlen(username) && *passwordLength == strlen(password) 344 && !strncmp(peerUsername, username, *userLength) 345 && !strncmp(peerPassword, password, *passwordLength)) { 346 NewState(ACCEPTED); 347 Interface().StateMachine().PeerAuthenticationAccepted(username); 348 UpEvent(); 349 SendAck(packet); 350 } else { 351 NewState(INITIAL); 352 Interface().StateMachine().PeerAuthenticationDenied(username); 353 UpFailedEvent(); 354 SendNak(packet); 355 } 356 } 357 358 359 void 360 PAP::RAEvent(struct mbuf *packet) 361 { 362 TRACE("PAP: RAEvent() state=%d\n", State()); 363 364 if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) { 365 // this packet is not a reply to our request 366 367 // TODO: log this event 368 m_freem(packet); 369 return; 370 } 371 372 switch(State()) { 373 case REQ_SENT: 374 NewState(ACCEPTED); 375 Interface().StateMachine().LocalAuthenticationAccepted( 376 Interface().Username()); 377 UpEvent(); 378 break; 379 380 default: 381 ; 382 } 383 384 m_freem(packet); 385 } 386 387 388 void 389 PAP::RNEvent(struct mbuf *packet) 390 { 391 TRACE("PAP: RNEvent() state=%d\n", State()); 392 393 if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) { 394 // this packet is not a reply to our request 395 396 // TODO: log this event 397 m_freem(packet); 398 return; 399 } 400 401 switch(State()) { 402 case REQ_SENT: 403 NewState(INITIAL); 404 Interface().StateMachine().LocalAuthenticationDenied( 405 Interface().Username()); 406 UpFailedEvent(); 407 break; 408 409 default: 410 ; 411 } 412 413 m_freem(packet); 414 } 415 416 417 void 418 PAP::InitializeRestartCount() 419 { 420 fRequestCounter = fMaxRequest; 421 } 422 423 424 bool 425 PAP::SendRequest() 426 { 427 TRACE("PAP: SendRequest() state=%d\n", State()); 428 429 --fRequestCounter; 430 fNextTimeout = system_time() + kPAPTimeout; 431 432 struct mbuf *packet = m_gethdr(MT_DATA); 433 if(!packet) 434 return false; 435 436 const char *username = Interface().Username(), *password = Interface().Password(); 437 438 packet->m_pkthdr.len = packet->m_len = 6 + strlen(username) + strlen(password); 439 440 // reserve some space for overhead (we are lazy and reserve too much) 441 packet->m_data += Interface().PacketOverhead(); 442 443 ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); 444 request->code = PPP_CONFIGURE_REQUEST; 445 request->id = fRequestID = NextID(); 446 request->length = htons(packet->m_len); 447 uint8 *data = request->data; 448 data[0] = strlen(username); 449 memcpy(data + 1, username, strlen(username)); 450 data[1 + data[0]] = strlen(password); 451 memcpy(data + 2 + data[0], password, strlen(password)); 452 453 return Interface().Send(packet, PAP_PROTOCOL) == B_OK; 454 } 455 456 457 bool 458 PAP::SendAck(struct mbuf *packet) 459 { 460 TRACE("PAP: SendAck() state=%d\n", State()); 461 462 if(!packet) 463 return false; 464 465 ppp_lcp_packet *ack = mtod(packet, ppp_lcp_packet*); 466 ack->code = PPP_CONFIGURE_ACK; 467 packet->m_len = 5; 468 if(packet->m_flags & M_PKTHDR) 469 packet->m_pkthdr.len = 5; 470 ack->length = htons(packet->m_len); 471 472 ack->data[0] = 0; 473 474 return Interface().Send(packet, PAP_PROTOCOL) == B_OK; 475 } 476 477 478 bool 479 PAP::SendNak(struct mbuf *packet) 480 { 481 TRACE("PAP: SendNak() state=%d\n", State()); 482 483 if(!packet) 484 return false; 485 486 ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*); 487 nak->code = PPP_CONFIGURE_NAK; 488 packet->m_len = 5; 489 if(packet->m_flags & M_PKTHDR) 490 packet->m_pkthdr.len = 5; 491 nak->length = htons(packet->m_len); 492 493 nak->data[0] = 0; 494 495 return Interface().Send(packet, PAP_PROTOCOL) == B_OK; 496 } 497