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 2766 - (hide annotations) (download) (as text)
Mon Dec 27 14:05:08 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 127977 byte(s)
'Auto window close'が有効の場合、切断後の接続ができない問題を修正した。
 ・スレッドの終了待ち合わせ処理の追加
 ・確保済みSSHリソースの解放

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     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
1837     unsigned char FAR *outmsg =
1838     begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
1839    
1840     set_uint32(outmsg, rows);
1841     set_uint32(outmsg + 4, cols);
1842     set_uint32(outmsg + 8, 0);
1843     set_uint32(outmsg + 12, 0);
1844     finish_send_packet(pvar);
1845     }
1846     }
1847    
1848     int SSH_get_min_packet_size(PTInstVar pvar)
1849     {
1850     if (SSHv1(pvar)) {
1851     return 12;
1852     } else {
1853     int block_size = CRYPT_get_decryption_block_size(pvar);
1854    
1855     return max(16, block_size);
1856     }
1857     }
1858    
1859     /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
1860     at least 5 bytes must be decrypted */
1861     void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
1862     {
1863     if (SSHv2(pvar)) {
1864     CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
1865     }
1866     }
1867    
1868     int SSH_get_clear_MAC_size(PTInstVar pvar)
1869     {
1870     if (SSHv1(pvar)) {
1871     return 0;
1872     } else {
1873     return CRYPT_get_receiver_MAC_size(pvar);
1874     }
1875     }
1876    
1877     void SSH_notify_user_name(PTInstVar pvar)
1878     {
1879     try_send_user_name(pvar);
1880     }
1881    
1882     void SSH_notify_cred(PTInstVar pvar)
1883     {
1884     try_send_credentials(pvar);
1885     }
1886    
1887     void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen)
1888     {
1889     if (SSHv1(pvar)) {
1890     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
1891     return;
1892     }
1893    
1894     while (buflen > 0) {
1895     int len =
1896     buflen >
1897     SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
1898     unsigned char FAR *outmsg =
1899     begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
1900    
1901     set_uint32(outmsg, len);
1902    
1903     if (pvar->ssh_state.compressing) {
1904     buf_ensure_size(&pvar->ssh_state.outbuf,
1905     &pvar->ssh_state.outbuflen,
1906     len + (len >> 6) + 50);
1907     pvar->ssh_state.compress_stream.next_in =
1908     pvar->ssh_state.precompress_outbuf;
1909     pvar->ssh_state.compress_stream.avail_in = 5;
1910     pvar->ssh_state.compress_stream.next_out =
1911     pvar->ssh_state.outbuf + 12;
1912     pvar->ssh_state.compress_stream.avail_out =
1913     pvar->ssh_state.outbuflen - 12;
1914    
1915     if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) !=
1916     Z_OK) {
1917     notify_fatal_error(pvar, "Error compressing packet data");
1918     return;
1919     }
1920    
1921     pvar->ssh_state.compress_stream.next_in =
1922     (unsigned char FAR *) buf;
1923     pvar->ssh_state.compress_stream.avail_in = len;
1924    
1925     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
1926     Z_OK) {
1927     notify_fatal_error(pvar, "Error compressing packet data");
1928     return;
1929     }
1930     } else {
1931     memcpy(outmsg + 4, buf, len);
1932     }
1933    
1934     finish_send_packet_special(pvar, 1);
1935    
1936     buflen -= len;
1937     buf += len;
1938     }
1939    
1940     } else { // for SSH2(yutaka)
1941     buffer_t *msg;
1942     unsigned char *outmsg;
1943     int len;
1944    
1945     msg = buffer_init();
1946     if (msg == NULL) {
1947     // TODO: error check
1948     return;
1949     }
1950     buffer_put_int(msg, pvar->remote_id);
1951     buffer_put_string(msg, (char *)buf, buflen);
1952    
1953     len = buffer_len(msg);
1954     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
1955     memcpy(outmsg, buffer_ptr(msg), len);
1956     finish_send_packet(pvar);
1957     buffer_free(msg);
1958    
1959     // remote window size������
1960     pvar->remote_window -= len;
1961    
1962     }
1963    
1964     }
1965    
1966     int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
1967     {
1968     int num_bytes = pvar->ssh_state.payload_datalen;
1969    
1970     if (num_bytes > len) {
1971     num_bytes = len;
1972     }
1973    
1974     if (!pvar->ssh_state.decompressing) {
1975     memcpy(dest,
1976     pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
1977     num_bytes);
1978     pvar->ssh_state.payload_datastart += num_bytes;
1979     } else if (num_bytes > 0) {
1980     pvar->ssh_state.decompress_stream.next_out = dest;
1981     pvar->ssh_state.decompress_stream.avail_out = num_bytes;
1982    
1983     if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) !=
1984     Z_OK) {
1985     notify_fatal_error(pvar,
1986     "Invalid compressed data in received packet");
1987     return 0;
1988     }
1989     }
1990    
1991     pvar->ssh_state.payload_datalen -= num_bytes;
1992    
1993     return num_bytes;
1994     }
1995    
1996     void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
1997     {
1998     char buf[1024];
1999     char buf2[1024];
2000    
2001     if (pvar->ssh_state.compressing) {
2002     unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2003     unsigned long total_out =
2004     pvar->ssh_state.compress_stream.total_out;
2005    
2006     if (total_out > 0) {
2007     _snprintf(buf, sizeof(buf), "level %d; ratio %.1f (%ld:%ld)",
2008     pvar->ssh_state.compression_level,
2009     ((double) total_in) / total_out, total_in,
2010     total_out);
2011     } else {
2012     _snprintf(buf, sizeof(buf), "level %d",
2013     pvar->ssh_state.compression_level);
2014     }
2015     } else {
2016     strcpy(buf, "none");
2017     }
2018     buf[sizeof(buf) - 1] = 0;
2019    
2020     if (pvar->ssh_state.decompressing) {
2021     unsigned long total_in =
2022     pvar->ssh_state.decompress_stream.total_in;
2023     unsigned long total_out =
2024     pvar->ssh_state.decompress_stream.total_out;
2025    
2026     if (total_in > 0) {
2027     _snprintf(buf2, sizeof(buf2), "level %d; ratio %.1f (%ld:%ld)",
2028     pvar->ssh_state.compression_level,
2029     ((double) total_out) / total_in, total_out,
2030     total_in);
2031     } else {
2032     _snprintf(buf2, sizeof(buf2), "level %d",
2033     pvar->ssh_state.compression_level);
2034     }
2035     } else {
2036     strcpy(buf2, "none");
2037     }
2038     buf2[sizeof(buf2) - 1] = 0;
2039    
2040     _snprintf(dest, len, "Upstream %s; Downstream %s", buf, buf2);
2041     dest[len - 1] = 0;
2042     }
2043    
2044     void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2045     {
2046     strncpy(dest, pvar->ssh_state.server_ID == NULL ? "Unknown"
2047     : pvar->ssh_state.server_ID, len);
2048     dest[len - 1] = 0;
2049     }
2050    
2051     void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2052     int len)
2053     {
2054     if (pvar->protocol_major == 0) {
2055     strncpy(dest, "Unknown", len);
2056     } else {
2057     _snprintf(dest, len, "%d.%d", pvar->protocol_major,
2058     pvar->protocol_minor);
2059     }
2060     dest[len - 1] = 0;
2061     }
2062    
2063     void SSH_end(PTInstVar pvar)
2064     {
2065     int i;
2066    
2067     for (i = 0; i < 256; i++) {
2068     SSHPacketHandlerItem FAR *first_item =
2069     pvar->ssh_state.packet_handlers[i];
2070    
2071     if (first_item != NULL) {
2072     SSHPacketHandlerItem FAR *item = first_item;
2073    
2074     do {
2075     SSHPacketHandlerItem FAR *cur_item = item;
2076    
2077     item = item->next_for_message;
2078     free(cur_item);
2079     } while (item != first_item);
2080     }
2081     pvar->ssh_state.packet_handlers[i] = NULL;
2082     }
2083    
2084     free(pvar->ssh_state.hostname);
2085     pvar->ssh_state.hostname = NULL;
2086     free(pvar->ssh_state.server_ID);
2087     pvar->ssh_state.server_ID = NULL;
2088     buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2089     buf_destroy(&pvar->ssh_state.precompress_outbuf,
2090     &pvar->ssh_state.precompress_outbuflen);
2091     buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2092     &pvar->ssh_state.postdecompress_inbuflen);
2093    
2094     if (pvar->ssh_state.compressing) {
2095     deflateEnd(&pvar->ssh_state.compress_stream);
2096     pvar->ssh_state.compressing = FALSE;
2097     }
2098     if (pvar->ssh_state.decompressing) {
2099     inflateEnd(&pvar->ssh_state.decompress_stream);
2100     pvar->ssh_state.decompressing = FALSE;
2101     }
2102 yutakakn 2766
2103     #if 1
2104     // SSH2���f�[�^���������� (2004.12.27 yutaka)
2105     if (SSHv2(pvar)) {
2106     if (pvar->kexdh) {
2107     DH_free(pvar->kexdh);
2108     pvar->kexdh = NULL;
2109     }
2110     memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2111     memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2112    
2113     if (pvar->my_kex != NULL) {
2114     buffer_free(pvar->my_kex);
2115     pvar->my_kex = NULL;
2116     }
2117     if (pvar->peer_kex != NULL) {
2118     buffer_free(pvar->peer_kex);
2119     pvar->peer_kex = NULL;
2120     }
2121    
2122     pvar->we_need = 0;
2123     pvar->key_done = 0;
2124     pvar->rekeying = 0;
2125    
2126     if (pvar->session_id != NULL) {
2127     free(pvar->session_id);
2128     pvar->session_id = NULL;
2129     }
2130     pvar->session_id_len = 0;
2131    
2132     pvar->userauth_success = 0;
2133     pvar->remote_id = 0;
2134     pvar->session_nego_status = 0;
2135    
2136     pvar->ssh_heartbeat_tick = 0;
2137     }
2138     #endif
2139    
2140 yutakakn 2728 }
2141    
2142     /* support for port forwarding */
2143     void SSH_channel_send(PTInstVar pvar, uint32 remote_channel_num,
2144     unsigned char FAR * buf, int len)
2145     {
2146     unsigned char FAR *outmsg =
2147     begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2148    
2149     set_uint32(outmsg, remote_channel_num);
2150     set_uint32(outmsg + 4, len);
2151    
2152     if (pvar->ssh_state.compressing) {
2153     buf_ensure_size(&pvar->ssh_state.outbuf,
2154     &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2155     pvar->ssh_state.compress_stream.next_in =
2156     pvar->ssh_state.precompress_outbuf;
2157     pvar->ssh_state.compress_stream.avail_in = 9;
2158     pvar->ssh_state.compress_stream.next_out =
2159     pvar->ssh_state.outbuf + 12;
2160     pvar->ssh_state.compress_stream.avail_out =
2161     pvar->ssh_state.outbuflen - 12;
2162    
2163     if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2164     notify_fatal_error(pvar, "Error compressing packet data");
2165     return;
2166     }
2167    
2168     pvar->ssh_state.compress_stream.next_in =
2169     (unsigned char FAR *) buf;
2170     pvar->ssh_state.compress_stream.avail_in = len;
2171    
2172     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2173     Z_OK) {
2174     notify_fatal_error(pvar, "Error compressing packet data");
2175     return;
2176     }
2177     } else {
2178     memcpy(outmsg + 8, buf, len);
2179     }
2180    
2181     finish_send_packet_special(pvar, 1);
2182     }
2183    
2184     void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2185     {
2186     unsigned char FAR *outmsg =
2187     begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2188    
2189     set_uint32(outmsg, remote_channel_num);
2190     finish_send_packet(pvar);
2191     }
2192    
2193     void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
2194     uint32 local_channel_num)
2195     {
2196     unsigned char FAR *outmsg =
2197     begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
2198    
2199     set_uint32(outmsg, remote_channel_num);
2200     set_uint32(outmsg + 4, local_channel_num);
2201     finish_send_packet(pvar);
2202     }
2203    
2204     void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2205     {
2206     unsigned char FAR *outmsg =
2207     begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2208    
2209     set_uint32(outmsg, remote_channel_num);
2210     finish_send_packet(pvar);
2211     }
2212    
2213     void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num)
2214     {
2215     unsigned char FAR *outmsg =
2216     begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2217    
2218     set_uint32(outmsg, remote_channel_num);
2219     finish_send_packet(pvar);
2220     }
2221    
2222     void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
2223     char FAR * to_local_host, int to_local_port)
2224     {
2225     int host_len = strlen(to_local_host);
2226     unsigned char FAR *outmsg =
2227     begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
2228     12 + host_len);
2229    
2230     set_uint32(outmsg, from_server_port);
2231     set_uint32(outmsg + 4, host_len);
2232     memcpy(outmsg + 8, to_local_host, host_len);
2233     set_uint32(outmsg + 8 + host_len, to_local_port);
2234     finish_send_packet(pvar);
2235    
2236     enque_forwarding_request_handlers(pvar);
2237     }
2238    
2239     void SSH_request_X11_forwarding(PTInstVar pvar,
2240     char FAR * auth_protocol,
2241     unsigned char FAR * auth_data,
2242     int auth_data_len, int screen_num)
2243     {
2244     int protocol_len = strlen(auth_protocol);
2245     int data_len = auth_data_len * 2;
2246     unsigned char FAR *outmsg =
2247     begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING,
2248     12 + protocol_len + data_len);
2249     int i;
2250     char FAR *auth_data_ptr;
2251    
2252     set_uint32(outmsg, protocol_len);
2253     memcpy(outmsg + 4, auth_protocol, protocol_len);
2254     set_uint32(outmsg + 4 + protocol_len, data_len);
2255     auth_data_ptr = outmsg + 8 + protocol_len;
2256     for (i = 0; i < auth_data_len; i++) {
2257     sprintf(auth_data_ptr + i * 2, "%.2x", auth_data[i]);
2258     }
2259     set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
2260    
2261     finish_send_packet(pvar);
2262    
2263     enque_forwarding_request_handlers(pvar);
2264     }
2265    
2266     void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num,
2267     char FAR * to_remote_host, int to_remote_port,
2268     char FAR * originator)
2269     {
2270     static const int msgs[]
2271     = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE };
2272     static const SSHPacketHandler handlers[]
2273     = { handle_channel_open_confirmation, handle_channel_open_failure };
2274    
2275     int host_len = strlen(to_remote_host);
2276    
2277     if ((pvar->ssh_state.
2278     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
2279     int originator_len = strlen(originator);
2280     unsigned char FAR *outmsg =
2281     begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2282     16 + host_len + originator_len);
2283    
2284     set_uint32(outmsg, local_channel_num);
2285     set_uint32(outmsg + 4, host_len);
2286     memcpy(outmsg + 8, to_remote_host, host_len);
2287     set_uint32(outmsg + 8 + host_len, to_remote_port);
2288     set_uint32(outmsg + 12 + host_len, originator_len);
2289     memcpy(outmsg + 16 + host_len, originator, originator_len);
2290     } else {
2291     unsigned char FAR *outmsg =
2292     begin_send_packet(pvar, SSH_MSG_PORT_OPEN,
2293     12 + host_len);
2294    
2295     set_uint32(outmsg, local_channel_num);
2296     set_uint32(outmsg + 4, host_len);
2297     memcpy(outmsg + 8, to_remote_host, host_len);
2298     set_uint32(outmsg + 8 + host_len, to_remote_port);
2299     }
2300    
2301     finish_send_packet(pvar);
2302    
2303     enque_handlers(pvar, 2, msgs, handlers);
2304     }
2305    
2306    
2307     /////////////////////////////////////////////////////////////////////////////
2308     //
2309     // SSH2 protocol procedure in the following code:
2310     //
2311     /////////////////////////////////////////////////////////////////////////////
2312    
2313     void debug_print(int no, char *msg, int len)
2314     {
2315     #ifdef _DEBUG
2316     FILE *fp;
2317     char file[128];
2318    
2319     sprintf(file, "dump%d.bin", no);
2320    
2321     fp = fopen(file, "wb");
2322     if (fp == NULL)
2323     return;
2324    
2325     fwrite(msg, 1, len, fp);
2326    
2327     fclose(fp);
2328     #endif
2329     }
2330    
2331     // �N���C�A���g�����T�[�o������������
2332     #ifdef SSH2_DEBUG
2333     static char *myproposal[PROPOSAL_MAX] = {
2334 yutakakn 2759 "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2335     // "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1",
2336     // "ssh-rsa,ssh-dss",
2337     "ssh-dss,ssh-rsa",
2338 yutakakn 2728 "3des-cbc,aes128-cbc",
2339     "3des-cbc,aes128-cbc",
2340 yutakakn 2758 "hmac-md5,hmac-sha1",
2341     "hmac-md5,hmac-sha1",
2342     // "hmac-sha1,hmac-md5",
2343     // "hmac-sha1,hmac-md5",
2344 yutakakn 2757 // "hmac-sha1",
2345     // "hmac-sha1",
2346 yutakakn 2728 "none",
2347     "none",
2348     "",
2349     "",
2350     };
2351     #else
2352     static char *myproposal[PROPOSAL_MAX] = {
2353 yutakakn 2758 "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1",
2354 yutakakn 2728 "ssh-rsa,ssh-dss",
2355     "3des-cbc,aes128-cbc",
2356     "3des-cbc,aes128-cbc",
2357 yutakakn 2757 "hmac-sha1,hmac-md5",
2358     "hmac-sha1,hmac-md5",
2359 yutakakn 2728 "none",
2360     "none",
2361     "",
2362     "",
2363     };
2364     #endif
2365    
2366    
2367     typedef struct ssh2_cipher {
2368     SSHCipher cipher;
2369     char *name;
2370     int block_size;
2371     int key_len;
2372     const EVP_CIPHER *(*func)(void);
2373     } ssh2_cipher_t;
2374    
2375     ssh2_cipher_t ssh2_ciphers[] = {
2376     {SSH_CIPHER_3DES_CBC, "3des-cbc", 8, 24, EVP_des_ede3_cbc},
2377     {SSH_CIPHER_AES128, "aes128-cbc", 16, 16, EVP_aes_128_cbc},
2378     {SSH_CIPHER_NONE, NULL, 0, 0, NULL},
2379     };
2380    
2381    
2382     typedef struct ssh2_mac {
2383     char *name;
2384     const EVP_MD *(*func)(void);
2385     int truncatebits;
2386     } ssh2_mac_t;
2387    
2388     ssh2_mac_t ssh2_macs[] = {
2389     {"hmac-sha1", EVP_sha1, 0},
2390     {"hmac-md5", EVP_md5, 0},
2391     {NULL, NULL, 0},
2392     };
2393    
2394     static Newkeys current_keys[MODE_MAX];
2395    
2396    
2397     #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
2398    
2399    
2400     static int get_cipher_block_size(SSHCipher cipher)
2401     {
2402     ssh2_cipher_t *ptr = ssh2_ciphers;
2403     int val = 0;
2404    
2405     while (ptr->name != NULL) {
2406     if (cipher == ptr->cipher) {
2407     val = ptr->block_size;
2408     break;
2409     }
2410     ptr++;
2411     }
2412     return (val);
2413     }
2414    
2415     static int get_cipher_key_len(SSHCipher cipher)
2416     {
2417     ssh2_cipher_t *ptr = ssh2_ciphers;
2418     int val = 0;
2419    
2420     while (ptr->name != NULL) {
2421     if (cipher == ptr->cipher) {
2422     val = ptr->key_len;
2423     break;
2424     }
2425     ptr++;
2426     }
2427     return (val);
2428     }
2429    
2430    
2431 yutakakn 2757 #if 0
2432 yutakakn 2728 static int get_mac_index(char *name)
2433     {
2434     ssh2_mac_t *ptr = ssh2_macs;
2435     int val = -1;
2436    
2437     while (ptr->name != NULL) {
2438     if (strcmp(ptr->name, name) == 0) {
2439     val = ptr - ssh2_macs;
2440     break;
2441     }
2442     ptr++;
2443     }
2444     return (val);
2445     }
2446 yutakakn 2757 #endif
2447 yutakakn 2728
2448    
2449     static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
2450     {
2451     FILE *fp;
2452     char filename[256];
2453    
2454     _snprintf(filename, sizeof(filename), "data%d.bin", lineno);
2455    
2456     fp = fopen(filename, "wb");
2457     if (fp == NULL)
2458     return;
2459    
2460     fwrite(buf, 1, len, fp);
2461    
2462     fclose(fp);
2463     }
2464    
2465    
2466     void SSH2_packet_start(buffer_t *msg, unsigned char type)
2467     {
2468     unsigned char buf[9];
2469     int len = 6;
2470    
2471     memset(buf, 0, sizeof(buf));
2472     buf[len - 1] = type;
2473     buffer_clear(msg);
2474     buffer_append(msg, buf, len);
2475     }
2476    
2477    
2478     // the caller is normalize_cipher_order()
2479     void SSH2_update_cipher_myproposal(PTInstVar pvar)
2480     {
2481     static char buf[128]; // TODO: malloc()��������
2482     int cipher;
2483     int len, i;
2484    
2485     // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
2486     buf[0] = '\0';
2487     for (i = 0 ; pvar->ts_SSH->CipherOrder[i] != 0 ; i++) {
2488     cipher = pvar->ts_SSH->CipherOrder[i] - '0';
2489     if (cipher == 0) // disabled line
2490     break;
2491     if (cipher == SSH_CIPHER_AES128) {
2492     strcat(buf, "aes128-cbc,");
2493     }
2494     if (cipher == SSH_CIPHER_3DES_CBC) {
2495     strcat(buf, "3des-cbc,");
2496     }
2497     }
2498     if (buf[0] != '\0') {
2499     len = strlen(buf);
2500     buf[len - 1] = '\0'; // get rid of comma
2501     myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
2502     myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
2503     }
2504     }
2505    
2506    
2507     // �N���C�A���g�����T�[�o�����L�[�����J�n�v��
2508     void SSH2_send_kexinit(PTInstVar pvar)
2509     {
2510     char cookie[SSH2_COOKIE_LENGTH];
2511     buffer_t *msg;
2512     unsigned char *outmsg;
2513     int len, i;
2514    
2515     msg = buffer_init();
2516     if (msg == NULL) {
2517     // TODO: error check
2518     return;
2519     }
2520     if (pvar->my_kex != NULL)
2521     buffer_free(pvar->my_kex);
2522     pvar->my_kex = msg;
2523    
2524     // ���b�Z�[�W�^�C�v
2525     //SSH2_packet_start(msg, SSH2_MSG_KEXINIT);
2526    
2527     // cookie���Z�b�g
2528     CRYPT_set_random_data(pvar, cookie, sizeof(cookie));
2529     CRYPT_set_server_cookie(pvar, cookie);
2530     buffer_append(msg, cookie, sizeof(cookie));
2531    
2532     // �N���C�A���g���L�[����
2533     for (i = 0 ; i < PROPOSAL_MAX ; i++) {
2534     buffer_put_string(msg, myproposal[i], strlen(myproposal[i]));
2535     }
2536     buffer_put_char(msg, 0);
2537     buffer_put_int(msg, 0);
2538    
2539     len = buffer_len(msg);
2540     outmsg = begin_send_packet(pvar, SSH2_MSG_KEXINIT, len);
2541     memcpy(outmsg, buffer_ptr(msg), len);
2542     finish_send_packet(pvar);
2543    
2544     //buffer_free(msg);
2545     }
2546    
2547    
2548     static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
2549     {
2550     char tmp[1024], *ptr;
2551     SSHCipher cipher = SSH_CIPHER_NONE;
2552    
2553     _snprintf(tmp, sizeof(tmp), my_proposal);
2554     ptr = strtok(tmp, ","); // not thread-safe
2555     while (ptr != NULL) {
2556     // server_proposal�����T�[�o��proposal���J���}���������i�[����������
2557     if (strstr(server_proposal, ptr)) { // match
2558