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 2856 - (show annotations) (download) (as text)
Sun Mar 26 15:43:58 2006 UTC (18 years ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 175589 byte(s)
SSH2のknown_hosts対応を追加した。

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