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 6656 - (hide annotations) (download) (as text)
Thu Mar 23 12:54:58 2017 UTC (7 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 261888 byte(s)
メッセージ処理が有効にされていなくても、handler が取得出来た時に handler を実行していた問題を修正

ticket:37052 で Unexpected SSH2 message ダイアログの後で ACCESS_VIOLATION で落ちている原因。

1. SSH2_MSG_USERAUTH_INFO_REQUEST 用に handler が登録される
2. SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 用に handler が登録しようとするが、
   1.とメッセージ番号が重複する為に登録されない。
3. SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ が飛んでくる
4. SSH2_MSG_USERAUTH_INFO_REQUEST は enable にされていないので、
   Unexpected SSH2 message ダイアログを表示する。
5. 有効にされていなくても hadler が取得できてしまった為、handler を実行する。
6. handler では SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ を考慮していない為、
   SSH2_MSG_USERAUTH_PK_OK として扱おうとして data の範囲を踏み越えて処理
   しようとして落ちる。

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