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 2757 - (show annotations) (download) (as text)
Fri Dec 17 14:05:55 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 118791 byte(s)
パケット受信時のHMACチェックを追加。
KEXにおけるHMACアルゴリズムチェックを追加。

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-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2287 "ssh-rsa,ssh-dss",
2288 "3des-cbc,aes128-cbc",
2289 "3des-cbc,aes128-cbc",
2290 "hmac-sha1,hmac-md5",
2291 "hmac-sha1,hmac-md5",
2292 // "hmac-sha1",
2293 // "hmac-sha1",
2294 "none",
2295 "none",
2296 "",
2297 "",
2298 };
2299 #else
2300 static char *myproposal[PROPOSAL_MAX] = {
2301 "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2302 "ssh-rsa,ssh-dss",
2303 "3des-cbc,aes128-cbc",
2304 "3des-cbc,aes128-cbc",
2305 "hmac-sha1,hmac-md5",
2306 "hmac-sha1,hmac-md5",
2307 "none",
2308 "none",
2309 "",
2310 "",
2311 };
2312 #endif
2313
2314
2315 typedef struct ssh2_cipher {
2316 SSHCipher cipher;
2317 char *name;
2318 int block_size;
2319 int key_len;
2320 const EVP_CIPHER *(*func)(void);
2321 } ssh2_cipher_t;
2322
2323 ssh2_cipher_t ssh2_ciphers[] = {
2324 {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
2325 {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
2326 {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
2327 };
2328
2329
2330 typedef struct ssh2_mac {
2331 char *name;
2332 const EVP_MD *(*func)(void);
2333 int truncatebits;
2334 } ssh2_mac_t;
2335
2336 ssh2_mac_t ssh2_macs[] = {
2337 {"hmac-sha1", EVP_sha1, 0},
2338 {"hmac-md5", EVP_md5, 0},
2339 {NULL, NULL, 0},
2340 };
2341
2342 static Newkeys current_keys[MODE_MAX];
2343
2344
2345 #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
2346
2347
2348 static int get_cipher_block_size(SSHCipher cipher)
2349 {
2350 ssh2_cipher_t *ptr = ssh2_ciphers;
2351 int val = 0;
2352
2353 while (ptr->name != NULL) {
2354 if (cipher == ptr->cipher) {
2355 val = ptr->block_size;
2356 break;
2357 }
2358 ptr++;
2359 }
2360 return (val);
2361 }
2362
2363 static int get_cipher_key_len(SSHCipher cipher)
2364 {
2365 ssh2_cipher_t *ptr = ssh2_ciphers;
2366 int val = 0;
2367
2368 while (ptr->name != NULL) {
2369 if (cipher == ptr->cipher) {
2370 val = ptr->key_len;
2371 break;
2372 }
2373 ptr++;
2374 }
2375 return (val);
2376 }
2377
2378
2379 #if 0
2380 static int get_mac_index(char *name)
2381 {
2382 ssh2_mac_t *ptr = ssh2_macs;
2383 int val = -1;
2384
2385 while (ptr->name != NULL) {
2386 if (strcmp(ptr->name, name) == 0) {
2387 val = ptr - ssh2_macs;
2388 break;
2389 }
2390 ptr++;
2391 }
2392 return (val);
2393 }
2394 #endif
2395
2396
2397 static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
2398 {
2399 FILE *fp;
2400 char filename[256];
2401
2402 _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
2403
2404 fp = fopen(filename, "wb");
2405 if (fp == NULL)
2406 return;
2407
2408 fwrite(buf, 1, len, fp);
2409
2410 fclose(fp);
2411 }
2412
2413
2414 void SSH2_packet_start(buffer_t *msg, unsigned char type)
2415 {
2416 unsigned char buf[9];
2417 int len = 6;
2418
2419 memset(buf, 0, sizeof(buf));
2420 buf[len - 1] = type;
2421 buffer_clear(msg);
2422 buffer_append(msg, buf, len);
2423 }
2424
2425
2426 // the caller is normalize_cipher_order()
2427 void SSH2_update_cipher_myproposal(PTInstVar pvar)
2428 {
2429 static char buf[128]; // TODO: malloc()��������
2430 int cipher;
2431 int len, i;
2432
2433 // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
2434 buf[0] = '\0';
2435 for (i = 0 ; pvar->ts_SSH->CipherOrder[i] != 0 ; i++) {
2436 cipher = pvar->ts_SSH->CipherOrder[i] - '0';
2437 if (cipher == 0) // disabled line
2438 break;
2439 if (cipher == SSH_CIPHER_AES128) {
2440 strcat(buf, "aes128-cbc,");
2441 }
2442 if (cipher == SSH_CIPHER_3DES_CBC) {
2443 strcat(buf, "3des-cbc,");
2444 }
2445 }
2446 if (buf[0] != '\0') {
2447 len = strlen(buf);
2448 buf[len - 1] = '\0'; // get rid of comma
2449 myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
2450 myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
2451 }
2452 }
2453
2454
2455 // �N���C�A���g�����T�[�o�����L�[�����J�n�v��
2456 void SSH2_send_kexinit(PTInstVar pvar)
2457 {
2458 char cookie[SSH2_COOKIE_LENGTH];
2459 buffer_t *msg;
2460 unsigned char *outmsg;
2461 int len, i;
2462
2463 msg = buffer_init();
2464 if (msg == NULL) {
2465 // TODO: error check
2466 return;
2467 }
2468 if (pvar->my_kex != NULL)
2469 buffer_free(pvar->my_kex);
2470 pvar->my_kex = msg;
2471
2472 // ���b�Z�[�W�^�C�v
2473 //SSH2_packet_start(msg, SSH2_MSG_KEXINIT);
2474
2475 // cookie���Z�b�g
2476 CRYPT_set_random_data(pvar, cookie, sizeof(cookie));
2477 CRYPT_set_server_cookie(pvar, cookie);
2478 buffer_append(msg, cookie, sizeof(cookie));
2479
2480 // �N���C�A���g���L�[����
2481 for (i = 0 ; i < PROPOSAL_MAX ; i++) {
2482 buffer_put_string(msg, myproposal[i], strlen(myproposal[i]));
2483 }
2484 buffer_put_char(msg, 0);
2485 buffer_put_int(msg, 0);
2486
2487 len = buffer_len(msg);
2488 outmsg = begin_send_packet(pvar, SSH2_MSG_KEXINIT, len);
2489 memcpy(outmsg, buffer_ptr(msg), len);
2490 finish_send_packet(pvar);
2491
2492 //buffer_free(msg);
2493 }
2494
2495
2496 static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
2497 {
2498 char tmp[1024], *ptr;
2499 SSHCipher cipher = SSH_CIPHER_NONE;
2500
2501 _snprintf(tmp, sizeof(tmp), my_proposal);
2502 ptr = strtok(tmp, ","); // not thread-safe
2503 while (ptr != NULL) {
2504 // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2505 if (strstr(server_proposal, ptr)) { // match
2506 break;
2507 }
2508 ptr = strtok(NULL, ",");
2509 }
2510 if (strstr(ptr, "3des-cbc")) {
2511 cipher = SSH_CIPHER_3DES_CBC;
2512
2513 } else if (strstr(ptr, "aes128-cbc")) {
2514 cipher = SSH_CIPHER_AES128;
2515 }
2516
2517 return (cipher);
2518 }
2519
2520
2521 static enum hmac_type choose_SSH2_hmac_algorithm(char *server_proposal, char *my_proposal)
2522 {
2523 char tmp[1024], *ptr;
2524 enum hmac_type type = HMAC_UNKNOWN;
2525
2526 _snprintf(tmp, sizeof(tmp), my_proposal);
2527 ptr = strtok(tmp, ","); // not thread-safe
2528 while (ptr != NULL) {
2529 // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2530 if (strstr(server_proposal, ptr)) { // match
2531 break;
2532 }
2533 ptr = strtok(NULL, ",");
2534 }
2535 if (strstr(ptr, "hmac-sha1")) {
2536 type = HMAC_SHA1;
2537 } else if (strstr(ptr, "hmac-md5")) {
2538 type = HMAC_MD5;
2539 }
2540
2541 return (type);
2542 }
2543
2544
2545 // �����A���S���Y�����L�[�T�C�Y�A�u���b�N�T�C�Y�AMAC�T�C�Y�����������l(we_need)�����������B
2546 static void choose_SSH2_key_maxlength(PTInstVar pvar)
2547 {
2548 int mode, need, val, ctos;
2549 char *macname;
2550 const EVP_MD *md;
2551
2552 for (mode = 0; mode < MODE_MAX; mode++) {
2553 if (mode == MODE_OUT)
2554 ctos = 1;
2555 else
2556 ctos = 0;
2557
2558 if (ctos == 1) {
2559 val = pvar->ctos_hmac;
2560 } else {
2561 val = pvar->stoc_hmac;
2562 }
2563
2564 // current_keys[]�����������������A������ pvar->ssh2_keys[] ���R�s�[�����B
2565 md = ssh2_macs[val].func();
2566 current_keys[mode].mac.md = md;
2567 current_keys[mode].mac.key_len = current_keys[mode].mac.mac_len = EVP_MD_size(md);
2568 if (ssh2_macs[val].truncatebits != 0) {
2569 current_keys[mode].mac.mac_len = ssh2_macs[val].truncatebits / 8;
2570 }
2571
2572 // �L�[�T�C�Y���u���b�N�T�C�Y�������������������� (2004.11.7 yutaka)
2573 if (ctos == 1) {
2574 current_keys[mode].enc.key_len = get_cipher_key_len(pvar->ctos_cipher);
2575 current_keys[mode].enc.block_size = get_cipher_block_size(pvar->ctos_cipher);
2576 } else {
2577 current_keys[mode].enc.key_len = get_cipher_key_len(pvar->stoc_cipher);
2578 current_keys[mode].enc.block_size = get_cipher_block_size(pvar->stoc_cipher);
2579 }
2580 current_keys[mode].mac.enabled = 0;
2581
2582 // �����_����MAC��disable
2583 pvar->ssh2_keys[mode].mac.enabled = 0;
2584 }
2585 need = 0;
2586 for (mode = 0; mode < MODE_MAX; mode++) {
2587 if (mode == MODE_OUT)
2588 ctos = 1;
2589 else
2590 ctos = 0;
2591
2592 val = current_keys[mode].enc.key_len;
2593 if (need < val)
2594 need = val;
2595
2596 val = current_keys[mode].enc.block_size;
2597 if (need < val)
2598 need = val;
2599
2600 val = current_keys[mode].mac.key_len;
2601 if (need < val)
2602 need = val;
2603 }
2604 pvar->we_need = need;
2605
2606 error:;
2607 }
2608
2609
2610 // �L�[�����J�n�O���`�F�b�N (SSH2_MSG_KEXINIT)
2611 // �����Y�������f�[�^���M���������������������\������
2612 static BOOL handle_SSH2_kexinit(PTInstVar pvar)
2613 {
2614 char buf[1024];
2615 char *data;
2616 int len, i, size;
2617 int offset = 0;
2618 char *msg = NULL;
2619 char tmp[1024+512];
2620 char *ptr;
2621
2622 // �������L�[�������I�����������������������A�T�[�o���� SSH2_MSG_KEXINIT ��
2623 // �������������������A�L�[���������s���B(2004.10.24 yutaka)
2624 if (pvar->key_done == 1) {
2625 pvar->rekeying = 1;
2626 pvar->key_done = 0;
2627
2628 // �T�[�o��SSH2_MSG_KEXINIT ������
2629 SSH2_send_kexinit(pvar);
2630 }
2631
2632 if (pvar->peer_kex != NULL) { // already allocated
2633 buffer_free(pvar->peer_kex);
2634 }
2635 pvar->peer_kex = buffer_init();
2636 if (pvar->peer_kex == NULL) {
2637 msg = "Out of memory @ handle_SSH2_kexinit()";
2638 goto error;
2639 }
2640 // [-2]:padding size
2641 // len = pvar->ssh_state.payloadlen + pvar->ssh_state.payload[-2] + 1;
2642 len = pvar->ssh_state.payloadlen - 1;
2643 // buffer_append(pvar->peer_kex, &pvar->ssh_state.payload[-6], len);
2644 buffer_append(pvar->peer_kex, pvar->ssh_state.payload, len);
2645 //write_buffer_file(&pvar->ssh_state.payload[-6], len);
2646
2647 // TODO: buffer overrun check
2648
2649 // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
2650 data = pvar->ssh_state.payload;
2651 // �p�P�b�g�T�C�Y - (�p�f�B���O+1)�G�^���p�P�b�g�T�C�Y
2652 len = pvar->ssh_state.payloadlen;
2653
2654 //write_buffer_file(data, len);
2655
2656 if (offset + 20 >= len) {
2657 msg = "payload size too small @ handle_SSH2_kexinit()";
2658 goto error;
2659 }
2660
2661 #if 0
2662 for (i = 0; i < SSH2_COOKIE_LENGTH; i++) {
2663 cookie[i] = data[i];
2664 }
2665 #endif
2666 // get rid of Cookie length
2667 offset += SSH2_COOKIE_LENGTH;
2668
2669 // �L�[�����A���S���Y���`�F�b�N
2670 size = get_payload_uint32(pvar, offset);
2671 offset += 4;
2672 for (i = 0; i < size; i++) {
2673 buf[i] = data[offset + i];
2674 }
2675 buf[i] = '\0'; // null-terminate
2676 offset += size;
2677
2678 // KEX�������B��������myproposal[PROPOSAL_KEX_ALGS]���������������������B
2679 // �T�[�o���A�N���C�A���g���������������� myproposal[PROPOSAL_KEX_ALGS] ���J���}�������������A
2680 // �������������� myproposal[] �����r���s���A�������}�b�`����������KEX�A���S���Y��������
2681 // �I���������B(2004.10.30 yutaka)
2682 pvar->kex_type = -1;
2683 _snprintf(tmp, sizeof(tmp), myproposal[PROPOSAL_KEX_ALGS]);
2684 ptr = strtok(tmp, ","); // not thread-safe
2685 while (ptr != NULL) {
2686 // buf[]�����T�[�o��proposal���J���}���������i�[����������
2687 if (strstr(buf, ptr)) { // match
2688 break;
2689 }
2690 ptr = strtok(NULL, ",");
2691 }
2692 if (ptr == NULL) { // not match
2693 strcpy(tmp, "unknown KEX algorithm: ");
2694 strcat(tmp, buf);
2695 msg = tmp;
2696 goto error;
2697 }
2698 if (strstr(ptr, KEX_DH14)) {
2699 pvar->kex_type = KEX_DH_GRP14_SHA1;
2700 } else if (strstr(ptr, KEX_DH1)) {
2701 pvar->kex_type = KEX_DH_GRP1_SHA1;
2702 } else if (strstr(ptr, KEX_DHGEX)) {
2703 pvar->kex_type = KEX_DH_GEX_SHA1;
2704 }
2705
2706
2707 // �z�X�g�L�[�A���S���Y���`�F�b�N
2708 size = get_payload_uint32(pvar, offset);
2709 offset += 4;
2710 for (i = 0; i < size; i++) {
2711 buf[i] = data[offset + i];
2712 }
2713 buf[i] = 0;
2714 offset += size;
2715 pvar->hostkey_type = -1;
2716 _snprintf(tmp, sizeof(tmp), myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]);
2717 ptr = strtok(tmp, ","); // not thread-safe
2718 while (ptr != NULL) {
2719 // buf[]�����T�[�o��proposal���J���}���������i�[����������
2720 if (strstr(buf, ptr)) { // match
2721 break;
2722 }
2723 ptr = strtok(NULL, ",");
2724 }
2725 if (ptr == NULL) { // not match
2726 strcpy(tmp, "unknown host KEY type: ");
2727 strcat(tmp, buf);
2728 msg = tmp;
2729 goto error;
2730 }
2731 if (strstr(ptr, "ssh-rsa")) {
2732 pvar->hostkey_type = KEY_RSA;
2733 } else if (strstr(ptr, "ssh-dss")) {
2734 pvar->hostkey_type = KEY_DSA;
2735 } else if (strstr(ptr, "rsa1")) {
2736 pvar->hostkey_type = KEY_RSA1;
2737 } else if (strstr(ptr, "rsa")) {
2738 pvar->hostkey_type = KEY_RSA;
2739 } else if (strstr(ptr, "dsa")) {
2740 pvar->hostkey_type = KEY_DSA;
2741 }
2742 #if 0
2743 // TODO: ������ KEY_RSA �����T�|�[�g���������� (2004.10.24 yutaka)
2744 if (pvar->hostkey_type != KEY_RSA) {
2745 strcpy(tmp, "unknown KEY type: ");
2746 strcat(tmp, buf);
2747 msg = tmp;
2748 goto error;
2749 }
2750 #endif
2751
2752 // �N���C�A���g -> �T�[�o�����A���S���Y���`�F�b�N
2753 size = get_payload_uint32(pvar, offset);
2754 offset += 4;
2755 for (i = 0; i < size; i++) {
2756 buf[i] = data[offset + i];
2757 }
2758 buf[i] = 0;
2759 offset += size;
2760 pvar->ctos_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]);
2761 if (pvar->ctos_cipher == SSH_CIPHER_NONE) {
2762 strcpy(tmp, "unknown Encrypt algorithm(ctos): ");
2763 strcat(tmp, buf);
2764 msg = tmp;
2765 goto error;
2766 }
2767
2768 // �T�[�o -> �N���C�A���g�����A���S���Y���`�F�b�N
2769 size = get_payload_uint32(pvar, offset);
2770 offset += 4;
2771 for (i = 0; i < size; i++) {
2772 buf[i] = data[offset + i];
2773 }
2774 buf[i] = 0;
2775 offset += size;
2776 pvar->stoc_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]);
2777 if (pvar->stoc_cipher == SSH_CIPHER_NONE) {
2778 strcpy(tmp, "unknown Encrypt algorithm(stoc): ");
2779 strcat(tmp, buf);
2780 msg = tmp;
2781 goto error;
2782 }
2783
2784
2785 // HMAC(Hash Message Authentication Code)�A���S���Y�������� (2004.12.17 yutaka)
2786 size = get_payload_uint32(pvar, offset);
2787 offset += 4;
2788 for (i = 0; i < size; i++) {
2789 buf[i] = data[offset + i];
2790 }
2791 buf[i] = 0;
2792 offset += size;
2793 pvar->ctos_hmac = choose_SSH2_hmac_algorithm(buf, myproposal[PROPOSAL_MAC_ALGS_CTOS]);
2794 if (pvar->ctos_hmac == HMAC_UNKNOWN) { // not match
2795 strcpy(tmp, "unknown HMAC algorithm: ");
2796 strcat(tmp, buf);
2797 msg = tmp;
2798 goto error;
2799 }
2800
2801 size = get_payload_uint32(pvar, offset);
2802 offset += 4;
2803 for (i = 0; i < size; i++) {
2804 buf[i] = data[offset + i];
2805 }
2806 buf[i] = 0;
2807 offset += size;
2808 pvar->stoc_hmac = choose_SSH2_hmac_algorithm(buf, myproposal[PROPOSAL_MAC_ALGS_STOC]);
2809 if (pvar->ctos_hmac == HMAC_UNKNOWN) { // not match
2810 strcpy(tmp, "unknown HMAC algorithm: ");
2811 strcat(tmp, buf);
2812 msg = tmp;
2813 goto error;
2814 }
2815
2816
2817 // we_need������ (2004.11.6 yutaka)
2818 // �L�[���������������X�L�b�v�����B
2819 if (pvar->rekeying == 0) {
2820 choose_SSH2_key_maxlength(pvar);
2821 }
2822
2823 // send DH kex init
2824 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
2825 SSH2_dh_kex_init(pvar);
2826
2827 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
2828 SSH2_dh_kex_init(pvar);
2829
2830 } else if (pvar->kex_type == KEX_DH_GEX_SHA1) {
2831 SSH2_dh_gex_kex_init(pvar);
2832
2833 }
2834
2835 return TRUE;
2836
2837 error:;
2838 buffer_free(pvar->peer_kex);
2839
2840 notify_fatal_error(pvar, msg);
2841
2842 return FALSE;
2843 }
2844
2845
2846
2847 static DH *dh_new_group_asc(const char *gen, const char *modulus)
2848 {
2849 DH *dh = NULL;
2850
2851 if ((dh = DH_new()) == NULL) {
2852 printf("dh_new_group_asc: DH_new");
2853 goto error;
2854 }
2855
2856 // P��G�����J�����������f�����g��������
2857 if (BN_hex2bn(&dh->p, modulus) == 0) {
2858 printf("BN_hex2bn p");
2859 goto error;
2860 }
2861
2862 if (BN_hex2bn(&dh->g, gen) == 0) {
2863 printf("BN_hex2bn g");
2864 goto error;
2865 }
2866
2867 return (dh);
2868
2869 error:
2870 DH_free(dh);
2871 return (NULL);
2872 }
2873
2874
2875 static DH *dh_new_group1(void)
2876 {
2877 static char *gen = "2", *group1 =
2878 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
2879 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
2880 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
2881 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
2882 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
2883 "FFFFFFFF" "FFFFFFFF";
2884
2885 return (dh_new_group_asc(gen, group1));
2886 }
2887
2888
2889 static DH *dh_new_group14(void)
2890 {
2891 static char *gen = "2", *group14 =
2892 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
2893 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
2894 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
2895 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
2896 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
2897 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
2898 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
2899 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
2900 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
2901 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
2902 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
2903
2904 return (dh_new_group_asc(gen, group14));
2905 }
2906
2907
2908 // DH������������
2909 static void dh_gen_key(PTInstVar pvar, DH *dh, int we_need /* bytes */ )
2910 {
2911 int i;
2912
2913 dh->priv_key = NULL;
2914
2915 // ����������������(X)������
2916 for (i = 0 ; i < 10 ; i++) { // retry counter
2917 if (dh->priv_key != NULL) {
2918 BN_clear_free(dh->priv_key);
2919 }
2920 dh->priv_key = BN_new();
2921 if (dh->priv_key == NULL)
2922 goto error;
2923 if (BN_rand(dh->priv_key, 2*(we_need*8), 0, 0) == 0)
2924 goto error;
2925 if (DH_generate_key(dh) == 0)
2926 goto error;
2927 if (dh_pub_is_valid(dh, dh->pub_key))
2928 break;
2929 }
2930 if (i >= 10) {
2931 goto error;
2932 }
2933 return;
2934
2935 error:;
2936 notify_fatal_error(pvar, "error occurred @ dh_gen_key()");
2937
2938 }
2939
2940 //
2941 // KEX_DH_GRP1_SHA1 or KEX_DH_GRP14_SHA1
2942 //
2943 static void SSH2_dh_kex_init(PTInstVar pvar)
2944 {
2945 DH *dh = NULL;
2946 char *s, *t;
2947 buffer_t *msg = NULL;
2948 unsigned char *outmsg;
2949 int len;
2950
2951 // Diffie-Hellman key agreement
2952 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
2953 dh = dh_new_group1();
2954 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
2955 dh = dh_new_group14();
2956 } else {
2957 goto error;
2958 }
2959
2960 // ����������������(X)������
2961 dh_gen_key(pvar, dh, pvar->we_need);
2962
2963 s = BN_bn2hex(dh->priv_key);
2964 t = BN_bn2hex(dh->pub_key);
2965
2966
2967 msg = buffer_init();
2968 if (msg == NULL) {
2969 // TODO: error check
2970 return;
2971 }
2972
2973 buffer_put_bignum2(msg, dh->pub_key);
2974
2975 len = buffer_len(msg);
2976 outmsg = begin_send_packet(pvar, SSH2_MSG_KEXDH_INIT, len);
2977 memcpy(outmsg, buffer_ptr(msg), len);
2978 finish_send_packet(pvar);
2979
2980 if (pvar->kexdh != NULL) {
2981 DH_free(dh);
2982 }
2983 pvar->kexdh = dh;
2984
2985 SSH2_dispatch_init(2);
2986 SSH2_dispatch_add_message(SSH2_MSG_KEXDH_REPLY);
2987
2988 buffer_free(msg);
2989 return;
2990
2991 error:;
2992 DH_free(dh);
2993 buffer_free(msg);
2994
2995 notify_fatal_error(pvar, "error occurred @ SSH2_dh_kex_init()");
2996 }
2997
2998
2999
3000 //
3001 // KEX_DH_GEX_SHA1
3002 //
3003 // cf. Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol
3004 // (draft-ietf-secsh-dh-group-exchange-04.txt)
3005 //
3006
3007 static int dh_estimate(int bits)
3008 {
3009 if (bits <= 128)
3010 return (1024); /* O(2**86) */
3011 if (bits <= 192)
3012 return (2048); /* O(2**116) */
3013 return (4096); /* O(2**156) */
3014 }
3015
3016 static void SSH2_dh_gex_kex_init(PTInstVar pvar)
3017 {
3018 buffer_t *msg = NULL;
3019 unsigned char *outmsg;
3020 int len;
3021 int bits, min, max;
3022
3023 msg = buffer_init();
3024 if (msg == NULL) {
3025 goto error;
3026 }
3027
3028 // �T�[�o���������������������r�b�g�����������iwe_need���o�C�g�j�B
3029 bits = dh_estimate(pvar->we_need * 8);
3030 min = 1024;
3031 max = 8192;
3032
3033 // �T�[�o��group size���������Ap �� g ���������������B
3034 buffer_put_int(msg, min);
3035 buffer_put_int(msg, bits);
3036 buffer_put_int(msg, max);
3037 len = buffer_len(msg);
3038 outmsg = begin_send_packet(pvar, SSH2_MSG_KEX_DH_GEX_REQUEST, len);
3039 memcpy(outmsg, buffer_ptr(msg), len);
3040 finish_send_packet(pvar);
3041
3042 // �������n�b�V���v�Z���g�����������������B
3043 pvar->kexgex_min = min;
3044 pvar->kexgex_bits = bits;
3045 pvar->kexgex_max = max;
3046
3047 SSH2_dispatch_init(2);
3048 SSH2_dispatch_add_message(SSH2_MSG_KEX_DH_GEX_GROUP);
3049
3050 buffer_free(msg);
3051 return;
3052
3053 error:;
3054 buffer_free(msg);
3055
3056 notify_fatal_error(pvar, "error occurred @ SSH2_dh_gex_kex_init()");
3057 }
3058
3059
3060 // SSH2_MSG_KEX_DH_GEX_GROUP
3061 static BOOL handle_SSH2_dh_gex_group(PTInstVar pvar)
3062 {
3063 char *data;
3064 int len;
3065 BIGNUM *p = NULL, *g = NULL;
3066 DH *dh = NULL;
3067 buffer_t *msg = NULL;
3068 unsigned char *outmsg;
3069
3070 // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
3071 data = pvar->ssh_state.payload;
3072 // �p�P�b�g�T�C�Y - (�p�f�B���O�T�C�Y+1)�G�^���p�P�b�g�T�C�Y
3073 len = pvar->ssh_state.payloadlen;
3074
3075 p = BN_new();
3076 g = BN_new();
3077 if (p == NULL || g == NULL)
3078 goto error;
3079
3080 buffer_get_bignum2(&data, p); // �f��������
3081 buffer_get_bignum2(&data, g); // ������������
3082
3083 dh = DH_new();
3084 if (dh == NULL)
3085 goto error;
3086 dh->p = p;
3087 dh->g = g;
3088
3089 // ����������������(X)������
3090 dh_gen_key(pvar, dh, pvar->we_need);
3091
3092 // ���J�����T�[�o�����M
3093 msg = buffer_init();
3094 if (msg == NULL) {
3095 goto error;
3096 }
3097 buffer_put_bignum2(msg, dh->pub_key);
3098 len = buffer_len(msg);
3099 outmsg = begin_send_packet(pvar, SSH2_MSG_KEX_DH_GEX_INIT, len);
3100 memcpy(outmsg, buffer_ptr(msg), len);
3101 finish_send_packet(pvar);
3102
3103 // ��������������DH�����A�������n�b�V���v�Z���g�����������������B(2004.10.31 yutaka)
3104 pvar->kexdh = dh;
3105
3106 SSH2_dispatch_init(2);
3107 SSH2_dispatch_add_message(SSH2_MSG_KEX_DH_GEX_REPLY);
3108
3109 buffer_free(msg);
3110
3111 return TRUE;
3112
3113 error:;
3114 BN_free(p);
3115 BN_free(g);
3116 DH_free(dh);
3117
3118 return FALSE;
3119 }
3120
3121
3122
3123 // SHA-1(160bit)��������
3124 unsigned char *kex_dh_hash(
3125 char *client_version_string,
3126 char *server_version_string,
3127 char *ckexinit, int ckexinitlen,
3128 char *skexinit, int skexinitlen,
3129 u_char *serverhostkeyblob, int sbloblen,
3130 BIGNUM *client_dh_pub,
3131 BIGNUM *server_dh_pub,
3132 BIGNUM *shared_secret)
3133 {
3134 buffer_t *b;
3135 static unsigned char digest[EVP_MAX_MD_SIZE];
3136 const EVP_MD *evp_md = EVP_sha1();
3137 EVP_MD_CTX md;
3138
3139 b = buffer_init();
3140 buffer_put_string(b, client_version_string, strlen(client_version_string));
3141 buffer_put_string(b, server_version_string, strlen(server_version_string));
3142
3143 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
3144 buffer_put_int(b, ckexinitlen+1);
3145 buffer_put_char(b, SSH2_MSG_KEXINIT);
3146 buffer_append(b, ckexinit, ckexinitlen);
3147 buffer_put_int(b, skexinitlen+1);
3148 buffer_put_char(b, SSH2_MSG_KEXINIT);
3149 buffer_append(b, skexinit, skexinitlen);
3150
3151 buffer_put_string(b, serverhostkeyblob, sbloblen);
3152 buffer_put_bignum2(b, client_dh_pub);
3153 buffer_put_bignum2(b, server_dh_pub);
3154 buffer_put_bignum2(b, shared_secret);
3155
3156 // yutaka
3157 //debug_print(38, buffer_ptr(b), buffer_len(b));
3158
3159 EVP_DigestInit(&md, evp_md);
3160 EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
3161 EVP_DigestFinal(&md, digest, NULL);
3162
3163 buffer_free(b);
3164
3165 //write_buffer_file(digest, EVP_MD_size(evp_md));
3166
3167 return digest;
3168 }
3169
3170
3171 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
3172 {
3173 int i;
3174 int n = BN_num_bits(dh_pub);
3175 int bits_set = 0;
3176
3177 if (dh_pub->neg) {
3178 //logit("invalid public DH value: negativ");
3179 return 0;
3180 }
3181 for (i = 0; i <= n; i++)
3182 if (BN_is_bit_set(dh_pub, i))
3183 bits_set++;
3184 //debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
3185
3186 /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
3187 if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
3188 return 1;
3189 //logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
3190 return 0;
3191 }
3192
3193
3194 static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret, char *session_id, int session_id_len)
3195 {
3196 buffer_t *b;
3197 const EVP_MD *evp_md = EVP_sha1();
3198 EVP_MD_CTX md;
3199 char c = id;
3200 int have;
3201 int mdsz = EVP_MD_size(evp_md); // 20bytes(160bit)
3202 u_char *digest = malloc(roundup(need, mdsz));
3203
3204 if (digest == NULL)
3205 goto skip;
3206
3207 b = buffer_init();
3208 if (b == NULL)
3209 goto skip;
3210
3211 buffer_put_bignum2(b, shared_secret);
3212
3213 /* K1 = HASH(K || H || "A" || session_id) */
3214 EVP_DigestInit(&md, evp_md);
3215 EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
3216 EVP_DigestUpdate(&md, hash, mdsz);
3217 EVP_DigestUpdate(&md, &c, 1);
3218 EVP_DigestUpdate(&md, session_id, session_id_len);
3219 EVP_DigestFinal(&md, digest, NULL);
3220
3221 /*
3222 * expand key:
3223 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
3224 * Key = K1 || K2 || ... || Kn
3225 */
3226 for (have = mdsz; need > have; have += mdsz) {
3227 EVP_DigestInit(&md, evp_md);
3228 EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
3229 EVP_DigestUpdate(&md, hash, mdsz);
3230 EVP_DigestUpdate(&md, digest, have);
3231 EVP_DigestFinal(&md, digest + have, NULL);
3232 }
3233 buffer_free(b);
3234
3235 skip:;
3236 return digest;
3237 }
3238
3239
3240 static void ssh2_set_newkeys(PTInstVar pvar, int mode)
3241 {
3242 // free already allocated buffer
3243 if (pvar->ssh2_keys[mode].enc.iv != NULL)
3244 free(pvar->ssh2_keys[mode].enc.iv);
3245 if (pvar->ssh2_keys[mode].enc.key != NULL)
3246 free(pvar->ssh2_keys[mode].enc.key);
3247 if (pvar->ssh2_keys[mode].mac.key != NULL)
3248 free(pvar->ssh2_keys[mode].<