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 2777 - (hide annotations) (download) (as text)
Thu Jan 6 12:29:07 2005 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 129771 byte(s)
telnet接続時にターミナルサイズ変更を行うと、アプリケーションエラーとなるバグを修正。

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