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