Browse Source

Plan 9 from Bell Labs 2003-08-31

David du Colombier 20 years ago
parent
commit
2da3ff1792

+ 10 - 10
dist/replica/plan9.db

@@ -76,9 +76,9 @@
 386/bin/auth/rsafill - 775 sys sys 1057955567 142267
 386/bin/auth/rsafill - 775 sys sys 1057955567 142267
 386/bin/auth/rsagen - 775 sys sys 1057955567 152977
 386/bin/auth/rsagen - 775 sys sys 1057955567 152977
 386/bin/auth/secretpem - 775 sys sys 1045537944 118526
 386/bin/auth/secretpem - 775 sys sys 1045537944 118526
-386/bin/auth/secstore - 775 sys sys 1056364186 187992
-386/bin/auth/secstored - 775 sys sys 1056364187 194114
-386/bin/auth/secuser - 775 sys sys 1056364188 150569
+386/bin/auth/secstore - 775 sys sys 1062277697 188052
+386/bin/auth/secstored - 775 sys sys 1062277702 193922
+386/bin/auth/secuser - 775 sys sys 1062277712 151114
 386/bin/auth/status - 775 sys sys 1020319060 738
 386/bin/auth/status - 775 sys sys 1020319060 738
 386/bin/auth/uniq - 775 sys sys 1056364188 61793
 386/bin/auth/uniq - 775 sys sys 1056364188 61793
 386/bin/auth/warning - 775 sys sys 1056364189 98089
 386/bin/auth/warning - 775 sys sys 1056364189 98089
@@ -4949,7 +4949,7 @@ sys/man/8/replica - 664 sys sys 1021579979 6239
 sys/man/8/rsa - 664 sys sys 1057955511 4628
 sys/man/8/rsa - 664 sys sys 1057955511 4628
 sys/man/8/scanmail - 664 sys sys 969499895 10803
 sys/man/8/scanmail - 664 sys sys 969499895 10803
 sys/man/8/scuzz - 664 sys sys 984709640 7916
 sys/man/8/scuzz - 664 sys sys 984709640 7916
-sys/man/8/secstore - 664 sys sys 1045501623 990
+sys/man/8/secstore - 664 sys sys 1062291170 1159
 sys/man/8/securenet - 664 sys sys 954305552 3160
 sys/man/8/securenet - 664 sys sys 954305552 3160
 sys/man/8/send - 664 sys sys 1045501634 2168
 sys/man/8/send - 664 sys sys 1045501634 2168
 sys/man/8/smtp - 664 sys sys 1049408388 4111
 sys/man/8/smtp - 664 sys sys 1049408388 4111
@@ -6716,15 +6716,15 @@ sys/src/cmd/auth/secstore - 20000000775 sys sys 1017337838 0
 sys/src/cmd/auth/secstore/SConn.c - 664 sys sys 1041890053 4381
 sys/src/cmd/auth/secstore/SConn.c - 664 sys sys 1041890053 4381
 sys/src/cmd/auth/secstore/SConn.h - 664 sys sys 1015008431 955
 sys/src/cmd/auth/secstore/SConn.h - 664 sys sys 1015008431 955
 sys/src/cmd/auth/secstore/aescbc.c - 664 sys sys 1045504879 3920
 sys/src/cmd/auth/secstore/aescbc.c - 664 sys sys 1045504879 3920
-sys/src/cmd/auth/secstore/dirls.c - 664 sys sys 1015008431 2106
+sys/src/cmd/auth/secstore/dirls.c - 664 sys sys 1062277640 1842
 sys/src/cmd/auth/secstore/mkfile - 664 sys sys 1048615193 844
 sys/src/cmd/auth/secstore/mkfile - 664 sys sys 1048615193 844
-sys/src/cmd/auth/secstore/pak.c - 664 sys sys 1041890053 9353
-sys/src/cmd/auth/secstore/password.c - 664 sys sys 1041890053 2698
+sys/src/cmd/auth/secstore/pak.c - 664 sys sys 1062277640 9297
+sys/src/cmd/auth/secstore/password.c - 664 sys sys 1062277640 2770
 sys/src/cmd/auth/secstore/secacct.c - 644 sys sys 1015008431 755
 sys/src/cmd/auth/secstore/secacct.c - 644 sys sys 1015008431 755
 sys/src/cmd/auth/secstore/secchk.c - 664 sys sys 1055698993 560
 sys/src/cmd/auth/secstore/secchk.c - 664 sys sys 1055698993 560
