1 /* Add passphrases to the tpasswd file. Use the last entry in the config
2 file by default or a particular one specified by index. */
14 #include "t_defines.h"
17 char Usage
[] = "usage: %s [-n configindex] [-p passfile] user\n";
18 #define USAGE() fprintf(stderr, Usage, Progname)
23 char *Passfile
= DEFAULT_PASSWD
;
25 int main(int argc
, char **argv
)
31 /* Parse option arguments. */
33 while ((c
= getopt(argc
, argv
, "n:p:")) != EOF
) {
37 Configindex
= atoi(optarg
);
63 char passphrase
[128], passphrase1
[128];
66 struct t_confent
*tcent
;
67 struct t_pw eps_passwd
;
69 /* Get the config entry. */
71 if (Configindex
<= 0) {
72 Configindex
= t_getprecount();
74 tcent
= gettcid(Configindex
);
76 fprintf(stderr
, "Invalid configuration file entry.\n");
80 /* Ask for the passphrase twice. */
82 printf("Setting passphrase for %s\n", name
);
84 if (t_getpass(passphrase
, sizeof(passphrase
), "Enter passphrase: ") < 0) {
87 if (t_getpass(passphrase1
, sizeof(passphrase1
), "Verify: ") < 0) {
90 if (strcmp(passphrase
, passphrase1
) != 0) {
91 fprintf(stderr
, "mismatch\n");
95 /* Create the passphrase verifier. */
97 t_makepwent(&eps_passwd
, name
, passphrase
, NULL
, tcent
);
99 /* Don't need these anymore. */
101 memset(passphrase
, 0, sizeof(passphrase
));
102 memset(passphrase1
, 0, sizeof(passphrase1
));
104 /* See if the passphrase file is there; create it if not. */
106 if ((f
= fopen(Passfile
, "r+")) == NULL
) {
107 creat(Passfile
, 0400);
112 /* Change the passphrase. */
114 if (t_changepw(Passfile
, &eps_passwd
.pebuf
) < 0) {
115 fprintf(stderr
, "Error changing passphrase\n");
120 /* TODO: Implement a more general method to handle delete/change */
123 t_changepw(pwname
, diff
)
125 const struct t_pwent
* diff
;
134 pwname
= DEFAULT_PASSWD
;
136 if((passfp
= fopen(pwname
, "rb")) == NULL
|| fstat(fileno(passfp
), &st
) < 0)
139 if((bakfile
= malloc(strlen(pwname
) + 5)) == NULL
) {
143 else if((bakfile2
= malloc(strlen(pwname
) + 5)) == NULL
) {
149 sprintf(bakfile
, "%s.bak", pwname
);
150 sprintf(bakfile2
, "%s.sav", pwname
);
152 if((bakfp
= fopen(bakfile2
, "wb")) == NULL
&&
153 (unlink(bakfile2
) < 0 || (bakfp
= fopen(bakfile2
, "wb")) == NULL
)) {
160 chmod(bakfile2
, st
.st_mode
& 0777);
162 fchmod(fileno(bakfp
), st
.st_mode
& 0777);
165 t_pwcopy(bakfp
, passfp
, diff
);
172 if(rename(pwname
, bakfile
) < 0)
174 if(rename(bakfile2
, pwname
) < 0)
178 link(pwname
, bakfile
);
180 link(bakfile2
, pwname
);
189 _TYPE( struct t_pwent
* )
190 t_makepwent(tpw
, user
, pass
, salt
, confent
)
194 const struct t_num
* salt
;
195 const struct t_confent
* confent
;
197 BigInteger x
, v
, n
, g
;
198 unsigned char dig
[SHA_DIGESTSIZE
];
201 tpw
->pebuf
.name
= tpw
->userbuf
;
202 tpw
->pebuf
.password
.data
= tpw
->pwbuf
;
203 tpw
->pebuf
.salt
.data
= tpw
->saltbuf
;
205 strncpy(tpw
->pebuf
.name
, user
, MAXUSERLEN
);
206 tpw
->pebuf
.index
= confent
->index
;
209 tpw
->pebuf
.salt
.len
= salt
->len
;
210 memcpy(tpw
->pebuf
.salt
.data
, salt
->data
, salt
->len
);
213 memset(dig
, 0, SALTLEN
); /* salt is 80 bits */
214 tpw
->pebuf
.salt
.len
= SALTLEN
;
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;
222 n
= BigIntegerFromBytes(confent
->modulus
.data
, confent
->modulus
.len
);
223 g
= BigIntegerFromBytes(confent
->generator
.data
, confent
->generator
.len
);
224 v
= BigIntegerFromInt(0);
227 SHA1Update(&ctxt
, user
, strlen(user
));
228 SHA1Update(&ctxt
, ":", 1);
229 SHA1Update(&ctxt
, pass
, strlen(pass
));
230 SHA1Final(dig
, &ctxt
);
233 SHA1Update(&ctxt
, tpw
->pebuf
.salt
.data
, tpw
->pebuf
.salt
.len
);
234 SHA1Update(&ctxt
, dig
, sizeof(dig
));
235 SHA1Final(dig
, &ctxt
);
237 /* x = H(s, H(u, ':', p)) */
238 x
= BigIntegerFromBytes(dig
, sizeof(dig
));
240 BigIntegerModExp(v
, g
, x
, n
);
241 tpw
->pebuf
.password
.len
= BigIntegerToBytes(v
, tpw
->pebuf
.password
.data
);
252 t_pwcopy(pwdest
, pwsrc
, diff
)
255 struct t_pwent
* diff
;
258 struct t_pwent
* ent
;
260 if((src
= t_openpw(pwsrc
)) == NULL
)
263 while((ent
= t_getpwent(src
)) != NULL
)
264 if(diff
&& strcmp(diff
->name
, ent
->name
) == 0) {
265 t_putpwent(diff
, pwdest
);
269 t_putpwent(ent
, pwdest
);
272 t_putpwent(diff
, pwdest
);
277 _TYPE( struct t_pwent
* )
282 char passbuf
[MAXB64PARAMLEN
];
283 char saltstr
[MAXB64SALTLEN
];
286 struct t_passwd
* nisent
;
287 /* FIXME: should tell caller to get conf entry from NIS also */
289 if(tpw
->state
== IN_NIS
) {
290 nisent
= _yp_gettpent();
292 savepwent(tpw
, &nisent
->tp
);
295 tpw
->state
= FILE_NIS
;
300 if(t_nextfield(tpw
->instream
, tpw
->userbuf
, MAXUSERLEN
) > 0) {
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);
307 savepwent(tpw
, nisent
);
314 return t_getpwent(tpw
);
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
);
331 if(t_nextline(tpw
->instream
) < 0)
338 const struct t_pwent
* ent
;
341 char strbuf
[MAXB64PARAMLEN
];
342 char saltbuf
[MAXB64SALTLEN
];
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
);
This page took 0.057867 seconds and 5 git commands to generate.