|
Lines 98-103
static u_int channels_alloc = 0;
Link Here
|
| 98 |
*/ |
98 |
*/ |
| 99 |
static int channel_max_fd = 0; |
99 |
static int channel_max_fd = 0; |
| 100 |
|
100 |
|
|
|
101 |
/* |
| 102 |
* Flag indicating that channel fds have been modified, used to restart |
| 103 |
* preparations for select if necessary |
| 104 |
*/ |
| 105 |
static int channel_fds_changed = 0; |
| 101 |
|
106 |
|
| 102 |
/* -- tcp forwarding */ |
107 |
/* -- tcp forwarding */ |
| 103 |
|
108 |
|
|
Lines 138-160
static int all_opens_permitted = 0;
Link Here
|
| 138 |
/* Maximum number of fake X11 displays to try. */ |
143 |
/* Maximum number of fake X11 displays to try. */ |
| 139 |
#define MAX_DISPLAYS 1000 |
144 |
#define MAX_DISPLAYS 1000 |
| 140 |
|
145 |
|
| 141 |
/* Saved X11 local (client) display. */ |
146 |
struct x11_fwd { |
| 142 |
static char *x11_saved_display = NULL; |
147 |
/* Saved X11 local (client) display. */ |
| 143 |
|
148 |
char *saved_display; |
| 144 |
/* Saved X11 authentication protocol name. */ |
149 |
|
| 145 |
static char *x11_saved_proto = NULL; |
150 |
/* Saved X11 authentication protocol name. */ |
|
|
151 |
char *saved_proto; |
| 152 |
|
| 153 |
/* Saved X11 authentication data. These are the real data. */ |
| 154 |
u_char *saved_data; |
| 155 |
u_int saved_data_len; |
| 146 |
|
156 |
|
| 147 |
/* Saved X11 authentication data. This is the real data. */ |
157 |
/* |
| 148 |
static char *x11_saved_data = NULL; |
158 |
* Fake X11 authentication data. This is what the server will be |
| 149 |
static u_int x11_saved_data_len = 0; |
159 |
sending us; we should replace any occurrences with the real data. |
|
|
160 |
*/ |
| 161 |
u_char *fake_data; |
| 162 |
u_int fake_data_len; |
| 163 |
|
| 164 |
u_int usecount; |
| 165 |
struct x11_fwd *next; |
| 166 |
}; |
| 150 |
|
167 |
|
| 151 |
/* |
168 |
static struct x11_fwd *x11_fwds = NULL; |
| 152 |
* Fake X11 authentication data. This is what the server will be sending us; |
|
|
| 153 |
* we should replace any occurrences of this by the real data. |
| 154 |
*/ |
| 155 |
static u_char *x11_fake_data = NULL; |
| 156 |
static u_int x11_fake_data_len; |
| 157 |
|
169 |
|
|
|
170 |
static void x11_put_fwd(struct x11_fwd *fwd); |
| 158 |
|
171 |
|
| 159 |
/* -- agent forwarding */ |
172 |
/* -- agent forwarding */ |
| 160 |
|
173 |
|
|
Lines 224-229
static void
Link Here
|
| 224 |
channel_register_fds(Channel *c, int rfd, int wfd, int efd, |
237 |
channel_register_fds(Channel *c, int rfd, int wfd, int efd, |
| 225 |
int extusage, int nonblock, int is_tty) |
238 |
int extusage, int nonblock, int is_tty) |
| 226 |
{ |
239 |
{ |
|
|
240 |
c->rfd = rfd; |
| 241 |
c->wfd = wfd; |
| 242 |
c->sock = (rfd == wfd) ? rfd : -1; |
| 243 |
c->efd = efd; |
| 244 |
channel_fds_changed = 1; |
| 245 |
|
| 246 |
if (rfd == -1 && wfd == -1 && efd == -1) |
| 247 |
return; |
| 248 |
|
| 227 |
/* Update the maximum file descriptor value. */ |
249 |
/* Update the maximum file descriptor value. */ |
| 228 |
channel_max_fd = MAX(channel_max_fd, rfd); |
250 |
channel_max_fd = MAX(channel_max_fd, rfd); |
| 229 |
channel_max_fd = MAX(channel_max_fd, wfd); |
251 |
channel_max_fd = MAX(channel_max_fd, wfd); |
|
Lines 236-245
channel_register_fds(Channel *c, int rfd
Link Here
|
| 236 |
if (efd != -1 && efd != rfd && efd != wfd) |
258 |
if (efd != -1 && efd != rfd && efd != wfd) |
| 237 |
fcntl(efd, F_SETFD, FD_CLOEXEC); |
259 |
fcntl(efd, F_SETFD, FD_CLOEXEC); |
| 238 |
|
260 |
|
| 239 |
c->rfd = rfd; |
|
|
| 240 |
c->wfd = wfd; |
| 241 |
c->sock = (rfd == wfd) ? rfd : -1; |
| 242 |
c->efd = efd; |
| 243 |
c->extended_usage = extusage; |
261 |
c->extended_usage = extusage; |
| 244 |
|
262 |
|
| 245 |
if ((c->isatty = is_tty) != 0) |
263 |
if ((c->isatty = is_tty) != 0) |
|
Lines 423-428
channel_free(Channel *c)
Link Here
|
| 423 |
if (c->filter_cleanup != NULL && c->filter_ctx != NULL) |
441 |
if (c->filter_cleanup != NULL && c->filter_ctx != NULL) |
| 424 |
c->filter_cleanup(c->self, c->filter_ctx); |
442 |
c->filter_cleanup(c->self, c->filter_ctx); |
| 425 |
channels[c->self] = NULL; |
443 |
channels[c->self] = NULL; |
|
|
444 |
if (c->x11_fwd) |
| 445 |
x11_put_fwd(c->x11_fwd); |
| 426 |
xfree(c); |
446 |
xfree(c); |
| 427 |
} |
447 |
} |
| 428 |
|
448 |
|
|
Lines 869-874
channel_pre_output_draining(Channel *c,
Link Here
|
| 869 |
FD_SET(c->sock, writeset); |
889 |
FD_SET(c->sock, writeset); |
| 870 |
} |
890 |
} |
| 871 |
|
891 |
|
|
|
892 |
static struct x11_fwd * |
| 893 |
x11_lookup_fwd_by_fakedata(unsigned char *proto, u_int protolen, unsigned char *data, u_int datalen) |
| 894 |
{ |
| 895 |
struct x11_fwd *fwd; |
| 896 |
|
| 897 |
for (fwd = x11_fwds; fwd; fwd = fwd->next) { |
| 898 |
if (protolen == strlen(fwd->saved_proto) && |
| 899 |
!memcmp(fwd->saved_proto, proto, protolen) && |
| 900 |
fwd->fake_data_len == datalen && |
| 901 |
!memcmp(fwd->fake_data, data, datalen)) |
| 902 |
break; |
| 903 |
} |
| 904 |
return fwd; |
| 905 |
} |
| 906 |
|
| 907 |
static struct x11_fwd * |
| 908 |
x11_lookup_fwd_by_realdata(const char *display, const char *proto, const u_char *authdata, u_int datalen) |
| 909 |
{ |
| 910 |
struct x11_fwd *fwd; |
| 911 |
|
| 912 |
for (fwd = x11_fwds; fwd; fwd = fwd->next) { |
| 913 |
if (!strcmp(display, fwd->saved_display) && |
| 914 |
!strcmp(proto, fwd->saved_proto) && |
| 915 |
datalen == fwd->saved_data_len && |
| 916 |
!memcmp(authdata, fwd->saved_data, datalen)) |
| 917 |
break; |
| 918 |
} |
| 919 |
return fwd; |
| 920 |
} |
| 921 |
|
| 922 |
static void x11_put_fwd(struct x11_fwd *fwd) |
| 923 |
{ |
| 924 |
fwd->usecount--; |
| 925 |
debug("Decrease usecount on X11 forward data for %s to %d.", fwd->saved_display, fwd->usecount); |
| 926 |
if (!fwd->usecount) { |
| 927 |
struct x11_fwd **tmp = &x11_fwds; |
| 928 |
while (*tmp) { |
| 929 |
if (*tmp == fwd) { |
| 930 |
*tmp = fwd->next; |
| 931 |
xfree(fwd); |
| 932 |
return; |
| 933 |
} |
| 934 |
tmp = &(*tmp)->next; |
| 935 |
} |
| 936 |
fatal("X11 forward data not found."); |
| 937 |
} |
| 938 |
} |
| 939 |
|
| 872 |
/* |
940 |
/* |
| 873 |
* This is a special state for X11 authentication spoofing. An opened X11 |
941 |
* This is a special state for X11 authentication spoofing. An opened X11 |
| 874 |
* connection (when authentication spoofing is being done) remains in this |
942 |
* connection (when authentication spoofing is being done) remains in this |
|
Lines 879-888
channel_pre_output_draining(Channel *c,
Link Here
|
| 879 |
* Returns: 0 = need more data, -1 = wrong cookie, 1 = ok |
947 |
* Returns: 0 = need more data, -1 = wrong cookie, 1 = ok |
| 880 |
*/ |
948 |
*/ |
| 881 |
static int |
949 |
static int |
| 882 |
x11_open_helper(Buffer *b) |
950 |
x11_open_helper(Channel *c) |
| 883 |
{ |
951 |
{ |
|
|
952 |
Buffer *b = &c->output; |
| 884 |
u_char *ucp; |
953 |
u_char *ucp; |
| 885 |
u_int proto_len, data_len; |
954 |
u_int proto_len, data_len; |
|
|
955 |
struct x11_fwd *fwd; |
| 956 |
int sock; |
| 886 |
|
957 |
|
| 887 |
/* Check if the fixed size part of the packet is in buffer. */ |
958 |
/* Check if the fixed size part of the packet is in buffer. */ |
| 888 |
if (buffer_len(b) < 12) |
959 |
if (buffer_len(b) < 12) |
|
Lines 907-956
x11_open_helper(Buffer *b)
Link Here
|
| 907 |
12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) |
978 |
12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) |
| 908 |
return 0; |
979 |
return 0; |
| 909 |
|
980 |
|
| 910 |
/* Check if authentication protocol matches. */ |
981 |
fwd = x11_lookup_fwd_by_fakedata(ucp+12, proto_len, |
| 911 |
if (proto_len != strlen(x11_saved_proto) || |
982 |
ucp + 12 + ((proto_len + 3) & ~3), data_len); |
| 912 |
memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { |
983 |
|
| 913 |
debug2("X11 connection uses different authentication protocol."); |
984 |
if (!fwd) { |
| 914 |
return -1; |
985 |
debug("No matching X11 forward found."); |
| 915 |
} |
|
|
| 916 |
/* Check if authentication data matches our fake data. */ |
| 917 |
if (data_len != x11_fake_data_len || |
| 918 |
memcmp(ucp + 12 + ((proto_len + 3) & ~3), |
| 919 |
x11_fake_data, x11_fake_data_len) != 0) { |
| 920 |
debug2("X11 auth data does not match fake data."); |
| 921 |
return -1; |
| 922 |
} |
| 923 |
/* Check fake data length */ |
| 924 |
if (x11_fake_data_len != x11_saved_data_len) { |
| 925 |
error("X11 fake_data_len %d != saved_data_len %d", |
| 926 |
x11_fake_data_len, x11_saved_data_len); |
| 927 |
return -1; |
986 |
return -1; |
| 928 |
} |
987 |
} |
|
|
988 |
fwd->usecount++; |
| 989 |
debug("Increase use count for X11 fwd for display %s to %d.", fwd->saved_display, fwd->usecount); |
| 990 |
c->x11_fwd = fwd; |
| 929 |
/* |
991 |
/* |
| 930 |
* Received authentication protocol and data match |
992 |
* We found a matching X11 forward. Substitute the fake data |
| 931 |
* our fake data. Substitute the fake data with real |
993 |
* with real data. |
| 932 |
* data. |
|
|
| 933 |
*/ |
994 |
*/ |
| 934 |
memcpy(ucp + 12 + ((proto_len + 3) & ~3), |
995 |
memcpy(ucp + 12 + ((proto_len + 3) & ~3), |
| 935 |
x11_saved_data, x11_saved_data_len); |
996 |
fwd->saved_data, fwd->saved_data_len); |
| 936 |
return 1; |
997 |
|
|
|
998 |
sock = x11_connect_display(fwd->saved_display); |
| 999 |
if (sock == -1) |
| 1000 |
return -2; |
| 1001 |
channel_register_fds(c, sock, sock, -1, 0, 1, 0); |
| 1002 |
c->type = SSH_CHANNEL_OPEN; |
| 1003 |
|
| 1004 |
/* Because we registered a new fd, the channel_pre handlers will be |
| 1005 |
called again immediately. And because we changed the channel type |
| 1006 |
to SSH_CHANNEL_OPEN, the x11 function won't be called next time. |
| 1007 |
It's just a normal channel now */ |
| 1008 |
return 0; |
| 937 |
} |
1009 |
} |
| 938 |
|
1010 |
|
| 939 |
static void |
1011 |
static void |
| 940 |
channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset) |
1012 |
channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset) |
| 941 |
{ |
1013 |
{ |
| 942 |
int ret = x11_open_helper(&c->output); |
1014 |
int ret = x11_open_helper(c); |
| 943 |
|
1015 |
|
| 944 |
if (ret == 1) { |
1016 |
if (ret < 0) { |
| 945 |
/* Start normal processing for the channel. */ |
|
|
| 946 |
c->type = SSH_CHANNEL_OPEN; |
| 947 |
channel_pre_open_13(c, readset, writeset); |
| 948 |
} else if (ret == -1) { |
| 949 |
/* |
1017 |
/* |
| 950 |
* We have received an X11 connection that has bad |
1018 |
* We have received an X11 connection that has bad |
| 951 |
* authentication information. |
1019 |
* authentication information. |
| 952 |
*/ |
1020 |
*/ |
| 953 |
logit("X11 connection rejected because of wrong authentication."); |
1021 |
switch (ret) { |
|
|
1022 |
case -1: |
| 1023 |
logit("X11 connection rejected because of wrong authentication."); |
| 1024 |
break; |
| 1025 |
case -2: |
| 1026 |
logit("X11 connection rejected due to failure to connect to local server."); |
| 1027 |
break; |
| 1028 |
} |
| 954 |
buffer_clear(&c->input); |
1029 |
buffer_clear(&c->input); |
| 955 |
buffer_clear(&c->output); |
1030 |
buffer_clear(&c->output); |
| 956 |
channel_close_fd(&c->sock); |
1031 |
channel_close_fd(&c->sock); |
|
Lines 965-979
channel_pre_x11_open_13(Channel *c, fd_s
Link Here
|
| 965 |
static void |
1040 |
static void |
| 966 |
channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset) |
1041 |
channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset) |
| 967 |
{ |
1042 |
{ |
| 968 |
int ret = x11_open_helper(&c->output); |
1043 |
int ret = x11_open_helper(c); |
| 969 |
|
1044 |
|
| 970 |
/* c->force_drain = 1; */ |
1045 |
if (ret < 0) { |
| 971 |
|
1046 |
switch (ret) { |
| 972 |
if (ret == 1) { |
1047 |
case -1: |
| 973 |
c->type = SSH_CHANNEL_OPEN; |
1048 |
logit("X11 connection rejected because of wrong authentication."); |
| 974 |
channel_pre_open(c, readset, writeset); |
1049 |
break; |
| 975 |
} else if (ret == -1) { |
1050 |
case -2: |
| 976 |
logit("X11 connection rejected because of wrong authentication."); |
1051 |
logit("X11 connection rejected due to failure to connect to local server."); |
|
|
1052 |
break; |
| 1053 |
} |
| 977 |
debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); |
1054 |
debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); |
| 978 |
chan_read_failed(c); |
1055 |
chan_read_failed(c); |
| 979 |
buffer_clear(&c->input); |
1056 |
buffer_clear(&c->input); |
|
Lines 2089-2114
channel_prepare_select(fd_set **readsetp
Link Here
|
| 2089 |
{ |
2166 |
{ |
| 2090 |
u_int n, sz, nfdset; |
2167 |
u_int n, sz, nfdset; |
| 2091 |
|
2168 |
|
| 2092 |
n = MAX(*maxfdp, channel_max_fd); |
2169 |
for (channel_fds_changed = 1; channel_fds_changed;) { |
|
|
2170 |
channel_fds_changed = 0; |
| 2171 |
n = MAX(*maxfdp, channel_max_fd); |
| 2172 |
|
| 2173 |
nfdset = howmany(n+1, NFDBITS); |
| 2174 |
/* Explicitly test here, because xrealloc isn't always called */ |
| 2175 |
if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask)) |
| 2176 |
fatal("channel_prepare_select: max_fd (%d) is too large", n); |
| 2177 |
sz = nfdset * sizeof(fd_mask); |
| 2178 |
|
| 2179 |
/* perhaps check sz < nalloc/2 and shrink? */ |
| 2180 |
if (*readsetp == NULL || sz > *nallocp) { |
| 2181 |
*readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask)); |
| 2182 |
*writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask)); |
| 2183 |
*nallocp = sz; |
| 2184 |
} |
| 2185 |
*maxfdp = n; |
| 2186 |
memset(*readsetp, 0, sz); |
| 2187 |
memset(*writesetp, 0, sz); |
| 2093 |
|
2188 |
|
| 2094 |
nfdset = howmany(n+1, NFDBITS); |
2189 |
if (!rekeying) |
| 2095 |
/* Explicitly test here, because xrealloc isn't always called */ |
2190 |
channel_handler(channel_pre, *readsetp, *writesetp); |
| 2096 |
if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask)) |
2191 |
} |
| 2097 |
fatal("channel_prepare_select: max_fd (%d) is too large", n); |
|
|
| 2098 |
sz = nfdset * sizeof(fd_mask); |
| 2099 |
|
| 2100 |
/* perhaps check sz < nalloc/2 and shrink? */ |
| 2101 |
if (*readsetp == NULL || sz > *nallocp) { |
| 2102 |
*readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask)); |
| 2103 |
*writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask)); |
| 2104 |
*nallocp = sz; |
| 2105 |
} |
| 2106 |
*maxfdp = n; |
| 2107 |
memset(*readsetp, 0, sz); |
| 2108 |
memset(*writesetp, 0, sz); |
| 2109 |
|
2192 |
|
| 2110 |
if (!rekeying) |
|
|
| 2111 |
channel_handler(channel_pre, *readsetp, *writesetp); |
| 2112 |
} |
2193 |
} |
| 2113 |
|
2194 |
|
| 2114 |
/* |
2195 |
/* |
|
Lines 3348-3370
connect_local_xsocket(u_int dnr)
Link Here
|
| 3348 |
} |
3429 |
} |
| 3349 |
|
3430 |
|
| 3350 |
int |
3431 |
int |
| 3351 |
x11_connect_display(void) |
3432 |
x11_connect_display(char *display) |
| 3352 |
{ |
3433 |
{ |
| 3353 |
u_int display_number; |
3434 |
u_int display_number; |
| 3354 |
const char *display; |
|
|
| 3355 |
char buf[1024], *cp; |
3435 |
char buf[1024], *cp; |
| 3356 |
struct addrinfo hints, *ai, *aitop; |
3436 |
struct addrinfo hints, *ai, *aitop; |
| 3357 |
char strport[NI_MAXSERV]; |
3437 |
char strport[NI_MAXSERV]; |
| 3358 |
int gaierr, sock = 0; |
3438 |
int gaierr, sock = 0; |
| 3359 |
|
3439 |
|
| 3360 |
/* Try to open a socket for the local X server. */ |
|
|
| 3361 |
display = getenv("DISPLAY"); |
| 3362 |
if (!display) { |
| 3363 |
error("DISPLAY not set."); |
| 3364 |
return -1; |
| 3365 |
} |
| 3366 |
/* |
3440 |
/* |
| 3367 |
* Now we decode the value of the DISPLAY variable and make a |
3441 |
* Decode the value of the DISPLAY variable and make a |
| 3368 |
* connection to the real X server. |
3442 |
* connection to the real X server. |
| 3369 |
*/ |
3443 |
*/ |
| 3370 |
|
3444 |
|
|
Lines 3465-3471
void
Link Here
|
| 3465 |
x11_input_open(int type, u_int32_t seq, void *ctxt) |
3539 |
x11_input_open(int type, u_int32_t seq, void *ctxt) |
| 3466 |
{ |
3540 |
{ |
| 3467 |
Channel *c = NULL; |
3541 |
Channel *c = NULL; |
| 3468 |
int remote_id, sock = 0; |
3542 |
int remote_id; |
| 3469 |
char *remote_host; |
3543 |
char *remote_host; |
| 3470 |
|
3544 |
|
| 3471 |
debug("Received X11 open request."); |
3545 |
debug("Received X11 open request."); |
|
Lines 3479-3505
x11_input_open(int type, u_int32_t seq,
Link Here
|
| 3479 |
} |
3553 |
} |
| 3480 |
packet_check_eom(); |
3554 |
packet_check_eom(); |
| 3481 |
|
3555 |
|
| 3482 |
/* Obtain a connection to the real X display. */ |
3556 |
/* Allocate a channel for this connection. */ |
| 3483 |
sock = x11_connect_display(); |
3557 |
c = channel_new("connected x11 socket", |
| 3484 |
if (sock != -1) { |
3558 |
SSH_CHANNEL_X11_OPEN, -1, -1, -1, 0, 0, 0, |
| 3485 |
/* Allocate a channel for this connection. */ |
3559 |
remote_host, 1); |
| 3486 |
c = channel_new("connected x11 socket", |
3560 |
c->remote_id = remote_id; |
| 3487 |
SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0, |
3561 |
c->force_drain = 1; |
| 3488 |
remote_host, 1); |
3562 |
|
| 3489 |
c->remote_id = remote_id; |
|
|
| 3490 |
c->force_drain = 1; |
| 3491 |
} |
| 3492 |
xfree(remote_host); |
3563 |
xfree(remote_host); |
| 3493 |
if (c == NULL) { |
3564 |
|
| 3494 |
/* Send refusal to the remote host. */ |
3565 |
/* Send a confirmation to the remote host. */ |
| 3495 |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
3566 |
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |
| 3496 |
packet_put_int(remote_id); |
3567 |
packet_put_int(remote_id); |
| 3497 |
} else { |
3568 |
packet_put_int(c->self); |
| 3498 |
/* Send a confirmation to the remote host. */ |
3569 |
|
| 3499 |
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |
|
|
| 3500 |
packet_put_int(remote_id); |
| 3501 |
packet_put_int(c->self); |
| 3502 |
} |
| 3503 |
packet_send(); |
3570 |
packet_send(); |
| 3504 |
} |
3571 |
} |
| 3505 |
|
3572 |
|
|
Lines 3536-3556
void
Link Here
|
| 3536 |
x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, |
3603 |
x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, |
| 3537 |
const char *proto, const char *data) |
3604 |
const char *proto, const char *data) |
| 3538 |
{ |
3605 |
{ |
|
|
3606 |
Channel *c = NULL; |
| 3539 |
u_int data_len = (u_int) strlen(data) / 2; |
3607 |
u_int data_len = (u_int) strlen(data) / 2; |
| 3540 |
u_int i, value; |
3608 |
u_int i, value; |
| 3541 |
char *new_data; |
3609 |
char *new_data; |
|
|
3610 |
u_char *realdata; |
| 3542 |
int screen_number; |
3611 |
int screen_number; |
| 3543 |
const char *cp; |
3612 |
const char *cp; |
| 3544 |
u_int32_t rnd = 0; |
3613 |
u_int32_t rnd = 0; |
|
|
3614 |
struct x11_fwd *fwd; |
| 3545 |
|
3615 |
|
| 3546 |
if (x11_saved_display == NULL) |
3616 |
if (compat20) { |
| 3547 |
x11_saved_display = xstrdup(disp); |
3617 |
c = channel_lookup(client_session_id); |
| 3548 |
else if (strcmp(disp, x11_saved_display) != 0) { |
3618 |
if (!c) |
| 3549 |
error("x11_request_forwarding_with_spoofing: different " |
3619 |
error("%s: channel %d: unknown channel", __func__, client_session_id); |
| 3550 |
"$DISPLAY already forwarded"); |
3620 |
} |
| 3551 |
return; |
3621 |
|
|
|
3622 |
/* Convert real authentication data to binary */ |
| 3623 |
realdata = xmalloc(data_len); |
| 3624 |
for (i = 0; i < data_len; i++) { |
| 3625 |
if (sscanf(data + 2 * i, "%2x", &value) != 1) |
| 3626 |
fatal("x11_request_forwarding: bad " |
| 3627 |
"authentication data: %.100s", data); |
| 3628 |
realdata[i] = value; |
| 3629 |
} |
| 3630 |
|
| 3631 |
fwd = x11_lookup_fwd_by_realdata(disp, proto, realdata, data_len); |
| 3632 |
if (fwd) { |
| 3633 |
fwd->usecount++; |
| 3634 |
debug("Increase use count for X11 fwd for display %s to %d.", disp, fwd->usecount); |
| 3635 |
xfree(realdata); |
| 3636 |
} else { |
| 3637 |
/* No existing forward. Create a new one */ |
| 3638 |
debug("Create new X11 fake auth data for display %s.", disp); |
| 3639 |
fwd = xmalloc(sizeof(*fwd)); |
| 3640 |
fwd->saved_display = xstrdup(disp); |
| 3641 |
fwd->saved_proto = xstrdup(proto); |
| 3642 |
fwd->saved_data = realdata; |
| 3643 |
fwd->saved_data_len = data_len; |
| 3644 |
fwd->fake_data = xmalloc(data_len); |
| 3645 |
fwd->fake_data_len = data_len; |
| 3646 |
|
| 3647 |
for (i = 0; i < data_len; i++) { |
| 3648 |
if (i % 4 == 0) |
| 3649 |
rnd = arc4random(); |
| 3650 |
fwd->fake_data[i] = rnd & 0xff; |
| 3651 |
rnd >>= 8; |
| 3652 |
} |
| 3653 |
|
| 3654 |
fwd->usecount = 1; |
| 3655 |
fwd->next = x11_fwds; |
| 3656 |
x11_fwds = fwd; |
| 3552 |
} |
3657 |
} |
| 3553 |
|
3658 |
|
|
|
3659 |
if (c) |
| 3660 |
c->x11_fwd = fwd; |
| 3661 |
|
| 3554 |
cp = strchr(disp, ':'); |
3662 |
cp = strchr(disp, ':'); |
| 3555 |
if (cp) |
3663 |
if (cp) |
| 3556 |
cp = strchr(cp, '.'); |
3664 |
cp = strchr(cp, '.'); |
|
Lines 3559-3589
x11_request_forwarding_with_spoofing(int
Link Here
|
| 3559 |
else |
3667 |
else |
| 3560 |
screen_number = 0; |
3668 |
screen_number = 0; |
| 3561 |
|
3669 |
|
| 3562 |
if (x11_saved_proto == NULL) { |
|
|
| 3563 |
/* Save protocol name. */ |
| 3564 |
x11_saved_proto = xstrdup(proto); |
| 3565 |
/* |
| 3566 |
* Extract real authentication data and generate fake data |
| 3567 |
* of the same length. |
| 3568 |
*/ |
| 3569 |
x11_saved_data = xmalloc(data_len); |
| 3570 |
x11_fake_data = xmalloc(data_len); |
| 3571 |
for (i = 0; i < data_len; i++) { |
| 3572 |
if (sscanf(data + 2 * i, "%2x", &value) != 1) |
| 3573 |
fatal("x11_request_forwarding: bad " |
| 3574 |
"authentication data: %.100s", data); |
| 3575 |
if (i % 4 == 0) |
| 3576 |
rnd = arc4random(); |
| 3577 |
x11_saved_data[i] = value; |
| 3578 |
x11_fake_data[i] = rnd & 0xff; |
| 3579 |
rnd >>= 8; |
| 3580 |
} |
| 3581 |
x11_saved_data_len = data_len; |
| 3582 |
x11_fake_data_len = data_len; |
| 3583 |
} |
| 3584 |
|
| 3585 |
/* Convert the fake data into hex. */ |
3670 |
/* Convert the fake data into hex. */ |
| 3586 |
new_data = tohex(x11_fake_data, data_len); |
3671 |
new_data = tohex(fwd->fake_data, data_len); |
| 3587 |
|
3672 |
|
| 3588 |
/* Send the request packet. */ |
3673 |
/* Send the request packet. */ |
| 3589 |
if (compat20) { |
3674 |
if (compat20) { |