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 2995 - (show annotations) (download) (as text)
Wed Aug 15 04:03:26 2007 UTC (16 years, 8 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 187698 byte(s)
$Log$ を削除した。

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