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 2924 - (show annotations) (download) (as text)
Sun Oct 29 17:26:47 2006 UTC (17 years, 5 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 181894 byte(s)
  ・MACとパケット圧縮を有効にするタイミングを SSH2_MSG_NEWKEYS の送受信時に変更することにより、Tectiva serverへつながらない問題を修正した。

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