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 2782 - (hide annotations) (download) (as text)
Mon Jan 24 14:07:07 2005 UTC (19 years, 2 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 133128 byte(s)
・keyboard-interactive認証をサポートした。
 それに伴い、teraterm.iniに "KeyboardInteractive" エントリを追加した。
・バージョンダイアログに OpenSSLバージョン を追加

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    
1035     _snprintf(TTSSH_ID, sizeof(TTSSH_ID),
1036     "SSH-%d.%d-TTSSH/1.5.4 Win32\n",
1037     pvar->protocol_major, pvar->protocol_minor);
1038     TTSSH_ID_len = strlen(TTSSH_ID);
1039    
1040     // for SSH2(yutaka)
1041     // �N���C�A���g�o�[�W�����������i���s���������������j
1042     strncpy(pvar->client_version_string, TTSSH_ID, TTSSH_ID_len);
1043    
1044     if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1045     0) != TTSSH_ID_len) {
1046     notify_fatal_error(pvar,
1047     "An error occurred while sending the SSH ID string.\n"
1048     "The connection will close.");
1049     } else {
1050     // ���s�R�[�h������ (2004.8.4 yutaka)
1051     pvar->server_version_string[--ID_len] = 0;
1052     pvar->client_version_string[--TTSSH_ID_len] = 0;
1053    
1054     // SSH�n���h�����o�^���s��
1055     init_protocol(pvar);
1056    
1057     SSH2_dispatch_init(1);
1058     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1059     }
1060     }
1061    
1062     return TRUE;
1063     }
1064     }
1065     }
1066    
1067     static BOOL handle_exit(PTInstVar pvar)
1068     {
1069     if (grab_payload(pvar, 4)) {
1070     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1071     finish_send_packet(pvar);
1072     notify_closed_connection(pvar);
1073     }
1074     return TRUE;
1075     }
1076    
1077     static BOOL handle_data(PTInstVar pvar)
1078     {
1079     if (grab_payload_limited(pvar, 4)) {
1080     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1081     pvar->ssh_state.payload_datastart = 4;
1082     }
1083     return TRUE;
1084     }
1085    
1086     static BOOL handle_channel_open(PTInstVar pvar)
1087     {
1088     int host_len;
1089     int originator_len;
1090    
1091     if ((pvar->ssh_state.
1092     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1093     if (grab_payload(pvar, 8)
1094     && grab_payload(pvar,
1095     8 + (host_len = get_payload_uint32(pvar, 4)))
1096     && grab_payload(pvar, originator_len =
1097     get_payload_uint32(pvar, host_len + 12))) {
1098     int local_port = get_payload_uint32(pvar, 8 + host_len);
1099    
1100     pvar->ssh_state.payload[8 + host_len] = 0;
1101     FWD_open(pvar, get_payload_uint32(pvar, 0),
1102     pvar->ssh_state.payload + 8, local_port,
1103     pvar->ssh_state.payload + 16 + host_len,
1104     originator_len);
1105     }
1106     } else {
1107     if (grab_payload(pvar, 8)
1108     && grab_payload(pvar,
1109     4 + (host_len =
1110     get_payload_uint32(pvar, 4)))) {
1111     int local_port = get_payload_uint32(pvar, 8 + host_len);
1112    
1113     pvar->ssh_state.payload[8 + host_len] = 0;
1114     FWD_open(pvar, get_payload_uint32(pvar, 0),
1115     pvar->ssh_state.payload + 8, local_port, NULL, 0);
1116     }
1117     }
1118    
1119     return TRUE;
1120     }
1121    
1122     static BOOL handle_X11_channel_open(PTInstVar pvar)
1123     {
1124     int originator_len;
1125    
1126     if ((pvar->ssh_state.
1127     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1128     if (grab_payload(pvar, 8)
1129     && grab_payload(pvar, originator_len =
1130     get_payload_uint32(pvar, 4))) {
1131     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1132     pvar->ssh_state.payload + 8, originator_len);
1133     }
1134     } else {
1135     if (grab_payload(pvar, 4)) {
1136     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0);
1137     }
1138     }
1139    
1140     return TRUE;
1141     }
1142    
1143     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1144     {
1145     if (grab_payload(pvar, 8)) {
1146     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1147     get_payload_uint32(pvar, 4));
1148     }
1149     return FALSE;
1150     }
1151    
1152     static BOOL handle_channel_open_failure(PTInstVar pvar)
1153     {
1154     if (grab_payload(pvar, 4)) {
1155     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1156     }
1157     return FALSE;
1158     }
1159    
1160     static BOOL handle_channel_data(PTInstVar pvar)
1161     {
1162     int len;
1163    
1164     if (grab_payload(pvar, 8)
1165     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1166     FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1167     pvar->ssh_state.payload + 8, len);
1168     }
1169     return TRUE;
1170     }
1171    
1172     static BOOL handle_channel_input_eof(PTInstVar pvar)
1173     {
1174     if (grab_payload(pvar, 4)) {
1175     FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1176     }
1177     return TRUE;
1178     }
1179    
1180     static BOOL handle_channel_output_eof(PTInstVar pvar)
1181     {
1182     if (grab_payload(pvar, 4)) {
1183     FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1184     }
1185     return TRUE;
1186     }
1187    
1188    
1189    
1190     // �n���h�����O�������b�Z�[�W����������
1191    
1192     #define HANDLE_MESSAGE_MAX 30
1193     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1194     static int handle_message_count = 0;
1195     static int handle_message_stage = 0;
1196    
1197     void SSH2_dispatch_init(int stage)
1198     {
1199     handle_message_count = 0;
1200     handle_message_stage = stage;
1201     }
1202    
1203     int SSH2_dispatch_enabled_check(unsigned char message)
1204     {
1205     int i;
1206    
1207     for (i = 0 ; i < handle_message_count ; i++) {
1208     if (handle_messages[i] == message)
1209     return 1;
1210     }
1211     return 0;
1212     }
1213    
1214     void SSH2_dispatch_add_message(unsigned char message)
1215     {
1216    
1217     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1218     // TODO: error check
1219     return;
1220     }
1221    
1222     handle_messages[handle_message_count++] = message;
1223     }
1224    
1225     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1226     {
1227     unsigned char c;
1228    
1229     for (c = begin ; c <= end ; c++) {
1230     SSH2_dispatch_add_message(c);
1231     }
1232     }
1233    
1234    
1235     /* default window/packet sizes for tcp/x11-fwd-channel */
1236     #define CHAN_SES_PACKET_DEFAULT (32*1024)
1237     #define CHAN_SES_WINDOW_DEFAULT (2*CHAN_SES_PACKET_DEFAULT) // READAMOUNT @ pkt.c����������������
1238    
1239     //#define CHAN_TCP_PACKET_DEFAULT (32*1024)
1240     //#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
1241     //#define CHAN_X11_PACKET_DEFAULT (16*1024)
1242     //#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
1243    
1244     // �N���C�A���g��window size���T�[�o���m������
1245     static void do_SSH2_adjust_window_size(PTInstVar pvar)
1246     {
1247     const unsigned int window_size = CHAN_SES_PACKET_DEFAULT;
1248     buffer_t *msg;
1249     unsigned char *outmsg;
1250     int len;
1251    
1252     // ���[�J����window size�������]�T�����������A�����������B
1253     if (pvar->local_window > window_size)
1254     return;
1255    
1256     {
1257     // pty open
1258     msg = buffer_init();
1259     if (msg == NULL) {
1260     // TODO: error check
1261     return;
1262     }
1263     buffer_put_int(msg, pvar->remote_id);
1264     buffer_put_int(msg, window_size - pvar->local_window);
1265    
1266     len = buffer_len(msg);
1267     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, len);
1268     memcpy(outmsg, buffer_ptr(msg), len);
1269     finish_send_packet(pvar);
1270     buffer_free(msg);
1271    
1272     // �N���C�A���g��window size��������
1273     pvar->local_window = window_size;
1274     }
1275    
1276     }
1277    
1278    
1279     static void SSH2_consume_packet_size(PTInstVar pvar, unsigned char message)
1280     {
1281     int len;
1282     char *data;
1283    
1284     if (!(message >= SSH2_MSG_CHANNEL_OPEN_CONFIRMATION && message <= SSH2_MSG_CHANNEL_FAILURE)) {
1285     return;
1286     }
1287    
1288     // 6byte�i�T�C�Y�{�p�f�B���O�{�^�C�v�j���������������~���y�C���[�h
1289     data = pvar->ssh_state.payload;
1290     // �p�P�b�g�T�C�Y - (�p�f�B���O�T�C�Y+1)�G�^���p�P�b�g�T�C�Y
1291     len = pvar->ssh_state.payloadlen;
1292    
1293     pvar->local_window -= (len + 1);
1294    
1295     do_SSH2_adjust_window_size(pvar);
1296    
1297     }
1298    
1299    
1300     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1301     int padding)
1302     {
1303     unsigned char message = prep_packet(pvar, data, len, padding);
1304    
1305    
1306     #ifdef SSH2_DEBUG
1307     // for SSH2(yutaka)
1308     if (SSHv2(pvar)) {
1309     if (pvar->key_done) {
1310     message = message;
1311     }
1312    
1313     if (pvar->userauth_success) {
1314     message = message;
1315     }
1316    
1317     if (pvar->rekeying) {
1318     message = message;
1319     }
1320     }
1321     #endif
1322    
1323     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1324     if (message != SSH_MSG_NONE) {
1325     // ���b�Z�[�W�^�C�v���������n���h�����N��
1326     SSHPacketHandler handler = get_handler(pvar, message);
1327    
1328     // for SSH2(yutaka)
1329     if (SSHv2(pvar)) {
1330     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1331     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1332     char buf[1024];
1333    
1334     _snprintf(buf, sizeof(buf),
1335     "Unexpected SSH2 message(%d) on current stage(%d)", message, handle_message_stage);
1336     notify_fatal_error(pvar, buf);
1337     // abort
1338     }
1339     }
1340    
1341     if (handler == NULL) {
1342     if (SSHv1(pvar)) {
1343     char buf[1024];
1344    
1345     _snprintf(buf, sizeof(buf),
1346     "Unexpected packet type received: %d", message);
1347     buf[sizeof(buf) - 1] = 0;
1348     notify_fatal_error(pvar, buf);
1349     } else {
1350     unsigned char FAR *outmsg =
1351     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1352    
1353     set_uint32(outmsg,
1354     pvar->ssh_state.receiver_sequence_number - 1);
1355     finish_send_packet(pvar);
1356     /* XXX need to decompress incoming packet, but how? */
1357     }
1358     } else {
1359     if (!handler(pvar)) {
1360     deque_handlers(pvar, message);
1361     }
1362     }
1363     }
1364     }
1365    
1366     static BOOL handle_pty_success(PTInstVar pvar)
1367     {
1368     FWD_enter_interactive_mode(pvar);
1369     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1370     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1371     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1372     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1373     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1374     handle_channel_input_eof);
1375     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1376     handle_channel_output_eof);
1377     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1378     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1379     return FALSE;
1380     }
1381    
1382     static BOOL handle_pty_failure(PTInstVar pvar)
1383     {
1384     notify_nonfatal_error(pvar,
1385     "The server cannot allocate a pseudo-terminal. "
1386     "You may encounter some problems with the terminal.");
1387     return handle_pty_success(pvar);
1388     }
1389    
1390     static void prep_pty(PTInstVar pvar)
1391     {
1392     int len = strlen(pvar->ts->TermType);
1393     unsigned char FAR *outmsg =
1394     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1395     4 + len + 16 + sizeof(ssh_ttymodes));
1396     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1397     static const SSHPacketHandler handlers[]
1398     = { handle_pty_success, handle_pty_failure };
1399    
1400     set_uint32(outmsg, len);
1401     memcpy(outmsg + 4, pvar->ts->TermType, len);
1402     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
1403     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
1404     set_uint32(outmsg + 4 + len + 8, 0);
1405     set_uint32(outmsg + 4 + len + 12, 0);
1406     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
1407     finish_send_packet(pvar);
1408    
1409     enque_handlers(pvar, 2, msgs, handlers);
1410    
1411     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
1412     finish_send_packet(pvar);
1413     }
1414    
1415     static void prep_forwarding(PTInstVar pvar)
1416     {
1417     FWD_prep_forwarding(pvar);
1418     prep_pty(pvar);
1419     }
1420    
1421     static void enable_compression(PTInstVar pvar)
1422     {
1423     pvar->ssh_state.compress_stream.zalloc = NULL;
1424     pvar->ssh_state.compress_stream.zfree = NULL;
1425     pvar->ssh_state.compress_stream.opaque = NULL;
1426     if (deflateInit
1427     (&pvar->ssh_state.compress_stream,
1428     pvar->ssh_state.compression_level) != Z_OK) {
1429     notify_fatal_error(pvar,
1430     "An error occurred while setting up compression.\n"
1431     "The connection will close.");
1432     return;
1433     } else {
1434     pvar->ssh_state.compressing = TRUE;
1435     }
1436    
1437     pvar->ssh_state.decompress_stream.zalloc = NULL;
1438     pvar->ssh_state.decompress_stream.zfree = NULL;
1439     pvar->ssh_state.decompress_stream.opaque = NULL;
1440     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
1441     deflateEnd(&pvar->ssh_state.compress_stream);
1442     notify_fatal_error(pvar,
1443     "An error occurred while setting up compression.\n"
1444     "The connection will close.");
1445     return;
1446     } else {
1447     pvar->ssh_state.decompressing = TRUE;
1448     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
1449     &pvar->ssh_state.postdecompress_inbuflen, 1000);
1450     }
1451     }
1452    
1453     static BOOL handle_enable_compression(PTInstVar pvar)
1454     {
1455     enable_compression(pvar);
1456     prep_forwarding(pvar);
1457     return FALSE;
1458     }
1459    
1460     static BOOL handle_disable_compression(PTInstVar pvar)
1461     {
1462     prep_forwarding(pvar);
1463     return FALSE;
1464     }
1465    
1466     static void prep_compression(PTInstVar pvar)
1467     {
1468     if (pvar->session_settings.CompressionLevel > 0) {
1469     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1470     static const SSHPacketHandler handlers[]
1471     = { handle_enable_compression, handle_disable_compression };
1472    
1473     unsigned char FAR *outmsg =
1474     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
1475    
1476     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
1477     finish_send_packet(pvar);
1478    
1479     pvar->ssh_state.compression_level =
1480     pvar->session_settings.CompressionLevel;
1481    
1482     enque_handlers(pvar, 2, msgs, handlers);
1483     } else {
1484     prep_forwarding(pvar);
1485     }
1486     }
1487    
1488     static void enque_simple_auth_handlers(PTInstVar pvar)
1489     {
1490     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1491     static const SSHPacketHandler handlers[]
1492     = { handle_auth_success, handle_auth_failure };
1493    
1494     enque_handlers(pvar, 2, msgs, handlers);
1495     }
1496    
1497     static BOOL handle_rsa_challenge(PTInstVar pvar)
1498     {
1499     int challenge_bytes;
1500    
1501     if (!grab_payload(pvar, 2)) {
1502     return FALSE;
1503     }
1504    
1505     challenge_bytes = get_mpint_len(pvar, 0);
1506    
1507     if (grab_payload(pvar, challenge_bytes)) {
1508     unsigned char FAR *outmsg =
1509     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
1510    
1511     if (CRYPT_generate_RSA_challenge_response
1512     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
1513     AUTH_destroy_cur_cred(pvar);
1514     finish_send_packet(pvar);
1515    
1516     enque_simple_auth_handlers(pvar);
1517     } else {
1518     notify_fatal_error(pvar,
1519     "An error occurred while decrypting the RSA challenge.\n"
1520     "Perhaps the key file is corrupted.");
1521     }
1522     }
1523    
1524     return FALSE;
1525     }
1526    
1527     #define OBFUSCATING_ROUND_TO 32
1528    
1529     static int obfuscating_round_up(PTInstVar pvar, int size)
1530     {
1531     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
1532     }
1533    
1534     static void try_send_credentials(PTInstVar pvar)
1535     {
1536     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
1537     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
1538     static const int RSA_msgs[] =
1539     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
1540     static const SSHPacketHandler RSA_handlers[]
1541     = { handle_rsa_challenge, handle_rsa_auth_refused };
1542     static const int TIS_msgs[] =
1543     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
1544     static const SSHPacketHandler TIS_handlers[]
1545     = { handle_TIS_challenge, handle_auth_failure };
1546    
1547     switch (cred->method) {
1548     case SSH_AUTH_NONE:
1549     return;
1550     case SSH_AUTH_PASSWORD:{
1551     int len = strlen(cred->password);
1552     // Round up password length to discourage traffic analysis
1553     int obfuscated_len = obfuscating_round_up(pvar, len);
1554     unsigned char FAR *outmsg =
1555     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
1556     4 + obfuscated_len);
1557    
1558     notify_verbose_message(pvar,
1559     "Trying PASSWORD authentication...",
1560     LOG_LEVEL_VERBOSE);
1561    
1562     set_uint32(outmsg, obfuscated_len);
1563     memcpy(outmsg + 4, cred->password, len);
1564     memset(outmsg + 4 + len, 0, obfuscated_len - len);
1565     AUTH_destroy_cur_cred(pvar);
1566     enque_simple_auth_handlers(pvar);
1567     break;
1568     }
1569     case SSH_AUTH_RHOSTS:{
1570     int len = strlen(cred->rhosts_client_user);
1571     unsigned char FAR *outmsg =
1572     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
1573    
1574     notify_verbose_message(pvar,
1575     "Trying RHOSTS authentication...",
1576     LOG_LEVEL_VERBOSE);
1577    
1578     set_uint32(outmsg, len);
1579     memcpy(outmsg + 4, cred->rhosts_client_user, len);
1580     AUTH_destroy_cur_cred(pvar);
1581     enque_simple_auth_handlers(pvar);
1582     break;
1583     }
1584     case SSH_AUTH_RSA:{
1585     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
1586     unsigned char FAR *outmsg =
1587     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
1588    
1589     notify_verbose_message(pvar,
1590     "Trying RSA authentication...",
1591     LOG_LEVEL_VERBOSE);
1592    
1593     set_ushort16_MSBfirst(outmsg, len * 8);
1594     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
1595     /* don't destroy the current credentials yet */
1596     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
1597     break;
1598     }
1599     case SSH_AUTH_RHOSTS_RSA:{
1600     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
1601     int name_len = strlen(cred->rhosts_client_user);
1602     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
1603     int index;
1604     unsigned char FAR *outmsg =
1605     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
1606     12 + mod_len + name_len + exp_len);
1607    
1608     notify_verbose_message(pvar,
1609     "Trying RHOSTS+RSA authentication...",
1610     LOG_LEVEL_VERBOSE);
1611    
1612     set_uint32(outmsg, name_len);
1613     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
1614     index = 4 + name_len;
1615    
1616     set_uint32(outmsg + index, 8 * mod_len);
1617     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
1618     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
1619     index += 6 + exp_len;
1620    
1621     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
1622     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
1623     /* don't destroy the current credentials yet */
1624     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
1625     break;
1626     }
1627     case SSH_AUTH_TIS:{
1628     if (cred->password == NULL) {
1629     unsigned char FAR *outmsg =
1630     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
1631    
1632     notify_verbose_message(pvar,
1633     "Trying TIS authentication...",
1634     LOG_LEVEL_VERBOSE);
1635     enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
1636     } else {
1637     int len = strlen(cred->password);
1638     int obfuscated_len = obfuscating_round_up(pvar, len);
1639     unsigned char FAR *outmsg =
1640     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
1641     4 + obfuscated_len);
1642    
1643     notify_verbose_message(pvar, "Sending TIS response",
1644     LOG_LEVEL_VERBOSE);
1645    
1646     set_uint32(outmsg, obfuscated_len);
1647     memcpy(outmsg + 4, cred->password, len);
1648     memset(outmsg + 4 + len, 0, obfuscated_len - len);
1649     enque_simple_auth_handlers(pvar);
1650     }
1651     AUTH_destroy_cur_cred(pvar);
1652     break;
1653     }
1654     default:
1655     notify_fatal_error(pvar,
1656     "Internal error: unsupported authentication method");
1657     return;
1658     }
1659    
1660     finish_send_packet(pvar);
1661     destroy_packet_buf(pvar);
1662    
1663     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
1664     }
1665     }
1666    
1667     static void try_send_user_name(PTInstVar pvar)
1668     {
1669     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
1670     char FAR *username = AUTH_get_user_name(pvar);
1671    
1672     if (username != NULL) {
1673     int len = strlen(username);
1674     int obfuscated_len = obfuscating_round_up(pvar, len);
1675     unsigned char FAR *outmsg =
1676     begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
1677     char buf[1024] = "Sending user name: ";
1678     static const int msgs[] =
1679     { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1680     static const SSHPacketHandler handlers[]
1681     = { handle_noauth_success, handle_auth_required };
1682    
1683     set_uint32(outmsg, obfuscated_len);
1684     memcpy(outmsg + 4, username, len);
1685     memset(outmsg + 4 + len, 0, obfuscated_len - len);
1686     finish_send_packet(pvar);
1687    
1688     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
1689    
1690     strncpy(buf + strlen(buf), username,
1691     sizeof(buf) - strlen(buf) - 2);
1692     buf[sizeof(buf) - 1] = 0;
1693     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1694    
1695     enque_handlers(pvar, 2, msgs, handlers);
1696     }
1697     }
1698     }
1699    
1700     static void send_session_key(PTInstVar pvar)
1701     {
1702     int encrypted_session_key_len;
1703     unsigned char FAR *outmsg;
1704    
1705     if (SSHv1(pvar)) {
1706     encrypted_session_key_len =
1707     CRYPT_get_encrypted_session_key_len(pvar);
1708     }
1709    
1710     if (!CRYPT_choose_ciphers(pvar))
1711     return;
1712    
1713     if (SSHv1(pvar)) {
1714     outmsg =
1715     begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
1716     15 + encrypted_session_key_len);
1717     outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
1718     memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
1719     outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
1720     outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
1721     if (!CRYPT_choose_session_key(pvar, outmsg + 11))
1722     return;
1723     set_uint32(outmsg + 11 + encrypted_session_key_len,
1724     SSH_PROTOFLAG_SCREEN_NUMBER |
1725     SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
1726     finish_send_packet(pvar);
1727     }
1728    
1729     if (!CRYPT_start_encryption(pvar, 1, 1))
1730     return;
1731     notify_established_secure_connection(pvar);
1732    
1733     if (SSHv1(pvar)) {
1734     enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
1735     }
1736    
1737     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
1738    
1739     if (SSHv1(pvar)) {
1740     try_send_user_name(pvar);
1741     }
1742     }
1743    
1744     /*************************
1745     END of message handlers
1746     ************************/
1747    
1748     void SSH_init(PTInstVar pvar)
1749     {
1750     int i;
1751    
1752     buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
1753     buf_create(&pvar->ssh_state.precompress_outbuf,
1754     &pvar->ssh_state.precompress_outbuflen);
1755     buf_create(&pvar->ssh_state.postdecompress_inbuf,
1756     &pvar->ssh_state.postdecompress_inbuflen);
1757     pvar->ssh_state.payload = NULL;
1758     pvar->ssh_state.compressing = FALSE;
1759     pvar->ssh_state.decompressing = FALSE;
1760     pvar->ssh_state.status_flags =
1761     STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
1762     pvar->ssh_state.payload_datalen = 0;
1763     pvar->ssh_state.hostname = NULL;
1764     pvar->ssh_state.server_ID = NULL;
1765     pvar->ssh_state.receiver_sequence_number = 0;
1766     pvar->ssh_state.sender_sequence_number = 0;
1767     for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
1768     pvar->ssh_state.packet_handlers[i] = NULL;
1769     }
1770    
1771     // for SSH2(yutaka)
1772     memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
1773     pvar->userauth_success = 0;
1774     pvar->session_nego_status = 0;
1775 yutakakn 2738 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
1776 yutakakn 2728 pvar->rekeying = 0;
1777     pvar->key_done = 0;
1778 yutakakn 2739 pvar->ssh2_autologin = 0; // autologin disabled(default)
1779 yutakakn 2728
1780     }
1781    
1782     void SSH_open(PTInstVar pvar)
1783     {
1784     pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
1785     pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
1786     pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
1787     }
1788    
1789     void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
1790     {
1791     if (SSHv1(pvar)) {
1792     int len = reason == NULL ? 0 : strlen(reason);
1793     unsigned char FAR *outmsg =
1794     begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
1795    
1796     set_uint32(outmsg, len);
1797     if (reason != NULL) {
1798     memcpy(outmsg + 4, reason, len);
1799     }
1800     finish_send_packet(pvar);
1801    
1802     } else { // for SSH2(yutaka)
1803     buffer_t *msg;
1804     unsigned char *outmsg;
1805     int len;
1806    
1807     // SSH2 server��channel close���`����
1808     msg = buffer_init();
1809     if (msg == NULL) {
1810     // TODO: error check
1811     return;
1812     }
1813     buffer_put_int(msg, pvar->remote_id);
1814    
1815     len = buffer_len(msg);
1816     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
1817     memcpy(outmsg, buffer_ptr(msg), len);
1818     finish_send_packet(pvar);
1819     buffer_free(msg);
1820    
1821     }
1822    
1823     }
1824    
1825     void SSH_notify_host_OK(PTInstVar pvar)
1826     {
1827     if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
1828     pvar->ssh_state.status_flags |= STATUS_HOST_OK;
1829     send_session_key(pvar);
1830     }
1831     }
1832    
1833     void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
1834     {
1835     pvar->ssh_state.win_cols = cols;
1836     pvar->ssh_state.win_rows = rows;
1837    
1838 yutakakn 2771 if (SSHv1(pvar)) {
1839     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
1840     unsigned char FAR *outmsg =
1841     begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
1842 yutakakn 2728
1843 yutakakn 2771 set_uint32(outmsg, rows);
1844     set_uint32(outmsg + 4, cols);
1845     set_uint32(outmsg + 8, 0);
1846     set_uint32(outmsg + 12, 0);
1847     finish_send_packet(pvar);
1848     }
1849    
1850 yutakakn 2777 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
1851     // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
1852 yutakakn 2771 buffer_t *msg;
1853     char *s;
1854     unsigned char *outmsg;
1855     int len;
1856    
1857     msg = buffer_init();
1858     if (msg == NULL) {
1859     // TODO: error check
1860     return;
1861     }
1862     buffer_put_int(msg, pvar->remote_id);
1863     s = "window-change";
1864     buffer_put_string(msg, s, strlen(s));
1865     buffer_put_char(msg, 0); // wantconfirm
1866     buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
1867     buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
1868     buffer_put_int(msg, 480); // XXX:
1869     buffer_put_int(msg, 640); // XXX:
1870     len = buffer_len(msg);
1871     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
1872     memcpy(outmsg, buffer_ptr(msg), len);
1873 yutakakn 2728 finish_send_packet(pvar);
1874 yutakakn 2771 buffer_free(msg);
1875    
1876 yutakakn 2777 } else {
1877     // SSH�����������������������B
1878    
1879 yutakakn 2728 }
1880 yutakakn 2777
1881 yutakakn 2728 }
1882    
1883     int SSH_get_min_packet_size(PTInstVar pvar)
1884     {
1885     if (SSHv1(pvar)) {
1886     return 12;
1887     } else {
1888     int block_size = CRYPT_get_decryption_block_size(pvar);
1889    
1890     return max(16, block_size);
1891     }
1892     }
1893    
1894     /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
1895     at least 5 bytes must be decrypted */
1896     void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
1897     {
1898     if (SSHv2(pvar)) {
1899     CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
1900     }
1901     }
1902    
1903     int SSH_get_clear_MAC_size(PTInstVar pvar)
1904     {
1905     if (SSHv1(pvar)) {
1906     return 0;
1907     } else {
1908     return CRYPT_get_receiver_MAC_size(pvar);
1909     }
1910     }
1911    
1912     void SSH_notify_user_name(PTInstVar pvar)
1913     {
1914     try_send_user_name(pvar);
1915     }
1916    
1917     void SSH_notify_cred(PTInstVar pvar)
1918     {
1919     try_send_credentials(pvar);
1920     }
1921    
1922     void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
1923     {
1924     if (SSHv1(pvar)) {
1925     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
1926     return;
1927     }
1928    
1929     while (buflen > 0) {
1930     int len =
1931     buflen >
1932     SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
1933     unsigned char FAR *outmsg =
1934     begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
1935    
1936     set_uint32(outmsg, len);
1937    
1938     if (pvar->ssh_state.compressing) {
1939     buf_ensure_size(&pvar->ssh_state.outbuf,
1940     &pvar->ssh_state.outbuflen,
1941     len + (len >> 6) + 50);
1942     pvar->ssh_state.compress_stream.next_in =
1943     pvar->ssh_state.precompress_outbuf;
1944     pvar->ssh_state.compress_stream.avail_in = 5;
1945     pvar->ssh_state.compress_stream.next_out =
1946     pvar->ssh_state.outbuf + 12;
1947     pvar->ssh_state.compress_stream.avail_out =
1948     pvar->ssh_state.outbuflen - 12;
1949    
1950     if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) !=
1951     Z_OK) {
1952     notify_fatal_error(pvar, "Error compressing packet data");
1953     return;
1954     }
1955    
1956     pvar->ssh_state.compress_stream.next_in =
1957     (unsigned char FAR *) buf;
1958     pvar->ssh_state.compress_stream.avail_in = len;
1959    
1960     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
1961     Z_OK) {
1962     notify_fatal_error(pvar, "Error compressing packet data");
1963     return;
1964     }
1965     } else {
1966     memcpy(outmsg + 4, buf, len);
1967     }
1968    
1969     finish_send_packet_special(pvar, 1);
1970    
1971     buflen -= len;
1972     buf += len;
1973     }
1974    
1975     } else { // for SSH2(yutaka)
1976     buffer_t *msg;
1977     unsigned char *outmsg;
1978     int len;
1979    
1980     msg = buffer_init();
1981     if (msg == NULL) {
1982     // TODO: error check
1983     return;
1984     }
1985     buffer_put_int(msg, pvar->remote_id);
1986     buffer_put_string(msg, (char *)buf, buflen);
1987    
1988     len = buffer_len(msg);
1989     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
1990     memcpy(outmsg, buffer_ptr(msg), len);
1991     finish_send_packet(pvar);
1992     buffer_free(msg);
1993    
1994     // remote window size������
1995     pvar->remote_window -= len;
1996    
1997     }
1998    
1999     }
2000    
2001     int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2002     {
2003     int num_bytes = pvar->ssh_state.payload_datalen;
2004    
2005     if (num_bytes > len) {
2006     num_bytes = len;
2007     }
2008    
2009     if (!pvar->ssh_state.decompressing) {
2010     memcpy(dest,
2011     pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2012     num_bytes);
2013     pvar->ssh_state.payload_datastart += num_bytes;
2014     } else if (num_bytes > 0) {
2015     pvar->ssh_state.decompress_stream.next_out = dest;
2016     pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2017    
2018     if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) !=
2019     Z_OK) {
2020     notify_fatal_error(pvar,
2021     "Invalid compressed data in received packet");
2022     return 0;
2023     }
2024     }
2025    
2026     pvar->ssh_state.payload_datalen -= num_bytes;
2027    
2028     return num_bytes;
2029     }
2030    
2031     void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2032     {
2033     char buf[1024];
2034     char buf2[1024];
2035    
2036     if (pvar->ssh_state.compressing) {
2037     unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2038     unsigned long total_out =
2039     pvar->ssh_state.compress_stream.total_out;
2040    
2041     if (total_out > 0) {
2042     _snprintf(buf, sizeof(buf), "level %d; ratio %.1f (%ld:%ld)",
2043     pvar->ssh_state.compression_level,
2044     ((double) total_in) / total_out, total_in,
2045     total_out);
2046     } else {
2047     _snprintf(buf, sizeof(buf), "level %d",
2048     pvar->ssh_state.compression_level);
2049     }
2050     } else {
2051     strcpy(buf, "none");
2052     }
2053     buf[sizeof(buf) - 1] = 0;
2054    
2055     if (pvar->ssh_state.decompressing) {
2056     unsigned long total_in =
2057     pvar->ssh_state.decompress_stream.total_in;
2058     unsigned long total_out =
2059     pvar->ssh_state.decompress_stream.total_out;
2060    
2061     if (total_in > 0) {
2062     _snprintf(buf2, sizeof(buf2), "level %d; ratio %.1f (%ld:%ld)",
2063     pvar->ssh_state.compression_level,
2064     ((double) total_out) / total_in, total_out,
2065     total_in);
2066     } else {
2067     _snprintf(buf2, sizeof(buf2), "level %d",
2068     pvar->ssh_state.compression_level);
2069     }
2070     } else {
2071     strcpy(buf2, "none");
2072     }
2073     buf2[sizeof(buf2) - 1] = 0;
2074    
2075     _snprintf(dest, len, "Upstream %s; Downstream %s", buf, buf2);
2076     dest[len - 1] = 0;
2077     }
2078    
2079     void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2080     {
2081     strncpy(dest, pvar->ssh_state.server_ID == NULL ? "Unknown"
2082     : pvar->ssh_state.server_ID, len);
2083     dest[len - 1] = 0;
2084     }
2085    
2086     void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2087     int len)
2088     {
2089     if (pvar->protocol_major == 0) {
2090     strncpy(dest, "Unknown", len);
2091     } else {
2092     _snprintf(dest, len, "%d.%d", pvar->protocol_major,
2093     pvar->protocol_minor);
2094     }
2095     dest[len - 1] = 0;
2096     }
2097    
2098     void SSH_end(PTInstVar pvar)
2099     {
2100     int i;
2101    
2102     for (i = 0; i < 256; i++) {
2103     SSHPacketHandlerItem FAR *first_item =
2104     pvar->ssh_state.packet_handlers[i];
2105    
2106     if (first_item != NULL) {
2107     SSHPacketHandlerItem FAR *item = first_item;
2108    
2109     do {
2110     SSHPacketHandlerItem FAR *cur_item = item;
2111    
2112     item = item->next_for_message;
2113     free(cur_item);
2114     } while (item != first_item);
2115     }
2116     pvar->ssh_state.packet_handlers[i] = NULL;
2117     }
2118    
2119     free(pvar->ssh_state.hostname);
2120     pvar->ssh_state.hostname = NULL;
2121     free(pvar->ssh_state.server_ID);
2122     pvar->ssh_state.server_ID = NULL;
2123     buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2124     buf_destroy(&pvar->ssh_state.precompress_outbuf,
2125     &pvar->ssh_state.precompress_outbuflen);
2126     buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2127     &pvar->ssh_state.postdecompress_inbuflen);
2128    
2129     if (pvar->ssh_state.compressing) {
2130     deflateEnd(&pvar->ssh_state.compress_stream);
2131     pvar->ssh_state.compressing = FALSE;
2132     }
2133     if (pvar->ssh_state.decompressing) {
2134     inflateEnd(&pvar->ssh_state.decompress_stream);
2135     pvar->ssh_state.decompressing = FALSE;
2136     }
2137 yutakakn 2766
2138     #if 1
2139     // SSH2���f�[�^���������� (2004.12.27 yutaka)
2140     if (SSHv2(pvar)) {
2141     if (pvar->kexdh) {
2142     DH_free(pvar->kexdh);
2143     pvar->kexdh = NULL;
2144     }
2145     memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2146     memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2147    
2148     if (pvar->my_kex != NULL) {
2149     buffer_free(pvar->my_kex);
2150     pvar->my_kex = NULL;
2151     }
2152     if (pvar->peer_kex != NULL) {
2153     buffer_free(pvar->peer_kex);
2154     pvar->peer_kex = NULL;
2155     }
2156    
2157     pvar->we_need = 0;
2158     pvar->key_done = 0;
2159     pvar->rekeying = 0;
2160    
2161     if (pvar->session_id != NULL) {
2162     free(pvar->session_id);
2163     pvar->session_id = NULL;
2164     }
2165     pvar->session_id_len = 0;
2166    
2167     pvar->userauth_success = 0;
2168     pvar->remote_id = 0;
2169     pvar->session_nego_status = 0;
2170    
2171     pvar->ssh_heartbeat_tick = 0;
2172     }
2173     #endif
2174    
2175 yutakakn 2728 }
2176    
2177     /* support for port forwarding */
2178     void SSH_channel_send(PTInstVar pvar, uint32 remote_channel_num,
2179     unsigned char FAR * buf, int len)
2180     {
2181     unsigned char FAR *outmsg =
2182     begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2183    
2184     set_uint32(outmsg, remote_channel_num);
2185     set_uint32(outmsg + 4, len);
2186    
2187     if (pvar->ssh_state.compressing) {
2188     buf_ensure_size(&pvar->ssh_state.outbuf,
2189     &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2190     pvar->ssh_state.compress_stream.next_in =
2191     pvar->ssh_state.precompress_outbuf;
2192     pvar->ssh_state.compress_stream.avail_in = 9;
2193     pvar->ssh_state.compress_stream.next_out =
2194     pvar->ssh_state.outbuf + 12;
2195     pvar->ssh_state.compress_stream.avail_out =
2196     pvar->ssh_state.outbuflen - 12;
2197    
2198     if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2199     notify_fatal_error(pvar, "Error compressing packet data");
2200     return;
2201     }
2202    
2203     pvar->ssh_state.compress_stream.next_in =
2204     (unsigned char FAR *) buf;
2205     pvar->ssh_state.compress_stream.avail_in = len;
2206    
2207     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2208     Z_OK) {
2209     notify_fatal_error(pvar, "Error compressing packet data");
2210     return;
2211     }
2212     } else {
2213     memcpy(outmsg + 8, buf, len);
2214     }
2215    
2216     finish_send_packet_special(pvar, 1);
2217     }
2218    
2219     void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2220     {
2221     unsigned char FAR *outmsg =
2222     begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2223    
2224     set_uint32(outmsg, remote_channel_num);
2225     finish_send_packet(pvar);
2226     }
2227    
2228     void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2229     uint32 local_channel_num)
2230     {
2231     unsigned char FAR *outmsg =
2232     begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2233    
2234     set_uint32(outmsg, remote_channel_num);
2235     set_uint32(outmsg + 4, local_channel_num);
2236     finish_send_packet(pvar);
2237     }
2238    
2239     void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2240     {
2241     unsigned char FAR *outmsg =
2242     begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2243    
2244     set_uint32(outmsg, remote_channel_num);
2245     finish_send_packet(pvar);
2246     }
2247    
2248     void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num)
2249     {
2250     unsigned char FAR *outmsg =
2251     begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2252    
2253     set_uint32(outmsg, remote_channel_num);
2254     finish_send_packet(pvar);
2255     }
2256    
2257     void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2258     char FAR * to_local_host, int to_local_port)
2259     {
2260     int host_len = strlen(to_local_host);
2261     unsigned char FAR *outmsg =
2262     begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2263     12 + host_len);
2264    
2265     set_uint32(outmsg, from_server_port);
2266     set_uint32(outmsg + 4, host_len);
2267     memcpy(outmsg + 8, to_local_host, host_len);
2268     set_uint32(outmsg + 8 + host_len, to_local_port);
2269     finish_send_packet(pvar);
2270    
2271     enque_forwarding_request_handlers(pvar);
2272     }
2273    
2274     void SSH_request_X11_forwarding(PTInstVar pvar,
2275     char FAR * auth_protocol,
2276     unsigned char FAR * auth_data,
2277     int auth_data_len, int screen_num)
2278     {
2279     int protocol_len = strlen(auth_protocol);
2280     int data_len = auth_data_len * 2;
2281     unsigned char FAR *outmsg =
2282     begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING,
2283     12 + protocol_len + data_len);
2284     int i;
2285     char FAR *auth_data_ptr;
2286    
2287     set_uint32(outmsg, protocol_len);
2288     memcpy(outmsg + 4, auth_protocol, protocol_len);
2289     set_uint32(outmsg + 4 + protocol_len, data_len);
2290     auth_data_ptr = outmsg + 8 + protocol_len;
2291     for (i = 0; i < auth_data_len; i++) {
2292     sprintf(auth_data_ptr + i * 2, "%.2x", auth_data[i]);
2293     }
2294     set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
2295    
2296     finish_send_packet(pvar);
2297    
2298     enque_forwarding_request_handlers(pvar);
2299     }
2300    
2301     void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
2302     char FAR * to_remote_host, int to_remote_port,
2303     char FAR * originator)
2304     {
2305     static const int msgs[]
2306     = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
2307     static const SSHPacketHandler handlers[]
2308     = { handle_channel_open_confirmation, handle_channel_open_failure };
2309    
2310     int host_len = strlen(to_remote_host);
2311    
2312     if ((pvar->ssh_state.
2313     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
2314     int originator_len = strlen(originator);
2315     unsigned char FAR *outmsg =
2316     begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2317     16 + host_len + originator_len);
2318    
2319     set_uint32(outmsg, local_channel_num);
2320     set_uint32(outmsg + 4, host_len);
2321     memcpy(outmsg + 8, to_remote_host, host_len);
2322     set_uint32(outmsg + 8 + host_len, to_remote_port);
2323     set_uint32(outmsg + 12 + host_len, originator_len);
2324     memcpy(outmsg + 16 + host_len, originator, originator_len);
2325     } else {
2326     unsigned char FAR *outmsg =
2327     begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2328     12 + host_len);
2329    
2330     set_uint32(outmsg, local_channel_num);
2331     set_uint32(outmsg + 4, host_len);
2332     memcpy(outmsg + 8, to_remote_host, host_len);
2333     set_uint32(outmsg + 8 + host_len, to_remote_port);
2334     }
2335    
2336     finish_send_packet(pvar);
2337    
2338     enque_handlers(pvar, 2, msgs, handlers);
2339     }
2340    
2341    
2342     /////////////////////////////////////////////////////////////////////////////
2343     //
2344     // SSH2 protocol procedure in the following code:
2345     //
2346     /////////////////////////////////////////////////////////////////////////////
2347    
2348     void debug_print(int no, char *msg, int len)
2349     {
2350     #ifdef _DEBUG
2351     FILE *fp;
2352     char file[128];
2353    
2354     sprintf(file, "dump%d.bin", no);
2355    
2356     fp = fopen(file, "wb");
2357     if (fp == NULL)
2358     return;
2359    
2360     fwrite(msg, 1, len, fp);
2361    
2362     fclose(fp);
2363     #endif
2364     }
2365    
2366     // �N���C�A���g�����T�[�o������������
2367     #ifdef SSH2_DEBUG
2368     static char *myproposal[PROPOSAL_MAX] = {
2369 yutakakn 2759 "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2370     // "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2371     // "ssh-rsa,ssh-dss",
2372     "ssh-dss,ssh-rsa",
2373 yutakakn 2728 "3des-cbc,aes128-cbc",
2374     "3des-cbc,aes128-cbc",
2375 yutakakn 2758 "hmac-md5,hmac-sha1",
2376     "hmac-md5,hmac-sha1",
2377     // "hmac-sha1,hmac-md5",
2378     // "hmac-sha1,hmac-md5",
2379 yutakakn 2757 // "hmac-sha1",
2380     // "hmac-sha1",
2381 yutakakn 2728 "none",
2382     "none",
2383     "",
2384     "",
2385     };
2386     #else
2387     static char *myproposal[PROPOSAL_MAX] = {
2388 yutakakn 2758 "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2389 yutakakn 2728 "ssh-rsa,ssh-dss",
2390     "3des-cbc,aes128-cbc",
2391     "3des-cbc,aes128-cbc",
2392 yutakakn 2757 "hmac-sha1,hmac-md5",
2393     "hmac-sha1,hmac-md5",
2394 yutakakn 2728 "none",
2395     "none",
2396     "",
2397     "",
2398     };
2399     #endif
2400    
2401    
2402     typedef struct ssh2_cipher {
2403     SSHCipher cipher;
2404     char *name;
2405     int block_size;
2406     int key_len;
2407     const EVP_CIPHER *(*func)(void);
2408     } ssh2_cipher_t;
2409    
2410     ssh2_cipher_t ssh2_ciphers[] = {
2411     {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
2412     {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
2413     {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
2414     };
2415    
2416    
2417     typedef struct ssh2_mac {
2418     char *name;
2419     const EVP_MD *(*func)(void);
2420     int truncatebits;
2421     } ssh2_mac_t;
2422    
2423     ssh2_mac_t ssh2_macs[] = {
2424     {"hmac-sha1", EVP_sha1, 0},
2425     {"hmac-md5", EVP_md5, 0},
2426     {NULL, NULL, 0},
2427     };
2428    
2429     static Newkeys current_keys[MODE_MAX];
2430    
2431    
2432     #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
2433    
2434    
2435     static int get_cipher_block_size(SSHCipher cipher)
2436     {
2437     ssh2_cipher_t *ptr = ssh2_ciphers;
2438     int val = 0;
2439    
2440     while (ptr->name != NULL) {
2441     if (cipher == ptr->cipher) {
2442     val = ptr->block_size;
2443     break;
2444     }
2445     ptr++;
2446     }
2447     return (val);
2448     }
2449    
2450     static int get_cipher_key_len(SSHCipher cipher)
2451     {
2452     ssh2_cipher_t *ptr = ssh2_ciphers;
2453     int val = 0;
2454    
2455     while (ptr->name != NULL) {
2456     if (cipher == ptr->cipher) {
2457     val = ptr->key_len;
2458     break;
2459     }
2460     ptr++;
2461     }
2462     return (val);
2463     }
2464    
2465    
2466 yutakakn 2757 #if 0
2467 yutakakn 2728 static int get_mac_index(char *name)
2468     {
2469     ssh2_mac_t *ptr = ssh2_macs;
2470     int val = -1;
2471    
2472     while (ptr->name != NULL) {
2473     if (strcmp(ptr->name, name) == 0) {
2474     val = ptr - ssh2_macs;
2475     break;
2476     }
2477     ptr++;
2478     }
2479     return (val);
2480     }
2481 yutakakn 2757 #endif
2482 yutakakn 2728
2483    
2484     static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
2485     {
2486     FILE *fp;
2487     char filename[256];
2488    
2489     _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
2490    
2491     fp = fopen(filename, "wb");
2492     if (fp == NULL)
2493     return;
2494    
2495     fwrite(buf, 1, len, fp);
2496    
2497     fclose(fp);
2498     }
2499    
2500    
2501     void SSH2_packet_start(buffer_t *msg, unsigned char type)
2502     {
2503     unsigned char buf[9];
2504     int len = 6;
2505    
2506     memset(buf, 0, sizeof(buf));
2507     buf[len - 1] = type;
2508     buffer_clear(msg);
2509     buffer_append(msg, buf, len);
2510     }
2511    
2512    
2513     // the caller is normalize_cipher_order()
2514     void SSH2_update_cipher_myproposal(PTInstVar pvar)
2515     {
2516     static char buf[128]; // TODO: malloc()��������
2517     int cipher;
2518     int len, i;
2519    
2520     // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
2521     buf[0] = '\0';
2522     for (i = 0 ; pvar->ts_SSH->CipherOrder[i] != 0 ; i++) {
2523     cipher = pvar->ts_SSH->CipherOrder[i] - '0';
2524     if (cipher == 0) // disabled line
2525     break;
2526     if (cipher == SSH_CIPHER_AES128) {
2527     strcat(buf, "aes128-cbc,");
2528     }
2529     if (cipher == SSH_CIPHER_3DES_CBC) {
2530     strcat(buf, "3des-cbc,");
2531     }
2532     }
2533     if (buf[0] != '\0') {
2534     len = strlen(buf);
2535     buf[len - 1] = '\0'; // get rid of comma
2536     myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
2537     myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
2538     }
2539     }
2540    
2541    
2542     // �N���C�A���g�����T�[�o�����L�[�����J�n�v��
2543     void SSH2_send_kexinit(PTInstVar pvar)
2544     {
2545