Root/package/network/services/ead/src/tinysrp/tphrase.c

1/* Add passphrases to the tpasswd file. Use the last entry in the config
2file by default or a particular one specified by index. */
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <unistd.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include "config.h"
11#include "t_pwd.h"
12#include "t_read.h"
13#include "t_sha.h"
14#include "t_defines.h"
15
16char *Progname;
17char Usage[] = "usage: %s [-n configindex] [-p passfile] user\n";
18#define USAGE() fprintf(stderr, Usage, Progname)
19
20void doit(char *);
21
22int Configindex = -1;
23char *Passfile = DEFAULT_PASSWD;
24
25int main(int argc, char **argv)
26{
27    int c;
28
29    Progname = *argv;
30
31    /* Parse option arguments. */
32
33    while ((c = getopt(argc, argv, "n:p:")) != EOF) {
34        switch (c) {
35
36        case 'n':
37            Configindex = atoi(optarg);
38            break;
39
40        case 'p':
41            Passfile = optarg;
42            break;
43
44        default:
45            USAGE();
46            exit(1);
47        }
48    }
49    argc -= optind;
50    argv += optind;
51
52    if (argc != 1) {
53        USAGE();
54        exit(1);
55    }
56    doit(argv[0]);
57
58    return 0;
59}
60
61void doit(char *name)
62{
63    char passphrase[128], passphrase1[128];
64    FILE *f;
65    struct t_conf *tc;
66    struct t_confent *tcent;
67    struct t_pw eps_passwd;
68
69    /* Get the config entry. */
70
71    if (Configindex <= 0) {
72        Configindex = t_getprecount();
73    }
74    tcent = gettcid(Configindex);
75    if (tcent == NULL) {
76        fprintf(stderr, "Invalid configuration file entry.\n");
77        exit(1);
78    }
79
80    /* Ask for the passphrase twice. */
81
82    printf("Setting passphrase for %s\n", name);
83
84    if (t_getpass(passphrase, sizeof(passphrase), "Enter passphrase: ") < 0) {
85        exit(1);
86    }
87    if (t_getpass(passphrase1, sizeof(passphrase1), "Verify: ") < 0) {
88        exit(1);
89    }
90    if (strcmp(passphrase, passphrase1) != 0) {
91        fprintf(stderr, "mismatch\n");
92        exit(1);
93    }
94
95    /* Create the passphrase verifier. */
96
97    t_makepwent(&eps_passwd, name, passphrase, NULL, tcent);
98
99    /* Don't need these anymore. */
100
101    memset(passphrase, 0, sizeof(passphrase));
102    memset(passphrase1, 0, sizeof(passphrase1));
103
104    /* See if the passphrase file is there; create it if not. */
105
106    if ((f = fopen(Passfile, "r+")) == NULL) {
107        creat(Passfile, 0400);
108    } else {
109        fclose(f);
110    }
111
112    /* Change the passphrase. */
113
114    if (t_changepw(Passfile, &eps_passwd.pebuf) < 0) {
115        fprintf(stderr, "Error changing passphrase\n");
116        exit(1);
117    }
118}
119
120/* TODO: Implement a more general method to handle delete/change */
121
122_TYPE( int )
123t_changepw(pwname, diff)
124     const char * pwname;
125     const struct t_pwent * diff;
126{
127  char * bakfile;
128  char * bakfile2;
129  struct stat st;
130  FILE * passfp;
131  FILE * bakfp;
132
133  if(pwname == NULL)
134    pwname = DEFAULT_PASSWD;
135
136  if((passfp = fopen(pwname, "rb")) == NULL || fstat(fileno(passfp), &st) < 0)
137    return -1;
138
139  if((bakfile = malloc(strlen(pwname) + 5)) == NULL) {
140    fclose(passfp);
141    return -1;
142  }
143  else if((bakfile2 = malloc(strlen(pwname) + 5)) == NULL) {
144    fclose(passfp);
145    free(bakfile);
146    return -1;
147  }
148
149  sprintf(bakfile, "%s.bak", pwname);
150  sprintf(bakfile2, "%s.sav", pwname);
151
152  if((bakfp = fopen(bakfile2, "wb")) == NULL &&
153     (unlink(bakfile2) < 0 || (bakfp = fopen(bakfile2, "wb")) == NULL)) {
154    fclose(passfp);
155    fclose(bakfp);
156    return -1;
157  }
158
159#ifdef NO_FCHMOD
160  chmod(bakfile2, st.st_mode & 0777);
161#else
162  fchmod(fileno(bakfp), st.st_mode & 0777);
163#endif
164
165  t_pwcopy(bakfp, passfp, diff);
166
167  fclose(bakfp);
168  fclose(passfp);
169
170#ifdef USE_RENAME
171  unlink(bakfile);
172  if(rename(pwname, bakfile) < 0)
173    return -1;
174  if(rename(bakfile2, pwname) < 0)
175    return -1;
176#else
177  unlink(bakfile);
178  link(pwname, bakfile);
179  unlink(pwname);
180  link(bakfile2, pwname);
181  unlink(bakfile2);
182#endif
183  free(bakfile);
184  free(bakfile2);
185
186  return 0;
187}
188
189_TYPE( struct t_pwent * )
190t_makepwent(tpw, user, pass, salt, confent)
191     struct t_pw * tpw;
192     const char * user;
193     const char * pass;
194     const struct t_num * salt;
195     const struct t_confent * confent;
196{
197  BigInteger x, v, n, g;
198  unsigned char dig[SHA_DIGESTSIZE];
199  SHA1_CTX ctxt;
200
201  tpw->pebuf.name = tpw->userbuf;
202  tpw->pebuf.password.data = tpw->pwbuf;
203  tpw->pebuf.salt.data = tpw->saltbuf;
204
205  strncpy(tpw->pebuf.name, user, MAXUSERLEN);
206  tpw->pebuf.index = confent->index;
207
208  if(salt) {
209    tpw->pebuf.salt.len = salt->len;
210    memcpy(tpw->pebuf.salt.data, salt->data, salt->len);
211  }
212  else {
213    memset(dig, 0, SALTLEN); /* salt is 80 bits */
214    tpw->pebuf.salt.len = SALTLEN;
215    do {
216      t_random(tpw->pebuf.salt.data, SALTLEN);
217    } while(memcmp(tpw->pebuf.salt.data, dig, SALTLEN) == 0);
218    if(tpw->pebuf.salt.data[0] == 0)
219      tpw->pebuf.salt.data[0] = 0xff;
220  }
221
222  n = BigIntegerFromBytes(confent->modulus.data, confent->modulus.len);
223  g = BigIntegerFromBytes(confent->generator.data, confent->generator.len);
224  v = BigIntegerFromInt(0);
225
226  SHA1Init(&ctxt);
227  SHA1Update(&ctxt, user, strlen(user));
228  SHA1Update(&ctxt, ":", 1);
229  SHA1Update(&ctxt, pass, strlen(pass));
230  SHA1Final(dig, &ctxt);
231
232  SHA1Init(&ctxt);
233  SHA1Update(&ctxt, tpw->pebuf.salt.data, tpw->pebuf.salt.len);
234  SHA1Update(&ctxt, dig, sizeof(dig));
235  SHA1Final(dig, &ctxt);
236
237  /* x = H(s, H(u, ':', p)) */
238  x = BigIntegerFromBytes(dig, sizeof(dig));
239
240  BigIntegerModExp(v, g, x, n);
241  tpw->pebuf.password.len = BigIntegerToBytes(v, tpw->pebuf.password.data);
242
243  BigIntegerFree(v);
244  BigIntegerFree(x);
245  BigIntegerFree(g);
246  BigIntegerFree(n);
247
248  return &tpw->pebuf;
249}
250
251int
252t_pwcopy(pwdest, pwsrc, diff)
253     FILE * pwdest;
254     FILE * pwsrc;
255     struct t_pwent * diff;
256{
257  struct t_pw * src;
258  struct t_pwent * ent;
259
260  if((src = t_openpw(pwsrc)) == NULL)
261    return -1;
262
263  while((ent = t_getpwent(src)) != NULL)
264    if(diff && strcmp(diff->name, ent->name) == 0) {
265      t_putpwent(diff, pwdest);
266      diff = NULL;
267    }
268    else
269      t_putpwent(ent, pwdest);
270
271  if(diff)
272    t_putpwent(diff, pwdest);
273
274  return 0;
275}
276
277_TYPE( struct t_pwent * )
278t_getpwent(tpw)
279     struct t_pw * tpw;
280{
281  char indexbuf[16];
282  char passbuf[MAXB64PARAMLEN];
283  char saltstr[MAXB64SALTLEN];
284
285#ifdef ENABLE_YP
286  struct t_passwd * nisent;
287  /* FIXME: should tell caller to get conf entry from NIS also */
288
289  if(tpw->state == IN_NIS) {
290    nisent = _yp_gettpent();
291    if(nisent != NULL) {
292      savepwent(tpw, &nisent->tp);
293      return &tpw->pebuf;
294    }
295    tpw->state = FILE_NIS;
296  }
297#endif
298
299  while(1) {
300    if(t_nextfield(tpw->instream, tpw->userbuf, MAXUSERLEN) > 0) {
301#ifdef ENABLE_YP
302      if(tpw->state == FILE_NIS && *tpw->userbuf == '+') {
303    t_nextline(tpw->instream);
304    if(strlen(tpw->userbuf) > 1) { /* +name:... */
305      nisent = _yp_gettpnam(tpw->userbuf + 1);
306      if(nisent != NULL) {
307        savepwent(tpw, nisent);
308        return &tpw->pebuf;
309      }
310    }
311    else { /* +:... */
312      tpw->state = IN_NIS;
313      _yp_settpent();
314      return t_getpwent(tpw);
315    }
316      }
317#endif
318      if(t_nextfield(tpw->instream, passbuf, MAXB64PARAMLEN) > 0 &&
319     (tpw->pebuf.password.len = t_fromb64(tpw->pwbuf, passbuf)) > 0 &&
320     t_nextfield(tpw->instream, saltstr, MAXB64SALTLEN) > 0 &&
321     (tpw->pebuf.salt.len = t_fromb64(tpw->saltbuf, saltstr)) > 0 &&
322     t_nextfield(tpw->instream, indexbuf, 16) > 0 &&
323     (tpw->pebuf.index = atoi(indexbuf)) > 0) {
324    tpw->pebuf.name = tpw->userbuf;
325    tpw->pebuf.password.data = tpw->pwbuf;
326    tpw->pebuf.salt.data = tpw->saltbuf;
327    t_nextline(tpw->instream);
328    return &tpw->pebuf;
329      }
330    }
331    if(t_nextline(tpw->instream) < 0)
332      return NULL;
333  }
334}
335
336_TYPE( void )
337t_putpwent(ent, fp)
338     const struct t_pwent * ent;
339     FILE * fp;
340{
341  char strbuf[MAXB64PARAMLEN];
342  char saltbuf[MAXB64SALTLEN];
343
344  fprintf(fp, "%s:%s:%s:%d\n", ent->name,
345      t_tob64(strbuf, ent->password.data, ent->password.len),
346      t_tob64(saltbuf, ent->salt.data, ent->salt.len), ent->index);
347}
348
349

Archive Download this file



interactive