mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 14:39:24 -05:00
Support XDM-AUTHORIZATION-1 for connecting to local X servers. If
we're going to be a security program, we can at least make a token effort to use the most secure local X auth available! And I'm still half-tempted to see if I can support it for remote X servers too... [originally from svn r2537]
This commit is contained in:
parent
86977efa81
commit
87f9446a26
@ -26,6 +26,13 @@ typedef void *Context; /* FIXME */
|
|||||||
|
|
||||||
#define OPTIMISE_SCROLL
|
#define OPTIMISE_SCROLL
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sk_getxdmdata() does not exist under the Mac (SGT: I have no
|
||||||
|
* idea whatsoever how to write it, and furthermore I'm unconvinced
|
||||||
|
* it's necessary), so it's a macro which always returns FALSE.
|
||||||
|
*/
|
||||||
|
#define sk_getxdmdata(socket, ip, port) (0)
|
||||||
|
|
||||||
/* To make it compile */
|
/* To make it compile */
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
1
putty.h
1
putty.h
@ -697,6 +697,7 @@ void cmdline_error(char *, ...);
|
|||||||
enum {
|
enum {
|
||||||
X11_NO_AUTH,
|
X11_NO_AUTH,
|
||||||
X11_MIT, /* MIT-MAGIC-COOKIE-1 */
|
X11_MIT, /* MIT-MAGIC-COOKIE-1 */
|
||||||
|
X11_XDM, /* XDM-AUTHORIZATION-1 */
|
||||||
X11_NAUTHS
|
X11_NAUTHS
|
||||||
};
|
};
|
||||||
extern const char *const x11_authnames[]; /* declared in x11fwd.c */
|
extern const char *const x11_authnames[]; /* declared in x11fwd.c */
|
||||||
|
2
ssh.h
2
ssh.h
@ -363,6 +363,8 @@ void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk,
|
|||||||
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk,
|
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk,
|
||||||
int len);
|
int len);
|
||||||
|
|
||||||
|
void des_encrypt_xdmauth(unsigned char *key, unsigned char *blk, int len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For progress updates in the key generation utility.
|
* For progress updates in the key generation utility.
|
||||||
*/
|
*/
|
||||||
|
26
sshdes.c
26
sshdes.c
@ -897,6 +897,32 @@ void des3_encrypt_pubkey_ossh(unsigned char *key, unsigned char *iv,
|
|||||||
memset(ourkeys, 0, sizeof(ourkeys));
|
memset(ourkeys, 0, sizeof(ourkeys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void des_encrypt_xdmauth(unsigned char *keydata, unsigned char *blk, int len)
|
||||||
|
{
|
||||||
|
unsigned char key[8];
|
||||||
|
DESContext dc;
|
||||||
|
int i, nbits, j;
|
||||||
|
unsigned int bits;
|
||||||
|
|
||||||
|
bits = 0;
|
||||||
|
nbits = 0;
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (nbits < 7) {
|
||||||
|
bits = (bits << 8) | keydata[j];
|
||||||
|
nbits += 8;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
key[i] = (bits >> (nbits - 7)) << 1;
|
||||||
|
bits &= ~(0x7F << (nbits - 7));
|
||||||
|
nbits -= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
des_key_setup(GET_32BIT_MSB_FIRST(key), GET_32BIT_MSB_FIRST(key + 4),
|
||||||
|
&dc);
|
||||||
|
des_cbc_encrypt(blk, blk, 24, &dc);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ssh2_cipher ssh_3des_ssh2 = {
|
static const struct ssh2_cipher ssh_3des_ssh2 = {
|
||||||
des3_make_context, des3_free_context, des3_iv, des3_key,
|
des3_make_context, des3_free_context, des3_iv, des3_key,
|
||||||
des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk,
|
des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk,
|
||||||
|
@ -71,4 +71,9 @@ void (*putty_signal(int sig, void (*func)(int)))(int);
|
|||||||
*/
|
*/
|
||||||
int init_ucs(int font_charset);
|
int init_ucs(int font_charset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Spare function exported directly from uxnet.c.
|
||||||
|
*/
|
||||||
|
int sk_getxdmdata(void *sock, unsigned long *ip, int *port);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
83
unix/uxnet.c
83
unix/uxnet.c
@ -305,27 +305,27 @@ static void *sk_tcp_get_private_ptr(Socket s);
|
|||||||
static void sk_tcp_set_frozen(Socket s, int is_frozen);
|
static void sk_tcp_set_frozen(Socket s, int is_frozen);
|
||||||
static char *sk_tcp_socket_error(Socket s);
|
static char *sk_tcp_socket_error(Socket s);
|
||||||
|
|
||||||
|
static struct socket_function_table tcp_fn_table = {
|
||||||
|
sk_tcp_plug,
|
||||||
|
sk_tcp_close,
|
||||||
|
sk_tcp_write,
|
||||||
|
sk_tcp_write_oob,
|
||||||
|
sk_tcp_flush,
|
||||||
|
sk_tcp_set_private_ptr,
|
||||||
|
sk_tcp_get_private_ptr,
|
||||||
|
sk_tcp_set_frozen,
|
||||||
|
sk_tcp_socket_error
|
||||||
|
};
|
||||||
|
|
||||||
Socket sk_register(void *sock, Plug plug)
|
Socket sk_register(void *sock, Plug plug)
|
||||||
{
|
{
|
||||||
static struct socket_function_table fn_table = {
|
|
||||||
sk_tcp_plug,
|
|
||||||
sk_tcp_close,
|
|
||||||
sk_tcp_write,
|
|
||||||
sk_tcp_write_oob,
|
|
||||||
sk_tcp_flush,
|
|
||||||
sk_tcp_set_private_ptr,
|
|
||||||
sk_tcp_get_private_ptr,
|
|
||||||
sk_tcp_set_frozen,
|
|
||||||
sk_tcp_socket_error
|
|
||||||
};
|
|
||||||
|
|
||||||
Actual_Socket ret;
|
Actual_Socket ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create Socket structure.
|
* Create Socket structure.
|
||||||
*/
|
*/
|
||||||
ret = smalloc(sizeof(struct Socket_tag));
|
ret = smalloc(sizeof(struct Socket_tag));
|
||||||
ret->fn = &fn_table;
|
ret->fn = &tcp_fn_table;
|
||||||
ret->error = NULL;
|
ret->error = NULL;
|
||||||
ret->plug = plug;
|
ret->plug = plug;
|
||||||
bufchain_init(&ret->output_data);
|
bufchain_init(&ret->output_data);
|
||||||
@ -355,18 +355,6 @@ Socket sk_register(void *sock, Plug plug)
|
|||||||
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||||
int nodelay, Plug plug)
|
int nodelay, Plug plug)
|
||||||
{
|
{
|
||||||
static struct socket_function_table fn_table = {
|
|
||||||
sk_tcp_plug,
|
|
||||||
sk_tcp_close,
|
|
||||||
sk_tcp_write,
|
|
||||||
sk_tcp_write_oob,
|
|
||||||
sk_tcp_flush,
|
|
||||||
sk_tcp_set_private_ptr,
|
|
||||||
sk_tcp_get_private_ptr,
|
|
||||||
sk_tcp_set_frozen,
|
|
||||||
sk_tcp_socket_error
|
|
||||||
};
|
|
||||||
|
|
||||||
int s;
|
int s;
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
struct sockaddr_in6 a6;
|
struct sockaddr_in6 a6;
|
||||||
@ -380,7 +368,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
* Create Socket structure.
|
* Create Socket structure.
|
||||||
*/
|
*/
|
||||||
ret = smalloc(sizeof(struct Socket_tag));
|
ret = smalloc(sizeof(struct Socket_tag));
|
||||||
ret->fn = &fn_table;
|
ret->fn = &tcp_fn_table;
|
||||||
ret->error = NULL;
|
ret->error = NULL;
|
||||||
ret->plug = plug;
|
ret->plug = plug;
|
||||||
bufchain_init(&ret->output_data);
|
bufchain_init(&ret->output_data);
|
||||||
@ -524,18 +512,6 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
|
|
||||||
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
|
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
|
||||||
{
|
{
|
||||||
static struct socket_function_table fn_table = {
|
|
||||||
sk_tcp_plug,
|
|
||||||
sk_tcp_close,
|
|
||||||
sk_tcp_write,
|
|
||||||
sk_tcp_write_oob,
|
|
||||||
sk_tcp_flush,
|
|
||||||
sk_tcp_set_private_ptr,
|
|
||||||
sk_tcp_get_private_ptr,
|
|
||||||
sk_tcp_set_frozen,
|
|
||||||
sk_tcp_socket_error
|
|
||||||
};
|
|
||||||
|
|
||||||
int s;
|
int s;
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
struct sockaddr_in6 a6;
|
struct sockaddr_in6 a6;
|
||||||
@ -550,7 +526,7 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
|
|||||||
* Create Socket structure.
|
* Create Socket structure.
|
||||||
*/
|
*/
|
||||||
ret = smalloc(sizeof(struct Socket_tag));
|
ret = smalloc(sizeof(struct Socket_tag));
|
||||||
ret->fn = &fn_table;
|
ret->fn = &tcp_fn_table;
|
||||||
ret->error = NULL;
|
ret->error = NULL;
|
||||||
ret->plug = plug;
|
ret->plug = plug;
|
||||||
bufchain_init(&ret->output_data);
|
bufchain_init(&ret->output_data);
|
||||||
@ -661,6 +637,35 @@ static void sk_tcp_close(Socket sock)
|
|||||||
sfree(s);
|
sfree(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sk_getxdmdata(void *sock, unsigned long *ip, int *port)
|
||||||
|
{
|
||||||
|
Actual_Socket s = (Actual_Socket) sock;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We must check that this socket really _is_ an Actual_Socket.
|
||||||
|
*/
|
||||||
|
if (s->fn != &tcp_fn_table)
|
||||||
|
return 0; /* failure */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we ever implement connecting to a local X server through
|
||||||
|
* a Unix socket, we return 0xFFFFFFFF for the IP address and
|
||||||
|
* our current pid for the port. Bizarre, but such is life.
|
||||||
|
*/
|
||||||
|
|
||||||
|
addrlen = sizeof(addr);
|
||||||
|
if (getsockname(s->s, (struct sockaddr *)&addr, &addrlen) < 0 ||
|
||||||
|
addr.sin_family != AF_INET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*ip = ntohl(addr.sin_addr.s_addr);
|
||||||
|
*port = ntohs(addr.sin_port);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The function which tries to send on a socket once it's deemed
|
* The function which tries to send on a socket once it's deemed
|
||||||
* writable.
|
* writable.
|
||||||
|
@ -88,6 +88,15 @@ GLOBAL void *logctx;
|
|||||||
*/
|
*/
|
||||||
#define SEL_NL { 13, 10 }
|
#define SEL_NL { 13, 10 }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sk_getxdmdata() does not exist under Windows (not that I
|
||||||
|
* couldn't write it if I wanted to, but I haven't bothered), so
|
||||||
|
* it's a macro which always returns FALSE. With any luck this will
|
||||||
|
* cause the compiler to notice it can optimise away the
|
||||||
|
* implementation of XDM-AUTHORIZATION-1 in x11fwd.c :-)
|
||||||
|
*/
|
||||||
|
#define sk_getxdmdata(socket, ip, port) (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exports from winctrls.c.
|
* Exports from winctrls.c.
|
||||||
*/
|
*/
|
||||||
|
19
x11fwd.c
19
x11fwd.c
@ -1,6 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "putty.h"
|
#include "putty.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
@ -52,7 +53,7 @@
|
|||||||
(endian=='B' ? PUT_16BIT_MSB_FIRST(cp, val) : PUT_16BIT_LSB_FIRST(cp, val))
|
(endian=='B' ? PUT_16BIT_MSB_FIRST(cp, val) : PUT_16BIT_LSB_FIRST(cp, val))
|
||||||
|
|
||||||
const char *const x11_authnames[] = {
|
const char *const x11_authnames[] = {
|
||||||
"", "MIT-MAGIC-COOKIE-1"
|
"", "MIT-MAGIC-COOKIE-1", "XDM-AUTHORIZATION-1"
|
||||||
};
|
};
|
||||||
|
|
||||||
struct X11Auth {
|
struct X11Auth {
|
||||||
@ -381,13 +382,27 @@ int x11_send(Socket s, char *data, int len)
|
|||||||
char realauthdata[64];
|
char realauthdata[64];
|
||||||
int realauthlen = 0;
|
int realauthlen = 0;
|
||||||
int authstrlen = strlen(x11_authnames[pr->auth->realproto]);
|
int authstrlen = strlen(x11_authnames[pr->auth->realproto]);
|
||||||
|
unsigned long ip;
|
||||||
|
int port;
|
||||||
static const char zeroes[4] = { 0,0,0,0 };
|
static const char zeroes[4] = { 0,0,0,0 };
|
||||||
|
|
||||||
if (pr->auth->realproto == X11_MIT) {
|
if (pr->auth->realproto == X11_MIT) {
|
||||||
assert(pr->auth->reallen <= lenof(realauthdata));
|
assert(pr->auth->reallen <= lenof(realauthdata));
|
||||||
realauthlen = pr->auth->reallen;
|
realauthlen = pr->auth->reallen;
|
||||||
memcpy(realauthdata, pr->auth->realdata, realauthlen);
|
memcpy(realauthdata, pr->auth->realdata, realauthlen);
|
||||||
}
|
} else if (pr->auth->realproto == X11_XDM &&
|
||||||
|
pr->auth->reallen == 16 &&
|
||||||
|
sk_getxdmdata(s, &ip, &port)) {
|
||||||
|
time_t t;
|
||||||
|
realauthlen = 24;
|
||||||
|
memset(realauthdata, 0, 24);
|
||||||
|
memcpy(realauthdata, pr->auth->realdata, 8);
|
||||||
|
PUT_32BIT_MSB_FIRST(realauthdata+8, ip);
|
||||||
|
PUT_16BIT_MSB_FIRST(realauthdata+12, port);
|
||||||
|
t = time(NULL);
|
||||||
|
PUT_32BIT_MSB_FIRST(realauthdata+14, t);
|
||||||
|
des_encrypt_xdmauth(pr->auth->realdata+9, realauthdata, 24);
|
||||||
|
}
|
||||||
/* implement other auth methods here if required */
|
/* implement other auth methods here if required */
|
||||||
|
|
||||||
PUT_16BIT(pr->firstpkt[0], pr->firstpkt + 6, authstrlen);
|
PUT_16BIT(pr->firstpkt[0], pr->firstpkt + 6, authstrlen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user