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