vnc: I don't like your face.
Cosmetic improvements to vnc auth code. Should not have user-visible changes.
This commit is contained in:
parent
f321298c55
commit
bd5af0df5d
3 changed files with 54 additions and 75 deletions
|
@ -2,26 +2,12 @@
|
||||||
#include <libsec.h>
|
#include <libsec.h>
|
||||||
#include <auth.h>
|
#include <auth.h>
|
||||||
|
|
||||||
char *serveraddr;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
VerLen = 12
|
|
||||||
};
|
|
||||||
|
|
||||||
static char version33[VerLen+1] = "RFB 003.003\n";
|
|
||||||
static char version38[VerLen+1] = "RFB 003.008\n";
|
|
||||||
static int srvversion;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
vncsrvhandshake(Vnc *v)
|
vncsrvhandshake(Vnc *v)
|
||||||
{
|
{
|
||||||
char msg[VerLen+1];
|
char msg[VerLen+1];
|
||||||
|
|
||||||
strecpy(msg, msg+sizeof msg, version33);
|
vncwrbytes(v, "RFB 003.003\n", VerLen);
|
||||||
if(verbose)
|
|
||||||
fprint(2, "server version: %s\n", msg);
|
|
||||||
vncwrbytes(v, msg, VerLen);
|
|
||||||
vncflush(v);
|
vncflush(v);
|
||||||
|
|
||||||
vncrdbytes(v, msg, VerLen);
|
vncrdbytes(v, msg, VerLen);
|
||||||
|
@ -33,67 +19,57 @@ vncsrvhandshake(Vnc *v)
|
||||||
int
|
int
|
||||||
vnchandshake(Vnc *v)
|
vnchandshake(Vnc *v)
|
||||||
{
|
{
|
||||||
char msg[VerLen+1];
|
char msg[VerLen + 1];
|
||||||
|
|
||||||
msg[VerLen] = 0;
|
msg[VerLen] = 0;
|
||||||
vncrdbytes(v, msg, VerLen);
|
vncrdbytes(v, msg, VerLen);
|
||||||
if(strncmp(msg, "RFB 003.", 8) != 0 ||
|
|
||||||
strncmp(msg, "RFB 003.007\n", VerLen) == 0){
|
|
||||||
werrstr("bad rfb version \"%s\"", msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(strncmp(msg, "RFB 003.008\n", VerLen) == 0)
|
|
||||||
srvversion = 38;
|
|
||||||
else
|
|
||||||
srvversion = 33;
|
|
||||||
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
fprint(2, "server version: %s\n", msg);
|
fprint(2, "server version: %s\n", msg);
|
||||||
strcpy(msg, version38);
|
|
||||||
|
if(strncmp(msg, "RFB 003.003\n", VerLen) == 0)
|
||||||
|
v->vers = 33;
|
||||||
|
else if(strncmp(msg, "RFB 003.007\n", VerLen) == 0)
|
||||||
|
v->vers = 37;
|
||||||
|
else if(strncmp(msg, "RFB 003.008\n", VerLen) == 0)
|
||||||
|
v->vers = 38;
|
||||||
|
else /* RFC6143: Any other should be treated as 3.3. */
|
||||||
|
v->vers = 33;
|
||||||
|
|
||||||
|
strcpy(msg, "RFB 003.008\n");
|
||||||
vncwrbytes(v, msg, VerLen);
|
vncwrbytes(v, msg, VerLen);
|
||||||
vncflush(v);
|
vncflush(v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong
|
|
||||||
sectype38(Vnc *v)
|
|
||||||
{
|
|
||||||
ulong auth, type;
|
|
||||||
int i, ntypes;
|
|
||||||
|
|
||||||
ntypes = vncrdchar(v);
|
|
||||||
if(ntypes == 0){
|
|
||||||
werrstr("no security types from server");
|
|
||||||
return AFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* choose the "most secure" security type */
|
|
||||||
auth = AFailed;
|
|
||||||
for(i = 0; i < ntypes; i++){
|
|
||||||
type = vncrdchar(v);
|
|
||||||
if(verbose){
|
|
||||||
fprint(2, "auth type %s\n",
|
|
||||||
type == AFailed ? "Invalid" :
|
|
||||||
type == ANoAuth ? "None" :
|
|
||||||
type == AVncAuth ? "VNC" : "Unknown");
|
|
||||||
}
|
|
||||||
if(type > auth && type <= AVncAuth)
|
|
||||||
auth = type;
|
|
||||||
}
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
vncauth(Vnc *v, char *keypattern)
|
vncauth(Vnc *v, char *keypattern)
|
||||||
{
|
{
|
||||||
char *reason;
|
|
||||||
uchar chal[VncChalLen];
|
uchar chal[VncChalLen];
|
||||||
ulong auth;
|
ulong auth, type;
|
||||||
|
int i, ntypes;
|
||||||
|
char *err;
|
||||||
|
|
||||||
if(keypattern == nil)
|
if(keypattern == nil)
|
||||||
keypattern = "";
|
keypattern = "";
|
||||||
|
|
||||||
auth = srvversion == 38 ? sectype38(v) : vncrdlong(v);
|
auth = AFailed;
|
||||||
|
if(v->vers == 33)
|
||||||
|
auth = vncrdlong(v);
|
||||||
|
else{
|
||||||
|
ntypes = vncrdchar(v);
|
||||||
|
for(i = 0; i < ntypes; i++){
|
||||||
|
type = vncrdchar(v);
|
||||||
|
if(verbose)
|
||||||
|
fprint(2, "auth type %uld\n", type);
|
||||||
|
if(type > auth && type <= AVncAuth)
|
||||||
|
auth = type;
|
||||||
|
}
|
||||||
|
if(auth == AFailed){
|
||||||
|
werrstr("no supported auth types");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(auth){
|
switch(auth){
|
||||||
default:
|
default:
|
||||||
|
@ -103,15 +79,14 @@ vncauth(Vnc *v, char *keypattern)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case AFailed:
|
case AFailed:
|
||||||
failed:
|
err = vncrdstring(v);
|
||||||
reason = vncrdstring(v);
|
werrstr("%s", err);
|
||||||
werrstr("%s", reason);
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
fprint(2, "auth failed: %s\n", reason);
|
fprint(2, "auth failed: %s\n", err);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case ANoAuth:
|
case ANoAuth:
|
||||||
if(srvversion == 38){
|
if(v->vers == 38){
|
||||||
vncwrchar(v, auth);
|
vncwrchar(v, auth);
|
||||||
vncflush(v);
|
vncflush(v);
|
||||||
}
|
}
|
||||||
|
@ -120,14 +95,14 @@ vncauth(Vnc *v, char *keypattern)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVncAuth:
|
case AVncAuth:
|
||||||
if(srvversion == 38){
|
if(v->vers == 38){
|
||||||
vncwrchar(v, auth);
|
vncwrchar(v, auth);
|
||||||
vncflush(v);
|
vncflush(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
vncrdbytes(v, chal, VncChalLen);
|
vncrdbytes(v, chal, VncChalLen);
|
||||||
if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey,
|
if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey,
|
||||||
"proto=vnc role=client server=%s %s", serveraddr, keypattern) != VncChalLen){
|
"proto=vnc role=client server=%s %s", v->srvaddr, keypattern) != VncChalLen){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
vncwrbytes(v, chal, VncChalLen);
|
vncwrbytes(v, chal, VncChalLen);
|
||||||
|
@ -135,18 +110,18 @@ vncauth(Vnc *v, char *keypattern)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in version 3.8 the auth status is always sent, in 3.3 only in AVncAuth */
|
/* in version 3.8 the auth status is always sent, in 3.3 and 3.7, only in AVncAuth */
|
||||||
if(srvversion == 38 || auth == AVncAuth){
|
if(v->vers == 38 || auth == AVncAuth){
|
||||||
auth = vncrdlong(v); /* auth status */
|
auth = vncrdlong(v); /* auth status */
|
||||||
switch(auth){
|
switch(auth){
|
||||||
default:
|
default:
|
||||||
werrstr("unknown server response 0x%lux", auth);
|
werrstr("unknown server response 0x%lux", auth);
|
||||||
return -1;
|
return -1;
|
||||||
case VncAuthFailed:
|
case VncAuthFailed:
|
||||||
if (srvversion == 38)
|
err = (v->vers == 38) ? vncrdstring(v) : "rejected";
|
||||||
goto failed;
|
werrstr("%s", err);
|
||||||
|
if(verbose)
|
||||||
werrstr("server says authentication failed");
|
fprint(2, "auth failed: %s\n", err);
|
||||||
return -1;
|
return -1;
|
||||||
case VncAuthTooMany:
|
case VncAuthTooMany:
|
||||||
werrstr("server says too many tries");
|
werrstr("server says too many tries");
|
||||||
|
|
|
@ -33,7 +33,11 @@ struct Vnc {
|
||||||
|
|
||||||
Rectangle dim;
|
Rectangle dim;
|
||||||
Pixfmt;
|
Pixfmt;
|
||||||
char *name; /* client only */
|
|
||||||
|
/* client only */
|
||||||
|
char *name;
|
||||||
|
char *srvaddr;
|
||||||
|
int vers;
|
||||||
|
|
||||||
int canresize;
|
int canresize;
|
||||||
struct {
|
struct {
|
||||||
|
@ -44,6 +48,7 @@ struct Vnc {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
VerLen = 12,
|
||||||
/* authentication negotiation */
|
/* authentication negotiation */
|
||||||
AFailed = 0,
|
AFailed = 0,
|
||||||
ANoAuth,
|
ANoAuth,
|
||||||
|
@ -142,4 +147,3 @@ extern void hexdump(void*, int);
|
||||||
extern void vnchungup(Vnc*);
|
extern void vnchungup(Vnc*);
|
||||||
|
|
||||||
extern int verbose;
|
extern int verbose;
|
||||||
extern char* serveraddr;
|
|
||||||
|
|
|
@ -111,10 +111,9 @@ main(int argc, char **argv)
|
||||||
if(argc != 1)
|
if(argc != 1)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
serveraddr = strdup(argv[0]);
|
dfd = dial(netmkvncaddr(argv[0]), nil, nil, &cfd);
|
||||||
dfd = dial(netmkvncaddr(serveraddr), nil, nil, &cfd);
|
|
||||||
if(dfd < 0)
|
if(dfd < 0)
|
||||||
sysfatal("cannot dial %s: %r", serveraddr);
|
sysfatal("cannot dial %s: %r", argv[0]);
|
||||||
if(tls){
|
if(tls){
|
||||||
TLSconn conn;
|
TLSconn conn;
|
||||||
|
|
||||||
|
@ -126,6 +125,7 @@ main(int argc, char **argv)
|
||||||
free(conn.sessionID);
|
free(conn.sessionID);
|
||||||
}
|
}
|
||||||
vnc = vncinit(dfd, cfd, nil);
|
vnc = vncinit(dfd, cfd, nil);
|
||||||
|
vnc->srvaddr = strdup(argv[0]);
|
||||||
|
|
||||||
if(vnchandshake(vnc) < 0)
|
if(vnchandshake(vnc) < 0)
|
||||||
sysfatal("handshake failure: %r");
|
sysfatal("handshake failure: %r");
|
||||||
|
|
Loading…
Reference in a new issue