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 2759 - (show annotations) (download) (as text)
Fri Dec 17 16:52:36 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 120758 byte(s)
KEXにおけるRSAおよびDSSのkey verify処理を追加。

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