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 2824 - (show annotations) (download) (as text)
Tue Jun 21 13:28:26 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 152463 byte(s)
SSH2鍵交換中の(鍵交換以外の)SSH2メッセージ送信を破棄するようにした。

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