-sys/src/cmd/auth/secstore/secstore.c - 664 sys sys 1041890054 12213
+sys/src/cmd/auth/secstore/secstore.c - 664 sys sys 1062277640 12269
 sys/src/cmd/auth/secstore/secstore.h - 664 sys sys 1041890053 841
 sys/src/cmd/auth/secstore/secstore.h - 664 sys sys 1041890053 841
-sys/src/cmd/auth/secstore/secstored.c - 664 sys sys 1034734162 8089
+sys/src/cmd/auth/secstore/secstored.c - 664 sys sys 1062277641 7952
 sys/src/cmd/auth/secstore/secuser.c - 664 sys sys 1061842567 4914
 sys/src/cmd/auth/secstore/secuser.c - 664 sys sys 1061842567 4914
 sys/src/cmd/auth/secstore/util.c - 664 sys sys 1021579985 1498
 sys/src/cmd/auth/secstore/util.c - 664 sys sys 1021579985 1498
 sys/src/cmd/auth/secureidcheck.c - 664 sys sys 1045504896 8973
 sys/src/cmd/auth/secureidcheck.c - 664 sys sys 1045504896 8973
@@ -9154,7 +9154,7 @@ sys/src/cmd/ip/httpd/sendfd.c - 664 sys sys 1017679317 12134
 sys/src/cmd/ip/httpd/wikipost.c - 664 sys sys 1019678647 5917
 sys/src/cmd/ip/httpd/wikipost.c - 664 sys sys 1019678647 5917
 sys/src/cmd/ip/imap4d - 20000000775 sys sys 988249981 0
 sys/src/cmd/ip/imap4d - 20000000775 sys sys 988249981 0
 sys/src/cmd/ip/imap4d/auth.c - 664 sys sys 1015013075 3510
 sys/src/cmd/ip/imap4d/auth.c - 664 sys sys 1015013075 3510
-sys/src/cmd/ip/imap4d/copy.c - 664 sys sys 1015013075 4584
+sys/src/cmd/ip/imap4d/copy.c - 664 sys sys 1062298855 4597
 sys/src/cmd/ip/imap4d/csquery.c - 664 sys sys 1015013076 762
 sys/src/cmd/ip/imap4d/csquery.c - 664 sys sys 1015013076 762
 sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1045505209 5668
 sys/src/cmd/ip/imap4d/date.c - 664 sys sys 1045505209 5668
 sys/src/cmd/ip/imap4d/debug.c - 664 sys sys 1016731557 1962
 sys/src/cmd/ip/imap4d/debug.c - 664 sys sys 1016731557 1962

+ 10 - 0
dist/replica/plan9.log

@@ -13103,3 +13103,13 @@
 1062180110 17 c sys/src/cmd/upas/ned/nedmail.c - 664 sys sys 1062073146 42984
 1062180110 17 c sys/src/cmd/upas/ned/nedmail.c - 664 sys sys 1062073146 42984
 1062180110 18 c sys/src/cmd/fossil/9proc.c - 664 sys sys 1062009435 15239
 1062180110 18 c sys/src/cmd/fossil/9proc.c - 664 sys sys 1062009435 15239
 1062180110 19 c sys/src/libc/9syscall/sys.h - 664 sys sys 1062076905 896
 1062180110 19 c sys/src/libc/9syscall/sys.h - 664 sys sys 1062076905 896
+1062279084 0 c 386/bin/auth/secstore - 775 sys sys 1062277697 188052
+1062279084 1 c 386/bin/auth/secstored - 775 sys sys 1062277702 193922
+1062279084 2 c 386/bin/auth/secuser - 775 sys sys 1062277712 151114
+1062279084 3 c sys/src/cmd/auth/secstore/dirls.c - 664 sys sys 1062277640 1842
+1062279084 4 c sys/src/cmd/auth/secstore/pak.c - 664 sys sys 1062277640 9297
+1062279084 5 c sys/src/cmd/auth/secstore/password.c - 664 sys sys 1062277640 2770
+1062279084 6 c sys/src/cmd/auth/secstore/secstore.c - 664 sys sys 1062277640 12269
+1062279084 7 c sys/src/cmd/auth/secstore/secstored.c - 664 sys sys 1062277641 7952
+1062291689 0 c sys/man/8/secstore - 664 sys sys 1062291170 1159
+1062298899 0 c sys/src/cmd/ip/imap4d/copy.c - 664 sys sys 1062298855 4597

