Add license
[l2tpns.git] / ppp.c
1 // L2TPNS PPP Stuff
2 // $Id: ppp.c,v 1.1 2003/12/16 07:07:39 fred_nerk Exp $
3
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <errno.h>
8 #include <stdlib.h>
9 #include "l2tpns.h"
10 #include "constants.h"
11 #include "plugin.h"
12 #include "util.h"
13
14 extern char debug;
15 extern tunnelt *tunnel;
16 extern sessiont *session;
17 extern radiust *radius;
18 extern u16 tapmac[3];
19 extern int tapfd;
20 extern char hostname[1000];
21 extern struct Tstats *_statistics;
22 extern unsigned long eth_tx;
23 extern time_t time_now;
24
25 // Process PAP messages
26 void processpap(tunnelidt t, sessionidt s, u8 * p, u16 l)
27 {
28 char user[129];
29 char pass[129];
30
31 #ifdef STAT_CALLS
32 STAT(call_processpap);
33 #endif
34 log_hex(5, "PAP", p, l);
35 if (l < 4)
36 {
37 log(1, 0, s, t, "Short PAP %u bytes", l);
38 STAT(tunnel_rx_errors);
39 return ;
40 }
41 if (*p != 1)
42 {
43 log(1, 0, s, t, "Unexpected PAP code %d\n", *p);
44 STAT(tunnel_rx_errors);
45 return ;
46 }
47 if (ntohs(*(u16 *) (p + 2)) > l)
48 {
49 log(1, 0, s, t, "Length mismatch PAP %d/%d\n", ntohs(*(u16 *) (p + 2)), l);
50 STAT(tunnel_rx_errors);
51 return ;
52 }
53 {
54 u8 *b = p;
55 b += 4;
56 if (*b && *b < sizeof(user))
57 memcpy(user, b + 1, *b);
58 user[*b] = 0;
59 b += 1 + *b;
60 if (*b && *b < sizeof(pass))
61 memcpy(pass, b + 1, *b);
62 pass[*b] = 0;
63 log(3, 0, s, t, "PAP login %s/%s\n", user, pass);
64 }
65 if (session[s].ip || !session[s].radius)
66 {
67 // respond now, either no RADIUS available or already authenticated
68 u8 b[MAXCONTROL];
69 u8 id = p[1];
70 u8 *p = makeppp(b, 0, 0, t, s, PPPPAP);
71 if (session[s].ip)
72 *p = 2; // ACK
73 else
74 *p = 3; // cant authorise
75 p[1] = id;
76 *(u16 *) (p + 2) = htons(5); // length
77 p[4] = 0; // no message
78 if (session[s].ip)
79 {
80 log(3, session[s].ip, s, t, "%d Already an IP allocated: %s (%d)\n", getpid(), inet_toa(htonl(session[s].ip)), session[s].ip);
81 }
82 else
83 {
84 log(1, 0, s, t, "No radius session available to authenticate session...\n");
85 }
86 log(3, 0, s, t, "Fallback response to PAP (%s)\n", (session[s].ip) ? "ACK" : "NAK");
87 tunnelsend(b, 5 + (p - b), t); // send it
88 }
89 else
90 { // set up RADIUS request
91 u8 r = session[s].radius;
92
93 // Run PRE_AUTH plugins
94 struct param_pre_auth packet = { &tunnel[t], &session[s], strdup(user), strdup(pass), PPPPAP, 1 };
95 run_plugins(PLUGIN_PRE_AUTH, &packet);
96 if (!packet.continue_auth)
97 {
98 log(3, 0, s, t, "A plugin rejected PRE_AUTH\n");
99 if (packet.username) free(packet.username);
100 if (packet.password) free(packet.password);
101 return;
102 }
103
104 strncpy(session[s].user, packet.username, sizeof(session[s].user));
105 strncpy(radius[r].pass, packet.password, sizeof(radius[r].pass));
106
107 free(packet.username);
108 free(packet.password);
109
110 radius[r].id = p[1];
111 log(3, 0, s, t, "Sending login for %s/%s to radius\n", user, pass);
112 radiussend(r, RADIUSAUTH);
113 }
114 }
115
116 // Process CHAP messages
117 void processchap(tunnelidt t, sessionidt s, u8 * p, u16 l)
118 {
119 u8 r;
120 u16 len;
121
122 #ifdef STAT_CALLS
123 STAT(call_processchap);
124 #endif
125 log_hex(5, "CHAP", p, l);
126 r = session[s].radius;
127 if (!r)
128 {
129 log(1, 0, s, t, "Unexpected CHAP message\n");
130 STAT(tunnel_rx_errors);
131 return;
132 }
133 if (*p != 2)
134 {
135 log(1, 0, s, t, "Unexpected CHAP response code %d\n", *p);
136 STAT(tunnel_rx_errors);
137 return;
138 }
139 if (p[1] != radius[r].id)
140 {
141 log(1, 0, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
142 STAT(tunnel_rx_errors);
143 return ;
144 }
145 len = ntohs(*(u16 *) (p + 2));
146 if (len > l)
147 {
148 log(1, 0, s, t, "Bad CHAP length %d\n", len);
149 STAT(tunnel_rx_errors);
150 return ;
151 }
152 if (p[4] != 16)
153 {
154 log(1, 0, s, t, "Bad CHAP response length %d\n", p[4]);
155 STAT(tunnel_rx_errors);
156 return ;
157 }
158 if (len - 21 >= sizeof(session[s].user))
159 {
160 log(1, 0, s, t, "CHAP user too long %d\n", len - 21);
161 STAT(tunnel_rx_errors);
162 return ;
163 }
164
165 // Run PRE_AUTH plugins
166 {
167 struct param_pre_auth packet = { &tunnel[t], &session[s], NULL, NULL, PPPCHAP, 1 };
168
169 packet.username = calloc(len-20, 1);
170 packet.password = calloc(16, 1);
171 memcpy(packet.username, p + 21, len - 21);
172 memcpy(packet.password, p + 5, 16);
173
174 run_plugins(PLUGIN_PRE_AUTH, &packet);
175 if (!packet.continue_auth)
176 {
177 log(3, 0, s, t, "A plugin rejected PRE_AUTH\n");
178 if (packet.username) free(packet.username);
179 if (packet.password) free(packet.password);
180 return;
181 }
182
183 strncpy(session[s].user, packet.username, sizeof(session[s].user));
184 memcpy(radius[r].pass, packet.password, 16);
185
186 free(packet.username);
187 free(packet.password);
188 }
189
190 radius[r].chap = 1;
191 radiussend(r, RADIUSAUTH);
192 log(3, 0, s, t, "CHAP login %s\n", session[s].user);
193 }
194
195 char *ppp_lcp_types[] = {
196 NULL,
197 "ConfigReq",
198 "ConfigAck",
199 "ConfigNak",
200 "ConfigRej",
201 "TerminateReq",
202 "TerminateAck",
203 "CodeRej",
204 "ProtocolRej",
205 "EchoReq",
206 "EchoReply",
207 "DiscardRequest",
208 };
209
210 void dumplcp(char *p, int l)
211 {
212 signed int x = l - 3;
213 char *o = (p + 3);
214
215 log_hex(5, "PPP LCP Packet", p, l);
216 log(4, 0, 0, 0, "PPP LCP Packet type %d (%s)\n", *p, ppp_lcp_types[(int)*p]);
217 log(4, 0, 0, 0, "Length: %d\n", l);
218 if (*p != ConfigReq && *p != ConfigRej && *p != ConfigAck)
219 return;
220
221 while (x > 2)
222 {
223 int type = *(u8 *)(o);
224 int length = *(u8 *)(o + 1);
225 if (length == 0)
226 {
227 log(4, 0, 0, 0, " Option length is 0...\n");
228 break;
229 }
230 if (type == 0)
231 {
232 log(4, 0, 0, 0, " Option type is 0...\n");
233 x -= length;
234 o += length;
235 continue;
236 }
237 switch (type)
238 {
239 case 1: // Maximum-Receive-Unit
240 log(4, 0, 0, 0, " %s %d\n", lcp_types[type], ntohs(*(u16 *)(o + 2)));
241 break;
242 case 3: // Authentication-Protocol
243 {
244 int proto = ntohs(*(u16 *)(o + 2));
245 log(4, 0, 0, 0, " %s %s\n", lcp_types[type],
246 proto == 0xC223 ? "CHAP" : "PAP");
247 break;
248 }
249 case 5: // Magic-Number
250 {
251 u32 magicno = ntohl(*(u32 *)(o + 2));
252 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], magicno);
253 break;
254 }
255 case 4: // Quality-Protocol
256 {
257 u32 qp = ntohl(*(u32 *)(o + 2));
258 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], qp);
259 break;
260 }
261 case 7: // Protocol-Field-Compression
262 {
263 u32 pfc = ntohl(*(u32 *)(o + 2));
264 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], pfc);
265 break;
266 }
267 case 8: // Address-And-Control-Field-Compression
268 {
269 u32 afc = ntohl(*(u32 *)(o + 2));
270 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], afc);
271 break;
272 }
273 default:
274 log(2, 0, 0, 0, " Unknown PPP LCP Option type %d\n", type);
275 break;
276 }
277 x -= length;
278 o += length;
279 }
280 }
281
282 // Process LCP messages
283 void processlcp(tunnelidt t, sessionidt s, u8 * p, u16 l)
284 {
285 u8 b[MAXCONTROL];
286 u8 *q = NULL;
287
288 #ifdef STAT_CALLS
289 STAT(call_processlcp);
290 #endif
291 log_hex(5, "LCP", p, l);
292 if (l < 4)
293 {
294 log(1, session[s].ip, s, t, "Short LCP %d bytes", l);
295 STAT(tunnel_rx_errors);
296 return ;
297 }
298 if (*p == ConfigAck)
299 {
300 log(3, session[s].ip, s, t, "LCP: Discarding ConfigAck\n");
301 }
302 else if (*p == ConfigReq)
303 {
304 signed int x = l - 1;
305 char *o = (p + 1);
306
307 log(3, session[s].ip, s, t, "LCP: ConfigReq (%d bytes)...\n", l);
308
309 while (x > 2)
310 {
311 int type = *(u8 *)(o);
312 int length = *(u8 *)(o + 1);
313 if (length == 0 || type == 0) break;
314 switch (type)
315 {
316 case 1: // Maximum-Receive-Unit
317 session[s].mru = ntohs(*(u16 *)(o + 2));
318 break;
319 case 3: // Authentication-Protocol
320 {
321 int proto = ntohs(*(u16 *)(o + 2));
322 if (proto == 0xC223)
323 {
324 log(2, session[s].ip, s, t, " Remote end is trying to do CHAP. Rejecting it.\n");
325
326 if (!q)
327 {
328 q = makeppp(b, p, l, t, s, PPPLCP);
329 *q++ = ConfigNak;
330 }
331 memcpy(q, o, length);
332 *(u16 *)(q += 2) = htons(0xC023); // NAK -> Use PAP instead
333 q += length;
334 }
335 break;
336 }
337 case 5: // Magic-Number
338 {
339 // u32 magicno = ntohl(*(u32 *)(o + 2));
340 break;
341 }
342 case 4: // Quality-Protocol
343 {
344 // u32 qp = ntohl(*(u32 *)(o + 2));
345 break;
346 }
347 case 7: // Protocol-Field-Compression
348 {
349 // u32 pfc = ntohl(*(u32 *)(o + 2));
350 break;
351 }
352 case 8: // Address-And-Control-Field-Compression
353 {
354 // u32 afc = ntohl(*(u32 *)(o + 2));
355 break;
356 }
357 default:
358 log(2, session[s].ip, s, t, " Unknown PPP LCP Option type %d\n", type);
359 break;
360 }
361 x -= length;
362 o += length;
363 }
364
365 if (!q)
366 {
367 // Send back a ConfigAck
368 log(3, session[s].ip, s, t, "ConfigReq accepted, sending as Ack\n");
369 q = makeppp(b, p, l, t, s, PPPLCP);
370 *q = ConfigAck;
371 tunnelsend(b, l + (q - b), t);
372 }
373 else
374 {
375 // Already built a ConfigNak... send it
376 log(3, session[s].ip, s, t, "Sending ConfigNak\n");
377 tunnelsend(b, l + (q - b), t);
378
379 log(3, session[s].ip, s, t, "Sending ConfigReq, requesting PAP login\n");
380 q = makeppp(b, NULL, 0, t, s, PPPLCP);
381 *q++ = ConfigReq;
382 *(u8 *)(q++) = 3;
383 *(u8 *)(q++) = 4;
384 *(u16 *)(q += 2) = htons(0xC023);
385 tunnelsend(b, l + (q - b), t);
386 }
387 }
388 else if (*p == ConfigNak)
389 {
390 log(1, session[s].ip, s, t, "Remote end sent a ConfigNak. Ignoring\n");
391 dumplcp(p, l);
392 return ;
393 }
394 else if (*p == TerminateReq)
395 {
396 *p = TerminateAck; // close
397 q = makeppp(b, p, l, t, s, PPPLCP);
398 log(3, session[s].ip, s, t, "LCP: Received TerminateReq. Sending TerminateAck\n");
399 sessionshutdown(s, "Remote end closed connection.");
400 tunnelsend(b, l + (q - b), t); // send it
401 }
402 else if (*p == TerminateReq)
403 {
404 sessionshutdown(s, "Remote end closed connection.");
405 }
406 else if (*p == EchoReq)
407 {
408 *p = EchoReply; // reply
409 *(u32 *) (p + 4) = htonl(session[s].magic); // our magic number
410 q = makeppp(b, p, l, t, s, PPPLCP);
411 log(3, session[s].ip, s, t, "LCP: Received EchoReq. Sending EchoReply\n");
412 tunnelsend(b, l + (q - b), t); // send it
413 }
414 else if (*p == EchoReply)
415 {
416 // Ignore it, last_packet time is set earlier than this.
417 }
418 else
419 {
420 log(1, session[s].ip, s, t, "Unexpected LCP code %d\n", *p);
421 STAT(tunnel_rx_errors);
422 return ;
423 }
424 }
425
426 // Process IPCP messages
427 void processipcp(tunnelidt t, sessionidt s, u8 * p, u16 l)
428 {
429 #ifdef STAT_CALLS
430 STAT(call_processipcp);
431 #endif
432 log_hex(5, "IPCP", p, l);
433 if (l < 5)
434 {
435 log(1, 0, s, t, "Short IPCP %d bytes", l);
436 STAT(tunnel_rx_errors);
437 return ;
438 }
439 if (*p == ConfigAck)
440 { // happy with our IPCP
441 u8 r = session[s].radius;
442 if ((!r || radius[r].state == RADIUSIPCP) && !session[s].walled_garden)
443 if (!r)
444 r = radiusnew(s);
445 if (r)
446 radiussend(r, RADIUSSTART); // send radius start, having got IPCP at last
447 return ; // done
448 }
449 if (*p != ConfigReq)
450 {
451 log(1, 0, s, t, "Unexpected IPCP code %d\n", *p);
452 STAT(tunnel_rx_errors);
453 return ;
454 }
455 if (ntohs(*(u16 *) (p + 2)) > l)
456 {
457 log(1, 0, s, t, "Length mismatch IPCP %d/%d\n", ntohs(*(u16 *) (p + 2)), l);
458 STAT(tunnel_rx_errors);
459 return ;
460 }
461 if (!session[s].ip)
462 {
463 log(3, 0, s, t, "Waiting on radius reply\n");
464 return ; // have to wait on RADIUS eply
465 }
466 // form a config reply quoting the IP in the session
467 {
468 u8 b[MAXCONTROL];
469 u8 *i,
470 *q;
471
472 q = p + 4;
473 i = p + l;
474 while (q < i && q[1])
475 {
476 if (*q != 0x81 && *q != 0x83 && *q != 3)
477 break;
478 q += q[1];
479 }
480 if (q < i)
481 { // reject
482 u16 n = 4;
483 i = p + l;
484 q = makeppp(b, p, l, t, s, PPPIPCP);
485 *q = ConfigRej;
486 p += 4;
487 while (p < i && p[1])
488 {
489 if (*p != 0x81 && *p != 0x83 && *p != 3)
490 {
491 log(2, 0, s, t, "IPCP reject %d\n", *p);
492 memcpy(q + n, p, p[1]);
493 n += p[1];
494 }
495 p += p[1];
496 }
497 *(u16 *) (q + 2) = htons(n);
498 tunnelsend(b, n + (q - b), t); // send it
499 }
500 else
501 {
502 *p = ConfigAck;
503 i = findppp(p, 0x81); // Primary DNS address
504 if (i)
505 {
506 if (*(u32 *) (i + 2) != htonl(session[s].dns1))
507 {
508 *(u32 *) (i + 2) = htonl(session[s].dns1);
509 *p = ConfigNak;
510 }
511 }
512 i = findppp(p, 0x83); // Secondary DNS address (TBA, is it)
513 if (i)
514 {
515 if (*(u32 *) (i + 2) != htonl(session[s].dns2))
516 {
517 *(u32 *) (i + 2) = htonl(session[s].dns2);
518 *p = ConfigNak;
519 }
520 }
521 i = findppp(p, 3); // IP address
522 if (!i || i[1] != 6)
523 {
524 log(1, 0, s, t, "No IP in IPCP request\n");
525 STAT(tunnel_rx_errors);
526 return ;
527 }
528 if (*(u32 *) (i + 2) != htonl(session[s].ip))
529 {
530 *(u32 *) (i + 2) = htonl(session[s].ip);
531 *p = ConfigNak;
532 }
533 q = makeppp(b, p, l, t, s, PPPIPCP);
534 tunnelsend(b, l + (q - b), t); // send it
535 }
536 }
537 }
538
539 // process IP packet received
540 void processipin(tunnelidt t, sessionidt s, u8 * p, u16 l)
541 {
542 #ifdef STAT_CALLS
543 STAT(call_processipin);
544 #endif
545 log_hex(5, "IP", p, l);
546
547 if (l > MAXETHER)
548 {
549 log(1, *(u32 *)(p + 12), s, t, "IP packet too long %d\n", l);
550 STAT(tunnel_rx_errors);
551 return ;
552 }
553
554 session[s].cin += l;
555 session[s].pin++;
556 eth_tx += l;
557
558 // Add on the tun header
559 p -= 4;
560 *(u32 *)p = htonl(0x00000800);
561 l += 4;
562
563 // Plugin hook
564 {
565 struct param_packet_rx packet = { &tunnel[t], &session[s], p, l };
566 run_plugins(PLUGIN_PACKET_TX, &packet);
567 }
568
569 // send to ethernet
570 if (write(tapfd, p, l) < 0)
571 {
572 STAT(tap_tx_errors);
573 log(0, 0, s, t, "Error writing %d bytes to TAP device: %s (tapfd=%d, p=%p)\n",
574 l, strerror(errno), tapfd, p);
575 }
576
577 if (session[s].snoop)
578 {
579 // Snooping this session, send it to ASIO
580 snoop_send_packet(p, l);
581 }
582 STAT(tap_tx_packets);
583 INC_STAT(tap_tx_bytes, l);
584 }
585
586 // Process LCP messages
587 void processccp(tunnelidt t, sessionidt s, u8 * p, u16 l)
588 {
589 #ifdef STAT_CALLS
590 STAT(call_processccp);
591 #endif
592 log_hex(5, "CCP", p, l);
593 if (l < 2 || (*p != ConfigReq && *p != TerminateReq))
594 {
595 log(1, 0, s, t, "Unexpecetd CCP request code %d\n", *p);
596 STAT(tunnel_rx_errors);
597 return ;
598 }
599 // reject
600 {
601 u8 b[MAXCONTROL];
602 u8 *q;
603 if (*p == ConfigReq)
604 {
605 if (l < 6)
606 {
607 *p = ConfigAck; // accept no compression
608 }
609 else
610 {
611 *p = ConfigRej; // reject
612 }
613 }
614 else
615 *p = TerminateAck; // close
616 q = makeppp(b, p, l, t, s, PPPCCP);
617 tunnelsend(b, l + (q - b), t); // send it
618 }
619 }
620
621 // send a CHAP PP packet
622 void sendchap(tunnelidt t, sessionidt s)
623 {
624 u8 b[MAXCONTROL];
625 u8 r = session[s].radius;
626 u8 *q;
627 #ifdef STAT_CALLS
628 STAT(call_sendchap);
629 #endif
630 if (!r)
631 {
632 log(1, 0, s, t, "No RADIUS to send challenge\n");
633 STAT(tunnel_tx_errors);
634 return ;
635 }
636 log(1, 0, s, t, "Send CHAP challenge\n");
637 { // new challenge
638 int n;
639 for (n = 0; n < 15; n++)
640 radius[r].auth[n] = rand();
641 }
642 radius[r].chap = 1; // CHAP not PAP
643 radius[r].id++;
644 if (radius[r].state != RADIUSCHAP)
645 radius[r].try = 0;
646 radius[r].state = RADIUSCHAP;
647 radius[r].retry = backoff(radius[r].try++);
648 if (radius[r].try > 5)
649 {
650 sessionshutdown(s, "Timeout CHAP");
651 STAT(tunnel_tx_errors);
652 return ;
653 }
654 q = makeppp(b, 0, 0, t, s, PPPCHAP);
655 *q = 1; // challenhe
656 q[1] = radius[r].id; // ID
657 q[4] = 16; // length
658 memcpy(q + 5, radius[r].auth, 16); // challenge
659 strcpy(q + 21, hostname); // our name
660 *(u16 *) (q + 2) = htons(strlen(hostname) + 21); // length
661 tunnelsend(b, strlen(hostname) + 21 + (q - b), t); // send it
662 }
663
664 // fill in a L2TP message with a PPP frame,
665 // copies existing PPP message and changes magic number if seen
666 // returns start of PPP frame
667 u8 *makeppp(u8 * b, u8 * p, int l, tunnelidt t, sessionidt s, u16 mtype)
668 {
669 *(u16 *) (b + 0) = htons(0x0002); // L2TP with no options
670 *(u16 *) (b + 2) = htons(tunnel[t].far); // tunnel
671 *(u16 *) (b + 4) = htons(session[s].far); // session
672 b += 6;
673 if (mtype != PPPLCP && !(session[s].flags & SESSIONACFC))
674 {
675 *(u16 *) b = htons(0xFF03); // HDLC header
676 b += 2;
677 }
678 if (mtype < 0x100 && session[s].flags & SESSIONPFC)
679 *b++ = mtype;
680 else
681 {
682 *(u16 *) b = htons(mtype);
683 b += 2;
684 }
685 if (p && l)
686 memcpy(b, p, l);
687 return b;
688 }
689
690 // find a PPP option, returns point to option, or 0 if not found
691 u8 *findppp(u8 * b, u8 mtype)
692 {
693 u16 l = ntohs(*(u16 *) (b + 2));
694 if (l < 4)
695 return 0;
696 b += 4;
697 l -= 4;
698 while (l)
699 {
700 if (l < b[1] || !b[1])
701 return 0; // faulty
702 if (*b == mtype)
703 return b;
704 l -= b[1];
705 b += b[1];
706 }
707 return 0;
708 }
709
710 // Send initial LCP ConfigReq
711 void initlcp(tunnelidt t, sessionidt s)
712 {
713 char b[500] = {0}, *q;
714
715 q = makeppp(b, NULL, 0, t, s, PPPLCP);
716 log(4, 0, s, t, "Sending LCP ConfigReq for PAP\n");
717 *q = ConfigReq;
718 *(u8 *)(q + 1) = (time_now % 255) + 1; // ID
719 *(u16 *)(q + 2) = htons(8); // Length
720 *(u8 *)(q + 4) = 3;
721 *(u8 *)(q + 5) = 4;
722 *(u16 *)(q + 6) = htons(0xC023); // PAP
723 tunnelsend(b, 12 + 8, t);
724 }
725