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