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 3104 - (hide annotations) (download) (as text)
Mon Feb 4 04:26:54 2008 UTC (16 years, 2 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 212082 byte(s)
isSSH を ts から cv に移動した。

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