18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * $Id: sendserver.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (C) 1995,1996,1997 Lars Fenneberg 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright 1992 Livingston Enterprises, Inc. 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and Merit Network, Inc. All Rights Reserved 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * See the file COPYRIGHT for the respective terms and conditions. 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the file is missing contact me at lf@elemental.net 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and I'll send you a copy. 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <includes.h> 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <radiusclient.h> 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <pathnames.h> 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void rc_random_vector (unsigned char *); 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int rc_check_reply (AUTH_HDR *, int, char *, unsigned char *, unsigned char); 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Function: rc_pack_list 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Purpose: Packs an attribute value pair list into a buffer. 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns: Number of octets packed. 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth) 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int length, i, pc, secretlen, padded_length; 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int total_length = 0; 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT4 lvalue; 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)]; 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char md5buf[256]; 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *buf, *vector, *lenptr; 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buf = auth->data; 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (vp != (VALUE_PAIR *) NULL) 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (vp->vendorcode != VENDOR_NONE) { 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = PW_VENDOR_SPECIFIC; 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Place-holder for where to put length */ 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lenptr = buf++; 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Insert vendor code */ 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = 0; 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = (((unsigned int) vp->vendorcode) >> 16) & 255; 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = (((unsigned int) vp->vendorcode) >> 8) & 255; 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = ((unsigned int) vp->vendorcode) & 255; 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Insert vendor-type */ 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = vp->attribute; 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Insert value */ 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch(vp->type) { 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_TYPE_STRING: 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = vp->lvalue; 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *lenptr = length + 8; 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = length+2; 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(buf, vp->strvalue, (size_t) length); 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buf += length; 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length += length+8; 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_TYPE_INTEGER: 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_TYPE_IPADDR: 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = sizeof(UINT4); 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *lenptr = length + 8; 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = length+2; 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lvalue = htonl(vp->lvalue); 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(buf, (char *) &lvalue, sizeof(UINT4)); 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buf += length; 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length += length+8; 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default: 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = vp->attribute; 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch (vp->attribute) { 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_USER_PASSWORD: 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Encrypt the password */ 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Chop off password at AUTH_PASS_LEN */ 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = vp->lvalue; 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (length > AUTH_PASS_LEN) length = AUTH_PASS_LEN; 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Calculate the padded length */ 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1); 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Record the attribute length */ 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = padded_length + 2; 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Pad the password with zeros */ 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset ((char *) passbuf, '\0', AUTH_PASS_LEN); 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) passbuf, vp->strvalue, (size_t) length); 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project secretlen = strlen (secret); 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project vector = (char *)auth->vector; 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN) { 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Calculate the MD5 digest*/ 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy ((char *) md5buf, secret); 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) md5buf + secretlen, vector, 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project AUTH_VECTOR_LEN); 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Remeber the start of the digest */ 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project vector = buf; 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Xor the password into the MD5 digest */ 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++) { 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ ^= passbuf[pc]; 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length += padded_length + 2; 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_CHAP_PASSWORD: 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = CHAP_VALUE_LENGTH + 2; 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Encrypt the Password */ 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = vp->lvalue; 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (length > CHAP_VALUE_LENGTH) { 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = CHAP_VALUE_LENGTH; 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset ((char *) passbuf, '\0', CHAP_VALUE_LENGTH); 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) passbuf, vp->strvalue, (size_t) length); 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Calculate the MD5 Digest */ 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project secretlen = strlen (secret); 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy ((char *) md5buf, secret); 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) md5buf + secretlen, (char *) auth->vector, 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project AUTH_VECTOR_LEN); 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Xor the password into the MD5 digest */ 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < CHAP_VALUE_LENGTH; i++) { 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ ^= passbuf[i]; 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length += CHAP_VALUE_LENGTH + 2; 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default: 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch (vp->type) { 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_TYPE_STRING: 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = vp->lvalue; 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = length + 2; 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy (buf, vp->strvalue, (size_t) length); 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buf += length; 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length += length + 2; 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_TYPE_INTEGER: 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case PW_TYPE_IPADDR: 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = sizeof (UINT4) + 2; 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lvalue = htonl (vp->lvalue); 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy (buf, (char *) &lvalue, sizeof (UINT4)); 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buf += sizeof (UINT4); 1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length += sizeof (UINT4) + 2; 1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default: 1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project vp = vp->next; 1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return total_length; 1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Function: rc_send_server 1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Purpose: send a request to a RADIUS server and wait for the reply 1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info) 1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int sockfd; 1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr salocal; 1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr saremote; 1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr_in *sin; 1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval authtime; 1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fd_set readfds; 2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project AUTH_HDR *auth, *recv_auth; 2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT4 auth_ipaddr; 2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *server_name; /* Name of server to query */ 2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int salen; 2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int result; 2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int total_length; 2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int length; 2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int retry_max; 2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int secretlen; 2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char secret[MAX_SECRET_LENGTH + 1]; 2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char vector[AUTH_VECTOR_LEN]; 2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char recv_buffer[BUFFER_LEN]; 2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char send_buffer[BUFFER_LEN]; 2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int retries; 2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project VALUE_PAIR *vp; 2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project server_name = data->server; 2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (server_name == (char *) NULL || server_name[0] == '\0') 2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE)) && \ 2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (vp->lvalue == PW_ADMINISTRATIVE)) 2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy(secret, MGMT_POLL_SECRET); 2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((auth_ipaddr = rc_get_ipaddr(server_name)) == 0) 2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (rc_find_server (server_name, &auth_ipaddr, secret) != 0) 2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sockfd = socket (AF_INET, SOCK_DGRAM, 0); 2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (sockfd < 0) 2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset (secret, '\0', sizeof (secret)); 2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_send_server: socket: %s", strerror(errno)); 2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = sizeof (salocal); 2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin = (struct sockaddr_in *) & salocal; 2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset ((char *) sin, '\0', (size_t) length); 2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin->sin_family = AF_INET; 2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin->sin_addr.s_addr = htonl(INADDR_ANY); 2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin->sin_port = htons ((unsigned short) 0); 2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (bind (sockfd, (struct sockaddr *) sin, length) < 0 || 2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project getsockname (sockfd, (struct sockaddr *) sin, &length) < 0) 2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close (sockfd); 2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset (secret, '\0', sizeof (secret)); 2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_send_server: bind: %s: %m", server_name); 2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project retry_max = data->retries; /* Max. numbers to try for reply */ 2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project retries = 0; /* Init retry cnt for blocking call */ 2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Build a request */ 2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth = (AUTH_HDR *) send_buffer; 2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth->code = data->code; 2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth->id = data->seq_nbr; 2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (data->code == PW_ACCOUNTING_REQUEST) 2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN; 2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth->length = htons ((unsigned short) total_length); 2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset((char *) auth->vector, 0, AUTH_VECTOR_LEN); 2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project secretlen = strlen (secret); 2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) auth + total_length, secret, secretlen); 2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc_md5_calc (vector, (char *) auth, total_length + secretlen); 2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN); 2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc_random_vector (vector); 2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy (auth->vector, vector, AUTH_VECTOR_LEN); 2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN; 2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth->length = htons ((unsigned short) total_length); 2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin = (struct sockaddr_in *) & saremote; 2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset ((char *) sin, '\0', sizeof (saremote)); 2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin->sin_family = AF_INET; 2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin->sin_addr.s_addr = htonl (auth_ipaddr); 2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sin->sin_port = htons ((unsigned short) data->svc_port); 2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (;;) 2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0, 2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (struct sockaddr *) sin, sizeof (struct sockaddr_in)); 2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project authtime.tv_usec = 0L; 3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project authtime.tv_sec = (long) data->timeout; 3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_ZERO (&readfds); 3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET (sockfd, &readfds); 3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0) 3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno == EINTR) 3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_send_server: select: %m"); 3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset (secret, '\0', sizeof (secret)); 3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close (sockfd); 3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (FD_ISSET (sockfd, &readfds)) 3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Timed out waiting for response. Retry "retry_max" times 3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * before giving up. If retry_max = 0, don't retry at all. 3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (++retries >= retry_max) 3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_send_server: no reply from RADIUS server %s:%u", 3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc_ip_hostname (auth_ipaddr), data->svc_port); 3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close (sockfd); 3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset (secret, '\0', sizeof (secret)); 3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (TIMEOUT_RC); 3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project salen = sizeof (saremote); 3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project length = recvfrom (sockfd, (char *) recv_buffer, 3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (int) sizeof (recv_buffer), 3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (int) 0, &saremote, &salen); 3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (length <= 0) 3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_send_server: recvfrom: %s:%d: %m", server_name,\ 3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data->svc_port); 3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close (sockfd); 3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset (secret, '\0', sizeof (secret)); 3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (ERROR_RC); 3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recv_auth = (AUTH_HDR *)recv_buffer; 3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr); 3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data->receive_pairs = rc_avpair_gen(recv_auth); 3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close (sockfd); 3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (info) 3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(info->secret, secret, sizeof(info->secret)); 3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(info->request_vector, vector, 3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sizeof(info->request_vector)); 3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset (secret, '\0', sizeof (secret)); 3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (result != OK_RC) return (result); 3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *msg = '\0'; 3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project vp = data->receive_pairs; 3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (vp) 3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE))) 3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcat(msg, vp->strvalue); 3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcat(msg, "\n"); 3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project vp = vp->next; 3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((recv_auth->code == PW_ACCESS_ACCEPT) || 3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (recv_auth->code == PW_PASSWORD_ACK) || 3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (recv_auth->code == PW_ACCOUNTING_RESPONSE)) 3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project result = OK_RC; 3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project result = BADRESP_RC; 3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (result); 3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Function: rc_check_reply 3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Purpose: verify items in returned packet. 3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns: OK_RC -- upon success, 3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * BADRESP_RC -- if anything looks funny. 3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret, 3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *vector, unsigned char seq_nbr) 3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int secretlen; 3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int totallen; 4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char calc_digest[AUTH_VECTOR_LEN]; 4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char reply_digest[AUTH_VECTOR_LEN]; 4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project totallen = ntohs (auth->length); 4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project secretlen = strlen (secret); 4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Do sanity checks on packet length */ 4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((totallen < 20) || (totallen > 4096)) 4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_check_reply: received RADIUS server response with invalid length"); 4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (BADRESP_RC); 4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Verify buffer space, should never trigger with current buffer size and check above */ 4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((totallen + secretlen) > bufferlen) 4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_check_reply: not enough buffer space to verify RADIUS server response"); 4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (BADRESP_RC); 4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Verify that id (seq. number) matches what we sent */ 4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (auth->id != seq_nbr) 4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_check_reply: received non-matching id in RADIUS server response"); 4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (BADRESP_RC); 4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Verify the reply digest */ 4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN); 4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN); 4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) auth + totallen, secret, secretlen); 4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc_md5_calc (calc_digest, (char *) auth, totallen + secretlen); 4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef DIGEST_DEBUG 4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fputs("reply_digest: ", stderr); 4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < AUTH_VECTOR_LEN; i++) 4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(stderr,"%.2x ", (int) reply_digest[i]); 4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fputs("\ncalc_digest: ", stderr); 4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < AUTH_VECTOR_LEN; i++) 4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(stderr,"%.2x ", (int) calc_digest[i]); 4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fputs("\n", stderr); 4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (memcmp ((char *) reply_digest, (char *) calc_digest, 4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project AUTH_VECTOR_LEN) != 0) 4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef RADIUS_116 4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* the original Livingston radiusd v1.16 seems to have 4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project a bug in digest calculation with accounting requests, 4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project authentication request are ok. i looked at the code 4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project but couldn't find any bugs. any help to get this 4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project kludge out are welcome. preferably i want to 4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project reproduce the calculation bug here to be compatible 4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project to stock Livingston radiusd v1.16. -lf, 03/14/96 4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (auth->code == PW_ACCOUNTING_RESPONSE) 4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (OK_RC); 4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("rc_check_reply: received invalid reply digest from RADIUS server"); 4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (BADRESP_RC); 4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (OK_RC); 4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Function: rc_random_vector 4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Purpose: generates a random vector of AUTH_VECTOR_LEN octets. 4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns: the vector (call by reference) 4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void rc_random_vector (unsigned char *vector) 4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int randno; 4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fd; 4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* well, I added this to increase the security for user passwords. 4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project we use /dev/urandom here, as /dev/random might block and we don't 4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project need that much randomness. BTW, great idea, Ted! -lf, 03/18/95 */ 4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((fd = open(_PATH_DEV_URANDOM, O_RDONLY)) >= 0) 4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pos; 4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int readcount; 4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project i = AUTH_VECTOR_LEN; 4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pos = vector; 5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (i > 0) 5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project readcount = read(fd, (char *)pos, i); 5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pos += readcount; 5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project i -= readcount; 5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(fd); 5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } /* else fall through */ 5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < AUTH_VECTOR_LEN;) 5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project randno = magic(); 5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy ((char *) vector, (char *) &randno, sizeof (int)); 5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project vector += sizeof (int); 5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project i += sizeof (int); 5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 521