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 2768 - (show annotations) (download) (as text)
Mon Dec 27 14:22:16 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 128469 byte(s)
メモリリークを修正。

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