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 2827 - (show annotations) (download) (as text)
Sat Jul 2 08:43:32 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 159616 byte(s)
SSH2_MSG_CHANNEL_OPEN_FAILURE ハンドラを追加した。

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