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 2793 - (hide annotations) (download) (as text)
Thu Mar 3 13:28:23 2005 UTC (19 years, 1 month ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 133488 byte(s)
クライアントのSSHバージョンを ttxssh.dll から取得して、サーバへ送るようにした。

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