Go to the documentation of this file.
   72 #include <netinet/in.h> 
   92 static void md5_calc(uint8_t out[16], 
void *in, 
size_t len);
 
  128     return (b->tv_sec - a->tv_sec) * 1000000 + (b->tv_usec - a->tv_usec);
 
  138     gettimeofday(&now, 
nullptr);
 
  168     totallen = ntohs(auth->
length);
 
  170     if (totallen != length) {
 
  171         debug(
"Received invalid reply length from server (want %d/ got %d)\n", totallen, length);
 
  182     memcpy(buffer + length, 
secretkey, secretlen);
 
  183     md5_calc(calc_digest, (
unsigned char *) auth, length + secretlen);
 
  186         debug(
"WARNING: Received invalid reply digest from server\n");
 
  202     static std::uniform_int_distribution<uint8_t> dist;
 
  205         aVector[i] = 
static_cast<char>(dist(mt) & 0xFF);
 
  220     int srv = 0, crt = 0;
 
  222     if ((cf = fopen(cfname, 
"r")) == 
nullptr) {
 
  226     while (fgets(line, 
MAXLINE, cf) != 
nullptr) {
 
  227         if (!memcmp(line, 
"server", 6))
 
  228             srv = sscanf(line, 
"server %s", 
server);
 
  229         if (!memcmp(line, 
"secret", 6))
 
  230             crt = sscanf(line, 
"secret %s", 
secretkey);
 
  231         if (!memcmp(line, 
"identifier", 10))
 
  233         if (!memcmp(line, 
"service", 7))
 
  234             sscanf(line, 
"service %s", 
svc_name);
 
  235         if (!memcmp(line, 
"port", 4))
 
  237         if (!memcmp(line, 
"timeout", 7))
 
  238             sscanf(line, 
"timeout %d", &
retries);
 
  251     while (*src && 
size > 1) {
 
  252         if (*src == 
'%' && src[1] != 
'\0' && src[2] != 
'\0') {
 
  258             *dst = strtol(tmp, 
nullptr, 16);
 
  274     unsigned short total_length;
 
  283     struct sockaddr_in saremote;
 
  304     length = strlen(username);
 
  310     memcpy(ptr, username, length);
 
  312     total_length += length + 2;
 
  317     length = strlen(passwd);
 
  322     memcpy(passbuf, passwd, length);
 
  347             *ptr = (cbc[i] ^= passbuf[j + i]);
 
  351     total_length += length + 2;
 
  381         total_length += len + 2;
 
  402     auth->
length = htons(total_length);
 
  411         gettimeofday(&sent, 
nullptr);
 
  412         if (
xsend(socket_fd, auth, total_length, 0) < 0) {
 
  416             if (xerrno != EAGAIN && xerrno != EWOULDBLOCK)
 
  417                 fprintf(stderr,
"ERROR: RADIUS send() failure: %s\n", 
xstrerr(xerrno));
 
  420         while ((time_spent = 
time_since(&sent)) < 1000000) {
 
  428                 tv.tv_usec = 1000000 - time_spent;
 
  431             FD_SET(socket_fd, &readfds);
 
  432             if (
xselect(socket_fd + 1, &readfds, 
nullptr, 
nullptr, &tv) == 0)  
 
  434             salen = 
sizeof(saremote);
 
  436                             0, (
struct sockaddr *) &saremote, &salen);
 
  453     fprintf(stderr, 
"%s: No response from RADIUS server\n", 
progname);
 
  454     SEND_ERR(
"No response from RADIUS server");
 
  461     struct sockaddr_in salocal;
 
  462     struct sockaddr_in saremote;
 
  463     unsigned short svc_port;
 
  468     const char *cfname = 
nullptr;
 
  473     while ((c = 
getopt(argc, argv, 
"h:p:f:w:i:t:")) != -1) {
 
  503     if (setvbuf(stdout, 
nullptr, _IOLBF, 0) != 0)
 
  508             fprintf(stderr, 
"FATAL: %s: can't open configuration file '%s'.\n", argv[0], cfname);
 
  513         fprintf(stderr, 
"FATAL: %s: Server not specified\n", argv[0]);
 
  517         fprintf(stderr, 
"FATAL: %s: Shared secret not specified\n", argv[0]);
 
  523         WSAStartup(2, &wsaData);
 
  532         svc_port = ntohs((
unsigned short) svp->s_port);
 
  540         fprintf(stderr, 
"FATAL: %s: Couldn't find host %s\n", argv[0], 
server);
 
  548     memset(&saremote, 0, 
sizeof(saremote));
 
  549     saremote.sin_family = AF_INET;
 
  551     saremote.sin_port = htons(svc_port);
 
  553     if (
xconnect(
sockfd, (
struct sockaddr *) &saremote, 
sizeof(saremote)) < 0) {
 
  557     salen = 
sizeof(salocal);
 
  559         perror(
"getsockname");
 
  563     if (fcntl(
sockfd, F_SETFL, fcntl(
sockfd, F_GETFL, 0) | O_NONBLOCK) < 0) {
 
  565         fprintf(stderr,
"%s| ERROR: fcntl() failure: %s\n", argv[0], 
xstrerr(xerrno));
 
  573         if ((end = strchr(buf, 
'\n')) == 
nullptr) {
 
  591         while (isspace(*ptr))
 
  593         if ((end = strchr(ptr, 
' ')) == 
nullptr) {
 
  600         while (isspace(*ptr))
 
  
uint32_t get_ipaddr(char *host)
const char * xstrerr(int error)
static void random_vector(char *aVector)
static char vector[AUTH_VECTOR_LEN]
SQUIDCEXTERN void SquidMD5Init(struct SquidMD5Context *context)
static char * recv_buffer
static char * send_buffer
void debug(const char *format,...)
static uint32_t auth_ipaddr
static void authenticate(int socket_fd, const char *username, const char *passwd)
static int timeval_diff(const struct timeval *a, const struct timeval *b)
static void urldecode(char *dst, const char *src, int size)
static char svc_name[MAXLINE]
SQUIDCEXTERN void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context)
int getopt(int nargc, char *const *nargv, const char *ostr)
ssize_t xsend(int socketFd, const void *buf, size_t bufLength, int flags)
POSIX send(2) equivalent.
std::mt19937::result_type RandomSeed32()
ssize_t xrecvfrom(int socketFd, void *buf, size_t bufLength, int flags, struct sockaddr *from, socklen_t *fromLength)
POSIX recvfrom(2) equivalent.
u_char vector[AUTH_VECTOR_LEN]
int xgetsockname(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX getsockname(2) equivalent.
static int result_recv(char *buffer, int length)
#define PW_AUTHENTICATION_REQUEST
static int rad_auth_config(const char *cfname)
#define PW_NAS_IP_ADDRESS
static int i_recv_buffer[2048]
static int time_since(const struct timeval *when)
#define PW_AUTHENTICATION_ACK
static char identifier[MAXLINE]
int xsocket(int domain, int type, int protocol)
POSIX socket(2) equivalent.
int xselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
POSIX select(2) equivalent.
#define HELPER_INPUT_BUFFER
static uint32_t nas_ipaddr
static char server[MAXLINE]
static char secretkey[MAXPASS+1]
static void Win32SockCleanup(void)
struct servent * xgetservbyname(const char *name, const char *proto)
POSIX getservbyname(3) equivalent.
SQUIDCEXTERN void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len)
int main(int argc, char **argv)
int xclose(int fd)
POSIX close(2) equivalent.
static int i_send_buffer[2048]
int xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength)
POSIX connect(2) equivalent.
static void md5_calc(uint8_t out[16], void *in, size_t len)