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 3081 - (hide annotations) (download) (as text)
Thu Dec 27 13:18:47 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 204306 byte(s)
SCPのファイル送信中に、TeraTermウィンドウを閉じようとすると、デッドロックとなる問題を修正。
ファイル受信処理(作成途中)のコードも入っていますが、現在動作しません。

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