xref: /haiku/src/add-ons/kernel/network/ppp/pap/Protocol.cpp (revision bab64f65bb775dc23060e276f1f1c4498ab7af6c)
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