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 2837 - (show annotations) (download) (as text)
Sat Jul 16 17:01:48 2005 UTC (18 years, 8 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 168851 byte(s)
SSH2接続時に TTY 情報を渡すようにした。

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