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