]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vnc/auth.c
devdraw: simplify drawgen()
[plan9front.git] / sys / src / cmd / vnc / auth.c
1 #include "vnc.h"
2 #include <libsec.h>
3 #include <auth.h>
4
5 char *serveraddr;
6
7 enum
8 {
9         VerLen  = 12
10 };
11
12 static char version[VerLen+1] = "RFB 003.003\n";
13
14 int
15 vncsrvhandshake(Vnc *v)
16 {
17         char msg[VerLen+1];
18
19         strecpy(msg, msg+sizeof msg, version);
20         if(verbose)
21                 fprint(2, "server version: %s\n", msg);
22         vncwrbytes(v, msg, VerLen);
23         vncflush(v);
24
25         vncrdbytes(v, msg, VerLen);
26         if(verbose)
27                 fprint(2, "client version: %s\n", msg);
28         return 0;
29 }
30
31 int
32 vnchandshake(Vnc *v)
33 {
34         char msg[VerLen+1];
35
36         msg[VerLen] = 0;
37         vncrdbytes(v, msg, VerLen);
38         if(strncmp(msg, "RFB ", 4) != 0){
39                 werrstr("bad rfb version \"%s\"", msg);
40                 return -1;
41         }
42         if(verbose)
43                 fprint(2, "server version: %s\n", msg);
44         strcpy(msg, version);
45         vncwrbytes(v, msg, VerLen);
46         vncflush(v);
47         return 0;
48 }
49
50 int
51 vncauth(Vnc *v, char *keypattern)
52 {
53         char *reason;
54         uchar chal[VncChalLen];
55         ulong auth;
56
57         if(keypattern == nil)
58                 keypattern = "";
59         auth = vncrdlong(v);
60         switch(auth){
61         default:
62                 werrstr("unknown auth type 0x%lux", auth);
63                 if(verbose)
64                         fprint(2, "unknown auth type 0x%lux\n", auth);
65                 return -1;
66
67         case AFailed:
68                 reason = vncrdstring(v);
69                 werrstr("%s", reason);
70                 if(verbose)
71                         fprint(2, "auth failed: %s\n", reason);
72                 return -1;
73
74         case ANoAuth:
75                 if(verbose)
76                         fprint(2, "no auth needed\n");
77                 break;
78
79         case AVncAuth:
80                 vncrdbytes(v, chal, VncChalLen);
81                 if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey,
82                         "proto=vnc role=client server=%s %s", serveraddr, keypattern) != VncChalLen){
83                         return -1;
84                 }
85                 vncwrbytes(v, chal, VncChalLen);
86                 vncflush(v);
87
88                 auth = vncrdlong(v);
89                 switch(auth){
90                 default:
91                         werrstr("unknown server response 0x%lux", auth);
92                         return -1;
93                 case VncAuthFailed:
94                         werrstr("server says authentication failed");
95                         return -1;
96                 case VncAuthTooMany:
97                         werrstr("server says too many tries");
98                         return -1;
99                 case VncAuthOK:
100                         break;
101                 }
102                 break;
103         }
104         return 0;
105 }
106
107 int
108 vncsrvauth(Vnc *v)
109 {
110         Chalstate *c;
111         AuthInfo *ai;
112
113         if((c = auth_challenge("proto=vnc role=server user=%q", getuser()))==nil)
114                 sysfatal("vncchal: %r");
115         if(c->nchal != VncChalLen)
116                 sysfatal("vncchal got %d bytes wanted %d", c->nchal, VncChalLen);
117         vncwrlong(v, AVncAuth);
118         vncwrbytes(v, c->chal, VncChalLen);
119         vncflush(v);
120
121         vncrdbytes(v, c->chal, VncChalLen);
122         c->resp = c->chal;
123         c->nresp = VncChalLen;
124         ai = auth_response(c);
125         auth_freechal(c);
126         if(ai == nil){
127                 fprint(2, "vnc auth failed: server factotum: %r\n");
128                 vncwrlong(v, VncAuthFailed);
129                 vncflush(v);
130                 return -1;
131         }
132         auth_freeAI(ai);
133         vncwrlong(v, VncAuthOK);
134         vncflush(v);
135
136         return 0;
137 }
138