+ 9 - 0
sys/man/8/secstore

@@ -9,6 +9,7 @@ secstored, secuser \- secstore commands
 [-x]
 [-x]
 .br
 .br
 .B auth/secuser
 .B auth/secuser
+[-v]
 username
 username
 .br
 .br
 .PP
 .PP
@@ -36,6 +37,14 @@ The
 .B /adm/secstore
 .B /adm/secstore
 directory should be created mode 770 for the userid
 directory should be created mode 770 for the userid
 or groupid of the secstored process.
 or groupid of the secstored process.
+.PP
+By default,
+.I secstored
+warns the client if no account exists.
+If you prefer to obscure this information, use
+.I secuser
+to create an account
+.BR FICTITIOUS .
 .SH FILES
 .SH FILES
 .B /adm/secstore/who/$uid
 .B /adm/secstore/who/$uid
 secstore account name, expiration date, verifier
 secstore account name, expiration date, verifier

+ 1 - 20
sys/src/cmd/auth/secstore/dirls.c

@@ -81,26 +81,7 @@ dirls(char *path)
 		list = erealloc(list, len+n+1);
 		list = erealloc(list, len+n+1);
 		len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
 		len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
 	}
 	}
+	free(dirbuf);
 	return list;
 	return list;
 }
 }
 
 
-#ifdef NOTDEF
-char *dirls(char *);
-void
-main(int argc, char *argv[])
-{
-	int i;
-	char *s;
-
-	for(i=1; i<argc; i++){
-		if((s = dirls(argv[i])) == nil)
-			sysfatal("dirls: %r");
-		write(1, s, strlen(s));
-		if(i != (argc-1))
-			write(1, "\n", 1);
-		free(s);
-	}
-
-	exits(nil);
-}
-#endif

+ 7 - 7
sys/src/cmd/auth/secstore/pak.c

@@ -190,7 +190,7 @@ PAKclient(SConn *conn, char *C, char *pass, char **pS)
 	memset(hexsigma, 0, strlen(hexsigma));
 	memset(hexsigma, 0, strlen(hexsigma));
 	n = conn->secret(conn, digest, 0);
 	n = conn->secret(conn, digest, 0);
 	memset(digest, 0, SHA1dlen);
 	memset(digest, 0, SHA1dlen);
-	if(n < 0){//assert
+	if(n < 0){
 		writerr(conn, "can't set secret");
 		writerr(conn, "can't set secret");
 		goto done;
 		goto done;
 	}
 	}
@@ -239,7 +239,7 @@ PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
 
 
 	// parse first message into C, m
 	// parse first message into C, m
 	eol = strchr(mess, '\n');
 	eol = strchr(mess, '\n');
