Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3012 - (show annotations) (download) (as text)
Sat Sep 29 11:01:26 2007 UTC (16 years, 6 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 189529 byte(s)
ソケットをノンブロッキングのままでパケット送信を行う。

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 The name of Robert O'Callahan may not be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "util.h"
32
33 #include <openssl/bn.h>
34 #include <openssl/evp.h>
35 #include <openssl/dh.h>
36 #include <openssl/engine.h>
37 #include <openssl/rsa.h>
38 #include <openssl/dsa.h>
39 #include <limits.h>
40 #include <malloc.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include <process.h>
44 #include <time.h>
45 #include "buffer.h"
46 #include "ssh.h"
47 #include "crypt.h"
48 #include "fwd.h"
49
50 // SSH2 macro
51 #ifdef _DEBUG
52 #define SSH2_DEBUG
53 #endif
54
55 #define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
56 #define INTBLOB_LEN 20
57 #define SIGBLOB_LEN (2*INTBLOB_LEN)
58
59 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
60
61 static void try_send_credentials(PTInstVar pvar);
62 static void prep_compression(PTInstVar pvar);
63
64 // �����v���g�^�C�v����
65 void SSH2_send_kexinit(PTInstVar pvar);
66 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
67 static void SSH2_dh_kex_init(PTInstVar pvar);
68 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
69 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
70 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
71 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
72 static BOOL handle_SSH2_authrequest(PTInstVar pvar);
73 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
74 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
75 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
76 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
77 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
78 static BOOL handle_SSH2_request_success(PTInstVar pvar);
79 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
80 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
81 static BOOL handle_SSH2_channel_data(PTInstVar pvar);
82 static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
83 static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
84 static BOOL handle_SSH2_channel_close(PTInstVar pvar);
85 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
86 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
87 static BOOL handle_SSH2_channel_request(PTInstVar pvar);
88 void SSH2_dispatch_init(int stage);
89 int SSH2_dispatch_enabled_check(unsigned char message);
90 void SSH2_dispatch_add_message(unsigned char message);
91 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
92 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
93 static void start_ssh_heartbeat_thread(PTInstVar pvar);
94
95
96 //
97 // SSH2 data structure
98 //
99
100 /* default window/packet sizes for tcp/x11-fwd-channel */
101 #define CHAN_SES_PACKET_DEFAULT (32*1024)
102 #define CHAN_SES_WINDOW_DEFAULT (2*CHAN_SES_PACKET_DEFAULT) // READAMOUNT @ pkt.c����������������
103 #define CHAN_TCP_PACKET_DEFAULT (32*1024)
104 #define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
105 #define CHAN_X11_PACKET_DEFAULT (16*1024)
106 #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
107
108 // channel data structure
109 #define CHANNEL_MAX 100
110
111 enum channel_type {
112 TYPE_SHELL, TYPE_PORTFWD,
113 };
114
115 typedef struct channel {
116 int used;
117 int self_id;
118 int remote_id;
119 unsigned int local_window;
120 unsigned int local_window_max;
121 unsigned int local_consumed;
122 unsigned int local_maxpacket;
123 unsigned int remote_window;
124 unsigned int remote_maxpacket;
125 enum channel_type type;
126 int local_num;
127 } Channel_t;
128
129 static Channel_t channels[CHANNEL_MAX];
130
131 //
132 // channel function
133 //
134 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
135 enum confirm_type type, int local_num)
136 {
137 int i, found;
138 Channel_t *c;
139
140 found = -1;
141 for (i = 0 ; i < CHANNEL_MAX ; i++) {
142 if (channels[i].used == 0) { // free channel
143 found = i;
144 break;
145 }
146 }
147 if (found == -1) { // not free channel
148 return (NULL);
149 }
150
151 // setup
152 c = &channels[found];
153 c->used = 1;
154 c->self_id = i;
155 c->remote_id = -1;
156 c->local_window = window;
157 c->local_window_max = window;
158 c->local_consumed = 0;
159 c->local_maxpacket = maxpack;
160 c->remote_window = 0;
161 c->remote_maxpacket = 0;
162 c->type = type;
163 c->local_num = local_num; // alloc_channel()�����l��������������
164
165 return (c);
166 }
167
168
169 // channel close�����`���l���\���������X�g�����p����
170 // (2007.4.26 yutaka)
171 static void ssh2_channel_delete(Channel_t *c)
172 {
173 memset(c, 0, sizeof(Channel_t));
174 c->used = 0;
175 }
176
177
178 // connection close������������
179 void ssh2_channel_free(void)
180 {
181 int i;
182 Channel_t *c;
183
184 for (i = 0 ; i < CHANNEL_MAX ; i++) {
185 c = &channels[i];
186 memset(c, 0, sizeof(Channel_t));
187 }
188
189 }
190
191 static Channel_t *ssh2_channel_lookup(int id)
192 {
193 Channel_t *c;
194
195 if (id < 0 || id >= CHANNEL_MAX) {
196 return (NULL);
197 }
198 c = &channels[id];
199 if (c->used == 0) { // already freed
200 return (NULL);
201 }
202 return (c);
203 }
204
205 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
206 // TODO: �����I�����`���l���\������1�������������B
207 // (2005.6.12 yutaka)
208 static Channel_t *ssh2_local_channel_lookup(int local_num)
209 {
210 int i;
211 Channel_t *c;
212
213 for (i = 0 ; i < CHANNEL_MAX ; i++) {
214 c = &channels[i];
215 if (c->local_num == local_num)
216 return (c);
217 }
218 return (NULL);
219 }
220
221
222 //
223 // SSH heartbeat mutex
224 //
225 static CRITICAL_SECTION g_ssh_heartbeat_lock; /* ���b�N�p���� */
226
227 void ssh_heartbeat_lock_initialize(void)
228 {
229 InitializeCriticalSection(&g_ssh_heartbeat_lock);
230 }
231
232 void ssh_heartbeat_lock_finalize(void)
233 {
234 DeleteCriticalSection(&g_ssh_heartbeat_lock);
235 }
236
237 void ssh_heartbeat_lock(void)
238 {
239 EnterCriticalSection(&g_ssh_heartbeat_lock);
240 }
241
242 void ssh_heartbeat_unlock(void)
243 {
244 LeaveCriticalSection(&g_ssh_heartbeat_lock);
245 }
246
247
248 //
249 // SSH memory dump (for debug)
250 //
251 // (2005.3.7 yutaka)
252 //
253 #define MEMTAG_MAX 100
254 #define LOGDUMP "ssh2dump.log"
255 #define SENDTOME "Please send '"LOGDUMP"' file to TeraTerm developer team."
256
257 typedef struct memtag {
258 char *name;
259 char *desc;
260 int len;
261 char *data;
262 } memtag_t;
263
264 static memtag_t memtags[MEMTAG_MAX];
265 static int memtag_count = 0;
266 static int memtag_use = 0;
267
268 /* �_���v���C�����t�H�[�}�b�g�\������ */
269 static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
270 {
271 int i, c;
272
273 /* �������A�h���X�\�� */
274 fprintf(fp, "%08X : ", addr);
275
276 /* �o�C�i���\���i4�o�C�g�������������}���j*/
277 for (i = 0 ; i < byte_cnt ; i++) {
278 if (i > 0 && i % 4 == 0)
279 fprintf(fp, " ");
280
281 fprintf(fp, "%02X", bytes[i]);
282 }
283
284 /* ASCII�\���������������������� */
285 fprintf(fp, " %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
286
287 /* ASCII�\�� */
288 for (i = 0 ; i < byte_cnt ; i++) {
289 c = bytes[i];
290 if (c >= 0x20 && c <= 0x7f) {
291 fprintf(fp, "%c", c);
292 } else {
293 fprintf(fp, ".");
294 }
295 }
296
297 fprintf(fp, "\n");
298 }
299
300
301 /* �_���v���[�`�� */
302 static void dump_memdump(FILE *fp, char *data, int len)
303 {
304 int c, addr;
305 int bytes[16], *ptr;
306 int byte_cnt;
307 int i;
308
309 addr = 0;
310 byte_cnt = 0;
311 ptr = bytes;
312 for (i = 0 ; i < len ; i++) {
313 c = data[i];
314 *ptr++ = c & 0xff;
315 byte_cnt++;
316
317 if (byte_cnt == 16) {
318 displine_memdump(fp, addr, bytes, byte_cnt);
319
320 addr += 16;
321 byte_cnt = 0;
322 ptr = bytes;
323 }
324 }
325
326 if (byte_cnt > 0) {
327 displine_memdump(fp, addr, bytes, byte_cnt);
328 }
329 }
330
331 void init_memdump(void)
332 {
333 int i;
334
335 for (i = 0 ; i < MEMTAG_MAX ; i++) {
336 memtags[i].name = NULL;
337 memtags[i].desc = NULL;
338 memtags[i].data = NULL;
339 memtags[i].len = 0;
340 }
341 memtag_use++;
342 }
343
344 void finish_memdump(void)
345 {
346 int i;
347
348 // initialize�������������������������������B(2005.4.3 yutaka)
349 if (memtag_use <= 0)
350 return;
351 memtag_use--;
352
353 for (i = 0 ; i < MEMTAG_MAX ; i++) {
354 free(memtags[i].name);
355 free(memtags[i].desc);
356 free(memtags[i].data);
357 memtags[i].len = 0;
358 }
359 }
360
361 void save_memdump(char *filename)
362 {
363 FILE *fp;
364 int i;
365 time_t t;
366 struct tm *tm;
367
368 fp = fopen(filename, "w");
369 if (fp == NULL)
370 return;
371
372 t = time(NULL);
373 tm = localtime(&t);
374
375 fprintf(fp, "<<< TeraTerm SSH2 log dump >>>\n");
376 fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
377 tm->tm_year + 1900,
378 tm->tm_mon + 1,
379 tm->tm_mday,
380 tm->tm_hour,
381 tm->tm_min,
382 tm->tm_sec);
383 fprintf(fp, "\n");
384
385 for (i = 0 ; i < memtag_count ; i++) {
386 fprintf(fp, "============================================\n");
387 fprintf(fp, "name: %s\n", memtags[i].name);
388 fprintf(fp, "--------------------------------------------\n");
389 fprintf(fp, "description: %s\n", memtags[i].desc);
390 fprintf(fp, "============================================\n");
391 dump_memdump(fp, memtags[i].data, memtags[i].len);
392 fprintf(fp, "\n\n\n");
393 }
394
395 fprintf(fp, "[EOF]\n");
396
397 fclose(fp);
398 }
399
400 void push_memdump(char *name, char *desc, char *data, int len)
401 {
402 memtag_t *ptr;
403 char *dp;
404
405 dp = malloc(len);
406 if (dp == NULL)
407 return;
408 memcpy(dp, data, len);
409
410 if (memtag_count >= MEMTAG_MAX)
411 return;
412
413 ptr = &memtags[memtag_count];
414 memtag_count++;
415 ptr->name = _strdup(name);
416 ptr->desc = _strdup(desc);
417 ptr->data = dp;
418 ptr->len = len;
419 }
420
421 void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
422 {
423 int len;
424 char *buf;
425
426 len = BN_num_bytes(bignum);
427 buf = malloc(len); // allocate
428 if (buf == NULL)
429 return;
430 BN_bn2bin(bignum, buf);
431 push_memdump(name, desc, buf, len); // at push_bignum_memdump()
432 free(buf); // free
433 }
434
435
436 //
437 //
438 //
439
440
441 static int get_predecryption_amount(PTInstVar pvar)
442 {
443 static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
444
445 if (SSHv1(pvar)) {
446 return 0;
447 } else {
448 int block_size = CRYPT_get_decryption_block_size(pvar);
449
450 if (block_size < 5) {
451 return small_block_decryption_sizes[block_size];
452 } else {
453 return block_size;
454 }
455 }
456 }
457
458 /* Get up to 'limit' bytes into the payload buffer.
459 'limit' is counted from the start of the payload data.
460 Returns the amount of data in the payload buffer, or
461 -1 if there is an error.
462 We can return more than limit in some cases. */
463 static int buffer_packet_data(PTInstVar pvar, int limit)
464 {
465 if (pvar->ssh_state.payloadlen >= 0) {
466 return pvar->ssh_state.payloadlen;
467 } else {
468 int cur_decompressed_bytes =
469 pvar->ssh_state.decompress_stream.next_out -
470 pvar->ssh_state.postdecompress_inbuf;
471
472 while (limit > cur_decompressed_bytes) {
473 int result;
474
475 pvar->ssh_state.payload =
476 pvar->ssh_state.postdecompress_inbuf + 1;
477 if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
478 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
479 &pvar->ssh_state.postdecompress_inbuflen,
480 min(limit, cur_decompressed_bytes * 2));
481 }
482
483 pvar->ssh_state.decompress_stream.next_out =
484 pvar->ssh_state.postdecompress_inbuf +
485 cur_decompressed_bytes;
486 pvar->ssh_state.decompress_stream.avail_out =
487 min(limit, pvar->ssh_state.postdecompress_inbuflen)
488 - cur_decompressed_bytes;
489
490 result =
491 inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
492 cur_decompressed_bytes =
493 pvar->ssh_state.decompress_stream.next_out -
494 pvar->ssh_state.postdecompress_inbuf;
495
496 switch (result) {
497 case Z_OK:
498 break;
499 case Z_BUF_ERROR:
500 pvar->ssh_state.payloadlen = cur_decompressed_bytes;
501 return cur_decompressed_bytes;
502 default:
503 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
504 "Invalid compressed data in received packet");
505 notify_fatal_error(pvar, pvar->ts->UIMsg);
506 return -1;
507 }
508 }
509
510 return cur_decompressed_bytes;
511 }
512 }
513
514 /* For use by the protocol processing code.
515 Gets N bytes of uncompressed payload. Returns FALSE if data not available
516 and a fatal error has been signaled.
517 The data is available in the payload buffer. This buffer address
518 can change during a call to grab_payload, so take care!
519 The payload pointer is set to point to the first byte of the actual data
520 (after the packet type byte).
521 */
522 static BOOL grab_payload(PTInstVar pvar, int num_bytes)
523 {
524 /* Accept maximum of 4MB of payload data */
525 int in_buffer = buffer_packet_data(pvar, 4 * 1024 * 1024);
526
527 if (in_buffer < 0) {
528 return FALSE;
529 } else {
530 pvar->ssh_state.payload_grabbed += num_bytes;
531 if (pvar->ssh_state.payload_grabbed > in_buffer) {
532 char buf[128];
533 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
534 "Received truncated packet (%ld > %d) @ grab_payload()");
535 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
536 pvar->ssh_state.payload_grabbed, in_buffer);
537 notify_fatal_error(pvar, buf);
538 return FALSE;
539 } else {
540 return TRUE;
541 }
542 }
543 }
544
545 static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
546 {
547 int in_buffer;
548
549 pvar->ssh_state.payload_grabbed += num_bytes;
550 in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
551
552 if (in_buffer < 0) {
553 return FALSE;
554 } else {
555 if (pvar->ssh_state.payload_grabbed > in_buffer) {
556 char buf[128];
557 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
558 "Received truncated packet (%ld > %d) @ grab_payload_limited()");
559 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
560 pvar->ssh_state.payload_grabbed, in_buffer);
561 notify_fatal_error(pvar, buf);
562 return FALSE;
563 } else {
564 return TRUE;
565 }
566 }
567 }
568
569 #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
570 #define get_uint32(buf) get_uint32_MSBfirst((buf))
571 #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
572 #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
573 #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
574
575 #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
576
577 /* Decrypt the payload, checksum it, eat the padding, get the packet type
578 and return it.
579 'data' points to the start of the packet --- its length field.
580 'len' is the length of the
581 payload + padding (+ length of CRC for SSHv1). 'padding' is the length
582 of the padding alone. */
583 static int prep_packet(PTInstVar pvar, char FAR * data, int len,
584 int padding)
585 {
586 pvar->ssh_state.payload = data + 4;
587 pvar->ssh_state.payloadlen = len;
588
589 if (SSHv1(pvar)) {
590 if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
591 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
592 "'CORE insertion attack' detected. Aborting connection.");
593 notify_fatal_error(pvar, pvar->ts->UIMsg);
594 }
595
596 CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
597 /* PKT guarantees that the data is always 4-byte aligned */
598 if (do_crc(pvar->ssh_state.payload, len - 4) !=
599 get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
600 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
601 "Detected corrupted data; connection terminating.");
602 notify_fatal_error(pvar, pvar->ts->UIMsg);
603 return SSH_MSG_NONE;
604 }
605
606 pvar->ssh_state.payload += padding;
607 pvar->ssh_state.payloadlen -= padding + 4;
608 } else {
609 int already_decrypted = get_predecryption_amount(pvar);
610
611 #if 0
612 CRYPT_decrypt(pvar, data + already_decrypted,
613 len - already_decrypted);
614 #else
615 CRYPT_decrypt(pvar, data + already_decrypted,
616 (4 + len) - already_decrypted);
617 #endif
618
619 if (!CRYPT_verify_receiver_MAC
620 (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
621 data + len + 4)) {
622 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
623 "Detected corrupted data; connection terminating.");
624 notify_fatal_error(pvar, pvar->ts->UIMsg);
625 return SSH_MSG_NONE;
626 }
627
628 pvar->ssh_state.payload++;
629 pvar->ssh_state.payloadlen -= padding + 1;
630 }
631
632 pvar->ssh_state.payload_grabbed = 0;
633
634 if (SSHv1(pvar)) {
635 if (pvar->ssh_state.decompressing) {
636 if (pvar->ssh_state.decompress_stream.avail_in != 0) {
637 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
638 "Internal error: a packet was not fully decompressed.\n"
639 "This is a bug, please report it.");
640 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
641 }
642
643 pvar->ssh_state.decompress_stream.next_in =
644 pvar->ssh_state.payload;
645 pvar->ssh_state.decompress_stream.avail_in =
646 pvar->ssh_state.payloadlen;
647 pvar->ssh_state.decompress_stream.next_out =
648 pvar->ssh_state.postdecompress_inbuf;
649 pvar->ssh_state.payloadlen = -1;
650 } else {
651 pvar->ssh_state.payload++;
652 }
653
654 if (!grab_payload_limited(pvar, 1)) {
655 return SSH_MSG_NONE;
656 }
657
658 } else {
659 // support of SSH2 packet compression (2005.7.9 yutaka)
660 // support of "Compression delayed" (2006.6.23 maya)
661 if ((pvar->stoc_compression == COMP_ZLIB ||
662 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
663 pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
664 int ret;
665
666 if (pvar->decomp_buffer == NULL) {
667 pvar->decomp_buffer = buffer_init();
668 if (pvar->decomp_buffer == NULL)
669 return SSH_MSG_NONE;
670 }
671 // ���x�m�������o�b�t�@���g�������������������Y�������B
672 buffer_clear(pvar->decomp_buffer);
673
674 // packet size��padding�������������y�C���[�h�����������W�J�����B
675 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
676 pvar->ssh_state.payload,
677 pvar->ssh_state.payloadlen,
678 pvar->decomp_buffer);
679
680 // �|�C���^���X�V�B
681 pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
682 pvar->ssh_state.payload++;
683 pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
684
685 } else {
686 pvar->ssh_state.payload++;
687 }
688
689 if (!grab_payload_limited(pvar, 1)) {
690 return SSH_MSG_NONE;
691 }
692
693 }
694
695 pvar->ssh_state.receiver_sequence_number++;
696
697 return pvar->ssh_state.payload[-1];
698 }
699
700 /* Create a packet to be sent. The SSH protocol packet type is in 'type';
701 'len' contains the length of the packet payload, in bytes (this
702 does not include the space for any of the packet headers or padding,
703 or for the packet type byte).
704 Returns a pointer to the payload data area, a region of length 'len',
705 to be filled by the caller. */
706 static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
707 {
708 unsigned char FAR *buf;
709
710 pvar->ssh_state.outgoing_packet_len = len + 1;
711
712 if (pvar->ssh_state.compressing) {
713 buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
714 &pvar->ssh_state.precompress_outbuflen, 1 + len);
715 buf = pvar->ssh_state.precompress_outbuf;
716 } else {
717 /* For SSHv2,
718 Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
719 + len(payload) + 4(minpadding), rounded up to nearest block_size
720 We only need a reasonable upper bound for the buffer size */
721 buf_ensure_size(&pvar->ssh_state.outbuf,
722 &pvar->ssh_state.outbuflen,
723 len + 30 + CRYPT_get_sender_MAC_size(pvar) +
724 CRYPT_get_encryption_block_size(pvar));
725 buf = pvar->ssh_state.outbuf + 12;
726 }
727
728 buf[0] = (unsigned char) type;
729 return buf + 1;
730 }
731
732 #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
733
734 // ���M���g���C����������
735 //
736 // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
737 // ���������������A�����������G���[���������B
738 // �����������ATCP�R�l�N�V�������f�������o���h���B
739 // (2006.12.9 yutaka)
740 static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
741 {
742 int n;
743 int err;
744
745 while (len > 0) {
746 n = (pvar->Psend)(pvar->socket, data, len, 0);
747
748 if (n < 0) {
749 err = WSAGetLastError();
750 if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
751 // send()�����l��0�������A�����G���[������ 10000 �������������A
752 // ���������������������B
753 // PuTTY 0.58���������Q�l�B
754 // (2007.2.4 yutak)
755 return 0; // success
756 }
757 return 1; // error
758 }
759
760 len -= n;
761 data += n;
762 }
763
764 return 0; // success
765 }
766
767 static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
768 {
769 #if 0
770 u_long do_block = 0;
771
772 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
773 0, 0) == SOCKET_ERROR
774 || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
775 || retry_send_packet(pvar, data, len)
776 || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
777 pvar->notification_msg,
778 pvar->notification_events) ==
779 SOCKET_ERROR) {
780 #else
781 // �\�P�b�g���m���u���b�L���O���������p�P�b�g���M���s���B(2007.9.26 yutaka)
782 if (retry_send_packet(pvar, data, len)) {
783 #endif
784 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
785 "A communications error occurred while sending an SSH packet.\n"
786 "The connection will close.");
787 notify_fatal_error(pvar, pvar->ts->UIMsg);
788 return FALSE;
789 } else {
790 return TRUE;
791 }
792 }
793
794 /* if skip_compress is true, then the data has already been compressed
795 into outbuf + 12 */
796 static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
797 {
798 int len = pvar->ssh_state.outgoing_packet_len;
799 char FAR *data;
800 int data_length;
801 buffer_t *msg = NULL; // for SSH2 packet compression
802
803 if (pvar->ssh_state.compressing) {
804 if (!skip_compress) {
805 buf_ensure_size(&pvar->ssh_state.outbuf,
806 &pvar->ssh_state.outbuflen,
807 len + (len >> 6) + 50 +
808 CRYPT_get_sender_MAC_size(pvar));
809 pvar->ssh_state.compress_stream.next_in =
810 pvar->ssh_state.precompress_outbuf;
811 pvar->ssh_state.compress_stream.avail_in = len;
812 pvar->ssh_state.compress_stream.next_out =
813 pvar->ssh_state.outbuf + 12;
814 pvar->ssh_state.compress_stream.avail_out =
815 pvar->ssh_state.outbuflen - 12;
816
817 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
818 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
819 "An error occurred while compressing packet data.\n"
820 "The connection will close.");
821 notify_fatal_error(pvar, pvar->ts->UIMsg);
822 return;
823 }
824 }
825
826 len =
827 pvar->ssh_state.outbuflen - 12 -
828 pvar->ssh_state.compress_stream.avail_out;
829 }
830
831 if (SSHv1(pvar)) {
832 int padding = 8 - ((len + 4) % 8);
833
834 data = pvar->ssh_state.outbuf + 8 - padding;
835 data_length = padding + len + 8;
836
837 set_uint32(data, len + 4);
838 if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
839 CRYPT_set_random_data(pvar, data + 4, padding);
840 } else {
841 memset(data + 4, 0, padding);
842 }
843 set_uint32(data + data_length - 4,
844 do_crc(data + 4, data_length - 8));
845 CRYPT_encrypt(pvar, data + 4, data_length - 4);
846 } else { //for SSH2(yutaka)
847 int block_size = CRYPT_get_encryption_block_size(pvar);
848 int encryption_size;
849 int padding;
850 BOOL ret;
851
852 /*
853 �f�[�^�\��
854 pvar->ssh_state.outbuf:
855 offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
856 <--ignore---> ^^^^^^^^ <---- payload --->
857 packet length
858
859 ^^padding
860
861 <---------------------------->
862 SSH2 sending data on TCP
863
864 NOTE:
865 payload = type(1) + raw-data
866 len = ssh_state.outgoing_packet_len = payload size
867 */
868 // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
869 // support of "Compression delayed" (2006.6.23 maya)
870 if ((pvar->ctos_compression == COMP_ZLIB ||
871 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
872 pvar->ssh2_keys[MODE_OUT].comp.enabled) {
873 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
874 msg = buffer_init();
875 if (msg == NULL) {
876 // TODO: error check
877 return;
878 }
879
880 // ���k�������w�b�_�������y�C���[�h�����B
881 buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
882 if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
883 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
884 "An error occurred while compressing packet data.\n"
885 "The connection will close.");
886 notify_fatal_error(pvar, pvar->ts->UIMsg);
887 return;
888 }
889 data = buffer_ptr(msg);
890 len = buffer_len(msg) - 5; // 'len' is overwritten.
891
892 } else {
893 // �����k
894 data = pvar->ssh_state.outbuf + 7;
895
896 }
897
898 // ���M�p�P�b�g�\�z(input parameter: data, len)
899 if (block_size < 8) {
900 block_size = 8;
901 }
902 encryption_size = ((len + 8) / block_size + 1) * block_size;
903 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
904
905 set_uint32(data, encryption_size - 4);
906 padding = encryption_size - len - 5;
907 data[4] = (unsigned char) padding;
908 CRYPT_set_random_data(pvar, data + 5 + len, padding);
909 ret = CRYPT_build_sender_MAC(pvar,
910 pvar->ssh_state.sender_sequence_number,
911 data, encryption_size,
912 data + encryption_size);
913 if (ret == FALSE) { // HMAC��������������������������
914 data_length = encryption_size;
915 }
916
917 // �p�P�b�g�������������BHMAC���~�������������O�B
918 CRYPT_encrypt(pvar, data, encryption_size);
919 }
920
921 send_packet_blocking(pvar, data, data_length);
922
923 buffer_free(msg);
924
925 pvar->ssh_state.sender_sequence_number++;
926
927 // ���M�������L�^
928 pvar->ssh_heartbeat_tick = time(NULL);
929 }
930
931 static void destroy_packet_buf(PTInstVar pvar)
932 {
933 memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
934 if (pvar->ssh_state.compressing) {
935 memset(pvar->ssh_state.precompress_outbuf, 0,
936 pvar->ssh_state.precompress_outbuflen);
937 }
938 }
939
940 /* The handlers are added to the queue for each message. When one of the
941 handlers fires, if it returns FALSE, then all handlers in the set are
942 removed from their queues. */
943 static void enque_handlers(PTInstVar pvar, int num_msgs,
944 const int FAR * messages,
945 const SSHPacketHandler FAR * handlers)
946 {
947 SSHPacketHandlerItem FAR *first_item;
948 SSHPacketHandlerItem FAR *last_item = NULL;
949 int i;
950
951 for (i = 0; i < num_msgs; i++) {
952 SSHPacketHandlerItem FAR *item =
953 (SSHPacketHandlerItem FAR *)
954 malloc(sizeof(SSHPacketHandlerItem));
955 SSHPacketHandlerItem FAR *cur_item =
956 pvar->ssh_state.packet_handlers[messages[i]];
957
958 item->handler = handlers[i];
959
960 if (cur_item == NULL) {
961 pvar->ssh_state.packet_handlers[messages[i]] = item;
962 item->next_for_message = item;
963 item->last_for_message = item;
964 item->active_for_message = messages[i];
965 } else {
966 item->next_for_message = cur_item;
967 item->last_for_message = cur_item->last_for_message;
968 cur_item->last_for_message->next_for_message = item;
969 cur_item->last_for_message = item;
970 item->active_for_message = -1;
971 }
972
973 if (last_item != NULL) {
974 last_item->next_in_set = item;
975 } else {
976 first_item = item;
977 }
978 last_item = item;
979 }
980
981 if (last_item != NULL) {
982 last_item->next_in_set = first_item;
983 }
984 }
985
986 static SSHPacketHandler get_handler(PTInstVar pvar, int message)
987 {
988 SSHPacketHandlerItem FAR *cur_item =
989 pvar->ssh_state.packet_handlers[message];
990
991 if (cur_item == NULL) {
992 return NULL;
993 } else {
994 return cur_item->handler;
995 }
996 }
997
998 /* Called only by SSH_handle_packet */
999 static void deque_handlers(PTInstVar pvar, int message)
1000 {
1001 SSHPacketHandlerItem FAR *cur_item =
1002 pvar->ssh_state.packet_handlers[message];
1003 SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1004
1005 do {
1006 SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1007
1008 if (cur_item->active_for_message >= 0) {
1009 SSHPacketHandlerItem FAR *replacement =
1010 cur_item->next_for_message;
1011
1012 if (replacement == cur_item) {
1013 replacement = NULL;
1014 } else {
1015 replacement->active_for_message =
1016 cur_item->active_for_message;
1017 }
1018 pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1019 replacement;
1020 }
1021 cur_item->next_for_message->last_for_message =
1022 cur_item->last_for_message;
1023 cur_item->last_for_message->next_for_message =
1024 cur_item->next_for_message;
1025
1026 free(cur_item);
1027 cur_item = next_in_set;
1028 } while (cur_item != first_item_in_set);
1029 }
1030
1031 static void enque_handler(PTInstVar pvar, int message,
1032 SSHPacketHandler handler)
1033 {
1034 enque_handlers(pvar, 1, &message, &handler);
1035 }
1036
1037 static void chop_newlines(char FAR * buf)
1038 {
1039 int len = strlen(buf);
1040
1041 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1042 buf[len - 1] = 0;
1043 len--;
1044 }
1045 }
1046
1047 /********************/
1048 /* Message handlers */
1049 /********************/
1050
1051 static BOOL handle_forwarding_success(PTInstVar pvar)
1052 {
1053 return FALSE;
1054 }
1055
1056 static BOOL handle_forwarding_failure(PTInstVar pvar)
1057 {
1058 return FALSE;
1059 }
1060
1061 static void enque_forwarding_request_handlers(PTInstVar pvar)
1062 {
1063 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1064 static const SSHPacketHandler handlers[]
1065 = { handle_forwarding_success, handle_forwarding_failure };
1066
1067 enque_handlers(pvar, 2, msgs, handlers);
1068 }
1069
1070 static BOOL handle_auth_failure(PTInstVar pvar)
1071 {
1072 notify_verbose_message(pvar, "Authentication failed",
1073 LOG_LEVEL_VERBOSE);
1074
1075 // retry count������ (2005.7.15 yutaka)
1076 pvar->userauth_retry_count++;
1077
1078 AUTH_set_generic_mode(pvar);
1079 AUTH_advance_to_next_cred(pvar);
1080 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1081 try_send_credentials(pvar);
1082 return FALSE;
1083 }
1084
1085 static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1086 {
1087 AUTH_destroy_cur_cred(pvar);
1088 return handle_auth_failure(pvar);
1089 }
1090
1091 static BOOL handle_TIS_challenge(PTInstVar pvar)
1092 {
1093 if (grab_payload(pvar, 4)) {
1094 int len = get_payload_uint32(pvar, 0);
1095
1096 if (grab_payload(pvar, len)) {
1097 notify_verbose_message(pvar, "Received TIS challenge",
1098 LOG_LEVEL_VERBOSE);
1099
1100 AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1101 AUTH_advance_to_next_cred(pvar);
1102 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1103 try_send_credentials(pvar);
1104 }
1105 }
1106 return FALSE;
1107 }
1108
1109 static BOOL handle_auth_required(PTInstVar pvar)
1110 {
1111 notify_verbose_message(pvar, "Server requires authentication",
1112 LOG_LEVEL_VERBOSE);
1113
1114 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1115 try_send_credentials(pvar);
1116 /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1117
1118 return FALSE;
1119 }
1120
1121 static BOOL handle_ignore(PTInstVar pvar)
1122 {
1123 if (SSHv1(pvar)) {
1124 if (grab_payload(pvar, 4)
1125 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1126 /* ignore it! but it must be decompressed */
1127 }
1128 }
1129 /*
1130 else {
1131 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1132 // Cisco ���[�^���� (2006.11.28 maya)
1133 }
1134 */
1135 return TRUE;
1136 }
1137
1138 static BOOL handle_debug(PTInstVar pvar)
1139 {
1140 BOOL always_display;
1141 char FAR *description;
1142 int description_len;
1143 char buf[2048];
1144
1145 if (SSHv1(pvar)) {
1146 if (grab_payload(pvar, 4)
1147 && grab_payload(pvar, description_len =
1148 get_payload_uint32(pvar, 0))) {
1149 always_display = FALSE;
1150 description = pvar->ssh_state.payload + 4;
1151 description[description_len] = 0;
1152 } else {
1153 return TRUE;
1154 }
1155 } else {
1156 if (grab_payload(pvar, 5)
1157 && grab_payload(pvar,
1158 (description_len = get_payload_uint32(pvar, 1)) + 4)
1159 && grab_payload(pvar,
1160 get_payload_uint32(pvar, 5 + description_len))) {
1161 always_display = pvar->ssh_state.payload[0] != 0;
1162 description = pvar->ssh_state.payload + 5;
1163 description[description_len] = 0;
1164 } else {
1165 return TRUE;
1166 }
1167 }
1168
1169 chop_newlines(description);
1170 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1171 description);
1172 if (always_display) {
1173 notify_nonfatal_error(pvar, buf);
1174 } else {
1175 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1176 }
1177 return TRUE;
1178 }
1179
1180 static BOOL handle_disconnect(PTInstVar pvar)
1181 {
1182 int reason_code;
1183 char FAR *description;
1184 int description_len;
1185 char buf[2048];
1186 char FAR *explanation = "";
1187 char uimsg[MAX_UIMSG];
1188
1189 if (SSHv1(pvar)) {
1190 if (grab_payload(pvar, 4)
1191 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1192 reason_code = -1;
1193 description = pvar->ssh_state.payload + 4;
1194 description[description_len] = 0;
1195 } else {
1196 return TRUE;
1197 }
1198 } else {
1199 if (grab_payload(pvar, 8)
1200 && grab_payload(pvar,
1201 (description_len = get_payload_uint32(pvar, 4)) + 4)
1202 && grab_payload(pvar,
1203 get_payload_uint32(pvar, 8 + description_len))) {
1204 reason_code = get_payload_uint32(pvar, 0);
1205 description = pvar->ssh_state.payload + 8;
1206 description[description_len] = 0;
1207 } else {
1208 return TRUE;
1209 }
1210 }
1211
1212 chop_newlines(description);
1213 if (description[0] == 0) {
1214 description = NULL;
1215 }
1216
1217 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1218 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1219 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1220 "This often happens when someone is already forwarding that port from the server.");
1221 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1222 explanation = uimsg;
1223 }
1224
1225 if (description != NULL) {
1226 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1227 "Server disconnected with message '%s'.%s");
1228 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1229 pvar->ts->UIMsg, description,
1230 explanation);
1231 } else {
1232 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1233 "Server disconnected (no reason given).%s");
1234 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1235 pvar->ts->UIMsg, explanation);
1236 }
1237 notify_fatal_error(pvar, buf);
1238
1239 return TRUE;
1240 }
1241
1242 static BOOL handle_unimplemented(PTInstVar pvar)
1243 {
1244 /* Should never receive this since we only send base 2.0 protocol messages */
1245 grab_payload(pvar, 4);
1246 return TRUE;
1247 }
1248
1249 static BOOL handle_crypt_success(PTInstVar pvar)
1250 {
1251 notify_verbose_message(pvar, "Secure mode successfully achieved",
1252 LOG_LEVEL_VERBOSE);
1253 return FALSE;
1254 }
1255
1256 static BOOL handle_noauth_success(PTInstVar pvar)
1257 {
1258 notify_verbose_message(pvar, "Server does not require authentication",
1259 LOG_LEVEL_VERBOSE);
1260 prep_compression(pvar);
1261 return FALSE;
1262 }
1263
1264 static BOOL handle_auth_success(PTInstVar pvar)
1265 {
1266 notify_verbose_message(pvar, "Authentication accepted",
1267 LOG_LEVEL_VERBOSE);
1268 prep_compression(pvar);
1269
1270 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1271 start_ssh_heartbeat_thread(pvar);
1272
1273 return FALSE;
1274 }
1275
1276 static BOOL handle_server_public_key(PTInstVar pvar)
1277 {
1278 int server_key_public_exponent_len;
1279 int server_key_public_modulus_pos;
1280 int server_key_public_modulus_len;
1281 int host_key_bits_pos;
1282 int host_key_public_exponent_len;
1283 int host_key_public_modulus_pos;
1284 int host_key_public_modulus_len;
1285 int protocol_flags_pos;
1286 int supported_ciphers;
1287 char FAR *inmsg;
1288 Key hostkey;
1289
1290 if (!grab_payload(pvar, 14))
1291 return FALSE;
1292 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1293
1294 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1295 return FALSE;
1296 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1297 server_key_public_modulus_len =
1298 get_mpint_len(pvar, server_key_public_modulus_pos);
1299
1300 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1301 return FALSE;
1302 host_key_bits_pos =
1303 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1304 host_key_public_exponent_len =
1305 get_mpint_len(pvar, host_key_bits_pos + 4);
1306
1307 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1308 return FALSE;
1309 host_key_public_modulus_pos =
1310 host_key_bits_pos + 6 + host_key_public_exponent_len;
1311 host_key_public_modulus_len =
1312 get_mpint_len(pvar, host_key_public_modulus_pos);
1313
1314 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1315 return FALSE;
1316 protocol_flags_pos =
1317 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1318
1319 inmsg = pvar->ssh_state.payload;
1320
1321 CRYPT_set_server_cookie(pvar, inmsg);
1322 if (!CRYPT_set_server_RSA_key(pvar,
1323 get_uint32(inmsg + 8),
1324 pvar->ssh_state.payload + 12,
1325 inmsg + server_key_public_modulus_pos))
1326 return FALSE;
1327 if (!CRYPT_set_host_RSA_key(pvar,
1328 get_uint32(inmsg + host_key_bits_pos),
1329 inmsg + host_key_bits_pos + 4,
1330 inmsg + host_key_public_modulus_pos))
1331 return FALSE;
1332 pvar->ssh_state.server_protocol_flags =
1333 get_uint32(inmsg + protocol_flags_pos);
1334
1335 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1336 if (!CRYPT_set_supported_ciphers(pvar,
1337 supported_ciphers,
1338 supported_ciphers))
1339 return FALSE;
1340 if (!AUTH_set_supported_auth_types(pvar,
1341 get_uint32(inmsg + protocol_flags_pos + 8)))
1342 return FALSE;
1343
1344 /* this must be the LAST THING in this function, since it can cause
1345 host_is_OK to be called. */
1346 hostkey.type = KEY_RSA1;
1347 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1348 hostkey.exp = inmsg + host_key_bits_pos + 4;
1349 hostkey.mod = inmsg + host_key_public_modulus_pos;
1350 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, &hostkey);
1351
1352 return FALSE;
1353 }
1354
1355 /*
1356 The ID must have already been found to start with "SSH-". It must
1357 be null-terminated.
1358 */
1359 static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1360 {
1361 char FAR *str;
1362
1363 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1364 }
1365
1366 if (*str != '.') {
1367 return FALSE;
1368 }
1369
1370 pvar->protocol_major = atoi(ID + 4);
1371 pvar->protocol_minor = atoi(str + 1);
1372
1373 // for SSH2(yutaka)
1374 // 1.99����SSH2�����������s��
1375 if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1376 // ���[�U�� SSH2 ���I������������������
1377 if (pvar->settings.ssh_protocol_version == 2) {
1378 pvar->protocol_major = 2;
1379 pvar->protocol_minor = 0;
1380 }
1381
1382 }
1383
1384 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1385 }
1386
1387 return *str == '-';
1388 }
1389
1390 /*
1391 On entry, the pvar->protocol_xxx fields hold the server's advertised
1392 protocol number. We replace the fields with the protocol number we will
1393 actually use, or return FALSE if there is no usable protocol version.
1394 */
1395 static BOOL negotiate_protocol(PTInstVar pvar)
1396 {
1397 switch (pvar->protocol_major) {
1398 case 1:
1399 if (pvar->protocol_minor > 5) {
1400 pvar->protocol_minor = 5;
1401 }
1402
1403 return TRUE;
1404
1405 // for SSH2(yutaka)
1406 case 2:
1407 return TRUE; // SSH2 support
1408
1409 default:
1410 return FALSE;
1411 }
1412 }
1413
1414 static void init_protocol(PTInstVar pvar)
1415 {
1416 CRYPT_initialize_random_numbers(pvar);
1417
1418 // known_hosts�t�@�C�������z�X�g���J������������������
1419 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
1420
1421 /* while we wait for a response from the server... */
1422
1423 if (SSHv1(pvar)) {
1424 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1425 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1426 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1427 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1428
1429 } else { // for SSH2(yutaka)
1430 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1431 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1432 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1433 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1434 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1435 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1436 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1437 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1438 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
1439 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1440 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1441 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1442 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1443
1444 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1445
1446 // ���[�U�F�������f�B�X�p�b�`���[�`��
1447 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1448 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1449 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1450 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1451 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1452 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1453 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1454 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1455 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1456 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1457 // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1458 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1459 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1460
1461 }
1462 }
1463
1464 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1465 {
1466 static const char prefix[] = "Received server prologue string: ";
1467
1468 // initialize SSH2 memory dump (2005.3.7 yutaka)
1469 init_memdump();
1470 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1471
1472 if (ID_len <= 0) {
1473 return FALSE;
1474 } else {
1475 int buf_len = ID_len + NUM_ELEM(prefix);
1476 char FAR *buf = (char FAR *) malloc(buf_len);
1477
1478 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1479 strncat_s(buf, buf_len, ID, _TRUNCATE);
1480 chop_newlines(buf);
1481
1482 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1483
1484 free(buf);
1485
1486
1487 // ���������R�s�[������ (2005.3.9 yutaka)
1488 #if 0
1489 // for calculate SSH2 hash
1490 // �T�[�o�o�[�W�����������i���s���������������j
1491 if (ID_len >= sizeof(pvar->server_version_string))
1492 return FALSE;
1493 strncpy(pvar->server_version_string, ID, ID_len);
1494 #endif
1495
1496
1497 if (ID[ID_len - 1] != '\n') {
1498 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1499 return FALSE;
1500 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1501 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1502 return FALSE;
1503 } else if (strncmp(ID, "SSH-", 4) != 0) {
1504 return FALSE;
1505 } else {
1506 ID[ID_len - 1] = 0;
1507
1508 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1509 ID[ID_len - 2] = 0;
1510 }
1511
1512 pvar->ssh_state.server_ID = _strdup(ID);
1513
1514 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1515 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1516 "This program does not understand the server's version of the protocol.");
1517 notify_fatal_error(pvar, pvar->ts->UIMsg);
1518 } else {
1519 char TTSSH_ID[1024];
1520 int TTSSH_ID_len;
1521 int a, b, c, d;
1522
1523 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1524 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1525
1526 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1527 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1528 pvar->protocol_major, pvar->protocol_minor, a, b);
1529 TTSSH_ID_len = strlen(TTSSH_ID);
1530
1531 // for SSH2(yutaka)
1532 // �N���C�A���g�o�[�W�����������i���s���������������j
1533 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1534 TTSSH_ID, _TRUNCATE);
1535
1536 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1537 _snprintf_s(pvar->server_version_string,
1538 sizeof(pvar->server_version_string), _TRUNCATE,
1539 "%s", pvar->ssh_state.server_ID);
1540
1541 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1542 0) != TTSSH_ID_len) {
1543 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1544 "An error occurred while sending the SSH ID string.\n"
1545 "The connection will close.");
1546 notify_fatal_error(pvar, pvar->ts->UIMsg);
1547 } else {
1548 // ���s�R�[�h������ (2004.8.4 yutaka)
1549 pvar->client_version_string[--TTSSH_ID_len] = 0;
1550
1551 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1552 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1553
1554 // SSH�n���h�����o�^���s��
1555 init_protocol(pvar);
1556
1557 SSH2_dispatch_init(1);
1558 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1559 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1560 }
1561 }
1562
1563 return TRUE;
1564 }
1565 }
1566 }
1567
1568 static BOOL handle_exit(PTInstVar pvar)
1569 {
1570 if (grab_payload(pvar, 4)) {
1571 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1572 finish_send_packet(pvar);
1573 notify_closed_connection(pvar);
1574 }
1575 return TRUE;
1576 }
1577
1578 static BOOL handle_data(PTInstVar pvar)
1579 {
1580 if (grab_payload_limited(pvar, 4)) {
1581 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1582 pvar->ssh_state.payload_datastart = 4;
1583 }
1584 return TRUE;
1585 }
1586
1587 static BOOL handle_channel_open(PTInstVar pvar)
1588 {
1589 int host_len;
1590 int originator_len;
1591
1592 if ((pvar->ssh_state.
1593 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1594 if (grab_payload(pvar, 8)
1595 && grab_payload(pvar,
1596 8 + (host_len = get_payload_uint32(pvar, 4)))
1597 && grab_payload(pvar, originator_len =
1598 get_payload_uint32(pvar, host_len + 12))) {
1599 int local_port = get_payload_uint32(pvar, 8 + host_len);
1600
1601 pvar->ssh_state.payload[8 + host_len] = 0;
1602 FWD_open(pvar, get_payload_uint32(pvar, 0),
1603 pvar->ssh_state.payload + 8, local_port,
1604 pvar->ssh_state.payload + 16 + host_len,
1605 originator_len,
1606 NULL);
1607 }
1608 } else {
1609 if (grab_payload(pvar, 8)
1610 && grab_payload(pvar,
1611 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1612 int local_port = get_payload_uint32(pvar, 8 + host_len);
1613
1614 pvar->ssh_state.payload[8 + host_len] = 0;
1615 FWD_open(pvar, get_payload_uint32(pvar, 0),
1616 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1617 NULL);
1618 }
1619 }
1620
1621 return TRUE;
1622 }
1623
1624 static BOOL handle_X11_channel_open(PTInstVar pvar)
1625 {
1626 int originator_len;
1627
1628 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1629 if (grab_payload(pvar, 8)
1630 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1631 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1632 pvar->ssh_state.payload + 8, originator_len, NULL);
1633 }
1634 } else {
1635 if (grab_payload(pvar, 4)) {
1636 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1637 }
1638 }
1639
1640 return TRUE;
1641 }
1642
1643 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1644 {
1645 if (grab_payload(pvar, 8)) {
1646 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1647 get_payload_uint32(pvar, 4));
1648 }
1649 return FALSE;
1650 }
1651
1652 static BOOL handle_channel_open_failure(PTInstVar pvar)
1653 {
1654 if (grab_payload(pvar, 4)) {
1655 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1656 }
1657 return FALSE;
1658 }
1659
1660 static BOOL handle_channel_data(PTInstVar pvar)
1661 {
1662 int len;
1663
1664 if (grab_payload(pvar, 8)
1665 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1666 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1667 pvar->ssh_state.payload + 8, len);
1668 }
1669 return TRUE;
1670 }
1671
1672 static BOOL handle_channel_input_eof(PTInstVar pvar)
1673 {
1674 if (grab_payload(pvar, 4)) {
1675 FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1676 }
1677 return TRUE;
1678 }
1679
1680 static BOOL handle_channel_output_eof(PTInstVar pvar)
1681 {
1682 if (grab_payload(pvar, 4)) {
1683 FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1684 }
1685 return TRUE;
1686 }
1687
1688
1689
1690 // �n���h�����O�������b�Z�[�W����������
1691
1692 #define HANDLE_MESSAGE_MAX 30
1693 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1694 static int handle_message_count = 0;
1695 static int handle_message_stage = 0;
1696
1697 void SSH2_dispatch_init(int stage)
1698 {
1699 handle_message_count = 0;
1700 handle_message_stage = stage;
1701 }
1702
1703 int SSH2_dispatch_enabled_check(unsigned char message)
1704 {
1705 int i;
1706
1707 for (i = 0 ; i < handle_message_count ; i++) {
1708 if (handle_messages[i] == message)
1709 return 1;
1710 }
1711 return 0;
1712 }
1713
1714 void SSH2_dispatch_add_message(unsigned char message)
1715 {
1716
1717 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1718 // TODO: error check
1719 return;
1720 }
1721
1722 handle_messages[handle_message_count++] = message;
1723 }
1724
1725 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1726 {
1727 unsigned char c;
1728
1729 for (c = begin ; c <= end ; c++) {
1730 SSH2_dispatch_add_message(c);
1731 }
1732 }
1733
1734
1735 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1736 int padding)
1737 {
1738 unsigned char message = prep_packet(pvar, data, len, padding);
1739
1740
1741 #ifdef SSH2_DEBUG
1742 // for SSH2(yutaka)
1743 if (SSHv2(pvar)) {
1744 if (pvar->key_done) {
1745 message = message;
1746 }
1747
1748 if (pvar->userauth_success) {
1749 message = message;
1750 }
1751
1752 if (pvar->rekeying) {
1753 message = message;
1754 }
1755 }
1756 #endif
1757
1758 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1759 if (message != SSH_MSG_NONE) {
1760 // ���b�Z�[�W�^�C�v���������n���h�����N��
1761 SSHPacketHandler handler = get_handler(pvar, message);
1762
1763 // for SSH2(yutaka)
1764 if (SSHv2(pvar)) {
1765 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1766 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1767 char buf[1024];
1768
1769 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1770 "Unexpected SSH2 message(%d) on current stage(%d)");
1771 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1772 pvar->ts->UIMsg, message, handle_message_stage);
1773 notify_fatal_error(pvar, buf);
1774 // abort
1775 }
1776 }
1777
1778 if (handler == NULL) {
1779 if (SSHv1(pvar)) {
1780 char buf[1024];
1781
1782 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
1783 "Unexpected packet type received: %d");
1784 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1785 pvar->ts->UIMsg, message, handle_message_stage);
1786 notify_fatal_error(pvar, buf);
1787 } else {
1788 unsigned char FAR *outmsg =
1789 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1790
1791 set_uint32(outmsg,
1792 pvar->ssh_state.receiver_sequence_number - 1);
1793 finish_send_packet(pvar);
1794 /* XXX need to decompress incoming packet, but how? */
1795 }
1796 } else {
1797 if (!handler(pvar)) {
1798 deque_handlers(pvar, message);
1799 }
1800 }
1801 }
1802 }
1803
1804 static BOOL handle_pty_success(PTInstVar pvar)
1805 {
1806 FWD_enter_interactive_mode(pvar);
1807 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1808 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1809 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1810 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1811 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1812 handle_channel_input_eof);
1813 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1814 handle_channel_output_eof);
1815 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1816 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1817 return FALSE;
1818 }
1819
1820 static BOOL handle_pty_failure(PTInstVar pvar)
1821 {
1822 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
1823 "The server cannot allocate a pseudo-terminal. "
1824 "You may encounter some problems with the terminal.");
1825 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1826 return handle_pty_success(pvar);
1827 }
1828
1829 static void prep_pty(PTInstVar pvar)
1830 {
1831 int len = strlen(pvar->ts->TermType);
1832 unsigned char FAR *outmsg =
1833 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1834 4 + len + 16 + sizeof(ssh_ttymodes));
1835 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1836 static const SSHPacketHandler handlers[]
1837 = { handle_pty_success, handle_pty_failure };
1838
1839 set_uint32(outmsg, len);
1840 memcpy(outmsg + 4, pvar->ts->TermType, len);
1841 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
1842 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
1843 set_uint32(outmsg + 4 + len + 8, 0);
1844 set_uint32(outmsg + 4 + len + 12, 0);
1845 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
1846 finish_send_packet(pvar);
1847
1848 enque_handlers(pvar, 2, msgs, handlers);
1849
1850 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
1851 finish_send_packet(pvar);
1852 }
1853
1854 static void prep_forwarding(PTInstVar pvar)
1855 {
1856 FWD_prep_forwarding(pvar);
1857 prep_pty(pvar);
1858 }
1859
1860
1861 //
1862 //
1863 // (2005.7.10 yutaka)
1864 static void enable_send_compression(PTInstVar pvar)
1865 {
1866 static int initialize = 0;
1867
1868 if (initialize) {
1869 deflateEnd(&pvar->ssh_state.compress_stream);
1870 }
1871 initialize = 1;
1872
1873 pvar->ssh_state.compress_stream.zalloc = NULL;
1874 pvar->ssh_state.compress_stream.zfree = NULL;
1875 pvar->ssh_state.compress_stream.opaque = NULL;
1876 if (deflateInit
1877 (&pvar->ssh_state.compress_stream,
1878 pvar->ssh_state.compression_level) != Z_OK) {
1879 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
1880 "An error occurred while setting up compression.\n"
1881 "The connection will close.");
1882 notify_fatal_error(pvar, pvar->ts->UIMsg);
1883 return;
1884 } else {
1885 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
1886 if (SSHv2(pvar)) {
1887 pvar->ssh_state.compressing = FALSE;
1888 } else {
1889 pvar->ssh_state.compressing = TRUE;
1890 }
1891 }
1892 }
1893
1894 static void enable_recv_compression(PTInstVar pvar)
1895 {
1896 static int initialize = 0;
1897
1898 if (initialize) {
1899 deflateEnd(&pvar->ssh_state.decompress_stream);
1900 }
1901 initialize = 1;
1902
1903 pvar->ssh_state.decompress_stream.zalloc = NULL;
1904 pvar->ssh_state.decompress_stream.zfree = NULL;
1905 pvar->ssh_state.decompress_stream.opaque = NULL;
1906 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
1907 deflateEnd(&pvar->ssh_state.compress_stream);
1908 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
1909 "An error occurred while setting up compression.\n"
1910 "The connection will close.");
1911 notify_fatal_error(pvar, pvar->ts->UIMsg);
1912 return;
1913 } else {
1914 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
1915 if (SSHv2(pvar)) {
1916 pvar->ssh_state.decompressing = FALSE;
1917 } else {
1918 pvar->ssh_state.decompressing = TRUE;
1919 }
1920
1921 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
1922 &pvar->ssh_state.postdecompress_inbuflen, 1000);
1923 }
1924 }
1925
1926 static void enable_compression(PTInstVar pvar)
1927 {
1928 enable_send_compression(pvar);
1929 enable_recv_compression(pvar);
1930
1931 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
1932 if (SSHv2(pvar)) {
1933 pvar->ssh_state.compressing = FALSE;
1934 pvar->ssh_state.decompressing = FALSE;
1935 }
1936
1937 }
1938
1939 static BOOL handle_enable_compression(PTInstVar pvar)
1940 {
1941 enable_compression(pvar);
1942 prep_forwarding(pvar);
1943 return FALSE;
1944 }
1945
1946 static BOOL handle_disable_compression(PTInstVar pvar)
1947 {
1948 prep_forwarding(pvar);
1949 return FALSE;
1950 }
1951
1952 static void prep_compression(PTInstVar pvar)
1953 {
1954 if (pvar->session_settings.CompressionLevel > 0) {
1955 // added if statement (2005.7.10 yutaka)
1956 if (SSHv1(pvar)) {
1957 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1958 static const SSHPacketHandler handlers[]
1959 = { handle_enable_compression, handle_disable_compression };
1960
1961 unsigned char FAR *outmsg =
1962 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
1963
1964 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
1965 finish_send_packet(pvar);
1966
1967 enque_handlers(pvar, 2, msgs, handlers);
1968 }
1969
1970 pvar->ssh_state.compression_level =
1971 pvar->session_settings.CompressionLevel;
1972
1973 } else {
1974 // added if statement (2005.7.10 yutaka)
1975 if (SSHv1(pvar)) {
1976 prep_forwarding(pvar);
1977 }
1978 }
1979 }
1980
1981 static void enque_simple_auth_handlers(PTInstVar pvar)
1982 {
1983 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1984 static const SSHPacketHandler handlers[]
1985 = { handle_auth_success, handle_auth_failure };
1986
1987 enque_handlers(pvar, 2, msgs, handlers);
1988 }
1989
1990 static BOOL handle_rsa_challenge(PTInstVar pvar)
1991 {
1992 int challenge_bytes;
1993
1994 if (!grab_payload(pvar, 2)) {
1995 return FALSE;
1996 }
1997
1998 challenge_bytes = get_mpint_len(pvar, 0);
1999
2000 if (grab_payload(pvar, challenge_bytes)) {
2001 unsigned char FAR *outmsg =
2002 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2003
2004 if (CRYPT_generate_RSA_challenge_response
2005 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2006
2007 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2008 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2009 #if 0
2010 //AUTH_destroy_cur_cred(pvar);
2011 #endif
2012
2013 finish_send_packet(pvar);
2014
2015 enque_simple_auth_handlers(pvar);
2016 } else {
2017 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2018 "An error occurred while decrypting the RSA challenge.\n"
2019 "Perhaps the key file is corrupted.");
2020 notify_fatal_error(pvar, pvar->ts->UIMsg);
2021 }
2022 }
2023
2024 return FALSE;
2025 }
2026
2027 #define OBFUSCATING_ROUND_TO 32
2028
2029 static int obfuscating_round_up(PTInstVar pvar, int size)
2030 {
2031 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2032 }
2033
2034 static void try_send_credentials(PTInstVar pvar)
2035 {
2036 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2037 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2038 static const int RSA_msgs[] =
2039 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2040 static const SSHPacketHandler RSA_handlers[]
2041 = { handle_rsa_challenge, handle_rsa_auth_refused };
2042 static const int TIS_msgs[] =
2043 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2044 static const SSHPacketHandler TIS_handlers[]
2045 = { handle_TIS_challenge, handle_auth_failure };
2046
2047 // SSH2���������������������X�L�b�v
2048 if (SSHv2(pvar))
2049 goto skip_ssh2;
2050
2051 switch (cred->method) {
2052 case SSH_AUTH_NONE:
2053 return;
2054 case SSH_AUTH_PASSWORD:{
2055 int len = strlen(cred->password);
2056 // Round up password length to discourage traffic analysis
2057 int obfuscated_len = obfuscating_round_up(pvar, len);
2058 unsigned char FAR *outmsg =
2059 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2060 4 + obfuscated_len);
2061
2062 notify_verbose_message(pvar,
2063 "Trying PASSWORD authentication...",
2064 LOG_LEVEL_VERBOSE);
2065
2066 set_uint32(outmsg, obfuscated_len);
2067 memcpy(outmsg + 4, cred->password, len);
2068 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2069
2070 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2071 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2072 #if 0
2073 //AUTH_destroy_cur_cred(pvar);
2074 #endif
2075
2076 enque_simple_auth_handlers(pvar);
2077 break;
2078 }
2079 case SSH_AUTH_RHOSTS:{
2080 int len = strlen(cred->rhosts_client_user);
2081 unsigned char FAR *outmsg =
2082 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2083
2084 notify_verbose_message(pvar,
2085 "Trying RHOSTS authentication...",
2086 LOG_LEVEL_VERBOSE);
2087
2088 set_uint32(outmsg, len);
2089 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2090 AUTH_destroy_cur_cred(pvar);
2091 enque_simple_auth_handlers(pvar);
2092 break;
2093 }
2094 case SSH_AUTH_RSA:{
2095 int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2096 unsigned char FAR *outmsg =
2097 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2098
2099 notify_verbose_message(pvar,
2100 "Trying RSA authentication...",
2101 LOG_LEVEL_VERBOSE);
2102
2103 set_ushort16_MSBfirst(outmsg, len * 8);
2104 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2105 /* don't destroy the current credentials yet */
2106 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2107 break;
2108 }
2109 case SSH_AUTH_RHOSTS_RSA:{
2110 int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2111 int name_len = strlen(cred->rhosts_client_user);
2112 int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2113 int index;
2114 unsigned char FAR *outmsg =
2115 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2116 12 + mod_len + name_len + exp_len);
2117
2118 notify_verbose_message(pvar,
2119 "Trying RHOSTS+RSA authentication...",
2120 LOG_LEVEL_VERBOSE);
2121
2122 set_uint32(outmsg, name_len);
2123 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2124 index = 4 + name_len;
2125
2126 set_uint32(outmsg + index, 8 * mod_len);
2127 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2128 BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2129 index += 6 + exp_len;
2130
2131 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2132 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2133 /* don't destroy the current credentials yet */
2134 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2135 break;
2136 }
2137 case SSH_AUTH_TIS:{
2138 if (cred->password == NULL) {
2139 unsigned char FAR *outmsg =
2140 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2141
2142 notify_verbose_message(pvar,
2143 "Trying TIS authentication...",
2144 LOG_LEVEL_VERBOSE);
2145 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2146 } else {
2147 int len = strlen(cred->password);
2148 int obfuscated_len = obfuscating_round_up(pvar, len);
2149 unsigned char FAR *outmsg =
2150 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2151 4 + obfuscated_len);
2152
2153 notify_verbose_message(pvar, "Sending TIS response",
2154 LOG_LEVEL_VERBOSE);
2155
2156 set_uint32(outmsg, obfuscated_len);
2157 memcpy(outmsg + 4, cred->password, len);
2158 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2159 enque_simple_auth_handlers(pvar);
2160 }
2161
2162 AUTH_destroy_cur_cred(pvar);
2163 break;
2164 }
2165 default:
2166 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2167 "Internal error: unsupported authentication method");
2168 notify_fatal_error(pvar, pvar->ts->UIMsg);
2169 return;
2170 }
2171
2172 finish_send_packet(pvar);
2173
2174 skip_ssh2:;
2175 destroy_packet_buf(pvar);
2176
2177 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2178 }
2179 }
2180
2181 static void try_send_user_name(PTInstVar pvar)
2182 {
2183 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2184 char FAR *username = AUTH_get_user_name(pvar);
2185
2186 if (username != NULL) {
2187 int len = strlen(username);
2188 int obfuscated_len = obfuscating_round_up(pvar, len);
2189 unsigned char FAR *outmsg =
2190 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2191 char buf[1024] = "Sending user name: ";
2192 static const int msgs[] =
2193 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2194 static const SSHPacketHandler handlers[]
2195 = { handle_noauth_success, handle_auth_required };
2196
2197 set_uint32(outmsg, obfuscated_len);
2198 memcpy(outmsg + 4, username, len);
2199 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2200 finish_send_packet(pvar);
2201
2202 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2203
2204 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2205 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2206
2207 enque_handlers(pvar, 2, msgs, handlers);
2208 }
2209 }
2210 }
2211
2212 static void send_session_key(PTInstVar pvar)
2213 {
2214 int encrypted_session_key_len;
2215 unsigned char FAR *outmsg;
2216
2217 if (SSHv1(pvar)) {
2218 encrypted_session_key_len =
2219 CRYPT_get_encrypted_session_key_len(pvar);
2220 }
2221
2222 if (!CRYPT_choose_ciphers(pvar))
2223 return;
2224
2225 if (SSHv1(pvar)) {
2226 outmsg =
2227 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2228 15 + encrypted_session_key_len);
2229 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2230 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2231 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2232 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2233 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2234 return;
2235 set_uint32(outmsg + 11 + encrypted_session_key_len,
2236 SSH_PROTOFLAG_SCREEN_NUMBER |
2237 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2238 finish_send_packet(pvar);
2239 }
2240
2241 if (!CRYPT_start_encryption(pvar, 1, 1))
2242 return;
2243 notify_established_secure_connection(pvar);
2244
2245 if (SSHv1(pvar)) {
2246 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2247 }
2248
2249 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2250
2251 if (SSHv1(pvar)) {
2252 try_send_user_name(pvar);
2253 }
2254 }
2255
2256 /*************************
2257 END of message handlers
2258 ************************/
2259
2260 void SSH_init(PTInstVar pvar)
2261 {
2262 int i;
2263
2264 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2265 buf_create(&pvar->ssh_state.precompress_outbuf,
2266 &pvar->ssh_state.precompress_outbuflen);
2267 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2268 &pvar->ssh_state.postdecompress_inbuflen);
2269 pvar->ssh_state.payload = NULL;
2270 pvar->ssh_state.compressing = FALSE;
2271 pvar->ssh_state.decompressing = FALSE;
2272 pvar->ssh_state.status_flags =
2273 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2274 pvar->ssh_state.payload_datalen = 0;
2275 pvar->ssh_state.hostname = NULL;
2276 pvar->ssh_state.server_ID = NULL;
2277 pvar->ssh_state.receiver_sequence_number = 0;
2278 pvar->ssh_state.sender_sequence_number = 0;
2279 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2280 pvar->ssh_state.packet_handlers[i] = NULL;
2281 }
2282
2283 // for SSH2(yutaka)
2284 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2285 pvar->userauth_success = 0;
2286 pvar->session_nego_status = 0;
2287 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2288 pvar->rekeying = 0;
2289 pvar->key_done = 0;
2290 pvar->ssh2_autologin = 0; // autologin disabled(default)
2291 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2292 pvar->userauth_retry_count = 0;
2293 pvar->decomp_buffer = NULL;
2294 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2295
2296 }
2297
2298 void SSH_open(PTInstVar pvar)
2299 {
2300 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2301 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2302 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2303 }
2304
2305 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2306 {
2307 if (SSHv1(pvar)) {
2308 int len = reason == NULL ? 0 : strlen(reason);
2309 unsigned char FAR *outmsg =
2310 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2311
2312 set_uint32(outmsg, len);
2313 if (reason != NULL) {
2314 memcpy(outmsg + 4, reason, len);
2315 }
2316 finish_send_packet(pvar);
2317
2318 } else { // for SSH2(yutaka)
2319 buffer_t *msg;
2320 unsigned char *outmsg;
2321 int len;
2322 Channel_t *c;
2323
2324 c = ssh2_channel_lookup(pvar->shell_id);
2325 if (c == NULL)
2326 return;
2327
2328 // SSH2 server��channel close���`����
2329 msg = buffer_init();
2330 if (msg == NULL) {
2331 // TODO: error check
2332 return;
2333 }
2334 buffer_put_int(msg, c->remote_id);
2335
2336 len = buffer_len(msg);
2337 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2338 memcpy(outmsg, buffer_ptr(msg), len);
2339 finish_send_packet(pvar);
2340 buffer_free(msg);
2341
2342 }
2343
2344 }
2345
2346 void SSH_notify_host_OK(PTInstVar pvar)
2347 {
2348 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2349 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2350 send_session_key(pvar);
2351 }
2352 }
2353
2354 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2355 {
2356 pvar->ssh_state.win_cols = cols;
2357 pvar->ssh_state.win_rows = rows;
2358
2359 if (SSHv1(pvar)) {
2360 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2361 unsigned char FAR *outmsg =
2362 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2363
2364 set_uint32(outmsg, rows);
2365 set_uint32(outmsg + 4, cols);
2366 set_uint32(outmsg + 8, 0);
2367 set_uint32(outmsg + 12, 0);
2368 finish_send_packet(pvar);
2369 }
2370
2371 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2372 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2373 buffer_t *msg;
2374 char *s;
2375 unsigned char *outmsg;
2376 int len;
2377 Channel_t *c;
2378
2379 c = ssh2_channel_lookup(pvar->shell_id);
2380 if (c == NULL)
2381 return;
2382
2383 msg = buffer_init();
2384 if (msg == NULL) {
2385 // TODO: error check
2386 return;
2387 }
2388 buffer_put_int(msg, c->remote_id);
2389 s = "window-change";
2390 buffer_put_string(msg, s, strlen(s));
2391 buffer_put_char(msg, 0); // wantconfirm
2392 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2393 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2394 buffer_put_int(msg, 480); // XXX:
2395 buffer_put_int(msg, 640); // XXX:
2396 len = buffer_len(msg);
2397 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2398 memcpy(outmsg, buffer_ptr(msg), len);
2399 finish_send_packet(pvar);
2400 buffer_free(msg);
2401
2402 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2403
2404 } else {
2405 // SSH�����������������������B
2406
2407 }
2408
2409 }
2410
2411 int SSH_get_min_packet_size(PTInstVar pvar)
2412 {
2413 if (SSHv1(pvar)) {
2414 return 12;
2415 } else {
2416 int block_size = CRYPT_get_decryption_block_size(pvar);
2417
2418 return max(16, block_size);
2419 }
2420 }
2421
2422 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2423 at least 5 bytes must be decrypted */
2424 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2425 {
2426 if (SSHv2(pvar)) {
2427 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2428 }
2429 }
2430
2431 int SSH_get_clear_MAC_size(PTInstVar pvar)
2432 {
2433 if (SSHv1(pvar)) {
2434 return 0;
2435 } else {
2436 return CRYPT_get_receiver_MAC_size(pvar);
2437 }
2438 }
2439
2440 void SSH_notify_user_name(PTInstVar pvar)
2441 {
2442 try_send_user_name(pvar);
2443 }
2444
2445 void SSH_notify_cred(PTInstVar pvar)
2446 {
2447 try_send_credentials(pvar);
2448 }
2449
2450 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
2451 {
2452 if (SSHv1(pvar)) {
2453 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2454 return;
2455 }
2456
2457 while (buflen > 0) {
2458 int len =
2459 buflen >
2460 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2461 unsigned char FAR *outmsg =
2462 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2463
2464 set_uint32(outmsg, len);
2465
2466 if (pvar->ssh_state.compressing) {
2467 buf_ensure_size(&pvar->ssh_state.outbuf,
2468 &pvar->ssh_state.outbuflen,
2469 len + (len >> 6) + 50);
2470 pvar->ssh_state.compress_stream.next_in =
2471 pvar->ssh_state.precompress_outbuf;
2472 pvar->ssh_state.compress_stream.avail_in = 5;
2473 pvar->ssh_state.compress_stream.next_out =
2474 pvar->ssh_state.outbuf + 12;
2475 pvar->ssh_state.compress_stream.avail_out =
2476 pvar->ssh_state.outbuflen - 12;
2477
2478 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2479 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2480 "Error compressing packet data");
2481 notify_fatal_error(pvar, pvar->ts->UIMsg);
2482 return;
2483 }
2484
2485 pvar->ssh_state.compress_stream.next_in =
2486 (unsigned char FAR *) buf;
2487 pvar->ssh_state.compress_stream.avail_in = len;
2488
2489 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2490 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2491 "Error compressing packet data");
2492 notify_fatal_error(pvar, pvar->ts->UIMsg);
2493 return;
2494 }
2495 } else {
2496 memcpy(outmsg + 4, buf, len);
2497 }
2498
2499 finish_send_packet_special(pvar, 1);
2500
2501 buflen -= len;
2502 buf += len;
2503 }
2504
2505 } else { // for SSH2(yutaka)
2506 buffer_t *msg;
2507 unsigned char *outmsg;
2508 int len;
2509 Channel_t *c;
2510
2511 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2512 if (pvar->rekeying) {
2513 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2514 // �������������������B
2515 c = NULL;
2516
2517 return;
2518 }
2519
2520 c = ssh2_channel_lookup(pvar->shell_id);
2521 if (c == NULL)
2522 return;
2523
2524 msg = buffer_init();
2525 if (msg == NULL) {
2526 // TODO: error check
2527 return;
2528 }
2529 buffer_put_int(msg, c->remote_id);
2530 buffer_put_string(msg, (char *)buf, buflen);
2531
2532 len = buffer_len(msg);
2533 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2534 memcpy(outmsg, buffer_ptr(msg), len);
2535 finish_send_packet(pvar);
2536 buffer_free(msg);
2537
2538 // remote window size������
2539 c->remote_window -= len;
2540
2541 }
2542
2543 }
2544
2545 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2546 {
2547 int num_bytes = pvar->ssh_state.payload_datalen;
2548
2549 if (num_bytes > len) {
2550 num_bytes = len;
2551 }
2552
2553 if (!pvar->ssh_state.decompressing) {
2554 memcpy(dest,
2555 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2556 num_bytes);
2557 pvar->ssh_state.payload_datastart += num_bytes;
2558 } else if (num_bytes > 0) {
2559 pvar->ssh_state.decompress_stream.next_out = dest;
2560 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2561
2562 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2563 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2564 "Invalid compressed data in received packet");
2565 notify_fatal_error(pvar, pvar->ts->UIMsg);
2566 return 0;
2567 }
2568 }
2569
2570 pvar->ssh_state.payload_datalen -= num_bytes;
2571
2572 return num_bytes;
2573 }
2574
2575 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2576 {
2577 char buf[1024];
2578 char buf2[1024];
2579
2580 // added support of SSH2 packet compression (2005.7.10 yutaka)
2581 // support of "Compression delayed" (2006.6.23 maya)
2582 if (pvar->ssh_state.compressing ||
2583 pvar->ctos_compression == COMP_ZLIB ||
2584 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2585 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2586 unsigned long total_out =
2587 pvar->ssh_state.compress_stream.total_out;
2588
2589 if (total_out > 0) {
2590 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2591 "level %d; ratio %.1f (%ld:%ld)");
2592 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2593 pvar->ssh_state.compression_level,
2594 ((double) total_in) / total_out, total_in,
2595 total_out);
2596 } else {
2597 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2598 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2599 pvar->ssh_state.compression_level);
2600 }
2601 } else {
2602 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2603 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2604 }
2605
2606 // support of "Compression delayed" (2006.6.23 maya)
2607 if (pvar->ssh_state.decompressing ||
2608 pvar->stoc_compression == COMP_ZLIB ||
2609 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2610 unsigned long total_in =
2611 pvar->ssh_state.decompress_stream.total_in;
2612 unsigned long total_out =
2613 pvar->ssh_state.decompress_stream.total_out;
2614
2615 if (total_in > 0) {
2616 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2617 "level %d; ratio %.1f (%ld:%ld)");
2618 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2619 pvar->ssh_state.compression_level,
2620 ((double) total_out) / total_in, total_out,
2621 total_in);
2622 } else {
2623 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2624 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2625 pvar->ssh_state.compression_level);
2626 }
2627 } else {
2628 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2629 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2630 }
2631
2632 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
2633 "Upstream %s; Downstream %s");
2634 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
2635 }
2636
2637 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2638 {
2639 strncpy_s(dest, len,
2640 pvar->ssh_state.server_ID == NULL ? "Unknown"
2641 : pvar->ssh_state.server_ID,
2642 _TRUNCATE);
2643 }
2644
2645 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2646 int len)
2647 {
2648 if (pvar->protocol_major == 0) {
2649 strncpy_s(dest, len, "Unknown", _TRUNCATE);
2650 } else {
2651 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
2652 pvar->protocol_minor);
2653 }
2654 }
2655
2656 void SSH_end(PTInstVar pvar)
2657 {
2658 int i;
2659
2660 for (i = 0; i < 256; i++) {
2661 SSHPacketHandlerItem FAR *first_item =
2662 pvar->ssh_state.packet_handlers[i];
2663
2664 if (first_item != NULL) {
2665 SSHPacketHandlerItem FAR *item = first_item;
2666
2667 do {
2668 SSHPacketHandlerItem FAR *cur_item = item;
2669
2670 item = item->next_for_message;
2671 free(cur_item);
2672 } while (item != first_item);
2673 }
2674 pvar->ssh_state.packet_handlers[i] = NULL;
2675 }
2676
2677 free(pvar->ssh_state.hostname);
2678 pvar->ssh_state.hostname = NULL;
2679 free(pvar->ssh_state.server_ID);
2680 pvar->ssh_state.server_ID = NULL;
2681 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2682 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2683 &pvar->ssh_state.precompress_outbuflen);
2684 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2685 &pvar->ssh_state.postdecompress_inbuflen);
2686
2687 // support of "Compression delayed" (2006.6.23 maya)
2688 if (pvar->ssh_state.compressing ||
2689 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2690 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2691 deflateEnd(&pvar->ssh_state.compress_stream);
2692 pvar->ssh_state.compressing = FALSE;
2693 }
2694 // support of "Compression delayed" (2006.6.23 maya)
2695 if (pvar->ssh_state.decompressing ||
2696 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2697 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2698 inflateEnd(&pvar->ssh_state.decompress_stream);
2699 pvar->ssh_state.decompressing = FALSE;
2700 }
2701
2702 #if 1
2703 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2704 if (SSHv2(pvar)) {
2705 if (pvar->kexdh) {
2706 DH_free(pvar->kexdh);
2707 pvar->kexdh = NULL;
2708 }
2709 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2710 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2711
2712 if (pvar->my_kex != NULL) {
2713 buffer_free(pvar->my_kex);
2714 pvar->my_kex = NULL;
2715 }
2716 if (pvar->peer_kex != NULL) {
2717 buffer_free(pvar->peer_kex);
2718 pvar->peer_kex = NULL;
2719 }
2720
2721 pvar->we_need = 0;
2722 pvar->key_done = 0;
2723 pvar->rekeying = 0;
2724
2725 if (pvar->session_id != NULL) {
2726 free(pvar->session_id);
2727 pvar->session_id = NULL;
2728 }
2729 pvar->session_id_len = 0;
2730
2731 pvar->userauth_success = 0;
2732 //pvar->remote_id = 0;
2733 pvar->shell_id = 0;
2734 pvar->session_nego_status = 0;
2735
2736 pvar->ssh_heartbeat_tick = 0;
2737
2738 if (pvar->decomp_buffer != NULL) {
2739 buffer_free(pvar->decomp_buffer);
2740 pvar->decomp_buffer = NULL;
2741 }
2742
2743 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
2744 free(pvar->ssh2_authlist);
2745 pvar->ssh2_authlist = NULL;
2746 }
2747 }
2748 #endif
2749
2750 }
2751
2752 /* support for port forwarding */
2753 void SSH_channel_send(PTInstVar pvar, int channel_num,
2754 uint32 remote_channel_num,
2755 unsigned char FAR * buf, int len)
2756 {
2757 int buflen = len;
2758
2759 if (SSHv1(pvar)) {
2760 unsigned char FAR *outmsg =
2761 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2762
2763 set_uint32(outmsg, remote_channel_num);
2764 set_uint32(outmsg + 4, len);
2765
2766 if (pvar->ssh_state.compressing) {
2767 buf_ensure_size(&pvar->ssh_state.outbuf,
2768 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2769 pvar->ssh_state.compress_stream.next_in =
2770 pvar->ssh_state.precompress_outbuf;
2771 pvar->ssh_state.compress_stream.avail_in = 9;
2772 pvar->ssh_state.compress_stream.next_out =
2773 pvar->ssh_state.outbuf + 12;
2774 pvar->ssh_state.compress_stream.avail_out =
2775 pvar->ssh_state.outbuflen - 12;
2776
2777 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2778 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2779 "Error compressing packet data");
2780 notify_fatal_error(pvar, pvar->ts->UIMsg);
2781 return;
2782 }
2783
2784 pvar->ssh_state.compress_stream.next_in =
2785 (unsigned char FAR *) buf;
2786 pvar->ssh_state.compress_stream.avail_in = len;
2787
2788 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2789 Z_OK) {
2790 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2791 "Error compressing packet data");
2792 notify_fatal_error(pvar, pvar->ts->UIMsg);
2793 return;
2794 }
2795 } else {
2796 memcpy(outmsg + 8, buf, len);
2797 }
2798
2799 finish_send_packet_special(pvar, 1);
2800
2801 } else {
2802 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
2803 buffer_t *msg;
2804 unsigned char *outmsg;
2805 int len;
2806 Channel_t *c;
2807
2808 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2809 if (pvar->rekeying) {
2810 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2811 // �������������������B
2812 c = NULL;
2813
2814 return;
2815 }
2816
2817 c = ssh2_local_channel_lookup(channel_num);
2818 if (c == NULL)
2819 return;
2820
2821 msg = buffer_init();
2822 if (msg == NULL) {
2823 // TODO: error check
2824 return;
2825 }
2826 buffer_put_int(msg, c->remote_id);
2827 buffer_put_string(msg, (char *)buf, buflen);
2828
2829 len = buffer_len(msg);
2830 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2831 memcpy(outmsg, buffer_ptr(msg), len);
2832 finish_send_packet(pvar);
2833 buffer_free(msg);
2834
2835 // remote window size������
2836 c->remote_window -= len;
2837 }
2838
2839 }
2840
2841 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2842 {
2843 if (SSHv1(pvar)) {
2844 unsigned char FAR *outmsg =
2845 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2846
2847 set_uint32(outmsg, remote_channel_num);
2848 finish_send_packet(pvar);
2849
2850 } else { // SSH2 (2005.6.26 yutaka)
2851 int len;
2852 Channel_t *c = NULL;
2853 buffer_t *msg;
2854 unsigned char *outmsg;
2855
2856 msg = buffer_init();
2857 if (msg == NULL) {
2858 // TODO: error check
2859 return;
2860 }
2861 buffer_put_int(msg, remote_channel_num);
2862 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
2863 buffer_put_string(msg, "", 0); // description
2864 buffer_put_string(msg, "", 0); // language tag
2865
2866 len = buffer_len(msg);
2867 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
2868 memcpy(outmsg, buffer_ptr(msg), len);
2869 finish_send_packet(pvar);
2870 buffer_free(msg);
2871
2872 }
2873 }
2874
2875 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2876 uint32 local_channel_num)
2877 {
2878 if (SSHv1(pvar)) {
2879 unsigned char FAR *outmsg =
2880 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2881
2882 set_uint32(outmsg, remote_channel_num);
2883 set_uint32(outmsg + 4, local_channel_num);
2884 finish_send_packet(pvar);
2885
2886 } else {
2887 buffer_t *msg;
2888 unsigned char *outmsg;
2889 int len;
2890 Channel_t *c;
2891
2892 // port-forwarding(remote to local)�����[�J�����������������T�[�o�������B(2005.7.2 yutaka)
2893 c = ssh2_local_channel_lookup(local_channel_num);
2894 if (c == NULL) {
2895 // It is sure to be successful as long as it's not a program bug either.
2896 return;
2897 }
2898
2899 msg = buffer_init();
2900 if (msg == NULL) {
2901 // TODO: error check
2902 return;
2903 }
2904 buffer_put_int(msg, c->remote_id);
2905 buffer_put_int(msg, c->self_id);
2906 buffer_put_int(msg, c->local_window);
2907 buffer_put_int(msg, c->local_maxpacket);
2908
2909 len = buffer_len(msg);
2910 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len);
2911 memcpy(outmsg, buffer_ptr(msg), len);
2912 finish_send_packet(pvar);
2913 buffer_free(msg);
2914
2915 }
2916 }
2917
2918 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2919 {
2920 if (SSHv1(pvar)){
2921 unsigned char FAR *outmsg =
2922 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2923
2924 set_uint32(outmsg, remote_channel_num);
2925 finish_send_packet(pvar);
2926
2927 } else {
2928 // SSH2: ���������B
2929
2930 }
2931 }
2932
2933 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num)
2934 {
2935 if (SSHv1(pvar)){
2936 unsigned char FAR *outmsg =
2937 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2938
2939 set_uint32(outmsg, remote_channel_num);
2940 finish_send_packet(pvar);
2941
2942 } else {
2943 // SSH2: �`���l���N���[�Y���T�[�o�����m
2944 buffer_t *msg;
2945 unsigned char *outmsg;
2946 int len;
2947 Channel_t *c;
2948
2949 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
2950 if (pvar->rekeying) {
2951 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2952 // �������������������B
2953 c = NULL;
2954
2955 return;
2956 }
2957
2958 c = ssh2_local_channel_lookup(local_channel_num);
2959 if (c == NULL)
2960 return;
2961
2962 msg = buffer_init();
2963 if (msg == NULL) {
2964 // TODO: error check
2965 return;
2966 }
2967 buffer_put_int(msg, c->remote_id); // remote ID
2968
2969 len = buffer_len(msg);
2970 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_EOF, len);
2971 memcpy(outmsg, buffer_ptr(msg), len);
2972 finish_send_packet(pvar);
2973 buffer_free(msg);
2974 }
2975
2976 }
2977
2978 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2979 char FAR * to_local_host, int to_local_port)
2980 {
2981 if (SSHv1(pvar)) {
2982 int host_len = strlen(to_local_host);
2983 unsigned char FAR *outmsg =
2984 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2985 12 + host_len);
2986
2987 set_uint32(outmsg, from_server_port);
2988 set_uint32(outmsg + 4, host_len);
2989 memcpy(outmsg + 8, to_local_host, host_len);
2990 set_uint32(outmsg + 8 + host_len, to_local_port);
2991 finish_send_packet(pvar);
2992
2993 enque_forwarding_request_handlers(pvar);
2994
2995 } else {
2996 // SSH2 port-forwading remote to local (2005.6.21 yutaka)
2997 buffer_t *msg;
2998 char *s;
2999 unsigned char *outmsg;
3000 int len;
3001
3002 msg = buffer_init();
3003 if (msg == NULL) {
3004 // TODO: error check
3005 return;
3006 }
3007 s = "tcpip-forward";
3008 buffer_put_string(msg, s, strlen(s)); // ctype
3009 buffer_put_char(msg, 1); // want reply
3010 s = "0.0.0.0";
3011 buffer_put_string(msg, s, strlen(s));
3012
3013 buffer_put_int(msg, from_server_port); // listening port
3014
3015 len = buffer_len(msg);
3016 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
3017 memcpy(outmsg, buffer_ptr(msg), len);
3018 finish_send_packet(pvar);
3019 buffer_free(msg);
3020
3021 }
3022 }
3023
3024 void SSH_request_X11_forwarding(PTInstVar pvar,
3025 char FAR * auth_protocol,
3026 unsigned char FAR * auth_data,
3027 int auth_data_len, int screen_num)
3028 {
3029 if (SSHv1(pvar)) {
3030 int protocol_len = strlen(auth_protocol);
3031 int data_len = auth_data_len * 2;
3032 int outmsg_len = 12 + protocol_len + data_len;
3033 unsigned char FAR *outmsg =
3034 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING, outmsg_len);
3035 int i;
3036 char FAR *auth_data_ptr;
3037
3038 set_uint32(outmsg, protocol_len);
3039 memcpy(outmsg + 4, auth_protocol, protocol_len);
3040 set_uint32(outmsg + 4 + protocol_len, data_len);
3041 auth_data_ptr = outmsg + 8 + protocol_len;
3042 for (i = 0; i < auth_data_len; i++) {
3043 _snprintf_s(auth_data_ptr + i * 2,
3044 outmsg_len - (auth_data_ptr - outmsg) - i * 2,
3045 _TRUNCATE, "%.2x", auth_data[i]);
3046 }
3047 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
3048
3049 finish_send_packet(pvar);
3050
3051 enque_forwarding_request_handlers(pvar);
3052
3053 } else {
3054 // SSH2: X11 port-forwarding (2005.7.2 yutaka)
3055 buffer_t *msg;
3056 char *s;
3057 unsigned char *outmsg;
3058 int len;
3059 Channel_t *c;
3060 int newlen;
3061 char *newdata;
3062 int i;
3063
3064 msg = buffer_init();
3065 if (msg == NULL) {
3066 // TODO: error check
3067 return;
3068 }
3069
3070 c = ssh2_channel_lookup(pvar->shell_id);
3071 if (c == NULL)
3072 return;
3073
3074 // making the fake data
3075 newlen = 2 * auth_data_len + 1;
3076 newdata = malloc(newlen);
3077 if (newdata == NULL)
3078 return;
3079 for (i = 0 ; i < auth_data_len ; i++) {
3080 _snprintf_s(newdata + i*2, newlen - i*2, _TRUNCATE, "%02x", auth_data[i]);
3081 }
3082 newdata[newlen - 1] = '\0';
3083
3084 buffer_put_int(msg, c->remote_id);
3085 s = "x11-req";
3086 buffer_put_string(msg, s, strlen(s)); // service name
3087 buffer_put_char(msg, 0); // want confirm (false)
3088 buffer_put_char(msg, 0); // XXX bool single connection
3089
3090 s = auth_protocol; // MIT-MAGIC-COOKIE-1
3091 buffer_put_string(msg, s, strlen(s));
3092 s = newdata;
3093 buffer_put_string(msg, s, strlen(s));
3094
3095 buffer_put_int(msg, screen_num);
3096
3097 len = buffer_len(msg);
3098 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
3099 memcpy(outmsg, buffer_ptr(msg), len);
3100 finish_send_packet(pvar);
3101 buffer_free(msg);
3102
3103 free(newdata);
3104 }
3105
3106 }
3107
3108 void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
3109 char FAR * to_remote_host, int to_remote_port,
3110 char FAR * originator, unsigned short originator_port)
3111 {
3112 static const int msgs[]
3113 = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
3114 static const SSHPacketHandler handlers[]
3115 = { handle_channel_open_confirmation, handle_channel_open_failure };
3116
3117 int host_len = strlen(to_remote_host);
3118
3119 if ((pvar->ssh_state.
3120 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
3121 int originator_len = strlen(originator);
3122 unsigned char FAR *outmsg =
3123 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
3124 16 + host_len + originator_len);
3125
3126 set_uint32(outmsg, local_channel_num);
3127 set_uint32(outmsg + 4, host_len);
3128 memcpy(outmsg + 8, to_remote_host, host_len);
3129 set_uint32(outmsg + 8 + host_len, to_remote_port);
3130 set_uint32(outmsg + 12 + host_len, originator_len);
3131 memcpy(outmsg + 16 + host_len, originator, originator_len);
3132 } else {
3133
3134 if (SSHv1(pvar)) {
3135 unsigned char FAR *outmsg =
3136 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
3137 12 + host_len);
3138
3139 set_uint32(outmsg, local_channel_num);
3140 set_uint32(outmsg + 4, host_len);
3141 memcpy(outmsg + 8, to_remote_host, host_len);
3142 set_uint32(outmsg + 8 + host_len, to_remote_port);
3143
3144 } else {
3145 // SSH2 port-fowarding (2005.2.26 yutaka)
3146 buffer_t *msg;
3147 char *s;
3148 unsigned char *outmsg;
3149 int len;
3150 Channel_t *c;
3151
3152 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
3153 if (pvar->rekeying) {
3154 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3155 // �������������������B
3156 c = NULL;
3157
3158 return;
3159 }
3160
3161 // changed window size from 128KB to 32KB. (2006.3.6 yutaka)
3162 c = ssh2_channel_new(CHAN_TCP_PACKET_DEFAULT, CHAN_TCP_PACKET_DEFAULT, TYPE_PORTFWD, local_channel_num);
3163 if (c == NULL) {
3164 // �]���`���l�����������\�P�b�g�������R�����C�� (2007.7.26 maya)
3165 FWD_free_channel(pvar, local_channel_num);
3166 UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar,
3167 "Could not open new channel. TTSSH is already opening too many channels.");
3168 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
3169 return;
3170 }
3171
3172 msg = buffer_init();
3173 if (msg == NULL) {
3174 // TODO: error check
3175 return;
3176 }
3177 s = "direct-tcpip";
3178 buffer_put_string(msg, s, strlen(s)); // ctype
3179 buffer_put_int(msg, c->self_id); // self
3180 buffer_put_int(msg, c->local_window); // local_window
3181 buffer_put_int(msg, c->local_maxpacket); // local_maxpacket
3182
3183 s = to_remote_host;
3184 buffer_put_string(msg, s, strlen(s)); // target host
3185 buffer_put_int(msg, to_remote_port); // target port
3186
3187 s = originator;
3188 buffer_put_string(msg, s, strlen(s)); // originator host
3189 buffer_put_int(msg, originator_port); // originator port
3190
3191 len = buffer_len(msg);
3192 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN, len);
3193 memcpy(outmsg, buffer_ptr(msg), len);
3194 finish_send_packet(pvar);
3195 buffer_free(msg);
3196
3197 return;
3198
3199 /* NOT REACHED */
3200 }
3201
3202 }
3203
3204 if (SSHv1(pvar)) { // SSH1����
3205 finish_send_packet(pvar);
3206 enque_handlers(pvar, 2, msgs, handlers);
3207 }
3208
3209 }
3210
3211
3212 /////////////////////////////////////////////////////////////////////////////
3213 //
3214 // SSH2 protocol procedure in the following code:
3215 //
3216 /////////////////////////////////////////////////////////////////////////////
3217
3218 void debug_print(int no, char *msg, int len)
3219 {
3220 #ifdef _DEBUG
3221 FILE *fp;
3222 char file[128];
3223
3224 _snprintf_s(file, sizeof(file), _TRUNCATE, "dump%d.bin", no);
3225
3226 fp = fopen(file, "wb");
3227 if (fp == NULL)
3228 return;
3229
3230 fwrite(msg, 1, len, fp);
3231
3232 fclose(fp);
3233 #endif
3234 }
3235