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 3077 - (hide annotations) (download) (as text)
Wed Dec 26 11:33:50 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 202637 byte(s)
SCPスレッドの復活。実際のパケット送信は、モードレスダイアログ内で行うことで、
コンテキストの乱れを発生させないようにする。

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