Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2748 - (hide annotations) (download) (as text)
Sat Dec 11 07:31:00 2004 UTC (19 years, 4 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 117218 byte(s)
SSH heartbeatスレッドの追加した。これにより、IPマスカレード環境において、ルータの
NATテーブルクリアにより、SSHコネクションが切断される現象が回避される。
それに合わせて、teraterm.iniのTTSSHセクションに、HeartBeat エントリを追加。

1 yutakakn 2728 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3     All rights reserved.
4    
5     Redistribution and use in source and binary forms, with or without modification,
6     are permitted provided that the following conditions are met:
7    
8     Redistributions of source code must retain the above copyright notice, this list of
9     conditions and the following disclaimer.
10    
11     Redistributions in binary form must reproduce the above copyright notice, this list
12     of conditions and the following disclaimer in the documentation and/or other materials
13     provided with the distribution.
14    
15     The name of Robert O'Callahan may not be used to endorse or promote products derived from
16     this software without specific prior written permission.
17    
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21     THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     #include "ttxssh.h"
30     #include "util.h"
31    
32     #include <openssl/bn.h>
33     #include <openssl/evp.h>
34     #include <openssl/dh.h>
35     #include <openssl/engine.h>
36     #include <limits.h>
37     #include <malloc.h>
38     #include <string.h>
39     #include <stdlib.h>
40 yutakakn 2748 #include <process.h>
41 yutakakn 2728 #include "buffer.h"
42     #include "ssh.h"
43     #include "crypt.h"
44    
45     #ifdef _DEBUG
46     #define SSH2_DEBUG
47     #endif
48    
49     static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
50    
51     static void try_send_credentials(PTInstVar pvar);
52     static void prep_compression(PTInstVar pvar);
53    
54     // �����v���g�^�C�v����
55     void SSH2_send_kexinit(PTInstVar pvar);
56     static BOOL handle_SSH2_kexinit(PTInstVar pvar);
57     static void SSH2_dh_kex_init(PTInstVar pvar);
58     static void SSH2_dh_gex_kex_init(PTInstVar pvar);
59     static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
60     static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
61     static BOOL handle_SSH2_newkeys(PTInstVar pvar);
62     static BOOL handle_SSH2_authrequest(PTInstVar pvar);
63     static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
64     static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
65     static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
66     static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
67     static BOOL handle_SSH2_request_success(PTInstVar pvar);
68     static BOOL handle_SSH2_channel_success(PTInstVar pvar);
69     static BOOL handle_SSH2_channel_data(PTInstVar pvar);
70     static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
71     static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
72     static BOOL handle_SSH2_channel_close(PTInstVar pvar);
73     static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
74     static BOOL handle_SSH2_channel_request(PTInstVar pvar);
75     void SSH2_dispatch_init(int stage);
76     int SSH2_dispatch_enabled_check(unsigned char message);
77     void SSH2_dispatch_add_message(unsigned char message);
78     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
79     int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
80 yutakakn 2748 static void start_ssh_heartbeat_thread(PTInstVar pvar);
81 yutakakn 2728
82    
83 yutakakn 2748 //
84     // SSH heartbeat mutex
85     //
86     static CRITICAL_SECTION g_ssh_heartbeat_lock; /* ���b�N�p���� */
87    
88     void ssh_heartbeat_lock_initialize(void)
89     {
90     InitializeCriticalSection(&g_ssh_heartbeat_lock);
91     }
92    
93     void ssh_heartbeat_lock(void)
94     {
95     EnterCriticalSection(&g_ssh_heartbeat_lock);
96     }
97    
98     void ssh_heartbeat_unlock(void)
99     {
100     LeaveCriticalSection(&g_ssh_heartbeat_lock);
101     }
102    
103    
104 yutakakn 2728 static int get_predecryption_amount(PTInstVar pvar)
105     {
106     static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
107    
108     if (SSHv1(pvar)) {
109     return 0;
110     } else {
111     int block_size = CRYPT_get_decryption_block_size(pvar);
112    
113     if (block_size < 5) {
114     return small_block_decryption_sizes[block_size];
115     } else {
116     return block_size;
117     }
118     }
119     }
120    
121     /* Get up to 'limit' bytes into the payload buffer.
122     'limit' is counted from the start of the payload data.
123     Returns the amount of data in the payload buffer, or
124     -1 if there is an error.
125     We can return more than limit in some cases. */
126     static int buffer_packet_data(PTInstVar pvar, int limit)
127     {
128     if (pvar->ssh_state.payloadlen >= 0) {
129     return pvar->ssh_state.payloadlen;
130     } else {
131     int cur_decompressed_bytes =
132     pvar->ssh_state.decompress_stream.next_out -
133     pvar->ssh_state.postdecompress_inbuf;
134    
135     while (limit > cur_decompressed_bytes) {
136     int result;
137    
138     pvar->ssh_state.payload =
139     pvar->ssh_state.postdecompress_inbuf + 1;
140     if (pvar->ssh_state.postdecompress_inbuflen ==
141     cur_decompressed_bytes) {
142     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
143     &pvar->ssh_state.postdecompress_inbuflen,
144     min(limit, cur_decompressed_bytes * 2));
145     }
146    
147     pvar->ssh_state.decompress_stream.next_out
148     =
149     pvar->ssh_state.postdecompress_inbuf +
150     cur_decompressed_bytes;
151     pvar->ssh_state.decompress_stream.avail_out =
152     min(limit, pvar->ssh_state.postdecompress_inbuflen)
153     - cur_decompressed_bytes;
154    
155     result =
156     inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
157     cur_decompressed_bytes =
158     pvar->ssh_state.decompress_stream.next_out -
159     pvar->ssh_state.postdecompress_inbuf;
160    
161     switch (result) {
162     case Z_OK:
163     break;
164     case Z_BUF_ERROR:
165     pvar->ssh_state.payloadlen = cur_decompressed_bytes;
166     return cur_decompressed_bytes;
167     default:
168     notify_fatal_error(pvar,
169     "Invalid compressed data in received packet");
170     return -1;
171     }
172     }
173    
174     return cur_decompressed_bytes;
175     }
176     }
177    
178     /* For use by the protocol processing code.
179     Gets N bytes of uncompressed payload. Returns FALSE if data not available
180     and a fatal error has been signaled.
181     The data is available in the payload buffer. This buffer address
182     can change during a call to grab_payload, so take care!
183     The payload pointer is set to point to the first byte of the actual data
184     (after the packet type byte).
185     */
186     static BOOL grab_payload(PTInstVar pvar, int num_bytes)
187     {
188     /* Accept maximum of 4MB of payload data */
189     int in_buffer = buffer_packet_data(pvar, 4 * 1024 * 1024);
190    
191     if (in_buffer < 0) {
192     return FALSE;
193     } else {
194     pvar->ssh_state.payload_grabbed += num_bytes;
195     if (pvar->ssh_state.payload_grabbed > in_buffer) {
196     notify_fatal_error(pvar, "Received truncated packet");
197     return FALSE;
198     } else {
199     return TRUE;
200     }
201     }
202     }
203    
204     static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
205     {
206     int in_buffer;
207    
208     pvar->ssh_state.payload_grabbed += num_bytes;
209     in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
210    
211     if (in_buffer < 0) {
212     return FALSE;
213     } else {
214     if (pvar->ssh_state.payload_grabbed > in_buffer) {
215     notify_fatal_error(pvar, "Received truncated packet");
216     return FALSE;
217     } else {
218     return TRUE;
219     }
220     }
221     }
222    
223     #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
224     #define get_uint32(buf) get_uint32_MSBfirst((buf))
225     #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
226     #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
227     #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
228    
229     #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
230    
231     /* Decrypt the payload, checksum it, eat the padding, get the packet type
232     and return it.
233     'data' points to the start of the packet --- its length field.
234     'len' is the length of the
235     payload + padding (+ length of CRC for SSHv1). 'padding' is the length
236     of the padding alone. */
237     static int prep_packet(PTInstVar pvar, char FAR * data, int len,
238     int padding)
239     {
240     pvar->ssh_state.payload = data + 4;
241     pvar->ssh_state.payloadlen = len;
242    
243     if (SSHv1(pvar)) {
244     if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
245     notify_fatal_error(pvar,
246     "'CORE insertion attack' detected. Aborting connection.");
247     return SSH_MSG_NONE;
248     }
249    
250     CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
251     /* PKT guarantees that the data is always 4-byte aligned */
252     if (do_crc(pvar->ssh_state.payload, len - 4) !=
253     get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
254     notify_fatal_error(pvar,
255     "Detected corrupted data; connection terminating.");
256     return SSH_MSG_NONE;
257     }
258    
259     pvar->ssh_state.payload += padding;
260     pvar->ssh_state.payloadlen -= padding + 4;
261     } else {
262     int already_decrypted = get_predecryption_amount(pvar);
263    
264     #if 0
265     CRYPT_decrypt(pvar, data + already_decrypted,
266     len - already_decrypted);
267     #else
268     CRYPT_decrypt(pvar, data + already_decrypted,
269     (4 + len) - already_decrypted);
270     #endif
271    
272     if (!CRYPT_verify_receiver_MAC
273     (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
274     data + len + 4)) {
275     notify_fatal_error(pvar,
276     "Detected corrupted data; connection terminating.");
277     return SSH_MSG_NONE;
278     }
279    
280     pvar->ssh_state.payload++;
281     pvar->ssh_state.payloadlen -= padding + 1;
282     }
283    
284     pvar->ssh_state.payload_grabbed = 0;
285    
286     if (pvar->ssh_state.decompressing) {
287     if (pvar->ssh_state.decompress_stream.avail_in != 0) {
288     notify_nonfatal_error(pvar,
289     "Internal error: a packet was not fully decompressed.\n"
290     "This is a bug, please report it.");
291     }
292    
293     pvar->ssh_state.decompress_stream.next_in =
294     pvar->ssh_state.payload;
295     pvar->ssh_state.decompress_stream.avail_in =
296     pvar->ssh_state.payloadlen;
297     pvar->ssh_state.decompress_stream.next_out =
298     pvar->ssh_state.postdecompress_inbuf;
299     pvar->ssh_state.payloadlen = -1;
300     } else {
301     pvar->ssh_state.payload++;
302     }
303    
304     if (!grab_payload_limited(pvar, 1)) {
305     return SSH_MSG_NONE;
306     }
307    
308     pvar->ssh_state.receiver_sequence_number++;
309    
310     return pvar->ssh_state.payload[-1];
311     }
312    
313     /* Create a packet to be sent. The SSH protocol packet type is in 'type';
314     'len' contains the length of the packet payload, in bytes (this
315     does not include the space for any of the packet headers or padding,
316     or for the packet type byte).
317     Returns a pointer to the payload data area, a region of length 'len',
318     to be filled by the caller. */
319     static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type,
320     int len)
321     {
322     unsigned char FAR *buf;
323    
324     pvar->ssh_state.outgoing_packet_len = len + 1;
325    
326     if (pvar->ssh_state.compressing) {
327     buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
328     &pvar->ssh_state.precompress_outbuflen, 1 + len);
329     buf = pvar->ssh_state.precompress_outbuf;
330     } else {
331     /* For SSHv2,
332     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
333     + len(payload) + 4(minpadding), rounded up to nearest block_size
334     We only need a reasonable upper bound for the buffer size */
335     buf_ensure_size(&pvar->ssh_state.outbuf,
336     &pvar->ssh_state.outbuflen,
337     len + 30 + CRYPT_get_sender_MAC_size(pvar) +
338     CRYPT_get_encryption_block_size(pvar));
339     buf = pvar->ssh_state.outbuf + 12;
340     }
341    
342     buf[0] = (unsigned char) type;
343     return buf + 1;
344     }
345    
346     #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
347    
348     static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
349     {
350     u_long do_block = 0;
351    
352     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
353     0, 0) == SOCKET_ERROR
354     || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
355     || (pvar->Psend) (pvar->socket, data, len, 0) != len
356     || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
357     pvar->notification_msg,
358     pvar->notification_events) ==
359     SOCKET_ERROR) {
360     notify_fatal_error(pvar,
361     "A communications error occurred while sending an SSH packet.\n"
362     "The connection will close.");
363     return FALSE;
364     } else {
365     return TRUE;
366     }
367     }
368    
369     /* if skip_compress is true, then the data has already been compressed
370     into outbuf + 12 */
371     static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
372     {
373     int len = pvar->ssh_state.outgoing_packet_len;
374     char FAR *data;
375     int data_length;
376    
377     if (pvar->ssh_state.compressing) {
378     if (!skip_compress) {
379     buf_ensure_size(&pvar->ssh_state.outbuf,
380     &pvar->ssh_state.outbuflen,
381     len + (len >> 6) + 50 +
382     CRYPT_get_sender_MAC_size(pvar));
383     pvar->ssh_state.compress_stream.next_in =
384     pvar->ssh_state.precompress_outbuf;
385     pvar->ssh_state.compress_stream.avail_in = len;
386     pvar->ssh_state.compress_stream.next_out =
387     pvar->ssh_state.outbuf + 12;
388     pvar->ssh_state.compress_stream.avail_out =
389     pvar->ssh_state.outbuflen - 12;
390    
391     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
392     Z_OK) {
393     notify_fatal_error(pvar,
394     "An error occurred while compressing packet data.\n"
395     "The connection will close.");
396     return;
397     }
398     }
399    
400     len =
401     pvar->ssh_state.outbuflen - 12 -
402     pvar->ssh_state.compress_stream.avail_out;
403     }
404    
405     if (SSHv1(pvar)) {
406     int padding = 8 - ((len + 4) % 8);
407    
408     data = pvar->ssh_state.outbuf + 8 - padding;
409     data_length = padding + len + 8;
410    
411     set_uint32(data, len + 4);
412     if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
413     CRYPT_set_random_data(pvar, data + 4, padding);
414     } else {
415     memset(data + 4, 0, padding);
416     }
417     set_uint32(data + data_length - 4,
418     do_crc(data + 4, data_length - 8));
419     CRYPT_encrypt(pvar, data + 4, data_length - 4);
420     } else { //for SSH2(yutaka)
421     int block_size = CRYPT_get_encryption_block_size(pvar);
422     int encryption_size;
423     int padding;
424     BOOL ret;
425    
426     if (block_size < 8) {
427     block_size = 8;
428     }
429     encryption_size = ((len + 8) / block_size + 1) * block_size;
430     data = pvar->ssh_state.outbuf + 7;
431     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
432    
433     set_uint32(data, encryption_size - 4);
434     padding = encryption_size - len - 5;
435     data[4] = (unsigned char) padding;
436     CRYPT_set_random_data(pvar, data + 5 + len, padding);
437     ret = CRYPT_build_sender_MAC(pvar,
438     pvar->ssh_state.sender_sequence_number,
439     data, encryption_size,
440     data + encryption_size);
441     if (ret == FALSE) { // HMAC��������������������������
442     data_length = encryption_size;
443     }
444    
445     // �p�P�b�g�������������BHMAC���~�������������O�B
446     CRYPT_encrypt(pvar, data, encryption_size);
447     }
448    
449     send_packet_blocking(pvar, data, data_length);
450    
451     pvar->ssh_state.sender_sequence_number++;
452 yutakakn 2748
453     // ���M�������L�^
454     pvar->ssh_heartbeat_tick = time(NULL);
455 yutakakn 2728 }
456    
457     static void destroy_packet_buf(PTInstVar pvar)
458     {
459     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
460     if (pvar->ssh_state.compressing) {
461     memset(pvar->ssh_state.precompress_outbuf, 0,
462     pvar->ssh_state.precompress_outbuflen);
463     }
464     }
465    
466     /* The handlers are added to the queue for each message. When one of the
467     handlers fires, if it returns FALSE, then all handlers in the set are
468     removed from their queues. */
469     static void enque_handlers(PTInstVar pvar, int num_msgs,
470     const int FAR * messages,
471     const SSHPacketHandler FAR * handlers)
472     {
473     SSHPacketHandlerItem FAR *first_item;
474     SSHPacketHandlerItem FAR *last_item = NULL;
475     int i;
476    
477     for (i = 0; i < num_msgs; i++) {
478     SSHPacketHandlerItem FAR *item =
479     (SSHPacketHandlerItem FAR *)
480     malloc(sizeof(SSHPacketHandlerItem));
481     SSHPacketHandlerItem FAR *cur_item =
482     pvar->ssh_state.packet_handlers[messages[i]];
483    
484     item->handler = handlers[i];
485    
486     if (cur_item == NULL) {
487     pvar->ssh_state.packet_handlers[messages[i]] = item;
488     item->next_for_message = item;
489     item->last_for_message = item;
490     item->active_for_message = messages[i];
491     } else {
492     item->next_for_message = cur_item;
493     item->last_for_message = cur_item->last_for_message;
494     cur_item->last_for_message->next_for_message = item;
495     cur_item->last_for_message = item;
496     item->active_for_message = -1;
497     }
498    
499     if (last_item != NULL) {
500     last_item->next_in_set = item;
501     } else {
502     first_item = item;
503     }
504     last_item = item;
505     }
506    
507     if (last_item != NULL) {
508     last_item->next_in_set = first_item;
509     }
510     }
511    
512     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
513     {
514     SSHPacketHandlerItem FAR *cur_item =
515     pvar->ssh_state.packet_handlers[message];
516    
517     if (cur_item == NULL) {
518     return NULL;
519     } else {
520     return cur_item->handler;
521     }
522     }
523    
524     /* Called only by SSH_handle_packet */
525     static void deque_handlers(PTInstVar pvar, int message)
526     {
527     SSHPacketHandlerItem FAR *cur_item =
528     pvar->ssh_state.packet_handlers[message];
529     SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
530    
531     do {
532     SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
533    
534     if (cur_item->active_for_message >= 0) {
535     SSHPacketHandlerItem FAR *replacement =
536     cur_item->next_for_message;
537    
538     if (replacement == cur_item) {
539     replacement = NULL;
540     } else {
541     replacement->active_for_message =
542     cur_item->active_for_message;
543     }
544     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
545     replacement;
546     }
547     cur_item->next_for_message->last_for_message =
548     cur_item->last_for_message;
549     cur_item->last_for_message->next_for_message =
550     cur_item->next_for_message;
551    
552     free(cur_item);
553     cur_item = next_in_set;
554     } while (cur_item != first_item_in_set);
555     }
556    
557     static void enque_handler(PTInstVar pvar, int message,
558     SSHPacketHandler handler)
559     {
560     enque_handlers(pvar, 1, &message, &handler);
561     }
562    
563     static void chop_newlines(char FAR * buf)
564     {
565     int len = strlen(buf);
566    
567     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
568     buf[len - 1] = 0;
569     len--;
570     }
571     }
572    
573     /********************/
574     /* Message handlers */
575     /********************/
576    
577     static BOOL handle_forwarding_success(PTInstVar pvar)
578     {
579     return FALSE;
580     }
581    
582     static BOOL handle_forwarding_failure(PTInstVar pvar)
583     {
584     return FALSE;
585     }
586    
587     static void enque_forwarding_request_handlers(PTInstVar pvar)
588     {
589     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
590     static const SSHPacketHandler handlers[]
591     = { handle_forwarding_success, handle_forwarding_failure };
592    
593     enque_handlers(pvar, 2, msgs, handlers);
594     }
595    
596     static BOOL handle_auth_failure(PTInstVar pvar)
597     {
598     notify_verbose_message(pvar, "Authentication failed",
599     LOG_LEVEL_VERBOSE);
600    
601     AUTH_set_generic_mode(pvar);
602     AUTH_advance_to_next_cred(pvar);
603     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
604     try_send_credentials(pvar);
605     return FALSE;
606     }
607    
608     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
609     {
610     AUTH_destroy_cur_cred(pvar);
611     return handle_auth_failure(pvar);
612     }
613    
614     static BOOL handle_TIS_challenge(PTInstVar pvar)
615     {
616     if (grab_payload(pvar, 4)) {
617     int len = get_payload_uint32(pvar, 0);
618    
619     if (grab_payload(pvar, len)) {
620     notify_verbose_message(pvar, "Received TIS challenge",
621     LOG_LEVEL_VERBOSE);
622    
623     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
624     AUTH_advance_to_next_cred(pvar);
625     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
626     try_send_credentials(pvar);
627     }
628     }
629     return FALSE;
630     }
631    
632     static BOOL handle_auth_required(PTInstVar pvar)
633     {
634     notify_verbose_message(pvar, "Server requires authentication",
635     LOG_LEVEL_VERBOSE);
636    
637     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
638     try_send_credentials(pvar);
639     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
640    
641     return FALSE;
642     }
643    
644     static BOOL handle_ignore(PTInstVar pvar)
645     {
646     if (grab_payload(pvar, 4)
647     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
648     /* ignore it! but it must be decompressed */
649     }
650     return TRUE;
651     }
652    
653     static BOOL handle_debug(PTInstVar pvar)
654     {
655     BOOL always_display;
656     char FAR *description;
657     int description_len;
658     char buf[2048];
659    
660     if (SSHv1(pvar)) {
661     if (grab_payload(pvar, 4)
662     && grab_payload(pvar, description_len =
663     get_payload_uint32(pvar, 0))) {
664     always_display = FALSE;
665     description = pvar->ssh_state.payload + 4;
666     description[description_len] = 0;
667     } else {
668     return TRUE;
669     }
670     } else {
671     if (grab_payload(pvar, 5)
672     && grab_payload(pvar,
673     (description_len =
674     get_payload_uint32(pvar, 1)) + 4)
675     && grab_payload(pvar,
676     get_payload_uint32(pvar,
677     5 + description_len))) {
678     always_display = pvar->ssh_state.payload[0] != 0;
679     description = pvar->ssh_state.payload + 5;
680     description[description_len] = 0;
681     } else {
682     return TRUE;
683     }
684     }
685    
686     chop_newlines(description);
687     _snprintf(buf, sizeof(buf), "DEBUG message from server: %s",
688     description);
689     buf[sizeof(buf) - 1] = 0;
690     if (always_display) {
691     notify_nonfatal_error(pvar, buf);
692     } else {
693     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
694     }
695     return TRUE;
696     }
697    
698     static BOOL handle_disconnect(PTInstVar pvar)
699     {
700     int reason_code;
701     char FAR *description;
702     int description_len;
703     char buf[2048];
704     char FAR *explanation = "";
705    
706     if (SSHv1(pvar)) {
707     if (grab_payload(pvar, 4)
708     && grab_payload(pvar, description_len =
709     get_payload_uint32(pvar, 0))) {
710     reason_code = -1;
711     description = pvar->ssh_state.payload + 4;
712     description[description_len] = 0;
713     } else {
714     return TRUE;
715     }
716     } else {
717     if (grab_payload(pvar, 8)
718     && grab_payload(pvar,
719     (description_len =
720     get_payload_uint32(pvar, 4)) + 4)
721     && grab_payload(pvar,
722     get_payload_uint32(pvar,
723     8 + description_len))) {
724     reason_code = get_payload_uint32(pvar, 0);
725     description = pvar->ssh_state.payload + 8;
726     description[description_len] = 0;
727     } else {
728     return TRUE;
729     }
730     }
731    
732     chop_newlines(description);
733     if (description[0] == 0) {
734     description = NULL;
735     }
736    
737     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
738     explanation =
739     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
740     "This often happens when someone is already forwarding that port from the server.";
741     }
742    
743     if (description != NULL) {
744     _snprintf(buf, sizeof(buf),
745     "Server disconnected with message '%s'.%s", description,
746     explanation);
747     } else {
748     _snprintf(buf, sizeof(buf),
749     "Server disconnected (no reason given).%s", explanation);
750     }
751     buf[sizeof(buf) - 1] = 0;
752     notify_fatal_error(pvar, buf);
753    
754     return TRUE;
755     }
756    
757     static BOOL handle_unimplemented(PTInstVar pvar)
758     {
759     /* Should never receive this since we only send base 2.0 protocol messages */
760     grab_payload(pvar, 4);
761     return TRUE;
762     }
763    
764     static BOOL handle_crypt_success(PTInstVar pvar)
765     {
766     notify_verbose_message(pvar, "Secure mode successfully achieved",
767     LOG_LEVEL_VERBOSE);
768     return FALSE;
769     }
770    
771     static BOOL handle_noauth_success(PTInstVar pvar)
772     {
773     notify_verbose_message(pvar, "Server does not require authentication",
774     LOG_LEVEL_VERBOSE);
775     prep_compression(pvar);
776     return FALSE;
777     }
778    
779     static BOOL handle_auth_success(PTInstVar pvar)
780     {
781     notify_verbose_message(pvar, "Authentication accepted",
782     LOG_LEVEL_VERBOSE);
783     prep_compression(pvar);
784 yutakakn 2748
785     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
786     start_ssh_heartbeat_thread(pvar);
787    
788 yutakakn 2728 return FALSE;
789     }
790    
791     static BOOL handle_server_public_key(PTInstVar pvar)
792     {
793     int server_key_public_exponent_len;
794     int server_key_public_modulus_pos;
795     int server_key_public_modulus_len;
796     int host_key_bits_pos;
797     int host_key_public_exponent_len;
798     int host_key_public_modulus_pos;
799     int host_key_public_modulus_len;
800     int protocol_flags_pos;
801     int supported_ciphers;
802     char FAR *inmsg;
803    
804     if (!grab_payload(pvar, 14))
805     return FALSE;
806     server_key_public_exponent_len = get_mpint_len(pvar, 12);
807    
808     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
809     return FALSE;
810     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
811     server_key_public_modulus_len =
812     get_mpint_len(pvar, server_key_public_modulus_pos);
813    
814     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
815     return FALSE;
816     host_key_bits_pos =
817     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
818     host_key_public_exponent_len =
819     get_mpint_len(pvar, host_key_bits_pos + 4);
820    
821     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
822     return FALSE;
823     host_key_public_modulus_pos =
824     host_key_bits_pos + 6 + host_key_public_exponent_len;
825     host_key_public_modulus_len =
826     get_mpint_len(pvar, host_key_public_modulus_pos);
827    
828     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
829     return FALSE;
830     protocol_flags_pos =
831     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
832    
833     inmsg = pvar->ssh_state.payload;
834    
835     CRYPT_set_server_cookie(pvar, inmsg);
836     if (!CRYPT_set_server_RSA_key
837     (pvar, get_uint32(inmsg + 8), pvar->ssh_state.payload + 12,
838     inmsg + server_key_public_modulus_pos))
839     return FALSE;
840     if (!CRYPT_set_host_RSA_key
841     (pvar, get_uint32(inmsg + host_key_bits_pos),
842     inmsg + host_key_bits_pos + 4,
843     inmsg + host_key_public_modulus_pos))
844     return FALSE;
845     pvar->ssh_state.server_protocol_flags =
846     get_uint32(inmsg + protocol_flags_pos);
847    
848     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
849     if (!CRYPT_set_supported_ciphers
850     (pvar, supported_ciphers, supported_ciphers))
851     return FALSE;
852     if (!AUTH_set_supported_auth_types
853     (pvar, get_uint32(inmsg + protocol_flags_pos + 8)))
854     return FALSE;
855    
856     /* this must be the LAST THING in this function, since it can cause
857     host_is_OK to be called. */
858     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname,
859     get_uint32(inmsg + host_key_bits_pos),
860     inmsg + host_key_bits_pos + 4,
861     inmsg + host_key_public_modulus_pos);
862    
863     return FALSE;
864     }
865    
866     /*
867     The ID must have already been found to start with "SSH-". It must
868     be null-terminated.
869     */
870     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
871     {
872     char FAR *str;
873    
874     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
875     }
876    
877     if (*str != '.') {
878     return FALSE;
879     }
880    
881     pvar->protocol_major = atoi(ID + 4);
882     pvar->protocol_minor = atoi(str + 1);
883    
884     // for SSH2(yutaka)
885     // 1.99����SSH2�����������s��
886     if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
887     // ���[�U�� SSH2 ���I������������������
888     if (pvar->settings.ssh_protocol_version == 2) {
889     pvar->protocol_major = 2;
890     pvar->protocol_minor = 0;
891     }
892    
893     }
894    
895     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
896     }
897    
898     return *str == '-';
899     }
900    
901     /*
902     On entry, the pvar->protocol_xxx fields hold the server's advertised
903     protocol number. We replace the fields with the protocol number we will
904     actually use, or return FALSE if there is no usable protocol version.
905     */
906     static BOOL negotiate_protocol(PTInstVar pvar)
907     {
908     switch (pvar->protocol_major) {
909     case 1:
910     if (pvar->protocol_minor > 5) {
911     pvar->protocol_minor = 5;
912     }
913    
914     return TRUE;
915    
916     // for SSH2(yutaka)
917     case 2:
918     return TRUE; // SSH2 support
919    
920     default:
921     return FALSE;
922     }
923     }
924    
925     static void init_protocol(PTInstVar pvar)
926     {
927     CRYPT_initialize_random_numbers(pvar);
928     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
929     /* while we wait for a response from the server... */
930    
931     if (SSHv1(pvar)) {
932     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
933     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
934     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
935     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
936    
937     } else { // for SSH2(yutaka)
938     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
939     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
940     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
941     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
942     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
943     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
944     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
945     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
946     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
947     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
948     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
949     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
950    
951     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
952    
953     // ���[�U�F�������f�B�X�p�b�`���[�`��
954     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
955     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
956     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
957     // enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
958     // enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_unimplemented);
959     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
960     // enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_unimplemented);
961     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
962     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
963     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
964     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
965     // enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_unimplemented);
966     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
967    
968     }
969     }
970    
971     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
972     {
973     static const char prefix[] = "Received server prologue string: ";
974    
975     if (ID_len <= 0) {
976     return FALSE;
977     } else {
978     char FAR *buf = (char FAR *) malloc(ID_len + NUM_ELEM(prefix));
979    
980     strcpy(buf, prefix);
981     strncpy(buf + NUM_ELEM(prefix) - 1, ID, ID_len);
982     buf[NUM_ELEM(prefix) + ID_len - 1] = 0;
983     chop_newlines(buf);
984    
985     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
986    
987     free(buf);
988    
989    
990     // for calculate SSH2 hash
991     // �T�[�o�o�[�W�����������i���s���������������j
992     if (ID_len >= sizeof(pvar->server_version_string))
993     return FALSE;
994     strncpy(pvar->server_version_string, ID, ID_len);
995    
996    
997     if (ID[ID_len - 1] != '\n') {
998     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
999     return FALSE;
1000     } else
1001     if ((pvar->ssh_state.
1002     status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1003     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1004     return FALSE;
1005     } else if (strncmp(ID, "SSH-", 4) != 0) {
1006     return FALSE;
1007     } else {
1008     ID[ID_len - 1] = 0;
1009    
1010     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1011     ID[ID_len - 2] = 0;
1012     }
1013    
1014     pvar->ssh_state.server_ID = _strdup(ID);
1015    
1016     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1017     notify_fatal_error(pvar,
1018     "This program does not understand the server's version of the protocol.");
1019     } else {
1020     char TTSSH_ID[1024];
1021     int TTSSH_ID_len;
1022    
1023     _snprintf(TTSSH_ID, sizeof(TTSSH_ID),
1024     "SSH-%d.%d-TTSSH/1.5.4 Win32\n",
1025     pvar->protocol_major, pvar->protocol_minor);
1026     TTSSH_ID_len = strlen(TTSSH_ID);
1027    
1028     // for SSH2(yutaka)
1029     // �N���C�A���g�o�[�W�����������i���s���������������j
1030     strncpy(pvar->client_version_string, TTSSH_ID, TTSSH_ID_len);
1031    
1032     if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1033     0) != TTSSH_ID_len) {
1034     notify_fatal_error(pvar,
1035     "An error occurred while sending the SSH ID string.\n"
1036     "The connection will close.");
1037     } else {
1038     // ���s�R�[�h������ (2004.8.4 yutaka)
1039     pvar->server_version_string[--ID_len] = 0;
1040     pvar->client_version_string[--TTSSH_ID_len] = 0;
1041    
1042     // SSH�n���h�����o�^���s��
1043     init_protocol(pvar);
1044    
1045     SSH2_dispatch_init(1);
1046     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1047     }
1048     }
1049    
1050     return TRUE;
1051     }
1052     }
1053     }
1054    
1055     static BOOL handle_exit(PTInstVar pvar)
1056     {
1057     if (grab_payload(pvar, 4)) {
1058     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1059     finish_send_packet(pvar);
1060     notify_closed_connection(pvar);
1061     }
1062     return TRUE;
1063     }
1064    
1065     static BOOL handle_data(PTInstVar pvar)
1066     {
1067     if (grab_payload_limited(pvar, 4)) {
1068     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1069     pvar->ssh_state.payload_datastart = 4;
1070     }
1071     return TRUE;
1072     }
1073    
1074     static BOOL handle_channel_open(PTInstVar pvar)
1075     {
1076     int host_len;
1077     int originator_len;
1078    
1079     if ((pvar->ssh_state.
1080     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1081     if (grab_payload(pvar, 8)
1082     && grab_payload(pvar,
1083     8 + (host_len = get_payload_uint32(pvar, 4)))
1084     && grab_payload(pvar, originator_len =
1085     get_payload_uint32(pvar, host_len + 12))) {
1086     int local_port = get_payload_uint32(pvar, 8 + host_len);
1087    
1088     pvar->ssh_state.payload[8 + host_len] = 0;
1089     FWD_open(pvar, get_payload_uint32(pvar, 0),
1090     pvar->ssh_state.payload + 8, local_port,
1091     pvar->ssh_state.payload + 16 + host_len,
1092     originator_len);
1093     }
1094     } else {
1095     if (grab_payload(pvar, 8)
1096     && grab_payload(pvar,
1097     4 + (host_len =
1098     get_payload_uint32(pvar, 4)))) {
1099     int local_port = get_payload_uint32(pvar, 8 + host_len);
1100    
1101     pvar->ssh_state.payload[8 + host_len] = 0;
1102     FWD_open(pvar, get_payload_uint32(pvar, 0),
1103     pvar->ssh_state.payload + 8, local_port, NULL, 0);
1104     }
1105     }
1106    
1107     return TRUE;
1108     }
1109    
1110     static BOOL handle_X11_channel_open(PTInstVar pvar)
1111     {
1112     int originator_len;
1113    
1114     if ((pvar->ssh_state.
1115     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1116     if (grab_payload(pvar, 8)
1117     && grab_payload(pvar, originator_len =
1118     get_payload_uint32(pvar, 4))) {
1119     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1120     pvar->ssh_state.payload + 8, originator_len);
1121     }
1122     } else {
1123     if (grab_payload(pvar, 4)) {
1124     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0);
1125     }
1126     }
1127    
1128     return TRUE;
1129     }
1130    
1131     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1132     {
1133     if (grab_payload(pvar, 8)) {
1134     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1135     get_payload_uint32(pvar, 4));
1136     }
1137     return FALSE;
1138     }
1139    
1140     static BOOL handle_channel_open_failure(PTInstVar pvar)
1141     {
1142     if (grab_payload(pvar, 4)) {
1143     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1144     }
1145     return FALSE;
1146     }
1147    
1148     static BOOL handle_channel_data(PTInstVar pvar)
1149     {
1150     int len;
1151    
1152     if (grab_payload(pvar, 8)
1153     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1154     FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1155     pvar->ssh_state.payload + 8, len);
1156     }
1157     return TRUE;
1158     }
1159    
1160     static BOOL handle_channel_input_eof(PTInstVar pvar)
1161     {
1162     if (grab_payload(pvar, 4)) {
1163     FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1164     }
1165     return TRUE;
1166     }
1167    
1168     static BOOL handle_channel_output_eof(PTInstVar pvar)
1169     {
1170     if (grab_payload(pvar, 4)) {
1171     FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1172     }
1173     return TRUE;
1174     }
1175    
1176    
1177    
1178     // �n���h�����O�������b�Z�[�W����������
1179    
1180     #define HANDLE_MESSAGE_MAX 30
1181     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1182     static int handle_message_count = 0;
1183     static int handle_message_stage = 0;
1184    
1185     void SSH2_dispatch_init(int stage)
1186     {
1187     handle_message_count = 0;
1188     handle_message_stage = stage;
1189     }
1190    
1191     int SSH2_dispatch_enabled_check(unsigned char message)
1192     {
1193     int i;
1194    
1195     for (i = 0 ; i < handle_message_count ; i++) {
1196     if (handle_messages[i] == message)
1197     return 1;
1198     }
1199     return 0;
1200     }
1201    
1202     void SSH2_dispatch_add_message(unsigned char message)
1203     {
1204    
1205     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1206     // TODO: error check
1207     return;
1208     }
1209    
1210     handle_messages[handle_message_count++] = message;
1211     }
1212    
1213     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1214     {
1215     unsigned char c;
1216    
1217     for (c = begin ; c <= end ; c++) {
1218     SSH2_dispatch_add_message(c);
1219     }
1220     }
1221    
1222    
1223     /* default window/packet sizes for tcp/x11-fwd-channel */
1224     #define CHAN_SES_PACKET_DEFAULT (32*1024)
1225     #define CHAN_SES_WINDOW_DEFAULT (2*CHAN_SES_PACKET_DEFAULT) // READAMOUNT @ pkt.c����������������
1226    
1227     //#define CHAN_TCP_PACKET_DEFAULT (32*1024)
1228     //#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
1229     //#define CHAN_X11_PACKET_DEFAULT (16*1024)
1230     //#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
1231    
1232     // �N���C�A���g��window size���T�[�o���m������
1233     static void do_SSH2_adjust_window_size(PTInstVar pvar)
1234     {
1235     const unsigned int window_size = CHAN_SES_PACKET_DEFAULT;
1236     buffer_t *msg;
1237     unsigned char *outmsg;
1238     int len;
1239    
1240     // ���[�J����window size�������]�T�����������A�����������B
1241     if (pvar->local_window > window_size)
1242     return;
1243    
1244     {
1245     // pty open
1246     msg = buffer_init();
1247     if (msg == NULL) {
1248     // TODO: error check
1249     return;
1250     }
1251     buffer_put_int(msg, pvar->remote_id);
1252     buffer_put_int(msg, window_size - pvar->local_window);
1253    
1254     len = buffer_len(msg);
1255     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, len);
1256     memcpy(outmsg, buffer_ptr(msg), len);
1257     finish_send_packet(pvar);
1258     buffer_free(msg);
1259    
1260     // �N���C�A���g��window size��������
1261     pvar->local_window = window_size;
1262     }
1263    
1264     }
1265    
1266    
1267     static void SSH2_consume_packet_size(PTInstVar pvar, unsigned char message)
1268     {
1269     int len;
1270     char *data;
1271    
1272     if (!(message >= SSH2_MSG_CHANNEL_OPEN_CONFIRMATION && message <= SSH2_MSG_CHANNEL_FAILURE)) {
1273     return;
1274     }
1275    
1276     // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
1277     data = pvar->ssh_state.payload;
1278     // �p�P�b�g�T�C�Y - (�p�f�B���O�T�C�Y+1)�G�^���p�P�b�g�T�C�Y
1279     len = pvar->ssh_state.payloadlen;
1280    
1281     pvar->local_window -= (len + 1);
1282    
1283     do_SSH2_adjust_window_size(pvar);
1284    
1285     }
1286    
1287    
1288     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1289     int padding)
1290     {
1291     unsigned char message = prep_packet(pvar, data, len, padding);
1292    
1293    
1294     #ifdef SSH2_DEBUG
1295     // for SSH2(yutaka)
1296     if (SSHv2(pvar)) {
1297     if (pvar->key_done) {
1298     message = message;
1299     }
1300    
1301     if (pvar->userauth_success) {
1302     message = message;
1303     }
1304    
1305     if (pvar->rekeying) {
1306     message = message;
1307     }
1308     }
1309     #endif
1310    
1311     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1312     if (message != SSH_MSG_NONE) {
1313     // ���b�Z�[�W�^�C�v���������n���h�����N��
1314     SSHPacketHandler handler = get_handler(pvar, message);
1315    
1316     // for SSH2(yutaka)
1317     if (SSHv2(pvar)) {
1318     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1319     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1320     char buf[1024];
1321    
1322     _snprintf(buf, sizeof(buf),
1323     "Unexpected SSH2 message(%d) on current stage(%d)", message, handle_message_stage);
1324     notify_fatal_error(pvar, buf);
1325     // abort
1326     }
1327     }
1328    
1329     if (handler == NULL) {
1330     if (SSHv1(pvar)) {
1331     char buf[1024];
1332    
1333     _snprintf(buf, sizeof(buf),
1334     "Unexpected packet type received: %d", message);
1335     buf[sizeof(buf) - 1] = 0;
1336     notify_fatal_error(pvar, buf);
1337     } else {
1338     unsigned char FAR *outmsg =
1339     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1340    
1341     set_uint32(outmsg,
1342     pvar->ssh_state.receiver_sequence_number - 1);
1343     finish_send_packet(pvar);
1344     /* XXX need to decompress incoming packet, but how? */
1345     }
1346     } else {
1347     if (!handler(pvar)) {
1348     deque_handlers(pvar, message);
1349     }
1350     }
1351     }
1352     }
1353    
1354     static BOOL handle_pty_success(PTInstVar pvar)
1355     {
1356     FWD_enter_interactive_mode(pvar);
1357     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1358     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1359     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1360     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1361     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1362     handle_channel_input_eof);
1363     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1364     handle_channel_output_eof);
1365     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1366     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1367     return FALSE;
1368     }
1369    
1370     static BOOL handle_pty_failure(PTInstVar pvar)
1371     {
1372     notify_nonfatal_error(pvar,
1373     "The server cannot allocate a pseudo-terminal. "
1374     "You may encounter some problems with the terminal.");
1375     return handle_pty_success(pvar);
1376     }
1377    
1378     static void prep_pty(PTInstVar pvar)
1379     {
1380     int len = strlen(pvar->ts->TermType);
1381     unsigned char FAR *outmsg =
1382     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1383     4 + len + 16 + sizeof(ssh_ttymodes));
1384     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1385     static const SSHPacketHandler handlers[]
1386     = { handle_pty_success, handle_pty_failure };
1387    
1388     set_uint32(outmsg, len);
1389     memcpy(outmsg + 4, pvar->ts->TermType, len);
1390     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
1391     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
1392     set_uint32(outmsg + 4 + len + 8, 0);
1393     set_uint32(outmsg + 4 + len + 12, 0);
1394     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
1395     finish_send_packet(pvar);
1396    
1397     enque_handlers(pvar, 2, msgs, handlers);
1398    
1399     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
1400     finish_send_packet(pvar);
1401     }
1402    
1403     static void prep_forwarding(PTInstVar pvar)
1404     {
1405     FWD_prep_forwarding(pvar);
1406     prep_pty(pvar);
1407     }
1408    
1409     static void enable_compression(PTInstVar pvar)
1410     {
1411     pvar->ssh_state.compress_stream.zalloc = NULL;
1412     pvar->ssh_state.compress_stream.zfree = NULL;
1413     pvar->ssh_state.compress_stream.opaque = NULL;
1414     if (deflateInit
1415     (&pvar->ssh_state.compress_stream,
1416     pvar->ssh_state.compression_level) != Z_OK) {
1417     notify_fatal_error(pvar,
1418     "An error occurred while setting up compression.\n"
1419     "The connection will close.");
1420     return;
1421     } else {
1422     pvar->ssh_state.compressing = TRUE;
1423     }
1424    
1425     pvar->ssh_state.decompress_stream.zalloc = NULL;
1426     pvar->ssh_state.decompress_stream.zfree = NULL;
1427     pvar->ssh_state.decompress_stream.opaque = NULL;
1428     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
1429     deflateEnd(&pvar->ssh_state.compress_stream);
1430     notify_fatal_error(pvar,
1431     "An error occurred while setting up compression.\n"
1432     "The connection will close.");
1433     return;
1434     } else {
1435     pvar->ssh_state.decompressing = TRUE;
1436     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
1437     &pvar->ssh_state.postdecompress_inbuflen, 1000);
1438     }
1439     }
1440    
1441     static BOOL handle_enable_compression(PTInstVar pvar)
1442     {
1443     enable_compression(pvar);
1444     prep_forwarding(pvar);
1445     return FALSE;
1446     }
1447    
1448     static BOOL handle_disable_compression(PTInstVar pvar)
1449     {
1450     prep_forwarding(pvar);
1451     return FALSE;
1452     }
1453    
1454     static void prep_compression(PTInstVar pvar)
1455     {
1456     if (pvar->session_settings.CompressionLevel > 0) {
1457     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1458     static const SSHPacketHandler handlers[]
1459     = { handle_enable_compression, handle_disable_compression };
1460    
1461     unsigned char FAR *outmsg =
1462     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
1463    
1464     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
1465     finish_send_packet(pvar);
1466    
1467     pvar->ssh_state.compression_level =
1468     pvar->session_settings.CompressionLevel;
1469    
1470     enque_handlers(pvar, 2, msgs, handlers);
1471     } else {
1472     prep_forwarding(pvar);
1473     }
1474     }
1475    
1476     static void enque_simple_auth_handlers(PTInstVar pvar)
1477     {
1478     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1479     static const SSHPacketHandler handlers[]
1480     = { handle_auth_success, handle_auth_failure };
1481    
1482     enque_handlers(pvar, 2, msgs, handlers);
1483     }
1484    
1485     static BOOL handle_rsa_challenge(PTInstVar pvar)
1486     {
1487     int challenge_bytes;
1488    
1489     if (!grab_payload(pvar, 2)) {
1490     return FALSE;
1491     }
1492    
1493     challenge_bytes = get_mpint_len(pvar, 0);
1494    
1495     if (grab_payload(pvar, challenge_bytes)) {
1496     unsigned char FAR *outmsg =
1497     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
1498    
1499     if (CRYPT_generate_RSA_challenge_response
1500     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
1501     AUTH_destroy_cur_cred(pvar);
1502     finish_send_packet(pvar);
1503    
1504     enque_simple_auth_handlers(pvar);
1505     } else {
1506     notify_fatal_error(pvar,
1507     "An error occurred while decrypting the RSA challenge.\n"
1508     "Perhaps the key file is corrupted.");
1509     }
1510     }
1511    
1512     return FALSE;
1513     }
1514    
1515     #define OBFUSCATING_ROUND_TO 32
1516    
1517     static int obfuscating_round_up(PTInstVar pvar, int size)
1518     {
1519     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
1520     }
1521    
1522     static void try_send_credentials(PTInstVar pvar)
1523     {
1524     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
1525     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
1526     static const int RSA_msgs[] =
1527     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
1528     static const SSHPacketHandler RSA_handlers[]
1529     = { handle_rsa_challenge, handle_rsa_auth_refused };
1530     static const int TIS_msgs[] =
1531     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
1532     static const SSHPacketHandler TIS_handlers[]
1533     = { handle_TIS_challenge, handle_auth_failure };
1534    
1535     switch (cred->method) {
1536     case SSH_AUTH_NONE:
1537     return;
1538     case SSH_AUTH_PASSWORD:{
1539     int len = strlen(cred->password);
1540     // Round up password length to discourage traffic analysis
1541     int obfuscated_len = obfuscating_round_up(pvar, len);
1542     unsigned char FAR *outmsg =
1543     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
1544     4 + obfuscated_len);
1545    
1546     notify_verbose_message(pvar,
1547     "Trying PASSWORD authentication...",
1548     LOG_LEVEL_VERBOSE);
1549    
1550     set_uint32(outmsg, obfuscated_len);
1551     memcpy(outmsg + 4, cred->password, len);
1552     memset(outmsg + 4 + len, 0, obfuscated_len - len);
1553     AUTH_destroy_cur_cred(pvar);
1554     enque_simple_auth_handlers(pvar);
1555     break;
1556     }
1557     case SSH_AUTH_RHOSTS:{
1558     int len = strlen(cred->rhosts_client_user);
1559     unsigned char FAR *outmsg =
1560     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
1561    
1562     notify_verbose_message(pvar,
1563     "Trying RHOSTS authentication...",
1564     LOG_LEVEL_VERBOSE);
1565    
1566     set_uint32(outmsg, len);
1567     memcpy(outmsg + 4, cred->rhosts_client_user, len);
1568     AUTH_destroy_cur_cred(pvar);
1569     enque_simple_auth_handlers(pvar);
1570     break;
1571     }
1572     case SSH_AUTH_RSA:{
1573     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
1574     unsigned char FAR *outmsg =
1575     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
1576    
1577     notify_verbose_message(pvar,
1578     "Trying RSA authentication...",
1579     LOG_LEVEL_VERBOSE);
1580    
1581     set_ushort16_MSBfirst(outmsg, len * 8);
1582     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
1583     /* don't destroy the current credentials yet */
1584     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
1585     break;
1586     }
1587     case SSH_AUTH_RHOSTS_RSA:{
1588     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
1589     int name_len = strlen(cred->rhosts_client_user);
1590     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
1591     int index;
1592     unsigned char FAR *outmsg =
1593     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
1594     12 + mod_len + name_len + exp_len);
1595    
1596     notify_verbose_message(pvar,
1597     "Trying RHOSTS+RSA authentication...",
1598     LOG_LEVEL_VERBOSE);
1599    
1600     set_uint32(outmsg, name_len);
1601     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
1602     index = 4 + name_len;
1603    
1604     set_uint32(outmsg + index, 8 * mod_len);
1605     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
1606     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
1607     index += 6 + exp_len;
1608    
1609     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
1610     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
1611     /* don't destroy the current credentials yet */
1612     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
1613     break;
1614     }
1615     case SSH_AUTH_TIS:{
1616     if (cred->password == NULL) {
1617     unsigned char FAR *outmsg =
1618     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
1619    
1620     notify_verbose_message(pvar,
1621     "Trying TIS authentication...",
1622     LOG_LEVEL_VERBOSE);
1623     enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
1624     } else {
1625     int len = strlen(cred->password);
1626     int obfuscated_len = obfuscating_round_up(pvar, len);
1627     unsigned char FAR *outmsg =
1628     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
1629     4 + obfuscated_len);
1630    
1631     notify_verbose_message(pvar, "Sending TIS response",
1632     LOG_LEVEL_VERBOSE);
1633    
1634     set_uint32(outmsg, obfuscated_len);
1635     memcpy(outmsg + 4, cred->password, len);
1636     memset(outmsg + 4 + len, 0, obfuscated_len - len);
1637     enque_simple_auth_handlers(pvar);
1638     }
1639     AUTH_destroy_cur_cred(pvar);
1640     break;
1641     }
1642     default:
1643     notify_fatal_error(pvar,
1644     "Internal error: unsupported authentication method");
1645     return;
1646     }
1647    
1648     finish_send_packet(pvar);
1649     destroy_packet_buf(pvar);
1650    
1651     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
1652     }
1653     }
1654    
1655     static void try_send_user_name(PTInstVar pvar)
1656     {
1657     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
1658     char FAR *username = AUTH_get_user_name(pvar);
1659    
1660     if (username != NULL) {
1661     int len = strlen(username);
1662     int obfuscated_len = obfuscating_round_up(pvar, len);
1663     unsigned char FAR *outmsg =
1664     begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
1665     char buf[1024] = "Sending user name: ";
1666     static const int msgs[] =
1667     { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1668     static const SSHPacketHandler handlers[]
1669     = { handle_noauth_success, handle_auth_required };
1670    
1671     set_uint32(outmsg, obfuscated_len);
1672     memcpy(outmsg + 4, username, len);
1673     memset(outmsg + 4 + len, 0, obfuscated_len - len);
1674     finish_send_packet(pvar);
1675    
1676     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
1677    
1678     strncpy(buf + strlen(buf), username,
1679     sizeof(buf) - strlen(buf) - 2);
1680     buf[sizeof(buf) - 1] = 0;
1681     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1682    
1683     enque_handlers(pvar, 2, msgs, handlers);
1684     }
1685     }
1686     }
1687    
1688     static void send_session_key(PTInstVar pvar)
1689     {
1690     int encrypted_session_key_len;
1691     unsigned char FAR *outmsg;
1692    
1693     if (SSHv1(pvar)) {
1694     encrypted_session_key_len =
1695     CRYPT_get_encrypted_session_key_len(pvar);
1696     }
1697    
1698     if (!CRYPT_choose_ciphers(pvar))
1699     return;
1700    
1701     if (SSHv1(pvar)) {
1702     outmsg =
1703     begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
1704     15 + encrypted_session_key_len);
1705     outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
1706     memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
1707     outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
1708     outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
1709     if (!CRYPT_choose_session_key(pvar, outmsg + 11))
1710     return;
1711     set_uint32(outmsg + 11 + encrypted_session_key_len,
1712     SSH_PROTOFLAG_SCREEN_NUMBER |
1713     SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
1714     finish_send_packet(pvar);
1715     }
1716    
1717     if (!CRYPT_start_encryption(pvar, 1, 1))
1718     return;
1719     notify_established_secure_connection(pvar);
1720    
1721     if (SSHv1(pvar)) {
1722     enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
1723     }
1724    
1725     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
1726    
1727     if (SSHv1(pvar)) {
1728     try_send_user_name(pvar);
1729     }
1730     }
1731    
1732     /*************************
1733     END of message handlers
1734     ************************/
1735    
1736     void SSH_init(PTInstVar pvar)
1737     {
1738     int i;
1739    
1740     buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
1741     buf_create(&pvar->ssh_state.precompress_outbuf,
1742     &pvar->ssh_state.precompress_outbuflen);
1743     buf_create(&pvar->ssh_state.postdecompress_inbuf,
1744     &pvar->ssh_state.postdecompress_inbuflen);
1745     pvar->ssh_state.payload = NULL;
1746     pvar->ssh_state.compressing = FALSE;
1747     pvar->ssh_state.decompressing = FALSE;
1748     pvar->ssh_state.status_flags =
1749     STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
1750     pvar->ssh_state.payload_datalen = 0;
1751     pvar->ssh_state.hostname = NULL;
1752     pvar->ssh_state.server_ID = NULL;
1753     pvar->ssh_state.receiver_sequence_number = 0;
1754     pvar->ssh_state.sender_sequence_number = 0;
1755     for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
1756     pvar->ssh_state.packet_handlers[i] = NULL;
1757     }
1758    
1759     // for SSH2(yutaka)
1760     memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
1761     pvar->userauth_success = 0;
1762     pvar->session_nego_status = 0;
1763 yutakakn 2738 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
1764 yutakakn 2728 pvar->rekeying = 0;
1765     pvar->key_done = 0;
1766 yutakakn 2739 pvar->ssh2_autologin = 0; // autologin disabled(default)
1767 yutakakn 2728
1768     }
1769    
1770     void SSH_open(PTInstVar pvar)
1771     {
1772     pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
1773     pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
1774     pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
1775     }
1776    
1777     void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
1778     {
1779     if (SSHv1(pvar)) {
1780     int len = reason == NULL ? 0 : strlen(reason);
1781     unsigned char FAR *outmsg =
1782     begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
1783    
1784     set_uint32(outmsg, len);
1785     if (reason != NULL) {
1786     memcpy(outmsg + 4, reason, len);
1787     }
1788     finish_send_packet(pvar);
1789    
1790     } else { // for SSH2(yutaka)
1791     buffer_t *msg;
1792     unsigned char *outmsg;
1793     int len;
1794    
1795     // SSH2 server��channel close���`����
1796     msg = buffer_init();
1797     if (msg == NULL) {
1798     // TODO: error check
1799     return;
1800     }
1801     buffer_put_int(msg, pvar->remote_id);
1802    
1803     len = buffer_len(msg);
1804     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
1805     memcpy(outmsg, buffer_ptr(msg), len);
1806     finish_send_packet(pvar);
1807     buffer_free(msg);
1808    
1809     }
1810    
1811     }
1812    
1813     void SSH_notify_host_OK(PTInstVar pvar)
1814     {
1815     if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
1816     pvar->ssh_state.status_flags |= STATUS_HOST_OK;
1817     send_session_key(pvar);
1818     }
1819     }
1820    
1821     void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
1822     {
1823     pvar->ssh_state.win_cols = cols;
1824     pvar->ssh_state.win_rows = rows;
1825    
1826     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
1827     unsigned char FAR *outmsg =
1828     begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
1829    
1830     set_uint32(outmsg, rows);
1831     set_uint32(outmsg + 4, cols);
1832     set_uint32(outmsg + 8, 0);
1833     set_uint32(outmsg + 12, 0);
1834     finish_send_packet(pvar);
1835     }
1836     }
1837    
1838     int SSH_get_min_packet_size(PTInstVar pvar)
1839     {
1840     if (SSHv1(pvar)) {
1841     return 12;
1842     } else {
1843     int block_size = CRYPT_get_decryption_block_size(pvar);
1844    
1845     return max(16, block_size);
1846     }
1847     }
1848    
1849     /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
1850     at least 5 bytes must be decrypted */
1851     void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
1852     {
1853     if (SSHv2(pvar)) {
1854     CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
1855     }
1856     }
1857    
1858     int SSH_get_clear_MAC_size(PTInstVar pvar)
1859     {
1860     if (SSHv1(pvar)) {
1861     return 0;
1862     } else {
1863     return CRYPT_get_receiver_MAC_size(pvar);
1864     }
1865     }
1866    
1867     void SSH_notify_user_name(PTInstVar pvar)
1868     {
1869     try_send_user_name(pvar);
1870     }
1871    
1872     void SSH_notify_cred(PTInstVar pvar)
1873     {
1874     try_send_credentials(pvar);
1875     }
1876    
1877     void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
1878     {
1879     if (SSHv1(pvar)) {
1880     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
1881     return;
1882     }
1883    
1884     while (buflen > 0) {
1885     int len =
1886     buflen >
1887     SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
1888     unsigned char FAR *outmsg =
1889     begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
1890    
1891     set_uint32(outmsg, len);
1892    
1893     if (pvar->ssh_state.compressing) {
1894     buf_ensure_size(&pvar->ssh_state.outbuf,
1895     &pvar->ssh_state.outbuflen,
1896     len + (len >> 6) + 50);
1897     pvar->ssh_state.compress_stream.next_in =
1898     pvar->ssh_state.precompress_outbuf;
1899     pvar->ssh_state.compress_stream.avail_in = 5;
1900     pvar->ssh_state.compress_stream.next_out =
1901     pvar->ssh_state.outbuf + 12;
1902     pvar->ssh_state.compress_stream.avail_out =
1903     pvar->ssh_state.outbuflen - 12;
1904    
1905     if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) !=
1906     Z_OK) {
1907     notify_fatal_error(pvar, "Error compressing packet data");
1908     return;
1909     }
1910    
1911     pvar->ssh_state.compress_stream.next_in =
1912     (unsigned char FAR *) buf;
1913     pvar->ssh_state.compress_stream.avail_in = len;
1914    
1915     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
1916     Z_OK) {
1917     notify_fatal_error(pvar, "Error compressing packet data");
1918     return;
1919     }
1920     } else {
1921     memcpy(outmsg + 4, buf, len);
1922     }
1923    
1924     finish_send_packet_special(pvar, 1);
1925    
1926     buflen -= len;
1927     buf += len;
1928     }
1929    
1930     } else { // for SSH2(yutaka)
1931     buffer_t *msg;
1932     unsigned char *outmsg;
1933     int len;
1934    
1935     msg = buffer_init();
1936     if (msg == NULL) {
1937     // TODO: error check
1938     return;
1939     }
1940     buffer_put_int(msg, pvar->remote_id);
1941     buffer_put_string(msg, (char *)buf, buflen);
1942    
1943     len = buffer_len(msg);
1944     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
1945     memcpy(outmsg, buffer_ptr(msg), len);
1946     finish_send_packet(pvar);
1947     buffer_free(msg);
1948    
1949     // remote window size������
1950     pvar->remote_window -= len;
1951    
1952     }
1953    
1954     }
1955    
1956     int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
1957     {
1958     int num_bytes = pvar->ssh_state.payload_datalen;
1959    
1960     if (num_bytes > len) {
1961     num_bytes = len;
1962     }
1963    
1964     if (!pvar->ssh_state.decompressing) {
1965     memcpy(dest,
1966     pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
1967     num_bytes);
1968     pvar->ssh_state.payload_datastart += num_bytes;
1969     } else if (num_bytes > 0) {
1970     pvar->ssh_state.decompress_stream.next_out = dest;
1971     pvar->ssh_state.decompress_stream.avail_out = num_bytes;
1972    
1973     if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) !=
1974     Z_OK) {
1975     notify_fatal_error(pvar,
1976     "Invalid compressed data in received packet");
1977     return 0;
1978     }
1979     }
1980    
1981     pvar->ssh_state.payload_datalen -= num_bytes;
1982    
1983     return num_bytes;
1984     }
1985    
1986     void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
1987     {
1988     char buf[1024];
1989     char buf2[1024];
1990    
1991     if (pvar->ssh_state.compressing) {
1992     unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
1993     unsigned long total_out =
1994     pvar->ssh_state.compress_stream.total_out;
1995    
1996     if (total_out > 0) {
1997     _snprintf(buf, sizeof(buf), "level %d; ratio %.1f (%ld:%ld)",
1998     pvar->ssh_state.compression_level,
1999     ((double) total_in) / total_out, total_in,
2000     total_out);
2001     } else {
2002     _snprintf(buf, sizeof(buf), "level %d",
2003     pvar->ssh_state.compression_level);
2004     }
2005     } else {
2006     strcpy(buf, "none");
2007     }
2008     buf[sizeof(buf) - 1] = 0;
2009    
2010     if (pvar->ssh_state.decompressing) {
2011     unsigned long total_in =
2012     pvar->ssh_state.decompress_stream.total_in;
2013     unsigned long total_out =
2014     pvar->ssh_state.decompress_stream.total_out;
2015    
2016     if (total_in > 0) {
2017     _snprintf(buf2, sizeof(buf2), "level %d; ratio %.1f (%ld:%ld)",
2018     pvar->ssh_state.compression_level,
2019     ((double) total_out) / total_in, total_out,
2020     total_in);
2021     } else {
2022     _snprintf(buf2, sizeof(buf2), "level %d",
2023     pvar->ssh_state.compression_level);
2024     }
2025     } else {
2026     strcpy(buf2, "none");
2027     }
2028     buf2[sizeof(buf2) - 1] = 0;
2029    
2030     _snprintf(dest, len, "Upstream %s; Downstream %s", buf, buf2);
2031     dest[len - 1] = 0;
2032     }
2033    
2034     void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2035     {
2036     strncpy(dest, pvar->ssh_state.server_ID == NULL ? "Unknown"
2037     : pvar->ssh_state.server_ID, len);
2038     dest[len - 1] = 0;
2039     }
2040    
2041     void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2042     int len)
2043     {
2044     if (pvar->protocol_major == 0) {
2045     strncpy(dest, "Unknown", len);
2046     } else {
2047     _snprintf(dest, len, "%d.%d", pvar->protocol_major,
2048     pvar->protocol_minor);
2049     }
2050     dest[len - 1] = 0;
2051     }
2052    
2053     void SSH_end(PTInstVar pvar)
2054     {
2055     int i;
2056    
2057     for (i = 0; i < 256; i++) {
2058     SSHPacketHandlerItem FAR *first_item =
2059     pvar->ssh_state.packet_handlers[i];
2060    
2061     if (first_item != NULL) {
2062     SSHPacketHandlerItem FAR *item = first_item;
2063    
2064     do {
2065     SSHPacketHandlerItem FAR *cur_item = item;
2066    
2067     item = item->next_for_message;
2068     free(cur_item);
2069     } while (item != first_item);
2070     }
2071     pvar->ssh_state.packet_handlers[i] = NULL;
2072     }
2073    
2074     free(pvar->ssh_state.hostname);
2075     pvar->ssh_state.hostname = NULL;
2076     free(pvar->ssh_state.server_ID);
2077     pvar->ssh_state.server_ID = NULL;
2078     buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2079     buf_destroy(&pvar->ssh_state.precompress_outbuf,
2080     &pvar->ssh_state.precompress_outbuflen);
2081     buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2082     &pvar->ssh_state.postdecompress_inbuflen);
2083    
2084     if (pvar->ssh_state.compressing) {
2085     deflateEnd(&pvar->ssh_state.compress_stream);
2086     pvar->ssh_state.compressing = FALSE;
2087     }
2088     if (pvar->ssh_state.decompressing) {
2089     inflateEnd(&pvar->ssh_state.decompress_stream);
2090     pvar->ssh_state.decompressing = FALSE;
2091     }
2092     }
2093    
2094     /* support for port forwarding */
2095     void SSH_channel_send(PTInstVar pvar, uint32 remote_channel_num,
2096     unsigned char FAR * buf, int len)
2097     {
2098     unsigned char FAR *outmsg =
2099     begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2100    
2101     set_uint32(outmsg, remote_channel_num);
2102     set_uint32(outmsg + 4, len);
2103    
2104     if (pvar->ssh_state.compressing) {
2105     buf_ensure_size(&pvar->ssh_state.outbuf,
2106     &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2107     pvar->ssh_state.compress_stream.next_in =
2108     pvar->ssh_state.precompress_outbuf;
2109     pvar->ssh_state.compress_stream.avail_in = 9;
2110     pvar->ssh_state.compress_stream.next_out =
2111     pvar->ssh_state.outbuf + 12;
2112     pvar->ssh_state.compress_stream.avail_out =
2113     pvar->ssh_state.outbuflen - 12;
2114    
2115     if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2116     notify_fatal_error(pvar, "Error compressing packet data");
2117     return;
2118     }
2119    
2120     pvar->ssh_state.compress_stream.next_in =
2121     (unsigned char FAR *) buf;
2122     pvar->ssh_state.compress_stream.avail_in = len;
2123    
2124     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2125     Z_OK) {
2126     notify_fatal_error(pvar, "Error compressing packet data");
2127     return;
2128     }
2129     } else {
2130     memcpy(outmsg + 8, buf, len);
2131     }
2132    
2133     finish_send_packet_special(pvar, 1);
2134     }
2135    
2136     void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2137     {
2138     unsigned char FAR *outmsg =
2139     begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2140    
2141     set_uint32(outmsg, remote_channel_num);
2142     finish_send_packet(pvar);
2143     }
2144    
2145     void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2146     uint32 local_channel_num)
2147     {
2148     unsigned char FAR *outmsg =
2149     begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2150    
2151     set_uint32(outmsg, remote_channel_num);
2152     set_uint32(outmsg + 4, local_channel_num);
2153     finish_send_packet(pvar);
2154     }
2155    
2156     void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2157     {
2158     unsigned char FAR *outmsg =
2159     begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2160    
2161     set_uint32(outmsg, remote_channel_num);
2162     finish_send_packet(pvar);
2163     }
2164    
2165     void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num)
2166     {
2167     unsigned char FAR *outmsg =
2168     begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2169    
2170     set_uint32(outmsg, remote_channel_num);
2171     finish_send_packet(pvar);
2172     }
2173    
2174     void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2175     char FAR * to_local_host, int to_local_port)
2176     {
2177     int host_len = strlen(to_local_host);
2178     unsigned char FAR *outmsg =
2179     begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2180     12 + host_len);
2181    
2182     set_uint32(outmsg, from_server_port);
2183     set_uint32(outmsg + 4, host_len);
2184     memcpy(outmsg + 8, to_local_host, host_len);
2185     set_uint32(outmsg + 8 + host_len, to_local_port);
2186     finish_send_packet(pvar);
2187    
2188     enque_forwarding_request_handlers(pvar);
2189     }
2190    
2191     void SSH_request_X11_forwarding(PTInstVar pvar,
2192     char FAR * auth_protocol,
2193     unsigned char FAR * auth_data,
2194     int auth_data_len, int screen_num)
2195     {
2196     int protocol_len = strlen(auth_protocol);
2197     int data_len = auth_data_len * 2;
2198     unsigned char FAR *outmsg =
2199     begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING,
2200     12 + protocol_len + data_len);
2201     int i;
2202     char FAR *auth_data_ptr;
2203    
2204     set_uint32(outmsg, protocol_len);
2205     memcpy(outmsg + 4, auth_protocol, protocol_len);
2206     set_uint32(outmsg + 4 + protocol_len, data_len);
2207     auth_data_ptr = outmsg + 8 + protocol_len;
2208     for (i = 0; i < auth_data_len; i++) {
2209     sprintf(auth_data_ptr + i * 2, "%.2x", auth_data[i]);
2210     }
2211     set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
2212    
2213     finish_send_packet(pvar);
2214    
2215     enque_forwarding_request_handlers(pvar);
2216     }
2217    
2218     void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
2219     char FAR * to_remote_host, int to_remote_port,
2220     char FAR * originator)
2221     {
2222     static const int msgs[]
2223     = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
2224     static const SSHPacketHandler handlers[]
2225     = { handle_channel_open_confirmation, handle_channel_open_failure };
2226    
2227     int host_len = strlen(to_remote_host);
2228    
2229     if ((pvar->ssh_state.
2230     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
2231     int originator_len = strlen(originator);
2232     unsigned char FAR *outmsg =
2233     begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2234     16 + host_len + originator_len);
2235    
2236     set_uint32(outmsg, local_channel_num);
2237     set_uint32(outmsg + 4, host_len);
2238     memcpy(outmsg + 8, to_remote_host, host_len);
2239     set_uint32(outmsg + 8 + host_len, to_remote_port);
2240     set_uint32(outmsg + 12 + host_len, originator_len);
2241     memcpy(outmsg + 16 + host_len, originator, originator_len);
2242     } else {
2243     unsigned char FAR *outmsg =
2244     begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2245     12 + host_len);
2246    
2247     set_uint32(outmsg, local_channel_num);
2248     set_uint32(outmsg + 4, host_len);
2249     memcpy(outmsg + 8, to_remote_host, host_len);
2250     set_uint32(outmsg + 8 + host_len, to_remote_port);
2251     }
2252    
2253     finish_send_packet(pvar);
2254    
2255     enque_handlers(pvar, 2, msgs, handlers);
2256     }
2257    
2258    
2259     /////////////////////////////////////////////////////////////////////////////
2260     //
2261     // SSH2 protocol procedure in the following code:
2262     //
2263     /////////////////////////////////////////////////////////////////////////////
2264    
2265     void debug_print(int no, char *msg, int len)
2266     {
2267     #ifdef _DEBUG
2268     FILE *fp;
2269     char file[128];
2270    
2271     sprintf(file, "dump%d.bin", no);
2272    
2273     fp = fopen(file, "wb");
2274     if (fp == NULL)
2275     return;
2276    
2277     fwrite(msg, 1, len, fp);
2278    
2279     fclose(fp);
2280     #endif
2281     }
2282    
2283     // �N���C�A���g�����T�[�o������������
2284     #ifdef SSH2_DEBUG
2285     static char *myproposal[PROPOSAL_MAX] = {
2286     // "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2287     "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2288     // "ssh-rsa,ssh-dss",
2289     "ssh-dss,ssh-rsa",
2290     "3des-cbc,aes128-cbc",
2291     "3des-cbc,aes128-cbc",
2292 yutakakn 2739 "hmac-sha1",
2293     // "hmac-sha1,hmac-md5",
2294     "hmac-sha1",
2295     // "hmac-sha1,hmac-md5",
2296 yutakakn 2728 "none",
2297     "none",
2298     "",
2299     "",
2300     };
2301     #else
2302     static char *myproposal[PROPOSAL_MAX] = {
2303     "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2304     "ssh-rsa,ssh-dss",
2305     "3des-cbc,aes128-cbc",
2306     "3des-cbc,aes128-cbc",
2307     "hmac-sha1",
2308     "hmac-sha1",
2309     "none",
2310     "none",
2311     "",
2312     "",
2313     };
2314     #endif
2315    
2316    
2317     typedef struct ssh2_cipher {
2318     SSHCipher cipher;
2319     char *name;
2320     int block_size;
2321     int key_len;
2322     const EVP_CIPHER *(*func)(void);
2323     } ssh2_cipher_t;
2324    
2325     ssh2_cipher_t ssh2_ciphers[] = {
2326     {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
2327     {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
2328     {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
2329     };
2330    
2331    
2332     typedef struct ssh2_mac {
2333     char *name;
2334     const EVP_MD *(*func)(void);
2335     int truncatebits;
2336     } ssh2_mac_t;
2337    
2338     ssh2_mac_t ssh2_macs[] = {
2339     {"hmac-sha1", EVP_sha1, 0},
2340     {"hmac-md5", EVP_md5, 0},
2341     {NULL, NULL, 0},
2342     };
2343    
2344     static Newkeys current_keys[MODE_MAX];
2345    
2346    
2347     #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
2348    
2349    
2350     static int get_cipher_block_size(SSHCipher cipher)
2351     {
2352     ssh2_cipher_t *ptr = ssh2_ciphers;
2353     int val = 0;
2354    
2355     while (ptr->name != NULL) {
2356     if (cipher == ptr->cipher) {
2357     val = ptr->block_size;
2358     break;
2359     }
2360     ptr++;
2361     }
2362     return (val);
2363     }
2364    
2365     static int get_cipher_key_len(SSHCipher cipher)
2366     {
2367     ssh2_cipher_t *ptr = ssh2_ciphers;
2368     int val = 0;
2369    
2370     while (ptr->name != NULL) {
2371     if (cipher == ptr->cipher) {
2372     val = ptr->key_len;
2373     break;
2374     }
2375     ptr++;
2376     }
2377     return (val);
2378     }
2379    
2380    
2381     static int get_mac_index(char *name)
2382     {
2383     ssh2_mac_t *ptr = ssh2_macs;
2384     int val = -1;
2385    
2386     while (ptr->name != NULL) {
2387     if (strcmp(ptr->name, name) == 0) {
2388     val = ptr - ssh2_macs;
2389     break;
2390     }
2391     ptr++;
2392     }
2393     return (val);
2394     }
2395    
2396    
2397     static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
2398     {
2399     FILE *fp;
2400     char filename[256];
2401    
2402     _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
2403    
2404     fp = fopen(filename, "wb");
2405     if (fp == NULL)
2406     return;
2407    
2408     fwrite(buf, 1, len, fp);
2409    
2410     fclose(fp);
2411     }
2412    
2413    
2414     void SSH2_packet_start(buffer_t *msg, unsigned char type)
2415     {
2416     unsigned char buf[9];
2417     int len = 6;
2418    
2419     memset(buf, 0, sizeof(buf));
2420     buf[len - 1] = type;
2421     buffer_clear(msg);
2422     buffer_append(msg, buf, len);
2423     }
2424    
2425    
2426     // the caller is normalize_cipher_order()
2427     void SSH2_update_cipher_myproposal(PTInstVar pvar)
2428     {
2429     static char buf[128]; // TODO: malloc()��������
2430     int cipher;
2431     int len, i;
2432    
2433     // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
2434     buf[0] = '\0';
2435     for (i = 0 ; pvar->ts_SSH->CipherOrder[i] != 0 ; i++) {
2436     cipher = pvar->ts_SSH->CipherOrder[i] - '0';
2437     if (cipher == 0) // disabled line
2438     break;
2439     if (cipher == SSH_CIPHER_AES128) {
2440     strcat(buf, "aes128-cbc,");
2441     }
2442     if (cipher == SSH_CIPHER_3DES_CBC) {
2443     strcat(buf, "3des-cbc,");
2444     }
2445     }
2446     if (buf[0] != '\0') {
2447     len = strlen(buf);
2448     buf[len - 1] = '\0'; // get rid of comma
2449     myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
2450     myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
2451     }
2452     }
2453    
2454    
2455     // �N���C�A���g�����T�[�o�����L�[�����J�n�v��
2456     void SSH2_send_kexinit(PTInstVar pvar)
2457     {
2458     char cookie[SSH2_COOKIE_LENGTH];
2459     buffer_t *msg;
2460     unsigned char *outmsg;
2461     int len, i;
2462    
2463     msg = buffer_init();
2464     if (msg == NULL) {
2465     // TODO: error check
2466     return;
2467     }
2468     if (pvar->my_kex != NULL)
2469     buffer_free(pvar->my_kex);
2470     pvar->my_kex = msg;
2471    
2472     // ���b�Z�[�W�^�C�v
2473     //SSH2_packet_start(msg, SSH2_MSG_KEXINIT);
2474    
2475     // cookie���Z�b�g
2476     CRYPT_set_random_data(pvar, cookie, sizeof(cookie));
2477     CRYPT_set_server_cookie(pvar, cookie);
2478     buffer_append(msg, cookie, sizeof(cookie));
2479    
2480     // �N���C�A���g���L�[����
2481     for (i = 0 ; i < PROPOSAL_MAX ; i++) {
2482     buffer_put_string(msg, myproposal[i], strlen(myproposal[i]));
2483     }
2484     buffer_put_char(msg, 0);
2485     buffer_put_int(msg, 0);
2486    
2487     len = buffer_len(msg);
2488     outmsg = begin_send_packet(pvar, SSH2_MSG_KEXINIT, len);
2489     memcpy(outmsg, buffer_ptr(msg), len);
2490     finish_send_packet(pvar);
2491    
2492     //buffer_free(msg);
2493     }
2494    
2495    
2496     static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
2497     {
2498     char tmp[1024], *ptr;
2499     SSHCipher cipher = SSH_CIPHER_NONE;
2500    
2501     _snprintf(tmp, sizeof(tmp), my_proposal);
2502     ptr = strtok(tmp, ","); // not thread-safe
2503     while (ptr != NULL) {
2504     // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2505     if (strstr(server_proposal, ptr)) { // match
2506     break;
2507     }
2508     ptr = strtok(NULL, ",");
2509     }
2510     if (strstr(ptr, "3des-cbc")) {
2511     cipher = SSH_CIPHER_3DES_CBC;
2512    
2513     } else if (strstr(ptr, "aes128-cbc")) {
2514     cipher = SSH_CIPHER_AES128;
2515     }
2516    
2517     return (cipher);
2518     }
2519    
2520    
2521     // �����A���S���Y�����L�[�T�C�Y�A�u���b�N�T�C�Y�AMAC�T�C�Y�����������l(we_need)�����������B
2522     static void choose_SSH2_key_maxlength(PTInstVar pvar)
2523     {
2524     int mode, need, val, ctos;
2525     char *macname;
2526     const EVP_MD *md;
2527    
2528     for (mode = 0; mode < MODE_MAX; mode++) {
2529     if (mode == MODE_OUT)
2530     ctos = 1;
2531     else
2532     ctos = 0;
2533     macname = myproposal[PROPOSAL_MAC_ALGS_CTOS + ctos];
2534     val = get_mac_index(macname);
2535     if (val == -1) {
2536     goto error;
2537     }
2538    
2539     // current_keys[]�����������������A������ pvar->ssh2_keys[] ���R�s�[�����B
2540     md = ssh2_macs[val].func();
2541     current_keys[mode].mac.md = md;
2542     current_keys[mode].mac.key_len = current_keys[mode].mac.mac_len = EVP_MD_size(md);
2543     if (ssh2_macs[val].truncatebits != 0) {
2544     current_keys[mode].mac.mac_len = ssh2_macs[val].truncatebits / 8;
2545     }
2546    
2547     // �L�[�T�C�Y���u���b�N�T�C�Y�������������������� (2004.11.7 yutaka)