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 2891 - (show annotations) (download) (as text)
Sat Aug 5 03:47:49 2006 UTC (17 years, 8 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 180786 byte(s)
パスワードをメモリ上に覚えておくかどうかの設定は teraterm.ini に反映させるようにした。

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->userauth_retry_count = 0;
2218 pvar->decomp_buffer = NULL;
2219
2220 }
2221
2222 void SSH_open(PTInstVar pvar)
2223 {
2224 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2225 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2226 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2227 }
2228
2229 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2230 {
2231 if (SSHv1(pvar)) {
2232 int len = reason == NULL ? 0 : strlen(reason);
2233 unsigned char FAR *outmsg =
2234 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2235
2236 set_uint32(outmsg, len);
2237 if (reason != NULL) {
2238 memcpy(outmsg + 4, reason, len);
2239 }
2240 finish_send_packet(pvar);
2241
2242 } else { // for SSH2(yutaka)
2243 buffer_t *msg;
2244 unsigned char *outmsg;
2245 int len;
2246 Channel_t *c;
2247
2248 c = ssh2_channel_lookup(pvar->shell_id);
2249 if (c == NULL)
2250 return;
2251
2252 // SSH2 server��channel close���`����
2253 msg = buffer_init();
2254 if (msg == NULL) {
2255 // TODO: error check
2256 return;
2257 }
2258 buffer_put_int(msg, c->remote_id);
2259
2260 len = buffer_len(msg);
2261 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2262 memcpy(outmsg, buffer_ptr(msg), len);
2263 finish_send_packet(pvar);
2264 buffer_free(msg);
2265
2266 }
2267
2268 }
2269
2270 void SSH_notify_host_OK(PTInstVar pvar)
2271 {
2272 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2273 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2274 send_session_key(pvar);
2275 }
2276 }
2277
2278 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2279 {
2280 pvar->ssh_state.win_cols = cols;
2281 pvar->ssh_state.win_rows = rows;
2282
2283 if (SSHv1(pvar)) {
2284 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2285 unsigned char FAR *outmsg =
2286 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2287
2288 set_uint32(outmsg, rows);
2289 set_uint32(outmsg + 4, cols);
2290 set_uint32(outmsg + 8, 0);
2291 set_uint32(outmsg + 12, 0);
2292 finish_send_packet(pvar);
2293 }
2294
2295 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2296 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2297 buffer_t *msg;
2298 char *s;
2299 unsigned char *outmsg;
2300 int len;
2301 Channel_t *c;
2302
2303 c = ssh2_channel_lookup(pvar->shell_id);
2304 if (c == NULL)
2305 return;
2306
2307 msg = buffer_init();
2308 if (msg == NULL) {
2309 // TODO: error check
2310 return;
2311 }
2312 buffer_put_int(msg, c->remote_id);
2313 s = "window-change";
2314 buffer_put_string(msg, s, strlen(s));
2315 buffer_put_char(msg, 0); // wantconfirm
2316 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2317 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2318 buffer_put_int(msg, 480); // XXX:
2319 buffer_put_int(msg, 640); // XXX:
2320 len = buffer_len(msg);
2321 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2322 memcpy(outmsg, buffer_ptr(msg), len);
2323 finish_send_packet(pvar);
2324 buffer_free(msg);
2325
2326 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2327
2328 } else {
2329 // SSH�����������������������B
2330
2331 }
2332
2333 }
2334
2335 int SSH_get_min_packet_size(PTInstVar pvar)
2336 {
2337 if (SSHv1(pvar)) {
2338 return 12;
2339 } else {
2340 int block_size = CRYPT_get_decryption_block_size(pvar);
2341
2342 return max(16, block_size);
2343 }
2344 }
2345
2346 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2347 at least 5 bytes must be decrypted */
2348 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2349 {
2350 if (SSHv2(pvar)) {
2351 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2352 }
2353 }
2354
2355 int SSH_get_clear_MAC_size(PTInstVar pvar)
2356 {
2357 if (SSHv1(pvar)) {
2358 return 0;
2359 } else {
2360 return CRYPT_get_receiver_MAC_size(pvar);
2361 }
2362 }
2363
2364 void SSH_notify_user_name(PTInstVar pvar)
2365 {
2366 try_send_user_name(pvar);
2367 }
2368
2369 void SSH_notify_cred(PTInstVar pvar)
2370 {
2371 try_send_credentials(pvar);
2372 }
2373
2374 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
2375 {
2376 if (SSHv1(pvar)) {
2377 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2378 return;
2379 }
2380
2381 while (buflen > 0) {
2382 int len =
2383 buflen >
2384 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2385 unsigned char FAR *outmsg =
2386 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2387
2388 set_uint32(outmsg, len);
2389
2390 if (pvar->ssh_state.compressing) {
2391 buf_ensure_size(&pvar->ssh_state.outbuf,
2392 &pvar->ssh_state.outbuflen,
2393 len + (len >> 6) + 50);
2394 pvar->ssh_state.compress_stream.next_in =
2395 pvar->ssh_state.precompress_outbuf;
2396 pvar->ssh_state.compress_stream.avail_in = 5;
2397 pvar->ssh_state.compress_stream.next_out =
2398 pvar->ssh_state.outbuf + 12;
2399 pvar->ssh_state.compress_stream.avail_out =
2400 pvar->ssh_state.outbuflen - 12;
2401
2402 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) !=
2403 Z_OK) {
2404 notify_fatal_error(pvar, "Error compressing packet data");
2405 return;
2406 }
2407
2408 pvar->ssh_state.compress_stream.next_in =
2409 (unsigned char FAR *) buf;
2410 pvar->ssh_state.compress_stream.avail_in = len;
2411
2412 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2413 Z_OK) {
2414 notify_fatal_error(pvar, "Error compressing packet data");
2415 return;
2416 }
2417 } else {
2418 memcpy(outmsg + 4, buf, len);
2419 }
2420
2421 finish_send_packet_special(pvar, 1);
2422
2423 buflen -= len;
2424 buf += len;
2425 }
2426
2427 } else { // for SSH2(yutaka)
2428 buffer_t *msg;
2429 unsigned char *outmsg;
2430 int len;
2431 Channel_t *c;
2432
2433 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2434 if (pvar->rekeying) {
2435 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2436 // �������������������B
2437 c = NULL;
2438
2439 return;
2440 }
2441
2442 c = ssh2_channel_lookup(pvar->shell_id);
2443 if (c == NULL)
2444 return;
2445
2446 msg = buffer_init();
2447 if (msg == NULL) {
2448 // TODO: error check
2449 return;
2450 }
2451 buffer_put_int(msg, c->remote_id);
2452 buffer_put_string(msg, (char *)buf, buflen);
2453
2454 len = buffer_len(msg);
2455 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2456 memcpy(outmsg, buffer_ptr(msg), len);
2457 finish_send_packet(pvar);
2458 buffer_free(msg);
2459
2460 // remote window size������
2461 c->remote_window -= len;
2462
2463 }
2464
2465 }
2466
2467 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2468 {
2469 int num_bytes = pvar->ssh_state.payload_datalen;
2470
2471 if (num_bytes > len) {
2472 num_bytes = len;
2473 }
2474
2475 if (!pvar->ssh_state.decompressing) {
2476 memcpy(dest,
2477 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2478 num_bytes);
2479 pvar->ssh_state.payload_datastart += num_bytes;
2480 } else if (num_bytes > 0) {
2481 pvar->ssh_state.decompress_stream.next_out = dest;
2482 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2483
2484 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) !=
2485 Z_OK) {
2486 notify_fatal_error(pvar,
2487 "Invalid compressed data in received packet");
2488 return 0;
2489 }
2490 }
2491
2492 pvar->ssh_state.payload_datalen -= num_bytes;
2493
2494 return num_bytes;
2495 }
2496
2497 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2498 {
2499 char buf[1024];
2500 char buf2[1024];
2501
2502 // added support of SSH2 packet compression (2005.7.10 yutaka)
2503 // support of "Compression delayed" (2006.6.23 maya)
2504 if (pvar->ssh_state.compressing ||
2505 pvar->ctos_compression == COMP_ZLIB ||
2506 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2507 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2508 unsigned long total_out =
2509 pvar->ssh_state.compress_stream.total_out;
2510
2511 if (total_out > 0) {
2512 _snprintf(buf, sizeof(buf), "level %d; ratio %.1f (%ld:%ld)",
2513 pvar->ssh_state.compression_level,
2514 ((double) total_in) / total_out, total_in,
2515 total_out);
2516 } else {
2517 _snprintf(buf, sizeof(buf), "level %d",
2518 pvar->ssh_state.compression_level);
2519 }
2520 } else {
2521 strcpy(buf, "none");
2522 }
2523 buf[sizeof(buf) - 1] = 0;
2524
2525 // support of "Compression delayed" (2006.6.23 maya)
2526 if (pvar->ssh_state.decompressing ||
2527 pvar->stoc_compression == COMP_ZLIB ||
2528 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2529 unsigned long total_in =
2530 pvar->ssh_state.decompress_stream.total_in;
2531 unsigned long total_out =
2532 pvar->ssh_state.decompress_stream.total_out;
2533
2534 if (total_in > 0) {
2535 _snprintf(buf2, sizeof(buf2), "level %d; ratio %.1f (%ld:%ld)",
2536 pvar->ssh_state.compression_level,
2537 ((double) total_out) / total_in, total_out,
2538 total_in);
2539 } else {
2540 _snprintf(buf2, sizeof(buf2), "level %d",
2541 pvar->ssh_state.compression_level);
2542 }
2543 } else {
2544 strcpy(buf2, "none");
2545 }
2546 buf2[sizeof(buf2) - 1] = 0;
2547
2548 _snprintf(dest, len, "Upstream %s; Downstream %s", buf, buf2);
2549 dest[len - 1] = 0;
2550 }
2551
2552 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2553 {
2554 strncpy(dest, pvar->ssh_state.server_ID == NULL ? "Unknown"
2555 : pvar->ssh_state.server_ID, len);
2556 dest[len - 1] = 0;
2557 }
2558
2559 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2560 int len)
2561 {
2562 if (pvar->protocol_major == 0) {
2563 strncpy(dest, "Unknown", len);
2564 } else {
2565 _snprintf(dest, len, "%d.%d", pvar->protocol_major,
2566 pvar->protocol_minor);
2567 }
2568 dest[len - 1] = 0;
2569 }
2570
2571 void SSH_end(PTInstVar pvar)
2572 {
2573 int i;
2574
2575 for (i = 0; i < 256; i++) {
2576 SSHPacketHandlerItem FAR *first_item =
2577 pvar->ssh_state.packet_handlers[i];
2578
2579 if (first_item != NULL) {
2580 SSHPacketHandlerItem FAR *item = first_item;
2581
2582 do {
2583 SSHPacketHandlerItem FAR *cur_item = item;
2584
2585 item = item->next_for_message;
2586 free(cur_item);
2587 } while (item != first_item);
2588 }
2589 pvar->ssh_state.packet_handlers[i] = NULL;
2590 }
2591
2592 free(pvar->ssh_state.hostname);
2593 pvar->ssh_state.hostname = NULL;
2594 free(pvar->ssh_state.server_ID);
2595 pvar->ssh_state.server_ID = NULL;
2596 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2597 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2598 &pvar->ssh_state.precompress_outbuflen);
2599 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2600 &pvar->ssh_state.postdecompress_inbuflen);
2601
2602 // support of "Compression delayed" (2006.6.23 maya)
2603 if (pvar->ssh_state.compressing ||
2604 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2605 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2606 deflateEnd(&pvar->ssh_state.compress_stream);
2607 pvar->ssh_state.compressing = FALSE;
2608 }
2609 // support of "Compression delayed" (2006.6.23 maya)
2610 if (pvar->ssh_state.decompressing ||
2611 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2612 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2613 inflateEnd(&pvar->ssh_state.decompress_stream);
2614 pvar->ssh_state.decompressing = FALSE;
2615 }
2616
2617 #if 1
2618 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2619 if (SSHv2(pvar)) {
2620 if (pvar->kexdh) {
2621 DH_free(pvar->kexdh);
2622 pvar->kexdh = NULL;
2623 }
2624 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2625 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2626
2627 if (pvar->my_kex != NULL) {
2628 buffer_free(pvar->my_kex);
2629 pvar->my_kex = NULL;
2630 }
2631 if (pvar->peer_kex != NULL) {
2632 buffer_free(pvar->peer_kex);
2633 pvar->peer_kex = NULL;
2634 }
2635
2636 pvar->we_need = 0;
2637 pvar->key_done = 0;
2638 pvar->rekeying = 0;
2639
2640 if (pvar->session_id != NULL) {
2641 free(pvar->session_id);
2642 pvar->session_id = NULL;
2643 }
2644 pvar->session_id_len = 0;
2645
2646 pvar->userauth_success = 0;
2647 //pvar->remote_id = 0;
2648 pvar->shell_id = 0;
2649 pvar->session_nego_status = 0;
2650
2651 pvar->ssh_heartbeat_tick = 0;
2652
2653 if (pvar->decomp_buffer != NULL) {
2654 buffer_free(pvar->decomp_buffer);
2655 pvar->decomp_buffer = NULL;
2656 }
2657 }
2658 #endif
2659
2660 }
2661
2662 /* support for port forwarding */
2663 void SSH_channel_send(PTInstVar pvar, int channel_num,
2664 uint32 remote_channel_num,
2665 unsigned char FAR * buf, int len)
2666 {
2667 int buflen = len;
2668
2669 if (SSHv1(pvar)) {
2670 unsigned char FAR *outmsg =
2671 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2672
2673 set_uint32(outmsg, remote_channel_num);
2674 set_uint32(outmsg + 4, len);
2675
2676 if (pvar->ssh_state.compressing) {
2677 buf_ensure_size(&pvar->ssh_state.outbuf,
2678 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2679 pvar->ssh_state.compress_stream.next_in =
2680 pvar->ssh_state.precompress_outbuf;
2681 pvar->ssh_state.compress_stream.avail_in = 9;
2682 pvar->ssh_state.compress_stream.next_out =
2683 pvar->ssh_state.outbuf + 12;
2684 pvar->ssh_state.compress_stream.avail_out =
2685 pvar->ssh_state.outbuflen - 12;
2686
2687 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2688 notify_fatal_error(pvar, "Error compressing packet data");
2689 return;
2690 }
2691
2692 pvar->ssh_state.compress_stream.next_in =
2693 (unsigned char FAR *) buf;
2694 pvar->ssh_state.compress_stream.avail_in = len;
2695
2696 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2697 Z_OK) {
2698 notify_fatal_error(pvar, "Error compressing packet data");
2699 return;
2700 }
2701 } else {
2702 memcpy(outmsg + 8, buf, len);
2703 }
2704
2705 finish_send_packet_special(pvar, 1);
2706
2707 } else {
2708 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
2709 buffer_t *msg;
2710 unsigned char *outmsg;
2711 int len;
2712 Channel_t *c;
2713
2714 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2715 if (pvar->rekeying) {
2716 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2717 // �������������������B
2718 c = NULL;
2719
2720 return;
2721 }
2722
2723 c = ssh2_local_channel_lookup(channel_num);
2724 if (c == NULL)
2725 return;
2726
2727 msg = buffer_init();
2728 if (msg == NULL) {
2729 // TODO: error check
2730 return;
2731 }
2732 buffer_put_int(msg, c->remote_id);
2733 buffer_put_string(msg, (char *)buf, buflen);
2734
2735 len = buffer_len(msg);
2736 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2737 memcpy(outmsg, buffer_ptr(msg), len);
2738 finish_send_packet(pvar);
2739 buffer_free(msg);
2740
2741 // remote window size������
2742 c->remote_window -= len;
2743 }
2744
2745 }
2746
2747 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2748 {
2749 if (SSHv1(pvar)) {
2750 unsigned char FAR *outmsg =
2751 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2752
2753 set_uint32(outmsg, remote_channel_num);
2754 finish_send_packet(pvar);
2755
2756 } else { // SSH2 (2005.6.26 yutaka)
2757 int len;
2758 Channel_t *c = NULL;
2759 buffer_t *msg;
2760 unsigned char *outmsg;
2761
2762 msg = buffer_init();
2763 if (msg == NULL) {
2764 // TODO: error check
2765 return;
2766 }
2767 buffer_put_int(msg, remote_channel_num);
2768 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
2769
2770 len = buffer_len(msg);
2771 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
2772 memcpy(outmsg, buffer_ptr(msg), len);
2773 finish_send_packet(pvar);
2774 buffer_free(msg);
2775
2776 }
2777 }
2778
2779 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2780 uint32 local_channel_num)
2781 {
2782 if (SSHv1(pvar)) {
2783 unsigned char FAR *outmsg =
2784 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2785
2786 set_uint32(outmsg, remote_channel_num);
2787 set_uint32(outmsg + 4, local_channel_num);
2788 finish_send_packet(pvar);
2789
2790 } else {
2791 buffer_t *msg;
2792 unsigned char *outmsg;
2793 int len;
2794 Channel_t *c;
2795
2796 // port-forwarding(remote to local)�����[�J�����������������T�[�o�������B(2005.7.2 yutaka)
2797 c = ssh2_local_channel_lookup(local_channel_num);
2798 if (c == NULL) {
2799 // It is sure to be successful as long as it's not a program bug either.
2800 return;
2801 }
2802
2803 msg = buffer_init();
2804 if (msg == NULL) {
2805 // TODO: error check
2806 return;
2807 }
2808 buffer_put_int(msg, c->remote_id);
2809 buffer_put_int(msg, c->self_id);
2810 buffer_put_int(msg, c->local_window);
2811 buffer_put_int(msg, c->local_maxpacket);
2812
2813 len = buffer_len(msg);
2814 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len);
2815 memcpy(outmsg, buffer_ptr(msg), len);
2816 finish_send_packet(pvar);
2817 buffer_free(msg);
2818
2819 }
2820 }
2821
2822 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2823 {
2824 if (SSHv1(pvar)){
2825 unsigned char FAR *outmsg =
2826 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2827
2828 set_uint32(outmsg, remote_channel_num);
2829 finish_send_packet(pvar);
2830
2831 } else {
2832 // SSH2: ���������B
2833
2834 }
2835 }
2836
2837 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num)
2838 {
2839 if (SSHv1(pvar)){
2840 unsigned char FAR *outmsg =
2841 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2842
2843 set_uint32(outmsg, remote_channel_num);
2844 finish_send_packet(pvar);
2845
2846 } else {
2847 // SSH2: �`���l���N���[�Y���T�[�o�����m
2848 buffer_t *msg;
2849 unsigned char *outmsg;
2850 int len;
2851 Channel_t *c;
2852
2853 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
2854 if (pvar->rekeying) {
2855 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2856 // �������������������B
2857 c = NULL;
2858
2859 return;
2860 }
2861
2862 c = ssh2_local_channel_lookup(local_channel_num);
2863 if (c == NULL)
2864 return;
2865
2866 msg = buffer_init();
2867 if (msg == NULL) {
2868 // TODO: error check
2869 return;
2870 }
2871 buffer_put_int(msg, c->remote_id); // remote ID
2872
2873 len = buffer_len(msg);
2874 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_EOF, len);
2875 memcpy(outmsg, buffer_ptr(msg), len);
2876 finish_send_packet(pvar);
2877 buffer_free(msg);
2878 }
2879
2880 }
2881
2882 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2883 char FAR * to_local_host, int to_local_port)
2884 {
2885 if (SSHv1(pvar)) {
2886 int host_len = strlen(to_local_host);
2887 unsigned char FAR *outmsg =
2888 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2889 12 + host_len);
2890
2891 set_uint32(outmsg, from_server_port);
2892 set_uint32(outmsg + 4, host_len);
2893 memcpy(outmsg + 8, to_local_host, host_len);
2894 set_uint32(outmsg + 8 + host_len, to_local_port);
2895 finish_send_packet(pvar);
2896
2897 enque_forwarding_request_handlers(pvar);
2898
2899 } else {
2900 // SSH2 port-forwading remote to local (2005.6.21 yutaka)
2901 buffer_t *msg;
2902 char *s;
2903 unsigned char *outmsg;
2904 int len;
2905
2906 msg = buffer_init();
2907 if (msg == NULL) {
2908 // TODO: error check
2909 return;
2910 }
2911 s = "tcpip-forward";
2912 buffer_put_string(msg, s, strlen(s)); // ctype
2913 buffer_put_char(msg, 1); // want reply
2914 s = "0.0.0.0";
2915 buffer_put_string(msg, s, strlen(s));
2916
2917 buffer_put_int(msg, from_server_port); // listening port
2918
2919 len = buffer_len(msg);
2920 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
2921 memcpy(outmsg, buffer_ptr(msg), len);
2922 finish_send_packet(pvar);
2923 buffer_free(msg);
2924
2925 }
2926 }
2927
2928 void SSH_request_X11_forwarding(PTInstVar pvar,
2929 char FAR * auth_protocol,
2930 unsigned char FAR * auth_data,
2931 int auth_data_len, int screen_num)
2932 {
2933 if (SSHv1(pvar)) {
2934 int protocol_len = strlen(auth_protocol);
2935 int data_len = auth_data_len * 2;
2936 unsigned char FAR *outmsg =
2937 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING,
2938 12 + protocol_len + data_len);
2939 int i;
2940 char FAR *auth_data_ptr;
2941
2942 set_uint32(outmsg, protocol_len);
2943 memcpy(outmsg + 4, auth_protocol, protocol_len);
2944 set_uint32(outmsg + 4 + protocol_len, data_len);
2945 auth_data_ptr = outmsg + 8 + protocol_len;
2946 for (i = 0; i < auth_data_len; i++) {
2947 sprintf(auth_data_ptr + i * 2, "%.2x", auth_data[i]);
2948 }
2949 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
2950
2951 finish_send_packet(pvar);
2952
2953 enque_forwarding_request_handlers(pvar);
2954
2955 } else {
2956 // SSH2: X11 port-forwarding (2005.7.2 yutaka)
2957 buffer_t *msg;
2958 char *s;
2959 unsigned char *outmsg;
2960 int len;
2961 Channel_t *c;
2962 int newlen;
2963 char *newdata;
2964 int i;
2965
2966 msg = buffer_init();
2967 if (msg == NULL) {
2968 // TODO: error check
2969 return;
2970 }
2971
2972 c = ssh2_channel_lookup(pvar->shell_id);
2973 if (c == NULL)
2974 return;
2975
2976 // making the fake data
2977 newlen = 2 * auth_data_len + 1;
2978 newdata = malloc(newlen);
2979 if (newdata == NULL)
2980 return;
2981 for (i = 0 ; i < auth_data_len ; i++) {
2982 _snprintf(newdata + i*2, newlen - i*2, "%02x", auth_data[i]);
2983 }
2984 newdata[newlen - 1] = '\0';
2985
2986 buffer_put_int(msg, c->remote_id);
2987 s = "x11-req";
2988 buffer_put_string(msg, s, strlen(s)); // service name
2989 buffer_put_char(msg, 0); // want confirm (false)
2990 buffer_put_char(msg, 0); // XXX bool single connection
2991
2992 s = auth_protocol; // MIT-MAGIC-COOKIE-1
2993 buffer_put_string(msg, s, strlen(s));
2994 s = newdata;
2995 buffer_put_string(msg, s, strlen(s));
2996
2997 buffer_put_int(msg, screen_num);
2998
2999 len = buffer_len(msg);
3000 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
3001 memcpy(outmsg, buffer_ptr(msg), len);
3002 finish_send_packet(pvar);
3003 buffer_free(msg);
3004
3005 free(newdata);
3006 }
3007
3008 }
3009
3010 void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
3011 char FAR * to_remote_host, int to_remote_port,
3012 char FAR * originator, unsigned short originator_port)
3013 {
3014 static const int msgs[]
3015 = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
3016 static const SSHPacketHandler handlers[]
3017 = { handle_channel_open_confirmation, handle_channel_open_failure };
3018
3019 int host_len = strlen(to_remote_host);
3020
3021 if ((pvar->ssh_state.
3022 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
3023 int originator_len = strlen(originator);
3024 unsigned char FAR *outmsg =
3025 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
3026 16 + host_len + originator_len);
3027
3028 set_uint32(outmsg, local_channel_num);
3029 set_uint32(outmsg + 4, host_len);
3030 memcpy(outmsg + 8, to_remote_host, host_len);
3031 set_uint32(outmsg + 8 + host_len, to_remote_port);
3032 set_uint32(outmsg + 12 + host_len, originator_len);
3033 memcpy(outmsg + 16 + host_len, originator, originator_len);
3034 } else {
3035
3036 if (SSHv1(pvar)) {
3037 unsigned char FAR *outmsg =
3038 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
3039 12 + host_len);
3040
3041 set_uint32(outmsg, local_channel_num);
3042 set_uint32(outmsg + 4, host_len);
3043 memcpy(outmsg + 8, to_remote_host, host_len);
3044 set_uint32(outmsg + 8 + host_len, to_remote_port);
3045
3046 } else {
3047 // SSH2 port-fowarding (2005.2.26 yutaka)
3048 buffer_t *msg;
3049 char *s;
3050 unsigned char *outmsg;
3051 int len;
3052 Channel_t *c;
3053
3054 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
3055 if (pvar->rekeying) {
3056 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3057 // �������������������B
3058 c = NULL;
3059
3060 return;
3061 }
3062
3063 // changed window size from 128KB to 32KB. (2006.3.6 yutaka)
3064 c = ssh2_channel_new(CHAN_TCP_PACKET_DEFAULT, CHAN_TCP_PACKET_DEFAULT, TYPE_PORTFWD, local_channel_num);
3065
3066 msg = buffer_init();
3067 if (msg == NULL) {
3068 // TODO: error check
3069 return;
3070 }
3071 s = "direct-tcpip";
3072 buffer_put_string(msg, s, strlen(s)); // ctype
3073 buffer_put_int(msg, c->self_id); // self
3074 buffer_put_int(msg, c->local_window); // local_window
3075 buffer_put_int(msg, c->local_maxpacket); // local_maxpacket
3076
3077 s = to_remote_host;
3078 buffer_put_string(msg, s, strlen(s)); // target host
3079 buffer_put_int(msg, to_remote_port); // target port
3080
3081 s = originator;
3082 buffer_put_string(msg, s, strlen(s)); // originator host
3083 buffer_put_int(msg, originator_port); // originator port
3084
3085 len = buffer_len(msg);
3086 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN, len);
3087 memcpy(outmsg, buffer_ptr(msg), len);
3088 finish_send_packet(pvar);
3089 buffer_free(msg);
3090
3091 return;
3092
3093 /* NOT REACHED */
3094 }
3095
3096 }
3097
3098 if (SSHv1(pvar)) { // SSH1����
3099 finish_send_packet(pvar);
3100 enque_handlers(pvar, 2, msgs, handlers);
3101 }
3102
3103 }
3104
3105
3106 /////////////////////////////////////////////////////////////////////////////
3107 //
3108 // SSH2 protocol procedure in the following code:
3109 //
3110 /////////////////////////////////////////////////////////////////////////////
3111
3112 void debug_print(int no, char *msg, int len)
3113 {
3114 #ifdef _DEBUG
3115 FILE *fp;
3116 char file[128];
3117
3118 sprintf(file, "dump%d.bin", no);
3119
3120 fp = fopen(file, "wb");
3121 if (fp == NULL)
3122 return;
3123
3124 fwrite(msg, 1, len, fp);
3125
3126 fclose(fp);
3127 #endif
3128 }
3129
3130 // �N���C�A���g�����T�[�o������������
3131 #ifdef SSH2_DEBUG
3132 static char *myproposal[PROPOSAL_MAX] = {
3133 // "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
3134 "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
3135 "ssh-rsa,ssh-dss",
3136 // "ssh-dss,ssh-rsa",
3137 "3des-cbc,aes128-cbc",
3138 "3des-cbc,aes128-cbc",
3139 "hmac-md5,hmac-sha1",
3140 "hmac-md5,hmac-sha1",
3141 // "hmac-sha1,hmac-md5",
3142 // "hmac-sha1,hmac-md5",
3143 // "hmac-sha1",
3144 // "hmac-sha1",
3145 KEX_DEFAULT_COMP,
3146 KEX_DEFAULT_COMP,
3147 "",
3148 "",
3149 };
3150 #else
3151 static char *myproposal[PROPOSAL_MAX] = {
3152 "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
3153 "ssh-rsa,ssh-dss",
3154 "3des-cbc,aes128-cbc",
3155 "3des-cbc,aes128-cbc",
3156 "hmac-sha1,hmac-md5",
3157 "hmac-sha1,hmac-md5",
3158 KEX_DEFAULT_COMP,
3159 KEX_DEFAULT_COMP,
3160 "",
3161 "",
3162 };
3163 #endif
3164
3165
3166 typedef struct ssh2_cipher {
3167 SSHCipher cipher;
3168 char *name;
3169 int block_size;
3170 int key_len;
3171 const EVP_CIPHER *(*func)(void);
3172 } ssh2_cipher_t;
3173
3174 ssh2_cipher_t ssh2_ciphers[] = {
3175 {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
3176 {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
3177 {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
3178 };
3179
3180
3181 typedef struct ssh2_mac {
3182 char *name;
3183 const EVP_MD *(*func)(void);
3184 int truncatebits;
3185 } ssh2_mac_t;
3186
3187 ssh2_mac_t ssh2_macs[] = {
3188 {"hmac-sha1", EVP_sha1, 0},
3189 {"hmac-md5", EVP_md5, 0},
3190 {NULL, NULL, 0},
3191 };
3192
3193 static Newkeys current_keys[MODE_MAX];
3194
3195
3196 #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
3197
3198
3199 //
3200 // general
3201 //
3202
3203 static int get_cipher_block_size(SSHCipher cipher)
3204 {
3205 ssh2_cipher_t *ptr = ssh2_ciphers;
3206 int val = 0;
3207
3208 while (ptr->name != NULL) {
3209 if (cipher == ptr->cipher) {
3210 val = ptr->block_size;
3211 break;
3212 }
3213 ptr++;
3214 }
3215 return (val);
3216 }
3217
3218 static int get_cipher_key_len(SSHCipher cipher)
3219 {
3220 ssh2_cipher_t *ptr = ssh2_ciphers;
3221 int val = 0;
3222
3223 while (ptr->name != NULL) {
3224 if (cipher == ptr->cipher) {
3225 val = ptr->key_len;
3226 break;
3227 }
3228 ptr++;
3229 }
3230 return (val);
3231 }
3232
3233
3234 #if 0
3235 static int get_mac_index(char *name)
3236 {
3237 ssh2_mac_t *ptr = ssh2_macs;
3238 int val = -1;
3239
3240 while (ptr->name != NULL) {
3241 if (strcmp(ptr->name, name) == 0) {
3242 val = ptr - ssh2_macs;
3243 break;
3244 }
3245 ptr++;
3246 }
3247 return (val);
3248 }
3249 #endif
3250
3251
3252 static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
3253 {
3254 FILE *fp;
3255 char filename[256];
3256
3257 _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
3258
3259 fp = fopen(filename, "wb");
3260 if (fp == NULL)
3261 return;
3262
3263 fwrite(buf, 1, len, fp);
3264
3265 fclose(fp);
3266 }
3267
3268
3269 void SSH2_packet_start(buffer_t *msg, unsigned char type)
3270 {