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 2806 - (show annotations) (download) (as text)
Mon Mar 28 13:52:05 2005 UTC (19 years ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 144181 byte(s)
SSH2_MSG_CHANNEL_REQUEST送信時において、wantconfirmをfalseにした(サーバからのリプライを期待しない)。
NetScreen(HITACHI) workaround対応。

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 The name of Robert O'Callahan may not be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "util.h"
32
33 #include <openssl/bn.h>
34 #include <openssl/evp.h>
35 #include <openssl/dh.h>
36 #include <openssl/engine.h>
37 #include <openssl/rsa.h>
38 #include <openssl/dsa.h>
39 #include <limits.h>
40 #include <malloc.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include <process.h>
44 #include <time.h>
45 #include "buffer.h"
46 #include "ssh.h"
47 #include "crypt.h"
48
49 // SSH2 macro
50 #ifdef _DEBUG
51 #define SSH2_DEBUG
52 #endif
53
54 #define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
55 #define INTBLOB_LEN 20
56 #define SIGBLOB_LEN (2*INTBLOB_LEN)
57
58 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
59
60 static void try_send_credentials(PTInstVar pvar);
61 static void prep_compression(PTInstVar pvar);
62
63 // �����v���g�^�C�v����
64 void SSH2_send_kexinit(PTInstVar pvar);
65 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
66 static void SSH2_dh_kex_init(PTInstVar pvar);
67 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
68 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
69 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
70 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
71 static BOOL handle_SSH2_authrequest(PTInstVar pvar);
72 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
73 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
74 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
75 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
76 static BOOL handle_SSH2_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 // ���������R�s�[������ (2005.3.9 yutaka)
1196 #if 0
1197 // for calculate SSH2 hash
1198 // �T�[�o�o�[�W�����������i���s���������������j
1199 if (ID_len >= sizeof(pvar->server_version_string))
1200 return FALSE;
1201 strncpy(pvar->server_version_string, ID, ID_len);
1202 #endif
1203
1204
1205 if (ID[ID_len - 1] != '\n') {
1206 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1207 return FALSE;
1208 } else
1209 if ((pvar->ssh_state.
1210 status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1211 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1212 return FALSE;
1213 } else if (strncmp(ID, "SSH-", 4) != 0) {
1214 return FALSE;
1215 } else {
1216 ID[ID_len - 1] = 0;
1217
1218 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1219 ID[ID_len - 2] = 0;
1220 }
1221
1222 pvar->ssh_state.server_ID = _strdup(ID);
1223
1224 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1225 notify_fatal_error(pvar,
1226 "This program does not understand the server's version of the protocol.");
1227 } else {
1228 char TTSSH_ID[1024];
1229 int TTSSH_ID_len;
1230 int a, b, c, d;
1231
1232 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1233 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1234
1235 _snprintf(TTSSH_ID, sizeof(TTSSH_ID),
1236 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1237 pvar->protocol_major, pvar->protocol_minor, a, b);
1238 TTSSH_ID_len = strlen(TTSSH_ID);
1239
1240 // for SSH2(yutaka)
1241 // �N���C�A���g�o�[�W�����������i���s���������������j
1242 strncpy(pvar->client_version_string, TTSSH_ID, TTSSH_ID_len);
1243
1244 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1245 _snprintf(pvar->server_version_string, sizeof(pvar->server_version_string), "%s", pvar->ssh_state.server_ID);
1246
1247 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1248 0) != TTSSH_ID_len) {
1249 notify_fatal_error(pvar,
1250 "An error occurred while sending the SSH ID string.\n"
1251 "The connection will close.");
1252 } else {
1253 // ���s�R�[�h������ (2004.8.4 yutaka)
1254 pvar->client_version_string[--TTSSH_ID_len] = 0;
1255
1256 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1257 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1258
1259 // SSH�n���h�����o�^���s��
1260 init_protocol(pvar);
1261
1262 SSH2_dispatch_init(1);
1263 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1264 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1265 }
1266 }
1267
1268 return TRUE;
1269 }
1270 }
1271 }
1272
1273 static BOOL handle_exit(PTInstVar pvar)
1274 {
1275 if (grab_payload(pvar, 4)) {
1276 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1277 finish_send_packet(pvar);
1278 notify_closed_connection(pvar);
1279 }
1280 return TRUE;
1281 }
1282
1283 static BOOL handle_data(PTInstVar pvar)
1284 {
1285 if (grab_payload_limited(pvar, 4)) {
1286 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1287 pvar->ssh_state.payload_datastart = 4;
1288 }
1289 return TRUE;
1290 }
1291
1292 static BOOL handle_channel_open(PTInstVar pvar)
1293 {
1294 int host_len;
1295 int originator_len;
1296
1297 if ((pvar->ssh_state.
1298 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1299 if (grab_payload(pvar, 8)
1300 && grab_payload(pvar,
1301 8 + (host_len = get_payload_uint32(pvar, 4)))
1302 && grab_payload(pvar, originator_len =
1303 get_payload_uint32(pvar, host_len + 12))) {
1304 int local_port = get_payload_uint32(pvar, 8 + host_len);
1305
1306 pvar->ssh_state.payload[8 + host_len] = 0;
1307 FWD_open(pvar, get_payload_uint32(pvar, 0),
1308 pvar->ssh_state.payload + 8, local_port,
1309 pvar->ssh_state.payload + 16 + host_len,
1310 originator_len);
1311 }
1312 } else {
1313 if (grab_payload(pvar, 8)
1314 && grab_payload(pvar,
1315 4 + (host_len =
1316 get_payload_uint32(pvar, 4)))) {
1317 int local_port = get_payload_uint32(pvar, 8 + host_len);
1318
1319 pvar->ssh_state.payload[8 + host_len] = 0;
1320 FWD_open(pvar, get_payload_uint32(pvar, 0),
1321 pvar->ssh_state.payload + 8, local_port, NULL, 0);
1322 }
1323 }
1324
1325 return TRUE;
1326 }
1327
1328 static BOOL handle_X11_channel_open(PTInstVar pvar)
1329 {
1330 int originator_len;
1331
1332 if ((pvar->ssh_state.
1333 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1334 if (grab_payload(pvar, 8)
1335 && grab_payload(pvar, originator_len =
1336 get_payload_uint32(pvar, 4))) {
1337 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1338 pvar->ssh_state.payload + 8, originator_len);
1339 }
1340 } else {
1341 if (grab_payload(pvar, 4)) {
1342 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0);
1343 }
1344 }
1345
1346 return TRUE;
1347 }
1348
1349 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1350 {
1351 if (grab_payload(pvar, 8)) {
1352 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1353 get_payload_uint32(pvar, 4));
1354 }
1355 return FALSE;
1356 }
1357
1358 static BOOL handle_channel_open_failure(PTInstVar pvar)
1359 {
1360 if (grab_payload(pvar, 4)) {
1361 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1362 }
1363 return FALSE;
1364 }
1365
1366 static BOOL handle_channel_data(PTInstVar pvar)
1367 {
1368 int len;
1369
1370 if (grab_payload(pvar, 8)
1371 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1372 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1373 pvar->ssh_state.payload + 8, len);
1374 }
1375 return TRUE;
1376 }
1377
1378 static BOOL handle_channel_input_eof(PTInstVar pvar)
1379 {
1380 if (grab_payload(pvar, 4)) {
1381 FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1382 }
1383 return TRUE;
1384 }
1385
1386 static BOOL handle_channel_output_eof(PTInstVar pvar)
1387 {
1388 if (grab_payload(pvar, 4)) {
1389 FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1390 }
1391 return TRUE;
1392 }
1393
1394
1395
1396 // �n���h�����O�������b�Z�[�W����������
1397
1398 #define HANDLE_MESSAGE_MAX 30
1399 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1400 static int handle_message_count = 0;
1401 static int handle_message_stage = 0;
1402
1403 void SSH2_dispatch_init(int stage)
1404 {
1405 handle_message_count = 0;
1406 handle_message_stage = stage;
1407 }
1408
1409 int SSH2_dispatch_enabled_check(unsigned char message)
1410 {
1411 int i;
1412
1413 for (i = 0 ; i < handle_message_count ; i++) {
1414 if (handle_messages[i] == message)
1415 return 1;
1416 }
1417 return 0;
1418 }
1419
1420 void SSH2_dispatch_add_message(unsigned char message)
1421 {
1422
1423 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1424 // TODO: error check
1425 return;
1426 }
1427
1428 handle_messages[handle_message_count++] = message;
1429 }
1430
1431 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1432 {
1433 unsigned char c;
1434
1435 for (c = begin ; c <= end ; c++) {
1436 SSH2_dispatch_add_message(c);
1437 }
1438 }
1439
1440
1441 /* default window/packet sizes for tcp/x11-fwd-channel */
1442 #define CHAN_SES_PACKET_DEFAULT (32*1024)
1443 #define CHAN_SES_WINDOW_DEFAULT (2*CHAN_SES_PACKET_DEFAULT) // READAMOUNT @ pkt.c����������������
1444
1445 //#define CHAN_TCP_PACKET_DEFAULT (32*1024)
1446 //#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
1447 //#define CHAN_X11_PACKET_DEFAULT (16*1024)
1448 //#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
1449
1450 // �N���C�A���g��window size���T�[�o���m������
1451 static void do_SSH2_adjust_window_size(PTInstVar pvar)
1452 {
1453 const unsigned int window_size = CHAN_SES_PACKET_DEFAULT;
1454 buffer_t *msg;
1455 unsigned char *outmsg;
1456 int len;
1457
1458 // ���[�J����window size�������]�T�����������A�����������B
1459 if (pvar->local_window > window_size)
1460 return;
1461
1462 {
1463 // pty open
1464 msg = buffer_init();
1465 if (msg == NULL) {
1466 // TODO: error check
1467 return;
1468 }
1469 buffer_put_int(msg, pvar->remote_id);
1470 buffer_put_int(msg, window_size - pvar->local_window);
1471
1472 len = buffer_len(msg);
1473 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, len);
1474 memcpy(outmsg, buffer_ptr(msg), len);
1475 finish_send_packet(pvar);
1476 buffer_free(msg);
1477
1478 // �N���C�A���g��window size��������
1479 pvar->local_window = window_size;
1480 }
1481
1482 }
1483
1484
1485 static void SSH2_consume_packet_size(PTInstVar pvar, unsigned char message)
1486 {
1487 int len;
1488 char *data;
1489
1490 if (!(message >= SSH2_MSG_CHANNEL_OPEN_CONFIRMATION && message <= SSH2_MSG_CHANNEL_FAILURE)) {
1491 return;
1492 }
1493
1494 // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
1495 data = pvar->ssh_state.payload;
1496 // �p�P�b�g�T�C�Y - (�p�f�B���O�T�C�Y+1)�G�^���p�P�b�g�T�C�Y
1497 len = pvar->ssh_state.payloadlen;
1498
1499 pvar->local_window -= (len + 1);
1500
1501 do_SSH2_adjust_window_size(pvar);
1502
1503 }
1504
1505
1506 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1507 int padding)
1508 {
1509 unsigned char message = prep_packet(pvar, data, len, padding);
1510
1511
1512 #ifdef SSH2_DEBUG
1513 // for SSH2(yutaka)
1514 if (SSHv2(pvar)) {
1515 if (pvar->key_done) {
1516 message = message;
1517 }
1518
1519 if (pvar->userauth_success) {
1520 message = message;
1521 }
1522
1523 if (pvar->rekeying) {
1524 message = message;
1525 }
1526 }
1527 #endif
1528
1529 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1530 if (message != SSH_MSG_NONE) {
1531 // ���b�Z�[�W�^�C�v���������n���h�����N��
1532 SSHPacketHandler handler = get_handler(pvar, message);
1533
1534 // for SSH2(yutaka)
1535 if (SSHv2(pvar)) {
1536 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1537 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1538 char buf[1024];
1539
1540 _snprintf(buf, sizeof(buf),
1541 "Unexpected SSH2 message(%d) on current stage(%d)", message, handle_message_stage);
1542 notify_fatal_error(pvar, buf);
1543 // abort
1544 }
1545 }
1546
1547 if (handler == NULL) {
1548 if (SSHv1(pvar)) {
1549 char buf[1024];
1550
1551 _snprintf(buf, sizeof(buf),
1552 "Unexpected packet type received: %d", message);
1553 buf[sizeof(buf) - 1] = 0;
1554 notify_fatal_error(pvar, buf);
1555 } else {
1556 unsigned char FAR *outmsg =
1557 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1558
1559 set_uint32(outmsg,
1560 pvar->ssh_state.receiver_sequence_number - 1);
1561 finish_send_packet(pvar);
1562 /* XXX need to decompress incoming packet, but how? */
1563 }
1564 } else {
1565 if (!handler(pvar)) {
1566 deque_handlers(pvar, message);
1567 }
1568 }
1569 }
1570 }
1571
1572 static BOOL handle_pty_success(PTInstVar pvar)
1573 {
1574 FWD_enter_interactive_mode(pvar);
1575 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1576 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1577 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1578 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1579 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1580 handle_channel_input_eof);
1581 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1582 handle_channel_output_eof);
1583 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1584 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1585 return FALSE;
1586 }
1587
1588 static BOOL handle_pty_failure(PTInstVar pvar)
1589 {
1590 notify_nonfatal_error(pvar,
1591 "The server cannot allocate a pseudo-terminal. "
1592 "You may encounter some problems with the terminal.");
1593 return handle_pty_success(pvar);
1594 }
1595
1596 static void prep_pty(PTInstVar pvar)
1597 {
1598 int len = strlen(pvar->ts->TermType);
1599 unsigned char FAR *outmsg =
1600 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1601 4 + len + 16 + sizeof(ssh_ttymodes));
1602 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1603 static const SSHPacketHandler handlers[]
1604 = { handle_pty_success, handle_pty_failure };
1605
1606 set_uint32(outmsg, len);
1607 memcpy(outmsg + 4, pvar->ts->TermType, len);
1608 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
1609 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
1610 set_uint32(outmsg + 4 + len + 8, 0);
1611 set_uint32(outmsg + 4 + len + 12, 0);
1612 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
1613 finish_send_packet(pvar);
1614
1615 enque_handlers(pvar, 2, msgs, handlers);
1616
1617 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
1618 finish_send_packet(pvar);
1619 }
1620
1621 static void prep_forwarding(PTInstVar pvar)
1622 {
1623 FWD_prep_forwarding(pvar);
1624 prep_pty(pvar);
1625 }
1626
1627 static void enable_compression(PTInstVar pvar)
1628 {
1629 pvar->ssh_state.compress_stream.zalloc = NULL;
1630 pvar->ssh_state.compress_stream.zfree = NULL;
1631 pvar->ssh_state.compress_stream.opaque = NULL;
1632 if (deflateInit
1633 (&pvar->ssh_state.compress_stream,
1634 pvar->ssh_state.compression_level) != Z_OK) {
1635 notify_fatal_error(pvar,
1636 "An error occurred while setting up compression.\n"
1637 "The connection will close.");
1638 return;
1639 } else {
1640 pvar->ssh_state.compressing = TRUE;
1641 }
1642
1643 pvar->ssh_state.decompress_stream.zalloc = NULL;
1644 pvar->ssh_state.decompress_stream.zfree = NULL;
1645 pvar->ssh_state.decompress_stream.opaque = NULL;
1646 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
1647 deflateEnd(&pvar->ssh_state.compress_stream);
1648 notify_fatal_error(pvar,
1649 "An error occurred while setting up compression.\n"
1650 "The connection will close.");
1651 return;
1652 } else {
1653 pvar->ssh_state.decompressing = TRUE;
1654 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
1655 &pvar->ssh_state.postdecompress_inbuflen, 1000);
1656 }
1657 }
1658
1659 static BOOL handle_enable_compression(PTInstVar pvar)
1660 {
1661 enable_compression(pvar);
1662 prep_forwarding(pvar);
1663 return FALSE;
1664 }
1665
1666 static BOOL handle_disable_compression(PTInstVar pvar)
1667 {
1668 prep_forwarding(pvar);
1669 return FALSE;
1670 }
1671
1672 static void prep_compression(PTInstVar pvar)
1673 {
1674 if (pvar->session_settings.CompressionLevel > 0) {
1675 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1676 static const SSHPacketHandler handlers[]
1677 = { handle_enable_compression, handle_disable_compression };
1678
1679 unsigned char FAR *outmsg =
1680 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
1681
1682 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
1683 finish_send_packet(pvar);
1684
1685 pvar->ssh_state.compression_level =
1686 pvar->session_settings.CompressionLevel;
1687
1688 enque_handlers(pvar, 2, msgs, handlers);
1689 } else {
1690 prep_forwarding(pvar);
1691 }
1692 }
1693
1694 static void enque_simple_auth_handlers(PTInstVar pvar)
1695 {
1696 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1697 static const SSHPacketHandler handlers[]
1698 = { handle_auth_success, handle_auth_failure };
1699
1700 enque_handlers(pvar, 2, msgs, handlers);
1701 }
1702
1703 static BOOL handle_rsa_challenge(PTInstVar pvar)
1704 {
1705 int challenge_bytes;
1706
1707 if (!grab_payload(pvar, 2)) {
1708 return FALSE;
1709 }
1710
1711 challenge_bytes = get_mpint_len(pvar, 0);
1712
1713 if (grab_payload(pvar, challenge_bytes)) {
1714 unsigned char FAR *outmsg =
1715 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
1716
1717 if (CRYPT_generate_RSA_challenge_response
1718 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
1719 AUTH_destroy_cur_cred(pvar);
1720 finish_send_packet(pvar);
1721
1722 enque_simple_auth_handlers(pvar);
1723 } else {
1724 notify_fatal_error(pvar,
1725 "An error occurred while decrypting the RSA challenge.\n"
1726 "Perhaps the key file is corrupted.");
1727 }
1728 }
1729
1730 return FALSE;
1731 }
1732
1733 #define OBFUSCATING_ROUND_TO 32
1734
1735 static int obfuscating_round_up(PTInstVar pvar, int size)
1736 {
1737 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
1738 }
1739
1740 static void try_send_credentials(PTInstVar pvar)
1741 {
1742 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
1743 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
1744 static const int RSA_msgs[] =
1745 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
1746 static const SSHPacketHandler RSA_handlers[]
1747 = { handle_rsa_challenge, handle_rsa_auth_refused };
1748 static const int TIS_msgs[] =
1749 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
1750 static const SSHPacketHandler TIS_handlers[]
1751 = { handle_TIS_challenge, handle_auth_failure };
1752
1753 // SSH2���������������������X�L�b�v
1754 if (SSHv2(pvar))
1755 goto skip_ssh2;
1756
1757 switch (cred->method) {
1758 case SSH_AUTH_NONE:
1759 return;
1760 case SSH_AUTH_PASSWORD:{
1761 int len = strlen(cred->password);
1762 // Round up password length to discourage traffic analysis
1763 int obfuscated_len = obfuscating_round_up(pvar, len);
1764 unsigned char FAR *outmsg =
1765 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
1766 4 + obfuscated_len);
1767
1768 notify_verbose_message(pvar,
1769 "Trying PASSWORD authentication...",
1770 LOG_LEVEL_VERBOSE);
1771
1772 set_uint32(outmsg, obfuscated_len);
1773 memcpy(outmsg + 4, cred->password, len);
1774 memset(outmsg + 4 + len, 0, obfuscated_len - len);
1775 AUTH_destroy_cur_cred(pvar);
1776 enque_simple_auth_handlers(pvar);
1777 break;
1778 }
1779 case SSH_AUTH_RHOSTS:{
1780 int len = strlen(cred->rhosts_client_user);
1781 unsigned char FAR *outmsg =
1782 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
1783
1784 notify_verbose_message(pvar,
1785 "Trying RHOSTS authentication...",
1786 LOG_LEVEL_VERBOSE);
1787
1788 set_uint32(outmsg, len);
1789 memcpy(outmsg + 4, cred->rhosts_client_user, len);
1790 AUTH_destroy_cur_cred(pvar);
1791 enque_simple_auth_handlers(pvar);
1792 break;
1793 }
1794 case SSH_AUTH_RSA:{
1795 int len = BN_num_bytes(cred->key_pair->RSA_key->n);
1796 unsigned char FAR *outmsg =
1797 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
1798
1799 notify_verbose_message(pvar,
1800 "Trying RSA authentication...",
1801 LOG_LEVEL_VERBOSE);
1802
1803 set_ushort16_MSBfirst(outmsg, len * 8);
1804 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
1805 /* don't destroy the current credentials yet */
1806 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
1807 break;
1808 }
1809 case SSH_AUTH_RHOSTS_RSA:{
1810 int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
1811 int name_len = strlen(cred->rhosts_client_user);
1812 int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
1813 int index;
1814 unsigned char FAR *outmsg =
1815 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
1816 12 + mod_len + name_len + exp_len);
1817
1818 notify_verbose_message(pvar,
1819 "Trying RHOSTS+RSA authentication...",
1820 LOG_LEVEL_VERBOSE);
1821
1822 set_uint32(outmsg, name_len);
1823 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
1824 index = 4 + name_len;
1825
1826 set_uint32(outmsg + index, 8 * mod_len);
1827 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
1828 BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
1829 index += 6 + exp_len;
1830
1831 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
1832 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
1833 /* don't destroy the current credentials yet */
1834 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
1835 break;
1836 }
1837 case SSH_AUTH_TIS:{
1838 if (cred->password == NULL) {
1839 unsigned char FAR *outmsg =
1840 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
1841
1842 notify_verbose_message(pvar,
1843 "Trying TIS authentication...",
1844 LOG_LEVEL_VERBOSE);
1845 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
1846 } else {
1847 int len = strlen(cred->password);
1848 int obfuscated_len = obfuscating_round_up(pvar, len);
1849 unsigned char FAR *outmsg =
1850 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
1851 4 + obfuscated_len);
1852
1853 notify_verbose_message(pvar, "Sending TIS response",
1854 LOG_LEVEL_VERBOSE);
1855
1856 set_uint32(outmsg, obfuscated_len);
1857 memcpy(outmsg + 4, cred->password, len);
1858 memset(outmsg + 4 + len, 0, obfuscated_len - len);
1859 enque_simple_auth_handlers(pvar);
1860 }
1861
1862 AUTH_destroy_cur_cred(pvar);
1863 break;
1864 }
1865 default:
1866 notify_fatal_error(pvar,
1867 "Internal error: unsupported authentication method");
1868 return;
1869 }
1870
1871 finish_send_packet(pvar);
1872
1873 skip_ssh2:;
1874 destroy_packet_buf(pvar);
1875
1876 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
1877 }
1878 }
1879
1880 static void try_send_user_name(PTInstVar pvar)
1881 {
1882 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
1883 char FAR *username = AUTH_get_user_name(pvar);
1884
1885 if (username != NULL) {
1886 int len = strlen(username);
1887 int obfuscated_len = obfuscating_round_up(pvar, len);
1888 unsigned char FAR *outmsg =
1889 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
1890 char buf[1024] = "Sending user name: ";
1891 static const int msgs[] =
1892 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1893 static const SSHPacketHandler handlers[]
1894 = { handle_noauth_success, handle_auth_required };
1895
1896 set_uint32(outmsg, obfuscated_len);
1897 memcpy(outmsg + 4, username, len);
1898 memset(outmsg + 4 + len, 0, obfuscated_len - len);
1899 finish_send_packet(pvar);
1900
1901 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
1902
1903 strncpy(buf + strlen(buf), username,
1904 sizeof(buf) - strlen(buf) - 2);
1905 buf[sizeof(buf) - 1] = 0;
1906 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1907
1908 enque_handlers(pvar, 2, msgs, handlers);
1909 }
1910 }
1911 }
1912
1913 static void send_session_key(PTInstVar pvar)
1914 {
1915 int encrypted_session_key_len;
1916 unsigned char FAR *outmsg;
1917
1918 if (SSHv1(pvar)) {
1919 encrypted_session_key_len =
1920 CRYPT_get_encrypted_session_key_len(pvar);
1921 }
1922
1923 if (!CRYPT_choose_ciphers(pvar))
1924 return;
1925
1926 if (SSHv1(pvar)) {
1927 outmsg =
1928 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
1929 15 + encrypted_session_key_len);
1930 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
1931 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
1932 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
1933 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
1934 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
1935 return;
1936 set_uint32(outmsg + 11 + encrypted_session_key_len,
1937 SSH_PROTOFLAG_SCREEN_NUMBER |
1938 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
1939 finish_send_packet(pvar);
1940 }
1941
1942 if (!CRYPT_start_encryption(pvar, 1, 1))
1943 return;
1944 notify_established_secure_connection(pvar);
1945
1946 if (SSHv1(pvar)) {
1947 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
1948 }
1949
1950 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
1951
1952 if (SSHv1(pvar)) {
1953 try_send_user_name(pvar);
1954 }
1955 }
1956
1957 /*************************
1958 END of message handlers
1959 ************************/
1960
1961 void SSH_init(PTInstVar pvar)
1962 {
1963 int i;
1964
1965 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
1966 buf_create(&pvar->ssh_state.precompress_outbuf,
1967 &pvar->ssh_state.precompress_outbuflen);
1968 buf_create(&pvar->ssh_state.postdecompress_inbuf,
1969 &pvar->ssh_state.postdecompress_inbuflen);
1970 pvar->ssh_state.payload = NULL;
1971 pvar->ssh_state.compressing = FALSE;
1972 pvar->ssh_state.decompressing = FALSE;
1973 pvar->ssh_state.status_flags =
1974 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
1975 pvar->ssh_state.payload_datalen = 0;
1976 pvar->ssh_state.hostname = NULL;
1977 pvar->ssh_state.server_ID = NULL;
1978 pvar->ssh_state.receiver_sequence_number = 0;
1979 pvar->ssh_state.sender_sequence_number = 0;
1980 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
1981 pvar->ssh_state.packet_handlers[i] = NULL;
1982 }
1983
1984 // for SSH2(yutaka)
1985 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
1986 pvar->userauth_success = 0;
1987 pvar->session_nego_status = 0;
1988 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
1989 pvar->rekeying = 0;
1990 pvar->key_done = 0;
1991 pvar->ssh2_autologin = 0; // autologin disabled(default)
1992 pvar->userauth_retry_count = 0;
1993
1994 }
1995
1996 void SSH_open(PTInstVar pvar)
1997 {
1998 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
1999 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2000 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2001 }
2002
2003 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2004 {
2005 if (SSHv1(pvar)) {
2006 int len = reason == NULL ? 0 : strlen(reason);
2007 unsigned char FAR *outmsg =
2008 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2009
2010 set_uint32(outmsg, len);
2011 if (reason != NULL) {
2012 memcpy(outmsg + 4, reason, len);
2013 }
2014 finish_send_packet(pvar);
2015
2016 } else { // for SSH2(yutaka)
2017 buffer_t *msg;
2018 unsigned char *outmsg;
2019 int len;
2020
2021 // SSH2 server��channel close���`����
2022 msg = buffer_init();
2023 if (msg == NULL) {
2024 // TODO: error check
2025 return;
2026 }
2027 buffer_put_int(msg, pvar->remote_id);
2028
2029 len = buffer_len(msg);
2030 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2031 memcpy(outmsg, buffer_ptr(msg), len);
2032 finish_send_packet(pvar);
2033 buffer_free(msg);
2034
2035 }
2036
2037 }
2038
2039 void SSH_notify_host_OK(PTInstVar pvar)
2040 {
2041 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2042 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2043 send_session_key(pvar);
2044 }
2045 }
2046
2047 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2048 {
2049 pvar->ssh_state.win_cols = cols;
2050 pvar->ssh_state.win_rows = rows;
2051
2052 if (SSHv1(pvar)) {
2053 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2054 unsigned char FAR *outmsg =
2055 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2056
2057 set_uint32(outmsg, rows);
2058 set_uint32(outmsg + 4, cols);
2059 set_uint32(outmsg + 8, 0);
2060 set_uint32(outmsg + 12, 0);
2061 finish_send_packet(pvar);
2062 }
2063
2064 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2065 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2066 buffer_t *msg;
2067 char *s;
2068 unsigned char *outmsg;
2069 int len;
2070
2071 msg = buffer_init();
2072 if (msg == NULL) {
2073 // TODO: error check
2074 return;
2075 }
2076 buffer_put_int(msg, pvar->remote_id);
2077 s = "window-change";
2078 buffer_put_string(msg, s, strlen(s));
2079 buffer_put_char(msg, 0); // wantconfirm
2080 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2081 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2082 buffer_put_int(msg, 480); // XXX:
2083 buffer_put_int(msg, 640); // XXX:
2084 len = buffer_len(msg);
2085 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2086 memcpy(outmsg, buffer_ptr(msg), len);
2087 finish_send_packet(pvar);
2088 buffer_free(msg);
2089
2090 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2091
2092 } else {
2093 // SSH�����������������������B
2094
2095 }
2096
2097 }
2098
2099 int SSH_get_min_packet_size(PTInstVar pvar)
2100 {
2101 if (SSHv1(pvar)) {
2102 return 12;
2103 } else {
2104 int block_size = CRYPT_get_decryption_block_size(pvar);
2105
2106 return max(16, block_size);
2107 }
2108 }
2109
2110 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2111 at least 5 bytes must be decrypted */
2112 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2113 {
2114 if (SSHv2(pvar)) {
2115 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2116 }
2117 }
2118
2119 int SSH_get_clear_MAC_size(PTInstVar pvar)
2120 {
2121 if (SSHv1(pvar)) {
2122 return 0;
2123 } else {
2124 return CRYPT_get_receiver_MAC_size(pvar);
2125 }
2126 }
2127
2128 void SSH_notify_user_name(PTInstVar pvar)
2129 {
2130 try_send_user_name(pvar);
2131 }
2132
2133 void SSH_notify_cred(PTInstVar pvar)
2134 {
2135 try_send_credentials(pvar);
2136 }
2137
2138 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
2139 {
2140 if (SSHv1(pvar)) {
2141 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2142 return;
2143 }
2144
2145 while (buflen > 0) {
2146 int len =
2147 buflen >
2148 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2149 unsigned char FAR *outmsg =
2150 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2151
2152 set_uint32(outmsg, len);
2153
2154 if (pvar->ssh_state.compressing) {
2155 buf_ensure_size(&pvar->ssh_state.outbuf,
2156 &pvar->ssh_state.outbuflen,
2157 len + (len >> 6) + 50);
2158 pvar->ssh_state.compress_stream.next_in =
2159 pvar->ssh_state.precompress_outbuf;
2160 pvar->ssh_state.compress_stream.avail_in = 5;
2161 pvar->ssh_state.compress_stream.next_out =
2162 pvar->ssh_state.outbuf + 12;
2163 pvar->ssh_state.compress_stream.avail_out =
2164 pvar->ssh_state.outbuflen - 12;
2165
2166 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) !=
2167 Z_OK) {
2168 notify_fatal_error(pvar, "Error compressing packet data");
2169 return;
2170 }
2171
2172 pvar->ssh_state.compress_stream.next_in =
2173 (unsigned char FAR *) buf;
2174 pvar->ssh_state.compress_stream.avail_in = len;
2175
2176 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2177 Z_OK) {
2178 notify_fatal_error(pvar, "Error compressing packet data");
2179 return;
2180 }
2181 } else {
2182 memcpy(outmsg + 4, buf, len);
2183 }
2184
2185 finish_send_packet_special(pvar, 1);
2186
2187 buflen -= len;
2188 buf += len;
2189 }
2190
2191 } else { // for SSH2(yutaka)
2192 buffer_t *msg;
2193 unsigned char *outmsg;
2194 int len;
2195
2196 msg = buffer_init();
2197 if (msg == NULL) {
2198 // TODO: error check
2199 return;
2200 }
2201 buffer_put_int(msg, pvar->remote_id);
2202 buffer_put_string(msg, (char *)buf, buflen);
2203
2204 len = buffer_len(msg);
2205 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2206 memcpy(outmsg, buffer_ptr(msg), len);
2207 finish_send_packet(pvar);
2208 buffer_free(msg);
2209
2210 // remote window size������
2211 pvar->remote_window -= len;
2212
2213 }
2214
2215 }
2216
2217 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2218 {
2219 int num_bytes = pvar->ssh_state.payload_datalen;
2220
2221 if (num_bytes > len) {
2222 num_bytes = len;
2223 }
2224
2225 if (!pvar->ssh_state.decompressing) {
2226 memcpy(dest,
2227 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2228 num_bytes);
2229 pvar->ssh_state.payload_datastart += num_bytes;
2230 } else if (num_bytes > 0) {
2231 pvar->ssh_state.decompress_stream.next_out = dest;
2232 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2233
2234 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) !=
2235 Z_OK) {
2236 notify_fatal_error(pvar,
2237 "Invalid compressed data in received packet");
2238 return 0;
2239 }
2240 }
2241
2242 pvar->ssh_state.payload_datalen -= num_bytes;
2243
2244 return num_bytes;
2245 }
2246
2247 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2248 {
2249 char buf[1024];
2250 char buf2[1024];
2251
2252 if (pvar->ssh_state.compressing) {
2253 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2254 unsigned long total_out =
2255 pvar->ssh_state.compress_stream.total_out;
2256
2257 if (total_out > 0) {
2258 _snprintf(buf, sizeof(buf), "level %d; ratio %.1f (%ld:%ld)",
2259 pvar->ssh_state.compression_level,
2260 ((double) total_in) / total_out, total_in,
2261 total_out);
2262 } else {
2263 _snprintf(buf, sizeof(buf), "level %d",
2264 pvar->ssh_state.compression_level);
2265 }
2266 } else {
2267 strcpy(buf, "none");
2268 }
2269 buf[sizeof(buf) - 1] = 0;
2270
2271 if (pvar->ssh_state.decompressing) {
2272 unsigned long total_in =
2273 pvar->ssh_state.decompress_stream.total_in;
2274 unsigned long total_out =
2275 pvar->ssh_state.decompress_stream.total_out;
2276
2277 if (total_in > 0) {
2278 _snprintf(buf2, sizeof(buf2), "level %d; ratio %.1f (%ld:%ld)",
2279 pvar->ssh_state.compression_level,
2280 ((double) total_out) / total_in, total_out,
2281 total_in);
2282 } else {
2283 _snprintf(buf2, sizeof(buf2), "level %d",
2284 pvar->ssh_state.compression_level);
2285 }
2286 } else {
2287 strcpy(buf2, "none");
2288 }
2289 buf2[sizeof(buf2) - 1] = 0;
2290
2291 _snprintf(dest, len, "Upstream %s; Downstream %s", buf, buf2);
2292 dest[len - 1] = 0;
2293 }
2294
2295 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2296 {
2297 strncpy(dest, pvar->ssh_state.server_ID == NULL ? "Unknown"
2298 : pvar->ssh_state.server_ID, len);
2299 dest[len - 1] = 0;
2300 }
2301
2302 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2303 int len)
2304 {
2305 if (pvar->protocol_major == 0) {
2306 strncpy(dest, "Unknown", len);
2307 } else {
2308 _snprintf(dest, len, "%d.%d", pvar->protocol_major,
2309 pvar->protocol_minor);
2310 }
2311 dest[len - 1] = 0;
2312 }
2313
2314 void SSH_end(PTInstVar pvar)
2315 {
2316 int i;
2317
2318 for (i = 0; i < 256; i++) {
2319 SSHPacketHandlerItem FAR *first_item =
2320 pvar->ssh_state.packet_handlers[i];
2321
2322 if (first_item != NULL) {
2323 SSHPacketHandlerItem FAR *item = first_item;
2324
2325 do {
2326 SSHPacketHandlerItem FAR *cur_item = item;
2327
2328 item = item->next_for_message;
2329 free(cur_item);
2330 } while (item != first_item);
2331 }
2332 pvar->ssh_state.packet_handlers[i] = NULL;
2333 }
2334
2335 free(pvar->ssh_state.hostname);
2336 pvar->ssh_state.hostname = NULL;
2337 free(pvar->ssh_state.server_ID);
2338 pvar->ssh_state.server_ID = NULL;
2339 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2340 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2341 &pvar->ssh_state.precompress_outbuflen);
2342 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2343 &pvar->ssh_state.postdecompress_inbuflen);
2344
2345 if (pvar->ssh_state.compressing) {
2346 deflateEnd(&pvar->ssh_state.compress_stream);
2347 pvar->ssh_state.compressing = FALSE;
2348 }
2349 if (pvar->ssh_state.decompressing) {
2350 inflateEnd(&pvar->ssh_state.decompress_stream);
2351 pvar->ssh_state.decompressing = FALSE;
2352 }
2353
2354 #if 1
2355 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2356 if (SSHv2(pvar)) {
2357 if (pvar->kexdh) {
2358 DH_free(pvar->kexdh);
2359 pvar->kexdh = NULL;
2360 }
2361 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2362 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2363
2364 if (pvar->my_kex != NULL) {
2365 buffer_free(pvar->my_kex);
2366 pvar->my_kex = NULL;
2367 }
2368 if (pvar->peer_kex != NULL) {
2369 buffer_free(pvar->peer_kex);
2370 pvar->peer_kex = NULL;
2371 }
2372
2373 pvar->we_need = 0;
2374 pvar->key_done = 0;
2375 pvar->rekeying = 0;
2376
2377 if (pvar->session_id != NULL) {
2378 free(pvar->session_id);
2379 pvar->session_id = NULL;
2380 }
2381 pvar->session_id_len = 0;
2382
2383 pvar->userauth_success = 0;
2384 pvar->remote_id = 0;
2385 pvar->session_nego_status = 0;
2386
2387 pvar->ssh_heartbeat_tick = 0;
2388 }
2389 #endif
2390
2391 }
2392
2393 /* support for port forwarding */
2394 void SSH_channel_send(PTInstVar pvar, uint32 remote_channel_num,
2395 unsigned char FAR * buf, int len)
2396 {
2397 unsigned char FAR *outmsg =
2398 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2399
2400 set_uint32(outmsg, remote_channel_num);
2401 set_uint32(outmsg + 4, len);
2402
2403 if (pvar->ssh_state.compressing) {
2404 buf_ensure_size(&pvar->ssh_state.outbuf,
2405 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2406 pvar->ssh_state.compress_stream.next_in =
2407 pvar->ssh_state.precompress_outbuf;
2408 pvar->ssh_state.compress_stream.avail_in = 9;
2409 pvar->ssh_state.compress_stream.next_out =
2410 pvar->ssh_state.outbuf + 12;
2411 pvar->ssh_state.compress_stream.avail_out =
2412 pvar->ssh_state.outbuflen - 12;
2413
2414 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2415 notify_fatal_error(pvar, "Error compressing packet data");
2416 return;
2417 }
2418
2419 pvar->ssh_state.compress_stream.next_in =
2420 (unsigned char FAR *) buf;
2421 pvar->ssh_state.compress_stream.avail_in = len;
2422
2423 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2424 Z_OK) {
2425 notify_fatal_error(pvar, "Error compressing packet data");
2426 return;
2427 }
2428 } else {
2429 memcpy(outmsg + 8, buf, len);
2430 }
2431
2432 finish_send_packet_special(pvar, 1);
2433 }
2434
2435 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2436 {
2437 unsigned char FAR *outmsg =
2438 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2439
2440 set_uint32(outmsg, remote_channel_num);
2441 finish_send_packet(pvar);
2442 }
2443
2444 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2445 uint32 local_channel_num)
2446 {
2447 unsigned char FAR *outmsg =
2448 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2449
2450 set_uint32(outmsg, remote_channel_num);
2451 set_uint32(outmsg + 4, local_channel_num);
2452 finish_send_packet(pvar);
2453 }
2454
2455 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2456 {
2457 unsigned char FAR *outmsg =
2458 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2459
2460 set_uint32(outmsg, remote_channel_num);
2461 finish_send_packet(pvar);
2462 }
2463
2464 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num)
2465 {
2466 unsigned char FAR *outmsg =
2467 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2468
2469 set_uint32(outmsg, remote_channel_num);
2470 finish_send_packet(pvar);
2471 }
2472
2473 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2474 char FAR * to_local_host, int to_local_port)
2475 {
2476 int host_len = strlen(to_local_host);
2477 unsigned char FAR *outmsg =
2478 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2479 12 + host_len);
2480
2481 set_uint32(outmsg, from_server_port);
2482 set_uint32(outmsg + 4, host_len);
2483 memcpy(outmsg + 8, to_local_host, host_len);
2484 set_uint32(outmsg + 8 + host_len, to_local_port);
2485 finish_send_packet(pvar);
2486
2487 enque_forwarding_request_handlers(pvar);
2488 }
2489
2490 void SSH_request_X11_forwarding(PTInstVar pvar,
2491 char FAR * auth_protocol,
2492 unsigned char FAR * auth_data,
2493 int auth_data_len, int screen_num)
2494 {
2495 int protocol_len = strlen(auth_protocol);
2496 int data_len = auth_data_len * 2;
2497 unsigned char FAR *outmsg =
2498 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING,
2499 12 + protocol_len + data_len);
2500 int i;
2501 char FAR *auth_data_ptr;
2502
2503 set_uint32(outmsg, protocol_len);
2504 memcpy(outmsg + 4, auth_protocol, protocol_len);
2505 set_uint32(outmsg + 4 + protocol_len, data_len);
2506 auth_data_ptr = outmsg + 8 + protocol_len;
2507 for (i = 0; i < auth_data_len; i++) {
2508 sprintf(auth_data_ptr + i * 2, "%.2x", auth_data[i]);
2509 }
2510 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
2511
2512 finish_send_packet(pvar);
2513
2514 enque_forwarding_request_handlers(pvar);
2515 }
2516
2517 void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
2518 char FAR * to_remote_host, int to_remote_port,
2519 char FAR * originator)
2520 {
2521 static const int msgs[]
2522 = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
2523 static const SSHPacketHandler handlers[]
2524 = { handle_channel_open_confirmation, handle_channel_open_failure };
2525
2526 int host_len = strlen(to_remote_host);
2527
2528 if ((pvar->ssh_state.
2529 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
2530 int originator_len = strlen(originator);
2531 unsigned char FAR *outmsg =
2532 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2533 16 + host_len + originator_len);
2534
2535 set_uint32(outmsg, local_channel_num);
2536 set_uint32(outmsg + 4, host_len);
2537 memcpy(outmsg + 8, to_remote_host, host_len);
2538 set_uint32(outmsg + 8 + host_len, to_remote_port);
2539 set_uint32(outmsg + 12 + host_len, originator_len);
2540 memcpy(outmsg + 16 + host_len, originator, originator_len);
2541 } else {
2542 unsigned char FAR *outmsg =
2543 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2544 12 + host_len);
2545
2546 set_uint32(outmsg, local_channel_num);
2547 set_uint32(outmsg + 4, host_len);
2548 memcpy(outmsg + 8, to_remote_host, host_len);
2549 set_uint32(outmsg + 8 + host_len, to_remote_port);
2550 }
2551
2552 finish_send_packet(pvar);
2553
2554 enque_handlers(pvar, 2, msgs, handlers);
2555 }
2556
2557
2558 /////////////////////////////////////////////////////////////////////////////
2559 //
2560 // SSH2 protocol procedure in the following code:
2561 //
2562 /////////////////////////////////////////////////////////////////////////////
2563
2564 void debug_print(int no, char *msg, int len)
2565 {
2566 #ifdef _DEBUG
2567 FILE *fp;
2568 char file[128];
2569
2570 sprintf(file, "dump%d.bin", no);
2571
2572 fp = fopen(file, "wb");
2573 if (fp == NULL)
2574 return;
2575
2576 fwrite(msg, 1, len, fp);
2577
2578 fclose(fp);
2579 #endif
2580 }
2581
2582 // �N���C�A���g�����T�[�o������������
2583 #ifdef SSH2_DEBUG
2584 static char *myproposal[PROPOSAL_MAX] = {
2585 // "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2586 "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2587 // "ssh-rsa,ssh-dss",
2588 "ssh-dss,ssh-rsa",
2589 "3des-cbc,aes128-cbc",
2590 "3des-cbc,aes128-cbc",
2591 "hmac-md5,hmac-sha1",
2592 "hmac-md5,hmac-sha1",
2593 // "hmac-sha1,hmac-md5",
2594 // "hmac-sha1,hmac-md5",
2595 // "hmac-sha1",
2596 // "hmac-sha1",
2597 "none",
2598 "none",
2599 "",
2600 "",
2601 };
2602 #else
2603 static char *myproposal[PROPOSAL_MAX] = {
2604 "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2605 "ssh-rsa,ssh-dss",
2606 "3des-cbc,aes128-cbc",
2607 "3des-cbc,aes128-cbc",
2608 "hmac-sha1,hmac-md5",
2609 "hmac-sha1,hmac-md5",
2610 "none",
2611 "none",
2612 "",
2613 "",
2614 };
2615 #endif
2616
2617
2618 typedef struct ssh2_cipher {
2619 SSHCipher cipher;
2620 char *name;
2621 int block_size;
2622 int key_len;
2623 const EVP_CIPHER *(*func)(void);
2624 } ssh2_cipher_t;
2625
2626 ssh2_cipher_t ssh2_ciphers[] = {
2627 {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
2628 {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
2629 {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
2630 };
2631
2632
2633 typedef struct ssh2_mac {
2634 char *name;
2635 const EVP_MD *(*func)(void);
2636 int truncatebits;
2637 } ssh2_mac_t;
2638
2639 ssh2_mac_t ssh2_macs[] = {
2640 {"hmac-sha1", EVP_sha1, 0},
2641 {"hmac-md5", EVP_md5, 0},
2642 {NULL, NULL, 0},
2643 };
2644
2645 static Newkeys current_keys[MODE_MAX];
2646
2647
2648 #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
2649
2650
2651 static int get_cipher_block_size(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->block_size;
2659 break;
2660 }
2661 ptr++;
2662 }
2663 return (val);
2664 }
2665
2666 static int get_cipher_key_len(SSHCipher cipher)
2667 {
2668 ssh2_cipher_t *ptr = ssh2_ciphers;
2669 int val = 0;
2670
2671 while (ptr->name != NULL) {
2672 if (cipher == ptr->cipher) {
2673 val = ptr->key_len;
2674 break;
2675 }
2676 ptr++;
2677 }
2678 return (val);
2679 }
2680
2681
2682 #if 0
2683 static int get_mac_index(char *name)
2684 {
2685 ssh2_mac_t *ptr = ssh2_macs;
2686 int val = -1;
2687
2688 while (ptr->name != NULL) {
2689 if (strcmp(ptr->name, name) == 0) {
2690 val = ptr - ssh2_macs;
2691 break;
2692 }
2693 ptr++;
2694 }
2695 return (val);
2696 }
2697 #endif
2698
2699
2700 static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
2701 {
2702 FILE *fp;
2703 char filename[256];
2704
2705 _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
2706
2707 fp = fopen(filename, "wb");
2708 if (fp == NULL)
2709 return;
2710
2711 fwrite(buf, 1, len, fp);
2712
2713 fclose(fp);
2714 }
2715
2716
2717 void SSH2_packet_start(buffer_t *msg, unsigned char type)
2718 {
2719 unsigned char buf[9];
2720 int len = 6;
2721
2722 memset(buf, 0, sizeof(buf));
2723 buf[len - 1] = type;
2724 buffer_clear(msg);
2725 buffer_append(msg, buf, len);
2726 }
2727
2728
2729 // the caller is normalize_cipher_order()
2730 void SSH2_update_cipher_myproposal(PTInstVar pvar)
2731 {
2732 static char buf[128]; // TODO: malloc()��������
2733 int cipher;
2734 int len, i;
2735
2736 // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
2737 buf[0] = '\0';
2738 for (i = 0 ; pvar->ts_SSH->CipherOrder[i] != 0 ; i++) {
2739 cipher = pvar->ts_SSH->CipherOrder[i] - '0';
2740 if (cipher == 0) // disabled line
2741 break;
2742 if (cipher == SSH_CIPHER_AES128) {
2743 strcat(buf, "aes128-cbc,");
2744 }
2745 if (cipher == SSH_CIPHER_3DES_CBC) {
2746 strcat(buf, "3des-cbc,");
2747 }
2748 }
2749 if (buf[0] != '\0') {
2750 len = strlen(buf);
2751 buf[len - 1] = '\0'; // get rid of comma
2752 myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
2753 myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
2754 }
2755 }
2756
2757
2758 // �N���C�A���g�����T�[�o�����L�[�����J�n�v��
2759 void SSH2_send_kexinit(PTInstVar pvar)
2760 {
2761 char cookie[SSH2_COOKIE_LENGTH];
2762 buffer_t *msg;
2763 unsigned char *outmsg;
2764 int len, i;
2765
2766 msg = buffer_init();
2767 if (msg == NULL) {
2768 // TODO: error check
2769 return;
2770 }
2771 if (pvar->my_kex != NULL)
2772 buffer_free(pvar->my_kex);
2773 pvar->my_kex = msg;
2774
2775 // ���b�Z�[�W�^�C�v
2776 //SSH2_packet_start(msg, SSH2_MSG_KEXINIT);
2777
2778 // cookie���Z�b�g
2779 CRYPT_set_random_data(pvar, cookie, sizeof(cookie));
2780 CRYPT_set_server_cookie(pvar, cookie);
2781 buffer_append(msg, cookie, sizeof(cookie));
2782
2783 // �N���C�A���g���L�[����
2784 for (i = 0 ; i < PROPOSAL_MAX ; i++) {
2785 buffer_put_string(msg, myproposal[i], strlen(myproposal[i]));
2786 }
2787 buffer_put_char(msg, 0);
2788 buffer_put_int(msg, 0);
2789
2790 len = buffer_len(msg);
2791 outmsg = begin_send_packet(pvar, SSH2_MSG_KEXINIT, len);
2792 memcpy(outmsg, buffer_ptr(msg), len);
2793 finish_send_packet(pvar);
2794
2795 // my_kex�����������������A�t���[���������������B
2796 //buffer_free(msg);
2797
2798 notify_verbose_message(pvar, "SSH2_MSG_KEXINIT was sent", LOG_LEVEL_VERBOSE);
2799 }
2800
2801
2802 static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
2803 {
2804 char tmp[1024], *ptr;
2805 SSHCipher cipher = SSH_CIPHER_NONE;
2806
2807 _snprintf(tmp, sizeof(tmp), my_proposal);
2808 ptr = strtok(tmp, ","); // not thread-safe
2809 while (ptr != NULL) {
2810 // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2811 if (strstr(server_proposal, ptr)) { // match
2812 break;
2813 }
2814 ptr = strtok(NULL, ",");
2815 }
2816 if (strstr(ptr, "3des-cbc")) {
2817 cipher = SSH_CIPHER_3DES_CBC;
2818
2819 } else if (strstr(ptr, "aes128-cbc")) {
2820 cipher = SSH_CIPHER_AES128;
2821 }
2822
2823 return (cipher);
2824 }
2825
2826
2827 static enum hmac_type choose_SSH2_hmac_algorithm(char *server_proposal, char *my_proposal)
2828 {
2829 char tmp[1024], *ptr;
2830 enum hmac_type type = HMAC_UNKNOWN;
2831
2832 _snprintf(tmp, sizeof(tmp), my_proposal);
2833 ptr = strtok(tmp, ","); // not thread-safe
2834 while (ptr != NULL) {
2835 // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2836 if (strstr(server_proposal, ptr)) { // match
2837 break;
2838 }
2839 ptr = strtok(NULL, ",");
2840 }
2841 if (strstr(ptr, "hmac-sha1")) {
2842 type = HMAC_SHA1;
2843 } else if (strstr(ptr, "hmac-md5")) {
2844 type = HMAC_MD5;
2845 }
2846
2847 return (type);
2848 }
2849
2850
2851 // �����A���S���Y�����L�[�T�C�Y�A�u���b�N�T�C�Y�AMAC�T�C�Y�����������l(we_need)�����������B
2852 static void choose_SSH2_key_maxlength(PTInstVar pvar)
2853 {
2854 int mode, need, val, ctos;
2855 const EVP_MD *md;
2856
2857 for (mode = 0; mode < MODE_MAX; mode++) {
2858 if (mode == MODE_OUT)
2859 ctos = 1;
2860 else
2861 ctos = 0;
2862
2863 if (ctos == 1) {
2864 val = pvar->ctos_hmac;
2865 } else {
2866 val = pvar->stoc_hmac;
2867 }
2868
2869 // current_keys[]�����������������A������ pvar->ssh2_keys[] ���R�s�[�����B
2870 md = ssh2_macs[val].func();
2871 current_keys[mode].mac.md = md;
2872 current_keys[mode].mac.key_len = current_keys[mode].mac.mac_len = EVP_MD_size(md);
2873 if (ssh2_macs[val].truncatebits != 0) {
2874 current_keys[mode].mac.mac_len = ssh2_macs[val].truncatebits / 8;
2875 }
2876
2877 // �L�[�T�C�Y���u���b�N�T�C�Y�������������������� (2004.11.7 yutaka)
2878 if (ctos == 1) {
2879 current_keys[mode].enc.key_len = get_cipher_key_len(pvar->ctos_cipher);
2880 current_keys[mode].enc.block_size = get_cipher_block_size(pvar->ctos_cipher);
2881 } else {
2882 current_keys[mode].enc.key_len = get_cipher_key_len(pvar->stoc_cipher);
2883 current_keys[mode].enc.block_size = get_cipher_block_size(pvar->stoc_cipher);
2884 }
2885 current_keys[mode].mac.enabled = 0;
2886
2887 // �����_����MAC��disable
2888 pvar->ssh2_keys[mode].mac.enabled = 0;
2889 }
2890 need = 0;
2891 for (mode = 0; mode < MODE_MAX; mode++) {
2892 if (mode == MODE_OUT)
2893 ctos = 1;
2894 else
2895 ctos = 0;
2896
2897 val = current_keys[mode].enc.key_len;
2898 if (need < val)
2899 need = val;
2900
2901 val = current_keys[mode].enc.block_size;
2902 if (need < val)
2903 need = val;
2904
2905 val = current_keys[mode].mac.key_len;
2906 if (need < val)
2907 need = val;
2908 }
2909 pvar->we_need = need;
2910
2911 }
2912
2913
2914 // �L�[�����J�n�O���`�F�b�N (SSH2_MSG_KEXINIT)
2915 // �����Y�������f�[�^���M���������������������\������
2916 static BOOL handle_SSH2_kexinit(PTInstVar pvar)
2917 {
2918 char buf[1024];
2919 char *data;
2920 int len, i, size;
2921 int offset = 0;
2922 char *msg = NULL;
2923 char tmp[1024+512];
2924 char *ptr;
2925
2926 notify_verbose_message(pvar, "SSH2_MSG_KEXINIT is receiving", LOG_LEVEL_VERBOSE);
2927
2928 // �������L�[�������I�����������������������A�T�[�o���� SSH2_MSG_KEXINIT ��
2929 // �������������������A�L�[���������s���B(2004.10.24 yutaka)
2930 if (pvar->key_done == 1) {
2931 pvar->rekeying = 1;
2932 pvar->key_done = 0;
2933
2934 // �T�[�o��SSH2_MSG_KEXINIT ������
2935 SSH2_send_kexinit(pvar);
2936 }
2937
2938 if (pvar->peer_kex != NULL) { // already allocated
2939 buffer_free(pvar->peer_kex);
2940 }
2941 pvar->peer_kex = buffer_init();
2942 if (pvar->peer_kex == NULL) {
2943 msg = "Out of memory @ handle_SSH2_kexinit()";
2944 goto error;
2945 }
2946 // [-2]:padding size
2947 // len = pvar->ssh_state.payloadlen + pvar->ssh_state.payload[-2] + 1;
2948 len = pvar->ssh_state.payloadlen - 1;
2949 // buffer_append(pvar->peer_kex, &pvar->ssh_state.payload[-6], len);
2950 buffer_append(pvar->peer_kex, pvar->ssh_state.payload, len);
2951 //write_buffer_file(&pvar->ssh_state.payload[-6], len);
2952
2953 // TODO: buffer overrun check
2954
2955 // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
2956 data = pvar->ssh_state.payload;
2957 // �p�P�b�g�T�C�Y - (�p�f�B���O+1)�G�^���p�P�b�g�T�C�Y
2958 len = pvar->ssh_state.payloadlen;
2959
2960 //write_buffer_file(data, len);
2961 push_memdump("KEXINIT", "�A���S���Y�����X�g������", data, len);
2962
2963 if (offset + 20 >= len) {
2964 msg = "payload size too small @ handle_SSH2_kexinit()";
2965 goto error;
2966 }
2967
2968 #if 0
2969 for (i = 0; i < SSH2_COOKIE_LENGTH; i++) {
2970 cookie[i] = data[i];
2971 }
2972 #endif
2973 // get rid of Cookie length
2974 offset += SSH2_COOKIE_LENGTH;
2975
2976 // �L�[�����A���S���Y���`�F�b�N
2977 size = get_payload_uint32(pvar, offset);
2978 offset += 4;
2979 for (i = 0; i < size; i++) {
2980 buf[i] = data[offset + i];
2981 }
2982 buf[i] = '\0'; // null-terminate
2983 offset += size;
2984
2985 // KEX�������B��������myproposal[PROPOSAL_KEX_ALGS]���������������������B
2986 // �T�[�o���A�N���C�A���g���������������� myproposal[PROPOSAL_KEX_ALGS] ���J���}�������������A
2987 // �������������� myproposal[] �����r���s���A�������}�b�`����������KEX�A���S���Y��������
2988 // �I���������B(2004.10.30 yutaka)
2989 pvar->kex_type = -1;
2990 _snprintf(tmp, sizeof(tmp), myproposal[PROPOSAL_KEX_ALGS]);
2991 ptr = strtok(tmp, ","); // not thread-safe
2992 while (ptr != NULL) {
2993 // buf[]�����T�[�o��proposal���J���}���������i�[����������
2994 if (strstr(buf, ptr)) { // match
2995 break;
2996 }
2997 ptr = strtok(NULL, ",");
2998 }
2999 if (ptr == NULL) { // not match
3000 strcpy(tmp, "unknown KEX algorithm: ");
3001 strcat(tmp, buf);
3002 msg = tmp;
3003 goto error;
3004 }
3005 if (strstr(ptr, KEX_DH14)) {
3006 pvar->kex_type = KEX_DH_GRP14_SHA1;
3007 } else if (strstr(ptr, KEX_DH1)) {
3008 pvar->kex_type = KEX_DH_GRP1_SHA1;
3009 } else if (strstr(ptr, KEX_DHGEX)) {
3010 pvar->kex_type = KEX_DH_GEX_SHA1;
3011 }
3012
3013
3014 // �z�X�g�L�[�A���S���Y���`�F�b�N
3015 size = get_payload_uint32(pvar, offset);
3016 offset += 4;
3017 for (i = 0; i < size; i++) {
3018 buf[i] = data[offset + i];
3019 }
3020 buf[i] = 0;
3021 offset += size;
3022 pvar->hostkey_type = -1;
3023 _snprintf(tmp, sizeof(tmp), myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]);
3024 ptr = strtok(tmp, ","); // not thread-safe
3025 while (ptr != NULL) {
3026 // buf[]�����T�[�o��proposal���J���}���������i�[����������
3027 if (strstr(buf, ptr)) { // match
3028 break;
3029 }
3030 ptr = strtok(NULL, ",");
3031 }
3032 if (ptr == NULL) { // not match
3033 strcpy(tmp, "unknown host KEY type: ");
3034 strcat(tmp, buf);
3035 msg = tmp;
3036 goto error;
3037 }
3038 if (strstr(ptr, "ssh-rsa")) {
3039 pvar->hostkey_type = KEY_RSA;
3040 } else if (strstr(ptr, "ssh-dss")) {
3041 pvar->hostkey_type = KEY_DSA;
3042 } else if (strstr(ptr, "rsa1")) {
3043 pvar->hostkey_type = KEY_RSA1;
3044 } else if (strstr(ptr, "rsa")) {
3045 pvar->hostkey_type = KEY_RSA;
3046 } else if (strstr(ptr, "dsa")) {
3047 pvar->hostkey_type = KEY_DSA;
3048 }
3049 #if 0
3050 // TODO: ������ KEY_RSA �����T�|�[�g���������� (2004.10.24 yutaka)
3051 if (pvar->hostkey_type != KEY_RSA) {
3052 strcpy(tmp, "unknown KEY type: ");
3053 strcat(tmp, buf);
3054 msg = tmp;
3055 goto error;
3056 }
3057 #endif
3058
3059 // �N���C�A���g -> �T�[�o�����A���S���Y���`�F�b�N
3060 size = get_payload_uint32(pvar, offset);
3061 offset += 4;
3062 for (i = 0; i < size; i++) {
3063 buf[i] = data[offset + i];
3064 }
3065 buf[i] = 0;
3066 offset += size;
3067 pvar->ctos_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]);
3068 if (pvar->ctos_cipher == SSH_CIPHER_NONE) {
3069 strcpy(tmp, "unknown Encrypt algorithm(ctos): ");
3070 strcat(tmp, buf);
3071 msg = tmp;
3072 goto error;
3073 }
3074
3075 // �T�[�o -> �N���C�A���g�����A���S���Y���`�F�b�N
3076 size = get_payload_uint32(pvar, offset);
3077 offset += 4;
3078 for (i = 0; i < size; i++) {
3079 buf[i] = data[offset + i];
3080 }
3081 buf[i] = 0;
3082 offset += size;
3083 pvar->stoc_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]);
3084 if (pvar->stoc_cipher == SSH_CIPHER_NONE) {
3085 strcpy(tmp, "unknown Encrypt algorithm(stoc): ");
3086 strcat(tmp, buf);
3087 msg = tmp;
3088 goto error;
3089 }
3090
3091
3092 // HMAC(Hash Message Authentication Code)�A���S���Y�������� (2004.12.17 yutaka)
3093 size = get_payload_uint32(pvar, offset);
3094 offset += 4;
3095 for (i = 0; i < size; i++) {
3096 buf[i] = data[offset + i];
3097 }
3098 buf[i] = 0;
3099 offset += size;
3100 pvar->ctos_hmac = choose_SSH2_hmac_algorithm(buf, myproposal[PROPOSAL_MAC_ALGS_CTOS]);
3101 if (pvar->ctos_hmac == HMAC_UNKNOWN) { // not match
3102 strcpy(tmp, "unknown HMAC algorithm: ");
3103 strcat(tmp, buf);
3104 msg = tmp;
3105 goto error;
3106 }
3107
3108 size = get_payload_uint32(pvar, offset);
3109 offset += 4;
3110 for (i = 0; i < size; i++) {
3111 buf[i] = data[offset + i];
3112 }
3113 buf[i] = 0;
3114 offset += size;
3115 pvar->stoc_hmac = choose_SSH2_hmac_algorithm(buf, myproposal[PROPOSAL_MAC_ALGS_STOC]);
3116 if (pvar->ctos_hmac == HMAC_UNKNOWN) { // not match
3117 strcpy(tmp, "unknown HMAC algorithm: ");
3118 strcat(tmp, buf);
3119 msg = tmp;
3120 goto error;
3121 }
3122
3123
3124 // we_need������ (2004.11.6 yutaka)
3125 // �L�[���������������X�L�b�v�����B
3126 if (pvar->rekeying == 0) {
3127 choose_SSH2_key_maxlength(pvar);
3128 }
3129
3130 // send DH kex init
3131 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
3132 SSH2_dh_kex_init(pvar);
3133
3134 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
3135 SSH2_dh_kex_init(pvar);
3136
3137 } else if (pvar->kex_type == KEX_DH_GEX_SHA1) {
3138 SSH2_dh_gex_kex_init(pvar);
3139
3140 }
3141
3142 return TRUE;
3143
3144 error:;
3145 buffer_free(pvar->peer_kex);
3146
3147 notify_fatal_error(pvar, msg);
3148
3149 return FALSE;
3150 }
3151
3152
3153
3154 static DH *dh_new_group_asc(const char *gen, const char *modulus)
3155 {
3156 DH *dh = NULL;
3157
3158 if ((dh = DH_new()) == NULL) {
3159 printf("dh_new_group_asc: DH_new");
3160 goto error;
3161 }
3162
3163 // P��G�����J�����������f�����g��������
3164 if (BN_hex2bn(&dh->p, modulus) == 0) {
3165 printf("BN_hex2bn p");
3166 goto error;
3167 }
3168
3169 if (BN_hex2bn(&dh->g, gen) == 0) {
3170 printf("BN_hex2bn g");
3171 goto error;
3172 }
3173
3174 return (dh);
3175
3176 error:
3177 DH_free(dh);
3178 return (NULL);
3179 }
3180
3181
3182 static DH *dh_new_group1(void)
3183 {
3184 static char *gen = "2", *group1 =
3185 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
3186 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
3187 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
3188 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
3189 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
3190 "FFFFFFFF" "FFFFFFFF";
3191
3192 return (dh_new_group_asc(gen, group1));
3193 }
3194
3195
3196 static DH *dh_new_group14(void)
3197 {
3198 static char *gen = "2", *group14 =
3199 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
3200 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
3201 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
3202 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
3203 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
3204 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
3205 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
3206 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
3207 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
3208 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
3209 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
3210
3211 return (dh_new_group_asc(gen, group14));
3212 }
3213
3214
3215 // DH������������
3216 static void dh_gen_key(PTInstVar pvar, DH *dh, int we_need /* bytes */ )
3217 {
3218 int i;
3219
3220 dh->priv_key = NULL;
3221
3222 // ����������������(X)������
3223 for (i = 0 ; i < 10 ; i++) { // retry counter
3224 if (dh->priv_key != NULL) {
3225 BN_clear_free(dh->priv_key);
3226 }
3227 dh->priv_key = BN_new();
3228 if (dh->priv_key == NULL)
3229 goto error;
3230 if (BN_rand(dh->priv_key, 2*(we_need*8), 0, 0) == 0)
3231 goto error;
3232 if (DH_generate_key(dh) == 0)
3233 goto error;