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 2793 - (show annotations) (download) (as text)
Thu Mar 3 13:28:23 2005 UTC (19 years, 1 month ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 133488 byte(s)
クライアントのSSHバージョンを ttxssh.dll から取得して、サーバへ送るようにした。

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