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 2938 - (show annotations) (download) (as text)
Tue Nov 28 13:20:52 2006 UTC (17 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 185841 byte(s)
Cisco ルータの送信する SSH2_MSG_IGNORE のデータが不正なようなので、何も処理しないようにした。

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