Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Diff of /trunk/ttssh2/ttxssh/x11util.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3226 by maya, Tue Mar 24 09:37:20 2009 UTC revision 3227 by maya, Tue Mar 24 15:10:33 2009 UTC
# Line 1  Line 1 
1  /*  /*
2  Copyright (c) 1998-2001, Robert O'Callahan  Copyright (c) 1998-2001, Robert O'Callahan
3  All rights reserved.  All rights reserved.
4    
5  Redistribution and use in source and binary forms, with or without modification,  Redistribution and use in source and binary forms, with or without modification,
6  are permitted provided that the following conditions are met:  are permitted provided that the following conditions are met:
7    
8  Redistributions of source code must retain the above copyright notice, this list of  Redistributions of source code must retain the above copyright notice, this list of
9  conditions and the following disclaimer.  conditions and the following disclaimer.
10    
11  Redistributions in binary form must reproduce the above copyright notice, this list  Redistributions in binary form must reproduce the above copyright notice, this list
12  of conditions and the following disclaimer in the documentation and/or other materials  of conditions and the following disclaimer in the documentation and/or other materials
13  provided with the distribution.  provided with the distribution.
14    
15  The name of Robert O'Callahan may not be used to endorse or promote products derived from  The name of Robert O'Callahan may not be used to endorse or promote products derived from
16  this software without specific prior written permission.  this software without specific prior written permission.
17    
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */  */
28    
29  #include "x11util.h"  #include "x11util.h"
30    
31  #include <openssl/rand.h>  #include <openssl/rand.h>
32  #include "util.h"  #include "util.h"
33  #include <stdlib.h>  #include <stdlib.h>
34    
35  typedef struct {  typedef struct {
36          PTInstVar pvar;          PTInstVar pvar;
37          X11AuthData FAR *auth_data;          X11AuthData FAR *auth_data;
38    
39          unsigned char FAR *init_buf;          unsigned char FAR *init_buf;
40          int init_buf_len;          int init_buf_len;
41          int init_data_len;          int init_data_len;
42  } X11UnspoofingFilterClosure;  } X11UnspoofingFilterClosure;
43    
44  void X11_get_DISPLAY_info(char FAR * name_buf, int name_buf_len,  void X11_get_DISPLAY_info(char FAR * name_buf, int name_buf_len,
45                            int FAR * port)                            int FAR * port)
46  {  {
47          char FAR *DISPLAY = getenv("DISPLAY");          char FAR *DISPLAY = getenv("DISPLAY");
48    
49          strncpy_s(name_buf, name_buf_len, "localhost", _TRUNCATE);          strncpy_s(name_buf, name_buf_len, "localhost", _TRUNCATE);
50          *port = 6000;          *port = 6000;
51    
52          if (DISPLAY != NULL) {          if (DISPLAY != NULL) {
53                  int i;                  int i;
54    
55                  for (i = 0; DISPLAY[i] != 0 && DISPLAY[i] != ':'; i++) {                  for (i = 0; DISPLAY[i] != 0 && DISPLAY[i] != ':'; i++) {
56                  }                  }
57    
58                  if (i > 0) {                  if (i > 0) {
59                          char c = DISPLAY[i];                          char c = DISPLAY[i];
60                          DISPLAY[i] = 0;                          DISPLAY[i] = 0;
61                          strncpy_s(name_buf, name_buf_len, DISPLAY, _TRUNCATE);                          strncpy_s(name_buf, name_buf_len, DISPLAY, _TRUNCATE);
62                          DISPLAY[i] = c;                          DISPLAY[i] = c;
63                  }                  }
64    
65                  if (DISPLAY[i] == ':') {                  if (DISPLAY[i] == ':') {
66                          *port = atoi(DISPLAY + i + 1) + 6000;                          *port = atoi(DISPLAY + i + 1) + 6000;
67                  }                  }
68          }          }
69  }  }
70    
71  X11AuthData FAR *X11_load_local_auth_data(int screen_num)  X11AuthData FAR *X11_load_local_auth_data(int screen_num)
72  {  {
73          X11AuthData FAR *auth_data =          X11AuthData FAR *auth_data =
74                  (X11AuthData FAR *) malloc(sizeof(X11AuthData));                  (X11AuthData FAR *) malloc(sizeof(X11AuthData));
75          char FAR *local_auth_data_str;          char FAR *local_auth_data_str;
76    
77          auth_data->local_protocol = getenv("TTSSH_XAUTH_PROTOCOL_NAME");          auth_data->local_protocol = getenv("TTSSH_XAUTH_PROTOCOL_NAME");
78    
79          local_auth_data_str = getenv("TTSSH_XAUTH_PROTOCOL_DATA");          local_auth_data_str = getenv("TTSSH_XAUTH_PROTOCOL_DATA");
80          if (local_auth_data_str == NULL) {          if (local_auth_data_str == NULL) {
81                  auth_data->local_data_len = 0;                  auth_data->local_data_len = 0;
82                  auth_data->local_data = NULL;                  auth_data->local_data = NULL;
83          } else {          } else {
84                  int str_len = strlen(local_auth_data_str);                  int str_len = strlen(local_auth_data_str);
85                  int i;                  int i;
86    
87                  auth_data->local_data_len = (str_len + 1) / 2;                  auth_data->local_data_len = (str_len + 1) / 2;
88                  auth_data->local_data = malloc(auth_data->local_data_len);                  auth_data->local_data = malloc(auth_data->local_data_len);
89    
90                  if (auth_data->local_data_len * 2 > str_len) {                  if (auth_data->local_data_len * 2 > str_len) {
91                          char buf[2] = { local_auth_data_str[0], 0 };                          char buf[2] = { local_auth_data_str[0], 0 };
92    
93                          auth_data->local_data[0] =                          auth_data->local_data[0] =
94                                  (unsigned char) strtol(buf, NULL, 16);                                  (unsigned char) strtol(buf, NULL, 16);
95                          i = 1;                          i = 1;
96                  } else {                  } else {
97                          i = 0;                          i = 0;
98                  }                  }
99    
100                  for (; i < str_len; i += 2) {                  for (; i < str_len; i += 2) {
101                          char buf[3] =                          char buf[3] =
102                                  { local_auth_data_str[i], local_auth_data_str[i + 1], 0 };                                  { local_auth_data_str[i], local_auth_data_str[i + 1], 0 };
103    
104                          auth_data->local_data[(i + 1) / 2] =                          auth_data->local_data[(i + 1) / 2] =
105                                  (unsigned char) strtol(buf, NULL, 16);                                  (unsigned char) strtol(buf, NULL, 16);
106                  }                  }
107          }          }
108    
109          auth_data->spoofed_protocol = _strdup("MIT-MAGIC-COOKIE-1");          auth_data->spoofed_protocol = _strdup("MIT-MAGIC-COOKIE-1");
110          auth_data->spoofed_data_len = 16;          auth_data->spoofed_data_len = 16;
111          auth_data->spoofed_data = malloc(auth_data->spoofed_data_len);          auth_data->spoofed_data = malloc(auth_data->spoofed_data_len);
112          RAND_bytes(auth_data->spoofed_data, auth_data->spoofed_data_len);          RAND_bytes(auth_data->spoofed_data, auth_data->spoofed_data_len);
113    
114          return auth_data;          return auth_data;
115  }  }
116    
117  void X11_dispose_auth_data(X11AuthData FAR * auth_data)  void X11_dispose_auth_data(X11AuthData FAR * auth_data)
118  {  {
119          memset(auth_data->local_data, 0, auth_data->local_data_len);          memset(auth_data->local_data, 0, auth_data->local_data_len);
120          free(auth_data->local_data);          free(auth_data->local_data);
121          free(auth_data->spoofed_protocol);          free(auth_data->spoofed_protocol);
122          memset(auth_data->spoofed_data, 0, auth_data->spoofed_data_len);          memset(auth_data->spoofed_data, 0, auth_data->spoofed_data_len);
123          free(auth_data->spoofed_data);          free(auth_data->spoofed_data);
124          free(auth_data);          free(auth_data);
125  }  }
126    
127  void *X11_init_unspoofing_filter(PTInstVar pvar,  void *X11_init_unspoofing_filter(PTInstVar pvar,
128                                   X11AuthData FAR * auth_data)                                   X11AuthData FAR * auth_data)
129  {  {
130          X11UnspoofingFilterClosure FAR *closure =          X11UnspoofingFilterClosure FAR *closure =
131                  malloc(sizeof(X11UnspoofingFilterClosure));                  malloc(sizeof(X11UnspoofingFilterClosure));
132    
133          closure->pvar = pvar;          closure->pvar = pvar;
134          closure->auth_data = auth_data;          closure->auth_data = auth_data;
135    
136          closure->init_data_len = 0;          closure->init_data_len = 0;
137          buf_create(&closure->init_buf, &closure->init_buf_len);          buf_create(&closure->init_buf, &closure->init_buf_len);
138    
139          return closure;          return closure;
140  }  }
141    
142  #define MERGE_NEED_MORE     0  #define MERGE_NEED_MORE     0
143  #define MERGE_GOT_GOOD_DATA 1  #define MERGE_GOT_GOOD_DATA 1
144  #define MERGE_GOT_BAD_DATA  2  #define MERGE_GOT_BAD_DATA  2
145    
146  static int merge_into_X11_init_packet(X11UnspoofingFilterClosure FAR *  static int merge_into_X11_init_packet(X11UnspoofingFilterClosure FAR *
147                                        closure, int length,                                        closure, int length,
148                                        unsigned char FAR * buf)                                        unsigned char FAR * buf)
149  {  {
150          buf_ensure_size_growing(&closure->init_buf, &closure->init_buf_len,          buf_ensure_size_growing(&closure->init_buf, &closure->init_buf_len,
151                                  closure->init_data_len + length);                                  closure->init_data_len + length);
152          memcpy(closure->init_buf + closure->init_data_len, buf, length);          memcpy(closure->init_buf + closure->init_data_len, buf, length);
153          closure->init_data_len += length;          closure->init_data_len += length;
154    
155          if (closure->init_data_len < 12) {          if (closure->init_data_len < 12) {
156                  return MERGE_NEED_MORE;                  return MERGE_NEED_MORE;
157          } else {          } else {
158                  int name_len;                  int name_len;
159                  int data_len;                  int data_len;
160                  int padded_name_len;                  int padded_name_len;
161                  int padded_data_len;                  int padded_data_len;
162    
163                  switch (closure->init_buf[0]) {                  switch (closure->init_buf[0]) {
164                  case 0x42:                              /* MSB first */                  case 0x42:                              /* MSB first */
165                          name_len = (closure->init_buf[6] << 8) | closure->init_buf[7];                          name_len = (closure->init_buf[6] << 8) | closure->init_buf[7];
166                          data_len = (closure->init_buf[8] << 8) | closure->init_buf[9];                          data_len = (closure->init_buf[8] << 8) | closure->init_buf[9];
167                          break;                          break;
168                  case 0x6C:                              /* LSB first */                  case 0x6C:                              /* LSB first */
169                          name_len = (closure->init_buf[7] << 8) | closure->init_buf[6];                          name_len = (closure->init_buf[7] << 8) | closure->init_buf[6];
170                          data_len = (closure->init_buf[9] << 8) | closure->init_buf[8];                          data_len = (closure->init_buf[9] << 8) | closure->init_buf[8];
171                          break;                          break;
172                  default:                  default:
173                          return MERGE_GOT_BAD_DATA;                          return MERGE_GOT_BAD_DATA;
174                  }                  }
175    
176                  padded_name_len = (name_len + 3) & ~0x3;                  padded_name_len = (name_len + 3) & ~0x3;
177                  padded_data_len = (data_len + 3) & ~0x3;                  padded_data_len = (data_len + 3) & ~0x3;
178    
179                  if (closure->init_data_len <                  if (closure->init_data_len <
180                      12 + padded_name_len + padded_data_len) {                      12 + padded_name_len + padded_data_len) {
181                          return MERGE_NEED_MORE;                          return MERGE_NEED_MORE;
182                  } else if (name_len ==                  } else if (name_len ==
183                             (int) strlen(closure->auth_data->spoofed_protocol)                             (int) strlen(closure->auth_data->spoofed_protocol)
184                             && memcmp(closure->init_buf + 12,                             && memcmp(closure->init_buf + 12,
185                                       closure->auth_data->spoofed_protocol,                                       closure->auth_data->spoofed_protocol,
186                                       name_len) == 0                                       name_len) == 0
187                             && data_len == closure->auth_data->spoofed_data_len                             && data_len == closure->auth_data->spoofed_data_len
188                             && memcmp(closure->init_buf + 12 + padded_name_len,                             && memcmp(closure->init_buf + 12 + padded_name_len,
189                                       closure->auth_data->spoofed_data,                                       closure->auth_data->spoofed_data,
190                                       data_len) == 0) {                                       data_len) == 0) {
191                          return MERGE_GOT_GOOD_DATA;                          return MERGE_GOT_GOOD_DATA;
192                  } else {                  } else {
193                          return MERGE_GOT_BAD_DATA;                          return MERGE_GOT_BAD_DATA;
194                  }                  }
195          }          }
196  }  }
197    
198  static void insert_real_X11_auth_data(X11UnspoofingFilterClosure FAR *  static void insert_real_X11_auth_data(X11UnspoofingFilterClosure FAR *
199                                        closure, int FAR * length,                                        closure, int FAR * length,
200                                        unsigned char FAR * FAR * buf)                                        unsigned char FAR * FAR * buf)
201  {  {
202          int name_len = closure->auth_data->local_protocol == NULL          int name_len = closure->auth_data->local_protocol == NULL
203                  ? 0 : strlen(closure->auth_data->local_protocol);                  ? 0 : strlen(closure->auth_data->local_protocol);
204          int data_len = closure->auth_data->local_data_len;          int data_len = closure->auth_data->local_data_len;
205          int padded_name_len = (name_len + 3) & ~0x3;          int padded_name_len = (name_len + 3) & ~0x3;
206          int padded_data_len = (data_len + 3) & ~0x3;          int padded_data_len = (data_len + 3) & ~0x3;
207    
208          *length = 12 + padded_name_len + padded_data_len;          *length = 12 + padded_name_len + padded_data_len;
209          buf_ensure_size(&closure->init_buf, &closure->init_buf_len, *length);          buf_ensure_size(&closure->init_buf, &closure->init_buf_len, *length);
210          *buf = closure->init_buf;          *buf = closure->init_buf;
211    
212          switch (closure->init_buf[0]) {          switch (closure->init_buf[0]) {
213          case 0x42:                                      /* MSB first */          case 0x42:                                      /* MSB first */
214                  closure->init_buf[6] = name_len >> 8;                  closure->init_buf[6] = name_len >> 8;
215                  closure->init_buf[7] = name_len & 0xFF;                  closure->init_buf[7] = name_len & 0xFF;
216                  closure->init_buf[8] = data_len >> 8;                  closure->init_buf[8] = data_len >> 8;
217                  closure->init_buf[9] = data_len & 0xFF;                  closure->init_buf[9] = data_len & 0xFF;
218                  break;                  break;
219          case 0x6C:                                      /* LSB first */          case 0x6C:                                      /* LSB first */
220                  closure->init_buf[7] = name_len >> 8;                  closure->init_buf[7] = name_len >> 8;
221                  closure->init_buf[6] = name_len & 0xFF;                  closure->init_buf[6] = name_len & 0xFF;
222                  closure->init_buf[9] = data_len >> 8;                  closure->init_buf[9] = data_len >> 8;
223                  closure->init_buf[8] = data_len & 0xFF;                  closure->init_buf[8] = data_len & 0xFF;
224                  break;                  break;
225          }          }
226    
227          memcpy(*buf + 12, closure->auth_data->local_protocol, name_len);          memcpy(*buf + 12, closure->auth_data->local_protocol, name_len);
228          memcpy(*buf + 12 + padded_name_len, closure->auth_data->local_data,          memcpy(*buf + 12 + padded_name_len, closure->auth_data->local_data,
229                 data_len);                 data_len);
230  }  }
231    
232  int X11_unspoofing_filter(void FAR * void_closure, int direction,  int X11_unspoofing_filter(void FAR * void_closure, int direction,
233                            int FAR * length, unsigned char FAR * FAR * buf)                            int FAR * length, unsigned char FAR * FAR * buf)
234  {  {
235          X11UnspoofingFilterClosure FAR *closure =          X11UnspoofingFilterClosure FAR *closure =
236                  (X11UnspoofingFilterClosure FAR *) void_closure;                  (X11UnspoofingFilterClosure FAR *) void_closure;
237    
238          if (length == NULL) {          if (length == NULL) {
239                  buf_destroy(&closure->init_buf, &closure->init_buf_len);                  buf_destroy(&closure->init_buf, &closure->init_buf_len);
240                  free(closure);                  free(closure);
241                  return FWD_FILTER_REMOVE;                  return FWD_FILTER_REMOVE;
242          } else if (direction == FWD_FILTER_FROM_SERVER) {          } else if (direction == FWD_FILTER_FROM_SERVER) {
243                  switch (merge_into_X11_init_packet(closure, *length, *buf)) {                  switch (merge_into_X11_init_packet(closure, *length, *buf)) {
244                  case MERGE_NEED_MORE:                  case MERGE_NEED_MORE:
245                          *length = 0;                          *length = 0;
246                          return FWD_FILTER_RETAIN;                          return FWD_FILTER_RETAIN;
247                  case MERGE_GOT_GOOD_DATA:                  case MERGE_GOT_GOOD_DATA:
248                          insert_real_X11_auth_data(closure, length, buf);                          insert_real_X11_auth_data(closure, length, buf);
249                          return FWD_FILTER_REMOVE;                          return FWD_FILTER_REMOVE;
250                  default:                  default:
251                  case MERGE_GOT_BAD_DATA:                  case MERGE_GOT_BAD_DATA:
252                          UTIL_get_lang_msg("MSG_X_AUTH_ERROR", closure->pvar,                          UTIL_get_lang_msg("MSG_X_AUTH_ERROR", closure->pvar,
253                                            "Remote X application sent incorrect authentication data.\n"                                            "Remote X application sent incorrect authentication data.\n"
254                                            "Its X session is being cancelled.");                                            "Its X session is being cancelled.");
255                          notify_nonfatal_error(closure->pvar, closure->pvar->ts->UIMsg);                          notify_nonfatal_error(closure->pvar, closure->pvar->ts->UIMsg);
256                          *length = 0;                          *length = 0;
257                          return FWD_FILTER_CLOSECHANNEL;                          return FWD_FILTER_CLOSECHANNEL;
258                  }                  }
259          } else {          } else {
260                  return FWD_FILTER_RETAIN;                  return FWD_FILTER_RETAIN;
261          }          }
262  }  }

Legend:
Removed from v.3226  
changed lines
  Added in v.3227

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26