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 3054 - (show annotations) (download) (as text)
Sun Oct 28 05:11:47 2007 UTC (16 years, 5 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 190682 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 unsigned int encryption_size;
849 unsigned 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 unsigned 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 if (len <= c->remote_window) {
2541 c->remote_window -= buflen;
2542 }
2543 else {
2544 c->remote_window = 0;
2545 }
2546
2547 }
2548
2549 }
2550
2551 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2552 {
2553 int num_bytes = pvar->ssh_state.payload_datalen;
2554
2555 if (num_bytes > len) {
2556 num_bytes = len;
2557 }
2558
2559 if (!pvar->ssh_state.decompressing) {
2560 memcpy(dest,
2561 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2562 num_bytes);
2563 pvar->ssh_state.payload_datastart += num_bytes;
2564 } else if (num_bytes > 0) {
2565 pvar->ssh_state.decompress_stream.next_out = dest;
2566 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2567
2568 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2569 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2570 "Invalid compressed data in received packet");
2571 notify_fatal_error(pvar, pvar->ts->UIMsg);
2572 return 0;
2573 }
2574 }
2575
2576 pvar->ssh_state.payload_datalen -= num_bytes;
2577
2578 return num_bytes;
2579 }
2580
2581 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2582 {
2583 char buf[1024];
2584 char buf2[1024];
2585
2586 // added support of SSH2 packet compression (2005.7.10 yutaka)
2587 // support of "Compression delayed" (2006.6.23 maya)
2588 if (pvar->ssh_state.compressing ||
2589 pvar->ctos_compression == COMP_ZLIB ||
2590 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2591 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2592 unsigned long total_out =
2593 pvar->ssh_state.compress_stream.total_out;
2594
2595 if (total_out > 0) {
2596 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2597 "level %d; ratio %.1f (%ld:%ld)");
2598 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2599 pvar->ssh_state.compression_level,
2600 ((double) total_in) / total_out, total_in,
2601 total_out);
2602 } else {
2603 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2604 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2605 pvar->ssh_state.compression_level);
2606 }
2607 } else {
2608 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2609 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2610 }
2611
2612 // support of "Compression delayed" (2006.6.23 maya)
2613 if (pvar->ssh_state.decompressing ||
2614 pvar->stoc_compression == COMP_ZLIB ||
2615 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2616 unsigned long total_in =
2617 pvar->ssh_state.decompress_stream.total_in;
2618 unsigned long total_out =
2619 pvar->ssh_state.decompress_stream.total_out;
2620
2621 if (total_in > 0) {
2622 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2623 "level %d; ratio %.1f (%ld:%ld)");
2624 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2625 pvar->ssh_state.compression_level,
2626 ((double) total_out) / total_in, total_out,
2627 total_in);
2628 } else {
2629 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2630 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2631 pvar->ssh_state.compression_level);
2632 }
2633 } else {
2634 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2635 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2636 }
2637
2638 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
2639 "Upstream %s; Downstream %s");
2640 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
2641 }
2642
2643 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2644 {
2645 strncpy_s(dest, len,
2646 pvar->ssh_state.server_ID == NULL ? "Unknown"
2647 : pvar->ssh_state.server_ID,
2648 _TRUNCATE);
2649 }
2650
2651 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2652 int len)
2653 {
2654 if (pvar->protocol_major == 0) {
2655 strncpy_s(dest, len, "Unknown", _TRUNCATE);
2656 } else {
2657 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
2658 pvar->protocol_minor);
2659 }
2660 }
2661
2662 void SSH_end(PTInstVar pvar)
2663 {
2664 int i;
2665
2666 for (i = 0; i < 256; i++) {
2667 SSHPacketHandlerItem FAR *first_item =
2668 pvar->ssh_state.packet_handlers[i];
2669
2670 if (first_item != NULL) {
2671 SSHPacketHandlerItem FAR *item = first_item;
2672
2673 do {
2674 SSHPacketHandlerItem FAR *cur_item = item;
2675
2676 item = item->next_for_message;
2677 free(cur_item);
2678 } while (item != first_item);
2679 }
2680 pvar->ssh_state.packet_handlers[i] = NULL;
2681 }
2682
2683 free(pvar->ssh_state.hostname);
2684 pvar->ssh_state.hostname = NULL;
2685 free(pvar->ssh_state.server_ID);
2686 pvar->ssh_state.server_ID = NULL;
2687 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2688 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2689 &pvar->ssh_state.precompress_outbuflen);
2690 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2691 &pvar->ssh_state.postdecompress_inbuflen);
2692
2693 // support of "Compression delayed" (2006.6.23 maya)
2694 if (pvar->ssh_state.compressing ||
2695 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2696 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2697 deflateEnd(&pvar->ssh_state.compress_stream);
2698 pvar->ssh_state.compressing = FALSE;
2699 }
2700 // support of "Compression delayed" (2006.6.23 maya)
2701 if (pvar->ssh_state.decompressing ||
2702 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2703 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2704 inflateEnd(&pvar->ssh_state.decompress_stream);
2705 pvar->ssh_state.decompressing = FALSE;
2706 }
2707
2708 #if 1
2709 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2710 if (SSHv2(pvar)) {
2711 if (pvar->kexdh) {
2712 DH_free(pvar->kexdh);
2713 pvar->kexdh = NULL;
2714 }
2715 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2716 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2717
2718 if (pvar->my_kex != NULL) {
2719 buffer_free(pvar->my_kex);
2720 pvar->my_kex = NULL;
2721 }
2722 if (pvar->peer_kex != NULL) {
2723 buffer_free(pvar->peer_kex);
2724 pvar->peer_kex = NULL;
2725 }
2726
2727 pvar->we_need = 0;
2728 pvar->key_done = 0;
2729 pvar->rekeying = 0;
2730
2731 if (pvar->session_id != NULL) {
2732 free(pvar->session_id);
2733 pvar->session_id = NULL;
2734 }
2735 pvar->session_id_len = 0;
2736
2737 pvar->userauth_success = 0;
2738 //pvar->remote_id = 0;
2739 pvar->shell_id = 0;
2740 pvar->session_nego_status = 0;
2741
2742 pvar->ssh_heartbeat_tick = 0;
2743
2744 if (pvar->decomp_buffer != NULL) {
2745 buffer_free(pvar->decomp_buffer);
2746 pvar->decomp_buffer = NULL;
2747 }
2748
2749 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
2750 free(pvar->ssh2_authlist);
2751 pvar->ssh2_authlist = NULL;
2752 }
2753
2754 pvar->tryed_ssh2_authlist = FALSE;
2755 }
2756 #endif
2757
2758 }
2759
2760 /* support for port forwarding */
2761 void SSH_channel_send(PTInstVar pvar, int channel_num,
2762 uint32 remote_channel_num,
2763 unsigned char FAR * buf, int len)
2764 {
2765 int buflen = len;
2766
2767 if (SSHv1(pvar)) {
2768 unsigned char FAR *outmsg =
2769 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2770
2771 set_uint32(outmsg, remote_channel_num);
2772 set_uint32(outmsg + 4, len);
2773
2774 if (pvar->ssh_state.compressing) {
2775 buf_ensure_size(&pvar->ssh_state.outbuf,
2776 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2777 pvar->ssh_state.compress_stream.next_in =
2778 pvar->ssh_state.precompress_outbuf;
2779 pvar->ssh_state.compress_stream.avail_in = 9;
2780 pvar->ssh_state.compress_stream.next_out =
2781 pvar->ssh_state.outbuf + 12;
2782 pvar->ssh_state.compress_stream.avail_out =
2783 pvar->ssh_state.outbuflen - 12;
2784
2785 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2786 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2787 "Error compressing packet data");
2788 notify_fatal_error(pvar, pvar->ts->UIMsg);
2789 return;
2790 }
2791
2792 pvar->ssh_state.compress_stream.next_in =
2793 (unsigned char FAR *) buf;
2794 pvar->ssh_state.compress_stream.avail_in = len;
2795
2796 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2797 Z_OK) {
2798 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2799 "Error compressing packet data");
2800 notify_fatal_error(pvar, pvar->ts->UIMsg);
2801 return;
2802 }
2803 } else {
2804 memcpy(outmsg + 8, buf, len);
2805 }
2806
2807 finish_send_packet_special(pvar, 1);
2808
2809 } else {
2810 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
2811 buffer_t *msg;
2812 unsigned char *outmsg;
2813 unsigned int len;
2814 Channel_t *c;
2815
2816 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2817 if (pvar->rekeying) {
2818 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2819 // �������������������B
2820 c = NULL;
2821
2822 return;
2823 }
2824
2825 c = ssh2_local_channel_lookup(channel_num);
2826 if (c == NULL)
2827 return;
2828
2829 msg = buffer_init();
2830 if (msg == NULL) {
2831 // TODO: error check
2832 return;
2833 }
2834 buffer_put_int(msg, c->remote_id);
2835 buffer_put_string(msg, (char *)buf, buflen);
2836
2837 len = buffer_len(msg);
2838 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2839 memcpy(outmsg, buffer_ptr(msg), len);
2840 finish_send_packet(pvar);
2841 buffer_free(msg);
2842
2843 // remote window size������
2844 if (len <= c->remote_window) {
2845 c->remote_window -= buflen;
2846 }
2847 else {
2848 c->remote_window = 0;
2849 }
2850 }
2851
2852 }
2853
2854 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2855 {
2856 if (SSHv1(pvar)) {
2857 unsigned char FAR *outmsg =
2858 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2859
2860 set_uint32(outmsg, remote_channel_num);
2861 finish_send_packet(pvar);
2862
2863 } else { // SSH2 (2005.6.26 yutaka)
2864 int len;
2865 Channel_t *c = NULL;
2866 buffer_t *msg;
2867 unsigned char *outmsg;
2868
2869 msg = buffer_init();
2870 if (msg == NULL) {
2871 // TODO: error check
2872 return;
2873 }
2874 buffer_put_int(msg, remote_channel_num);
2875 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
2876 buffer_put_string(msg, "", 0); // description
2877 buffer_put_string(msg, "", 0); // language tag
2878
2879 len = buffer_len(msg);
2880 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
2881 memcpy(outmsg, buffer_ptr(msg), len);
2882 finish_send_packet(pvar);
2883 buffer_free(msg);
2884
2885 }
2886 }
2887
2888 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2889 uint32 local_channel_num)
2890 {
2891 if (SSHv1(pvar)) {
2892 unsigned char FAR *outmsg =
2893 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2894
2895 set_uint32(outmsg, remote_channel_num);
2896 set_uint32(outmsg + 4, local_channel_num);
2897 finish_send_packet(pvar);
2898
2899 } else {
2900 buffer_t *msg;
2901 unsigned char *outmsg;
2902 int len;
2903 Channel_t *c;
2904
2905 // port-forwarding(remote to local)�����[�J�����������������T�[�o�������B(2005.7.2 yutaka)
2906 c = ssh2_local_channel_lookup(local_channel_num);
2907 if (c == NULL) {
2908 // It is sure to be successful as long as it's not a program bug either.
2909 return;
2910 }
2911
2912 msg = buffer_init();
2913 if (msg == NULL) {
2914 // TODO: error check
2915 return;
2916 }
2917 buffer_put_int(msg, c->remote_id);
2918 buffer_put_int(msg, c->self_id);
2919 buffer_put_int(msg, c->local_window);
2920 buffer_put_int(msg, c->local_maxpacket);
2921
2922 len = buffer_len(msg);
2923 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len);
2924 memcpy(outmsg, buffer_ptr(msg), len);
2925 finish_send_packet(pvar);
2926 buffer_free(msg);
2927
2928 }
2929 }
2930
2931 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2932 {
2933 if (SSHv1(pvar)){
2934 unsigned char FAR *outmsg =
2935 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2936
2937 set_uint32(outmsg, remote_channel_num);
2938 finish_send_packet(pvar);
2939
2940 } else {
2941 // SSH2: ���������B
2942
2943 }
2944 }
2945
2946 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num)
2947 {
2948 if (SSHv1(pvar)){
2949 unsigned char FAR *outmsg =
2950 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2951
2952 set_uint32(outmsg, remote_channel_num);
2953 finish_send_packet(pvar);
2954
2955 } else {
2956 // SSH2: �`���l���N���[�Y���T�[�o�����m
2957 buffer_t *msg;
2958 unsigned char *outmsg;
2959 int len;
2960 Channel_t *c;
2961
2962 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
2963 if (pvar->rekeying) {
2964 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2965 // �������������������B
2966 c = NULL;
2967
2968 return;
2969 }
2970
2971 c = ssh2_local_channel_lookup(local_channel_num);
2972 if (c == NULL)
2973 return;
2974
2975 msg = buffer_init();
2976 if (msg == NULL) {
2977 // TODO: error check
2978 return;
2979 }
2980 buffer_put_int(msg, c->remote_id); // remote ID
2981
2982 len = buffer_len(msg);
2983 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_EOF, len);
2984 memcpy(outmsg, buffer_ptr(msg), len);
2985 finish_send_packet(pvar);
2986 buffer_free(msg);
2987 }
2988
2989 }
2990
2991 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2992 char FAR * to_local_host, int to_local_port)
2993 {
2994 if (SSHv1(pvar)) {
2995 int host_len = strlen(to_local_host);
2996 unsigned char FAR *outmsg =
2997 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2998 12 + host_len);
2999
3000 set_uint32(outmsg, from_server_port);
3001 set_uint32(outmsg + 4, host_len);
3002 memcpy(outmsg + 8, to_local_host, host_len);
3003 set_uint32(outmsg + 8 + host_len, to_local_port);
3004 finish_send_packet(pvar);
3005
3006 enque_forwarding_request_handlers(pvar);
3007
3008 } else {
3009 // SSH2 port-forwading remote to local (2005.6.21 yutaka)
3010 buffer_t *msg;
3011 char *s;
3012 unsigned char *outmsg;
3013 int len;
3014
3015 msg = buffer_init();
3016 if (msg == NULL) {
3017 // TODO: error check
3018 return;
3019 }
3020 s = "tcpip-forward";
3021 buffer_put_string(msg, s, strlen(s)); // ctype
3022 buffer_put_char(msg, 1); // want reply
3023 s = "0.0.0.0";
3024 buffer_put_string(msg, s, strlen(s));
3025
3026 buffer_put_int(msg, from_server_port); // listening port
3027
3028 len = buffer_len(msg);
3029 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
3030 memcpy(outmsg, buffer_ptr(msg), len);
3031 finish_send_packet(pvar);
3032 buffer_free(msg);
3033
3034 }
3035 }
3036
3037 void SSH_request_X11_forwarding(PTInstVar pvar,
3038 char FAR * auth_protocol,
3039 unsigned char FAR * auth_data,
3040 int auth_data_len, int screen_num)
3041 {
3042 if (SSHv1(pvar)) {
3043 int protocol_len = strlen(auth_protocol);
3044 int data_len = auth_data_len * 2;
3045 int outmsg_len = 12 + protocol_len + data_len;
3046 unsigned char FAR *outmsg =
3047 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING, outmsg_len);
3048 int i;
3049 char FAR *auth_data_ptr;
3050
3051 set_uint32(outmsg, protocol_len);
3052 memcpy(outmsg + 4, auth_protocol, protocol_len);
3053 set_uint32(outmsg + 4 + protocol_len, data_len);
3054 auth_data_ptr = outmsg + 8 + protocol_len;
3055 for (i = 0; i < auth_data_len; i++) {
3056 _snprintf_s(auth_data_ptr + i * 2,
3057 outmsg_len - (auth_data_ptr - outmsg) - i * 2,
3058 _TRUNCATE, "%.2x", auth_data[i]);
3059 }
3060 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
3061
3062 finish_send_packet(pvar);
3063
3064 enque_forwarding_request_handlers(pvar);
3065
3066 } else {
3067 // SSH2: X11 port-forwarding (2005.7.2 yutaka)
3068 buffer_t *msg;
3069 char *s;
3070 unsigned char *outmsg;
3071 int len;
3072 Channel_t *c;
3073 int newlen;
3074 char *newdata;
3075 int i;
3076
3077 msg = buffer_init();
3078 if (msg == NULL) {
3079 // TODO: error check
3080 return;
3081 }
3082
3083 c = ssh2_channel_lookup(pvar->shell_id);
3084 if (c == NULL)
3085 return;
3086
3087 // making the fake data
3088 newlen = 2 * auth_data_len + 1;
3089 newdata = malloc(newlen);
3090 if (newdata == NULL)
3091 return;
3092 for (i = 0 ; i < auth_data_len ; i++) {
3093 _snprintf_s(newdata + i*2, newlen - i*2, _TRUNCATE, "%02x", auth_data[i]);
3094 }
3095 newdata[newlen - 1] = '\0';
3096
3097 buffer_put_int(msg, c->remote_id);
3098 s = "x11-req";
3099 buffer_put_string(msg, s, strlen(s)); // service name
3100 buffer_put_char(msg, 0); // want confirm (false)
3101 buffer_put_char(msg, 0); // XXX bool single connection
3102
3103 s = auth_protocol; // MIT-MAGIC-COOKIE-1
3104 buffer_put_string(msg, s, strlen(s));
3105 s = newdata;
3106 buffer_put_string(msg, s, strlen(s));
3107
3108 buffer_put_int(msg, screen_num);
3109
3110 len = buffer_len(msg);
3111 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
3112 memcpy(outmsg, buffer_ptr(msg), len);
3113 finish_send_packet(pvar);
3114 buffer_free(msg);
3115
3116 free(newdata);
3117 }
3118
3119 }
3120
3121 void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
3122 char FAR * to_remote_host, int to_remote_port,
3123 char FAR * originator, unsigned short originator_port)
3124 {
3125 static const int msgs[]
3126 = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
3127 static const SSHPacketHandler handlers[]
3128 = { handle_channel_open_confirmation, handle_channel_open_failure };
3129
3130 int host_len = strlen(to_remote_host);
3131
3132 if ((pvar->ssh_state.
3133 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
3134 int originator_len = strlen(originator);
3135 unsigned char FAR *outmsg =
3136 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
3137 16 + host_len + originator_len);
3138
3139 set_uint32(outmsg, local_channel_num);
3140 set_uint32(outmsg + 4, host_len);
3141 memcpy(outmsg + 8, to_remote_host, host_len);
3142 set_uint32(outmsg + 8 + host_len, to_remote_port);
3143 set_uint32(outmsg + 12 + host_len, originator_len);
3144 memcpy(outmsg + 16 + host_len, originator, originator_len);
3145 } else {
3146
3147 if (SSHv1(pvar)) {
3148 unsigned char FAR *outmsg =
3149 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
3150 12 + host_len);
3151
3152 set_uint32(outmsg, local_channel_num);
3153 set_uint32(outmsg + 4, host_len);
3154 memcpy(outmsg + 8, to_remote_host, host_len);
3155 set_uint32(outmsg + 8 + host_len, to_remote_port);
3156
3157 } else {
3158 // SSH2 port-fowarding (2005.2.26 yutaka)
3159 buffer_t *msg;
3160 char *s;
3161 unsigned char *outmsg;
3162 int len;
3163 Channel_t *c;
3164
3165 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
3166 if (pvar->rekeying) {
3167 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3168 // �������������������B
3169 c = NULL;
3170
3171 return;
3172 }
3173
3174 // changed window size from 128KB to 32KB. (2006.3.6 yutaka)
3175 c = ssh2_channel_new(CHAN_TCP_PACKET_DEFAULT, CHAN_TCP_PACKET_DEFAULT, TYPE_PORTFWD, local_channel_num);
3176 if (c == NULL) {
3177 // �]���`���l�����������\�P�b�g�������R�����C�� (2007.7.26 maya)
3178 FWD_free_channel(pvar, local_channel_num);
3179 UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar,
3180 "Could not open new channel. TTSSH is already opening too many channels.");
3181 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
3182 return;
3183 }
3184
3185 msg = buffer_init();
3186 if (msg == NULL) {
3187 // TODO: error check
3188 return;
3189 }
3190 s = "direct-tcpip";
3191 buffer_put_string(msg, s, strlen(s)); // ctype
3192 buffer_put_int(msg, c->self_id); // self
3193 buffer_put_int(msg, c->local_window); // local_window
3194 buffer_put_int(msg, c->local_maxpacket); // local_maxpacket
3195
3196 s = to_remote_host;
3197 buffer_put_string(msg, s, strlen(s)); // target host
3198 buffer_put_int(msg, to_remote_port); // target port
3199
3200 s = originator;
3201 buffer_put_string(msg, s, strlen(s)); // originator host
3202 buffer_put_int(msg, originator_port); // originator port
3203
3204 len = buffer_len(msg);
3205 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN, len);
3206 memcpy(outmsg, buffer_ptr(msg), len);
3207 finish_send_packet(pvar);
3208 buffer_free(msg);
3209
3210 return;
3211
3212 /* NOT REACHED */
3213 }
3214
3215 }
3216
3217 if (SSHv1(pvar)) { // SSH1����
3218 finish_send_packet(pvar);
3219 enque_handlers(pvar, 2, msgs, handlers);
3220 }
3221
3222 }
3223
3224
3225 /////////////////////////////////////////////////////////////////////////////
3226 //
3227 // SSH2 protocol procedure in the following code:
3228 //
3229 /////////////////////////////////////////////////////////////////////////////
3230
3231 void debug_print(int no, char *msg, int len)
3232 {
3233 #ifdef _DEBUG
3234 FILE *fp;
3235 char file[128];
3236
3237 _snprintf_s(file, sizeof(file), _TRUNCATE, "dump%d.bin", no);
3238
3239 fp = fopen(file, "wb");