-	if(strncmp("C=", mess, 2) != 0 || !eol){//assert
+	if(strncmp("C=", mess, 2) != 0 || !eol){
 		fprint(2,"mess[1]=%s\n", mess);
 		fprint(2,"mess[1]=%s\n", mess);
 		writerr(conn, "PAK version mismatch");
 		writerr(conn, "PAK version mismatch");
 		goto done;
 		goto done;
@@ -248,7 +248,7 @@ PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
 	*eol = 0;
 	*eol = 0;
 	hexm = eol+3;
 	hexm = eol+3;
 	eol = strchr(hexm, '\n');
 	eol = strchr(hexm, '\n');
-	if(strncmp("m=", hexm-2, 2) != 0 || !eol){//assert
+	if(strncmp("m=", hexm-2, 2) != 0 || !eol){
 		writerr(conn, "PAK version mismatch");
 		writerr(conn, "PAK version mismatch");
 		goto done;
 		goto done;
 	}
 	}
@@ -273,7 +273,7 @@ PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
 	// random y, mu=g**y, sigma=g**xy
 	// random y, mu=g**y, sigma=g**xy
 	y = mprand(240, genrandom, nil);
 	y = mprand(240, genrandom, nil);
 	mpmod(y, pak->q, y);
 	mpmod(y, pak->q, y);
-	if(mpcmp(y, mpzero) == 0){//assert
+	if(mpcmp(y, mpzero) == 0){
 		mpassign(mpone, y);
 		mpassign(mpone, y);
 	}
 	}
 	mpexp(pak->g, y, pak->p, mu);
 	mpexp(pak->g, y, pak->p, mu);
@@ -290,12 +290,12 @@ PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
 	conn->write(conn, (uchar*)mess2, strlen(mess2));
 	conn->write(conn, (uchar*)mess2, strlen(mess2));
 
 
 	// recv hash2(g**xy)
 	// recv hash2(g**xy)
-	if(readstr(conn, mess2) < 0){//assert
+	if(readstr(conn, mess2) < 0){
 		writerr(conn, "couldn't read verifier");
 		writerr(conn, "couldn't read verifier");
 		goto done;
 		goto done;
 	}
 	}
 	eol = strchr(mess2, '\n');
 	eol = strchr(mess2, '\n');
-	if(strncmp("k'=", mess2, 3) != 0 || !eol){//assert
+	if(strncmp("k'=", mess2, 3) != 0 || !eol){
 		writerr(conn, "verifier syntax error");
 		writerr(conn, "verifier syntax error");
 		goto done;
 		goto done;
 	}
 	}
@@ -311,7 +311,7 @@ PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
 	// set session key
 	// set session key
 	shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
 	shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
 	n = conn->secret(conn, digest, 1);
 	n = conn->secret(conn, digest, 1);
-	if(n < 0){//assert
+	if(n < 0){
 		writerr(conn, "can't set secret");
 		writerr(conn, "can't set secret");
 		goto done;
 		goto done;
 	}
 	}

+ 5 - 2
sys/src/cmd/auth/secstore/password.c

@@ -45,8 +45,11 @@ getPW(char *id, int dead_or_alive)
 	char *f1, *f2; // fields 1, 2 = attribute, value
 	char *f1, *f2; // fields 1, 2 = attribute, value
 
 
 	if((bin = openPW(id, OREAD)) == 0){
 	if((bin = openPW(id, OREAD)) == 0){
-		werrstr("no such account");
-		return nil;
+		id = "FICTITIOUS";
+		if((bin = openPW(id, OREAD)) == 0){
+			werrstr("account does not exist");
+			return nil;
+		}
 	}
 	}
 	pw = emalloc(sizeof(*pw));
 	pw = emalloc(sizeof(*pw));
 	pw->id = estrdup(id);
 	pw->id = estrdup(id);

+ 7 - 3
sys/src/cmd/auth/secstore/secstore.c

@@ -50,11 +50,15 @@ getfile(SConn *conn, char *gf, uchar **buf, ulong *buflen, uchar *key, int nkey)
 		fprint(2, "remote: %s\n", s);
 		fprint(2, "remote: %s\n", s);
 		return -1;
 		return -1;
 	}
 	}
-	if((len = atoi(s)) < 0){
+	len = atoi(s);
+	if(len == -1){
 		fprint(2, "remote file %s does not exist\n", gf);
 		fprint(2, "remote file %s does not exist\n", gf);
 		return -1;
 		return -1;
-	}else if(len > MAXFILESIZE){//assert
-		fprint(2, "implausible filesize %d for %s\n", len, gf);
+	}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;
 		return -1;
 	}
 	}
 	if(buf != nil){
 	if(buf != nil){

+ 46 - 34
sys/src/cmd/auth/secstore/secstored.c

@@ -48,9 +48,26 @@ getdir(SConn *conn, char *id)
 		len -= n;
 		len -= n;
 	}
 	}
 	free(s);
 	free(s);
+	free(ls);
 	return 0;
 	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
 static int
 getfile(SConn *conn, char *id, char *gf)
 getfile(SConn *conn, char *id, char *gf)
 {
 {
@@ -61,11 +78,6 @@ getfile(SConn *conn, char *id, char *gf)
 		return getdir(conn, id);
 		return getdir(conn, id);
 
 
 	/* send file size */
 	/* send file size */
-	if(strchr(gf,'/') != nil || strcmp(gf,"..")==0){
-		syslog(0, LOG, "no slashes allowed: %s\n", gf);
-		conn->write(conn, (uchar*)"-2", 2);
-		return -1;
-	}
 	s = emalloc(Maxmsg);
 	s = emalloc(Maxmsg);
 	snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, gf);
 	snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, gf);
 	gd = open(s, OREAD);
 	gd = open(s, OREAD);
@@ -76,7 +88,7 @@ getfile(SConn *conn, char *id, char *gf)
 		return -1;
 		return -1;
 	}
 	}
 	len = seek(gd, 0, 2);
 	len = seek(gd, 0, 2);
