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 2771 - (show annotations) (download) (as text)
Tue Jan 4 13:57:01 2005 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 129314 byte(s)
SSH2ターミナルサイズ変更通知の追加

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