home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 April / PCO0499.ISO / filesbbs / os2 / apach134.arj / APACH134.ZIP / src / support / htdigest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-03  |  4.4 KB  |  208 lines

  1. /******************************************************************************
  2.  ******************************************************************************
  3.  * NOTE! This program is not safe as a setuid executable!  Do not make it
  4.  * setuid!
  5.  ******************************************************************************
  6.  *****************************************************************************/
  7. /*
  8.  * htdigest.c: simple program for manipulating digest passwd file for Apache
  9.  *
  10.  * by Alexei Kosut, based on htpasswd.c, by Rob McCool
  11.  */
  12.  
  13. #include "ap_config.h"
  14. #include <sys/types.h>
  15. #ifdef MPE
  16. #include <signal.h>
  17. #else
  18. #include <sys/signal.h>
  19. #endif
  20.  
  21. /* This is probably the easiest way to do it */
  22. #include "../main/md5c.c"
  23.  
  24. #define LF 10
  25. #define CR 13
  26.  
  27. #define MAX_STRING_LEN 256
  28.  
  29. char *tn;
  30.  
  31. static char *strd(char *s)
  32. {
  33.     char *d;
  34.  
  35.     d = (char *) malloc(strlen(s) + 1);
  36.     strcpy(d, s);
  37.     return (d);
  38. }
  39.  
  40. static void getword(char *word, char *line, char stop)
  41. {
  42.     int x = 0, y;
  43.  
  44.     for (x = 0; ((line[x]) && (line[x] != stop)); x++)
  45.     word[x] = line[x];
  46.  
  47.     word[x] = '\0';
  48.     if (line[x])
  49.     ++x;
  50.     y = 0;
  51.  
  52.     while ((line[y++] = line[x++]));
  53. }
  54.  
  55. static int getline(char *s, int n, FILE *f)
  56. {
  57.     register int i = 0;
  58.  
  59.     while (1) {
  60.     s[i] = (char) fgetc(f);
  61.  
  62.     if (s[i] == CR)
  63.         s[i] = fgetc(f);
  64.  
  65.     if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) {
  66.         s[i] = '\0';
  67.         return (feof(f) ? 1 : 0);
  68.     }
  69.     ++i;
  70.     }
  71. }
  72.  
  73. static void putline(FILE *f, char *l)
  74. {
  75.     int x;
  76.  
  77.     for (x = 0; l[x]; x++)
  78.     fputc(l[x], f);
  79.     fputc('\n', f);
  80. }
  81.  
  82.  
  83. static void add_password(char *user, char *realm, FILE *f)
  84. {
  85.     char *pw;
  86.     AP_MD5_CTX context;
  87.     unsigned char digest[16];
  88.     char string[MAX_STRING_LEN];
  89.     unsigned int i;
  90.  
  91.     pw = strd((char *) getpass("New password:"));
  92.     if (strcmp(pw, (char *) getpass("Re-type new password:"))) {
  93.     fprintf(stderr, "They don't match, sorry.\n");
  94.     if (tn)
  95.         unlink(tn);
  96.     exit(1);
  97.     }
  98.     fprintf(f, "%s:%s:", user, realm);
  99.  
  100.     /* Do MD5 stuff */
  101.     sprintf(string, "%s:%s:%s", user, realm, pw);
  102.  
  103.     ap_MD5Init(&context);
  104.     ap_MD5Update(&context, (unsigned char *) string, strlen(string));
  105.     ap_MD5Final(digest, &context);
  106.  
  107.     for (i = 0; i < 16; i++)
  108.     fprintf(f, "%02x", digest[i]);
  109.  
  110.     fprintf(f, "\n");
  111. }
  112.  
  113. static void usage(void)
  114. {
  115.     fprintf(stderr, "Usage: htdigest [-c] passwordfile realm username\n");
  116.     fprintf(stderr, "The -c flag creates a new file.\n");
  117.     exit(1);
  118. }
  119.  
  120. static void interrupted(void)
  121. {
  122.     fprintf(stderr, "Interrupted.\n");
  123.     if (tn)
  124.     unlink(tn);
  125.     exit(1);
  126. }
  127.  
  128. int main(int argc, char *argv[])
  129. {
  130.     FILE *tfp, *f;
  131.     char user[MAX_STRING_LEN];
  132.     char realm[MAX_STRING_LEN];
  133.     char line[MAX_STRING_LEN];
  134.     char l[MAX_STRING_LEN];
  135.     char w[MAX_STRING_LEN];
  136.     char x[MAX_STRING_LEN];
  137.     char command[MAX_STRING_LEN];
  138.     int found;
  139.  
  140.     tn = NULL;
  141.     signal(SIGINT, (void (*)()) interrupted);
  142.     if (argc == 5) {
  143.     if (strcmp(argv[1], "-c"))
  144.         usage();
  145.     if (!(tfp = fopen(argv[2], "w"))) {
  146.         fprintf(stderr, "Could not open passwd file %s for writing.\n",
  147.             argv[2]);
  148.         perror("fopen");
  149.         exit(1);
  150.     }
  151.     printf("Adding password for %s in realm %s.\n", argv[4], argv[3]);
  152.     add_password(argv[4], argv[3], tfp);
  153.     fclose(tfp);
  154.     exit(0);
  155.     }
  156.     else if (argc != 4)
  157.     usage();
  158.  
  159.     tn = tmpnam(NULL);
  160.     if (!(tfp = fopen(tn, "w"))) {
  161.     fprintf(stderr, "Could not open temp file.\n");
  162.     exit(1);
  163.     }
  164.  
  165.     if (!(f = fopen(argv[1], "r"))) {
  166.     fprintf(stderr,
  167.         "Could not open passwd file %s for reading.\n", argv[1]);
  168.     fprintf(stderr, "Use -c option to create new one.\n");
  169.     exit(1);
  170.     }
  171.     strcpy(user, argv[3]);
  172.     strcpy(realm, argv[2]);
  173.  
  174.     found = 0;
  175.     while (!(getline(line, MAX_STRING_LEN, f))) {
  176.     if (found || (line[0] == '#') || (!line[0])) {
  177.         putline(tfp, line);
  178.         continue;
  179.     }
  180.     strcpy(l, line);
  181.     getword(w, l, ':');
  182.     getword(x, l, ':');
  183.     if (strcmp(user, w) || strcmp(realm, x)) {
  184.         putline(tfp, line);
  185.         continue;
  186.     }
  187.     else {
  188.         printf("Changing password for user %s in realm %s\n", user, realm);
  189.         add_password(user, realm, tfp);
  190.         found = 1;
  191.     }
  192.     }
  193.     if (!found) {
  194.     printf("Adding user %s in realm %s\n", user, realm);
  195.     add_password(user, realm, tfp);
  196.     }
  197.     fclose(f);
  198.     fclose(tfp);
  199. #if defined(OS2) || defined(WIN32)
  200.     sprintf(command, "copy \"%s\" \"%s\"", tn, argv[1]);
  201. #else
  202.     sprintf(command, "cp %s %s", tn, argv[1]);
  203. #endif
  204.     system(command);
  205.     unlink(tn);
  206.     exit(0);
  207. }
  208.