-	if(len < 0 || len > MAXFILESIZE){//assert
+	if(len < 0 || len > MAXFILESIZE){
 		syslog(0, LOG, "implausible filesize %d for %s\n", len, gf);
 		syslog(0, LOG, "implausible filesize %d for %s\n", len, gf);
 		free(s);
 		free(s);
 		conn->write(conn, (uchar*)"-3", 2);
 		conn->write(conn, (uchar*)"-3", 2);
@@ -111,7 +123,7 @@ putfile(SConn *conn, char *id, char *pf)
 
 
 	/* get file size */
 	/* get file size */
 	n = readstr(conn, s);
 	n = readstr(conn, s);
-	if(n < 0){//assert
+	if(n < 0){
 		syslog(0, LOG, "remote: %s: %r\n", s);
 		syslog(0, LOG, "remote: %s: %r\n", s);
 		return -1;
 		return -1;
 	}
 	}
@@ -119,7 +131,7 @@ putfile(SConn *conn, char *id, char *pf)
 	if(len == -1){
 	if(len == -1){
 		syslog(0, LOG, "remote file %s does not exist\n", pf);
 		syslog(0, LOG, "remote file %s does not exist\n", pf);
 		return -1;
 		return -1;
-	}else if(len < 0 || len > MAXFILESIZE){//assert
+	}else if(len < 0 || len > MAXFILESIZE){
 		syslog(0, LOG, "implausible filesize %ld for %s\n", len, pf);
 		syslog(0, LOG, "implausible filesize %ld for %s\n", len, pf);
 		return -1;
 		return -1;
 	}
 	}
@@ -131,18 +143,18 @@ putfile(SConn *conn, char *id, char *pf)
 	}
 	}
 	snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, pf);
 	snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, pf);
 	pd = create(s, OWRITE, 0660);
 	pd = create(s, OWRITE, 0660);
