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 2798 - (show annotations) (download) (as text)
Thu Mar 10 13:40:39 2005 UTC (19 years, 1 month ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 140602 byte(s)
すでにログイン処理を行っている場合は、SSH2_MSG_SERVICE_REQUESTの送信は
しないことにする。OpenSSHでは支障ないが、Tru64 UNIXではサーバエラーとなってしまうため。

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