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 2782 - (show annotations) (download) (as text)
Mon Jan 24 14:07:07 2005 UTC (19 years, 2 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 133128 byte(s)
・keyboard-interactive認証をサポートした。
 それに伴い、teraterm.iniに "KeyboardInteractive" エントリを追加した。
・バージョンダイアログに OpenSSLバージョン を追加

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