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