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 2762 - (show annotations) (download) (as text)
Wed Dec 22 17:28:14 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 126555 byte(s)
SSH2公開鍵認証(RSA/DSA)をサポートした。

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