From 35f10d93f4f2bbd5791dc0996a36f0ba8386576d Mon Sep 17 00:00:00 2001 From: fendo Date: Sat, 15 Dec 2012 00:00:13 +0100 Subject: [PATCH] Final development LAC functionality. Fix Possible ring buffer overflow. --- Docs/manual.html | 22 +++++++++++++++++----- Makefile | 12 ++++++++---- l2tplac.c | 2 +- l2tpns.c | 24 ++++++++++++++++-------- l2tpns.h | 2 ++ ppp.c | 2 +- radius.c | 39 +++++++++++++++++++++++++++++++++++---- 7 files changed, 80 insertions(+), 23 deletions(-) diff --git a/Docs/manual.html b/Docs/manual.html index f52ad29..d6930dd 100644 --- a/Docs/manual.html +++ b/Docs/manual.html @@ -252,15 +252,22 @@ session is established.
  • bind_address (ip address)
    -When the tun interface is created, it is assigned the address -specified here. If no address is given, 1.1.1.1 is used. Packets -containing user traffic should be routed via this address if given, -otherwise the primary address of the machine. +It's the listen address of the l2tp udp protocol sent and received +to LAC. This address is also assigned to the tun interface if no +iftun_address is specified. Packets containing user traffic should be +routed via this address if given, otherwise the primary address of the +machine. +
  • + +
  • iftun_address (ip address)
    +This parameter is used when you want a tun interface address different +from the address of "bind_address" (For use in cases of specific configuration). +If no address is given to iftun_address and bind_address, 1.1.1.1 is used.
  • peer_address (ip address)
    Address to send to clients as the default gateway. - +
  • send_garp (boolean)
    Determines whether or not to send a gratuitous ARP for the @@ -368,6 +375,11 @@ Drop sessions who have not responded within idle_echo_timeout seconds (default: 240 (seconds))
  • +
  • bind_address_remotelns (ip address)
    +Address of the interface to listen the remote LNS tunnels. +If no address is given, all interfaces are listened (Any Address). +
  • +
  • bind_portremotelns (short)
    Port to bind for the Remote LNS (default: 65432).
  • diff --git a/Makefile b/Makefile index e915e9b..36ba2e1 100644 --- a/Makefile +++ b/Makefile @@ -112,20 +112,24 @@ install: all ## Dependencies: (autogenerated) ## arp.o: arp.c l2tpns.h -cli.o: cli.c l2tpns.h constants.h util.h cluster.h tbf.h ll.h bgp.h +cli.o: cli.c l2tpns.h constants.h util.h cluster.h tbf.h ll.h bgp.h \ + l2tplac.h cluster.o: cluster.c l2tpns.h cluster.h util.h tbf.h bgp.h constants.o: constants.c constants.h control.o: control.c l2tpns.h control.h icmp.o: icmp.c l2tpns.h l2tpns.o: l2tpns.c md5.h l2tpns.h cluster.h plugin.h ll.h constants.h \ - control.h util.h tbf.h bgp.h + control.h util.h tbf.h bgp.h l2tplac.h ll.o: ll.c ll.h md5.o: md5.c md5.h -ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h -radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h cluster.h +ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h \ + l2tplac.h +radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h cluster.h \ + l2tplac.h tbf.o: tbf.c l2tpns.h util.h tbf.h util.o: util.c l2tpns.h bgp.h bgp.o: bgp.c l2tpns.h bgp.h util.h +l2tplac.o: l2tplac.c md5.h l2tpns.h util.h l2tplac.h autosnoop.so: autosnoop.c l2tpns.h plugin.h autothrottle.so: autothrottle.c l2tpns.h plugin.h garden.so: garden.c l2tpns.h plugin.h control.h diff --git a/l2tplac.c b/l2tplac.c index f073ecc..3851fa0 100644 --- a/l2tplac.c +++ b/l2tplac.c @@ -236,7 +236,7 @@ void lac_save_rad_tag_tunnels(sessionidt s) if (pconfigrlns[idrlns].state == CONFRLNSFREE) { pconfigrlns[idrlns].ip = ptunnelrlns[idtag].tunnel_server_endpoint; - pconfigrlns[idrlns].port = L2TPPORT; //Default L2TP poart + pconfigrlns[idrlns].port = L2TPPORT; //Default L2TP port strcpy(pconfigrlns[idrlns].l2tp_secret, ptunnelrlns[idtag].tunnel_password); strcpy(pconfigrlns[idrlns].tunnel_assignment_id, ptunnelrlns[idtag].tunnel_assignment_id); diff --git a/l2tpns.c b/l2tpns.c index 694726d..9dbde7a 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -178,8 +178,10 @@ config_descriptt config_values[] = { #endif CONFIG("echo_timeout", echo_timeout, INT), CONFIG("idle_echo_timeout", idle_echo_timeout, INT), + CONFIG("iftun_address", iftun_address, IPv4), #ifdef LAC CONFIG("disable_lac_func", disable_lac_func, BOOL), + CONFIG("bind_address_remotelns", bind_address_remotelns, IPv4), CONFIG("bind_portremotelns", bind_portremotelns, SHORT), #endif { NULL, 0, 0, 0 }, @@ -292,7 +294,7 @@ void _log(int level, sessionidt s, tunnelidt t, const char *format, ...) ringbuffer->buffer[ringbuffer->tail].session = s; ringbuffer->buffer[ringbuffer->tail].tunnel = t; va_start(ap, format); - vsnprintf(ringbuffer->buffer[ringbuffer->tail].message, 4095, format, ap); + vsnprintf(ringbuffer->buffer[ringbuffer->tail].message, MAX_LOG_LENGTH, format, ap); va_end(ap); } #endif @@ -747,8 +749,8 @@ static void inittun(void) req.ifmsg.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE; req.ifmsg.ifaddr.ifa_index = tunidx; - if (config->bind_address) - ip = config->bind_address; + if (config->iftun_address) + ip = config->iftun_address; else ip = 0x01010101; // 1.1.1.1 netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip)); @@ -878,6 +880,7 @@ static void initudp(void) memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(config->bind_portremotelns); + addr.sin_addr.s_addr = config->bind_address_remotelns; udplacfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); setsockopt(udplacfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); { @@ -2177,7 +2180,7 @@ void sendipcp(sessionidt s, tunnelidt t) q[4] = 3; // ip address option q[5] = 6; // option length *(in_addr_t *) (q + 6) = config->peer_address ? config->peer_address : - config->bind_address ? config->bind_address : + config->iftun_address ? config->iftun_address : my_address; // send my IP tunnelsend(buf, 10 + (q - buf), t); // send it @@ -3062,6 +3065,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) tunnelshutdown(t, "Stopped", 0, 0, 0); // Shut down cleanly break; case 6: // HELLO + LOG(3, s, t, "Received HELLO\n"); controlnull(t); // simply ACK break; case 7: // OCRQ @@ -3157,7 +3161,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) // Set multilink options before sending initial LCP packet sess_local[s].mp_mrru = 1614; - sess_local[s].mp_epdis = ntohl(config->bind_address ? config->bind_address : my_address); + sess_local[s].mp_epdis = ntohl(config->iftun_address ? config->iftun_address : my_address); sendlcp(s, t); change_state(s, lcp, RequestSent); @@ -4196,7 +4200,7 @@ static void mainloop(void) if ((s = read(tunfd, p, size_bufp)) > 0) { processtun(p, s); - tun_pkts++; + tun_pkts++; } else { @@ -4228,7 +4232,7 @@ static void mainloop(void) if (c >= config->multi_read_count) { #ifdef LAC - LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun and %d cluster %d rmlns packets\n", + LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster and %d rmlns packets\n", config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts, udplac_pkts); #else LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun and %d cluster packets\n", @@ -4887,7 +4891,7 @@ static int dump_session(FILE **f, sessiont *s) "# uptime: %ld\n" "# format: username ip qos uptxoctets downrxoctets\n", hostname, - fmtaddr(config->bind_address ? config->bind_address : my_address, 0), + fmtaddr(config->iftun_address ? config->iftun_address : my_address, 0), now, now - basetime); } @@ -5271,7 +5275,11 @@ static void update_config() #ifdef LAC if(!config->bind_portremotelns) config->bind_portremotelns = L2TPLACPORT; + if(!config->bind_address_remotelns) + config->bind_address_remotelns = INADDR_ANY; #endif + if(!config->iftun_address) + config->iftun_address = config->bind_address; // re-initialise the random number source initrandom(config->random_device); diff --git a/l2tpns.h b/l2tpns.h index 8143736..0d07ae3 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -761,10 +761,12 @@ typedef struct int echo_timeout; // Time between last packet sent and LCP ECHO generation int idle_echo_timeout; // Time between last packet seen and // Drop sessions who have not responded within IDLE_ECHO_TIMEOUT seconds + in_addr_t iftun_address; #ifdef LAC int disable_lac_func; int highest_rlnsid; uint16_t bind_portremotelns; + in_addr_t bind_address_remotelns; #endif } configt; diff --git a/ppp.c b/ppp.c index 584ce61..236188e 100644 --- a/ppp.c +++ b/ppp.c @@ -558,7 +558,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (session[s].die) // going down... return; - LOG((*p == EchoReq || *p == EchoReply) ? 4 : 3, s, t, + LOG(((*p == EchoReq || *p == EchoReply) ? 4 : 3), s, t, "LCP: recv %s\n", ppp_code(*p)); if (config->debug > 3) dumplcp(p, l); diff --git a/radius.c b/radius.c index 843931f..e783323 100644 --- a/radius.c +++ b/radius.c @@ -600,6 +600,7 @@ void processrad(uint8_t *buf, int len, char socket_index) run_plugins(PLUGIN_POST_AUTH, &packet); r_code = packet.auth_allowed ? AccessAccept : AccessReject; +#ifndef LAC // process auth response if (radius[r].chap) { @@ -631,6 +632,7 @@ void processrad(uint8_t *buf, int len, char socket_index) LOG(3, s, session[s].tunnel, " PAP User %s authentication %s.\n", session[s].user, (r_code == AccessAccept) ? "allowed" : "denied"); } +#endif if (r_code == AccessAccept) { @@ -958,14 +960,43 @@ void processrad(uint8_t *buf, int len, char socket_index) { session[s].route[ro].ip = 0; } - - // Restart LCP auth... - lcp_restart(s); - sendlcp(s, t); break; } } + + // process auth response + if (radius[r].chap) + { + // CHAP + uint8_t *p = makeppp(b, sizeof(b), 0, 0, s, t, PPPCHAP, 0, 0, 0); + if (!p) return; // Abort! + + *p = (r_code == AccessAccept) ? 3 : 4; // ack/nak + p[1] = radius[r].id; + *(uint16_t *) (p + 2) = ntohs(4); // no message + tunnelsend(b, (p - b) + 4, t); // send it + + LOG(3, s, session[s].tunnel, " CHAP User %s authentication %s.\n", session[s].user, + (r_code == AccessAccept) ? "allowed" : "denied"); + } + else + { + // PAP + uint8_t *p = makeppp(b, sizeof(b), 0, 0, s, t, PPPPAP, 0, 0, 0); + if (!p) return; // Abort! + + // ack/nak + *p = r_code; + p[1] = radius[r].id; + *(uint16_t *) (p + 2) = ntohs(5); + p[4] = 0; // no message + tunnelsend(b, (p - b) + 5, t); // send it + + LOG(3, s, session[s].tunnel, " PAP User %s authentication %s.\n", session[s].user, + (r_code == AccessAccept) ? "allowed" : "denied"); + } #endif + if (!session[s].dns1 && config->default_dns1) { session[s].dns1 = ntohl(config->default_dns1); -- 2.20.1