New config file format
[l2tpns.git] / ppp.c
1 // L2TPNS PPP Stuff
2 // $Id: ppp.c,v 1.2 2004/03/05 00:09:03 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 tunnelt *tunnel;
15 extern sessiont *session;
16 extern radiust *radius;
17 extern int tapfd;
18 extern char hostname[1000];
19 extern struct Tstats *_statistics;
20 extern unsigned long eth_tx;
21 extern time_t time_now;
22 extern struct configt *config;
23
24 // Process PAP messages
25 void processpap(tunnelidt t, sessionidt s, u8 * p, u16 l)
26 {
27 char user[129];
28 char pass[129];
29
30 #ifdef STAT_CALLS
31 STAT(call_processpap);
32 #endif
33 log_hex(5, "PAP", p, l);
34 if (l < 4)
35 {
36 log(1, 0, s, t, "Short PAP %u bytes", l);
37 STAT(tunnel_rx_errors);
38 return ;
39 }
40 if (*p != 1)
41 {
42 log(1, 0, s, t, "Unexpected PAP code %d\n", *p);
43 STAT(tunnel_rx_errors);
44 return ;
45 }
46 if (ntohs(*(u16 *) (p + 2)) > l)
47 {
48 log(1, 0, s, t, "Length mismatch PAP %d/%d\n", ntohs(*(u16 *) (p + 2)), l);
49 STAT(tunnel_rx_errors);
50 return ;
51 }
52 {
53 u8 *b = p;
54 b += 4;
55 if (*b && *b < sizeof(user))
56 memcpy(user, b + 1, *b);
57 user[*b] = 0;
58 b += 1 + *b;
59 if (*b && *b < sizeof(pass))
60 memcpy(pass, b + 1, *b);
61 pass[*b] = 0;
62 log(3, 0, s, t, "PAP login %s/%s\n", user, pass);
63 }
64 if (session[s].ip || !session[s].radius)
65 {
66 // respond now, either no RADIUS available or already authenticated
67 u8 b[MAXCONTROL];
68 u8 id = p[1];
69 u8 *p = makeppp(b, 0, 0, t, s, PPPPAP);
70 if (session[s].ip)
71 *p = 2; // ACK
72 else
73 *p = 3; // cant authorise
74 p[1] = id;
75 *(u16 *) (p + 2) = htons(5); // length
76 p[4] = 0; // no message
77 if (session[s].ip)
78 {
79 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_pool_index);
80 }
81 else
82 {
83 log(1, 0, s, t, "No radius session available to authenticate session...\n");
84 }
85 log(3, 0, s, t, "Fallback response to PAP (%s)\n", (session[s].ip) ? "ACK" : "NAK");
86 tunnelsend(b, 5 + (p - b), t); // send it
87 }
88 else
89 { // set up RADIUS request
90 u8 r = session[s].radius;
91
92 // Run PRE_AUTH plugins
93 struct param_pre_auth packet = { &tunnel[t], &session[s], strdup(user), strdup(pass), PPPPAP, 1 };
94 run_plugins(PLUGIN_PRE_AUTH, &packet);
95 if (!packet.continue_auth)
96 {
97 log(3, 0, s, t, "A plugin rejected PRE_AUTH\n");
98 if (packet.username) free(packet.username);
99 if (packet.password) free(packet.password);
100 return;
101 }
102
103 strncpy(session[s].user, packet.username, sizeof(session[s].user) - 1);
104 strncpy(radius[r].pass, packet.password, sizeof(radius[r].pass) - 1);
105
106 free(packet.username);
107 free(packet.password);
108
109 radius[r].id = p[1];
110 log(3, 0, s, t, "Sending login for %s/%s to radius\n", user, pass);
111 radiussend(r, RADIUSAUTH);
112 }
113 }
114
115 // Process CHAP messages
116 void processchap(tunnelidt t, sessionidt s, u8 * p, u16 l)
117 {
118 u8 r;
119 u16 len;
120
121 #ifdef STAT_CALLS
122 STAT(call_processchap);
123 #endif
124 log_hex(5, "CHAP", p, l);
125 r = session[s].radius;
126 if (!r)
127 {
128 log(1, 0, s, t, "Unexpected CHAP message\n");
129 STAT(tunnel_rx_errors);
130 return;
131 }
132 if (*p != 2)
133 {
134 log(1, 0, s, t, "Unexpected CHAP response code %d\n", *p);
135 STAT(tunnel_rx_errors);
136 return;
137 }
138 if (p[1] != radius[r].id)
139 {
140 log(1, 0, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
141 STAT(tunnel_rx_errors);
142 return ;
143 }
144 len = ntohs(*(u16 *) (p + 2));
145 if (len > l)
146 {
147 log(1, 0, s, t, "Bad CHAP length %d\n", len);
148 STAT(tunnel_rx_errors);
149 return ;
150 }
151 if (p[4] != 16)
152 {
153 log(1, 0, s, t, "Bad CHAP response length %d\n", p[4]);
154 STAT(tunnel_rx_errors);
155 return ;
156 }
157 if (len - 21 >= sizeof(session[s].user))
158 {
159 log(1, 0, s, t, "CHAP user too long %d\n", len - 21);
160 STAT(tunnel_rx_errors);
161 return ;
162 }
163
164 // Run PRE_AUTH plugins
165 {
166 struct param_pre_auth packet = { &tunnel[t], &session[s], NULL, NULL, PPPCHAP, 1 };
167
168 packet.username = calloc(len-20, 1);
169 packet.password = calloc(16, 1);
170 memcpy(packet.username, p + 21, len - 21);
171 memcpy(packet.password, p + 5, 16);
172
173 run_plugins(PLUGIN_PRE_AUTH, &packet);
174 if (!packet.continue_auth)
175 {
176 log(3, 0, s, t, "A plugin rejected PRE_AUTH\n");
177 if (packet.username) free(packet.username);
178 if (packet.password) free(packet.password);
179 return;
180 }
181
182 strncpy(session[s].user, packet.username, sizeof(session[s].user) - 1);
183 memcpy(radius[r].pass, packet.password, 16);
184
185 free(packet.username);
186 free(packet.password);
187 }
188
189 radius[r].chap = 1;
190 radiussend(r, RADIUSAUTH);
191 log(3, 0, s, t, "CHAP login %s\n", session[s].user);
192 }
193
194 char *ppp_lcp_types[] = {
195 NULL,
196 "ConfigReq",
197 "ConfigAck",
198 "ConfigNak",
199 "ConfigRej",
200 "TerminateReq",
201 "TerminateAck",
202 "CodeRej",
203 "ProtocolRej",
204 "EchoReq",
205 "EchoReply",
206 "DiscardRequest",
207 };
208
209 void dumplcp(char *p, int l)
210 {
211 signed int x = l - 3;
212 char *o = (p + 3);
213
214 log_hex(5, "PPP LCP Packet", p, l);
215 log(4, 0, 0, 0, "PPP LCP Packet type %d (%s)\n", *p, ppp_lcp_types[(int)*p]);
216 log(4, 0, 0, 0, "Length: %d\n", l);
217 if (*p != ConfigReq && *p != ConfigRej && *p != ConfigAck)
218 return;
219
220 while (x > 2)
221 {
222 int type = *(u8 *)(o);
223 int length = *(u8 *)(o + 1);
224 if (length == 0)
225 {
226 log(4, 0, 0, 0, " Option length is 0...\n");
227 break;
228 }
229 if (type == 0)
230 {
231 log(4, 0, 0, 0, " Option type is 0...\n");
232 x -= length;
233 o += length;
234 continue;
235 }
236 switch (type)
237 {
238 case 1: // Maximum-Receive-Unit
239 log(4, 0, 0, 0, " %s %d\n", lcp_types[type], ntohs(*(u16 *)(o + 2)));
240 break;
241 case 3: // Authentication-Protocol
242 {
243 int proto = ntohs(*(u16 *)(o + 2));
244 log(4, 0, 0, 0, " %s %s\n", lcp_types[type],
245 proto == 0xC223 ? "CHAP" : "PAP");
246 break;
247 }
248 case 5: // Magic-Number
249 {
250 u32 magicno = ntohl(*(u32 *)(o + 2));
251 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], magicno);
252 break;
253 }
254 case 4: // Quality-Protocol
255 {
256 u32 qp = ntohl(*(u32 *)(o + 2));
257 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], qp);
258 break;
259 }
260 case 7: // Protocol-Field-Compression
261 {
262 u32 pfc = ntohl(*(u32 *)(o + 2));
263 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], pfc);
264 break;
265 }
266 case 8: // Address-And-Control-Field-Compression
267 {
268 u32 afc = ntohl(*(u32 *)(o + 2));
269 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], afc);
270 break;
271 }
272 default:
273 log(2, 0, 0, 0, " Unknown PPP LCP Option type %d\n", type);
274 break;
275 }
276 x -= length;
277 o += length;
278 }
279 }
280
281 // Process LCP messages
282 void processlcp(tunnelidt t, sessionidt s, u8 * p, u16 l)
283 {
284 u8 b[MAXCONTROL];
285 u8 *q = NULL;
286
287 #ifdef STAT_CALLS
288 STAT(call_processlcp);
289 #endif
290 log_hex(5, "LCP", p, l);
291 if (l < 4)
292 {
293 log(1, session[s].ip, s, t, "Short LCP %d bytes", l);
294 STAT(tunnel_rx_errors);
295 return ;
296 }
297 if (*p == ConfigAck)
298 {
299 log(3, session[s].ip, s, t, "LCP: Discarding ConfigAck\n");
300 }
301 else if (*p == ConfigReq)
302 {
303 signed int x = l - 1;
304 char *o = (p + 1);
305
306 log(3, session[s].ip, s, t, "LCP: ConfigReq (%d bytes)...\n", l);
307
308 while (x > 2)
309 {
310 int type = *(u8 *)(o);
311 int length = *(u8 *)(o + 1);
312 if (length == 0 || type == 0) break;
313 switch (type)
314 {
315 case 1: // Maximum-Receive-Unit
316 session[s].mru = ntohs(*(u16 *)(o + 2));
317 break;
318 case 3: // Authentication-Protocol
319 {
320 int proto = ntohs(*(u16 *)(o + 2));
321 if (proto == 0xC223)
322 {
323 log(2, session[s].ip, s, t, " Remote end is trying to do CHAP. Rejecting it.\n");
324
325 if (!q)
326 {
327 q = makeppp(b, p, l, t, s, PPPLCP);
328 *q++ = ConfigNak;
329 }
330 memcpy(q, o, length);
331 *(u16 *)(q += 2) = htons(0xC023); // NAK -> Use PAP instead
332 q += length;
333 }
334 break;
335 }
336 case 5: // Magic-Number
337 {
338 // u32 magicno = ntohl(*(u32 *)(o + 2));
339 break;
340 }
341 case 4: // Quality-Protocol
342 {
343 // u32 qp = ntohl(*(u32 *)(o + 2));
344 break;
345 }
346 case 7: // Protocol-Field-Compression
347 {
348 // u32 pfc = ntohl(*(u32 *)(o + 2));
349 break;
350 }
351 case 8: // Address-And-Control-Field-Compression
352 {
353 // u32 afc = ntohl(*(u32 *)(o + 2));
354 break;
355 }
356 default:
357 log(2, session[s].ip, s, t, " Unknown PPP LCP Option type %d\n", type);
358 break;
359 }
360 x -= length;
361 o += length;
362 }
363
364 if (!q)
365 {
366 // Send back a ConfigAck
367 log(3, session[s].ip, s, t, "ConfigReq accepted, sending as Ack\n");
368 q = makeppp(b, p, l, t, s, PPPLCP);
369 *q = ConfigAck;
370 tunnelsend(b, l + (q - b), t);
371 }
372 else
373 {
374 // Already built a ConfigNak... send it
375 log(3, session[s].ip, s, t, "Sending ConfigNak\n");
376 tunnelsend(b, l + (q - b), t);
377
378 log(3, session[s].ip, s, t, "Sending ConfigReq, requesting PAP login\n");
379 q = makeppp(b, NULL, 0, t, s, PPPLCP);
380 *q++ = ConfigReq;
381 *(u8 *)(q++) = 3;
382 *(u8 *)(q++) = 4;
383 *(u16 *)(q += 2) = htons(0xC023);
384 tunnelsend(b, l + (q - b), t);
385 }
386 }
387 else if (*p == ConfigNak)
388 {
389 log(1, session[s].ip, s, t, "Remote end sent a ConfigNak. Ignoring\n");
390 dumplcp(p, l);
391 return ;
392 }
393 else if (*p == TerminateReq)
394 {
395 *p = TerminateAck; // close
396 q = makeppp(b, p, l, t, s, PPPLCP);
397 log(3, session[s].ip, s, t, "LCP: Received TerminateReq. Sending TerminateAck\n");
398 sessionshutdown(s, "Remote end closed connection.");
399 tunnelsend(b, l + (q - b), t); // send it
400 }
401 else if (*p == TerminateReq)
402 {
403 sessionshutdown(s, "Remote end closed connection.");
404 }
405 else if (*p == EchoReq)
406 {
407 *p = EchoReply; // reply
408 *(u32 *) (p + 4) = htonl(session[s].magic); // our magic number
409 q = makeppp(b, p, l, t, s, PPPLCP);
410 log(4, session[s].ip, s, t, "LCP: Received EchoReq. Sending EchoReply\n");
411 tunnelsend(b, l + (q - b), t); // send it
412 }
413 else if (*p == EchoReply)
414 {
415 // Ignore it, last_packet time is set earlier than this.
416 }
417 else
418 {
419 log(1, session[s].ip, s, t, "Unexpected LCP code %d\n", *p);
420 STAT(tunnel_rx_errors);
421 return ;
422 }
423 }
424
425 // Process IPCP messages
426 void processipcp(tunnelidt t, sessionidt s, u8 * p, u16 l)
427 {
428 #ifdef STAT_CALLS
429 STAT(call_processipcp);
430 #endif
431 log_hex(5, "IPCP", p, l);
432 if (l < 5)
433 {
434 log(1, 0, s, t, "Short IPCP %d bytes", l);
435 STAT(tunnel_rx_errors);
436 return ;
437 }
438 if (*p == ConfigAck)
439 { // happy with our IPCP
440 u8 r = session[s].radius;
441 if ((!r || radius[r].state == RADIUSIPCP) && !session[s].servicenet)
442 if (!r)
443 r = radiusnew(s);
444 if (r)
445 radiussend(r, RADIUSSTART); // send radius start, having got IPCP at last
446 return ; // done
447 }
448 if (*p != ConfigReq)
449 {
450 log(1, 0, s, t, "Unexpected IPCP code %d\n", *p);
451 STAT(tunnel_rx_errors);
452 return ;
453 }
454 if (ntohs(*(u16 *) (p + 2)) > l)
455 {
456 log(1, 0, s, t, "Length mismatch IPCP %d/%d\n", ntohs(*(u16 *) (p + 2)), l);
457 STAT(tunnel_rx_errors);
458 return ;
459 }
460 if (!session[s].ip)
461 {
462 log(3, 0, s, t, "Waiting on radius reply\n");
463 return ; // have to wait on RADIUS eply
464 }
465 // form a config reply quoting the IP in the session
466 {
467 u8 b[MAXCONTROL];
468 u8 *i,
469 *q;
470
471 q = p + 4;
472 i = p + l;
473 while (q < i && q[1])
474 {
475 if (*q != 0x81 && *q != 0x83 && *q != 3)
476 break;
477 q += q[1];
478 }
479 if (q < i)
480 { // reject
481 u16 n = 4;
482 i = p + l;
483 q = makeppp(b, p, l, t, s, PPPIPCP);
484 *q = ConfigRej;
485 p += 4;
486 while (p < i && p[1])
487 {
488 if (*p != 0x81 && *p != 0x83 && *p != 3)
489 {
490 log(2, 0, s, t, "IPCP reject %d\n", *p);
491 memcpy(q + n, p, p[1]);
492 n += p[1];
493 }
494 p += p[1];
495 }
496 *(u16 *) (q + 2) = htons(n);
497 tunnelsend(b, n + (q - b), t); // send it
498 }
499 else
500 {
501 *p = ConfigAck;
502 i = findppp(p, 0x81); // Primary DNS address
503 if (i)
504 {
505 if (*(u32 *) (i + 2) != htonl(session[s].dns1))
506 {
507 *(u32 *) (i + 2) = htonl(session[s].dns1);
508 *p = ConfigNak;
509 }
510 }
511 i = findppp(p, 0x83); // Secondary DNS address (TBA, is it)
512 if (i)
513 {
514 if (*(u32 *) (i + 2) != htonl(session[s].dns2))
515 {
516 *(u32 *) (i + 2) = htonl(session[s].dns2);
517 *p = ConfigNak;
518 }
519 }
520 i = findppp(p, 3); // IP address
521 if (!i || i[1] != 6)
522 {
523 log(1, 0, s, t, "No IP in IPCP request\n");
524 STAT(tunnel_rx_errors);
525 return ;
526 }
527 if (*(u32 *) (i + 2) != htonl(session[s].ip))
528 {
529 *(u32 *) (i + 2) = htonl(session[s].ip);
530 *p = ConfigNak;
531 }
532 q = makeppp(b, p, l, t, s, PPPIPCP);
533 tunnelsend(b, l + (q - b), t); // send it
534 }
535 }
536 }
537
538 // process IP packet received
539 void processipin(tunnelidt t, sessionidt s, u8 * p, u16 l)
540 {
541 #ifdef STAT_CALLS
542 STAT(call_processipin);
543 #endif
544 log_hex(5, "IP", p, l);
545
546 if (l > MAXETHER)
547 {
548 log(1, *(u32 *)(p + 12), s, t, "IP packet too long %d\n", l);
549 STAT(tunnel_rx_errors);
550 return ;
551 }
552
553 session[s].cin += l;
554 session[s].total_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