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 2739 - (show annotations) (download) (as text)
Wed Dec 1 15:37:49 2004 UTC (19 years, 4 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 114398 byte(s)
SSH2自動ログイン機能を追加。
現状、パスワード認証のみに対応。
・コマンドライン
  /ssh /auth=認証メソッド /user=ユーザ名 /passwd=パスワード

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 = 2; // SSH2(default)
1739 pvar->rekeying = 0;
1740 pvar->key_done = 0;
1741 pvar->ssh2_autologin = 0; // autologin disabled(default)
1742
1743 }
1744
1745 void SSH_open(PTInstVar pvar)
1746 {
1747 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
1748 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
1749 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
1750 }
1751
1752 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
1753 {
1754 if (SSHv1(pvar)) {
1755 int len = reason == NULL ? 0 : strlen(reason);
1756 unsigned char FAR *outmsg =
1757 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
1758
1759 set_uint32(outmsg, len);
1760 if (reason != NULL) {
1761 memcpy(outmsg + 4, reason, len);
1762 }
1763 finish_send_packet(pvar);
1764
1765 } else { // for SSH2(yutaka)
1766 buffer_t *msg;
1767 unsigned char *outmsg;
1768 int len;
1769
1770 // SSH2 server��channel close���`����
1771 msg = buffer_init();
1772 if (msg == NULL) {
1773 // TODO: error check
1774 return;
1775 }
1776 buffer_put_int(msg, pvar->remote_id);
1777
1778 len = buffer_len(msg);
1779 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
1780 memcpy(outmsg, buffer_ptr(msg), len);
1781 finish_send_packet(pvar);
1782 buffer_free(msg);
1783
1784 }
1785
1786 }
1787
1788 void SSH_notify_host_OK(PTInstVar pvar)
1789 {
1790 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
1791 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
1792 send_session_key(pvar);
1793 }
1794 }
1795
1796 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
1797 {
1798 pvar->ssh_state.win_cols = cols;
1799 pvar->ssh_state.win_rows = rows;
1800
1801 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
1802 unsigned char FAR *outmsg =
1803 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
1804
1805 set_uint32(outmsg, rows);
1806 set_uint32(outmsg + 4, cols);
1807 set_uint32(outmsg + 8, 0);
1808 set_uint32(outmsg + 12, 0);
1809 finish_send_packet(pvar);
1810 }
1811 }
1812
1813 int SSH_get_min_packet_size(PTInstVar pvar)
1814 {
1815 if (SSHv1(pvar)) {
1816 return 12;
1817 } else {
1818 int block_size = CRYPT_get_decryption_block_size(pvar);
1819
1820 return max(16, block_size);
1821 }
1822 }
1823
1824 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
1825 at least 5 bytes must be decrypted */
1826 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
1827 {
1828 if (SSHv2(pvar)) {
1829 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
1830 }
1831 }
1832
1833 int SSH_get_clear_MAC_size(PTInstVar pvar)
1834 {
1835 if (SSHv1(pvar)) {
1836 return 0;
1837 } else {
1838 return CRYPT_get_receiver_MAC_size(pvar);
1839 }
1840 }
1841
1842 void SSH_notify_user_name(PTInstVar pvar)
1843 {
1844 try_send_user_name(pvar);
1845 }
1846
1847 void SSH_notify_cred(PTInstVar pvar)
1848 {
1849 try_send_credentials(pvar);
1850 }
1851
1852 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
1853 {
1854 if (SSHv1(pvar)) {
1855 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
1856 return;
1857 }
1858
1859 while (buflen > 0) {
1860 int len =
1861 buflen >
1862 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
1863 unsigned char FAR *outmsg =
1864 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
1865
1866 set_uint32(outmsg, len);
1867
1868 if (pvar->ssh_state.compressing) {
1869 buf_ensure_size(&pvar->ssh_state.outbuf,
1870 &pvar->ssh_state.outbuflen,
1871 len + (len >> 6) + 50);
1872 pvar->ssh_state.compress_stream.next_in =
1873 pvar->ssh_state.precompress_outbuf;
1874 pvar->ssh_state.compress_stream.avail_in = 5;
1875 pvar->ssh_state.compress_stream.next_out =
1876 pvar->ssh_state.outbuf + 12;
1877 pvar->ssh_state.compress_stream.avail_out =
1878 pvar->ssh_state.outbuflen - 12;
1879
1880 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) !=
1881 Z_OK) {
1882 notify_fatal_error(pvar, "Error compressing packet data");
1883 return;
1884 }
1885
1886 pvar->ssh_state.compress_stream.next_in =
1887 (unsigned char FAR *) buf;
1888 pvar->ssh_state.compress_stream.avail_in = len;
1889
1890 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
1891 Z_OK) {
1892 notify_fatal_error(pvar, "Error compressing packet data");
1893 return;
1894 }
1895 } else {
1896 memcpy(outmsg + 4, buf, len);
1897 }
1898
1899 finish_send_packet_special(pvar, 1);
1900
1901 buflen -= len;
1902 buf += len;
1903 }
1904
1905 } else { // for SSH2(yutaka)
1906 buffer_t *msg;
1907 unsigned char *outmsg;
1908 int len;
1909
1910 msg = buffer_init();
1911 if (msg == NULL) {
1912 // TODO: error check
1913 return;
1914 }
1915 buffer_put_int(msg, pvar->remote_id);
1916 buffer_put_string(msg, (char *)buf, buflen);
1917
1918 len = buffer_len(msg);
1919 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
1920 memcpy(outmsg, buffer_ptr(msg), len);
1921 finish_send_packet(pvar);
1922 buffer_free(msg);
1923
1924 // remote window size������
1925 pvar->remote_window -= len;
1926
1927 }
1928
1929 }
1930
1931 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
1932 {
1933 int num_bytes = pvar->ssh_state.payload_datalen;
1934
1935 if (num_bytes > len) {
1936 num_bytes = len;
1937 }
1938
1939 if (!pvar->ssh_state.decompressing) {
1940 memcpy(dest,
1941 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
1942 num_bytes);
1943 pvar->ssh_state.payload_datastart += num_bytes;
1944 } else if (num_bytes > 0) {
1945 pvar->ssh_state.decompress_stream.next_out = dest;
1946 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
1947
1948 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) !=
1949 Z_OK) {
1950 notify_fatal_error(pvar,
1951 "Invalid compressed data in received packet");
1952 return 0;
1953 }
1954 }
1955
1956 pvar->ssh_state.payload_datalen -= num_bytes;
1957
1958 return num_bytes;
1959 }
1960
1961 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
1962 {
1963 char buf[1024];
1964 char buf2[1024];
1965
1966 if (pvar->ssh_state.compressing) {
1967 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
1968 unsigned long total_out =
1969 pvar->ssh_state.compress_stream.total_out;
1970
1971 if (total_out > 0) {
1972 _snprintf(buf, sizeof(buf), "level %d; ratio %.1f (%ld:%ld)",
1973 pvar->ssh_state.compression_level,
1974 ((double) total_in) / total_out, total_in,
1975 total_out);
1976 } else {
1977 _snprintf(buf, sizeof(buf), "level %d",
1978 pvar->ssh_state.compression_level);
1979 }
1980 } else {
1981 strcpy(buf, "none");
1982 }
1983 buf[sizeof(buf) - 1] = 0;
1984
1985 if (pvar->ssh_state.decompressing) {
1986 unsigned long total_in =
1987 pvar->ssh_state.decompress_stream.total_in;
1988 unsigned long total_out =
1989 pvar->ssh_state.decompress_stream.total_out;
1990
1991 if (total_in > 0) {
1992 _snprintf(buf2, sizeof(buf2), "level %d; ratio %.1f (%ld:%ld)",
1993 pvar->ssh_state.compression_level,
1994 ((double) total_out) / total_in, total_out,
1995 total_in);
1996 } else {
1997 _snprintf(buf2, sizeof(buf2), "level %d",
1998 pvar->ssh_state.compression_level);
1999 }
2000 } else {
2001 strcpy(buf2, "none");
2002 }
2003 buf2[sizeof(buf2) - 1] = 0;
2004
2005 _snprintf(dest, len, "Upstream %s; Downstream %s", buf, buf2);
2006 dest[len - 1] = 0;
2007 }
2008
2009 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2010 {
2011 strncpy(dest, pvar->ssh_state.server_ID == NULL ? "Unknown"
2012 : pvar->ssh_state.server_ID, len);
2013 dest[len - 1] = 0;
2014 }
2015
2016 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2017 int len)
2018 {
2019 if (pvar->protocol_major == 0) {
2020 strncpy(dest, "Unknown", len);
2021 } else {
2022 _snprintf(dest, len, "%d.%d", pvar->protocol_major,
2023 pvar->protocol_minor);
2024 }
2025 dest[len - 1] = 0;
2026 }
2027
2028 void SSH_end(PTInstVar pvar)
2029 {
2030 int i;
2031
2032 for (i = 0; i < 256; i++) {
2033 SSHPacketHandlerItem FAR *first_item =
2034 pvar->ssh_state.packet_handlers[i];
2035
2036 if (first_item != NULL) {
2037 SSHPacketHandlerItem FAR *item = first_item;
2038
2039 do {
2040 SSHPacketHandlerItem FAR *cur_item = item;
2041
2042 item = item->next_for_message;
2043 free(cur_item);
2044 } while (item != first_item);
2045 }
2046 pvar->ssh_state.packet_handlers[i] = NULL;
2047 }
2048
2049 free(pvar->ssh_state.hostname);
2050 pvar->ssh_state.hostname = NULL;
2051 free(pvar->ssh_state.server_ID);
2052 pvar->ssh_state.server_ID = NULL;
2053 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2054 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2055 &pvar->ssh_state.precompress_outbuflen);
2056 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2057 &pvar->ssh_state.postdecompress_inbuflen);
2058
2059 if (pvar->ssh_state.compressing) {
2060 deflateEnd(&pvar->ssh_state.compress_stream);
2061 pvar->ssh_state.compressing = FALSE;
2062 }
2063 if (pvar->ssh_state.decompressing) {
2064 inflateEnd(&pvar->ssh_state.decompress_stream);
2065 pvar->ssh_state.decompressing = FALSE;
2066 }
2067 }
2068
2069 /* support for port forwarding */
2070 void SSH_channel_send(PTInstVar pvar, uint32 remote_channel_num,
2071 unsigned char FAR * buf, int len)
2072 {
2073 unsigned char FAR *outmsg =
2074 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2075
2076 set_uint32(outmsg, remote_channel_num);
2077 set_uint32(outmsg + 4, len);
2078
2079 if (pvar->ssh_state.compressing) {
2080 buf_ensure_size(&pvar->ssh_state.outbuf,
2081 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2082 pvar->ssh_state.compress_stream.next_in =
2083 pvar->ssh_state.precompress_outbuf;
2084 pvar->ssh_state.compress_stream.avail_in = 9;
2085 pvar->ssh_state.compress_stream.next_out =
2086 pvar->ssh_state.outbuf + 12;
2087 pvar->ssh_state.compress_stream.avail_out =
2088 pvar->ssh_state.outbuflen - 12;
2089
2090 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2091 notify_fatal_error(pvar, "Error compressing packet data");
2092 return;
2093 }
2094
2095 pvar->ssh_state.compress_stream.next_in =
2096 (unsigned char FAR *) buf;
2097 pvar->ssh_state.compress_stream.avail_in = len;
2098
2099 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2100 Z_OK) {
2101 notify_fatal_error(pvar, "Error compressing packet data");
2102 return;
2103 }
2104 } else {
2105 memcpy(outmsg + 8, buf, len);
2106 }
2107
2108 finish_send_packet_special(pvar, 1);
2109 }
2110
2111 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2112 {
2113 unsigned char FAR *outmsg =
2114 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2115
2116 set_uint32(outmsg, remote_channel_num);
2117 finish_send_packet(pvar);
2118 }
2119
2120 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2121 uint32 local_channel_num)
2122 {
2123 unsigned char FAR *outmsg =
2124 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2125
2126 set_uint32(outmsg, remote_channel_num);
2127 set_uint32(outmsg + 4, local_channel_num);
2128 finish_send_packet(pvar);
2129 }
2130
2131 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2132 {
2133 unsigned char FAR *outmsg =
2134 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2135
2136 set_uint32(outmsg, remote_channel_num);
2137 finish_send_packet(pvar);
2138 }
2139
2140 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num)
2141 {
2142 unsigned char FAR *outmsg =
2143 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2144
2145 set_uint32(outmsg, remote_channel_num);
2146 finish_send_packet(pvar);
2147 }
2148
2149 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2150 char FAR * to_local_host, int to_local_port)
2151 {
2152 int host_len = strlen(to_local_host);
2153 unsigned char FAR *outmsg =
2154 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2155 12 + host_len);
2156
2157 set_uint32(outmsg, from_server_port);
2158 set_uint32(outmsg + 4, host_len);
2159 memcpy(outmsg + 8, to_local_host, host_len);
2160 set_uint32(outmsg + 8 + host_len, to_local_port);
2161 finish_send_packet(pvar);
2162
2163 enque_forwarding_request_handlers(pvar);
2164 }
2165
2166 void SSH_request_X11_forwarding(PTInstVar pvar,
2167 char FAR * auth_protocol,
2168 unsigned char FAR * auth_data,
2169 int auth_data_len, int screen_num)
2170 {
2171 int protocol_len = strlen(auth_protocol);
2172 int data_len = auth_data_len * 2;
2173 unsigned char FAR *outmsg =
2174 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING,
2175 12 + protocol_len + data_len);
2176 int i;
2177 char FAR *auth_data_ptr;
2178
2179 set_uint32(outmsg, protocol_len);
2180 memcpy(outmsg + 4, auth_protocol, protocol_len);
2181 set_uint32(outmsg + 4 + protocol_len, data_len);
2182 auth_data_ptr = outmsg + 8 + protocol_len;
2183 for (i = 0; i < auth_data_len; i++) {
2184 sprintf(auth_data_ptr + i * 2, "%.2x", auth_data[i]);
2185 }
2186 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
2187
2188 finish_send_packet(pvar);
2189
2190 enque_forwarding_request_handlers(pvar);
2191 }
2192
2193 void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
2194 char FAR * to_remote_host, int to_remote_port,
2195 char FAR * originator)
2196 {
2197 static const int msgs[]
2198 = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
2199 static const SSHPacketHandler handlers[]
2200 = { handle_channel_open_confirmation, handle_channel_open_failure };
2201
2202 int host_len = strlen(to_remote_host);
2203
2204 if ((pvar->ssh_state.
2205 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
2206 int originator_len = strlen(originator);
2207 unsigned char FAR *outmsg =
2208 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2209 16 + host_len + originator_len);
2210
2211 set_uint32(outmsg, local_channel_num);
2212 set_uint32(outmsg + 4, host_len);
2213 memcpy(outmsg + 8, to_remote_host, host_len);
2214 set_uint32(outmsg + 8 + host_len, to_remote_port);
2215 set_uint32(outmsg + 12 + host_len, originator_len);
2216 memcpy(outmsg + 16 + host_len, originator, originator_len);
2217 } else {
2218 unsigned char FAR *outmsg =
2219 begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2220 12 + host_len);
2221
2222 set_uint32(outmsg, local_channel_num);
2223 set_uint32(outmsg + 4, host_len);
2224 memcpy(outmsg + 8, to_remote_host, host_len);
2225 set_uint32(outmsg + 8 + host_len, to_remote_port);
2226 }
2227
2228 finish_send_packet(pvar);
2229
2230 enque_handlers(pvar, 2, msgs, handlers);
2231 }
2232
2233
2234 /////////////////////////////////////////////////////////////////////////////
2235 //
2236 // SSH2 protocol procedure in the following code:
2237 //
2238 /////////////////////////////////////////////////////////////////////////////
2239
2240 void debug_print(int no, char *msg, int len)
2241 {
2242 #ifdef _DEBUG
2243 FILE *fp;
2244 char file[128];
2245
2246 sprintf(file, "dump%d.bin", no);
2247
2248 fp = fopen(file, "wb");
2249 if (fp == NULL)
2250 return;
2251
2252 fwrite(msg, 1, len, fp);
2253
2254 fclose(fp);
2255 #endif
2256 }
2257
2258 // �N���C�A���g�����T�[�o������������
2259 #ifdef SSH2_DEBUG
2260 static char *myproposal[PROPOSAL_MAX] = {
2261 // "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2262 "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2263 // "ssh-rsa,ssh-dss",
2264 "ssh-dss,ssh-rsa",
2265 "3des-cbc,aes128-cbc",
2266 "3des-cbc,aes128-cbc",
2267 "hmac-sha1",
2268 // "hmac-sha1,hmac-md5",
2269 "hmac-sha1",
2270 // "hmac-sha1,hmac-md5",
2271 "none",
2272 "none",
2273 "",
2274 "",
2275 };
2276 #else
2277 static char *myproposal[PROPOSAL_MAX] = {
2278 "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2279 "ssh-rsa,ssh-dss",
2280 "3des-cbc,aes128-cbc",
2281 "3des-cbc,aes128-cbc",
2282 "hmac-sha1",
2283 "hmac-sha1",
2284 "none",
2285 "none",
2286 "",
2287 "",
2288 };
2289 #endif
2290
2291
2292 typedef struct ssh2_cipher {
2293 SSHCipher cipher;
2294 char *name;
2295 int block_size;
2296 int key_len;
2297 const EVP_CIPHER *(*func)(void);
2298 } ssh2_cipher_t;
2299
2300 ssh2_cipher_t ssh2_ciphers[] = {
2301 {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
2302 {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
2303 {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
2304 };
2305
2306
2307 typedef struct ssh2_mac {
2308 char *name;
2309 const EVP_MD *(*func)(void);
2310 int truncatebits;
2311 } ssh2_mac_t;
2312
2313 ssh2_mac_t ssh2_macs[] = {
2314 {"hmac-sha1", EVP_sha1, 0},
2315 {"hmac-md5", EVP_md5, 0},
2316 {NULL, NULL, 0},
2317 };
2318
2319 static Newkeys current_keys[MODE_MAX];
2320
2321
2322 #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
2323
2324
2325 static int get_cipher_block_size(SSHCipher cipher)
2326 {
2327 ssh2_cipher_t *ptr = ssh2_ciphers;
2328 int val = 0;
2329
2330 while (ptr->name != NULL) {
2331 if (cipher == ptr->cipher) {
2332 val = ptr->block_size;
2333 break;
2334 }
2335 ptr++;
2336 }
2337 return (val);
2338 }
2339
2340 static int get_cipher_key_len(SSHCipher cipher)
2341 {
2342 ssh2_cipher_t *ptr = ssh2_ciphers;
2343 int val = 0;
2344
2345 while (ptr->name != NULL) {
2346 if (cipher == ptr->cipher) {
2347 val = ptr->key_len;
2348 break;
2349 }
2350 ptr++;
2351 }
2352 return (val);
2353 }
2354
2355
2356 static int get_mac_index(char *name)
2357 {
2358 ssh2_mac_t *ptr = ssh2_macs;
2359 int val = -1;
2360
2361 while (ptr->name != NULL) {
2362 if (strcmp(ptr->name, name) == 0) {
2363 val = ptr - ssh2_macs;
2364 break;
2365 }
2366 ptr++;
2367 }
2368 return (val);
2369 }
2370
2371
2372 static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
2373 {
2374 FILE *fp;
2375 char filename[256];
2376
2377 _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
2378
2379 fp = fopen(filename, "wb");
2380 if (fp == NULL)
2381 return;
2382
2383 fwrite(buf, 1, len, fp);
2384
2385 fclose(fp);
2386 }
2387
2388
2389 void SSH2_packet_start(buffer_t *msg, unsigned char type)
2390 {
2391 unsigned char buf[9];
2392 int len = 6;
2393
2394 memset(buf, 0, sizeof(buf));
2395 buf[len - 1] = type;
2396 buffer_clear(msg);
2397 buffer_append(msg, buf, len);
2398 }
2399
2400
2401 // the caller is normalize_cipher_order()
2402 void SSH2_update_cipher_myproposal(PTInstVar pvar)
2403 {
2404 static char buf[128]; // TODO: malloc()��������
2405 int cipher;
2406 int len, i;
2407
2408 // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
2409 buf[0] = '\0';
2410 for (i = 0 ; pvar->ts_SSH->CipherOrder[i] != 0 ; i++) {
2411 cipher = pvar->ts_SSH->CipherOrder[i] - '0';
2412 if (cipher == 0) // disabled line
2413 break;
2414 if (cipher == SSH_CIPHER_AES128) {
2415 strcat(buf, "aes128-cbc,");
2416 }
2417 if (cipher == SSH_CIPHER_3DES_CBC) {
2418 strcat(buf, "3des-cbc,");
2419 }
2420 }
2421 if (buf[0] != '\0') {
2422 len = strlen(buf);
2423 buf[len - 1] = '\0'; // get rid of comma
2424 myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
2425 myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
2426 }
2427 }
2428
2429
2430 // �N���C�A���g�����T�[�o�����L�[�����J�n�v��
2431 void SSH2_send_kexinit(PTInstVar pvar)
2432 {
2433 char cookie[SSH2_COOKIE_LENGTH];
2434 buffer_t *msg;
2435 unsigned char *outmsg;
2436 int len, i;
2437
2438 msg = buffer_init();
2439 if (msg == NULL) {
2440 // TODO: error check
2441 return;
2442 }
2443 if (pvar->my_kex != NULL)
2444 buffer_free(pvar->my_kex);
2445 pvar->my_kex = msg;
2446
2447 // ���b�Z�[�W�^�C�v
2448 //SSH2_packet_start(msg, SSH2_MSG_KEXINIT);
2449
2450 // cookie���Z�b�g
2451 CRYPT_set_random_data(pvar, cookie, sizeof(cookie));
2452 CRYPT_set_server_cookie(pvar, cookie);
2453 buffer_append(msg, cookie, sizeof(cookie));
2454
2455 // �N���C�A���g���L�[����
2456 for (i = 0 ; i < PROPOSAL_MAX ; i++) {
2457 buffer_put_string(msg, myproposal[i], strlen(myproposal[i]));
2458 }
2459 buffer_put_char(msg, 0);
2460 buffer_put_int(msg, 0);
2461
2462 len = buffer_len(msg);
2463 outmsg = begin_send_packet(pvar, SSH2_MSG_KEXINIT, len);
2464 memcpy(outmsg, buffer_ptr(msg), len);
2465 finish_send_packet(pvar);
2466
2467 //buffer_free(msg);
2468 }
2469
2470
2471 static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
2472 {
2473 char tmp[1024], *ptr;
2474 SSHCipher cipher = SSH_CIPHER_NONE;
2475
2476 _snprintf(tmp, sizeof(tmp), my_proposal);
2477 ptr = strtok(tmp, ","); // not thread-safe
2478 while (ptr != NULL) {
2479 // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2480 if (strstr(server_proposal, ptr)) { // match
2481 break;
2482 }
2483 ptr = strtok(NULL, ",");
2484 }
2485 if (strstr(ptr, "3des-cbc")) {
2486 cipher = SSH_CIPHER_3DES_CBC;
2487
2488 } else if (strstr(ptr, "aes128-cbc")) {
2489 cipher = SSH_CIPHER_AES128;
2490 }
2491
2492 return (cipher);
2493 }
2494
2495
2496 // �����A���S���Y�����L�[�T�C�Y�A�u���b�N�T�C�Y�AMAC�T�C�Y�����������l(we_need)�����������B
2497 static void choose_SSH2_key_maxlength(PTInstVar pvar)
2498 {
2499 int mode, need, val, ctos;
2500 char *macname;
2501 const EVP_MD *md;
2502
2503 for (mode = 0; mode < MODE_MAX; mode++) {
2504 if (mode == MODE_OUT)
2505 ctos = 1;
2506 else
2507 ctos = 0;
2508 macname = myproposal[PROPOSAL_MAC_ALGS_CTOS + ctos];
2509 val = get_mac_index(macname);
2510 if (val == -1) {
2511 goto error;
2512 }
2513
2514 // current_keys[]�����������������A������ pvar->ssh2_keys[] ���R�s�[�����B
2515 md = ssh2_macs[val].func();
2516 current_keys[mode].mac.md = md;
2517 current_keys[mode].mac.key_len = current_keys[mode].mac.mac_len = EVP_MD_size(md);
2518 if (ssh2_macs[val].truncatebits != 0) {
2519 current_keys[mode].mac.mac_len = ssh2_macs[val].truncatebits / 8;
2520 }
2521
2522 // �L�[�T�C�Y���u���b�N�T�C�Y�������������������� (2004.11.7 yutaka)
2523 if (ctos == 1) {
2524 current_keys[mode].enc.key_len = get_cipher_key_len(pvar->ctos_cipher);
2525 current_keys[mode].enc.block_size = get_cipher_block_size(pvar->ctos_cipher);
2526 } else {
2527 current_keys[mode].enc.key_len = get_cipher_key_len(pvar->stoc_cipher);
2528 current_keys[mode].enc.block_size = get_cipher_block_size(pvar->stoc_cipher);
2529 }
2530 current_keys[mode].mac.enabled = 0;
2531
2532 // �����_����MAC��disable
2533 pvar->ssh2_keys[mode].mac.enabled = 0;
2534 }
2535 need = 0;
2536 for (mode = 0; mode < MODE_MAX; mode++) {
2537 if (mode == MODE_OUT)
2538 ctos = 1;
2539 else
2540 ctos = 0;
2541
2542 val = current_keys[mode].enc.key_len;
2543 if (need < val)
2544 need = val;
2545
2546 val = current_keys[mode].enc.block_size;
2547 if (need < val)
2548 need = val;
2549
2550 val = current_keys[mode].mac.key_len;
2551 if (need < val)
2552 need = val;
2553 }
2554 pvar->we_need = need;
2555
2556 error:;
2557 }
2558
2559
2560 // �L�[�����J�n�O���`�F�b�N (SSH2_MSG_KEXINIT)
2561 // �����Y�������f�[�^���M���������������������\������
2562 static BOOL handle_SSH2_kexinit(PTInstVar pvar)
2563 {
2564 char buf[1024];
2565 char *data;
2566 int len, i, size;
2567 int offset = 0;
2568 char *msg = NULL;
2569 char tmp[1024+512];
2570 char *ptr;
2571
2572 // �������L�[�������I�����������������������A�T�[�o���� SSH2_MSG_KEXINIT ��
2573 // �������������������A�L�[���������s���B(2004.10.24 yutaka)
2574 if (pvar->key_done == 1) {
2575 pvar->rekeying = 1;
2576 pvar->key_done = 0;
2577
2578 // �T�[�o��SSH2_MSG_KEXINIT ������
2579 SSH2_send_kexinit(pvar);
2580 }
2581
2582 if (pvar->peer_kex != NULL) { // already allocated
2583 buffer_free(pvar->peer_kex);
2584 }
2585 pvar->peer_kex = buffer_init();
2586 if (pvar->peer_kex == NULL) {
2587 msg = "Out of memory @ handle_SSH2_kexinit()";
2588 goto error;
2589 }
2590 // [-2]:padding size
2591 // len = pvar->ssh_state.payloadlen + pvar->ssh_state.payload[-2] + 1;
2592 len = pvar->ssh_state.payloadlen - 1;
2593 // buffer_append(pvar->peer_kex, &pvar->ssh_state.payload[-6], len);
2594 buffer_append(pvar->peer_kex, pvar->ssh_state.payload, len);
2595 //write_buffer_file(&pvar->ssh_state.payload[-6], len);
2596
2597 // TODO: buffer overrun check
2598
2599 // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
2600 data = pvar->ssh_state.payload;
2601 // �p�P�b�g�T�C�Y - (�p�f�B���O+1)�G�^���p�P�b�g�T�C�Y
2602 len = pvar->ssh_state.payloadlen;
2603
2604 //write_buffer_file(data, len);
2605
2606 if (offset + 20 >= len) {
2607 msg = "payload size too small @ handle_SSH2_kexinit()";
2608 goto error;
2609 }
2610
2611 #if 0
2612 for (i = 0; i < SSH2_COOKIE_LENGTH; i++) {
2613 cookie[i] = data[i];
2614 }
2615 #endif
2616 // get rid of Cookie length
2617 offset += SSH2_COOKIE_LENGTH;
2618
2619 // �L�[�����A���S���Y���`�F�b�N
2620 size = get_payload_uint32(pvar, offset);
2621 offset += 4;
2622 for (i = 0; i < size; i++) {
2623 buf[i] = data[offset + i];
2624 }
2625 buf[i] = '\0'; // null-terminate
2626 offset += size;
2627
2628 // KEX�������B��������myproposal[PROPOSAL_KEX_ALGS]���������������������B
2629 // �T�[�o���A�N���C�A���g���������������� myproposal[PROPOSAL_KEX_ALGS] ���J���}�������������A
2630 // �������������� myproposal[] �����r���s���A�������}�b�`����������KEX�A���S���Y��������
2631 // �I���������B(2004.10.30 yutaka)
2632 pvar->kex_type = -1;
2633 _snprintf(tmp, sizeof(tmp), myproposal[PROPOSAL_KEX_ALGS]);
2634 ptr = strtok(tmp, ","); // not thread-safe
2635 while (ptr != NULL) {
2636 // buf[]�����T�[�o��proposal���J���}���������i�[����������
2637 if (strstr(buf, ptr)) { // match
2638 break;
2639 }
2640 ptr = strtok(NULL, ",");
2641 }
2642 if (ptr == NULL) { // not match
2643 strcpy(tmp, "unknown KEX algorithm: ");
2644 strcat(tmp, buf);
2645 msg = tmp;
2646 goto error;
2647 }
2648 if (strstr(ptr, KEX_DH14)) {
2649 pvar->kex_type = KEX_DH_GRP14_SHA1;
2650 } else if (strstr(ptr, KEX_DH1)) {
2651 pvar->kex_type = KEX_DH_GRP1_SHA1;
2652 } else if (strstr(ptr, KEX_DHGEX)) {
2653 pvar->kex_type = KEX_DH_GEX_SHA1;
2654 }
2655
2656
2657 // �z�X�g�L�[�A���S���Y���`�F�b�N
2658 size = get_payload_uint32(pvar, offset);
2659 offset += 4;
2660 for (i = 0; i < size; i++) {
2661 buf[i] = data[offset + i];
2662 }
2663 buf[i] = 0;
2664 offset += size;
2665 pvar->hostkey_type = -1;
2666 _snprintf(tmp, sizeof(tmp), myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]);
2667 ptr = strtok(tmp, ","); // not thread-safe
2668 while (ptr != NULL) {
2669 // buf[]�����T�[�o��proposal���J���}���������i�[����������
2670 if (strstr(buf, ptr)) { // match
2671 break;
2672 }
2673 ptr = strtok(NULL, ",");
2674 }
2675 if (ptr == NULL) { // not match
2676 strcpy(tmp, "unknown host KEY type: ");
2677 strcat(tmp, buf);
2678 msg = tmp;
2679 goto error;
2680 }
2681 if (strstr(ptr, "ssh-rsa")) {
2682 pvar->hostkey_type = KEY_RSA;
2683 } else if (strstr(ptr, "ssh-dss")) {
2684 pvar->hostkey_type = KEY_DSA;
2685 } else if (strstr(ptr, "rsa1")) {
2686 pvar->hostkey_type = KEY_RSA1;
2687 } else if (strstr(ptr, "rsa")) {
2688 pvar->hostkey_type = KEY_RSA;
2689 } else if (strstr(ptr, "dsa")) {
2690 pvar->hostkey_type = KEY_DSA;
2691 }
2692 #if 0
2693 // TODO: ������ KEY_RSA �����T�|�[�g���������� (2004.10.24 yutaka)
2694 if (pvar->hostkey_type != KEY_RSA) {
2695 strcpy(tmp, "unknown KEY type: ");
2696 strcat(tmp, buf);
2697 msg = tmp;
2698 goto error;
2699 }
2700 #endif
2701
2702 // �N���C�A���g -> �T�[�o�����A���S���Y���`�F�b�N
2703 size = get_payload_uint32(pvar, offset);
2704 offset += 4;
2705 for (i = 0; i < size; i++) {
2706 buf[i] = data[offset + i];
2707 }
2708 buf[i] = 0;
2709 offset += size;
2710 pvar->ctos_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]);
2711 if (pvar->ctos_cipher == SSH_CIPHER_NONE) {
2712 strcpy(tmp, "unknown Encrypt algorithm(ctos): ");
2713 strcat(tmp, buf);
2714 msg = tmp;
2715 goto error;
2716 }
2717
2718 // �T�[�o -> �N���C�A���g�����A���S���Y���`�F�b�N
2719 size = get_payload_uint32(pvar, offset);
2720 offset += 4;
2721 for (i = 0; i < size; i++) {
2722 buf[i] = data[offset + i];
2723 }
2724 buf[i] = 0;
2725 offset += size;
2726 pvar->stoc_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]);
2727 if (pvar->stoc_cipher == SSH_CIPHER_NONE) {
2728 strcpy(tmp, "unknown Encrypt algorithm(stoc): ");
2729 strcat(tmp, buf);
2730 msg = tmp;
2731 goto error;
2732 }
2733
2734 // we_need������ (2004.11.6 yutaka)
2735 // �L�[���������������X�L�b�v�����B
2736 if (pvar->rekeying == 0) {
2737 choose_SSH2_key_maxlength(pvar);
2738 }
2739
2740 // send DH kex init
2741 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
2742 SSH2_dh_kex_init(pvar);
2743
2744 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
2745 SSH2_dh_kex_init(pvar);
2746
2747 } else if (pvar->kex_type == KEX_DH_GEX_SHA1) {
2748 SSH2_dh_gex_kex_init(pvar);
2749
2750 }
2751
2752 return TRUE;
2753
2754 error:;
2755 buffer_free(pvar->peer_kex);
2756
2757 notify_fatal_error(pvar, msg);
2758
2759 return FALSE;
2760 }
2761
2762
2763
2764 static DH *dh_new_group_asc(const char *gen, const char *modulus)
2765 {
2766 DH *dh = NULL;
2767
2768 if ((dh = DH_new()) == NULL) {
2769 printf("dh_new_group_asc: DH_new");
2770 goto error;
2771 }
2772
2773 // P��G�����J�����������f�����g��������
2774 if (BN_hex2bn(&dh->p, modulus) == 0) {
2775 printf("BN_hex2bn p");
2776 goto error;
2777 }
2778
2779 if (BN_hex2bn(&dh->g, gen) == 0) {
2780 printf("BN_hex2bn g");
2781 goto error;
2782 }
2783
2784 return (dh);
2785
2786 error:
2787 DH_free(dh);
2788 return (NULL);
2789 }
2790
2791
2792 static DH *dh_new_group1(void)
2793 {
2794 static char *gen = "2", *group1 =
2795 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
2796 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
2797 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
2798 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
2799 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
2800 "FFFFFFFF" "FFFFFFFF";
2801
2802 return (dh_new_group_asc(gen, group1));
2803 }
2804
2805
2806 static DH *dh_new_group14(void)
2807 {
2808 static char *gen = "2", *group14 =
2809 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
2810 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
2811 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
2812 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
2813 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
2814 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
2815 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
2816 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
2817 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
2818 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
2819 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
2820
2821 return (dh_new_group_asc(gen, group14));
2822 }
2823
2824
2825 // DH������������
2826 static void dh_gen_key(PTInstVar pvar, DH *dh, int we_need /* bytes */ )
2827 {
2828 int i;
2829
2830 dh->priv_key = NULL;
2831
2832 // ����������������(X)������
2833 for (i = 0 ; i < 10 ; i++) { // retry counter
2834 if (dh->priv_key != NULL) {
2835 BN_clear_free(dh->priv_key);
2836 }
2837 dh->priv_key = BN_new();
2838 if (dh->priv_key == NULL)
2839 goto error;
2840 if (BN_rand(dh->priv_key, 2*(we_need*8), 0, 0) == 0)
2841 goto error;
2842 if (DH_generate_key(dh) == 0)
2843 goto error;
2844 if (dh_pub_is_valid(dh, dh->pub_key))
2845 break;
2846 }
2847 if (i >= 10) {
2848 goto error;
2849 }
2850 return;
2851
2852 error:;
2853 notify_fatal_error(pvar, "error occurred @ dh_gen_key()");
2854
2855 }
2856
2857 //
2858 // KEX_DH_GRP1_SHA1 or KEX_DH_GRP14_SHA1
2859 //
2860 static void SSH2_dh_kex_init(PTInstVar pvar)
2861 {
2862 DH *dh = NULL;
2863 char *s, *t;
2864 buffer_t *msg = NULL;
2865 unsigned char *outmsg;
2866 int len;
2867
2868 // Diffie-Hellman key agreement
2869 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
2870 dh = dh_new_group1();
2871 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
2872 dh = dh_new_group14();
2873 } else {
2874 goto error;
2875 }
2876
2877 // ����������������(X)������
2878 dh_gen_key(pvar, dh, pvar->we_need);
2879
2880 s = BN_bn2hex(dh->priv_key);
2881 t = BN_bn2hex(dh->pub_key);
2882
2883
2884 msg = buffer_init();
2885 if (msg == NULL) {
2886 // TODO: error check
2887 return;
2888 }
2889
2890 buffer_put_bignum2(msg, dh->pub_key);
2891
2892 len = buffer_len(msg);
2893 outmsg = begin_send_packet(pvar, SSH2_MSG_KEXDH_INIT, len);
2894 memcpy(outmsg, buffer_ptr(msg), len);
2895 finish_send_packet(pvar);
2896
2897 if (pvar->kexdh != NULL) {
2898 DH_free(dh);
2899 }
2900 pvar->kexdh = dh;
2901
2902 SSH2_dispatch_init(2);
2903 SSH2_dispatch_add_message(SSH2_MSG_KEXDH_REPLY);
2904
2905 buffer_free(msg);
2906 return;
2907
2908 error:;
2909 DH_free(dh);
2910 buffer_free(msg);
2911
2912 notify_fatal_error(pvar, "error occurred @ SSH2_dh_kex_init()");
2913 }
2914
2915
2916
2917 //
2918 // KEX_DH_GEX_SHA1
2919 //
2920 // cf. Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol
2921 // (draft-ietf-secsh-dh-group-exchange-04.txt)
2922 //
2923
2924 static int dh_estimate(int bits)
2925 {
2926 if (bits <= 128)
2927 return (1024); /* O(2**86) */
2928 if (bits <= 192)
2929 return (2048); /* O(2**116) */
2930 return (4096); /* O(2**156) */
2931 }
2932
2933 static void SSH2_dh_gex_kex_init(PTInstVar pvar)
2934 {
2935 buffer_t *msg = NULL;
2936 unsigned char *outmsg;
2937 int len;
2938 int bits, min, max;
2939
2940 msg = buffer_init();
2941 if (msg == NULL) {
2942 goto error;
2943 }
2944
2945 // �T�[�o���������������������r�b�g�����������iwe_need���o�C�g�j�B
2946 bits = dh_estimate(pvar->we_need * 8);
2947 min = 1024;
2948 max = 8192;
2949
2950 // �T�[�o��group size���������Ap �� g ���������������B
2951 buffer_put_int(msg, min);
2952 buffer_put_int(msg, bits);
2953 buffer_put_int(msg, max);
2954 len = buffer_len(msg);
2955 outmsg = begin_send_packet(pvar, SSH2_MSG_KEX_DH_GEX_REQUEST, len);
2956 memcpy(outmsg, buffer_ptr(msg), len);
2957 finish_send_packet(pvar);
2958
2959 // �������n�b�V���v�Z���g�����������������B
2960 pvar->kexgex_min = min;
2961 pvar->kexgex_bits = bits;
2962 pvar->kexgex_max = max;
2963
2964 SSH2_dispatch_init(2);
2965 SSH2_dispatch_add_message(SSH2_MSG_KEX_DH_GEX_GROUP);
2966
2967 buffer_free(msg);
2968 return;
2969
2970 error:;
2971 buffer_free(msg);
2972
2973 notify_fatal_error(pvar, "error occurred @ SSH2_dh_gex_kex_init()");
2974 }
2975
2976
2977 // SSH2_MSG_KEX_DH_GEX_GROUP
2978 static BOOL handle_SSH2_dh_gex_group(PTInstVar pvar)
2979 {
2980 char *data;
2981 int len;
2982 BIGNUM *p = NULL, *g = NULL;
2983 DH *dh = NULL;
2984 buffer_t *msg = NULL;
2985 unsigned char *outmsg;
2986
2987 // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
2988 data = pvar->ssh_state.payload;
2989 // �p�P�b�g�T�C�Y - (�p�f�B���O�T�C�Y+1)�G�^���p�P�b�g�T�C�Y
2990 len = pvar->ssh_state.payloadlen;
2991
2992 p = BN_new();
2993 g = BN_new();
2994 if (p == NULL || g == NULL)
2995 goto error;
2996
2997 buffer_get_bignum2(&data, p); // �f��������
2998 buffer_get_bignum2(&data, g); // ������������
2999
3000 dh = DH_new();
3001 if (dh == NULL)
3002 goto error;
3003 dh->p = p;
3004 dh->g = g;
3005
3006 // ����������������(X)������
3007 dh_gen_key(pvar, dh, pvar->we_need);
3008
3009 // ���J�����T�[�o�����M
3010 msg = buffer_init();
3011 if (msg == NULL) {
3012 goto error;
3013 }
3014 buffer_put_bignum2(msg, dh->pub_key);
3015 len = buffer_len(msg);
3016 outmsg = begin_send_packet(pvar, SSH2_MSG_KEX_DH_GEX_INIT, len);
3017 memcpy(outmsg, buffer_ptr(msg), len);
3018 finish_send_packet(pvar);
3019
3020 // ��������������DH�����A�������n�b�V���v�Z���g�����������������B(2004.10.31 yutaka)
3021 pvar->kexdh = dh;
3022
3023 SSH2_dispatch_init(2);
3024 SSH2_dispatch_add_message(SSH2_MSG_KEX_DH_GEX_REPLY);
3025
3026 buffer_free(msg);
3027
3028 return TRUE;
3029
3030 error:;
3031 BN_free(p);
3032 BN_free(g);
3033 DH_free(dh);
3034
3035 return FALSE;
3036 }
3037
3038
3039
3040 // SHA-1(160bit)��������
3041 unsigned char *kex_dh_hash(
3042 char *client_version_string,
3043 char *server_version_string,
3044 char *ckexinit, int ckexinitlen,
3045 char *skexinit, int skexinitlen,
3046 u_char *serverhostkeyblob, int sbloblen,
3047 BIGNUM *client_dh_pub,
3048 BIGNUM *server_dh_pub,
3049 BIGNUM *shared_secret)
3050 {
3051 buffer_t *b;
3052 static unsigned char digest[EVP_MAX_MD_SIZE];
3053 const EVP_MD *evp_md = EVP_sha1();
3054 EVP_MD_CTX md;
3055
3056 b = buffer_init();
3057 buffer_put_string(b, client_version_string, strlen(client_version_string));
3058 buffer_put_string(b, server_version_string, strlen(server_version_string));
3059
3060 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
3061 buffer_put_int(b, ckexinitlen+1);
3062 buffer_put_char(b, SSH2_MSG_KEXINIT);
3063 buffer_append(b, ckexinit, ckexinitlen);
3064 buffer_put_int(b, skexinitlen+1);
3065 buffer_put_char(b, SSH2_MSG_KEXINIT);
3066 buffer_append(b, skexinit, skexinitlen);
3067
3068 buffer_put_string(b, serverhostkeyblob, sbloblen);
3069 buffer_put_bignum2(b, client_dh_pub);
3070 buffer_put_bignum2(b, server_dh_pub);
3071 buffer_put_bignum2(b, shared_secret);
3072
3073 // yutaka
3074 //debug_print(38, buffer_ptr(b), buffer_len(b));
3075
3076 EVP_DigestInit(&md, evp_md);
3077 EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
3078 EVP_DigestFinal(&md, digest, NULL);
3079
3080 buffer_free(b);
3081
3082 //write_buffer_file(digest, EVP_MD_size(evp_md));
3083
3084 return digest;
3085 }
3086
3087
3088 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
3089 {
3090 int i;
3091 int n = BN_num_bits(dh_pub);
3092 int bits_set = 0;
3093
3094 if (dh_pub->neg) {
3095 //logit("invalid public DH value: negativ");
3096 return 0;
3097 }
3098 for (i = 0; i <= n; i++)
3099 if (BN_is_bit_set(dh_pub, i))
3100 bits_set++;
3101 //debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
3102
3103 /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
3104 if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
3105 return 1;
3106 //logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
3107 return 0;
3108 }
3109
3110
3111 static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret, char *session_id, int session_id_len)
3112 {
3113 buffer_t *b;
3114 const EVP_MD *evp_md = EVP_sha1();
3115 EVP_MD_CTX md;
3116 char c = id;
3117 int have;
3118 int mdsz = EVP_MD_size(evp_md); // 20bytes(160bit)
3119 u_char *digest = malloc(roundup(need, mdsz));
3120
3121 if (digest == NULL)
3122 goto skip;
3123
3124 b = buffer_init();
3125 if (b == NULL)
3126 goto skip;
3127
3128 buffer_put_bignum2(b, shared_secret);
3129
3130 /* K1 = HASH(K || H || "A" || session_id) */
3131 EVP_DigestInit(&md, evp_md);
3132 EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
3133 EVP_DigestUpdate(&md, hash, mdsz);
3134 EVP_DigestUpdate(&md, &c, 1);
3135 EVP_DigestUpdate(&md, session_id, session_id_len);
3136 EVP_DigestFinal(&md, digest, NULL);
3137
3138 /*
3139 * expand key:
3140 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
3141 * Key = K1 || K2 || ... || Kn
3142 */
3143 for (have = mdsz; need > have; have += mdsz) {
3144 EVP_DigestInit(&md, evp_md);
3145 EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
3146 EVP_DigestUpdate(&md, hash, mdsz);
3147 EVP_DigestUpdate(&md, digest, have);
3148 EVP_DigestFinal(&md, digest + have, NULL);
3149 }
3150 buffer_free(b);
3151
3152 skip:;
3153 return digest;
3154 }
3155
3156
3157 static void ssh2_set_newkeys(PTInstVar pvar, int mode)
3158 {
3159 // free already allocated buffer
3160 if (pvar->ssh2_keys[mode].enc.iv != NULL)
3161 free(pvar->ssh2_keys[mode].enc.iv);
3162 if (pvar->ssh2_keys[mode].enc.key != NULL)
3163 free(pvar->ssh2_keys[mode].enc.key);
3164 if (pvar->ssh2_keys[mode].mac.key != NULL)
3165 free(pvar->ssh2_keys[mode].mac.key);
3166
3167 pvar->ssh2_keys[mode] = current_keys[mode];
3168 }
3169
3170
3171 void kex_derive_keys(PTInstVar pvar, int need, u_char *hash, BIGNUM *shared_secret, char *session_id, int session_id_len)
3172 {
3173 #define NKEYS 6
3174 u_char *keys[NKEYS];
3175 int i, mode, ctos;
3176
3177 for (i = 0; i < NKEYS; i++) {
3178 keys[i] = derive_key('A'+i, need, hash, shared_secret, session_id, session_id_len);
3179 //debug_print(i, keys[i], need);
3180 }
3181
3182 for (mode = 0; mode < MODE_MAX; mode++) {
3183 if (mode == MODE_OUT)
3184 ctos = 1;
3185 else
3186 ctos = 0;
3187
3188 // setting
3189 current_keys[mode].enc.iv = keys[ctos ? 0 : 1];
3190 current_keys[mode].enc.key = keys[ctos ? 2 : 3];
3191 current_keys[mode].mac.key = keys[ctos ? 4 : 5];
3192
3193 //debug_print(20 + mode*3, current_keys[mode]->enc.iv, 8);
3194 //debug_print(21 + mode*3, current_keys[mode]->enc.key, 24);
3195 //debug_print(22 + mode*3, current_keys[mode]->mac.key, 24);
3196 }
3197 }
3198
3199
3200
3201 /*
3202 * See:
3203 * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
3204 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
3205 */
3206 /*
3207 * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
3208 * oiw(14) secsig(3) algorithms(2) 26 }
3209 */
3210 static const u_char id_sha1[] = {
3211 0x30, 0x21, /* type Sequence, length 0x21 (33) */
3212 0x30, 0x09, /* type Sequence, length 0x09 */
3213 0x06, 0x05, /* type OID, length 0x05 */
3214 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
3215 0x05, 0x00, /* NULL */
3216 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
3217 };
3218 /*
3219 * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
3220 * rsadsi(113549) digestAlgorithm(2) 5 }
3221 */
3222 static const u_char id_md5[] = {
3223 0x30, 0x20, /* type Sequence, length 0x20 (32) */
3224 0x30, 0x0c, /* type Sequence, length 0x09 */
3225 0x06, 0x08, /* type OID, length 0x05 */
3226 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
3227 0x05, 0x00, /* NULL */
3228 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
3229 };
3230
3231 static int
3232 openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
3233 u_char *sigbuf, u_int siglen, RSA *rsa)
3234 {
3235 u_int ret, rsasize, oidlen = 0, hlen = 0;
3236 int len;
3237 const u_char *oid = NULL;
3238 u_char *decrypted = NULL;
3239