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 2796 - (show annotations) (download) (as text)
Tue Mar 8 14:24:11 2005 UTC (19 years, 1 month ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 139728 byte(s)
SSH2 log dump機構の追加。
とりあえず、DH_GEXにおけるkey verifyまでにトレース採取を組み込んだ。

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