Add missing va_end(ap);
[dragonfly.git] / usr.bin / keyinit / skeyinit.c
1 /*   change password or add user to S/KEY authentication system.
2  *   S/KEY is a tradmark of Bellcore.
3  *
4  *   $DragonFly: src/usr.bin/keyinit/skeyinit.c,v 1.2 2003/10/04 20:36:46 hmp Exp $
5  */
6
7 #include <ctype.h>
8 #include <err.h>
9 #include <pwd.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14
15 #include <skey.h>
16 #include <unistd.h>
17
18 #define NAMELEN 2
19
20 int
21 main(int argc, char **argv)
22 {
23         struct skey skey;
24         int rval,n,nn,i,defaultsetup;
25         char seed[18],tmp[80],key[8];
26         struct passwd *ppuser,*pp;
27         char defaultseed[17], passwd[256],passwd2[256] ;
28
29
30         time_t now;
31         struct tm *tm;
32         char tbuf[27],buf[60];
33         char lastc, me[80];
34         int l;
35
36         time(&now);
37 #if 0   /* Choose a more random seed */
38         tm = localtime(&now);
39         strftime(tbuf, sizeof(tbuf), "%M%j", tm);
40 #else
41         sprintf(tbuf, "%05ld", (long) (now % 100000));
42 #endif
43         gethostname(defaultseed,NAMELEN);
44         strcpy(&defaultseed[NAMELEN],tbuf);
45
46         pp = ppuser = getpwuid(getuid());
47         strcpy(me,pp->pw_name);
48         defaultsetup = 1;
49         if( argc > 1){
50                 if(strcmp("-s", argv[1]) == 0)
51                         defaultsetup = 0;
52                 else
53                         pp = getpwnam(argv[1]);
54                 if(argc > 2)
55                         pp = getpwnam(argv[2]);
56
57         }
58         if(pp == NULL){
59                 printf("User unknown\n");
60                 return 1;
61         }
62         if(strcmp( pp->pw_name,me) != 0){
63                 if(getuid() != 0){
64                         /* Only root can change other's passwds */
65                         printf("Permission denied.\n");
66                         return(1);
67                 }
68         }
69
70
71
72         rval = skeylookup(&skey,pp->pw_name);
73         switch(rval){
74         case -1:
75                 perror("error in opening database");
76                 return 1;
77         case 0:
78                 printf("Updating %s:\n",pp->pw_name);
79                 printf("Old key: %s\n",skey.seed);
80                 /* lets be nice if they have a skey.seed that ends in 0-8 just add one*/
81                 l = strlen(skey.seed);
82                 if( l > 0){
83                         lastc = skey.seed[l-1];
84                         if( isdigit(lastc) && lastc != '9' ){
85                                 strcpy(defaultseed, skey.seed);
86                                 defaultseed[l-1] = lastc + 1;
87                         }
88                         if( isdigit(lastc) && lastc == '9' && l < 16){
89                                 strcpy(defaultseed, skey.seed);
90                                 defaultseed[l-1] = '0';
91                                 defaultseed[l] = '0';
92                                 defaultseed[l+1] = '\0';
93                         }
94                 }
95                 break;
96         case 1:
97                 skey.val = 0;   /* XXX */
98                 printf("Adding %s:\n",pp->pw_name);
99                 break;
100         }
101     n = 99;
102     if( ! defaultsetup){
103         printf("Reminder you need the 6 english words from the key command.\n");
104         for(i=0;;i++){
105                 if(i >= 2) exit(1);
106                 printf("Enter sequence count from 1 to 9999: ");
107                 fgets(tmp,sizeof(tmp),stdin);
108                 n = atoi(tmp);
109                 if(n > 0 && n < 10000)
110                         break;  /* Valid range */
111                 printf("Count must be > 0 and < 10000\n");
112         }
113     }
114     if( !defaultsetup){
115         printf("Enter new key [default %s]: ", defaultseed);
116         fflush(stdout);
117         fgets(seed,sizeof(seed),stdin);
118         rip(seed);
119         if(strlen(seed) > 16){
120                 printf("Seed truncated to 16 chars\n");
121                 seed[16] = '\0';
122         }
123         if( seed[0] == '\0') strcpy(seed,defaultseed);
124         for(i=0;;i++){
125                 if(i >= 2) exit(1);
126                 printf("s/key %d %s\ns/key access password: ",n,seed);
127                 fgets(tmp,sizeof(tmp),stdin);
128                 rip(tmp);
129                 if(tmp[0] == '?'){
130                         printf("Enter 6 English words from secure S/Key calculation.\n");
131                         continue;
132                 }
133                 if(tmp[0] == '\0'){
134                         exit(1);
135                 }
136                 if(etob(key,tmp) == 1 || atob8(key,tmp) == 0)
137                         break;  /* Valid format */
138                 printf("Invalid format, try again with 6 English words.\n");
139         }
140     } else {
141         /* Get user's secret password */
142         fprintf(stderr,"Reminder - Only use this method if you are directly connected.\n");
143         fprintf(stderr,"If you are using telnet or rlogin exit with no password and use keyinit -s.\n");
144         for(i=0;;i++){
145                 if(i >= 2) exit(1);
146                 fprintf(stderr,"Enter secret password: ");
147                 readpass(passwd,sizeof(passwd));
148                 if(passwd[0] == '\0'){
149                         exit(1);
150                 }
151                 fprintf(stderr,"Again secret password: ");
152                 readpass(passwd2,sizeof(passwd));
153                 if(passwd2[0] == '\0'){
154                         exit(1);
155                 }
156                 if(strlen(passwd) < 4 && strlen(passwd2) < 4) {
157                         fprintf(stderr, "Sorry your password must be longer\n\r");
158                         exit(1);
159                 }
160                 if(strcmp(passwd,passwd2) == 0) break;
161                 fprintf(stderr, "Sorry no match\n");
162
163
164         }
165         strcpy(seed,defaultseed);
166
167         /* Crunch seed and password into starting key */
168         if(keycrunch(key,seed,passwd) != 0)
169                 errx(1, "key crunch failed");
170         nn = n;
171         while(nn-- != 0)
172                 f(key);
173     }
174         time(&now);
175         tm = localtime(&now);
176         strftime(tbuf, sizeof(tbuf), " %b %d,%Y %T", tm);
177         if (skey.val == NULL)
178                   skey.val = (char *) malloc(16+1);
179
180
181         btoa8(skey.val,key);
182         fprintf(skey.keyfile,"%s %04d %-16s %s %-21s\n",pp->pw_name,n,
183                 seed,skey.val, tbuf);
184         fclose(skey.keyfile);
185         printf("\nID %s s/key is %d %s\n",pp->pw_name,n,seed);
186         printf("%s\n",btoe(buf,key));
187 #ifdef HEXIN
188         printf("%s\n",put8(buf,key));
189 #endif
190         return 0;
191 }