diff options
-rw-r--r-- | dat.h | 5 | ||||
-rw-r--r-- | fmt.c | 25 | ||||
-rw-r--r-- | fns.h | 7 | ||||
-rw-r--r-- | mkfile | 1 | ||||
-rw-r--r-- | musw.c | 29 | ||||
-rw-r--r-- | muswd.c | 35 | ||||
-rw-r--r-- | net.c | 37 | ||||
-rw-r--r-- | pack.c | 4 | ||||
-rw-r--r-- | party.c | 2 | ||||
-rw-r--r-- | physics.c | 2 | ||||
-rw-r--r-- | sprite.c | 2 | ||||
-rw-r--r-- | universe.c | 2 |
12 files changed, 126 insertions, 25 deletions
@@ -46,7 +46,7 @@ enum { enum { ProtocolID = 0x5753554d, /* MUSW */ - Framehdrsize = 4+1+4+4+2, + Framehdrsize = 4+1+4+4+2+MD5dlen, MTU = 1024 }; @@ -147,6 +147,7 @@ struct Frame u32int seq; u32int ack; u16int len; + uchar sig[MD5dlen]; uchar data[]; }; @@ -177,3 +178,5 @@ struct Party Universe *u; Party *prev, *next; }; + +#pragma varargck type "Φ" Frame* @@ -0,0 +1,25 @@ +#include <u.h> +#include <libc.h> +#include <ip.h> +#include <mp.h> +#include <libsec.h> +#include <thread.h> +#include <draw.h> +#include <geometry.h> +#include "dat.h" +#include "fns.h" + +int +Φfmt(Fmt *f) +{ + int n, i; + Frame *frame; + + frame = va_arg(f->args, Frame*); + + n = fmtprint(f, "id %x type %ud seq %ud ack %ud len %ud sig ", + frame->id, frame->type, frame->seq, frame->ack, frame->len); + for(i = 0; i < MD5dlen; i++) + n += fmtprint(f, "%2.2x", frame->sig[i]); + return n; +} @@ -53,4 +53,11 @@ ulong dhgenkey(ulong, ulong, ulong); NetConn *newnetconn(NCState, Udphdr*); void delnetconn(NetConn*); Frame *newframe(Frame*, u8int, u32int, u32int, u16int, uchar*); +void signframe(Frame*, ulong); +int verifyframe(Frame*, ulong); void delframe(Frame*); + +/* + * fmt + */ +int Φfmt(Fmt*); @@ -15,6 +15,7 @@ OFILES=\ universe.$O\ sprite.$O\ net.$O\ + fmt.$O\ HFILES=\ dat.h\ @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <bio.h> #include <thread.h> #include <draw.h> @@ -164,6 +166,7 @@ sendkeys(ulong kdown) frame = newframe(nil, NCinput, 0, 0, sizeof(kdown), nil); pack(frame->data, frame->len, "k", kdown); + signframe(frame, netconn.dh.priv); sendp(egress, frame); } @@ -241,9 +244,8 @@ threadnetrecv(void *arg) if(debug){ rport = frame->udp.rport[0]<<8 | frame->udp.rport[1]; lport = frame->udp.lport[0]<<8 | frame->udp.lport[1]; - fprint(2, "%I!%ud ← %I!%ud | rcvd type %ud seq %ud ack %ud len %ud\n", - frame->udp.laddr, lport, frame->udp.raddr, rport, - frame->type, frame->seq, frame->ack, frame->len); + fprint(2, "%I!%ud → %I!%ud | rcvd %Φ\n", + frame->udp.laddr, lport, frame->udp.raddr, rport, frame); } } closeioproc(io); @@ -267,27 +269,33 @@ threadnetppu(void *) unpack(frame->data, frame->len, "kk", &netconn.dh.p, &netconn.dh.g); newf = newframe(frame, NCdhx, 0, 0, sizeof(ulong), nil); - + netconn.dh.sec = truerand(); pack(newf->data, newf->len, "k", dhgenkey(netconn.dh.g, netconn.dh.sec, netconn.dh.p)); sendp(egress, newf); if(debug) fprint(2, "\tsent pubkey %ld\n", dhgenkey(netconn.dh.g, netconn.dh.sec, netconn.dh.p)); - + break; case NSdhx: unpack(frame->data, frame->len, "k", &netconn.dh.pub); netconn.state = NCSConnected; if(debug) - fprint(2, "\trecvd pubkey %ld\n", netconn.dh.pub); + fprint(2, "\trcvd pubkey %ld\n", netconn.dh.pub); netconn.dh.priv = dhgenkey(netconn.dh.pub, netconn.dh.sec, netconn.dh.p); break; } break; case NCSConnected: + if(verifyframe(frame, netconn.dh.priv) != 0){ + if(debug) + fprint(2, "\tbad signature\n"); + goto discard; + } + switch(frame->type){ case NSsimstate: unpack(frame->data, frame->len, "PdPdP", @@ -297,6 +305,7 @@ threadnetppu(void *) break; case NSnudge: newf = newframe(frame, NCnudge, 0, 0, 0, nil); + signframe(newf, netconn.dh.priv); sendp(egress, newf); @@ -308,7 +317,7 @@ threadnetppu(void *) break; } discard: - free(frame); + delframe(frame); } } @@ -332,9 +341,8 @@ threadnetsend(void *arg) if(debug){ rport = frame->udp.rport[0]<<8 | frame->udp.rport[1]; lport = frame->udp.lport[0]<<8 | frame->udp.lport[1]; - fprint(2, "%I!%ud → %I!%ud | sent type %ud seq %ud ack %ud len %ud\n", - frame->udp.laddr, lport, frame->udp.raddr, rport, - frame->type, frame->seq, frame->ack, frame->len); + fprint(2, "%I!%ud → %I!%ud | sent %Φ\n", + frame->udp.laddr, lport, frame->udp.raddr, rport, frame); } free(frame); @@ -438,6 +446,7 @@ threadmain(int argc, char *argv[]) GEOMfmtinstall(); fmtinstall('I', eipfmt); + fmtinstall(L'Φ', Φfmt); ARGBEGIN{ case 'd': debug++; @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <thread.h> #include <draw.h> #include <geometry.h> @@ -46,7 +48,7 @@ popconn(NetConn *nc) ncpe = conns+nconns; - for(ncp = conns; ncp < conns+nconns; ncp++) + for(ncp = conns; ncp < ncpe; ncp++) if(*ncp == nc){ memmove(ncp, ncp+1, sizeof(NetConn*)*(ncpe-ncp-1)); nconns--; @@ -77,9 +79,8 @@ threadnetrecv(void *arg) if(debug){ rport = frame->udp.rport[0]<<8 | frame->udp.rport[1]; lport = frame->udp.lport[0]<<8 | frame->udp.lport[1]; - fprint(2, "%I!%ud ← %I!%ud | rcvd type %ud seq %ud ack %ud len %ud\n", - frame->udp.laddr, lport, frame->udp.raddr, rport, - frame->type, frame->seq, frame->ack, frame->len); + fprint(2, "%I!%ud → %I!%ud | rcvd %Φ\n", + frame->udp.laddr, lport, frame->udp.raddr, rport, frame); } } closeioproc(io); @@ -103,13 +104,13 @@ threadnetppu(void *) if(frame->type == NChi){ nc = newnetconn(NCSConnecting, &frame->udp); putconn(nc); - + newf = newframe(frame, NShi, 0, 0, 2*sizeof(ulong), nil); - + dhgenpg(&nc->dh.p, &nc->dh.g); pack(newf->data, newf->len, "kk", nc->dh.p, nc->dh.g); sendp(egress, newf); - + if(debug) fprint(2, "\tsent p %ld g %ld\n", nc->dh.p, nc->dh.g); }else @@ -124,10 +125,10 @@ threadnetppu(void *) nc->state = NCSConnected; if(debug) - fprint(2, "\trecvd pubkey %ld\n", nc->dh.pub); + fprint(2, "\trcvd pubkey %ld\n", nc->dh.pub); newf = newframe(frame, NSdhx, 0, 0, sizeof(ulong), nil); - + nc->dh.sec = truerand(); nc->dh.priv = dhgenkey(nc->dh.pub, nc->dh.sec, nc->dh.p); pack(newf->data, newf->len, "k", dhgenkey(nc->dh.g, nc->dh.sec, nc->dh.p)); @@ -140,6 +141,12 @@ threadnetppu(void *) } break; case NCSConnected: + if(verifyframe(frame, nc->dh.priv) != 0){ + if(debug) + fprint(2, "\tbad signature\n"); + goto discard; + } + switch(frame->type){ case NCinput: unpack(frame->data, frame->len, "k", &kdown); @@ -150,13 +157,13 @@ threadnetppu(void *) break; case NCbuhbye: popconn(nc); - free(nc); + delnetconn(nc); break; } break; } discard: - free(frame); + delframe(frame); } } @@ -180,9 +187,8 @@ threadnetsend(void *arg) if(debug){ rport = frame->udp.rport[0]<<8 | frame->udp.rport[1]; lport = frame->udp.lport[0]<<8 | frame->udp.lport[1]; - fprint(2, "%I!%ud → %I!%ud | sent type %ud seq %ud ack %ud len %ud\n", - frame->udp.laddr, lport, frame->udp.raddr, rport, - frame->type, frame->seq, frame->ack, frame->len); + fprint(2, "%I!%ud → %I!%ud | sent %Φ\n", + frame->udp.laddr, lport, frame->udp.raddr, rport, frame); } free(frame); @@ -334,6 +340,7 @@ threadmain(int argc, char *argv[]) GEOMfmtinstall(); fmtinstall('I', eipfmt); + fmtinstall(L'Φ', Φfmt); addr = "udp!*!112"; ARGBEGIN{ case 'a': @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <thread.h> #include <draw.h> #include <geometry.h> @@ -69,6 +71,7 @@ newframe(Frame *pf, u8int type, u32int seq, u32int ack, u16int len, uchar *data) Frame *f; f = emalloc(sizeof(Frame)+len); + memset(f, 0, sizeof(Frame)); f->id = ProtocolID; f->type = type; if(pf != nil){ @@ -88,6 +91,40 @@ newframe(Frame *pf, u8int type, u32int seq, u32int ack, u16int len, uchar *data) } void +signframe(Frame *f, ulong key) +{ + uchar k[sizeof(ulong)]; + uchar h[MD5dlen]; + uchar msg[MTU]; + int n; + + k[0] = key; k[1] = key>>8; k[2] = key>>16; k[3] = key>>24; + + memset(f->sig, 0, MD5dlen); + n = pack(msg, sizeof msg, "f", f); + hmac_md5(msg, n, k, sizeof k, h, nil); + memmove(f->sig, h, MD5dlen); +} + +int +verifyframe(Frame *f, ulong key) +{ + uchar k[sizeof(ulong)]; + uchar h0[MD5dlen], h1[MD5dlen]; + uchar msg[MTU]; + int n; + + k[0] = key; k[1] = key>>8; k[2] = key>>16; k[3] = key>>24; + + memmove(h0, f->sig, MD5dlen); + memset(f->sig, 0, MD5dlen); + n = pack(msg, sizeof msg, "f", f); + hmac_md5(msg, n, k, sizeof k, h1, nil); + memmove(f->sig, h0, MD5dlen); + return memcmp(h0, h1, MD5dlen); +} + +void delframe(Frame *f) { free(f); @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <draw.h> #include <geometry.h> #include "dat.h" @@ -91,6 +93,7 @@ vpack(uchar *p, int n, char *fmt, va_list a) put4(p, F->seq), p += 4; put4(p, F->ack), p += 4; put2(p, F->len), p += 2; + memmove(p, F->sig, MD5dlen), p += MD5dlen; if(p+F->len > e) goto err; @@ -161,6 +164,7 @@ vunpack(uchar *p, int n, char *fmt, va_list a) F->seq = get4(p), p += 4; F->ack = get4(p), p += 4; F->len = get2(p), p += 2; + memmove(F->sig, p, MD5dlen), p += MD5dlen; if(p+F->len > e) goto err; @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <draw.h> #include <geometry.h> #include "dat.h" @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <draw.h> #include <geometry.h> #include "dat.h" @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <draw.h> #include <geometry.h> #include "dat.h" @@ -1,6 +1,8 @@ #include <u.h> #include <libc.h> #include <ip.h> +#include <mp.h> +#include <libsec.h> #include <draw.h> #include <geometry.h> #include "dat.h" |