changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: wpa: cleanup, pad eap-ttls/pap password, zero passwords and key material after use

changeset 4227: c3f8bf355f2e
parent 4226: 76e57c8daa02
child 4228: fc8b053ff8a9
author: cinap_lenrek@felloff.net
date: Mon, 26 Jan 2015 01:26:42 +0100
files: sys/src/cmd/aux/wpa.c
description: wpa: cleanup, pad eap-ttls/pap password, zero passwords and key material after use
     1.1--- a/sys/src/cmd/aux/wpa.c
     1.2+++ b/sys/src/cmd/aux/wpa.c
     1.3@@ -446,14 +446,22 @@ int
     1.4 factotumctl(char *fmt, ...)
     1.5 {
     1.6 	va_list list;
     1.7-	int r, fd;
     1.8+	int fd, r, n;
     1.9+	char *s;
    1.10 
    1.11-	if((fd = open("/mnt/factotum/ctl", OWRITE)) < 0)
    1.12-		return -1;
    1.13-	va_start(list, fmt);
    1.14-	r = vfprint(fd, fmt, list);
    1.15-	va_end(list);
    1.16-	close(fd);
    1.17+	r = -1;
    1.18+	if((fd = open("/mnt/factotum/ctl", OWRITE)) >= 0){
    1.19+		va_start(list, fmt);
    1.20+		s = vsmprint(fmt, list);
    1.21+		va_end(list);
    1.22+		if(s != nil){
    1.23+			n = strlen(s);
    1.24+			r = write(fd, s, n);
    1.25+			memset(s, 0, n);
    1.26+			free(s);
    1.27+		}
    1.28+		close(fd);
    1.29+	}
    1.30 	return r;
    1.31 }
    1.32 
    1.33@@ -462,7 +470,7 @@ setpmk(uchar pmk[PMKlen])
    1.34 {
    1.35 	if(getessid() == nil)
    1.36 		return -1;
    1.37-	return factotumctl("key proto=wpapsk role=client essid=%q !password=%.32H\n", essid, pmk);
    1.38+	return factotumctl("key proto=wpapsk role=client essid=%q !password=%.*H\n", essid, PMKlen, pmk);
    1.39 }
    1.40 
    1.41 int
    1.42@@ -842,9 +850,10 @@ tlswrap(int fd, char *label)
    1.43 		tls->sessionKeylen = 128;
    1.44 		tls->sessionKey = emalloc(tls->sessionKeylen);
    1.45 	}
    1.46-	if((fd = tlsClient(fd, tls)) < 0)
    1.47+	fd = tlsClient(fd, tls);
    1.48+	if(fd < 0)
    1.49 		sysfatal("tlsClient: %r");
    1.50-	if(label != nil){
    1.51+	if(label != nil && tls->sessionKey != nil){
    1.52 		/*
    1.53 		 * PMK is derived from MSK by taking the first 256 bits.
    1.54 		 * we store the PMK into factotum with setpmk() associated
    1.55@@ -852,7 +861,14 @@ tlswrap(int fd, char *label)
    1.56 		 */
    1.57 		if(setpmk(tls->sessionKey) < 0)
    1.58 			sysfatal("setpmk: %r");
    1.59+
    1.60+		/* destroy session key */
    1.61+		memset(tls->sessionKey, 0, tls->sessionKeylen);
    1.62 	}
    1.63+	free(tls->cert);	/* TODO: check cert */
    1.64+	free(tls->sessionID);
    1.65+	free(tls->sessionKey);
    1.66+	free(tls);
    1.67 	return fd;
    1.68 }
    1.69 
    1.70@@ -874,12 +890,16 @@ eapreq(Eapconn *conn, int code, int id, 
    1.71 		eapreset(conn);
    1.72 		if(code == 4 || debug)
    1.73 			fprint(2, "%s: eap code %s\n", argv0, code == 3 ? "Success" : "NAK");
    1.74+		return;
    1.75 	default:
    1.76+	unhandled:
    1.77+		if(debug)
    1.78+			fprint(2, "unhandled: %.*H\n", datalen < 0 ? 0 : datalen, data);
    1.79 		return;
    1.80 	}
    1.81+	if(datalen < 1)
    1.82+		goto unhandled;
    1.83 
    1.84-	if(datalen < 1)
    1.85-		return;
    1.86 	tp = data[0];
    1.87 	switch(tp){
    1.88 	case 1:		/* Identity */
    1.89@@ -887,15 +907,15 @@ eapreq(Eapconn *conn, int code, int id, 
    1.90 		datalen = 1+strlen(user);
    1.91 		memmove(data+1, user, datalen-1);
    1.92 		eapresp(conn, 2, id, data, datalen);
    1.93-		break;
    1.94+		return;
    1.95 	case 2:
    1.96 		fprint(2, "%s: eap error: %.*s\n", argv0, datalen-1, (char*)data+1);
    1.97-		break;
    1.98+		return;
    1.99 	case 33:	/* EAP Extensions (AVP) */
   1.100 		if(debug)
   1.101 			fprint(2, "eap extension: %.*H\n", datalen, data);
   1.102 		eapresp(conn, 2, id, data, datalen);
   1.103-		break;
   1.104+		return;
   1.105 	case 26:	/* MS-CHAP-V2 */
   1.106 		data++;
   1.107 		datalen--;
   1.108@@ -936,6 +956,7 @@ eapreq(Eapconn *conn, int code, int id, 
   1.109 
   1.110 				*(--data) = tp, len++;
   1.111 				eapresp(conn, 2, id, data, len);
   1.112+				return;
   1.113 			}
   1.114 			break;
   1.115 
   1.116@@ -947,7 +968,7 @@ eapreq(Eapconn *conn, int code, int id, 
   1.117 					datalen < 4 ? 0 : datalen-4, (char*)data+4);
   1.118 			*(--data) = tp;
   1.119 			eapresp(conn, 2, id, data, 2);
   1.120-			break;
   1.121+			return;
   1.122 		}
   1.123 		break;
   1.124 
   1.125@@ -992,8 +1013,7 @@ eapreq(Eapconn *conn, int code, int id, 
   1.126 			if((pid = rfork(RFPROC|RFMEM)) == -1)
   1.127 				sysfatal("fork: %r");
   1.128 			if(pid == 0){
   1.129-				pid = getpid();
   1.130-				tunn->readerpid = pid;
   1.131+				tunn->readerpid = getpid();
   1.132 				tlsreader(tunn, conn);
   1.133 				if(conn->tunn == tunn)
   1.134 					conn->tunn = nil;
   1.135@@ -1001,7 +1021,7 @@ eapreq(Eapconn *conn, int code, int id, 
   1.136 				free(tunn);
   1.137 				exits(nil);
   1.138 			}
   1.139-			break;
   1.140+			return;
   1.141 		}
   1.142 		if(tunn == nil)
   1.143 			break;
   1.144@@ -1014,43 +1034,38 @@ eapreq(Eapconn *conn, int code, int id, 
   1.145 			data += 4;
   1.146 		}
   1.147 		data++;
   1.148-		if(datalen <= 0)
   1.149-			break;
   1.150-		if(write(tunn->fd, data, datalen) != datalen)
   1.151-			break;
   1.152+		if(datalen > 0)
   1.153+			write(tunn->fd, data, datalen);
   1.154 		if(frag || (tp == 25 && data[0] == 20)){	/* ack change cipher spec */
   1.155 			data -= 2;
   1.156 			data[0] = tp;
   1.157 			data[1] = 0;
   1.158 			eapresp(conn, 2, id, data, 2);
   1.159 		}
   1.160-		break;
   1.161+		return;
   1.162 	}
   1.163+	goto unhandled;
   1.164 }
   1.165 
   1.166 int
   1.167-avp(uchar *p, int code, void *val, int len)
   1.168+avp(uchar *p, int n, int code, void *val, int len, int pad)
   1.169 {
   1.170-	int n;
   1.171-
   1.172-	n = 4 + 4 + len;
   1.173-
   1.174-	*p++ = code >> 24;
   1.175-	*p++ = code >> 16;
   1.176-	*p++ = code >> 8;
   1.177-	*p++ = code;
   1.178-	*p++ = 2;
   1.179-
   1.180-	*p++ = n >> 16;
   1.181-	*p++ = n >> 8;
   1.182-	*p++ = n;
   1.183-
   1.184-	memmove(p, val, len);
   1.185-	p += len;
   1.186-
   1.187-	n = (n + 3) & ~3;
   1.188-	memset(p, 0, n - len);
   1.189-
   1.190+	len += 8;
   1.191+	if(len > n){
   1.192+		len = n - 8;
   1.193+		pad = 0;
   1.194+	}
   1.195+	p[0] = code >> 24;
   1.196+	p[1] = code >> 16;
   1.197+	p[2] = code >> 8;
   1.198+	p[3] = code;
   1.199+	p[4] = 2;
   1.200+	p[5] = len >> 16;
   1.201+	p[6] = len >> 8;
   1.202+	p[7] = len;
   1.203+	memmove(p+8, val, len-8);
   1.204+	n = (len + pad) & ~pad;
   1.205+	memset(p + len, 0, n - len);
   1.206 	return n;
   1.207 }
   1.208 
   1.209@@ -1070,21 +1085,19 @@ ttlsclient(int fd)
   1.210 	int n;
   1.211 
   1.212 	fd = tlswrap(fd, "ttls keying material");
   1.213-
   1.214-	/* we should really do challenge response here */
   1.215 	if((up = auth_getuserpasswd(nil, "proto=pass service=wpa essid=%q", essid)) == nil)
   1.216-		sysfatal("ttlsclient %d: no user/pass for essid=%q", getpid(), essid);
   1.217-
   1.218-	n = avp(buf, AvpUserName, up->user, strlen(up->user));
   1.219-	n += avp(buf+n, AvpUserPass, up->passwd, strlen(up->passwd));
   1.220+		sysfatal("auth_getuserpasswd: %r");
   1.221+	n = avp(buf, sizeof(buf), AvpUserName, up->user, strlen(up->user), 3);
   1.222+	n += avp(buf+n, sizeof(buf)-n, AvpUserPass, up->passwd, strlen(up->passwd), 15);
   1.223 	freeup(up);
   1.224-	if(write(fd, buf, n) != n)
   1.225-		sysfatal("ttlsclient write: %r");
   1.226+	write(fd, buf, n);
   1.227+	memset(buf, 0, n);
   1.228 }
   1.229 
   1.230 void
   1.231 peapwrite(Eapconn *conn, uchar *data, int len)
   1.232 {
   1.233+	assert(len >= 4);
   1.234 	fdwrite(conn, data + 4, len - 4);
   1.235 }
   1.236