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
PAPHandler(PAP & owner,KPPPInterface & interface)30 PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface)
31 : KPPPOptionHandler("PAP", kAuthenticationType, interface, NULL),
32 fOwner(owner)
33 {
34 }
35
36
37 status_t
SendingAck(const KPPPConfigurePacket & ack)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
AddToRequest(KPPPConfigurePacket & request)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
ParseRequest(const KPPPConfigurePacket & request,int32 index,KPPPConfigurePacket & nak,KPPPConfigurePacket & reject)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
PAP(KPPPInterface & interface,driver_parameter * settings)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
~PAP()95 PAP::~PAP()
96 {
97 }
98
99
100 status_t
InitCheck() const101 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
Up()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
Down()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
Send(net_buffer * packet,uint16 protocolNumber)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
Receive(net_buffer * packet,uint16 protocolNumber)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
Pulse()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
NextID()256 PAP::NextID()
257 {
258 return (uint8) atomic_add(&fID, 1);
259 }
260
261
262 void
NewState(pap_state next)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
TOGoodEvent()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
TOBadEvent()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
RREvent(net_buffer * packet)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
RAEvent(net_buffer * packet)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
RNEvent(net_buffer * packet)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
InitializeRestartCount()438 PAP::InitializeRestartCount()
439 {
440 fRequestCounter = fMaxRequest;
441 }
442
443
444 bool
SendRequest()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
SendAck(net_buffer * packet)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
SendNak(net_buffer * packet)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