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 3018 - (show annotations) (download) (as text)
Mon Oct 1 14:46:22 2007 UTC (16 years, 6 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 189802 byte(s)
自動ログイン時に認証情報を送れなくなっていたのを修正した。

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