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 2728 - (show annotations) (download) (as text)
Sun Nov 14 15:53:21 2004 UTC (19 years, 5 months ago) by yutakakn
Original Path: ttssh2/branches/avendor/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 114026 byte(s)
no message

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