6 #include <sys/socket.h>
10 #include <arpa/inet.h>
12 #include <netinet/in.h>
14 #include <linux/rtnetlink.h>
17 #include "constants.h"
27 extern radiust
*radius
;
28 extern sessiont
*session
;
29 extern tunnelt
*tunnel
;
30 extern configt
*config
;
32 extern ip_filtert
*ip_filters
;
34 static const hasht zero
;
36 static void calc_auth(const void *buf
, size_t len
, const uint8_t *in
, uint8_t *out
)
41 MD5_Update(&ctx
, (void *)buf
, 4); // code, id, length
42 MD5_Update(&ctx
, (void *)in
, 16); // auth
43 MD5_Update(&ctx
, (void *)(buf
+ 20), len
- 20);
44 MD5_Update(&ctx
, config
->radiussecret
, strlen(config
->radiussecret
));
48 // Set up socket for radius requests
53 uint16_t min
= config
->radius_bind_min
;
54 uint16_t max
= config
->radius_bind_max
;
56 struct sockaddr_in addr
;
64 else if (max
) /* no minimum specified, bind from max down */
71 LOG(3, 0, 0, "Creating %d sockets for RADIUS queries\n", RADIUS_FDS
);
72 radfds
= calloc(sizeof(int), RADIUS_FDS
);
73 for (i
= 0; i
< RADIUS_FDS
; i
++)
76 radfds
[i
] = socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
77 flags
= fcntl(radfds
[i
], F_GETFL
, 0);
78 fcntl(radfds
[i
], F_SETFL
, flags
| O_NONBLOCK
);
84 memset(&addr
, 0, sizeof(addr
));
85 addr
.sin_family
= AF_INET
;
86 addr
.sin_addr
.s_addr
= INADDR_ANY
;
89 addr
.sin_port
= htons(port
);
90 if ((b
= bind(radfds
[i
], (struct sockaddr
*) &addr
, sizeof(addr
))) < 0)
92 if ((port
+= inc
) < min
|| port
> max
)
94 LOG(0, 0, 0, "Can't bind RADIUS socket in range %u-%u\n", min
, max
);
103 void radiusclear(uint16_t r
, sessionidt s
)
105 if (s
) sess_local
[s
].radius
= 0;
106 memset(&radius
[r
], 0, sizeof(radius
[r
])); // radius[r].state = RADIUSNULL;
109 static uint16_t get_free_radius()
112 static uint32_t next_radius_id
= 0;
114 for (count
= MAXRADIUS
; count
> 0; --count
)
116 ++next_radius_id
; // Find the next ID to check.
117 if (next_radius_id
>= MAXRADIUS
)
120 if (radius
[next_radius_id
].state
== RADIUSNULL
)
122 return next_radius_id
;
126 LOG(0, 0, 0, "Can't find a free radius session! This is very bad!\n");
130 uint16_t radiusnew(sessionidt s
)
132 uint16_t r
= sess_local
[s
].radius
;
137 LOG(3, s
, session
[s
].tunnel
, "Re-used radius %d\n", r
);
141 if (!(r
= get_free_radius()))
143 LOG(1, s
, session
[s
].tunnel
, "No free RADIUS sessions\n");
144 STAT(radius_overflow
);
148 memset(&radius
[r
], 0, sizeof(radius
[r
]));
149 sess_local
[s
].radius
= r
;
150 radius
[r
].session
= s
;
151 radius
[r
].state
= RADIUSWAIT
;
152 radius
[r
].retry
= TIME
+ 1200; // Wait at least 120 seconds to re-claim this.
154 random_data(radius
[r
].auth
, sizeof(radius
[r
].auth
));
156 LOG(3, s
, session
[s
].tunnel
, "Allocated radius %d\n", r
);
160 // Send a RADIUS request
161 void radiussend(uint16_t r
, uint8_t state
)
163 struct sockaddr_in addr
;
164 uint8_t b
[4096]; // RADIUS packet
172 s
= radius
[r
].session
;
173 if (!config
->numradiusservers
)
175 LOG(0, s
, session
[s
].tunnel
, "No RADIUS servers\n");
178 if (!*config
->radiussecret
)
180 LOG(0, s
, session
[s
].tunnel
, "No RADIUS secret\n");
184 if (state
!= RADIUSAUTH
&& state
!= RADIUSJUSTAUTH
&& !config
->radius_accounting
)
186 // Radius accounting is turned off
191 if (radius
[r
].state
!= state
)
194 radius
[r
].state
= state
;
195 radius
[r
].retry
= backoff(radius
[r
].try++) + 20; // 3s, 4s, 6s, 10s...
196 LOG(4, s
, session
[s
].tunnel
, "Send RADIUS id %d sock %d state %s try %d\n",
197 r
>> RADIUS_SHIFT
, r
& RADIUS_MASK
,
198 radius_state(radius
[r
].state
), radius
[r
].try);
200 if (radius
[r
].try > config
->numradiusservers
* 2)
204 if (state
== RADIUSAUTH
|| state
== RADIUSJUSTAUTH
)
205 sessionshutdown(s
, "RADIUS timeout.", CDN_ADMIN_DISC
, TERM_REAUTHENTICATION_FAILURE
);
208 LOG(1, s
, session
[s
].tunnel
, "RADIUS timeout, but in state %s so don't timeout session\n",
209 radius_state(state
));
212 STAT(radius_timeout
);
216 STAT(radius_retries
);
217 radius
[r
].state
= RADIUSWAIT
;
218 radius
[r
].retry
= 100;
222 // contruct RADIUS access request
227 b
[0] = AccessRequest
; // access request
232 b
[0] = AccountingRequest
; // accounting request
235 LOG(0, 0, 0, "Unknown radius state %d\n", state
);
237 b
[1] = r
>> RADIUS_SHIFT
; // identifier
238 memcpy(b
+ 4, radius
[r
].auth
, 16);
244 p
[1] = strlen(session
[s
].user
) + 2;
245 strcpy((char *) p
+ 2, session
[s
].user
);
248 if (state
== RADIUSAUTH
|| state
== RADIUSJUSTAUTH
)
252 *p
= 3; // CHAP password
254 p
[2] = radius
[r
].id
; // ID
255 memcpy(p
+ 3, radius
[r
].pass
, 16); // response from CHAP request
257 *p
= 60; // CHAP Challenge
259 memcpy(p
+ 2, radius
[r
].auth
, 16);
264 strcpy(pass
, radius
[r
].pass
);
267 pass
[pl
++] = 0; // pad
276 MD5_Update(&ctx
, config
->radiussecret
, strlen(config
->radiussecret
));
278 MD5_Update(&ctx
, pass
+ p
- 16, 16);
280 MD5_Update(&ctx
, radius
[r
].auth
, 16);
281 MD5_Final(hash
, &ctx
);
284 pass
[p
] ^= hash
[p
& 15];
293 memcpy(p
+ 2, pass
, pl
);
299 *p
= 40; // accounting type
301 *(uint32_t *) (p
+ 2) = htonl(state
- RADIUSSTART
+ 1); // start=1, stop=2, interim=3
305 *p
= 44; // session ID
307 sprintf((char *) p
+ 2, "%08X%08X", session
[s
].unique_id
, session
[s
].opened
);
309 if (state
== RADIUSSTART
)
313 *(uint32_t *) (p
+ 2) = htonl(time(NULL
) - session
[s
].opened
);
315 sess_local
[s
].last_interim
= time_now
; // Setup "first" Interim
319 *p
= 42; // input octets
321 *(uint32_t *) (p
+ 2) = htonl(session
[s
].cin
);
324 *p
= 43; // output octets
326 *(uint32_t *) (p
+ 2) = htonl(session
[s
].cout
);
329 *p
= 46; // session time
331 *(uint32_t *) (p
+ 2) = htonl(time(NULL
) - session
[s
].opened
);
334 *p
= 47; // input packets
336 *(uint32_t *) (p
+ 2) = htonl(session
[s
].pin
);
339 *p
= 48; // output packets
341 *(uint32_t *) (p
+ 2) = htonl(session
[s
].pout
);
344 *p
= 52; // input gigawords
346 *(uint32_t *) (p
+ 2) = htonl(session
[s
].cin_wrap
);
349 *p
= 53; // output gigawords
351 *(uint32_t *) (p
+ 2) = htonl(session
[s
].cout_wrap
);
354 if (state
== RADIUSSTOP
&& radius
[r
].term_cause
)
356 *p
= 49; // acct-terminate-cause
358 *(uint32_t *) (p
+ 2) = htonl(radius
[r
].term_cause
);
361 if (radius
[r
].term_msg
)
363 *p
= 26; // vendor-specific
364 *(uint32_t *) (p
+ 2) = htonl(9); // Cisco
365 p
[6] = 1; // Cisco-AVPair
366 p
[7] = 2 + sprintf((char *) p
+ 8, "disc-cause-ext=%s", radius
[r
].term_msg
);
373 if (session
[s
].classlen
) {
375 p
[1] = session
[s
].classlen
+ 2;
376 memcpy(p
+ 2, session
[s
].class, session
[s
].classlen
);
381 struct param_radius_account acct
= { &tunnel
[session
[s
].tunnel
], &session
[s
], &p
};
382 run_plugins(PLUGIN_RADIUS_ACCOUNT
, &acct
);
391 *(uint32_t *) (p
+ 2) = htonl(s
);
394 *p
= 6; // Service-Type
396 *(uint32_t *) (p
+ 2) = htonl((state
== RADIUSJUSTAUTH
? 8 : 2)); // Authenticate only or Framed-User respectevily
399 *p
= 7; // Framed-Protocol
400 p
[1] = htonl((state
== RADIUSJUSTAUTH
? 0 : 6));
401 *(uint32_t *) (p
+ 2) = htonl((state
== RADIUSJUSTAUTH
? 0 : 1)); // PPP
406 *p
= 8; // Framed-IP-Address
408 *(uint32_t *) (p
+ 2) = htonl(session
[s
].ip
);
412 if (session
[s
].route
[0].ip
)
415 for (r
= 0; s
&& r
< MAXROUTE
&& session
[s
].route
[r
].ip
; r
++)
417 *p
= 22; // Framed-Route
418 p
[1] = sprintf((char *) p
+ 2, "%s/%d %s 1",
419 fmtaddr(htonl(session
[s
].route
[r
].ip
), 0),
420 session
[s
].route
[r
].prefixlen
,
421 fmtaddr(htonl(session
[s
].ip
), 1)) + 2;
427 if (session
[s
].session_timeout
)
429 *p
= 27; // Session-Timeout
431 *(uint32_t *) (p
+ 2) = htonl(session
[s
].session_timeout
);
435 if (session
[s
].idle_timeout
)
437 *p
= 28; // Idle-Timeout
439 *(uint32_t *) (p
+ 2) = htonl(session
[s
].idle_timeout
);
443 if (*session
[s
].called
)
446 p
[1] = strlen(session
[s
].called
) + 2;
447 strcpy((char *) p
+ 2, session
[s
].called
);
451 if (*session
[s
].calling
)
454 p
[1] = strlen(session
[s
].calling
) + 2;
455 strcpy((char *) p
+ 2, session
[s
].calling
);
463 *(uint32_t *)(p
+ 2) = config
->bind_address
;
467 *(uint16_t *) (b
+ 2) = htons(p
- b
);
468 if (state
!= RADIUSAUTH
&& state
!= RADIUSJUSTAUTH
)
470 // Build auth for accounting packet
471 calc_auth(b
, p
- b
, zero
, b
+ 4);
472 memcpy(radius
[r
].auth
, b
+ 4, 16);
474 memset(&addr
, 0, sizeof(addr
));
475 addr
.sin_family
= AF_INET
;
476 *(uint32_t *) & addr
.sin_addr
= config
->radiusserver
[(radius
[r
].try - 1) % config
->numradiusservers
];
479 uint16_t port
= config
->radiusport
[(radius
[r
].try - 1) % config
->numradiusservers
];
480 // assume RADIUS accounting port is the authentication port +1
481 addr
.sin_port
= htons((state
== RADIUSAUTH
|| state
== RADIUSJUSTAUTH
) ? port
: port
+1);
484 LOG_HEX(5, "RADIUS Send", b
, (p
- b
));
485 sendto(radfds
[r
& RADIUS_MASK
], b
, p
- b
, 0, (void *) &addr
, sizeof(addr
));
488 static void handle_avpair(sessionidt s
, uint8_t *avp
, int len
)
491 uint8_t *value
= memchr(avp
, '=', len
);
492 uint8_t tmp
[2048] = "";
506 if (len
> 2 && (*value
== '"' || *value
== '\'') && value
[len
- 1] == *value
)
512 // copy and null terminate
513 else if (len
< sizeof(tmp
) - 1)
515 memcpy(tmp
, value
, len
);
524 struct param_radius_response p
= { &tunnel
[session
[s
].tunnel
], &session
[s
], (char *) key
, (char *) value
};
525 run_plugins(PLUGIN_RADIUS_RESPONSE
, &p
);
529 // process RADIUS response
530 void processrad(uint8_t *buf
, int len
, char socket_index
)
541 int OpentunnelReq
= 0;
545 LOG_HEX(5, "RADIUS Response", buf
, len
);
546 if (len
< 20 || len
< ntohs(*(uint16_t *) (buf
+ 2)))
548 LOG(1, 0, 0, "Duff RADIUS response length %d\n", len
);
552 r_code
= buf
[0]; // response type
553 r_id
= buf
[1]; // radius reply indentifier.
555 len
= ntohs(*(uint16_t *) (buf
+ 2));
556 r
= socket_index
| (r_id
<< RADIUS_SHIFT
);
557 s
= radius
[r
].session
;
558 LOG(3, s
, session
[s
].tunnel
, "Received %s, radius %d response for session %u (%s, id %d)\n",
559 radius_state(radius
[r
].state
), r
, s
, radius_code(r_code
), r_id
);
561 if (!s
&& radius
[r
].state
!= RADIUSSTOP
)
563 LOG(1, s
, session
[s
].tunnel
, " Unexpected RADIUS response\n");
566 if (radius
[r
].state
!= RADIUSAUTH
&& radius
[r
].state
!= RADIUSJUSTAUTH
&& radius
[r
].state
!= RADIUSSTART
567 && radius
[r
].state
!= RADIUSSTOP
&& radius
[r
].state
!= RADIUSINTERIM
)
569 LOG(1, s
, session
[s
].tunnel
, " Unexpected RADIUS response\n");
572 t
= session
[s
].tunnel
;
573 calc_auth(buf
, len
, radius
[r
].auth
, hash
);
575 if (memcmp(hash
, buf
+ 4, 16))
577 LOG(0, s
, session
[s
].tunnel
, " Incorrect auth on RADIUS response!! (wrong secret in radius config?)\n");
578 return; // Do nothing. On timeout, it will try the next radius server.
581 if (((radius
[r
].state
== RADIUSAUTH
||radius
[r
].state
== RADIUSJUSTAUTH
) && r_code
!= AccessAccept
&& r_code
!= AccessReject
) ||
582 ((radius
[r
].state
== RADIUSSTART
|| radius
[r
].state
== RADIUSSTOP
|| radius
[r
].state
== RADIUSINTERIM
) && r_code
!= AccountingResponse
))
584 LOG(1, s
, session
[s
].tunnel
, " Unexpected RADIUS response %s\n", radius_code(r_code
));
585 return; // We got something we didn't expect. Let the timeouts take
586 // care off finishing the radius session if that's really correct.
589 if (radius
[r
].state
== RADIUSAUTH
|| radius
[r
].state
== RADIUSJUSTAUTH
)
591 // run post-auth plugin
592 struct param_post_auth packet
= {
596 (r_code
== AccessAccept
),
597 radius
[r
].chap
? PPPCHAP
: PPPPAP
600 run_plugins(PLUGIN_POST_AUTH
, &packet
);
601 r_code
= packet
.auth_allowed
? AccessAccept
: AccessReject
;
603 if (r_code
== AccessAccept
)
606 // Extract IP, routes, etc
607 uint8_t *p
= buf
+ 20;
608 uint8_t *e
= buf
+ len
;
610 uint8_t strtemp
[256];
611 lac_reset_rad_tag_tunnel_ctxt();
613 for (; p
+ 2 <= e
&& p
[1] && p
+ p
[1] <= e
; p
+= p
[1])
615 if (*p
== 26 && p
[1] >= 7)
617 // Vendor-Specific Attribute
618 uint32_t vendor
= ntohl(*(int *)(p
+ 2));
619 uint8_t attrib
= *(p
+ 6);
620 int attrib_length
= *(p
+ 7) - 2;
622 LOG(4, s
, session
[s
].tunnel
, " Radius reply contains Vendor-Specific. Vendor=%u Attrib=%u Length=%d\n", vendor
, attrib
, attrib_length
);
623 if (vendor
== 9 && attrib
== 1) // Cisco-AVPair
625 if (attrib_length
< 0) continue;
626 LOG(3, s
, session
[s
].tunnel
, " Cisco-AVPair value: %.*s\n",
627 attrib_length
, p
+ 8);
629 handle_avpair(s
, p
+ 8, attrib_length
);
632 else if (vendor
== 529 && attrib
>= 135 && attrib
<= 136) // Ascend
634 // handle old-format ascend DNS attributes below
637 else if (vendor
== 64520) // Sames
639 //Sames vendor-specific 64520
640 uint8_t *pvs
= p
+ 6; // pvs set to begin to attribute
641 LOG(3, s
, session
[s
].tunnel
, " Sames vendor-specific: %d, Attrib: %d, lenght: %d\n", vendor
, attrib
, attrib_length
);
642 grp_processvendorspecific(s
, pvs
);
647 LOG(3, s
, session
[s
].tunnel
, " Unknown vendor-specific: %d, Attrib: %d\n", vendor
, attrib
);
655 if (p
[1] < 6) continue;
656 session
[s
].ip
= ntohl(*(uint32_t *) (p
+ 2));
657 session
[s
].ip_pool_index
= -1;
658 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains IP address %s\n",
659 fmtaddr(htonl(session
[s
].ip
), 0));
661 if (session
[s
].ip
== 0xFFFFFFFE)
662 session
[s
].ip
= 0; // assign from pool
667 if (p
[1] < 6) continue;
668 session
[s
].dns1
= ntohl(*(uint32_t *) (p
+ 2));
669 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains primary DNS address %s\n",
670 fmtaddr(htonl(session
[s
].dns1
), 0));
675 if (p
[1] < 6) continue;
676 session
[s
].dns2
= ntohl(*(uint32_t *) (p
+ 2));
677 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains secondary DNS address %s\n",
678 fmtaddr(htonl(session
[s
].dns2
), 0));
687 uint8_t *e
= p
+ p
[1];
688 while (n
< e
&& (isdigit(*n
) || *n
== '.'))
696 u
= u
* 10 + *n
- '0';
703 while (n
< e
&& isdigit(*n
))
704 bits
= bits
* 10 + *n
++ - '0';
706 else if ((ip
>> 24) < 128)
708 else if ((ip
>> 24) < 192)
713 if (routes
== MAXROUTE
)
715 LOG(1, s
, session
[s
].tunnel
, " Too many routes\n");
719 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains route for %s/%d\n",
720 fmtaddr(htonl(ip
), 0), bits
);
722 session
[s
].route
[routes
].ip
= ip
;
723 session
[s
].route
[routes
].prefixlen
= bits
;
730 char *filter
= (char *) p
+ 2;
736 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains Filter-Id \"%.*s\"\n", l
, filter
);
737 if ((suffix
= memchr(filter
, '.', l
)))
739 int b
= suffix
- filter
;
740 if (l
- b
== 3 && !memcmp("in", suffix
+1, 2))
741 fp
= &session
[s
].filter_in
;
742 else if (l
- b
== 4 && !memcmp("out", suffix
+1, 3))
743 fp
= &session
[s
].filter_out
;
750 LOG(3, s
, session
[s
].tunnel
, " Invalid filter\n");
754 if ((f
= find_filter(filter
, l
)) < 0 || !*ip_filters
[f
].name
)
756 LOG(3, s
, session
[s
].tunnel
, " Unknown filter\n");
761 ip_filters
[f
].used
++;
767 if (p
[1] < 6) continue;
768 session
[s
].session_timeout
= ntohl(*(uint32_t *)(p
+ 2));
769 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains Session-Timeout = %u\n", session
[s
].session_timeout
);
770 if(!session
[s
].session_timeout
&& config
->kill_timedout_sessions
)
771 sessionshutdown(s
, "Session timeout is zero", CDN_ADMIN_DISC
, 0);
776 if (p
[1] < 6) continue;
777 session
[s
].idle_timeout
= ntohl(*(uint32_t *)(p
+ 2));
778 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains Idle-Timeout = %u\n", session
[s
].idle_timeout
);
786 uint8_t *e
= p
+ p
[1];
787 uint8_t *m
= memchr(n
, '/', e
- n
);
790 inet_pton(AF_INET6
, (char *) n
, &r6
);
793 while (m
< e
&& isdigit(*m
)) {
794 prefixlen
= prefixlen
* 10 + *m
++ - '0';
799 if (routes6
== MAXROUTE6
)
801 LOG(1, s
, session
[s
].tunnel
, " Too many IPv6 routes\n");
805 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains route for %s/%d\n", n
, prefixlen
);
806 session
[s
].route6
[routes6
].ipv6route
= r6
;
807 session
[s
].route6
[routes6
].ipv6prefixlen
= prefixlen
;
814 // Delegated-IPv6-Prefix
815 if ((p
[1] > 4) && (p
[3] > 0) && (p
[3] <= 128))
817 char ipv6addr
[INET6_ADDRSTRLEN
];
819 if (routes6
== MAXROUTE6
)
821 LOG(1, s
, session
[s
].tunnel
, " Too many IPv6 routes\n");
825 memcpy(&session
[s
].route6
[routes6
].ipv6route
, &p
[4], p
[1] - 4);
826 session
[s
].route6
[routes6
].ipv6prefixlen
= p
[3];
827 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains Delegated IPv6 Prefix %s/%d\n",
828 inet_ntop(AF_INET6
, &session
[s
].route6
[routes6
].ipv6route
, ipv6addr
, INET6_ADDRSTRLEN
), session
[s
].route6
[routes6
].ipv6prefixlen
);
835 // Framed-IPv6-Address
838 char ipv6addr
[INET6_ADDRSTRLEN
];
839 memcpy(&session
[s
].ipv6address
, &p
[2], 16);
840 LOG(3, s
, session
[s
].tunnel
, " Radius reply contains Framed-IPv6-Address %s\n", inet_ntop(AF_INET6
, &session
[s
].ipv6address
, ipv6addr
, INET6_ADDRSTRLEN
));
846 if (p
[1] < 3) continue;
847 session
[s
].classlen
= p
[1] - 2;
848 if (session
[s
].classlen
> MAXCLASS
)
849 session
[s
].classlen
= MAXCLASS
;
850 memcpy(session
[s
].class, p
+ 2, session
[s
].classlen
);
855 if (p
[1] != 6) continue;
857 LOG(3, s
, session
[s
].tunnel
, " Radius reply Tunnel-Type:%d %d\n",
858 tag
, ntohl(*(uint32_t *)(p
+ 2)) & 0xFFFFFF);
860 lac_set_rad_tag_tunnel_type(tag
, ntohl(*(uint32_t *)(p
+ 2)) & 0xFFFFFF);
861 /* Request open tunnel to remote LNS*/
866 // Tunnel-Medium-Type
867 if (p
[1] < 6) continue;
869 LOG(3, s
, session
[s
].tunnel
, " Radius reply Tunnel-Medium-Type:%d %d\n",
870 tag
, ntohl(*(uint32_t *)(p
+ 2)) & 0xFFFFFF);
872 lac_set_rad_tag_tunnel_medium_type(tag
, ntohl(*(uint32_t *)(p
+ 2)) & 0xFFFFFF);
876 // Tunnel-Server-Endpoint
877 if (p
[1] < 3) continue;
879 //If the Tag field is greater than 0x1F,
880 // it SHOULD be interpreted as the first byte of the following String field.
881 memset(strtemp
, 0, 256);
885 memcpy(strtemp
, (p
+ 2), p
[1]-2);
888 memcpy(strtemp
, (p
+ 3), p
[1]-3);
890 LOG(3, s
, session
[s
].tunnel
, " Radius reply Tunnel-Server-Endpoint:%d %s\n", tag
, strtemp
);
892 lac_set_rad_tag_tunnel_serv_endpt(tag
, (char *) strtemp
);
899 if (p
[1] < 5) continue;
902 memset(strtemp
, 0, 256);
904 memcpy(strtemp
, (p
+ 3), lentemp
);
905 if (!rad_tunnel_pwdecode(strtemp
, &lentemp
, config
->radiussecret
, radius
[r
].auth
))
907 LOG_HEX(3, "Error Decode Tunnel-Password, Dump Radius reponse:", p
, p
[1]);
911 LOG(3, s
, session
[s
].tunnel
, " Radius reply Tunnel-Password:%d %s\n", tag
, strtemp
);
912 if (strlen((char *) strtemp
) > 63)
914 LOG(1, s
, session
[s
].tunnel
, "tunnel password is too long (>63)\n");
918 lac_set_rad_tag_tunnel_password(tag
, (char *) strtemp
);
922 // Tunnel-Assignment-Id
923 if (p
[1] < 3) continue;
925 //If the Tag field is greater than 0x1F,
926 // it SHOULD be interpreted as the first byte of the following String field.
927 memset(strtemp
, 0, 256);
931 memcpy(strtemp
, (p
+ 2), p
[1]-2);
934 memcpy(strtemp
, (p
+ 3), p
[1]-3);
936 LOG(3, s
, session
[s
].tunnel
, " Radius reply Tunnel-Assignment-Id:%d %s\n", tag
, strtemp
);
938 lac_set_rad_tag_tunnel_assignment_id(tag
, (char *) strtemp
);
942 else if (r_code
== AccessReject
)
944 LOG(2, s
, session
[s
].tunnel
, " Authentication rejected for %s\n", session
[s
].user
);
945 sessionkill(s
, "Authentication rejected");
949 if ((!config
->disable_lac_func
) && OpentunnelReq
)
951 char assignment_id
[256];
952 // Save radius tag context to conf
953 lac_save_rad_tag_tunnels(s
);
955 memset(assignment_id
, 0, 256);
956 if (!lac_rad_select_assignment_id(s
, assignment_id
))
957 break; // Error no assignment_id
959 LOG(3, s
, session
[s
].tunnel
, "Select Tunnel Remote LNS for assignment_id == %s\n", assignment_id
);
961 if (lac_rad_forwardtoremotelns(s
, assignment_id
, session
[s
].user
))
964 // Sanity check, no local IP to session forwarded
966 for (ro
= 0; r
< MAXROUTE
&& session
[s
].route
[ro
].ip
; r
++)
968 session
[s
].route
[ro
].ip
= 0;
974 // process auth response
978 uint8_t *p
= makeppp(b
, sizeof(b
), 0, 0, s
, t
, PPPCHAP
, 0, 0, 0);
979 if (!p
) return; // Abort!
981 *p
= (r_code
== AccessAccept
) ? 3 : 4; // ack/nak
983 *(uint16_t *) (p
+ 2) = ntohs(4); // no message
984 tunnelsend(b
, (p
- b
) + 4, t
); // send it
986 LOG(3, s
, session
[s
].tunnel
, " CHAP User %s authentication %s.\n", session
[s
].user
,
987 (r_code
== AccessAccept
) ? "allowed" : "denied");
992 uint8_t *p
= makeppp(b
, sizeof(b
), 0, 0, s
, t
, PPPPAP
, 0, 0, 0);
993 if (!p
) return; // Abort!
998 *(uint16_t *) (p
+ 2) = ntohs(5);
999 p
[4] = 0; // no message
1000 tunnelsend(b
, (p
- b
) + 5, t
); // send it
1002 LOG(3, s
, session
[s
].tunnel
, " PAP User %s authentication %s.\n", session
[s
].user
,
1003 (r_code
== AccessAccept
) ? "allowed" : "denied");
1006 if (!session
[s
].dns1
&& config
->default_dns1
)
1008 session
[s
].dns1
= ntohl(config
->default_dns1
);
1009 LOG(3, s
, t
, " Sending dns1 = %s\n", fmtaddr(config
->default_dns1
, 0));
1011 if (!session
[s
].dns2
&& config
->default_dns2
)
1013 session
[s
].dns2
= ntohl(config
->default_dns2
);
1014 LOG(3, s
, t
, " Sending dns2 = %s\n", fmtaddr(config
->default_dns2
, 0));
1017 // Valid Session, set it up
1018 session
[s
].unique_id
= 0;
1023 // An ack for a stop or start record.
1024 LOG(3, s
, t
, " RADIUS accounting ack recv in state %s\n", radius_state(radius
[r
].state
));
1029 // finished with RADIUS
1033 // Send a retry for RADIUS/CHAP message
1034 void radiusretry(uint16_t r
)
1036 sessionidt s
= radius
[r
].session
;
1041 if (s
) t
= session
[s
].tunnel
;
1043 switch (radius
[r
].state
)
1045 case RADIUSCHAP
: // sending CHAP down PPP
1048 case RADIUSAUTH
: // sending auth to RADIUS server
1049 case RADIUSJUSTAUTH
: // sending auth to RADIUS server
1050 case RADIUSSTART
: // sending start accounting to RADIUS server
1051 case RADIUSSTOP
: // sending stop accounting to RADIUS server
1052 case RADIUSINTERIM
: // sending interim accounting to RADIUS server
1053 radiussend(r
, radius
[r
].state
);
1056 case RADIUSNULL
: // Not in use
1057 case RADIUSWAIT
: // waiting timeout before available, in case delayed reply from RADIUS server
1058 // free up RADIUS task
1060 LOG(3, s
, session
[s
].tunnel
, "Freeing up radius session %d\n", r
);
1067 void processdae(uint8_t *buf
, int len
, struct sockaddr_in
*addr
, int alen
, struct in_addr
*local
)
1069 int i
, r_code
, r_id
, length
, attribute_length
;
1070 uint8_t *packet
, attribute
;
1072 char username
[MAXUSER
] = "";
1081 uint8_t *avpair
[64];
1082 int avpair_len
[sizeof(avpair
)/sizeof(*avpair
)];
1087 LOG(3, 0, 0, "DAE request from %s\n", fmtaddr(addr
->sin_addr
.s_addr
, 0));
1088 LOG_HEX(5, "DAE Request", buf
, len
);
1090 if (len
< 20 || len
< ntohs(*(uint16_t *) (buf
+ 2)))
1092 LOG(1, 0, 0, "Duff DAE request length %d\n", len
);
1096 r_code
= buf
[0]; // request type
1097 r_id
= buf
[1]; // radius indentifier.
1099 if (r_code
!= DisconnectRequest
&& r_code
!= CoARequest
)
1101 LOG(1, 0, 0, "Unrecognised DAE request %s\n", radius_code(r_code
));
1105 if (!config
->cluster_iam_master
)
1107 master_forward_dae_packet(buf
, len
, addr
->sin_addr
.s_addr
, addr
->sin_port
);
1111 len
= ntohs(*(uint16_t *) (buf
+ 2));
1113 LOG(3, 0, 0, "Received DAE %s, id %d\n", radius_code(r_code
), r_id
);
1115 // check authenticator
1116 calc_auth(buf
, len
, zero
, hash
);
1117 if (memcmp(hash
, buf
+ 4, 16) != 0)
1119 LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n");
1123 // unpack attributes
1129 attribute
= *packet
++;
1130 attribute_length
= *packet
++;
1131 if (attribute_length
< 2)
1134 length
-= attribute_length
;
1135 attribute_length
-= 2;
1138 case 1: /* username */
1139 len
= attribute_length
< MAXUSER
? attribute_length
: MAXUSER
- 1;
1140 memcpy(username
, packet
, len
);
1142 LOG(4, 0, 0, " Received DAE User-Name: %s\n", username
);
1145 case 4: /* nas ip address */
1146 nas
= *(uint32_t *) packet
; // net order
1147 if (nas
!= config
->bind_address
)
1148 error
= 403; // NAS identification mismatch
1150 LOG(4, 0, 0, " Received DAE NAS-IP-Address: %s\n", fmtaddr(nas
, 0));
1153 case 5: /* nas port */
1154 port
= ntohl(*(uint32_t *) packet
);
1155 if (port
< 1 || port
> MAXSESSION
)
1158 LOG(4, 0, 0, " Received DAE NAS-Port: %u\n", port
);
1161 case 6: /* service type */
1163 uint32_t service_type
= ntohl(*(uint32_t *) packet
);
1164 auth_only
= service_type
== 8; // Authenticate only
1166 LOG(4, 0, 0, " Received DAE Service-Type: %u\n", service_type
);
1170 case 8: /* ip address */
1171 ip
= *(uint32_t *) packet
; // net order
1172 LOG(4, 0, 0, " Received DAE Framed-IP-Address: %s\n", fmtaddr(ip
, 0));
1175 case 11: /* filter id */
1176 LOG(4, 0, 0, " Received DAE Filter-Id: %.*s\n", attribute_length
, packet
);
1177 if (!(p
= memchr(packet
, '.', attribute_length
)))
1179 error
= 404; // invalid request
1184 i
= find_filter((char *) packet
, len
);
1185 if (i
< 0 || !*ip_filters
[i
].name
)
1191 if (!memcmp(p
, ".in", attribute_length
- len
))
1193 else if (!memcmp(p
, ".out", attribute_length
- len
))
1200 case 26: /* vendor specific */
1201 if (attribute_length
>= 6
1202 && ntohl(*(uint32_t *) packet
) == 9 // Cisco
1203 && *(packet
+ 4) == 1 // Cisco-AVPair
1204 && *(packet
+ 5) >= 2) // length
1206 int len
= *(packet
+ 5) - 2;
1207 uint8_t *a
= packet
+ 6;
1209 LOG(4, 0, 0, " Received DAE Cisco-AVPair: %.*s\n", len
, a
);
1210 if (avp
< sizeof(avpair
)/sizeof(*avpair
) - 1)
1213 avpair_len
[avp
++] = len
;
1219 packet
+= attribute_length
;
1222 if (!error
&& auth_only
)
1224 if (fin
!= -1 || fout
!= -1 || avp
)
1225 error
= 401; // unsupported attribute
1227 error
= 405; // unsupported service
1230 if (!error
&& !(port
|| ip
|| *username
))
1231 error
= 402; // missing attribute
1233 // exact match for SID if given
1237 if (!session
[s
].opened
)
1238 error
= 503; // not found
1243 // find/check session by IP
1244 i
= sessionbyip(ip
);
1245 if (!i
|| (s
&& s
!= i
)) // not found or mismatching port
1251 if (!error
&& *username
)
1255 if (strcmp(session
[s
].user
, username
))
1258 else if (!(s
= sessionbyuser(username
)))
1262 t
= session
[s
].tunnel
;
1266 case DisconnectRequest
: // Packet of Disconnect/Death
1269 r_code
= DisconnectNAK
;
1273 LOG(3, s
, t
, " DAE Disconnect %d (%s)\n", s
, session
[s
].user
);
1274 r_code
= DisconnectACK
;
1276 sessionshutdown(s
, "Requested by PoD", CDN_ADMIN_DISC
, TERM_ADMIN_RESET
); // disconnect session
1279 case CoARequest
: // Change of Authorization
1286 LOG(3, s
, t
, " DAE Change %d (%s)\n", s
, session
[s
].user
);
1291 struct param_radius_reset p
= { &tunnel
[session
[s
].tunnel
], &session
[s
] };
1292 run_plugins(PLUGIN_RADIUS_RESET
, &p
);
1299 LOG(3, s
, t
, " Filter in %d (%s)\n", fin
, ip_filters
[fin
- 1].name
);
1304 LOG(3, s
, t
, " Filter out %d (%s)\n", fout
, ip_filters
[fout
- 1].name
);
1306 filter_session(s
, fin
, fout
);
1308 // process cisco av-pair(s)
1309 for (i
= 0; i
< avp
; i
++)
1311 LOG(3, s
, t
, " Cisco-AVPair: %.*s\n", avpair_len
[i
], avpair
[i
]);
1312 handle_avpair(s
, avpair
[i
], avpair_len
[i
]);
1315 cluster_send_session(s
);
1333 *(uint32_t *) packet
= htonl(error
);
1337 *((uint16_t *)(buf
+ 2)) = htons(len
);
1340 calc_auth(buf
, len
, hash
, buf
+ 4);
1342 LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code
), r_id
);
1344 // send DAE response
1345 if (sendtofrom(daefd
, buf
, len
, MSG_DONTWAIT
| MSG_NOSIGNAL
, (struct sockaddr
*) addr
, alen
, local
) < 0)
1346 LOG(0, 0, 0, "Error sending DAE response packet: %s\n", strerror(errno
));
1349 // Decrypte the encrypted Tunnel Password.
1350 // Defined in RFC-2868.
1351 // the pl2tpsecret buffer must set to 256 characters.
1352 // return 0 on decoding error else length of decoded l2tpsecret
1353 int rad_tunnel_pwdecode(uint8_t *pl2tpsecret
, size_t *pl2tpsecretlen
,
1354 const char *radiussecret
, const uint8_t * auth
)
1356 MD5_CTX ctx
, oldctx
;
1359 unsigned i
, n
, len
, decodedlen
;
1361 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 6 7
1362 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1363 | Salt | Salt | String ..........
1364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/
1366 len
= *pl2tpsecretlen
;
1370 LOG(1, 0, 0, "tunnel password is too short, We need at least a salt\n");
1377 *pl2tpsecretlen
= 0;
1378 LOG(1, 0, 0, "tunnel passwd is empty !!!\n");
1382 len
-= 2; /* discount the salt */
1384 //Use the secret to setup the decryption
1385 secretlen
= strlen(radiussecret
);
1388 MD5_Update(&ctx
, (void *) radiussecret
, secretlen
);
1389 oldctx
= ctx
; /* save intermediate work */
1391 // Set up the initial key:
1392 // b(1) = MD5(radiussecret + auth + salt)
1393 MD5_Update(&ctx
, (void *) auth
, 16);
1394 MD5_Update(&ctx
, pl2tpsecret
, 2);
1397 for (n
= 0; n
< len
; n
+= 16)
1403 MD5_Final(hash
, &ctx
);
1407 // the first octet, it's the 'data_len'
1409 decodedlen
= pl2tpsecret
[2] ^ hash
[0];
1410 if (decodedlen
>= len
)
1412 LOG(1, 0, 0, "tunnel password is too long !!!\n");
1416 MD5_Update(&ctx
, pl2tpsecret
+ 2, 16);
1420 MD5_Final(hash
, &ctx
);
1423 MD5_Update(&ctx
, pl2tpsecret
+ n
+ 2, 16);
1426 for (i
= base
; i
< 16; i
++)
1428 pl2tpsecret
[n
+ i
- 1] = pl2tpsecret
[n
+ i
+ 2] ^ hash
[i
];
1432 if (decodedlen
> 239) decodedlen
= 239;
1434 *pl2tpsecretlen
= decodedlen
;
1435 pl2tpsecret
[decodedlen
] = 0;