home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / radius_2.zip / radpass.c < prev    next >
C/C++ Source or Header  |  1996-05-20  |  8KB  |  306 lines

  1. /*
  2.  *
  3.  *    RADIUS
  4.  *    Remote Authentication Dial In User Service
  5.  *
  6.  *
  7.  *    Livingston Enterprises, Inc.
  8.  *    6920 Koll Center Parkway
  9.  *    Pleasanton, CA   94566
  10.  *
  11.  *    Copyright 1992 Livingston Enterprises, Inc.
  12.  *
  13.  *    Permission to use, copy, modify, and distribute this software for any
  14.  *    purpose and without fee is hereby granted, provided that this
  15.  *    copyright and permission notice appear on all copies and supporting
  16.  *    documentation, the name of Livingston Enterprises, Inc. not be used
  17.  *    in advertising or publicity pertaining to distribution of the
  18.  *    program without specific prior permission, and notice be given
  19.  *    in supporting documentation that copying and distribution is by
  20.  *    permission of Livingston Enterprises, Inc.   
  21.  *
  22.  *    Livingston Enterprises, Inc. makes no representations about
  23.  *    the suitability of this software for any purpose.  It is
  24.  *    provided "as is" without express or implied warranty.
  25.  *
  26.  */
  27.  
  28. static char sccsid[] =
  29. "@(#)radpass.c    1.5 Copyright 1992 Livingston Enterprises Inc";
  30.  
  31. #include    <sys/types.h>
  32. #include    <sys/socket.h>
  33. #include    <netinet/in.h>
  34.  
  35. #include    <stdio.h>
  36. #include    <stdlib.h>
  37. #include    <unistd.h>
  38. #include    <netdb.h>
  39. #include    <pwd.h>
  40. #include    <time.h>
  41.  
  42. #include    "radius.h"
  43.  
  44. #define MAXPWNAM    8
  45. #define MAXPASS        16
  46.  
  47. u_char        recv_buffer[4096];
  48. u_char        send_buffer[4096];
  49. u_char        *progname;
  50. int        sockfd;
  51. u_char        vector[AUTH_VECTOR_LEN];
  52. u_char        oldpass[AUTH_PASS_LEN];
  53.  
  54. void usage();
  55. void random_vector(u_char    *vector);
  56. void result_recv(UINT4    host,u_short    udp_port,u_char    *buffer,int    length);
  57.  
  58. int
  59. main(argc, argv)
  60. int    argc;
  61. u_char    *argv[];
  62. {
  63.     int            salen;
  64.     int            result;
  65.     struct    sockaddr    salocal;
  66.     struct    sockaddr    saremote;
  67.     struct    sockaddr_in    *sin;
  68.     struct    servent        *svp;
  69.         u_short                 svc_port;
  70.     AUTH_HDR        *auth;
  71.     u_char            *username;
  72.     u_char            newpass1[AUTH_PASS_LEN];
  73.     u_char            newpass2[AUTH_PASS_LEN];
  74.     u_char            passbuf[AUTH_PASS_LEN];
  75.     u_char            md5buf[256];
  76.     u_char            *oldvector;
  77.     UINT4            get_ipaddr();
  78.     UINT4            auth_ipaddr;
  79.     u_short            local_port;
  80.     int            total_length;
  81.     u_char            *ptr;
  82.     int            length;
  83.     int            secretlen;
  84.     int            i;
  85.     char            *getpass();
  86.  
  87.     progname = argv[0];
  88.  
  89.     if(argc != 2) {
  90.         usage();
  91.     }
  92.     /* Get the user name */
  93.     username = argv[1];
  94.  
  95.     svp = getservbyname ("radius", "udp");
  96.     if (svp == (struct servent *) 0) {
  97.         fprintf (stderr, "No such service: %s/%s\n", "radius", "udp");
  98.         exit(-1);
  99.     }
  100.     svc_port = ntohs((u_short) svp->s_port);
  101.  
  102.     /* Get the IP address of the authentication server */
  103.     if((auth_ipaddr = get_ipaddr("radius-server")) == (UINT4)0) {
  104.         fprintf(stderr, "Couldn't find host radius-server\n");
  105.         exit(-1);
  106.     }
  107.  
  108.     sockfd = socket (AF_INET, SOCK_DGRAM, 0);
  109.     if (sockfd < 0) {
  110.         (void) perror ("socket");
  111.         exit(-1);
  112.     }
  113.  
  114.     sin = (struct sockaddr_in *) & salocal;
  115.         memset ((char *) sin, '\0', sizeof (salocal));
  116.     sin->sin_family = AF_INET;
  117.     sin->sin_addr.s_addr = INADDR_ANY;
  118.  
  119.     local_port = 1025;
  120.     do {
  121.         local_port++;
  122.         sin->sin_port = htons((u_short)local_port);
  123.     } while((bind(sockfd, &salocal, sizeof (struct sockaddr_in)) < 0) &&
  124.                         local_port < 64000);
  125.     if(local_port >= 64000) {
  126.         close(sockfd);
  127.         (void) perror ("bind");
  128.         exit(-1);
  129.     }
  130.  
  131.     printf("Changing Password for user %s\n", username);
  132.  
  133.     /* Get their old password */
  134.     strcpy((char *)oldpass, getpass("Old Password:"));
  135.     if(*oldpass == '\0') {
  136.         exit(0);
  137.     }
  138.     printf("\n");
  139.     /* Get their new password */
  140.     strcpy((char *)newpass1, getpass("New Password:"));
  141.     if(*newpass1 == '\0') {
  142.         exit(0);
  143.     }
  144.     printf("\n");
  145.     /* Get their new password again */
  146.     strcpy((char *)newpass2, getpass("Re-type New Password:"));
  147.     if(strcmp(newpass1, newpass2) != 0) {
  148.         printf("New Passwords didn't match\n");
  149.         exit(-1);
  150.     }
  151.     printf("\n");
  152.     /* Build a password change request */
  153.     auth = (AUTH_HDR *)send_buffer;
  154.     auth->code = PW_PASSWORD_REQUEST;
  155.     auth->id = 0;
  156.     random_vector(vector);
  157.     memcpy(auth->vector, vector, AUTH_VECTOR_LEN);
  158.     total_length = AUTH_HDR_LEN;
  159.     ptr = auth->data;
  160.  
  161.     /* User Name */
  162.     *ptr++ = PW_USER_NAME;
  163.     length = strlen(username);
  164.     if(length > MAXPWNAM) {
  165.         length = MAXPWNAM;
  166.     }
  167.     *ptr++ = length + 2;
  168.     memcpy(ptr, username, length);
  169.     ptr += length;
  170.     total_length += length + 2;
  171.  
  172.     /* New Password */
  173.     *ptr++ = PW_PASSWORD;
  174.     *ptr++ = AUTH_PASS_LEN + 2;
  175.  
  176.     /* Encrypt the Password */
  177.     length = strlen(newpass1);
  178.     if(length > MAXPASS) {
  179.         length = MAXPASS;
  180.     }
  181.     memset(passbuf, 0, AUTH_PASS_LEN);
  182.     memcpy(passbuf, newpass1, length);
  183.     /* Calculate the MD5 Digest */
  184.     secretlen = strlen(oldpass);
  185.     strcpy(md5buf, oldpass);
  186.     memcpy(md5buf + secretlen, auth->vector, AUTH_VECTOR_LEN);
  187.     md5_calc(ptr, md5buf, secretlen + AUTH_VECTOR_LEN);
  188.     oldvector = ptr;
  189.     /* Xor the password into the MD5 digest */
  190.     for(i = 0;i < AUTH_PASS_LEN;i++) {
  191.         *ptr++ ^= passbuf[i];
  192.     }
  193.     total_length += AUTH_PASS_LEN + 2;
  194.  
  195.     /* Old Password */
  196.     *ptr++ = PW_OLD_PASSWORD;
  197.     *ptr++ = AUTH_PASS_LEN + 2;
  198.  
  199.     /* Encrypt the Password */
  200.     length = strlen(oldpass);
  201.     if(length > MAXPASS) {
  202.         length = MAXPASS;
  203.     }
  204.     memset(passbuf, 0, AUTH_PASS_LEN);
  205.     memcpy(passbuf, oldpass, length);
  206.     /* Calculate the MD5 Digest */
  207.     secretlen = strlen(oldpass);
  208.     strcpy(md5buf, oldpass);
  209.     memcpy(md5buf + secretlen, oldvector, AUTH_VECTOR_LEN);
  210.     md5_calc(ptr, md5buf, secretlen + AUTH_VECTOR_LEN);
  211.  
  212.     /* Xor the password into the MD5 digest */
  213.     for(i = 0;i < AUTH_PASS_LEN;i++) {
  214.         *ptr++ ^= passbuf[i];
  215.     }
  216.     total_length += AUTH_PASS_LEN + 2;
  217.  
  218.     auth->length = htonl(total_length);
  219.  
  220.     sin = (struct sockaddr_in *) & saremote;
  221.         memset ((char *) sin, '\0', sizeof (saremote));
  222.     sin->sin_family = AF_INET;
  223.     sin->sin_addr.s_addr = htonl(auth_ipaddr);
  224.     sin->sin_port = htons(svc_port);
  225.  
  226.     sendto(sockfd, (char *)auth, (int)total_length, (int)0,
  227.             &saremote, sizeof(struct sockaddr_in));
  228.  
  229.     salen = sizeof (saremote);
  230.     result = recvfrom (sockfd, (char *) recv_buffer,
  231.             (int) sizeof(recv_buffer),
  232.             (int) 0, & saremote, & salen);
  233.  
  234.     if(result > 0) {
  235.         result_recv(sin->sin_addr.s_addr,
  236.                     sin->sin_port, recv_buffer, result);
  237.         exit(0);
  238.     }
  239.     (void) perror ("recv");
  240.     close(sockfd);
  241.     exit(0);
  242. }
  243.  
  244. void
  245. result_recv(host, udp_port, buffer, length)
  246. UINT4    host;
  247. u_short    udp_port;
  248. u_char    *buffer;
  249. int    length;
  250. {
  251.     AUTH_HDR    *auth;
  252.     int        totallen;
  253.     char        *ip_hostname();
  254.     u_char        reply_digest[AUTH_VECTOR_LEN];
  255.     u_char        calc_digest[AUTH_VECTOR_LEN];
  256.     int        secretlen;
  257.  
  258.     auth = (AUTH_HDR *)buffer;
  259.     totallen = ntohs(auth->length);
  260.  
  261.     if(totallen != AUTH_HDR_LEN) {
  262.         printf("Received invalid reply length from server\n");
  263.         exit(-1);
  264.     }
  265.  
  266.     /* Verify the reply digest */
  267.     memcpy(reply_digest, auth->vector, AUTH_VECTOR_LEN);
  268.     memcpy(auth->vector, vector, AUTH_VECTOR_LEN);
  269.     secretlen = strlen(oldpass);
  270.     memcpy(buffer + AUTH_HDR_LEN, oldpass, secretlen);
  271.     md5_calc(calc_digest, (char *)auth, AUTH_HDR_LEN);
  272.  
  273.     if(memcmp(reply_digest, calc_digest, AUTH_VECTOR_LEN) != 0) {
  274.         printf("Warning: Received invalid reply digest from server\n");
  275.     }
  276.  
  277.     if(auth->code == PW_PASSWORD_ACK) {
  278.         printf("Password successfully changed\n");
  279.     }
  280.     else {
  281.         printf("Request Denied\n");
  282.     }
  283. }
  284. void
  285. usage()
  286. {
  287.     printf("Usage: %s username\n", progname);
  288.     exit(-1);
  289. }
  290.  
  291. void
  292. random_vector(vector)
  293. u_char    *vector;
  294. {
  295.     int    randno;
  296.     int    i;
  297.  
  298.     srand(time(0));
  299.     for(i = 0;i < AUTH_VECTOR_LEN;) {
  300.         randno = rand();
  301.         memcpy(vector, &randno, sizeof(int));
  302.         vector += sizeof(int);
  303.         i += sizeof(int);
  304.     }
  305. }
  306.