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 2834 - (show annotations) (download) (as text)
Sun Jul 10 06:44:48 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 167510 byte(s)
キー再作成時にパケット圧縮が正常に動作せず、サーバ側で正しく解凍できないバグを修正。

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