-	if(pd < 0){//assert
+	if(pd < 0){
 		syslog(0, LOG, "can't open %s: %r\n", s);
 		syslog(0, LOG, "can't open %s: %r\n", s);
 		return -1;
 		return -1;
 	}
 	}
 	while(len > 0){
 	while(len > 0){
 		n = conn->read(conn, (uchar*)s, Maxmsg);
 		n = conn->read(conn, (uchar*)s, Maxmsg);
-		if(n <= 0){//assert
+		if(n <= 0){
 			syslog(0, LOG, "empty file chunk\n");
 			syslog(0, LOG, "empty file chunk\n");
 			return -1;
 			return -1;
 		}
 		}
 		nw = write(pd, s, n);
 		nw = write(pd, s, n);
-		if(nw != n){//assert
+		if(nw != n){
 			syslog(0, LOG, "write error on %s: %r", pf);
 			syslog(0, LOG, "write error on %s: %r", pf);
 			return -1;
 			return -1;
 		}
 		}
@@ -161,16 +173,18 @@ removefile(SConn *conn, char *id, char *f)
 
 
 	snprint(buf, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, f);
 	snprint(buf, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, f);
 
 
-	if((d =dirstat(buf)) == nil){
+	if((d = dirstat(buf)) == nil){
 		snprint(buf, sizeof buf, "remove failed: %r");
 		snprint(buf, sizeof buf, "remove failed: %r");
 		writerr(conn, buf);
 		writerr(conn, buf);
 		return -1;
 		return -1;
 	}else if(d->mode & DMDIR){
 	}else if(d->mode & DMDIR){
 		snprint(buf, sizeof buf, "can't remove a directory");
 		snprint(buf, sizeof buf, "can't remove a directory");
 		writerr(conn, buf);
 		writerr(conn, buf);
+		free(d);
 		return -1;
 		return -1;
 	}
 	}
 
 
+	free(d);
 	if(remove(buf) < 0){
 	if(remove(buf) < 0){
 		snprint(buf, sizeof buf, "remove failed: %r");
 		snprint(buf, sizeof buf, "remove failed: %r");
 		writerr(conn, buf);
 		writerr(conn, buf);
@@ -206,7 +220,7 @@ static int
 dologin(int fd, char *S, int forceSTA)
 dologin(int fd, char *S, int forceSTA)
 {
 {
 	int i, n, rv;
 	int i, n, rv;
-	char *file, *nl;
+	char *file;
 	char msg[Maxmsg+1];
 	char msg[Maxmsg+1];
 	PW *pw;
 	PW *pw;
 	SConn *conn;
 	SConn *conn;
@@ -245,32 +259,27 @@ dologin(int fd, char *S, int forceSTA)
 
 
 	// perform operations as asked
 	// perform operations as asked
 	while((n = readstr(conn, msg)) > 0){
 	while((n = readstr(conn, msg)) > 0){
+		syslog(0, LOG, "[%s] %s", pw->id, msg);
+
 		if(strncmp(msg, "GET ", 4) == 0){
 		if(strncmp(msg, "GET ", 4) == 0){
-			file = msg+4;
-			if(nl = strchr(file, '\n'))
-				*nl = 0;
-			if(getfile(conn, pw->id, file) < 0)
-				goto Out;
-			syslog(0, LOG, "GET %s/%s", pw->id, file);
+			file = validatefile(msg+4);
+			if(file==nil || getfile(conn, pw->id, file) < 0)
+				goto Err;
+
 		}else if(strncmp(msg, "PUT ", 4) == 0){
 		}else if(strncmp(msg, "PUT ", 4) == 0){
-			file = msg+4;
-			if(nl = strchr(file, '\n'))
-				*nl = 0;
-			if(putfile(conn, pw->id, file) < 0){
-				writerr(conn, "write error");
+			file = validatefile(msg+4);
+			if(file==nil || putfile(conn, pw->id, file) < 0){
 				syslog(0, LOG, "failed PUT %s/%s", pw->id, file);
 				syslog(0, LOG, "failed PUT %s/%s", pw->id, file);
-				goto Out;
+				goto Err;
 			}
 			}
-			syslog(0, LOG, "PUT %s/%s", pw->id, file);
+
 		}else if(strncmp(msg, "RM ", 3) == 0){
 		}else if(strncmp(msg, "RM ", 3) == 0){
-			file = msg + 3;
-			if(nl = strchr(file, '\n'))
-				*nl = 0;
-			if(removefile(conn, pw->id, file) < 0){
+			file = validatefile(msg+3);
+			if(file==nil || removefile(conn, pw->id, file) < 0){
 				syslog(0, LOG, "failed RM %s/%s", pw->id, file);
 				syslog(0, LOG, "failed RM %s/%s", pw->id, file);
-				goto Out;
+				goto Err;
 			}
 			}
-			syslog(0, LOG, "RM %s/%s", pw->id, file);
+
 		}else if(strncmp(msg, "CHPASS", 6) == 0){
 		}else if(strncmp(msg, "CHPASS", 6) == 0){
 			if(readstr(conn, msg) < 0){
 			if(readstr(conn, msg) < 0){
 				syslog(0, LOG, "protocol botch CHPASS for %s", pw->id);
 				syslog(0, LOG, "protocol botch CHPASS for %s", pw->id);
@@ -282,12 +291,12 @@ dologin(int fd, char *S, int forceSTA)
 				syslog(0, LOG, "password change failed for %s (%d): %r", pw->id, i);
 				syslog(0, LOG, "password change failed for %s (%d): %r", pw->id, i);
 			if(i==4)
 			if(i==4)
 				goto Out;
 				goto Out;
-			syslog(0, LOG, "CHPASS for '%s'", pw->id);
+
 		}else if(strncmp(msg, "BYE", 3) == 0){
 		}else if(strncmp(msg, "BYE", 3) == 0){
 			rv = 0;
 			rv = 0;
 			break;
 			break;
+
 		}else{
 		}else{
-			syslog(0, LOG, "unrecognized operation: %s\n", msg);
 			writerr(conn, "unrecognized operation");
 			writerr(conn, "unrecognized operation");
 			break;
 			break;
 		}
 		}
@@ -300,6 +309,9 @@ Out:
 	freePW(pw);
 	freePW(pw);
 	conn->free(conn);
 	conn->free(conn);
 	return rv;
 	return rv;
+Err:
+	writerr(conn, "operation failed");
+	goto Out;
 }
 }
 
 
 void
 void

+ 1 - 0
sys/src/cmd/ip/imap4d/copy.c

@@ -196,6 +196,7 @@ saveMsg(char *dst, char *digest, int flags, char *head, int nhead, Biobuf *b, lo
 		if(dstate != nil)
 		if(dstate != nil)
 			sha1(nil, 0, shadig, dstate);
 			sha1(nil, 0, shadig, dstate);
 		mbUnlock(ml);
 		mbUnlock(ml);
+		close(fd);
 		return 0;
 		return 0;
 	}
 	}
 	ok = 1;
 	ok = 1;