int vncsrvauth(Vnc *v) { Chalstate *c; AuthInfo *ai; if((c = auth_challenge("proto=vnc role=server user=%q", getuser()))==nil) sysfatal("vncchal: %r"); if(c->nchal != VncChalLen) sysfatal("vncchal got %d bytes wanted %d", c->nchal, VncChalLen); vncwrlong(v, AVncAuth); vncwrbytes(v, c->chal, VncChalLen); vncflush(v); vncrdbytes(v, c->chal, VncChalLen); c->resp = c->chal; c->nresp = VncChalLen; ai = auth_response(c); auth_freechal(c); if(ai == nil){ fprint(2, "vnc auth failed: server factotum: %r\n"); vncwrlong(v, VncAuthFailed); vncflush(v); return -1; } auth_freeAI(ai); vncwrlong(v, VncAuthOK); vncflush(v); return 0; }
ushort vncrdshort(Vnc *v) { uchar buf[2]; vncrdbytes(v, buf, 2); return SHORT(buf); }
ulong vncrdlong(Vnc *v) { uchar buf[4]; vncrdbytes(v, buf, 4); return LONG(buf); }
uint32_t vncrdlong(Vnc *v) { uint8_t buf[4]; vncrdbytes(v, buf, 4); return LONG(buf); }
uchar vncrdchar(Vnc *v) { uchar buf[1]; vncrdbytes(v, buf, 1); return buf[0]; }
uint16_t vncrdshort(Vnc *v) { uint8_t buf[2]; vncrdbytes(v, buf, 2); return SHORT(buf); }
uint8_t vncrdchar(Vnc *v) { uint8_t buf[1]; vncrdbytes(v, buf, 1); return buf[0]; }
void vncgobble(Vnc *v, long n) { uchar buf[8192]; long m; while(n > 0){ m = n; if(m > sizeof(buf)) m = sizeof(buf); vncrdbytes(v, buf, m); n -= m; } }
char* vncrdstring(Vnc *v) { ulong len; char *s; len = vncrdlong(v); s = malloc(len+1); assert(s != nil); vncrdbytes(v, s, len); s[len] = '\0'; return s; }
void vncgobble(Vnc *v, int32_t n) { uint8_t buf[8192]; int32_t m; while(n > 0){ m = n; if(m > sizeof(buf)) m = sizeof(buf); vncrdbytes(v, buf, m); n -= m; } }
int vncsrvhandshake(Vnc *v) { char msg[VerLen+1]; strecpy(msg, msg+sizeof msg, version); if(verbose) fprint(2, "server version: %s", msg); vncwrbytes(v, msg, VerLen); vncflush(v); vncrdbytes(v, msg, VerLen); if(verbose) fprint(2, "client version: %s", msg); return 0; }
int vnchandshake(Vnc *v) { char msg[VerLen+1]; msg[VerLen] = 0; vncrdbytes(v, msg, VerLen); if(strncmp(msg, "RFB ", 4) != 0){ werrstr("bad rfb version \"%s\"", msg); return -1; } if(verbose) fprint(2, "server version: %s", msg); strcpy(msg, version); vncwrbytes(v, msg, VerLen); vncflush(v); return 0; }
Pixfmt vncrdpixfmt(Vnc *v) { Pixfmt fmt; uchar pad[3]; fmt.bpp = vncrdchar(v); fmt.depth = vncrdchar(v); fmt.bigendian = vncrdchar(v); fmt.truecolor = vncrdchar(v); fmt.red.max = vncrdshort(v); fmt.green.max = vncrdshort(v); fmt.blue.max = vncrdshort(v); fmt.red.shift = vncrdchar(v); fmt.green.shift = vncrdchar(v); fmt.blue.shift = vncrdchar(v); vncrdbytes(v, pad, 3); return fmt; }
void writesnarf(Vnc *v, long n) { uchar buf[8192]; long m; Biobuf *b; if((b = Bopen("/dev/snarf", OWRITE)) == nil) { vncgobble(v, n); return; } while(n > 0) { m = n; if(m > sizeof(buf)) m = sizeof(buf); vncrdbytes(v, buf, m); n -= m; Bwrite(b, buf, m); } Bterm(b); snarfvers++; }
int vncauth(Vnc *v, char *keypattern) { char pw[128], *reason; uint8_t chal[VncChalLen]; uint32_t auth; char *p, *server; if(keypattern == nil) keypattern = ""; auth = vncrdlong(v); switch(auth){ default: werrstr("unknown auth type 0x%lux", auth); if(verbose) fprint(2, "unknown auth type 0x%lux", auth); return -1; case AFailed: reason = vncrdstring(v); werrstr("%s", reason); if(verbose) fprint(2, "auth failed: %s\n", reason); return -1; case ANoAuth: if(verbose) fprint(2, "no auth needed"); break; case AVncAuth: vncrdbytes(v, chal, VncChalLen); server = strdup(serveraddr); p = strrchr(server, ':'); if(p) *p = 0; if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey, "proto=vnc role=client server=%s %s", server, keypattern) != VncChalLen){ /* BUG This is for drawterm users who don't start their own factotums */ readln("password: "******"unknown server response 0x%lux", auth); return -1; case VncAuthFailed: werrstr("server says authentication failed"); return -1; case VncAuthTooMany: werrstr("server says too many tries"); return -1; case VncAuthOK: break; } break; } return 0; }