aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/secstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/secstore')
-rw-r--r--src/cmd/secstore/SConn.c213
-rw-r--r--src/cmd/secstore/SConn.h26
-rw-r--r--src/cmd/secstore/aescbc.c156
-rw-r--r--src/cmd/secstore/dirls.c87
-rw-r--r--src/cmd/secstore/mkfile27
-rw-r--r--src/cmd/secstore/pak.c344
-rw-r--r--src/cmd/secstore/password.c136
-rw-r--r--src/cmd/secstore/portdate9
-rw-r--r--src/cmd/secstore/secacct.c35
-rw-r--r--src/cmd/secstore/secchk.c28
-rw-r--r--src/cmd/secstore/secstore.c585
-rw-r--r--src/cmd/secstore/secstore.h31
-rw-r--r--src/cmd/secstore/secstored.c420
-rw-r--r--src/cmd/secstore/secureidcheck.c446
-rw-r--r--src/cmd/secstore/secuser.c244
-rw-r--r--src/cmd/secstore/util.c28
16 files changed, 0 insertions, 2815 deletions
diff --git a/src/cmd/secstore/SConn.c b/src/cmd/secstore/SConn.c
deleted file mode 100644
index 7a8654ac..00000000
--- a/src/cmd/secstore/SConn.c
+++ /dev/null
@@ -1,213 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-
-extern int verbose;
-
-typedef struct ConnState {
- uchar secret[SHA1dlen];
- ulong seqno;
- RC4state rc4;
-} ConnState;
-
-typedef struct SS{
- int fd; // file descriptor for read/write of encrypted data
- int alg; // if nonzero, "alg sha rc4_128"
- ConnState in, out;
-} SS;
-
-static int
-SC_secret(SConn *conn, uchar *sigma, int direction)
-{
- SS *ss = (SS*)(conn->chan);
- int nsigma = conn->secretlen;
-
- if(direction != 0){
- hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->out.secret, nil);
- hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->in.secret, nil);
- }else{
- hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->out.secret, nil);
- hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->in.secret, nil);
- }
- setupRC4state(&ss->in.rc4, ss->in.secret, 16); // restrict to 128 bits
- setupRC4state(&ss->out.rc4, ss->out.secret, 16);
- ss->alg = 1;
- return 0;
-}
-
-static void
-hash(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
- DigestState sha;
- uchar seq[4];
-
- seq[0] = seqno>>24;
- seq[1] = seqno>>16;
- seq[2] = seqno>>8;
- seq[3] = seqno;
- memset(&sha, 0, sizeof sha);
- sha1(secret, SHA1dlen, nil, &sha);
- sha1(data, len, nil, &sha);
- sha1(seq, 4, d, &sha);
-}
-
-static int
-verify(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
- DigestState sha;
- uchar seq[4];
- uchar digest[SHA1dlen];
-
- seq[0] = seqno>>24;
- seq[1] = seqno>>16;
- seq[2] = seqno>>8;
- seq[3] = seqno;
- memset(&sha, 0, sizeof sha);
- sha1(secret, SHA1dlen, nil, &sha);
- sha1(data, len, nil, &sha);
- sha1(seq, 4, digest, &sha);
- return memcmp(d, digest, SHA1dlen);
-}
-
-static int
-SC_read(SConn *conn, uchar *buf, int n)
-{
- SS *ss = (SS*)(conn->chan);
- uchar count[2], digest[SHA1dlen];
- int len, nr;
-
- if(read(ss->fd, count, 2) != 2 || (count[0]&0x80) == 0){
- snprint((char*)buf,n,"!SC_read invalid count");
- return -1;
- }
- len = (count[0]&0x7f)<<8 | count[1]; // SSL-style count; no pad
- if(ss->alg){
- len -= SHA1dlen;
- if(len <= 0 || readn(ss->fd, digest, SHA1dlen) != SHA1dlen){
- snprint((char*)buf,n,"!SC_read missing sha1");
- return -1;
- }
- if(len > n || readn(ss->fd, buf, len) != len){
- snprint((char*)buf,n,"!SC_read missing data");
- return -1;
- }
- rc4(&ss->in.rc4, digest, SHA1dlen);
- rc4(&ss->in.rc4, buf, len);
- if(verify(ss->in.secret, buf, len, ss->in.seqno, digest) != 0){
- snprint((char*)buf,n,"!SC_read integrity check failed");
- return -1;
- }
- }else{
- if(len <= 0 || len > n){
- snprint((char*)buf,n,"!SC_read implausible record length");
- return -1;
- }
- if( (nr = readn(ss->fd, buf, len)) != len){
- snprint((char*)buf,n,"!SC_read expected %d bytes, but got %d", len, nr);
- return -1;
- }
- }
- ss->in.seqno++;
- return len;
-}
-
-static int
-SC_write(SConn *conn, uchar *buf, int n)
-{
- SS *ss = (SS*)(conn->chan);
- uchar count[2], digest[SHA1dlen], enc[Maxmsg+1];
- int len;
-
- if(n <= 0 || n > Maxmsg+1){
- werrstr("!SC_write invalid n %d", n);
- return -1;
- }
- len = n;
- if(ss->alg)
- len += SHA1dlen;
- count[0] = 0x80 | len>>8;
- count[1] = len;
- if(write(ss->fd, count, 2) != 2){
- werrstr("!SC_write invalid count");
- return -1;
- }
- if(ss->alg){
- hash(ss->out.secret, buf, n, ss->out.seqno, digest);
- rc4(&ss->out.rc4, digest, SHA1dlen);
- memcpy(enc, buf, n);
- rc4(&ss->out.rc4, enc, n);
- if(write(ss->fd, digest, SHA1dlen) != SHA1dlen ||
- write(ss->fd, enc, n) != n){
- werrstr("!SC_write error on send");
- return -1;
- }
- }else{
- if(write(ss->fd, buf, n) != n){
- werrstr("!SC_write error on send");
- return -1;
- }
- }
- ss->out.seqno++;
- return n;
-}
-
-static void
-SC_free(SConn *conn)
-{
- SS *ss = (SS*)(conn->chan);
-
- close(ss->fd);
- free(ss);
- free(conn);
-}
-
-SConn*
-newSConn(int fd)
-{
- SS *ss;
- SConn *conn;
-
- if(fd < 0)
- return nil;
- ss = (SS*)emalloc(sizeof(*ss));
- conn = (SConn*)emalloc(sizeof(*conn));
- ss->fd = fd;
- ss->alg = 0;
- conn->chan = (void*)ss;
- conn->secretlen = SHA1dlen;
- conn->free = SC_free;
- conn->secret = SC_secret;
- conn->read = SC_read;
- conn->write = SC_write;
- return conn;
-}
-
-void
-writerr(SConn *conn, char *s)
-{
- char buf[Maxmsg];
-
- snprint(buf, Maxmsg, "!%s", s);
- conn->write(conn, (uchar*)buf, strlen(buf));
-}
-
-int
-readstr(SConn *conn, char *s)
-{
- int n;
-
- n = conn->read(conn, (uchar*)s, Maxmsg);
- if(n >= 0){
- s[n] = 0;
- if(s[0] == '!'){
- memmove(s, s+1, n);
- n = -1;
- }
- }else{
- strcpy(s, "read error");
- }
- return n;
-}
-
diff --git a/src/cmd/secstore/SConn.h b/src/cmd/secstore/SConn.h
deleted file mode 100644
index 9a428d83..00000000
--- a/src/cmd/secstore/SConn.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// delimited, authenticated, encrypted connection
-enum{ Maxmsg=4096 }; // messages > Maxmsg bytes are truncated
-typedef struct SConn SConn;
-
-extern SConn* newSConn(int); // arg is open file descriptor
-struct SConn{
- void *chan;
- int secretlen;
- int (*secret)(SConn*, uchar*, int);//
- int (*read)(SConn*, uchar*, int); // <0 if error; errmess in buffer
- int (*write)(SConn*, uchar*, int);
- void (*free)(SConn*); // also closes file descriptor
-};
-// secret(s,b,dir) sets secret for digest, encrypt, using the secretlen
-// bytes in b to form keys for the two directions;
-// set dir=0 in client, dir=1 in server
-
-// error convention: write !message in-band
-extern void writerr(SConn*, char*);
-extern int readstr(SConn*, char*); // call with buf of size Maxmsg+1
- // returns -1 upon error, with error message in buf
-
-extern void *emalloc(ulong); /* dies on failure; clears memory */
-extern void *erealloc(void *, ulong);
-extern char *estrdup(char *);
-
diff --git a/src/cmd/secstore/aescbc.c b/src/cmd/secstore/aescbc.c
deleted file mode 100644
index 56aeb00b..00000000
--- a/src/cmd/secstore/aescbc.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* encrypt file by writing
- v2hdr,
- 16byte initialization vector,
- AES-CBC(key, random | file),
- HMAC_SHA1(md5(key), AES-CBC(random | file))
-*/
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mp.h>
-#include <libsec.h>
-
-extern char* getpassm(char*);
-
-enum{ CHK = 16, BUF = 4096 };
-
-uchar v2hdr[AESbsize+1] = "AES CBC SHA1 2\n";
-Biobuf bin;
-Biobuf bout;
-
-void
-safewrite(uchar *buf, int n)
-{
- int i = Bwrite(&bout, buf, n);
-
- if(i == n)
- return;
- fprint(2, "write error\n");
- exits("write error");
-}
-
-void
-saferead(uchar *buf, int n)
-{
- int i = Bread(&bin, buf, n);
-
- if(i == n)
- return;
- fprint(2, "read error\n");
- exits("read error");
-}
-
-int
-main(int argc, char **argv)
-{
- int encrypt = 0; /* 0=decrypt, 1=encrypt */
- int n, nkey, pass_stdin = 0;
- char *pass;
- uchar key[AESmaxkey], key2[SHA1dlen];
- uchar buf[BUF+SHA1dlen]; /* assumption: CHK <= SHA1dlen */
- AESstate aes;
- DigestState *dstate;
-
- ARGBEGIN{
- case 'e':
- encrypt = 1;
- break;
- case 'i':
- pass_stdin = 1;
- break;
- }ARGEND;
- if(argc!=0){
- fprint(2,"usage: %s -d < cipher.aes > clear.txt\n", argv0);
- fprint(2," or: %s -e < clear.txt > cipher.aes\n", argv0);
- exits("usage");
- }
- Binit(&bin, 0, OREAD);
- Binit(&bout, 1, OWRITE);
-
- if(pass_stdin){
- n = readn(3, buf, (sizeof buf)-1);
- if(n < 1)
- exits("usage: echo password |[3=1] auth/aescbc -i ...");
- buf[n] = 0;
- while(buf[n-1] == '\n')
- buf[--n] = 0;
- }else{
- pass = readcons("aescbc key", nil, 1);
- n = strlen(pass);
- if(n >= BUF)
- exits("key too long");
- strcpy((char*)buf, pass);
- memset(pass, 0, n);
- free(pass);
- }
- if(n <= 0){
- fprint(2,"no key\n");
- exits("key");
- }
- dstate = sha1((uchar*)"aescbc file", 11, nil, nil);
- sha1(buf, n, key2, dstate);
- memcpy(key, key2, 16);
- nkey = 16;
- md5(key, nkey, key2, 0); /* so even if HMAC_SHA1 is broken, encryption key is protected */
-
- if(encrypt){
- safewrite(v2hdr, AESbsize);
- genrandom(buf,2*AESbsize); /* CBC is semantically secure if IV is unpredictable. */
- setupAESstate(&aes, key, nkey, buf); /* use first AESbsize bytes as IV */
- aesCBCencrypt(buf+AESbsize, AESbsize, &aes); /* use second AESbsize bytes as initial plaintext */
- safewrite(buf, 2*AESbsize);
- dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
- while(1){
- n = Bread(&bin, buf, BUF);
- if(n < 0){
- fprint(2,"read error\n");
- exits("read error");
- }
- aesCBCencrypt(buf, n, &aes);
- safewrite(buf, n);
- dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
- if(n < BUF)
- break; /* EOF */
- }
- hmac_sha1(0, 0, key2, MD5dlen, buf, dstate);
- safewrite(buf, SHA1dlen);
- }else{ /* decrypt */
- saferead(buf, AESbsize);
- if(memcmp(buf, v2hdr, AESbsize) == 0){
- saferead(buf, 2*AESbsize); /* read IV and random initial plaintext */
- setupAESstate(&aes, key, nkey, buf);
- dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
- aesCBCdecrypt(buf+AESbsize, AESbsize, &aes);
- saferead(buf, SHA1dlen);
- while((n = Bread(&bin, buf+SHA1dlen, BUF)) > 0){
- dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
- aesCBCdecrypt(buf, n, &aes);
- safewrite(buf, n);
- memmove(buf, buf+n, SHA1dlen); /* these bytes are not yet decrypted */
- }
- hmac_sha1(0, 0, key2, MD5dlen, buf+SHA1dlen, dstate);
- if(memcmp(buf, buf+SHA1dlen, SHA1dlen) != 0){
- fprint(2,"decrypted file failed to authenticate\n");
- exits("decrypted file failed to authenticate");
- }
- }else{ /* compatibility with past mistake */
- // if file was encrypted with bad aescbc use this:
- // memset(key, 0, AESmaxkey);
- // else assume we're decrypting secstore files
- setupAESstate(&aes, key, AESbsize, buf);
- saferead(buf, CHK);
- aesCBCdecrypt(buf, CHK, &aes);
- while((n = Bread(&bin, buf+CHK, BUF)) > 0){
- aesCBCdecrypt(buf+CHK, n, &aes);
- safewrite(buf, n);
- memmove(buf, buf+n, CHK);
- }
- if(memcmp(buf, "XXXXXXXXXXXXXXXX", CHK) != 0){
- fprint(2,"decrypted file failed to authenticate\n");
- exits("decrypted file failed to authenticate");
- }
- }
- }
- exits("");
- return 1; /* gcc */
-}
diff --git a/src/cmd/secstore/dirls.c b/src/cmd/secstore/dirls.c
deleted file mode 100644
index b4479413..00000000
--- a/src/cmd/secstore/dirls.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-
-static long
-ls(char *p, Dir **dirbuf)
-{
- int fd;
- long n;
- Dir *db;
-
- if((db = dirstat(p)) == nil ||
- !(db->qid.type & QTDIR) ||
- (fd = open(p, OREAD)) < 0 )
- return -1;
- free(db);
- n = dirreadall(fd, dirbuf);
- close(fd);
- return n;
-}
-
-static uchar*
-sha1file(char *pfx, char *nm)
-{
- int n, fd, len;
- char *tmp;
- uchar buf[8192];
- static uchar digest[SHA1dlen];
- DigestState *s;
-
- len = strlen(pfx)+1+strlen(nm)+1;
- tmp = emalloc(len);
- snprint(tmp, len, "%s/%s", pfx, nm);
- if((fd = open(tmp, OREAD)) < 0){
- free(tmp);
- return nil;
- }
- free(tmp);
- s = nil;
- while((n = read(fd, buf, sizeof buf)) > 0)
- s = sha1(buf, n, nil, s);
- close(fd);
- sha1(nil, 0, digest, s);
- return digest;
-}
-
-static int
-compare(Dir *a, Dir *b)
-{
- return strcmp(a->name, b->name);
-}
-
-/* list the (name mtime size sum) of regular, readable files in path */
-char *
-dirls(char *path)
-{
- char *list, *date, dig[30], buf[128];
- int m, nmwid, lenwid;
- long i, n, ndir, len;
- Dir *dirbuf;
-
- if(path==nil || (ndir = ls(path, &dirbuf)) < 0)
- return nil;
-
- qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(const void *, const void *))compare);
- for(nmwid=lenwid=i=0; i<ndir; i++){
- if((m = strlen(dirbuf[i].name)) > nmwid)
- nmwid = m;
- snprint(buf, sizeof(buf), "%ulld", dirbuf[i].length);
- if((m = strlen(buf)) > lenwid)
- lenwid = m;
- }
- for(list=nil, len=0, i=0; i<ndir; i++){
- date = ctime(dirbuf[i].mtime);
- date[28] = 0; // trim newline
- n = snprint(buf, sizeof buf, "%*ulld %s", lenwid, dirbuf[i].length, date+4);
- n += enc64(dig, sizeof dig, sha1file(path, dirbuf[i].name), SHA1dlen);
- n += nmwid+3+strlen(dirbuf[i].name);
- list = erealloc(list, len+n+1);
- len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
- }
- free(dirbuf);
- return list;
-}
-
diff --git a/src/cmd/secstore/mkfile b/src/cmd/secstore/mkfile
deleted file mode 100644
index 72986edd..00000000
--- a/src/cmd/secstore/mkfile
+++ /dev/null
@@ -1,27 +0,0 @@
-<$PLAN9/src/mkhdr
-
-BIN=$PLAN9/bin
-#CFLAGS=-Fw
-HFILES =\
- SConn.h\
- secstore.h\
-
-OFILES =\
- pak.$O\
- password.$O\
- SConn.$O\
- util.$O\
-
-
-TARG=aescbc secstore secstored secuser
-
-<$PLAN9/src/mkmany
-
-$O.aescbc: aescbc.$O util.$O
- $LD -o $target $prereq $LDFLAGS
-
-$O.secstored: secstored.$O dirls.$O secureidcheck.$O $OFILES
- $LD -o $target $prereq
-
-$O.secuser: secuser.$O $OFILES
- $LD -o $target $prereq
diff --git a/src/cmd/secstore/pak.c b/src/cmd/secstore/pak.c
deleted file mode 100644
index fb008e0f..00000000
--- a/src/cmd/secstore/pak.c
+++ /dev/null
@@ -1,344 +0,0 @@
-// PAK is an encrypted key exchange protocol designed by Philip MacKenzie et al.
-// It is patented and use outside Plan 9 requires you get a license.
-// (All other EKE protocols are patented as well, by Lucent or others.)
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-extern int verbose;
-
-char VERSION[] = "secstore";
-static char *feedback[] = {"alpha","bravo","charlie","delta","echo","foxtrot","golf","hotel"};
-
-typedef struct PAKparams{
- mpint *q, *p, *r, *g;
-} PAKparams;
-
-static PAKparams *pak;
-
-// from seed EB7B6E35F7CD37B511D96C67D6688CC4DD440E1E
-static void
-initPAKparams(void)
-{
- if(pak)
- return;
- pak = (PAKparams*)emalloc(sizeof(*pak));
- pak->q = strtomp("E0F0EF284E10796C5A2A511E94748BA03C795C13", nil, 16, nil);
- pak->p = strtomp("C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBB"
- "DB12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A86"
- "3A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D9"
- "3D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D",
- nil, 16, nil);
- pak->r = strtomp("DF310F4E54A5FEC5D86D3E14863921E834113E060F90052AD332B3241"
- "CEF2497EFA0303D6344F7C819691A0F9C4A773815AF8EAECFB7EC1D98F039F17A32A7E"
- "887D97251A927D093F44A55577F4D70444AEBD06B9B45695EC23962B175F266895C67D"
- "21C4656848614D888A4", nil, 16, nil);
- pak->g = strtomp("2F1C308DC46B9A44B52DF7DACCE1208CCEF72F69C743ADD4D23271734"
- "44ED6E65E074694246E07F9FD4AE26E0FDDD9F54F813C40CB9BCD4338EA6F242AB94CD"
- "410E676C290368A16B1A3594877437E516C53A6EEE5493A038A017E955E218E7819734"
- "E3E2A6E0BAE08B14258F8C03CC1B30E0DDADFCF7CEDF0727684D3D255F1",
- nil, 16, nil);
-}
-
-// H = (sha(ver,C,sha(passphrase)))^r mod p,
-// a hash function expensive to attack by brute force.
-static void
-longhash(char *ver, char *C, uchar *passwd, mpint *H)
-{
- uchar *Cp;
- int i, n, nver, nC;
- uchar buf[140], key[1];
-
- nver = strlen(ver);
- nC = strlen(C);
- n = nver + nC + SHA1dlen;
- Cp = (uchar*)emalloc(n);
- memmove(Cp, ver, nver);
- memmove(Cp+nver, C, nC);
- memmove(Cp+nver+nC, passwd, SHA1dlen);
- for(i = 0; i < 7; i++){
- key[0] = 'A'+i;
- hmac_sha1(Cp, n, key, sizeof key, buf+i*SHA1dlen, nil);
- }
- memset(Cp, 0, n);
- free(Cp);
- betomp(buf, sizeof buf, H);
- mpmod(H, pak->p, H);
- mpexp(H, pak->r, pak->p, H);
-}
-
-// Hi = H^-1 mod p
-char *
-PAK_Hi(char *C, char *passphrase, mpint *H, mpint *Hi)
-{
- uchar passhash[SHA1dlen];
-
- sha1((uchar *)passphrase, strlen(passphrase), passhash, nil);
- initPAKparams();
- longhash(VERSION, C, passhash, H);
- mpinvert(H, pak->p, Hi);
- return mptoa(Hi, 64, nil, 0);
-}
-
-// another, faster, hash function for each party to
-// confirm that the other has the right secrets.
-static void
-shorthash(char *mess, char *C, char *S, char *m, char *mu, char *sigma, char *Hi, uchar *digest)
-{
- SHA1state *state;
-
- state = sha1((uchar*)mess, strlen(mess), 0, 0);
- state = sha1((uchar*)C, strlen(C), 0, state);
- state = sha1((uchar*)S, strlen(S), 0, state);
- state = sha1((uchar*)m, strlen(m), 0, state);
- state = sha1((uchar*)mu, strlen(mu), 0, state);
- state = sha1((uchar*)sigma, strlen(sigma), 0, state);
- state = sha1((uchar*)Hi, strlen(Hi), 0, state);
- state = sha1((uchar*)mess, strlen(mess), 0, state);
- state = sha1((uchar*)C, strlen(C), 0, state);
- state = sha1((uchar*)S, strlen(S), 0, state);
- state = sha1((uchar*)m, strlen(m), 0, state);
- state = sha1((uchar*)mu, strlen(mu), 0, state);
- state = sha1((uchar*)sigma, strlen(sigma), 0, state);
- sha1((uchar*)Hi, strlen(Hi), digest, state);
-}
-
-// On input, conn provides an open channel to the server;
-// C is the name this client calls itself;
-// pass is the user's passphrase
-// On output, session secret has been set in conn
-// (unless return code is negative, which means failure).
-// If pS is not nil, it is set to the (alloc'd) name the server calls itself.
-int
-PAKclient(SConn *conn, char *C, char *pass, char **pS)
-{
- char *mess, *mess2, *eol, *S, *hexmu, *ks, *hexm, *hexsigma = nil, *hexHi;
- char kc[2*SHA1dlen+1];
- uchar digest[SHA1dlen];
- int rc = -1, n;
- mpint *x, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
- mpint *H = mpnew(0), *Hi = mpnew(0);
-
- hexHi = PAK_Hi(C, pass, H, Hi);
- if(verbose)
- fprint(2,"%s\n", feedback[H->p[0]&0x7]); // provide a clue to catch typos
-
- // random 1<=x<=q-1; send C, m=g**x H
- x = mprand(240, genrandom, nil);
- mpmod(x, pak->q, x);
- if(mpcmp(x, mpzero) == 0)
- mpassign(mpone, x);
- mpexp(pak->g, x, pak->p, m);
- mpmul(m, H, m);
- mpmod(m, pak->p, m);
- hexm = mptoa(m, 64, nil, 0);
- mess = (char*)emalloc(2*Maxmsg+2);
- mess2 = mess+Maxmsg+1;
- snprint(mess, Maxmsg, "%s\tPAK\nC=%s\nm=%s\n", VERSION, C, hexm);
- conn->write(conn, (uchar*)mess, strlen(mess));
-
- // recv g**y, S, check hash1(g**xy)
- if(readstr(conn, mess) < 0){
- fprint(2, "error: %s\n", mess);
- writerr(conn, "couldn't read g**y");
- goto done;
- }
- eol = strchr(mess, '\n');
- if(strncmp("mu=", mess, 3) != 0 || !eol || strncmp("\nk=", eol, 3) != 0){
- writerr(conn, "verifier syntax error");
- goto done;
- }
- hexmu = mess+3;
- *eol = 0;
- ks = eol+3;
- eol = strchr(ks, '\n');
- if(!eol || strncmp("\nS=", eol, 3) != 0){
- writerr(conn, "verifier syntax error for secstore 1.0");
- goto done;
- }
- *eol = 0;
- S = eol+3;
- eol = strchr(S, '\n');
- if(!eol){
- writerr(conn, "verifier syntax error for secstore 1.0");
- goto done;
- }
- *eol = 0;
- if(pS)
- *pS = estrdup(S);
- strtomp(hexmu, nil, 64, mu);
- mpexp(mu, x, pak->p, sigma);
- hexsigma = mptoa(sigma, 64, nil, 0);
- shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- enc64(kc, sizeof kc, digest, SHA1dlen);
- if(strcmp(ks, kc) != 0){
- writerr(conn, "verifier didn't match");
- goto done;
- }
-
- // send hash2(g**xy)
- shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- enc64(kc, sizeof kc, digest, SHA1dlen);
- snprint(mess2, Maxmsg, "k'=%s\n", kc);
- conn->write(conn, (uchar*)mess2, strlen(mess2));
-
- // set session key
- shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- memset(hexsigma, 0, strlen(hexsigma));
- n = conn->secret(conn, digest, 0);
- memset(digest, 0, SHA1dlen);
- if(n < 0){
- writerr(conn, "can't set secret");
- goto done;
- }
-
- rc = 0;
-done:
- mpfree(x);
- mpfree(sigma);
- mpfree(mu);
- mpfree(m);
- mpfree(Hi);
- mpfree(H);
- free(hexsigma);
- free(hexHi);
- free(hexm);
- free(mess);
- return rc;
-}
-
-// On input,
-// mess contains first message;
-// name is name this server should call itself.
-// On output, session secret has been set in conn;
-// if pw!=nil, then *pw points to PW struct for authenticated user.
-// returns -1 if error
-int
-PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
-{
- int rc = -1, n;
- char mess2[Maxmsg+1], *eol;
- char *C, ks[41], *kc, *hexm, *hexmu = nil, *hexsigma = nil, *hexHi = nil;
- uchar digest[SHA1dlen];
- mpint *H = mpnew(0), *Hi = mpnew(0);
- mpint *y = nil, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
- PW *pw = nil;
-
- // secstore version and algorithm
- snprint(mess2,Maxmsg,"%s\tPAK\n", VERSION);
- n = strlen(mess2);
- if(strncmp(mess,mess2,n) != 0){
- writerr(conn, "protocol should start with ver alg");
- return -1;
- }
- mess += n;
- initPAKparams();
-
- // parse first message into C, m
- eol = strchr(mess, '\n');
- if(strncmp("C=", mess, 2) != 0 || !eol){
- fprint(2,"mess[1]=%s\n", mess);
- writerr(conn, "PAK version mismatch");
- goto done;
- }
- C = mess+2;
- *eol = 0;
- hexm = eol+3;
- eol = strchr(hexm, '\n');
- if(strncmp("m=", hexm-2, 2) != 0 || !eol){
- writerr(conn, "PAK version mismatch");
- goto done;
- }
- *eol = 0;
- strtomp(hexm, nil, 64, m);
- mpmod(m, pak->p, m);
-
- // lookup client
- if((pw = getPW(C,0)) == nil) {
- snprint(mess2, sizeof mess2, "%r");
- writerr(conn, mess2);
- goto done;
- }
- if(mpcmp(m, mpzero) == 0) {
- writerr(conn, "account exists");
- freePW(pw);
- pw = nil;
- goto done;
- }
- hexHi = mptoa(pw->Hi, 64, nil, 0);
-
- // random y, mu=g**y, sigma=g**xy
- y = mprand(240, genrandom, nil);
- mpmod(y, pak->q, y);
- if(mpcmp(y, mpzero) == 0){
- mpassign(mpone, y);
- }
- mpexp(pak->g, y, pak->p, mu);
- mpmul(m, pw->Hi, m);
- mpmod(m, pak->p, m);
- mpexp(m, y, pak->p, sigma);
-
- // send g**y, hash1(g**xy)
- hexmu = mptoa(mu, 64, nil, 0);
- hexsigma = mptoa(sigma, 64, nil, 0);
- shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- enc64(ks, sizeof ks, digest, SHA1dlen);
- snprint(mess2, sizeof mess2, "mu=%s\nk=%s\nS=%s\n", hexmu, ks, S);
- conn->write(conn, (uchar*)mess2, strlen(mess2));
-
- // recv hash2(g**xy)
- if(readstr(conn, mess2) < 0){
- writerr(conn, "couldn't read verifier");
- goto done;
- }
- eol = strchr(mess2, '\n');
- if(strncmp("k'=", mess2, 3) != 0 || !eol){
- writerr(conn, "verifier syntax error");
- goto done;
- }
- kc = mess2+3;
- *eol = 0;
- shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- enc64(ks, sizeof ks, digest, SHA1dlen);
- if(strcmp(ks, kc) != 0) {
- rc = -2;
- goto done;
- }
-
- // set session key
- shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- n = conn->secret(conn, digest, 1);
- if(n < 0){
- writerr(conn, "can't set secret");
- goto done;
- }
-
- rc = 0;
-done:
- if(rc<0 && pw){
- pw->failed++;
- putPW(pw);
- }
- if(rc==0 && pw && pw->failed>0){
- pw->failed = 0;
- putPW(pw);
- }
- if(pwp)
- *pwp = pw;
- else
- freePW(pw);
- free(hexsigma);
- free(hexHi);
- free(hexmu);
- mpfree(y);
- mpfree(sigma);
- mpfree(mu);
- mpfree(m);
- mpfree(Hi);
- mpfree(H);
- return rc;
-}
-
diff --git a/src/cmd/secstore/password.c b/src/cmd/secstore/password.c
deleted file mode 100644
index aacadd9b..00000000
--- a/src/cmd/secstore/password.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* password.c */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-static Biobuf*
-openPW(char *id, int mode)
-{
- Biobuf *b;
- int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
- char *fn = emalloc(nfn);
-
- snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
- b = Bopen(fn, mode);
- free(fn);
- return b;
-}
-
-static ulong
-mtimePW(char *id)
-{
- Dir *d;
- int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
- char *fn = emalloc(nfn);
- ulong mt;
-
- snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
- d = dirstat(fn);
- free(fn);
- mt = d->mtime;
- free(d);
- return mt;
-}
-
-PW *
-getPW(char *id, int dead_or_alive)
-{
- uint now = time(0);
- Biobuf *bin;
- PW *pw;
- char *f1, *f2; // fields 1, 2 = attribute, value
-
- if((bin = openPW(id, OREAD)) == 0){
- id = "FICTITIOUS";
- if((bin = openPW(id, OREAD)) == 0){
- werrstr("account does not exist");
- return nil;
- }
- }
- pw = emalloc(sizeof(*pw));
- pw->id = estrdup(id);
- pw->status |= Enabled;
- while( (f1 = Brdline(bin, '\n')) != 0){
- f1[Blinelen(bin)-1] = 0;
- for(f2 = f1; *f2 && (*f2!=' ') && (*f2!='\t'); f2++){}
- if(*f2)
- for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++){}
- if(strcmp(f1, "exp") == 0){
- pw->expire = strtoul(f2, 0, 10);
- }else if(strcmp(f1, "DISABLED") == 0){
- pw->status &= ~Enabled;
- }else if(strcmp(f1, "STA") == 0){
- pw->status |= STA;
- }else if(strcmp(f1, "failed") == 0){
- pw->failed = strtoul(f2, 0, 10);
- }else if(strcmp(f1, "other") == 0){
- pw->other = estrdup(f2);
- }else if(strcmp(f1, "PAK-Hi") == 0){
- pw->Hi = strtomp(f2, nil, 64, nil);
- }
- }
- Bterm(bin);
- if(dead_or_alive)
- return pw; // return PW entry for editing, whether currently valid or not
- if(pw->expire <= now){
- werrstr("account expired");
- freePW(pw);
- return nil;
- }
- if((pw->status & Enabled) == 0){
- werrstr("account disabled");
- freePW(pw);
- return nil;
- }
- if(pw->failed < 10)
- return pw; // success
- if(now < mtimePW(id)+300){
- werrstr("too many failures; try again in five minutes");
- freePW(pw);
- return nil;
- }
- pw->failed = 0;
- putPW(pw); // reset failed-login-counter after five minutes
- return pw;
-}
-
-int
-putPW(PW *pw)
-{
- Biobuf *bout;
- char *hexHi;
-
- if((bout = openPW(pw->id, OWRITE|OTRUNC)) ==0){
- werrstr("can't open PW file");
- return -1;
- }
- Bprint(bout, "exp %lud\n", pw->expire);
- if(!(pw->status & Enabled))
- Bprint(bout, "DISABLED\n");
- if(pw->status & STA)
- Bprint(bout, "STA\n");
- if(pw->failed)
- Bprint(bout, "failed\t%d\n", pw->failed);
- if(pw->other)
- Bprint(bout,"other\t%s\n", pw->other);
- hexHi = mptoa(pw->Hi, 64, nil, 0);
- Bprint(bout, "PAK-Hi\t%s\n", hexHi);
- free(hexHi);
- return 0;
-}
-
-void
-freePW(PW *pw)
-{
- if(pw == nil)
- return;
- free(pw->id);
- free(pw->other);
- mpfree(pw->Hi);
- free(pw);
-}
-
diff --git a/src/cmd/secstore/portdate b/src/cmd/secstore/portdate
deleted file mode 100644
index 8d50496e..00000000
--- a/src/cmd/secstore/portdate
+++ /dev/null
@@ -1,9 +0,0 @@
-SConn.c 2004/1225
-SConn.h 2004/1225
-aescbc.c 2004/1225
-dirls.c 2004/1225
-pak.c 2004/1225
-password.c 2004/1225
-secstore.c 2004/1225
-secstore.h 2004/1225
-util.c 2004/1225
diff --git a/src/cmd/secstore/secacct.c b/src/cmd/secstore/secacct.c
deleted file mode 100644
index 4390129a..00000000
--- a/src/cmd/secstore/secacct.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-
-int verbose = 1;
-static char testmess[] = "__secstore\tPAK\nC=%s\nm=0\n";
-
-void
-main(int argc, char **argv)
-{
- int n, m, fd;
- uchar buf[500];
-
- if(argc != 2)
- exits("usage: secacct userid");
-
- n = snprint((char*)buf, sizeof buf, testmess, argv[1]);
- hnputs(buf, 0x8000+n-2);
-
- fd = dial("tcp!ruble.cs.bell-labs.com!5356", 0, 0, 0);
- if(fd < 0)
- exits("cannot dial ruble");
- if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2)
- exits("cannot exchange first round");
- n = ((buf[0]&0x7f)<<8) + buf[1];
- if(n+1 > sizeof buf)
- exits("implausibly large count");
- m = readn(fd, buf, n);
- close(fd);
- if(m != n)
- fprint(2,"short read from secstore\n");
- buf[m] = 0;
- print("%s\n", (char*)buf);
- exits(0);
-}
diff --git a/src/cmd/secstore/secchk.c b/src/cmd/secstore/secchk.c
deleted file mode 100644
index 59e26d51..00000000
--- a/src/cmd/secstore/secchk.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ndb.h>
-
-extern char* secureidcheck(char *user, char *response);
-Ndb *db;
-
-void
-main(int argc, char **argv)
-{
- Ndb *db2;
-
- if(argc!=2){
- fprint(2,"usage %s pinsecurid\n", argv[0]);
- exits("usage");
- }
- db = ndbopen("/lib/ndb/auth");
- if(db == 0)
- syslog(0, "secstore", "no /lib/ndb/auth");
- db2 = ndbopen(0);
- if(db2 == 0)
- syslog(0, "secstore", "no /lib/ndb/local");
- db = ndbcat(db, db2);
- print("user=%s\n", getenv("user"));
- print("%s\n", secureidcheck(getenv("user"), argv[1]));
- exits(0);
-}
diff --git a/src/cmd/secstore/secstore.c b/src/cmd/secstore/secstore.c
deleted file mode 100644
index 864aa88d..00000000
--- a/src/cmd/secstore/secstore.c
+++ /dev/null
@@ -1,585 +0,0 @@
-/* network login client */
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include <authsrv.h>
-#include "SConn.h"
-#include "secstore.h"
-enum{ CHK = 16, MAXFILES = 100 };
-
-typedef struct AuthConn{
- SConn *conn;
- char pass[64];
- int passlen;
-} AuthConn;
-
-int verbose;
-Nvrsafe nvr;
-char *SECSTORE_DIR;
-
-void
-usage(void)
-{
- fprint(2, "usage: secstore [-cin] [-g getfile] [-p putfile] [-r rmfile] [-s tcp!server!5356] [-u user] [-v]\n");
- exits("usage");
-}
-
-static int
-getfile(SConn *conn, char *gf, uchar **buf, ulong *buflen, uchar *key, int nkey)
-{
- int fd = -1;
- int i, n, nr, nw, len;
- char s[Maxmsg+1];
- uchar skey[SHA1dlen], ib[Maxmsg+CHK], *ibr, *ibw, *bufw, *bufe;
- AESstate aes;
- DigestState *sha;
-
- if(strchr(gf, '/')){
- fprint(2, "simple filenames, not paths like %s\n", gf);
- return -1;
- }
- memset(&aes, 0, sizeof aes);
-
- snprint(s, Maxmsg, "GET %s\n", gf);
- conn->write(conn, (uchar*)s, strlen(s));
-
- /* get file size */
- s[0] = '\0';
- bufw = bufe = nil;
- if(readstr(conn, s) < 0){
- fprint(2, "remote: %s\n", s);
- return -1;
- }
- len = atoi(s);
- if(len == -1){
- fprint(2, "remote file %s does not exist\n", gf);
- return -1;
- }else if(len == -3){
- fprint(2, "implausible filesize for %s\n", gf);
- return -1;
- }else if(len < 0){
- fprint(2, "GET refused for %s\n", gf);
- return -1;
- }
- if(buf != nil){
- *buflen = len - AESbsize - CHK;
- *buf = bufw = emalloc(len);
- bufe = bufw + len;
- }
-
- /* directory listing */
- if(strcmp(gf,".")==0){
- if(buf != nil)
- *buflen = len;
- for(i=0; i < len; i += n){
- if((n = conn->read(conn, (uchar*)s, Maxmsg)) <= 0){
- fprint(2, "empty file chunk\n");
- return -1;
- }
- if(buf == nil)
- write(1, s, n);
- else
- memmove((*buf)+i, s, n);
- }
- return 0;
- }
-
- /* conn is already encrypted against wiretappers,
- but gf is also encrypted against server breakin. */
- if(buf == nil && (fd =create(gf, OWRITE, 0600)) < 0){
- fprint(2, "can't open %s: %r\n", gf);
- return -1;
- }
-
- ibr = ibw = ib;
- for(nr=0; nr < len;){
- if((n = conn->read(conn, ibw, Maxmsg)) <= 0){
- fprint(2, "empty file chunk n=%d nr=%d len=%d: %r\n", n, nr, len);
- return -1;
- }
- nr += n;
- ibw += n;
- if(!aes.setup){ /* first time, read 16 byte IV */
- if(n < AESbsize){
- fprint(2, "no IV in file\n");
- return -1;
- }
- sha = sha1((uchar*)"aescbc file", 11, nil, nil);
- sha1(key, nkey, skey, sha);
- setupAESstate(&aes, skey, AESbsize, ibr);
- memset(skey, 0, sizeof skey);
- ibr += AESbsize;
- n -= AESbsize;
- }
- aesCBCdecrypt(ibw-n, n, &aes);
- n = ibw-ibr-CHK;
- if(n > 0){
- if(buf == nil){
- nw = write(fd, ibr, n);
- if(nw != n){
- fprint(2, "write error on %s", gf);
- return -1;
- }
- }else{
- assert(bufw+n <= bufe);
- memmove(bufw, ibr, n);
- bufw += n;
- }
- ibr += n;
- }
- memmove(ib, ibr, ibw-ibr);
- ibw = ib + (ibw-ibr);
- ibr = ib;
- }
- if(buf == nil)
- close(fd);
- n = ibw-ibr;
- if((n != CHK) || (memcmp(ib, "XXXXXXXXXXXXXXXX", CHK) != 0)){
- fprint(2,"decrypted file failed to authenticate!\n");
- return -1;
- }
- return 0;
-}
-
-// This sends a file to the secstore disk that can, in an emergency, be
-// decrypted by the program aescbc.c.
-static int
-putfile(SConn *conn, char *pf, uchar *buf, ulong len, uchar *key, int nkey)
-{
- int i, n, fd, ivo, bufi, done;
- char s[Maxmsg];
- uchar skey[SHA1dlen], b[CHK+Maxmsg], IV[AESbsize];
- AESstate aes;
- DigestState *sha;
-
- /* create initialization vector */
- srand(time(0)); /* doesn't need to be unpredictable */
- for(i=0; i<AESbsize; i++)
- IV[i] = 0xff & rand();
- sha = sha1((uchar*)"aescbc file", 11, nil, nil);
- sha1(key, nkey, skey, sha);
- setupAESstate(&aes, skey, AESbsize, IV);
- memset(skey, 0, sizeof skey);
-
- snprint(s, Maxmsg, "PUT %s\n", pf);
- conn->write(conn, (uchar*)s, strlen(s));
-
- if(buf == nil){
- /* get file size */
- if((fd = open(pf, OREAD)) < 0){
- fprint(2, "can't open %s: %r\n", pf);
- return -1;
- }
- len = seek(fd, 0, 2);
- seek(fd, 0, 0);
- } else {
- fd = -1;
- }
- if(len > MAXFILESIZE){
- fprint(2, "implausible filesize %ld for %s\n", len, pf);
- return -1;
- }
-
- /* send file size */
- snprint(s, Maxmsg, "%ld", len+AESbsize+CHK);
- conn->write(conn, (uchar*)s, strlen(s));
-
- /* send IV and file+XXXXX in Maxmsg chunks */
- ivo = AESbsize;
- bufi = 0;
- memcpy(b, IV, ivo);
- for(done = 0; !done; ){
- if(buf == nil){
- n = read(fd, b+ivo, Maxmsg-ivo);
- if(n < 0){
- fprint(2, "read error on %s: %r\n", pf);
- return -1;
- }
- }else{
- if((n = len - bufi) > Maxmsg-ivo)
- n = Maxmsg-ivo;
- memcpy(b+ivo, buf+bufi, n);
- bufi += n;
- }
- n += ivo;
- ivo = 0;
- if(n < Maxmsg){ /* EOF on input; append XX... */
- memset(b+n, 'X', CHK);
- n += CHK; // might push n>Maxmsg
- done = 1;
- }
- aesCBCencrypt(b, n, &aes);
- if(n > Maxmsg){
- assert(done==1);
- conn->write(conn, b, Maxmsg);
- n -= Maxmsg;
- memmove(b, b+Maxmsg, n);
- }
- conn->write(conn, b, n);
- }
-
- if(buf == nil)
- close(fd);
- fprint(2, "saved %ld bytes\n", len);
-
- return 0;
-}
-
-static int
-removefile(SConn *conn, char *rf)
-{
- char buf[Maxmsg];
-
- if(strchr(rf, '/')){
- fprint(2, "simple filenames, not paths like %s\n", rf);
- return -1;
- }
-
- snprint(buf, Maxmsg, "RM %s\n", rf);
- conn->write(conn, (uchar*)buf, strlen(buf));
-
- return 0;
-}
-
-static int
-cmd(AuthConn *c, char **gf, int *Gflag, char **pf, char **rf)
-{
- ulong len;
- int rv = -1;
- uchar *memfile, *memcur, *memnext;
-
- while(*gf != nil){
- if(verbose)
- fprint(2, "get %s\n", *gf);
- if(getfile(c->conn, *gf, *Gflag ? &memfile : nil, &len, (uchar*)c->pass, c->passlen) < 0)
- goto Out;
- if(*Gflag){
- // write one line at a time, as required by /mnt/factotum/ctl
- memcur = memfile;
- while(len>0){
- memnext = (uchar*)strchr((char*)memcur, '\n');
- if(memnext){
- write(1, memcur, memnext-memcur+1);
- len -= memnext-memcur+1;
- memcur = memnext+1;
- }else{
- write(1, memcur, len);
- break;
- }
- }
- free(memfile);
- }
- gf++;
- Gflag++;
- }
- while(*pf != nil){
- if(verbose)
- fprint(2, "put %s\n", *pf);
- if(putfile(c->conn, *pf, nil, 0, (uchar*)c->pass, c->passlen) < 0)
- goto Out;
- pf++;
- }
- while(*rf != nil){
- if(verbose)
- fprint(2, "rm %s\n", *rf);
- if(removefile(c->conn, *rf) < 0)
- goto Out;
- rf++;
- }
-
- c->conn->write(c->conn, (uchar*)"BYE", 3);
- rv = 0;
-
-Out:
- c->conn->free(c->conn);
- return rv;
-}
-
-static int
-chpasswd(AuthConn *c, char *id)
-{
- ulong len;
- int rv = -1, newpasslen = 0;
- mpint *H, *Hi;
- uchar *memfile;
- char *newpass, *passck;
- char *list, *cur, *next, *hexHi;
- char *f[8], prompt[128];
-
- H = mpnew(0);
- Hi = mpnew(0);
- // changing our password is vulnerable to connection failure
- for(;;){
- snprint(prompt, sizeof(prompt), "new password for %s: ", id);
- newpass = readcons(prompt, nil, 1);
- if(newpass == nil)
- goto Out;
- if(strlen(newpass) >= 7)
- break;
- else if(strlen(newpass) == 0){
- fprint(2, "!password change aborted\n");
- goto Out;
- }
- print("!password must be at least 7 characters\n");
- }
- newpasslen = strlen(newpass);
- snprint(prompt, sizeof(prompt), "retype password: ");
- passck = readcons(prompt, nil, 1);
- if(passck == nil){
- fprint(2, "readcons failed\n");
- goto Out;
- }
- if(strcmp(passck, newpass) != 0){
- fprint(2, "passwords didn't match\n");
- goto Out;
- }
-
- c->conn->write(c->conn, (uchar*)"CHPASS", strlen("CHPASS"));
- hexHi = PAK_Hi(id, newpass, H, Hi);
- c->conn->write(c->conn, (uchar*)hexHi, strlen(hexHi));
- free(hexHi);
- mpfree(H);
- mpfree(Hi);
-
- if(getfile(c->conn, ".", (uchar **)(void*)&list, &len, nil, 0) < 0){
- fprint(2, "directory listing failed.\n");
- goto Out;
- }
-
- /* Loop over files and reencrypt them; try to keep going after error */
- for(cur=list; (next=strchr(cur, '\n')) != nil; cur=next+1){
- *next = '\0';
- if(tokenize(cur, f, nelem(f))< 1)
- break;
- fprint(2, "reencrypting '%s'\n", f[0]);
- if(getfile(c->conn, f[0], &memfile, &len, (uchar*)c->pass, c->passlen) < 0){
- fprint(2, "getfile of '%s' failed\n", f[0]);
- continue;
- }
- if(putfile(c->conn, f[0], memfile, len, (uchar*)newpass, newpasslen) < 0)
- fprint(2, "putfile of '%s' failed\n", f[0]);
- free(memfile);
- }
- free(list);
- c->conn->write(c->conn, (uchar*)"BYE", 3);
- rv = 0;
-
-Out:
- if(newpass != nil){
- memset(newpass, 0, newpasslen);
- free(newpass);
- }
- c->conn->free(c->conn);
- return rv;
-}
-
-static AuthConn*
-login(char *id, char *dest, int pass_stdin, int pass_nvram)
-{
- AuthConn *c;
- int fd, n, ntry = 0;
- char *S, *PINSTA = nil, *nl, s[Maxmsg+1], *pass;
-
- if(dest == nil){
- fprint(2, "tried to login with nil dest\n");
- exits("nil dest");
- }
- c = emalloc(sizeof(*c));
- if(pass_nvram){
- /* if(readnvram(&nvr, 0) < 0) */
- exits("readnvram: %r");
- strecpy(c->pass, c->pass+sizeof c->pass, nvr.config);
- }
- if(pass_stdin){
- n = readn(0, s, Maxmsg-2); // so len(PINSTA)<Maxmsg-3
- if(n < 1)
- exits("no password on standard input");
- s[n] = 0;
- nl = strchr(s, '\n');
- if(nl){
- *nl++ = 0;
- PINSTA = estrdup(nl);
- nl = strchr(PINSTA, '\n');
- if(nl)
- *nl = 0;
- }
- strecpy(c->pass, c->pass+sizeof c->pass, s);
- }
- while(1){
- if(verbose)
- fprint(2, "dialing %s\n", dest);
- if((fd = dial(dest, nil, nil, nil)) < 0){
- fprint(2, "can't dial %s\n", dest);
- free(c);
- return nil;
- }
- if((c->conn = newSConn(fd)) == nil){
- free(c);
- return nil;
- }
- ntry++;
- if(!pass_stdin && !pass_nvram){
- pass = readcons("secstore password", nil, 1);
- if(pass == nil)
- pass = estrdup("");
- if(strlen(pass) >= sizeof c->pass){
- fprint(2, "password too long, skipping secstore login\n");
- exits("password too long");
- }
- strcpy(c->pass, pass);
- memset(pass, 0, strlen(pass));
- free(pass);
- }
- if(c->pass[0]==0){
- fprint(2, "null password, skipping secstore login\n");
- exits("no password");
- }
- if(PAKclient(c->conn, id, c->pass, &S) >= 0)
- break;
- c->conn->free(c->conn);
- if(pass_stdin)
- exits("invalid password on standard input");
- if(pass_nvram)
- exits("invalid password in nvram");
- // and let user try retyping the password
- if(ntry==3)
- fprint(2, "Enter an empty password to quit.\n");
- }
- c->passlen = strlen(c->pass);
- fprint(2, "server: %s\n", S);
- free(S);
- if(readstr(c->conn, s) < 0){
- c->conn->free(c->conn);
- free(c);
- return nil;
- }
- if(strcmp(s, "STA") == 0){
- long sn;
- if(pass_stdin){
- if(PINSTA)
- strncpy(s+3, PINSTA, (sizeof s)-3);
- else
- exits("missing PIN+SecureID on standard input");
- free(PINSTA);
- }else{
- pass = readcons("STA PIN+SecureID", nil, 1);
- if(pass == nil)
- pass = estrdup("");
- strncpy(s+3, pass, (sizeof s)-4);
- memset(pass, 0, strlen(pass));
- free(pass);
- }
- sn = strlen(s+3);
- if(verbose)
- fprint(2, "%ld\n", sn);
- c->conn->write(c->conn, (uchar*)s, sn+3);
- readstr(c->conn, s);
- }
- if(strcmp(s, "OK") != 0){
- fprint(2, "%s\n", s);
- c->conn->free(c->conn);
- free(c);
- return nil;
- }
- return c;
-}
-
-int
-main(int argc, char **argv)
-{
- int chpass = 0, pass_stdin = 0, pass_nvram = 0, rc;
- int ngfile = 0, npfile = 0, nrfile = 0, Gflag[MAXFILES+1];
- char *gfile[MAXFILES], *pfile[MAXFILES], *rfile[MAXFILES];
- char *serve, *tcpserve, *user;
- AuthConn *c;
-
- serve = "$auth";
- user = getuser();
- memset(Gflag, 0, sizeof Gflag);
- fmtinstall('B', mpfmt);
- fmtinstall('H', encodefmt);
-
- ARGBEGIN{
- case 'c':
- chpass = 1;
- break;
- case 'G':
- Gflag[ngfile]++;
- /* fall through */
- case 'g':
- if(ngfile >= MAXFILES)
- exits("too many gfiles");
- gfile[ngfile++] = ARGF();
- if(gfile[ngfile-1] == nil)
- usage();
- break;
- case 'i':
- pass_stdin = 1;
- break;
- case 'n':
- pass_nvram = 1;
- break;
- case 'p':
- if(npfile >= MAXFILES)
- exits("too many pfiles");
- pfile[npfile++] = ARGF();
- if(pfile[npfile-1] == nil)
- usage();
- break;
- case 'r':
- if(nrfile >= MAXFILES)
- exits("too many rfiles");
- rfile[nrfile++] = ARGF();
- if(rfile[nrfile-1] == nil)
- usage();
- break;
- case 's':
- serve = EARGF(usage());
- break;
- case 'u':
- user = EARGF(usage());
- break;
- case 'v':
- verbose++;
- break;
- default:
- usage();
- break;
- }ARGEND;
- gfile[ngfile] = nil;
- pfile[npfile] = nil;
- rfile[nrfile] = nil;
-
- if(argc!=0 || user==nil)
- usage();
-
- if(chpass && (ngfile || npfile || nrfile)){
- fprint(2, "Get, put, and remove invalid with password change.\n");
- exits("usage");
- }
-
- rc = strlen(serve)+sizeof("tcp!!99990");
- tcpserve = emalloc(rc);
- if(strchr(serve,'!'))
- strcpy(tcpserve, serve);
- else
- snprint(tcpserve, rc, "tcp!%s!5356", serve);
- c = login(user, tcpserve, pass_stdin, pass_nvram);
- free(tcpserve);
- if(c == nil){
- fprint(2, "secstore authentication failed\n");
- exits("secstore authentication failed");
- }
- if(chpass)
- rc = chpasswd(c, user);
- else
- rc = cmd(c, gfile, Gflag, pfile, rfile);
- if(rc < 0){
- fprint(2, "secstore cmd failed\n");
- exits("secstore cmd failed");
- }
- exits("");
- return 0;
-}
-
diff --git a/src/cmd/secstore/secstore.h b/src/cmd/secstore/secstore.h
deleted file mode 100644
index dbd2ec9c..00000000
--- a/src/cmd/secstore/secstore.h
+++ /dev/null
@@ -1,31 +0,0 @@
-enum{ MAXFILESIZE = 10*1024*1024 };
-
-enum{// PW status bits
- Enabled = (1<<0),
- STA = (1<<1), // extra SecurID step
-};
-
-typedef struct PW {
- char *id; // user id
- ulong expire; // expiration time (epoch seconds)
- ushort status; // Enabled, STA, ...
- ushort failed; // number of failed login attempts
- char *other; // other information, e.g. sponsor
- mpint *Hi; // H(passphrase)^-1 mod p
-} PW;
-
-PW *getPW(char *, int);
-int putPW(PW *);
-void freePW(PW *);
-
-// *client: SConn, client name, passphrase
-// *server: SConn, (partial) 1st msg, PW entry
-// *setpass: Username, hashed passphrase, PW entry
-int PAKclient(SConn *, char *, char *, char **);
-int PAKserver(SConn *, char *, char *, PW **);
-char *PAK_Hi(char *, char *, mpint *, mpint *);
-
-#define LOG "secstore"
-
-extern char *SECSTORE_DIR;
-
diff --git a/src/cmd/secstore/secstored.c b/src/cmd/secstore/secstored.c
deleted file mode 100644
index 58f7459a..00000000
--- a/src/cmd/secstore/secstored.c
+++ /dev/null
@@ -1,420 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ndb.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-char *SECSTORE_DIR;
-char* secureidcheck(char *, char *); // from /sys/src/cmd/auth/
-extern char* dirls(char *path);
-
-int verbose;
-Ndb *db;
-
-static void
-usage(void)
-{
- fprint(2, "usage: secstored [-R] [-S servername] [-s tcp!*!5356] [-v] [-x netmtpt]\n");
- exits("usage");
-}
-
-static int
-getdir(SConn *conn, char *id)
-{
- char *ls, *s;
- uchar *msg;
- int n, len;
-
- s = emalloc(Maxmsg);
- snprint(s, Maxmsg, "%s/store/%s", SECSTORE_DIR, id);
-
- if((ls = dirls(s)) == nil)
- len = 0;
- else
- len = strlen(ls);
-
- /* send file size */
- snprint(s, Maxmsg, "%d", len);
- conn->write(conn, (uchar*)s, strlen(s));
-
- /* send directory listing in Maxmsg chunks */
- n = Maxmsg;
- msg = (uchar*)ls;
- while(len > 0){
- if(len < Maxmsg)
- n = len;
- conn->write(conn, msg, n);
- msg += n;
- len -= n;
- }
- free(s);
- free(ls);
- return 0;
-}
-
-char *
-validatefile(char *f)
-{
- char *nl;
-
- if(f==nil || *f==0)
- return nil;
- if(nl = strchr(f, '\n'))
- *nl = 0;
- if(strchr(f,'/') != nil || strcmp(f,"..")==0 || strlen(f) >= 300){
- syslog(0, LOG, "no slashes allowed: %s\n", f);
- return nil;
- }
- return f;
-}
-
-static int
-getfile(SConn *conn, char *id, char *gf)
-{
- int n, gd, len;
- ulong mode;
- char *s;
- Dir *st;
-
- if(strcmp(gf,".")==0)
- return getdir(conn, id);
-
- /* send file size */
- s = emalloc(Maxmsg);
- snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, gf);
- gd = open(s, OREAD);
- if(gd < 0){
- syslog(0, LOG, "can't open %s: %r\n", s);
- free(s);
- conn->write(conn, (uchar*)"-1", 2);
- return -1;
- }
- st = dirfstat(gd);
- if(st == nil){
- syslog(0, LOG, "can't stat %s: %r\n", s);
- free(s);
- conn->write(conn, (uchar*)"-1", 2);
- return -1;
- }
- mode = st->mode;
- len = st->length;
- free(st);
- if(mode & DMDIR) {
- syslog(0, LOG, "%s should be a plain file, not a directory\n", s);
- free(s);
- conn->write(conn, (uchar*)"-1", 2);
- return -1;
- }
- if(len < 0 || len > MAXFILESIZE){
- syslog(0, LOG, "implausible filesize %d for %s\n", len, gf);
- free(s);
- conn->write(conn, (uchar*)"-3", 2);
- return -1;
- }
- snprint(s, Maxmsg, "%d", len);
- conn->write(conn, (uchar*)s, strlen(s));
-
- /* send file in Maxmsg chunks */
- while(len > 0){
- n = read(gd, s, Maxmsg);
- if(n <= 0){
- syslog(0, LOG, "read error on %s: %r\n", gf);
- free(s);
- return -1;
- }
- conn->write(conn, (uchar*)s, n);
- len -= n;
- }
- close(gd);
- free(s);
- return 0;
-}
-
-static int
-putfile(SConn *conn, char *id, char *pf)
-{
- int n, nw, pd;
- long len;
- char s[Maxmsg+1];
-
- /* get file size */
- n = readstr(conn, s);
- if(n < 0){
- syslog(0, LOG, "remote: %s: %r\n", s);
- return -1;
- }
- len = atoi(s);
- if(len == -1){
- syslog(0, LOG, "remote file %s does not exist\n", pf);
- return -1;
- }else if(len < 0 || len > MAXFILESIZE){
- syslog(0, LOG, "implausible filesize %ld for %s\n", len, pf);
- return -1;
- }
-
- /* get file in Maxmsg chunks */
- if(strchr(pf,'/') != nil || strcmp(pf,"..")==0){
- syslog(0, LOG, "no slashes allowed: %s\n", pf);
- return -1;
- }
- snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, pf);
- pd = create(s, OWRITE, 0660);
- if(pd < 0){
- syslog(0, LOG, "can't open %s: %r\n", s);
- return -1;
- }
- while(len > 0){
- n = conn->read(conn, (uchar*)s, Maxmsg);
- if(n <= 0){
- syslog(0, LOG, "empty file chunk\n");
- return -1;
- }
- nw = write(pd, s, n);
- if(nw != n){
- syslog(0, LOG, "write error on %s: %r", pf);
- return -1;
- }
- len -= n;
- }
- close(pd);
- return 0;
-
-}
-
-static int
-removefile(SConn *conn, char *id, char *f)
-{
- Dir *d;
- char buf[Maxmsg];
-
- snprint(buf, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, f);
-
- if((d = dirstat(buf)) == nil){
- snprint(buf, sizeof buf, "remove failed: %r");
- writerr(conn, buf);
- return -1;
- }else if(d->mode & DMDIR){
- snprint(buf, sizeof buf, "can't remove a directory");
- writerr(conn, buf);
- free(d);
- return -1;
- }
-
- free(d);
- if(remove(buf) < 0){
- snprint(buf, sizeof buf, "remove failed: %r");
- writerr(conn, buf);
- return -1;
- }
- return 0;
-}
-
-/* given line directory from accept, returns ipaddr!port */
-static char*
-remoteIP(char *ldir)
-{
- int fd, n;
- char rp[100], ap[500];
-
- snprint(rp, sizeof rp, "%s/remote", ldir);
- fd = open(rp, OREAD);
- if(fd < 0)
- return strdup("?!?");
- n = read(fd, ap, sizeof ap);
- if(n <= 0 || n == sizeof ap){
- fprint(2, "error %d reading %s: %r\n", n, rp);
- return strdup("?!?");
- }
- close(fd);
- ap[n--] = 0;
- if(ap[n] == '\n')
- ap[n] = 0;
- return strdup(ap);
-}
-
-static int
-dologin(int fd, char *S, int forceSTA)
-{
- int i, n, rv;
- char *file, *mess;
- char msg[Maxmsg+1];
- PW *pw;
- SConn *conn;
-
- pw = nil;
- rv = -1;
-
- // collect the first message
- if((conn = newSConn(fd)) == nil)
- return -1;
- if(readstr(conn, msg) < 0){
- fprint(2, "remote: %s: %r\n", msg);
- writerr(conn, "can't read your first message");
- goto Out;
- }
-
- // authenticate
- if(PAKserver(conn, S, msg, &pw) < 0){
- if(pw != nil)
- syslog(0, LOG, "secstore denied for %s", pw->id);
- goto Out;
- }
- if((forceSTA || pw->status&STA) != 0){
- conn->write(conn, (uchar*)"STA", 3);
- if(readstr(conn, msg) < 10 || strncmp(msg, "STA", 3) != 0){
- syslog(0, LOG, "no STA from %s", pw->id);
- goto Out;
- }
- mess = secureidcheck(pw->id, msg+3);
- if(mess != nil){
- syslog(0, LOG, "secureidcheck denied %s because %s", pw->id, mess);
- goto Out;
- }
- }
- conn->write(conn, (uchar*)"OK", 2);
- syslog(0, LOG, "AUTH %s", pw->id);
-
- // perform operations as asked
- while((n = readstr(conn, msg)) > 0){
- syslog(0, LOG, "[%s] %s", pw->id, msg);
-
- if(strncmp(msg, "GET ", 4) == 0){
- file = validatefile(msg+4);
- if(file==nil || getfile(conn, pw->id, file) < 0)
- goto Err;
-
- }else if(strncmp(msg, "PUT ", 4) == 0){
- file = validatefile(msg+4);
- if(file==nil || putfile(conn, pw->id, file) < 0){
- syslog(0, LOG, "failed PUT %s/%s", pw->id, file);
- goto Err;
- }
-
- }else if(strncmp(msg, "RM ", 3) == 0){
- file = validatefile(msg+3);
- if(file==nil || removefile(conn, pw->id, file) < 0){
- syslog(0, LOG, "failed RM %s/%s", pw->id, file);
- goto Err;
- }
-
- }else if(strncmp(msg, "CHPASS", 6) == 0){
- if(readstr(conn, msg) < 0){
- syslog(0, LOG, "protocol botch CHPASS for %s", pw->id);
- writerr(conn, "protocol botch while setting PAK");
- goto Out;
- }
- pw->Hi = strtomp(msg, nil, 64, pw->Hi);
- for(i=0; i < 4 && putPW(pw) < 0; i++)
- syslog(0, LOG, "password change failed for %s (%d): %r", pw->id, i);
- if(i==4)
- goto Out;
-
- }else if(strncmp(msg, "BYE", 3) == 0){
- rv = 0;
- break;
-
- }else{
- writerr(conn, "unrecognized operation");
- break;
- }
-
- }
- if(n <= 0)
- syslog(0, LOG, "%s closed connection without saying goodbye\n", pw->id);
-
-Out:
- freePW(pw);
- conn->free(conn);
- return rv;
-Err:
- writerr(conn, "operation failed");
- goto Out;
-}
-
-void
-main(int argc, char **argv)
-{
- int afd, dfd, lcfd, forceSTA = 0;
- char adir[40], ldir[40], *remote;
- char *serve = "tcp!*!5356", *p, aserve[128];
- char *S = "secstore";
- char *dbpath;
- Ndb *db2;
-
- S = sysname();
- SECSTORE_DIR = unsharp("#9/secstore");
-// setnetmtpt(net, sizeof(net), nil);
- ARGBEGIN{
- case 'R':
- forceSTA = 1;
- break;
- case 's':
- serve = EARGF(usage());
- break;
- case 'S':
- S = EARGF(usage());
- break;
- case 'x':
- p = ARGF();
- if(p == nil)
- usage();
- USED(p);
- // setnetmtpt(net, sizeof(net), p);
- break;
- case 'v':
- verbose++;
- break;
- default:
- usage();
- }ARGEND;
-
- if(!verbose)
- switch(rfork(RFNOTEG|RFPROC|RFFDG)) {
- case -1:
- sysfatal("fork: %r");
- case 0:
- break;
- default:
- exits(0);
- }
-
- snprint(aserve, sizeof aserve, "%s", serve);
- afd = announce(aserve, adir);
- if(afd < 0)
- sysfatal("%s: %r\n", aserve);
- syslog(0, LOG, "ANNOUNCE %s", aserve);
- for(;;){
- if((lcfd = listen(adir, ldir)) < 0)
- exits("can't listen");
- switch(fork()){
- case -1:
- fprint(2, "secstore forking: %r\n");
- close(lcfd);
- break;
- case 0:
- // "/lib/ndb/common.radius does not exist" if db set before fork
- db = ndbopen(dbpath=unsharp("#9/ndb/auth"));
- if(db == 0)
- syslog(0, LOG, "no ndb/auth");
- db2 = ndbopen(0);
- if(db2 == 0)
- syslog(0, LOG, "no ndb/local");
- db = ndbcat(db, db2);
- if((dfd = accept(lcfd, ldir)) < 0)
- exits("can't accept");
- alarm(30*60*1000); // 30 min
- remote = remoteIP(ldir);
- syslog(0, LOG, "secstore from %s", remote);
- free(remote);
- dologin(dfd, S, forceSTA);
- exits(nil);
- default:
- close(lcfd);
- break;
- }
- }
-}
-
diff --git a/src/cmd/secstore/secureidcheck.c b/src/cmd/secstore/secureidcheck.c
deleted file mode 100644
index 95adb385..00000000
--- a/src/cmd/secstore/secureidcheck.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* RFC2138 */
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-#include <ctype.h>
-#include <mp.h>
-#include <libsec.h>
-#include <bio.h>
-#include <ndb.h>
-#define AUTHLOG "auth"
-
-enum{ R_AccessRequest=1, /* Packet code */
- R_AccessAccept=2,
- R_AccessReject=3,
- R_AccessChallenge=11,
- R_UserName=1,
- R_UserPassword=2,
- R_NASIPAddress=4,
- R_ReplyMessage=18,
- R_State=24,
- R_NASIdentifier=32
-};
-
-typedef struct Secret{
- uchar *s;
- int len;
-} Secret;
-
-typedef struct Attribute{
- struct Attribute *next;
- uchar type;
- uchar len; // number of bytes in value
- uchar val[256];
-} Attribute;
-
-typedef struct Packet{
- uchar code, ID;
- uchar authenticator[16];
- Attribute first;
-} Packet;
-
-// assumes pass is at most 16 chars
-void
-hide(Secret *shared, uchar *auth, Secret *pass, uchar *x)
-{
- DigestState *M;
- int i, n = pass->len;
-
- M = md5(shared->s, shared->len, nil, nil);
- md5(auth, 16, x, M);
- if(n > 16)
- n = 16;
- for(i = 0; i < n; i++)
- x[i] ^= (pass->s)[i];
-}
-
-int
-authcmp(Secret *shared, uchar *buf, int m, uchar *auth)
-{
- DigestState *M;
- uchar x[16];
-
- M = md5(buf, 4, nil, nil); // Code+ID+Length
- M = md5(auth, 16, nil, M); // RequestAuth
- M = md5(buf+20, m-20, nil, M); // Attributes
- md5(shared->s, shared->len, x, M);
- return memcmp(x, buf+4, 16);
-}
-
-Packet*
-newRequest(uchar *auth)
-{
- static uchar ID = 0;
- Packet *p;
-
- p = (Packet*)malloc(sizeof(*p));
- if(p == nil)
- return nil;
- p->code = R_AccessRequest;
- p->ID = ++ID;
- memmove(p->authenticator, auth, 16);
- p->first.next = nil;
- p->first.type = 0;
- return p;
-}
-
-void
-freePacket(Packet *p)
-{
- Attribute *a, *x;
-
- if(!p)
- return;
- a = p->first.next;
- while(a){
- x = a;
- a = a->next;
- free(x);
- }
- free(p);
-}
-
-int
-ding(void *v, char *msg)
-{
- USED(v);
-/* syslog(0, AUTHLOG, "ding %s", msg); */
- if(strstr(msg, "alarm"))
- return 1;
- return 0;
-}
-
-Packet *
-rpc(char *dest, Secret *shared, Packet *req)
-{
- uchar buf[4096], buf2[4096], *b, *e;
- Packet *resp;
- Attribute *a;
- int m, n, fd, try;
-
- // marshal request
- e = buf + sizeof buf;
- buf[0] = req->code;
- buf[1] = req->ID;
- memmove(buf+4, req->authenticator, 16);
- b = buf+20;
- for(a = &req->first; a; a = a->next){
- if(b + 2 + a->len > e)
- return nil;
- *b++ = a->type;
- *b++ = 2 + a->len;
- memmove(b, a->val, a->len);
- b += a->len;
- }
- n = b-buf;
- buf[2] = n>>8;
- buf[3] = n;
-
- // send request, wait for reply
- fd = dial(dest, 0, 0, 0);
- if(fd < 0){
- syslog(0, AUTHLOG, "%s: rpc can't get udp channel", dest);
- return nil;
- }
- atnotify(ding, 1);
- m = -1;
- for(try = 0; try < 2; try++){
- alarm(4000);
- m = write(fd, buf, n);
- if(m != n){
- syslog(0, AUTHLOG, "%s: rpc write err %d %d: %r", dest, m, n);
- m = -1;
- break;
- }
- m = read(fd, buf2, sizeof buf2);
- alarm(0);
- if(m < 0){
- syslog(0, AUTHLOG, "%s rpc read err %d: %r", dest, m);
- break; // failure
- }
- if(m == 0 || buf2[1] != buf[1]){ // need matching ID
- syslog(0, AUTHLOG, "%s unmatched reply %d", dest, m);
- continue;
- }
- if(authcmp(shared, buf2, m, buf+4) == 0)
- break;
- syslog(0, AUTHLOG, "%s bad rpc chksum", dest);
- }
- close(fd);
- if(m <= 0)
- return nil;
-
- // unmarshal reply
- b = buf2;
- e = buf2+m;
- resp = (Packet*)malloc(sizeof(*resp));
- if(resp == nil)
- return nil;
- resp->code = *b++;
- resp->ID = *b++;
- n = *b++;
- n = (n<<8) | *b++;
- if(m != n){
- syslog(0, AUTHLOG, "rpc got %d bytes, length said %d", m, n);
- if(m > n)
- e = buf2+n;
- }
- memmove(resp->authenticator, b, 16);
- b += 16;
- a = &resp->first;
- a->type = 0;
- while(1){
- if(b >= e){
- a->next = nil;
- break; // exit loop
- }
- a->type = *b++;
- a->len = (*b++) - 2;
- if(b + a->len > e){ // corrupt packet
- a->next = nil;
- freePacket(resp);
- return nil;
- }
- memmove(a->val, b, a->len);
- b += a->len;
- if(b < e){ // any more attributes?
- a->next = (Attribute*)malloc(sizeof(*a));
- if(a->next == nil){
- free(req);
- return nil;
- }
- a = a->next;
- }
- }
- return resp;
-}
-
-int
-setAttribute(Packet *p, uchar type, uchar *s, int n)
-{
- Attribute *a;
-
- a = &p->first;
- if(a->type != 0){
- a = (Attribute*)malloc(sizeof(*a));
- if(a == nil)
- return -1;
- a->next = p->first.next;
- p->first.next = a;
- }
- a->type = type;
- a->len = n;
- if(a->len > 253 ) // RFC2138, section 5
- a->len = 253;
- memmove(a->val, s, a->len);
- return 0;
-}
-
-/* return a reply message attribute string */
-char*
-replymsg(Packet *p)
-{
- Attribute *a;
- static char buf[255];
-
- for(a = &p->first; a; a = a->next){
- if(a->type == R_ReplyMessage){
- if(a->len >= sizeof buf)
- a->len = sizeof(buf)-1;
- memmove(buf, a->val, a->len);
- buf[a->len] = 0;
- }
- }
- return buf;
-}
-
-/* for convenience while debugging */
-char *replymess;
-Attribute *stateattr;
-
-void
-logPacket(Packet *p)
-{
- Attribute *a;
- char buf[255];
- char pbuf[4*1024];
- uchar *au = p->authenticator;
- int i;
- char *np, *e;
-
- e = pbuf + sizeof(pbuf);
-
- np = seprint(pbuf, e, "Packet ID=%d auth=%x %x %x... ", p->ID, au[0], au[1], au[2]);
- switch(p->code){
- case R_AccessRequest:
- np = seprint(np, e, "request\n");
- break;
- case R_AccessAccept:
- np = seprint(np, e, "accept\n");
- break;
- case R_AccessReject:
- np = seprint(np, e, "reject\n");
- break;
- case R_AccessChallenge:
- np = seprint(np, e, "challenge\n");
- break;
- default:
- np = seprint(np, e, "code=%d\n", p->code);
- break;
- }
- replymess = "0000000";
- for(a = &p->first; a; a = a->next){
- if(a->len > 253 )
- a->len = 253;
- memmove(buf, a->val, a->len);
- np = seprint(np, e, " [%d]", a->type);
- for(i = 0; i<a->len; i++)
- if(isprint(a->val[i]))
- np = seprint(np, e, "%c", a->val[i]);
- else
- np = seprint(np, e, "\\%o", a->val[i]);
- np = seprint(np, e, "\n");
- buf[a->len] = 0;
- if(a->type == R_ReplyMessage)
- replymess = strdup(buf);
- else if(a->type == R_State)
- stateattr = a;
- }
-
- syslog(0, AUTHLOG, "%s", pbuf);
-}
-
-static uchar*
-getipv4addr(void)
-{
- Ipifc *nifc;
- Iplifc *lifc;
- static Ipifc *ifc;
-
- ifc = readipifc("/net", ifc, -1);
- for(nifc = ifc; nifc; nifc = nifc->next)
- for(lifc = nifc->lifc; lifc; lifc = lifc->next)
- if(ipcmp(lifc->ip, IPnoaddr) != 0 && ipcmp(lifc->ip, v4prefix) != 0)
- return lifc->ip;
- return nil;
-}
-
-extern Ndb *db;
-
-/* returns 0 on success, error message on failure */
-char*
-secureidcheck(char *user, char *response)
-{
- Packet *req = nil, *resp = nil;
- ulong u[4];
- uchar x[16];
- char *radiussecret;
- char ruser[ 64];
- char dest[3*IPaddrlen+20];
- Secret shared, pass;
- char *rv = "authentication failed";
- Ndbs s;
- Ndbtuple *t, *nt, *tt;
- uchar *ip;
- static Ndb *netdb;
-
- if(netdb == nil)
- netdb = ndbopen(0);
-
- /* bad responses make them disable the fob, avoid silly checks */
- if(strlen(response) < 4 || strpbrk(response,"abcdefABCDEF") != nil)
- goto out;
-
- /* get radius secret */
- radiussecret = ndbgetvalue(db, &s, "radius", "lra-radius", "secret", &t);
- if(radiussecret == nil){
- syslog(0, AUTHLOG, "secureidcheck: nil radius secret: %r");
- goto out;
- }
-
- /* translate user name if we have to */
- strcpy(ruser, user);
- for(nt = t; nt; nt = nt->entry){
- if(strcmp(nt->attr, "uid") == 0 && strcmp(nt->val, user) == 0)
- for(tt = nt->line; tt != nt; tt = tt->line)
- if(strcmp(tt->attr, "rid") == 0){
- strcpy(ruser, tt->val);
- break;
- }
- }
- ndbfree(t);
-
- u[0] = fastrand();
- u[1] = fastrand();
- u[2] = fastrand();
- u[3] = fastrand();
- req = newRequest((uchar*)u);
- if(req == nil)
- goto out;
- shared.s = (uchar*)radiussecret;
- shared.len = strlen(radiussecret);
- ip = getipv4addr();
- if(ip == nil){
- syslog(0, AUTHLOG, "no interfaces: %r\n");
- goto out;
- }
- if(setAttribute(req, R_NASIPAddress, ip + IPv4off, 4) < 0)
- goto out;
-
- if(setAttribute(req, R_UserName, (uchar*)ruser, strlen(ruser)) < 0)
- goto out;
- pass.s = (uchar*)response;
- pass.len = strlen(response);
- hide(&shared, req->authenticator, &pass, x);
- if(setAttribute(req, R_UserPassword, x, 16) < 0)
- goto out;
-
- t = ndbsearch(netdb, &s, "sys", "lra-radius");
- if(t == nil){
- syslog(0, AUTHLOG, "secureidcheck: nil radius sys search: %r\n");
- goto out;
- }
- for(nt = t; nt; nt = nt->entry){
- if(strcmp(nt->attr, "ip") != 0)
- continue;
-
- snprint(dest,sizeof dest,"udp!%s!oradius", nt->val);
- resp = rpc(dest, &shared, req);
- if(resp == nil){
- syslog(0, AUTHLOG, "%s nil response", dest);
- continue;
- }
- if(resp->ID != req->ID){
- syslog(0, AUTHLOG, "%s mismatched ID req=%d resp=%d",
- dest, req->ID, resp->ID);
- freePacket(resp);
- resp = nil;
- continue;
- }
-
- switch(resp->code){
- case R_AccessAccept:
- syslog(0, AUTHLOG, "%s accepted ruser=%s", dest, ruser);
- rv = nil;
- break;
- case R_AccessReject:
- syslog(0, AUTHLOG, "%s rejected ruser=%s %s", dest, ruser, replymsg(resp));
- rv = "secureid failed";
- break;
- case R_AccessChallenge:
- syslog(0, AUTHLOG, "%s challenge ruser=%s %s", dest, ruser, replymsg(resp));
- rv = "secureid out of sync";
- break;
- default:
- syslog(0, AUTHLOG, "%s code=%d ruser=%s %s", dest, resp->code, ruser, replymsg(resp));
- break;
- }
- break; // we have a proper reply, no need to ask again
- }
- ndbfree(t);
- free(radiussecret);
-out:
- freePacket(req);
- freePacket(resp);
- return rv;
-}
diff --git a/src/cmd/secstore/secuser.c b/src/cmd/secstore/secuser.c
deleted file mode 100644
index 31ba184b..00000000
--- a/src/cmd/secstore/secuser.c
+++ /dev/null
@@ -1,244 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-int verbose;
-
-static void userinput(char *, int);
-char *SECSTORE_DIR;
-
-static void
-ensure_exists(char *f, ulong perm)
-{
- int fd;
-
- if(access(f, AEXIST) >= 0)
- return;
- if(verbose)
- fprint(2,"first time setup for secstore: create %s %lo\n", f, perm);
- fd = create(f, OREAD, perm);
- if(fd < 0){
- fprint(2, "unable to create %s\n", f);
- exits("secstored directories");
- }
- close(fd);
-}
-
-
-int
-main(int argc, char **argv)
-{
- int isnew;
- char *id, buf[Maxmsg], home[Maxmsg], prompt[100], *hexHi;
- char *pass, *passck;
- long expsecs;
- mpint *H = mpnew(0), *Hi = mpnew(0);
- PW *pw;
- Tm *tm;
-
- SECSTORE_DIR = unsharp("#9/secstore");
-
- ARGBEGIN{
- case 'v':
- verbose++;
- break;
- }ARGEND;
- if(argc!=1){
- print("usage: secuser [-v] <user>\n");
- exits("usage");
- }
-
- ensure_exists(SECSTORE_DIR, DMDIR|0755L);
- snprint(home, sizeof(home), "%s/who", SECSTORE_DIR);
- ensure_exists(home, DMDIR|0755L);
- snprint(home, sizeof(home), "%s/store", SECSTORE_DIR);
- ensure_exists(home, DMDIR|0700L);
-
- id = argv[0];
- if(verbose)
- fprint(2,"secuser %s\n", id);
- if((pw = getPW(id,1)) == nil){
- isnew = 1;
- print("new account (because %s/%s %r)\n", SECSTORE_DIR, id);
- pw = emalloc(sizeof(*pw));
- pw->id = estrdup(id);
- snprint(home, sizeof(home), "%s/store/%s", SECSTORE_DIR, id);
- if(access(home, AEXIST) == 0){
- print("new user, but directory %s already exists\n", home);
- exits(home);
- }
- }else{
- isnew = 0;
- }
-
- /* get main password for id */
- for(;;){
- if(isnew)
- snprint(prompt, sizeof(prompt), "%s password", id);
- else
- snprint(prompt, sizeof(prompt), "%s password [default = don't change]", id);
- pass = readcons(prompt, nil, 1);
- if(pass == nil){
- print("getpass failed\n");
- exits("getpass failed");
- }
- if(verbose)
- print("%ld characters\n", strlen(pass));
- if(pass[0] == '\0' && isnew == 0)
- break;
- if(strlen(pass) >= 7)
- break;
- print("password must be at least 7 characters\n");
- }
-
- if(pass[0] != '\0'){
- snprint(prompt, sizeof(prompt), "retype password");
- if(verbose)
- print("confirming...\n");
- passck = readcons(prompt, nil, 1);
- if(passck == nil){
- print("getpass failed\n");
- exits("getpass failed");
- }
- if(strcmp(pass, passck) != 0){
- print("passwords didn't match\n");
- exits("no match");
- }
- memset(passck, 0, strlen(passck));
- free(passck);
- hexHi = PAK_Hi(id, pass, H, Hi);
- memset(pass, 0, strlen(pass));
- free(pass);
- free(hexHi);
- mpfree(H);
- pw->Hi = Hi;
- }
-
- /* get expiration time (midnight of date specified) */
- if(isnew)
- expsecs = time(0) + 365*24*60*60;
- else
- expsecs = pw->expire;
-
- for(;;){
- tm = localtime(expsecs);
- print("expires [DDMMYYYY, default = %2.2d%2.2d%4.4d]: ",
- tm->mday, tm->mon, tm->year+1900);
- userinput(buf, sizeof(buf));
- if(strlen(buf) == 0)
- break;
- if(strlen(buf) != 8){
- print("!bad date format: %s\n", buf);
- continue;
- }
- tm->mday = (buf[0]-'0')*10 + (buf[1]-'0');
- if(tm->mday > 31 || tm->mday < 1){
- print("!bad day of month: %d\n", tm->mday);
- continue;
- }
- tm->mon = (buf[2]-'0')*10 + (buf[3]-'0') - 1;
- if(tm->mon > 11 || tm->mday < 0){
- print("!bad month: %d\n", tm->mon + 1);
- continue;
- }
- tm->year = atoi(buf+4) - 1900;
- if(tm->year < 70){
- print("!bad year: %d\n", tm->year + 1900);
- continue;
- }
- tm->sec = 59;
- tm->min = 59;
- tm->hour = 23;
- tm->yday = 0;
- expsecs = tm2sec(tm);
- break;
- }
- pw->expire = expsecs;
-
- /* failed logins */
- if(pw->failed != 0 )
- print("clearing %d failed login attempts\n", pw->failed);
- pw->failed = 0;
-
- /* status bits */
- if(isnew)
- pw->status = Enabled;
- for(;;){
- print("Enabled or Disabled [default %s]: ",
- (pw->status & Enabled) ? "Enabled" : "Disabled" );
- userinput(buf, sizeof(buf));
- if(strlen(buf) == 0)
- break;
- if(buf[0]=='E' || buf[0]=='e'){
- pw->status |= Enabled;
- break;
- }
- if(buf[0]=='D' || buf[0]=='d'){
- pw->status = pw->status & ~Enabled;
- break;
- }
- }
- for(;;){
- print("require STA? [default %s]: ",
- (pw->status & STA) ? "yes" : "no" );
- userinput(buf, sizeof(buf));
- if(strlen(buf) == 0)
- break;
- if(buf[0]=='Y' || buf[0]=='y'){
- pw->status |= STA;
- break;
- }
- if(buf[0]=='N' || buf[0]=='n'){
- pw->status = pw->status & ~STA;
- break;
- }
- }
-
- /* free form field */
- if(isnew)
- pw->other = nil;
- print("comments [default = %s]: ", (pw->other == nil) ? "" : pw->other);
- userinput(buf, 72); /* 72 comes from password.h */
- if(buf[0])
- if((pw->other = strdup(buf)) == nil)
- sysfatal("strdup");
-
- syslog(0, LOG, "CHANGELOGIN for '%s'", pw->id);
- if(putPW(pw) < 0){
- print("error writing entry: %r\n");
- exits("can't write password file");
- }else{
- print("change written\n");
- if(isnew && create(home, OREAD, DMDIR | 0775L) < 0){
- print("unable to create %s: %r\n", home);
- exits(home);
- }
- }
-
- exits("");
- return 1; /* keep other compilers happy */
-}
-
-
-static void
-userinput(char *buf, int blen)
-{
- int n;
-
- while(1){
- n = read(0, buf, blen);
- if(n<=0)
- exits("read error");
- if(buf[n-1]=='\n'){
- buf[n-1] = '\0';
- return;
- }
- buf += n; blen -= n;
- if(blen<=0)
- exits("input too large");
- }
-}
-
diff --git a/src/cmd/secstore/util.c b/src/cmd/secstore/util.c
deleted file mode 100644
index ebbb12df..00000000
--- a/src/cmd/secstore/util.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <u.h>
-#include <libc.h>
-
-void *
-emalloc(ulong n)
-{
- void *p = malloc(n);
- if(p == nil)
- sysfatal("emalloc");
- memset(p, 0, n);
- return p;
-}
-
-void *
-erealloc(void *p, ulong n)
-{
- if ((p = realloc(p, n)) == nil)
- sysfatal("erealloc");
- return p;
-}
-
-char *
-estrdup(char *s)
-{
- if ((s = strdup(s)) == nil)
- sysfatal("estrdup");
- return s;
-}