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 3096 - (hide annotations) (download) (as text)
Sat Jan 19 15:02:03 2008 UTC (16 years, 2 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 211629 byte(s)
SFTPサポートのためのフレームワークを追加。動作上は影響ありません。

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