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
16static const bigtime_t kPAPTimeout = 3000000;
17	// 3 seconds
18
19// PAPHandler
20static const uint8 kAuthenticationType = 0x3;
21static const char *kAuthenticatorTypeString = "Authenticator";
22
23typedef struct authentication_item {
24	uint8 type;
25	uint8 length;
26	uint16 protocolNumber;
27} _PACKED authentication_item;
28
29
30PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface)
31	: KPPPOptionHandler("PAP", kAuthenticationType, interface, NULL),
32	fOwner(owner)
33{
34}
35
36
37status_t
38PAPHandler::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
45status_t
46PAPHandler::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
63status_t
64PAPHandler::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
82PAP::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
95PAP::~PAP()
96{
97}
98
99
100status_t
101PAP::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
110bool
111PAP::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
139bool
140PAP::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
169status_t
170PAP::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
180status_t
181PAP::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
233void
234PAP::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
255uint8
256PAP::NextID()
257{
258	return (uint8) atomic_add(&fID, 1);
259}
260
261
262void
263PAP::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
286void
287PAP::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
306void
307PAP::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
331void
332PAP::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
371void
372PAP::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
404void
405PAP::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
437void
438PAP::InitializeRestartCount()
439{
440	fRequestCounter = fMaxRequest;
441}
442
443
444bool
445PAP::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
478bool
479PAP::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
502bool
503PAP::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