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 3083 - (hide annotations) (download) (as text)
Fri Dec 28 12:24:29 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 207600 byte(s)
SSH_scp_transaction()にファイル受信処理を追加。
ただし、受信中はユーザの操作を受け付けなくなるという問題があり、今後の課題。
実質的にはUIを用意していないので、ユーザがSCPによるファイル受信を行うことは
いまのところできなくしてあります。

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