68#include <sys/socket.h>
71#include <netinet/in.h>
100static void md5_calc(uint8_t out[16],
void *in,
size_t len);
136 return (b->tv_sec - a->tv_sec) * 1000000 + (b->tv_usec - a->tv_usec);
146 gettimeofday(&
now,
nullptr);
176 totallen = ntohs(auth->
length);
178 if (totallen != length) {
179 debug(
"Received invalid reply length from server (want %d/ got %d)\n", totallen, length);
190 memcpy(buffer + length,
secretkey, secretlen);
191 md5_calc(calc_digest, (
unsigned char *) auth, length + secretlen);
194 debug(
"WARNING: Received invalid reply digest from server\n");
210 static std::uniform_int_distribution<uint8_t> dist;
213 aVector[i] =
static_cast<char>(dist(mt) & 0xFF);
228 int srv = 0, crt = 0;
230 if ((cf = fopen(cfname,
"r")) ==
nullptr) {
234 while (fgets(line,
MAXLINE, cf) !=
nullptr) {
235 if (!memcmp(line,
"server", 6))
236 srv = sscanf(line,
"server %s",
server);
237 if (!memcmp(line,
"secret", 6))
238 crt = sscanf(line,
"secret %s",
secretkey);
239 if (!memcmp(line,
"identifier", 10))
241 if (!memcmp(line,
"service", 7))
242 sscanf(line,
"service %s",
svc_name);
243 if (!memcmp(line,
"port", 4))
245 if (!memcmp(line,
"timeout", 7))
246 sscanf(line,
"timeout %d", &
retries);
259 while (*src &&
size > 1) {
260 if (*src ==
'%' && src[1] !=
'\0' && src[2] !=
'\0') {
266 *dst = strtol(tmp,
nullptr, 16);
282 unsigned short total_length;
291 struct sockaddr_in saremote;
312 length = strlen(username);
318 memcpy(ptr, username, length);
320 total_length += length + 2;
325 length = strlen(passwd);
330 memcpy(passbuf, passwd, length);
355 *ptr = (cbc[i] ^= passbuf[j + i]);
359 total_length += length + 2;
389 total_length += len + 2;
410 auth->
length = htons(total_length);
419 gettimeofday(&sent,
nullptr);
420 if (send(socket_fd, (
char *) auth, total_length, 0) < 0) {
424 if (xerrno != EAGAIN && xerrno != EWOULDBLOCK)
425 fprintf(stderr,
"ERROR: RADIUS send() failure: %s\n",
xstrerr(xerrno));
428 while ((time_spent =
time_since(&sent)) < 1000000) {
436 tv.tv_usec = 1000000 - time_spent;
439 FD_SET(socket_fd, &readfds);
440 if (select(socket_fd + 1, &readfds,
nullptr,
nullptr, &tv) == 0)
442 salen =
sizeof(saremote);
444 0, (
struct sockaddr *) &saremote, &salen);
461 fprintf(stderr,
"%s: No response from RADIUS server\n",
progname);
462 SEND_ERR(
"No response from RADIUS server");
469 struct sockaddr_in salocal;
470 struct sockaddr_in saremote;
472 unsigned short svc_port;
477 const char *cfname =
nullptr;
482 while ((c =
getopt(argc, argv,
"h:p:f:w:i:t:")) != -1) {
512 if (setvbuf(stdout,
nullptr, _IOLBF, 0) != 0)
517 fprintf(stderr,
"FATAL: %s: can't open configuration file '%s'.\n", argv[0], cfname);
522 fprintf(stderr,
"FATAL: %s: Server not specified\n", argv[0]);
526 fprintf(stderr,
"FATAL: %s: Shared secret not specified\n", argv[0]);
532 WSAStartup(2, &wsaData);
539 svp = getservbyname(
svc_name,
"udp");
541 svc_port = ntohs((
unsigned short) svp->s_port);
549 fprintf(stderr,
"FATAL: %s: Couldn't find host %s\n", argv[0],
server);
552 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
557 memset(&saremote, 0,
sizeof(saremote));
558 saremote.sin_family = AF_INET;
560 saremote.sin_port = htons(svc_port);
562 if (connect(
sockfd, (
struct sockaddr *) &saremote,
sizeof(saremote)) < 0) {
566 salen =
sizeof(salocal);
567 if (getsockname(
sockfd, (
struct sockaddr *) &salocal, &salen) < 0) {
568 perror(
"getsockname");
572 if (fcntl(
sockfd, F_SETFL, fcntl(
sockfd, F_GETFL, 0) | O_NONBLOCK) < 0) {
574 fprintf(stderr,
"%s| ERROR: fcntl() failure: %s\n", argv[0],
xstrerr(xerrno));
582 if ((end = strchr(buf,
'\n')) ==
nullptr) {
600 while (isspace(*ptr))
602 if ((end = strchr(ptr,
' ')) ==
nullptr) {
609 while (isspace(*ptr))
static void Win32SockCleanup(void)
std::mt19937::result_type RandomSeed32()
#define HELPER_INPUT_BUFFER
static uint32_t auth_ipaddr
static uint32_t nas_ipaddr
static int timeval_diff(const struct timeval *a, const struct timeval *b)
static void urldecode(char *dst, const char *src, int size)
static int i_send_buffer[2048]
int main(int argc, char **argv)
static void md5_calc(uint8_t out[16], void *in, size_t len)
static char secretkey[MAXPASS+1]
static char * recv_buffer
static void random_vector(char *aVector)
static char svc_name[MAXLINE]
static char identifier[MAXLINE]
static char * send_buffer
static char vector[AUTH_VECTOR_LEN]
static char server[MAXLINE]
static int rad_auth_config(const char *cfname)
static int i_recv_buffer[2048]
static int time_since(const struct timeval *when)
static int result_recv(char *buffer, int length)
static void authenticate(int socket_fd, const char *username, const char *passwd)
void debug(const char *format,...)
int getopt(int nargc, char *const *nargv, const char *ostr)
SQUIDCEXTERN void SquidMD5Init(struct SquidMD5Context *context)
SQUIDCEXTERN void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len)
SQUIDCEXTERN void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context)
uint32_t get_ipaddr(char *host)
#define PW_NAS_IP_ADDRESS
#define PW_AUTHENTICATION_REQUEST
#define PW_AUTHENTICATION_ACK
u_char vector[AUTH_VECTOR_LEN]
const char * xstrerr(int error)