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 2826 - (show annotations) (download) (as text)
Sat Jul 2 07:56:13 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 158137 byte(s)
update SSH2 port-forwading(remote to local)

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