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 3003 - (show annotations) (download) (as text)
Mon Aug 20 14:21:57 2007 UTC (16 years, 7 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 190996 byte(s)
インデントを変更した。

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