ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/thttpd/extras/htpasswd.c
Revision: 1.1
Committed: Mon Jun 18 21:11:58 2001 UTC (25 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: mp_j, dp_j, cp_j, HEAD
Branch point for: connpatch, dirpatch, mmapppatch
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*
2     * htpasswd.c: simple program for manipulating password file for NCSA httpd
3     *
4     * Rob McCool
5     */
6    
7     /* Modified 29aug97 by Jef Poskanzer to accept new password on stdin,
8     ** if stdin is a pipe or file. This is necessary for use from CGI.
9     */
10    
11     #include <sys/types.h>
12     #include <stdio.h>
13     #include <string.h>
14     #include <signal.h>
15     #include <stdlib.h>
16     #include <time.h>
17     #include <unistd.h>
18    
19     extern char *crypt(const char *key, const char *setting);
20    
21     #define LF 10
22     #define CR 13
23    
24     #define MAX_STRING_LEN 256
25    
26     char *tn;
27    
28     void interrupted(int);
29    
30     static char * strd(char *s) {
31     char *d;
32    
33     d=(char *)malloc(strlen(s) + 1);
34     strcpy(d,s);
35     return(d);
36     }
37    
38     static void getword(char *word, char *line, char stop) {
39     int x = 0,y;
40    
41     for(x=0;((line[x]) && (line[x] != stop));x++)
42     word[x] = line[x];
43    
44     word[x] = '\0';
45     if(line[x]) ++x;
46     y=0;
47    
48     while((line[y++] = line[x++]));
49     }
50    
51     static int getline(char *s, int n, FILE *f) {
52     register int i=0;
53    
54     while(1) {
55     s[i] = (char)fgetc(f);
56    
57     if(s[i] == CR)
58     s[i] = fgetc(f);
59    
60     if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
61     s[i] = '\0';
62     return (feof(f) ? 1 : 0);
63     }
64     ++i;
65     }
66     }
67    
68     static void putline(FILE *f,char *l) {
69     int x;
70    
71     for(x=0;l[x];x++) fputc(l[x],f);
72     fputc('\n',f);
73     }
74    
75    
76     /* From local_passwd.c (C) Regents of Univ. of California blah blah */
77     static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
78     "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
79    
80     static void to64(register char *s, register long v, register int n) {
81     while (--n >= 0) {
82     *s++ = itoa64[v&0x3f];
83     v >>= 6;
84     }
85     }
86    
87     #ifdef MPE
88     /* MPE lacks getpass() and a way to suppress stdin echo. So for now, just
89     issue the prompt and read the results with echo. (Ugh). */
90    
91     char *getpass(const char *prompt) {
92    
93     static char password[81];
94    
95     fputs(prompt,stderr);
96     gets((char *)&password);
97    
98     if (strlen((char *)&password) > 8) {
99     password[8]='\0';
100     }
101    
102     return (char *)&password;
103     }
104     #endif
105    
106     static void
107     add_password( char* user, FILE* f )
108     {
109     char pass[100];
110     char* pw;
111     char* cpw;
112     char salt[3];
113    
114     if ( ! isatty( fileno( stdin ) ) )
115     {
116     (void) fgets( pass, sizeof(pass), stdin );
117     if ( pass[strlen(pass) - 1] == '\n' )
118     pass[strlen(pass) - 1] = '\0';
119     pw = pass;
120     }
121     else
122     {
123     pw = strd( (char*) getpass( "New password:" ) );
124     if ( strcmp( pw, (char*) getpass( "Re-type new password:" ) ) != 0 )
125     {
126     (void) fprintf( stderr, "They don't match, sorry.\n" );
127     if ( tn )
128     unlink( tn );
129     exit( 1 );
130     }
131     }
132     (void) srandom( (int) time( (time_t*) 0 ) );
133     to64( &salt[0], random(), 2 );
134     cpw = crypt( pw, salt );
135     (void) fprintf( f, "%s:%s\n", user, cpw );
136     }
137    
138     static void usage(void) {
139     fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n");
140     fprintf(stderr,"The -c flag creates a new file.\n");
141     exit(1);
142     }
143    
144     void interrupted(int signo) {
145     fprintf(stderr,"Interrupted.\n");
146     if(tn) unlink(tn);
147     exit(1);
148     }
149    
150     int main(int argc, char *argv[]) {
151     FILE *tfp,*f;
152     char user[MAX_STRING_LEN];
153     char line[MAX_STRING_LEN];
154     char l[MAX_STRING_LEN];
155     char w[MAX_STRING_LEN];
156     char command[MAX_STRING_LEN];
157     int found;
158    
159     tn = NULL;
160     signal(SIGINT,(void (*)(int))interrupted);
161     if(argc == 4) {
162     if(strcmp(argv[1],"-c"))
163     usage();
164     if(!(tfp = fopen(argv[2],"w"))) {
165     fprintf(stderr,"Could not open passwd file %s for writing.\n",
166     argv[2]);
167     perror("fopen");
168     exit(1);
169     }
170     printf("Adding password for %s.\n",argv[3]);
171     add_password(argv[3],tfp);
172     fclose(tfp);
173     exit(0);
174     } else if(argc != 3) usage();
175    
176     tn = tmpnam(NULL);
177     if(!(tfp = fopen(tn,"w"))) {
178     fprintf(stderr,"Could not open temp file.\n");
179     exit(1);
180     }
181    
182     if(!(f = fopen(argv[1],"r"))) {
183     fprintf(stderr,
184     "Could not open passwd file %s for reading.\n",argv[1]);
185     fprintf(stderr,"Use -c option to create new one.\n");
186     exit(1);
187     }
188     strcpy(user,argv[2]);
189    
190     found = 0;
191     while(!(getline(line,MAX_STRING_LEN,f))) {
192     if(found || (line[0] == '#') || (!line[0])) {
193     putline(tfp,line);
194     continue;
195     }
196     strcpy(l,line);
197     getword(w,l,':');
198     if(strcmp(user,w)) {
199     putline(tfp,line);
200     continue;
201     }
202     else {
203     printf("Changing password for user %s\n",user);
204     add_password(user,tfp);
205     found = 1;
206     }
207     }
208     if(!found) {
209     printf("Adding user %s\n",user);
210     add_password(user,tfp);
211     }
212     fclose(f);
213     fclose(tfp);
214     sprintf(command,"cp %s %s",tn,argv[1]);
215     system(command);
216     unlink(tn);
217     exit(0);
218     }