]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vnc/auth.c
vnc: don't prompt for password on auth_respond() failure
[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         char *p, *server;
57
58         if(keypattern == nil)
59                 keypattern = "";
60         auth = vncrdlong(v);
61         switch(auth){
62         default:
63                 werrstr("unknown auth type 0x%lux", auth);
64                 if(verbose)
65                         fprint(2, "unknown auth type 0x%lux\n", auth);
66                 return -1;
67
68         case AFailed:
69                 reason = vncrdstring(v);
70                 werrstr("%s", reason);
71                 if(verbose)
72                         fprint(2, "auth failed: %s\n", reason);
73                 return -1;
74
75         case ANoAuth:
76                 if(verbose)
77                         fprint(2, "no auth needed\n");
78                 break;
79
80         case AVncAuth:
81                 vncrdbytes(v, chal, VncChalLen);
82                 server = strdup(serveraddr);
83                 p = strrchr(server, ':');
84                 if(p)
85                         *p = 0;
86                 if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey,
87                         "proto=vnc role=client server=%s %s", server, keypattern) != VncChalLen){
88                         free(server);
89                         return -1;
90                 }
91                 free(server);
92                 vncwrbytes(v, chal, VncChalLen);
93                 vncflush(v);
94
95                 auth = vncrdlong(v);
96                 switch(auth){
97                 default:
98                         werrstr("unknown server response 0x%lux", auth);
99                         return -1;
100                 case VncAuthFailed:
101                         werrstr("server says authentication failed");
102                         return -1;
103                 case VncAuthTooMany:
104                         werrstr("server says too many tries");
105                         return -1;
106                 case VncAuthOK:
107                         break;
108                 }
109                 break;
110         }
111         return 0;
112 }
113
114 int
115 vncsrvauth(Vnc *v)
116 {
117         Chalstate *c;
118         AuthInfo *ai;
119
120         if((c = auth_challenge("proto=vnc role=server user=%q", getuser()))==nil)
121                 sysfatal("vncchal: %r");
122         if(c->nchal != VncChalLen)
123                 sysfatal("vncchal got %d bytes wanted %d", c->nchal, VncChalLen);
124         vncwrlong(v, AVncAuth);
125         vncwrbytes(v, c->chal, VncChalLen);
126         vncflush(v);
127
128         vncrdbytes(v, c->chal, VncChalLen);
129         c->resp = c->chal;
130         c->nresp = VncChalLen;
131         ai = auth_response(c);
132         auth_freechal(c);
133         if(ai == nil){
134                 fprint(2, "vnc auth failed: server factotum: %r\n");
135                 vncwrlong(v, VncAuthFailed);
136                 vncflush(v);
137                 return -1;
138         }
139         auth_freeAI(ai);
140         vncwrlong(v, VncAuthOK);
141         vncflush(v);
142
143         return 0;
144 }
145