diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-08-21 02:43:31 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-08-21 02:43:31 +0200 |
commit | 63b18e79252845d09abbad44672eabd9233a911b (patch) | |
tree | a71e5f93e01bf695bca43cc148ebf9a2c9a738c7 /sys/src/cmd/auth | |
parent | e48a5832b26f817ab06db2d42f88288373b78fac (diff) |
introduce AES key into nvram and keyfs
Diffstat (limited to 'sys/src/cmd/auth')
-rw-r--r-- | sys/src/cmd/auth/convkeys.c | 161 | ||||
-rw-r--r-- | sys/src/cmd/auth/keyfs.c | 321 | ||||
-rw-r--r-- | sys/src/cmd/auth/lib/getauthkey.c | 7 | ||||
-rw-r--r-- | sys/src/cmd/auth/lib/readln.c | 5 |
4 files changed, 284 insertions, 210 deletions
diff --git a/sys/src/cmd/auth/convkeys.c b/sys/src/cmd/auth/convkeys.c index bb7d553b3..7886fa457 100644 --- a/sys/src/cmd/auth/convkeys.c +++ b/sys/src/cmd/auth/convkeys.c @@ -7,18 +7,21 @@ #include <bio.h> #include "authcmdlib.h" -Authkey authkey; +Authkey okey, nkey; + int verb; int usepass; +int convaes; + +uchar zeros[16]; -int convert(char*, Authkey*, int); +int convert(char**, int); void usage(void); void main(int argc, char *argv[]) { Dir *d; - Authkey key; char *p, *file; int fd, len; @@ -29,6 +32,9 @@ main(int argc, char *argv[]) case 'v': verb = 1; break; + case 'a': + convaes = 1; + break; default: usage(); }ARGEND @@ -40,12 +46,13 @@ main(int argc, char *argv[]) /* get original key */ if(usepass){ print("enter password file is encoded with\n"); - getpass(&authkey, nil, 0, 1); - } else - getauthkey(&authkey); + getpass(&okey, nil, 0, 1); + } else { + getauthkey(&okey); + } if(!verb){ print("enter password to reencode with\n"); - getpass(&key, nil, 0, 1); + getpass(&nkey, nil, 0, 1); } fd = open(file, ORDWR); @@ -56,17 +63,15 @@ main(int argc, char *argv[]) error("can't stat %s: %r\n", file); len = d->length; p = malloc(len); - if(!p) + if(p == nil) error("out of memory"); if(read(fd, p, len) != len) error("can't read key file: %r\n"); - len = convert(p, &key, len); - if(verb) - exits(0); + len = convert(&p, len); if(pwrite(fd, p, len, 0) != len) error("can't write key file: %r\n"); close(fd); - exits(0); + exits(nil); } void @@ -76,7 +81,7 @@ randombytes(uchar *p, int len) fd = open("/dev/random", OREAD); if(fd < 0){ - fprint(2, "convkeys: can't open /dev/random, using rand()\n"); + fprint(2, "%s: can't open /dev/random, using rand()\n", argv0); srand(time(0)); for(i = 0; i < len; i++) p[i] = rand(); @@ -86,34 +91,7 @@ randombytes(uchar *p, int len) close(fd); } -void -oldCBCencrypt(char *key7, char *p, int len) -{ - uchar ivec[8]; - uchar key[8]; - DESstate s; - - memset(ivec, 0, 8); - des56to64((uchar*)key7, key); - setupDESstate(&s, key, ivec); - desCBCencrypt((uchar*)p, len, &s); -} - -void -oldCBCdecrypt(char *key7, char *p, int len) -{ - uchar ivec[8]; - uchar key[8]; - DESstate s; - - memset(ivec, 0, 8); - des56to64((uchar*)key7, key); - setupDESstate(&s, key, ivec); - desCBCdecrypt((uchar*)p, len, &s); - -} - -static int +int badname(char *s) { int n; @@ -128,35 +106,102 @@ badname(char *s) } int -convert(char *p, Authkey *key, int len) +convert(char **db, int len) { - int i; + int i, nu, keydblen, keydboff, keydbaes; + char *p = *db; + + keydblen = KEYDBLEN; + keydboff = KEYDBOFF; + keydbaes = len > 24 && memcmp(p, "AES KEYS", 8) == 0; + if(keydbaes){ + keydblen += AESKEYLEN; + keydboff = 8+16; /* signature[8] + iv[16] */ + } + + len -= keydboff; + if(len % keydblen){ + fprint(2, "%s: file odd length; not converting %d bytes\n", argv0, len % keydblen); + len -= len % keydblen; + } + len += keydboff; + + if(keydbaes){ + AESstate s; - len -= KEYDBOFF; - if(len % KEYDBLEN){ - fprint(2, "convkeys: file odd length; not converting %d bytes\n", - len % KEYDBLEN); - len -= len % KEYDBLEN; + /* make sure we have aes key for decryption */ + if(memcmp(okey.aes, zeros, AESKEYLEN) == 0){ + fprint(2, "%s: no aes key in NVRAM\n", argv0); + exits("no aes key"); + } + setupAESstate(&s, okey.aes, AESKEYLEN, zeros); + aesCBCdecrypt((uchar*)p+8, len-8, &s); + } else { + DESstate s; + uchar k[8]; + + des56to64((uchar*)okey.des, k); + setupDESstate(&s, k, zeros); + desCBCdecrypt((uchar*)p, len, &s); } - len += KEYDBOFF; - oldCBCdecrypt(authkey.des, p, len); - for(i = KEYDBOFF; i < len; i += KEYDBLEN) + + nu = 0; + for(i = keydboff; i < len; i += keydblen) { if (badname(&p[i])) { - print("bad name %.30s... - aborting\n", &p[i]); - return 0; + fprint(2, "%s: bad name %.30s... - aborting\n", argv0, &p[i]); + exits("bad name"); } - if(verb) - for(i = KEYDBOFF; i < len; i += KEYDBLEN) + nu++; + } + + if(verb){ + for(i = keydboff; i < len; i += keydblen) print("%s\n", &p[i]); + exits(nil); + } + + if(convaes && !keydbaes){ + char *s, *d; + + keydboff = 8+16; + keydblen += AESKEYLEN; + len = keydboff + keydblen*nu; + p = realloc(p, len); + if(p == nil) + error("out of memory"); + *db = p; + s = p + KEYDBOFF + nu*KEYDBLEN; + d = p + keydboff + nu*keydblen; + for(i=0; i<nu; i++){ + s -= KEYDBLEN; + d -= keydblen; + memmove(d, s, KEYDBLEN); + memset(d + KEYDBLEN, 0, keydblen-KEYDBLEN); + } + keydbaes = 1; + } - randombytes((uchar*)p, 8); - oldCBCencrypt(key->des, p, len); + randombytes((uchar*)p, keydboff); + if(keydbaes){ + AESstate s; + + memmove(p, "AES KEYS", 8); + setupAESstate(&s, nkey.aes, AESKEYLEN, zeros); + aesCBCencrypt((uchar*)p+8, len-8, &s); + } else { + DESstate s; + uchar k[8]; + + des56to64((uchar*)nkey.des, k); + setupDESstate(&s, k, zeros); + desCBCencrypt((uchar*)p, len, &s); + } return len; } void usage(void) { - fprint(2, "usage: convkeys keyfile\n"); + fprint(2, "usage: %s [-pva] keyfile\n", argv0); exits("usage"); } diff --git a/sys/src/cmd/auth/keyfs.c b/sys/src/cmd/auth/keyfs.c index 8c6c01748..9ec02e0fb 100644 --- a/sys/src/cmd/auth/keyfs.c +++ b/sys/src/cmd/auth/keyfs.c @@ -14,6 +14,8 @@ #pragma varargck type "W" char* Authkey authkey; +int keydbaes; +uchar zeros[16]; typedef struct Fid Fid; typedef struct User User; @@ -22,6 +24,7 @@ enum { Qroot, Quser, Qkey, + Qaeskey, Qsecret, Qlog, Qstatus, @@ -52,6 +55,7 @@ struct Fid { struct User { char *name; char key[DESKEYLEN]; + uchar aeskey[AESKEYLEN]; char secret[SECRETLEN]; ulong expire; /* 0 == never */ uchar status; @@ -68,6 +72,7 @@ char *qinfo[Qmax] = { [Qroot] "keys", [Quser] ".", [Qkey] "key", + [Qaeskey] "aeskey", [Qsecret] "secret", [Qlog] "log", [Qexpire] "expire", @@ -85,8 +90,7 @@ User *users[Nuser]; char *userkeys; int nuser; ulong uniq = 1; -Fcall rhdr, - thdr; +Fcall rhdr, thdr; int usepass; char *warnarg; uchar mdata[8192 + IOHDRSZ]; @@ -102,6 +106,7 @@ void insertuser(User*); void writeusers(void); void io(int, int); void *emalloc(ulong); +char *estrdup(char*); Qid mkqid(User*, ulong); int dostat(User*, ulong, void*, int); int newkeys(void); @@ -136,6 +141,12 @@ usage(void) exits("usage"); } +static int +haveaeskey(void) +{ + return memcmp(authkey.aes, zeros, 16) != 0; +} + void main(int argc, char *argv[]) { @@ -169,11 +180,22 @@ main(int argc, char *argv[]) if(pipe(p) < 0) error("can't make pipe: %r"); - if(usepass) { + if(usepass) getpass(&authkey, nil, 0, 0); - } else { + else { if(!getauthkey(&authkey)) - print("keyfs: warning: can't read NVRAM\n"); + fprint(2, "keyfs: warning: can't read NVRAM\n"); + } + + keydbaes = 0; + if(!newkeys() || !readusers()){ + if(!keydbaes) + keydbaes = haveaeskey(); + else if(!haveaeskey()){ + fprint(2, "keyfs: no aes key in NVRAM\n"); + getpass(&authkey, nil, 0, 0); + readusers(); + } } switch(rfork(RFPROC|RFNAMEG|RFNOTEG|RFNOWAIT|RFENVG|RFFDG)){ @@ -209,7 +231,7 @@ Attach(Fid *f) { if(f->busy) Clunk(f); - f->user = 0; + f->user = nil; f->qtype = Qroot; f->busy = 1; thdr.qid = mkqid(f->user, f->qtype); @@ -272,7 +294,7 @@ Walk(Fid *f) if(strcmp(name, "..") == 0) goto Accept; user = finduser(name); - if(!user) + if(user == nil) goto Out; qtype = Quser; @@ -283,7 +305,7 @@ Walk(Fid *f) case Quser: if(strcmp(name, "..") == 0) { qtype = Qroot; - user = 0; + user = nil; goto Accept; } max = Qmax; @@ -314,14 +336,16 @@ Walk(Fid *f) if(rhdr.fid != rhdr.newfid && i == rhdr.nwname){ nf->busy = 1; nf->qtype = qtype; - if(nf->user = user) - nf->user->ref++; + nf->user = user; + if(user != nil) + user->ref++; }else if(nf == nil && rhdr.nwname > 0){ /* walk without clone (rare) */ Clunk(f); f->busy = 1; f->qtype = qtype; - if(f->user = user) - f->user->ref++; + f->user = user; + if(user != nil) + user->ref++; } thdr.nwqid = i; @@ -332,12 +356,12 @@ char * Clunk(Fid *f) { f->busy = 0; - if(f->user && --f->user->ref == 0 && f->user->removed) { + if(f->user != nil && --f->user->ref == 0 && f->user->removed) { free(f->user->name); free(f->user); } - f->user = 0; - return 0; + f->user = nil; + return nil; } char * @@ -350,6 +374,8 @@ Open(Fid *f) mode = rhdr.mode; if(f->qtype == Quser && (mode & (OWRITE|OTRUNC))) return "user already exists"; + if(f->qtype == Qaeskey && !keydbaes) + return "keyfile not in aes format"; thdr.qid = mkqid(f->user, f->qtype); thdr.iounit = messagesize - IOHDRSZ; return 0; @@ -364,7 +390,7 @@ Create(Fid *f) if(!f->busy) return "create of unused fid"; name = rhdr.name; - if(f->user){ + if(f->user != nil){ return "permission denied"; }else{ perm = rhdr.perm; @@ -374,7 +400,7 @@ Create(Fid *f) return "empty file name"; if(strlen(name) >= Namelen) return "file name too long"; - if(finduser(name)) + if(finduser(name) != nil) return "user already exists"; f->user = installuser(name); f->user->ref++; @@ -404,7 +430,7 @@ Read(Fid *f) case Qroot: j = 0; for(i = 0; i < Nuser; i++) - for(u = users[i]; u; j += m, u = u->link){ + for(u = users[i]; u != nil; j += m, u = u->link){ m = dostat(u, Quser, data, n); if(m <= BIT16SZ) break; @@ -431,19 +457,7 @@ Read(Fid *f) thdr.count = data - thdr.data; return 0; case Qkey: - if(f->user->status != Sok) - return "user disabled"; - if(f->user->purgatory > time(0)) - return "user in purgatory"; - if(f->user->expire != 0 && f->user->expire < time(0)) - return "user expired"; - if(off != 0) - return 0; - if(n > DESKEYLEN) - n = DESKEYLEN; - memmove(thdr.data, f->user->key, n); - thdr.count = n; - return 0; + case Qaeskey: case Qsecret: if(f->user->status != Sok) return "user disabled"; @@ -451,57 +465,52 @@ Read(Fid *f) return "user in purgatory"; if(f->user->expire != 0 && f->user->expire < time(0)) return "user expired"; - if(off != 0) - return 0; - if(n > strlen(f->user->secret)) - n = strlen(f->user->secret); - memmove(thdr.data, f->user->secret, n); + m = 0; + switch(f->qtype){ + case Qkey: + data = f->user->key; + m = DESKEYLEN; + break; + case Qaeskey: + data = (char*)f->user->aeskey; + m = AESKEYLEN; + break; + case Qsecret: + data = f->user->secret; + Readstr: + m = strlen(data); + break; + } + if(off >= m) + n = 0; + else { + data += off; + m -= off; + if(n > m) + n = m; + } + if(data != thdr.data) + memmove(thdr.data, data, n); thdr.count = n; return 0; case Qstatus: - if(off != 0){ - thdr.count = 0; - return 0; - } if(f->user->status == Sok && f->user->expire && f->user->expire < time(0)) - sprint(thdr.data, "expired\n"); + sprint(data, "expired\n"); else - sprint(thdr.data, "%s\n", status[f->user->status]); - thdr.count = strlen(thdr.data); - return 0; + sprint(data, "%s\n", status[f->user->status]); + goto Readstr; case Qexpire: - if(off != 0){ - thdr.count = 0; - return 0; - } if(!f->user->expire) strcpy(data, "never\n"); else sprint(data, "%lud\n", f->user->expire); - if(n > strlen(data)) - n = strlen(data); - thdr.count = n; - return 0; + goto Readstr; case Qlog: - if(off != 0){ - thdr.count = 0; - return 0; - } sprint(data, "%lud\n", f->user->bad); - if(n > strlen(data)) - n = strlen(data); - thdr.count = n; - return 0; + goto Readstr; case Qwarnings: - if(off != 0){ - thdr.count = 0; - return 0; - } sprint(data, "%ud\n", f->user->warnings); - if(n > strlen(data)) - n = strlen(data); - thdr.count = n; - return 0; + goto Readstr; default: return "permission denied: unknown qid"; } @@ -525,11 +534,17 @@ Write(Fid *f) memmove(f->user->key, data, DESKEYLEN); thdr.count = DESKEYLEN; break; + case Qaeskey: + if(n != AESKEYLEN) + return "garbled write data"; + memmove(f->user->aeskey, data, AESKEYLEN); + thdr.count = AESKEYLEN; + break; case Qsecret: if(n >= SECRETLEN) return "garbled write data"; memmove(f->user->secret, data, n); - f->user->secret[n] = 0; + f->user->secret[n] = '\0'; thdr.count = n; break; case Qstatus: @@ -639,9 +654,7 @@ Wstat(Fid *f) if(!removeuser(f->user)) return "user previously removed"; free(f->user->name); - f->user->name = strdup(d.name); - if(f->user->name == nil) - error("wstat: malloc failed: %r"); + f->user->name = estrdup(d.name); insertuser(f->user); writeusers(); return 0; @@ -683,17 +696,6 @@ dostat(User *user, ulong qtype, void *p, int n) return convD2M(&d, p, n); } -int -passline(Biobuf *b, void *vbuf) -{ - char *buf = vbuf; - - if(Bread(b, buf, KEYDBLEN) != KEYDBLEN) - return 0; - decrypt(authkey.des, buf, KEYDBLEN); - buf[Namelen-1] = '\0'; - return 1; -} void randombytes(uchar *p, int len) @@ -713,57 +715,35 @@ randombytes(uchar *p, int len) } void -oldCBCencrypt(char *key7, uchar *p, int len) -{ - uchar ivec[8]; - uchar key[8]; - DESstate s; - - memset(ivec, 0, 8); - des56to64((uchar*)key7, key); - setupDESstate(&s, key, ivec); - desCBCencrypt((uchar*)p, len, &s); -} - -void -oldCBCdecrypt(char *key7, uchar *p, int len) -{ - uchar ivec[8]; - uchar key[8]; - DESstate s; - - memset(ivec, 0, 8); - des56to64((uchar*)key7, key); - setupDESstate(&s, key, ivec); - desCBCdecrypt((uchar*)p, len, &s); - -} - -void writeusers(void) { + int keydblen, keydboff; int fd, i, nu; User *u; uchar *p, *buf; ulong expire; + /* what format to use */ + keydblen = KEYDBLEN; + keydboff = KEYDBOFF; + if(keydbaes){ + keydblen += AESKEYLEN; + keydboff = 8+16; /* segnature[8] + iv[16] */ + } + /* count users */ nu = 0; for(i = 0; i < Nuser; i++) - for(u = users[i]; u; u = u->link) + for(u = users[i]; u != nil; u = u->link) nu++; /* pack into buffer */ - buf = malloc(KEYDBOFF + nu*KEYDBLEN); - if(buf == 0){ - fprint(2, "keyfs: can't write keys file, out of memory\n"); - return; - } + buf = emalloc(keydboff + nu*keydblen); p = buf; - randombytes(p, KEYDBOFF); - p += KEYDBOFF; + randombytes(p, keydboff); + p += keydboff; for(i = 0; i < Nuser; i++) - for(u = users[i]; u; u = u->link){ + for(u = users[i]; u != nil; u = u->link){ strncpy((char*)p, u->name, Namelen); p += Namelen; memmove(p, u->key, DESKEYLEN); @@ -777,10 +757,27 @@ writeusers(void) *p++ = expire >> 24; memmove(p, u->secret, SECRETLEN); p += SECRETLEN; + if(keydbaes){ + memmove(p, u->aeskey, AESKEYLEN); + p += AESKEYLEN; + } } /* encrypt */ - oldCBCencrypt(authkey.des, buf, p - buf); + if(keydbaes){ + AESstate s; + + memmove(buf, "AES KEYS", 8); + setupAESstate(&s, authkey.aes, AESKEYLEN, zeros); + aesCBCencrypt(buf+8, (p - (buf+8)), &s); + } else { + uchar key[8]; + DESstate s; + + des56to64((uchar*)authkey.des, key); + setupDESstate(&s, key, zeros); + desCBCencrypt(buf, p - buf, &s); + } /* write file */ fd = create(userkeys, OWRITE, 0660); @@ -858,6 +855,7 @@ userok(char *user, int nu) int readusers(void) { + int keydblen, keydboff; int fd, i, n, nu; uchar *p, *buf, *ep; User *u; @@ -872,12 +870,7 @@ readusers(void) close(fd); return 0; } - buf = malloc(d->length); - if(buf == 0){ - close(fd); - free(d); - return 0; - } + buf = emalloc(d->length); n = readn(fd, buf, d->length); close(fd); free(d); @@ -886,18 +879,41 @@ readusers(void) return 0; } + keydblen = KEYDBLEN; + keydboff = KEYDBOFF; + keydbaes = n > 24 && memcmp(buf, "AES KEYS", 8) == 0; + /* decrypt */ - n -= n % KEYDBLEN; - oldCBCdecrypt(authkey.des, buf, n); + if(keydbaes){ + AESstate s; + + /* make sure we have AES encryption key */ + if(!haveaeskey()){ + free(buf); + return 0; + } + keydblen += AESKEYLEN; + keydboff = 8+16; /* signature[8] + iv[16] */ + setupAESstate(&s, authkey.aes, AESKEYLEN, zeros); + aesCBCdecrypt(buf+8, n-8, &s); + } else { + uchar key[8]; + DESstate s; + + des56to64((uchar*)authkey.des, key); + setupDESstate(&s, key, zeros); + desCBCdecrypt(buf, n, &s); + } /* unpack */ nu = 0; - for(i = KEYDBOFF; i < n; i += KEYDBLEN){ - ep = buf + i; - if(userok((char*)ep, i/KEYDBLEN) < 0) + n = (n - keydboff) / keydblen; + ep = buf + keydboff; + for(i = 0; i < n; ep += keydblen, i++){ + if(userok((char*)ep, i) < 0) continue; u = finduser((char*)ep); - if(u == 0) + if(u == nil) u = installuser((char*)ep); memmove(u->key, ep + Namelen, DESKEYLEN); p = ep + Namelen + DESKEYLEN; @@ -909,11 +925,14 @@ readusers(void) p += 4; memmove(u->secret, p, SECRETLEN); u->secret[SECRETLEN-1] = 0; + p += SECRETLEN; + if(keydbaes) + memmove(u->aeskey, p, AESKEYLEN); nu++; } free(buf); - print("%d keys read\n", nu); + print("%d keys read in %s foarmat\n", nu, keydbaes ? "AES" : "DES"); return 1; } @@ -925,9 +944,7 @@ installuser(char *name) h = hash(name); u = emalloc(sizeof *u); - u->name = strdup(name); - if(u->name == nil) - error("malloc failed: %r"); + u->name = estrdup(name); u->removed = 0; u->ref = 0; u->purgatory = 0; @@ -946,10 +963,10 @@ finduser(char *name) { User *u; - for(u = users[hash(name)]; u; u = u->link) + for(u = users[hash(name)]; u != nil; u = u->link) if(strcmp(name, u->name) == 0) return u; - return 0; + return nil; } int @@ -961,7 +978,7 @@ removeuser(User *user) user->removed = 1; name = user->name; last = &users[hash(name)]; - for(u = *last; u; u = *last){ + for(u = *last; u != nil; u = *last){ if(strcmp(name, u->name) == 0){ *last = u->link; return 1; @@ -998,20 +1015,20 @@ findfid(int fid) { Fid *f, *ff; - ff = 0; - for(f = fids; f; f = f->next) + ff = nil; + for(f = fids; f != nil; f = f->next) if(f->fid == fid) return f; else if(!ff && !f->busy) ff = f; - if(ff){ + if(ff != nil){ ff->fid = fid; return ff; } f = emalloc(sizeof *f); f->fid = fid; f->busy = 0; - f->user = 0; + f->user = nil; f->next = fids; fids = f; return f; @@ -1088,10 +1105,24 @@ emalloc(ulong n) { void *p; - if(p = malloc(n)) + if((p = malloc(n)) != nil){ + memset(p, 0, n); return p; + } error("out of memory"); - return 0; /* not reached */ + return nil; /* not reached */ +} + +char * +estrdup(char *s) +{ + char *d; + int n; + + n = strlen(s)+1; + d = emalloc(n); + memmove(d, s, n); + return d; } void diff --git a/sys/src/cmd/auth/lib/getauthkey.c b/sys/src/cmd/auth/lib/getauthkey.c index 84c3d1557..48437e808 100644 --- a/sys/src/cmd/auth/lib/getauthkey.c +++ b/sys/src/cmd/auth/lib/getauthkey.c @@ -5,13 +5,14 @@ #include "authcmdlib.h" static int -getkey(char *authkey) +getkey(Authkey *authkey) { Nvrsafe safe; if(readnvram(&safe, 0) < 0) return -1; - memmove(authkey, safe.machkey, DESKEYLEN); + memmove(authkey->des, safe.machkey, DESKEYLEN); + memmove(authkey->aes, safe.aesmachkey, AESKEYLEN); memset(&safe, 0, sizeof safe); return 0; } @@ -20,7 +21,7 @@ int getauthkey(Authkey *authkey) { memset(authkey, 0, sizeof(Authkey)); - if(getkey(authkey->des) == 0) + if(getkey(authkey) == 0) return 1; print("can't read NVRAM, please enter machine key\n"); getpass(authkey, nil, 0, 1); diff --git a/sys/src/cmd/auth/lib/readln.c b/sys/src/cmd/auth/lib/readln.c index 38a712497..f5b8789f7 100644 --- a/sys/src/cmd/auth/lib/readln.c +++ b/sys/src/cmd/auth/lib/readln.c @@ -22,15 +22,12 @@ getpass(Authkey *key, char *pass, int check, int confirm) continue; } } - if(!passtokey(key, pass)){ - print("bad password, try again\n"); - continue; - } if(check) if(err = okpasswd(pass)){ print("%s, try again\n", err); continue; } + passtokey(key, pass); break; } } |