Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4682 - (show annotations) (download) (as text)
Fri Oct 21 15:58:49 2011 UTC (12 years, 5 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 248805 byte(s)
クライアントとサーバのバージョンが一致しない場合に接続しないようにした
クライアントが SSH1 でサーバが 1.99 の場合に SSH2 で接続される問題を修正
  http://sourceforge.jp/ticket/browse.php?group_id=1412&tid=26566
1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 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 #include "resource.h"
33 #include "libputty.h"
34 #include "key.h"
35
36 #include <openssl/bn.h>
37 #include <openssl/evp.h>
38 #include <openssl/dh.h>
39 #include <openssl/engine.h>
40 #include <openssl/rsa.h>
41 #include <openssl/dsa.h>
42 #include <openssl/md5.h>
43 #include <limits.h>
44 #include <malloc.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include <process.h>
48 #include <time.h>
49 #include <commctrl.h>
50 #include "buffer.h"
51 #include "ssh.h"
52 #include "crypt.h"
53 #include "fwd.h"
54 #include "sftp.h"
55 #include "kex.h"
56
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #include <assert.h>
60
61 #include <direct.h>
62 #include <io.h>
63
64 // SSH2 macro
65 #ifdef _DEBUG
66 #define SSH2_DEBUG
67 #endif
68
69 //#define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
70 #undef DONT_WANTCONFIRM // (2008.11.25 maya)
71
72 //
73 // SSH2 data structure
74 //
75
76 // channel data structure
77 #define CHANNEL_MAX 100
78
79 enum scp_state {
80 SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
81 };
82
83 typedef struct bufchain {
84 buffer_t *msg;
85 struct bufchain *next;
86 } bufchain_t;
87
88 typedef struct scp {
89 enum scp_dir dir; // transfer direction
90 enum scp_state state; // SCP state
91 char localfile[MAX_PATH]; // local filename
92 char localfilefull[MAX_PATH]; // local filename fullpath
93 char remotefile[MAX_PATH]; // remote filename
94 FILE *localfp; // file pointer for local file
95 struct __stat64 filestat; // file status information
96 HWND progress_window;
97 HANDLE thread;
98 unsigned int thread_id;
99 PTInstVar pvar;
100 // for receiving file
101 long long filetotalsize;
102 long long filercvsize;
103 } scp_t;
104
105 typedef struct channel {
106 int used;
107 int self_id;
108 int remote_id;
109 unsigned int local_window;
110 unsigned int local_window_max;
111 unsigned int local_consumed;
112 unsigned int local_maxpacket;
113 unsigned int remote_window;
114 unsigned int remote_maxpacket;
115 enum channel_type type;
116 int local_num;
117 bufchain_t *bufchain;
118 scp_t scp;
119 buffer_t *agent_msg;
120 int agent_request_len;
121 } Channel_t;
122
123 static Channel_t channels[CHANNEL_MAX];
124
125 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
126
127 static void try_send_credentials(PTInstVar pvar);
128 static void prep_compression(PTInstVar pvar);
129
130 // �����v���g�^�C�v����
131 void SSH2_send_kexinit(PTInstVar pvar);
132 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
133 static void SSH2_dh_kex_init(PTInstVar pvar);
134 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
135 static void SSH2_ecdh_kex_init(PTInstVar pvar);
136 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
137 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
138 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
139 static BOOL handle_SSH2_service_accept(PTInstVar pvar);
140 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
141 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
142 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
143 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
144 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
145 static BOOL handle_SSH2_request_success(PTInstVar pvar);
146 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
147 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
148 static BOOL handle_SSH2_channel_failure(PTInstVar pvar);
149 static BOOL handle_SSH2_channel_data(PTInstVar pvar);
150 static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
151 static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
152 static BOOL handle_SSH2_channel_close(PTInstVar pvar);
153 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
154 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
155 static BOOL handle_SSH2_channel_request(PTInstVar pvar);
156 void SSH2_dispatch_init(int stage);
157 int SSH2_dispatch_enabled_check(unsigned char message);
158 void SSH2_dispatch_add_message(unsigned char message);
159 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
160 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
161 static void start_ssh_heartbeat_thread(PTInstVar pvar);
162 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
163 void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);
164 static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, int local_channel_num, unsigned char *data, unsigned int buflen);
165
166 //
167 // channel function
168 //
169 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
170 enum confirm_type type, int local_num)
171 {
172 int i, found;
173 Channel_t *c;
174
175 found = -1;
176 for (i = 0 ; i < CHANNEL_MAX ; i++) {
177 if (channels[i].used == 0) { // free channel
178 found = i;
179 break;
180 }
181 }
182 if (found == -1) { // not free channel
183 return (NULL);
184 }
185
186 // setup
187 c = &channels[found];
188 memset(c, 0, sizeof(Channel_t));
189 c->used = 1;
190 c->self_id = i;
191 c->remote_id = -1;
192 c->local_window = window;
193 c->local_window_max = window;
194 c->local_consumed = 0;
195 c->local_maxpacket = maxpack;
196 c->remote_window = 0;
197 c->remote_maxpacket = 0;
198 c->type = type;
199 c->local_num = local_num; // alloc_channel()�����l��������������
200 c->bufchain = NULL;
201 if (type == TYPE_SCP) {
202 c->scp.state = SCP_INIT;
203 c->scp.progress_window = NULL;
204 c->scp.thread = (HANDLE)-1;
205 c->scp.localfp = NULL;
206 }
207 if (type == TYPE_AGENT) {
208 c->agent_msg = buffer_init();
209 c->agent_request_len = 0;
210 }
211
212 return (c);
213 }
214
215 // remote_window�������������������A�������������o�b�t�@�����X�g�i�������j���������������B
216 static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
217 {
218 bufchain_t *p, *old;
219
220 // allocate new buffer
221 p = malloc(sizeof(bufchain_t));
222 if (p == NULL)
223 return;
224 p->msg = buffer_init();
225 if (p == NULL) {
226 free(p);
227 return;
228 }
229 buffer_put_raw(p->msg, buf, buflen);
230 p->next = NULL;
231
232 if (c->bufchain == NULL) {
233 c->bufchain = p;
234 } else {
235 old = c->bufchain;
236 while (old->next)
237 old = old->next;
238 old->next = p;
239 }
240 }
241
242
243 static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
244 {
245 bufchain_t *ch;
246 unsigned int size;
247
248 while (c->bufchain) {
249 // ����������������
250 ch = c->bufchain;
251 size = buffer_len(ch->msg);
252 if (size >= c->remote_window)
253 break;
254
255 if (c->local_num == -1) { // shell or SCP
256 SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);
257 } else { // port-forwarding
258 SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
259 }
260
261 c->bufchain = ch->next;
262
263 buffer_free(ch->msg);
264 free(ch);
265 }
266 }
267
268
269
270 // channel close�����`���l���\���������X�g�����p����
271 // (2007.4.26 yutaka)
272 static void ssh2_channel_delete(Channel_t *c)
273 {
274 bufchain_t *ch, *ptr;
275
276 ch = c->bufchain;
277 while (ch) {
278 if (ch->msg)
279 buffer_free(ch->msg);
280 ptr = ch;
281 ch = ch->next;
282 free(ptr);
283 }
284
285 if (c->type == TYPE_SCP) {
286 c->scp.state = SCP_CLOSING;
287 if (c->scp.localfp != NULL)
288 fclose(c->scp.localfp);
289 if (c->scp.progress_window != NULL) {
290 DestroyWindow(c->scp.progress_window);
291 c->scp.progress_window = NULL;
292 }
293 if (c->scp.thread != (HANDLE)-1L) {
294 WaitForSingleObject(c->scp.thread, INFINITE);
295 CloseHandle(c->scp.thread);
296 c->scp.thread = (HANDLE)-1L;
297 }
298 }
299 if (c->type == TYPE_AGENT) {
300 buffer_free(c->agent_msg);
301 }
302
303 memset(c, 0, sizeof(Channel_t));
304 c->used = 0;
305 }
306
307
308 // connection close������������
309 void ssh2_channel_free(void)
310 {
311 int i;
312 Channel_t *c;
313
314 for (i = 0 ; i < CHANNEL_MAX ; i++) {
315 c = &channels[i];
316 ssh2_channel_delete(c);
317 }
318
319 }
320
321 static Channel_t *ssh2_channel_lookup(int id)
322 {
323 Channel_t *c;
324
325 if (id < 0 || id >= CHANNEL_MAX) {
326 return (NULL);
327 }
328 c = &channels[id];
329 if (c->used == 0) { // already freed
330 return (NULL);
331 }
332 return (c);
333 }
334
335 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
336 // TODO: �����I�����`���l���\������1�������������B
337 // (2005.6.12 yutaka)
338 static Channel_t *ssh2_local_channel_lookup(int local_num)
339 {
340 int i;
341 Channel_t *c;
342
343 for (i = 0 ; i < CHANNEL_MAX ; i++) {
344 c = &channels[i];
345 if (c->local_num == local_num)
346 return (c);
347 }
348 return (NULL);
349 }
350
351
352 //
353 // SSH heartbeat mutex
354 //
355 // TTSSH�� thread-safe �������������A�}���`�X���b�h�������p�P�b�g���M�����������B
356 // �V���O���X���b�h�����R���e�L�X�g�X�C�b�`�������������������������A
357 // ���b�N�������K�v�����������A���������B(2007.12.26 yutaka)
358 //
359 static CRITICAL_SECTION g_ssh_heartbeat_lock; /* �����M�p���b�N */
360
361 void ssh_heartbeat_lock_initialize(void)
362 {
363 //InitializeCriticalSection(&g_ssh_heartbeat_lock);
364 }
365
366 void ssh_heartbeat_lock_finalize(void)
367 {
368 //DeleteCriticalSection(&g_ssh_heartbeat_lock);
369 }
370
371 void ssh_heartbeat_lock(void)
372 {
373 //EnterCriticalSection(&g_ssh_heartbeat_lock);
374 }
375
376 void ssh_heartbeat_unlock(void)
377 {
378 //LeaveCriticalSection(&g_ssh_heartbeat_lock);
379 }
380
381
382 //
383 // SSH memory dump (for debug)
384 //
385 // (2005.3.7 yutaka)
386 //
387 #define MEMTAG_MAX 300
388 #define LOGDUMP "ssh2connect.log"
389 #define LOG_PACKET_DUMP "ssh2packet.log"
390 #define SENDTOME "Please send '"LOGDUMP"' file to Tera Term developer team."
391
392 typedef struct memtag {
393 char *name;
394 char *desc;
395 time_t time;
396 int len;
397 char *data;
398 } memtag_t;
399
400 static memtag_t memtags[MEMTAG_MAX];
401 static int memtag_count = 0;
402 static int memtag_use = 0;
403
404 /* �_���v���C�����t�H�[�}�b�g�\������ */
405 static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
406 {
407 int i, c;
408
409 /* �������A�h���X�\�� */
410 fprintf(fp, "%08X : ", addr);
411
412 /* �o�C�i���\���i4�o�C�g�������������}���j*/
413 for (i = 0 ; i < byte_cnt ; i++) {
414 if (i > 0 && i % 4 == 0)
415 fprintf(fp, " ");
416
417 fprintf(fp, "%02X", bytes[i]);
418 }
419
420 /* ASCII�\���������������������� */
421 fprintf(fp, " %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
422
423 /* ASCII�\�� */
424 for (i = 0 ; i < byte_cnt ; i++) {
425 c = bytes[i];
426 if (isprint(c)) {
427 fprintf(fp, "%c", c);
428 } else {
429 fprintf(fp, ".");
430 }
431 }
432
433 fprintf(fp, "\n");
434 }
435
436
437 /* �_���v���[�`�� */
438 static void dump_memdump(FILE *fp, char *data, int len)
439 {
440 int c, addr;
441 int bytes[16], *ptr;
442 int byte_cnt;
443 int i;
444
445 addr = 0;
446 byte_cnt = 0;
447 ptr = bytes;
448 for (i = 0 ; i < len ; i++) {
449 c = data[i];
450 *ptr++ = c & 0xff;
451 byte_cnt++;
452
453 if (byte_cnt == 16) {
454 displine_memdump(fp, addr, bytes, byte_cnt);
455
456 addr += 16;
457 byte_cnt = 0;
458 ptr = bytes;
459 }
460 }
461
462 if (byte_cnt > 0) {
463 displine_memdump(fp, addr, bytes, byte_cnt);
464 }
465 }
466
467 void init_memdump(void)
468 {
469 int i;
470
471 if (memtag_use > 0)
472 return;
473
474 for (i = 0 ; i < MEMTAG_MAX ; i++) {
475 memtags[i].name = NULL;
476 memtags[i].desc = NULL;
477 memtags[i].data = NULL;
478 memtags[i].len = 0;
479 }
480 memtag_use++;
481 }
482
483 void finish_memdump(void)
484 {
485 int i;
486
487 // initialize�������������������������������B(2005.4.3 yutaka)
488 if (memtag_use <= 0)
489 return;
490 memtag_use--;
491
492 for (i = 0 ; i < MEMTAG_MAX ; i++) {
493 free(memtags[i].name);
494 free(memtags[i].desc);
495 free(memtags[i].data);
496 memtags[i].len = 0;
497 }
498 memtag_count = 0;
499 }
500
501 void save_memdump(char *filename)
502 {
503 FILE *fp;
504 int i;
505 time_t t;
506 struct tm *tm;
507
508 fp = fopen(filename, "w");
509 if (fp == NULL)
510 return;
511
512 t = time(NULL);
513 tm = localtime(&t);
514
515 fprintf(fp, "<<< Tera Term SSH2 log dump >>>\n");
516 fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
517 tm->tm_year + 1900,
518 tm->tm_mon + 1,
519 tm->tm_mday,
520 tm->tm_hour,
521 tm->tm_min,
522 tm->tm_sec);
523 fprintf(fp, "\n");
524
525 for (i = 0 ; i < memtag_count ; i++) {
526 fprintf(fp, "============================================\n");
527 fprintf(fp, "name: %s\n", memtags[i].name);
528 fprintf(fp, "--------------------------------------------\n");
529 fprintf(fp, "description: %s\n", memtags[i].desc);
530 fprintf(fp, "--------------------------------------------\n");
531 fprintf(fp, "time: %s", ctime(&memtags[i].time));
532 fprintf(fp, "============================================\n");
533 dump_memdump(fp, memtags[i].data, memtags[i].len);
534 fprintf(fp, "\n\n\n");
535 }
536
537 fprintf(fp, "[EOF]\n");
538
539 fclose(fp);
540 }
541
542 void push_memdump(char *name, char *desc, char *data, int len)
543 {
544 memtag_t *ptr;
545 char *dp;
546
547 dp = malloc(len);
548 if (dp == NULL)
549 return;
550 memcpy(dp, data, len);
551
552 if (memtag_count >= MEMTAG_MAX)
553 return;
554
555 ptr = &memtags[memtag_count];
556 memtag_count++;
557 ptr->name = _strdup(name);
558 ptr->desc = _strdup(desc);
559 ptr->time = time(NULL);
560 ptr->data = dp;
561 ptr->len = len;
562 }
563
564 void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
565 {
566 int len;
567 char *buf;
568
569 len = BN_num_bytes(bignum);
570 buf = malloc(len); // allocate
571 if (buf == NULL)
572 return;
573 BN_bn2bin(bignum, buf);
574 push_memdump(name, desc, buf, len); // at push_bignum_memdump()
575 free(buf); // free
576 }
577
578
579 //
580 //
581 //
582
583
584 static int get_predecryption_amount(PTInstVar pvar)
585 {
586 static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
587
588 if (SSHv1(pvar)) {
589 return 0;
590 } else {
591 int block_size = CRYPT_get_decryption_block_size(pvar);
592
593 if (block_size < 5) {
594 return small_block_decryption_sizes[block_size];
595 } else {
596 return block_size;
597 }
598 }
599 }
600
601 /* Get up to 'limit' bytes into the payload buffer.
602 'limit' is counted from the start of the payload data.
603 Returns the amount of data in the payload buffer, or
604 -1 if there is an error.
605 We can return more than limit in some cases. */
606 static int buffer_packet_data(PTInstVar pvar, int limit)
607 {
608 if (pvar->ssh_state.payloadlen >= 0) {
609 return pvar->ssh_state.payloadlen;
610 } else {
611 int cur_decompressed_bytes =
612 pvar->ssh_state.decompress_stream.next_out -
613 pvar->ssh_state.postdecompress_inbuf;
614
615 while (limit > cur_decompressed_bytes) {
616 int result;
617
618 pvar->ssh_state.payload =
619 pvar->ssh_state.postdecompress_inbuf + 1;
620 if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
621 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
622 &pvar->ssh_state.postdecompress_inbuflen,
623 min(limit, cur_decompressed_bytes * 2));
624 }
625
626 pvar->ssh_state.decompress_stream.next_out =
627 pvar->ssh_state.postdecompress_inbuf +
628 cur_decompressed_bytes;
629 pvar->ssh_state.decompress_stream.avail_out =
630 min(limit, pvar->ssh_state.postdecompress_inbuflen)
631 - cur_decompressed_bytes;
632
633 result =
634 inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
635 cur_decompressed_bytes =
636 pvar->ssh_state.decompress_stream.next_out -
637 pvar->ssh_state.postdecompress_inbuf;
638
639 switch (result) {
640 case Z_OK:
641 break;
642 case Z_BUF_ERROR:
643 pvar->ssh_state.payloadlen = cur_decompressed_bytes;
644 return cur_decompressed_bytes;
645 default:
646 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
647 "Invalid compressed data in received packet");
648 notify_fatal_error(pvar, pvar->ts->UIMsg);
649 return -1;
650 }
651 }
652
653 return cur_decompressed_bytes;
654 }
655 }
656
657 /* For use by the protocol processing code.
658 Gets N bytes of uncompressed payload. Returns FALSE if data not available
659 and a fatal error has been signaled.
660 The data is available in the payload buffer. This buffer address
661 can change during a call to grab_payload, so take care!
662 The payload pointer is set to point to the first byte of the actual data
663 (after the packet type byte).
664 */
665 static BOOL grab_payload(PTInstVar pvar, int num_bytes)
666 {
667 /* Accept maximum of 4MB of payload data */
668 int in_buffer = buffer_packet_data(pvar, PACKET_MAX_SIZE);
669
670 if (in_buffer < 0) {
671 return FALSE;
672 } else {
673 pvar->ssh_state.payload_grabbed += num_bytes;
674 if (pvar->ssh_state.payload_grabbed > in_buffer) {
675 char buf[128];
676 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
677 "Received truncated packet (%ld > %d) @ grab_payload()");
678 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
679 pvar->ssh_state.payload_grabbed, in_buffer);
680 notify_fatal_error(pvar, buf);
681 return FALSE;
682 } else {
683 return TRUE;
684 }
685 }
686 }
687
688 static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
689 {
690 int in_buffer;
691
692 pvar->ssh_state.payload_grabbed += num_bytes;
693 in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
694
695 if (in_buffer < 0) {
696 return FALSE;
697 } else {
698 if (pvar->ssh_state.payload_grabbed > in_buffer) {
699 char buf[128];
700 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
701 "Received truncated packet (%ld > %d) @ grab_payload_limited()");
702 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
703 pvar->ssh_state.payload_grabbed, in_buffer);
704 notify_fatal_error(pvar, buf);
705 return FALSE;
706 } else {
707 return TRUE;
708 }
709 }
710 }
711
712 #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
713 #define get_uint32(buf) get_uint32_MSBfirst((buf))
714 #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
715 #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
716 #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
717
718 #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
719
720 /* Decrypt the payload, checksum it, eat the padding, get the packet type
721 and return it.
722 'data' points to the start of the packet --- its length field.
723 'len' is the length of the
724 payload + padding (+ length of CRC for SSHv1). 'padding' is the length
725 of the padding alone. */
726 static int prep_packet(PTInstVar pvar, char FAR * data, int len,
727 int padding)
728 {
729 pvar->ssh_state.payload = data + 4;
730 pvar->ssh_state.payloadlen = len;
731
732 if (SSHv1(pvar)) {
733 if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
734 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
735 "'CORE insertion attack' detected. Aborting connection.");
736 notify_fatal_error(pvar, pvar->ts->UIMsg);
737 }
738
739 CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
740 /* PKT guarantees that the data is always 4-byte aligned */
741 if (do_crc(pvar->ssh_state.payload, len - 4) !=
742 get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
743 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
744 "Detected corrupted data; connection terminating.");
745 notify_fatal_error(pvar, pvar->ts->UIMsg);
746 return SSH_MSG_NONE;
747 }
748
749 pvar->ssh_state.payload += padding;
750 pvar->ssh_state.payloadlen -= padding + 4;
751 } else {
752 int already_decrypted = get_predecryption_amount(pvar);
753
754 #if 0
755 CRYPT_decrypt(pvar, data + already_decrypted,
756 len - already_decrypted);
757 #else
758 CRYPT_decrypt(pvar, data + already_decrypted,
759 (4 + len) - already_decrypted);
760 #endif
761
762 if (!CRYPT_verify_receiver_MAC
763 (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
764 data + len + 4)) {
765 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
766 "Detected corrupted data; connection terminating.");
767 notify_fatal_error(pvar, pvar->ts->UIMsg);
768 return SSH_MSG_NONE;
769 }
770
771 pvar->ssh_state.payload++;
772 pvar->ssh_state.payloadlen -= padding + 1;
773 }
774
775 pvar->ssh_state.payload_grabbed = 0;
776
777 if (SSHv1(pvar)) {
778 if (pvar->ssh_state.decompressing) {
779 if (pvar->ssh_state.decompress_stream.avail_in != 0) {
780 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
781 "Internal error: a packet was not fully decompressed.\n"
782 "This is a bug, please report it.");
783 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
784 }
785
786 pvar->ssh_state.decompress_stream.next_in =
787 pvar->ssh_state.payload;
788 pvar->ssh_state.decompress_stream.avail_in =
789 pvar->ssh_state.payloadlen;
790 pvar->ssh_state.decompress_stream.next_out =
791 pvar->ssh_state.postdecompress_inbuf;
792 pvar->ssh_state.payloadlen = -1;
793 } else {
794 pvar->ssh_state.payload++;
795 }
796
797 if (!grab_payload_limited(pvar, 1)) {
798 return SSH_MSG_NONE;
799 }
800
801 } else {
802 // support of SSH2 packet compression (2005.7.9 yutaka)
803 // support of "Compression delayed" (2006.6.23 maya)
804 if ((pvar->stoc_compression == COMP_ZLIB ||
805 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
806 pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
807 int ret;
808
809 if (pvar->decomp_buffer == NULL) {
810 pvar->decomp_buffer = buffer_init();
811 if (pvar->decomp_buffer == NULL)
812 return SSH_MSG_NONE;
813 }
814 // ���x�m�������o�b�t�@���g�������������������Y�������B
815 buffer_clear(pvar->decomp_buffer);
816
817 // packet size��padding�������������y�C���[�h�����������W�J�����B
818 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
819 pvar->ssh_state.payload,
820 pvar->ssh_state.payloadlen,
821 pvar->decomp_buffer);
822
823 // �|�C���^���X�V�B
824 pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
825 pvar->ssh_state.payload++;
826 pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
827
828 } else {
829 pvar->ssh_state.payload++;
830 }
831
832 if (!grab_payload_limited(pvar, 1)) {
833 return SSH_MSG_NONE;
834 }
835
836 }
837
838 pvar->ssh_state.receiver_sequence_number++;
839
840 return pvar->ssh_state.payload[-1];
841 }
842
843 /* Create a packet to be sent. The SSH protocol packet type is in 'type';
844 'len' contains the length of the packet payload, in bytes (this
845 does not include the space for any of the packet headers or padding,
846 or for the packet type byte).
847 Returns a pointer to the payload data area, a region of length 'len',
848 to be filled by the caller. */
849 static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
850 {
851 unsigned char FAR *buf;
852
853 pvar->ssh_state.outgoing_packet_len = len + 1;
854
855 if (pvar->ssh_state.compressing) {
856 buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
857 &pvar->ssh_state.precompress_outbuflen, 1 + len);
858 buf = pvar->ssh_state.precompress_outbuf;
859 } else {
860 /* For SSHv2,
861 Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
862 + len(payload) + 4(minpadding), rounded up to nearest block_size
863 We only need a reasonable upper bound for the buffer size */
864 buf_ensure_size(&pvar->ssh_state.outbuf,
865 &pvar->ssh_state.outbuflen,
866 len + 30 + CRYPT_get_sender_MAC_size(pvar) +
867 CRYPT_get_encryption_block_size(pvar));
868 buf = pvar->ssh_state.outbuf + 12;
869 }
870
871 buf[0] = (unsigned char) type;
872 return buf + 1;
873 }
874
875 #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
876
877 // ���M���g���C����������
878 //
879 // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
880 // ���������������A�����������G���[���������B
881 // �����������ATCP�R�l�N�V�������f�������o���h���B
882 // (2006.12.9 yutaka)
883 static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
884 {
885 int n;
886 int err;
887
888 while (len > 0) {
889 n = (pvar->Psend)(pvar->socket, data, len, 0);
890
891 if (n < 0) {
892 err = WSAGetLastError();
893 if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
894 // send()�����l��0�������A�����G���[������ 10000 �������������A
895 // ���������������������B
896 // PuTTY 0.58���������Q�l�B
897 // (2007.2.4 yutak)
898 return 0; // success
899 }
900 return 1; // error
901 }
902
903 len -= n;
904 data += n;
905 }
906
907 return 0; // success
908 }
909
910 static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
911 {
912 // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
913 // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
914 // ���������������������������������B(2007.10.30 yutaka)
915 u_long do_block = 0;
916 int code = 0;
917 char *kind = NULL, buf[256];
918
919 #if 0
920 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
921 0, 0) == SOCKET_ERROR
922 || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
923 || retry_send_packet(pvar, data, len)
924 || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
925 pvar->notification_msg,
926 pvar->notification_events) ==
927 SOCKET_ERROR) {
928 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
929 "A communications error occurred while sending an SSH packet.\n"
930 "The connection will close.");
931 notify_fatal_error(pvar, pvar->ts->UIMsg);
932 return FALSE;
933 } else {
934 return TRUE;
935 }
936 #else
937 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
938 0, 0) == SOCKET_ERROR) {
939 code = WSAGetLastError();
940 kind = "WSAAsyncSelect1";
941 goto error;
942 }
943 if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
944 code = WSAGetLastError();
945 kind = "ioctlsocket";
946 goto error;
947 }
948 if (retry_send_packet(pvar, data, len) != 0) {
949 code = WSAGetLastError();
950 kind = "retry_send_packet";
951 goto error;
952 }
953 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
954 pvar->notification_msg,
955 pvar->notification_events) ==
956 SOCKET_ERROR) {
957 code = WSAGetLastError();
958 kind = "WSAAsyncSelect2";
959 goto error;
960 }
961 return TRUE;
962
963 error:
964 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
965 "A communications error occurred while sending an SSH packet.\n"
966 "The connection will close. (%s:%d)");
967 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
968 kind, code);
969 notify_fatal_error(pvar, buf);
970 return FALSE;
971 #endif
972 }
973
974 /* if skip_compress is true, then the data has already been compressed
975 into outbuf + 12 */
976 static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
977 {
978 unsigned int len = pvar->ssh_state.outgoing_packet_len;
979 unsigned char FAR *data;
980 unsigned int data_length;
981 buffer_t *msg = NULL; // for SSH2 packet compression
982
983 if (pvar->ssh_state.compressing) {
984 if (!skip_compress) {
985 buf_ensure_size(&pvar->ssh_state.outbuf,
986 &pvar->ssh_state.outbuflen,
987 (int)(len + (len >> 6) + 50 +
988 CRYPT_get_sender_MAC_size(pvar)));
989 pvar->ssh_state.compress_stream.next_in =
990 pvar->ssh_state.precompress_outbuf;
991 pvar->ssh_state.compress_stream.avail_in = len;
992 pvar->ssh_state.compress_stream.next_out =
993 pvar->ssh_state.outbuf + 12;
994 pvar->ssh_state.compress_stream.avail_out =
995 pvar->ssh_state.outbuflen - 12;
996
997 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
998 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
999 "An error occurred while compressing packet data.\n"
1000 "The connection will close.");
1001 notify_fatal_error(pvar, pvar->ts->UIMsg);
1002 return;
1003 }
1004 }
1005
1006 len =
1007 pvar->ssh_state.outbuflen - 12 -
1008 pvar->ssh_state.compress_stream.avail_out;
1009 }
1010
1011 if (SSHv1(pvar)) {
1012 int padding = 8 - ((len + 4) % 8);
1013
1014 data = pvar->ssh_state.outbuf + 8 - padding;
1015 data_length = padding + len + 8;
1016
1017 set_uint32(data, len + 4);
1018 if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
1019 CRYPT_set_random_data(pvar, data + 4, padding);
1020 } else {
1021 memset(data + 4, 0, padding);
1022 }
1023 set_uint32(data + data_length - 4,
1024 do_crc(data + 4, data_length - 8));
1025 CRYPT_encrypt(pvar, data + 4, data_length - 4);
1026 } else { //for SSH2(yutaka)
1027 int block_size = CRYPT_get_encryption_block_size(pvar);
1028 unsigned int encryption_size;
1029 unsigned int padding;
1030 BOOL ret;
1031
1032 /*
1033 �f�[�^�\��
1034 pvar->ssh_state.outbuf:
1035 offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
1036 <--ignore---> ^^^^^^^^ <---- payload --->
1037 packet length
1038
1039 ^^padding
1040
1041 <---------------------------->
1042 SSH2 sending data on TCP
1043
1044 NOTE:
1045 payload = type(1) + raw-data
1046 len = ssh_state.outgoing_packet_len = payload size
1047 */
1048 // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1049 // support of "Compression delayed" (2006.6.23 maya)
1050 if ((pvar->ctos_compression == COMP_ZLIB ||
1051 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1052 pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1053 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1054 msg = buffer_init();
1055 if (msg == NULL) {
1056 // TODO: error check
1057 return;
1058 }
1059
1060 // ���k�������w�b�_�������y�C���[�h�����B
1061 buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1062 if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1063 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1064 "An error occurred while compressing packet data.\n"
1065 "The connection will close.");
1066 notify_fatal_error(pvar, pvar->ts->UIMsg);
1067 return;
1068 }
1069 data = buffer_ptr(msg);
1070 len = buffer_len(msg) - 5; // 'len' is overwritten.
1071
1072 } else {
1073 // �����k
1074 data = pvar->ssh_state.outbuf + 7;
1075
1076 }
1077
1078 // ���M�p�P�b�g�\�z(input parameter: data, len)
1079 if (block_size < 8) {
1080 block_size = 8;
1081 }
1082 #if 0
1083 encryption_size = ((len + 8) / block_size + 1) * block_size;
1084 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1085
1086 set_uint32(data, encryption_size - 4);
1087 padding = encryption_size - len - 5;
1088 data[4] = (unsigned char) padding;
1089 #else
1090 // �������p�P�b�g�����������������A�T�[�o����"Bad packet length"���������������������������B
1091 // (2007.10.29 yutaka)
1092 encryption_size = 4 + 1 + len;
1093 padding = block_size - (encryption_size % block_size);
1094 if (padding < 4)
1095 padding += block_size;
1096 encryption_size += padding;
1097 set_uint32(data, encryption_size - 4);
1098 data[4] = (unsigned char) padding;
1099 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1100 if (msg) {
1101 // �p�P�b�g���k�������A�o�b�t�@���g�������B(2011.6.10 yutaka)
1102 buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
1103 // realloc()���������A�|�C���^�����������\�������������A���x���������B
1104 data = buffer_ptr(msg);
1105 }
1106 #endif
1107 //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1108 CRYPT_set_random_data(pvar, data + 5 + len, padding);
1109 ret = CRYPT_build_sender_MAC(pvar,
1110 pvar->ssh_state.sender_sequence_number,
1111 data, encryption_size,
1112 data + encryption_size);
1113 if (ret == FALSE) { // HMAC��������������������������
1114 data_length = encryption_size;
1115 }
1116
1117 // �p�P�b�g�������������BHMAC���~�������������O�B
1118 CRYPT_encrypt(pvar, data, encryption_size);
1119 }
1120
1121 send_packet_blocking(pvar, data, data_length);
1122
1123 buffer_free(msg);
1124
1125 pvar->ssh_state.sender_sequence_number++;
1126
1127 // ���M�������L�^
1128 pvar->ssh_heartbeat_tick = time(NULL);
1129 }
1130
1131 static void destroy_packet_buf(PTInstVar pvar)
1132 {
1133 memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1134 if (pvar->ssh_state.compressing) {
1135 memset(pvar->ssh_state.precompress_outbuf, 0,
1136 pvar->ssh_state.precompress_outbuflen);
1137 }
1138 }
1139
1140 /* The handlers are added to the queue for each message. When one of the
1141 handlers fires, if it returns FALSE, then all handlers in the set are
1142 removed from their queues. */
1143 static void enque_handlers(PTInstVar pvar, int num_msgs,
1144 const int FAR * messages,
1145 const SSHPacketHandler FAR * handlers)
1146 {
1147 SSHPacketHandlerItem FAR *first_item;
1148 SSHPacketHandlerItem FAR *last_item = NULL;
1149 int i;
1150
1151 for (i = 0; i < num_msgs; i++) {
1152 SSHPacketHandlerItem FAR *item =
1153 (SSHPacketHandlerItem FAR *)
1154 malloc(sizeof(SSHPacketHandlerItem));
1155 SSHPacketHandlerItem FAR *cur_item =
1156 pvar->ssh_state.packet_handlers[messages[i]];
1157
1158 item->handler = handlers[i];
1159
1160 if (cur_item == NULL) {
1161 pvar->ssh_state.packet_handlers[messages[i]] = item;
1162 item->next_for_message = item;
1163 item->last_for_message = item;
1164 item->active_for_message = messages[i];
1165 } else {
1166 item->next_for_message = cur_item;
1167 item->last_for_message = cur_item->last_for_message;
1168 cur_item->last_for_message->next_for_message = item;
1169 cur_item->last_for_message = item;
1170 item->active_for_message = -1;
1171 }
1172
1173 if (last_item != NULL) {
1174 last_item->next_in_set = item;
1175 } else {
1176 first_item = item;
1177 }
1178 last_item = item;
1179 }
1180
1181 if (last_item != NULL) {
1182 last_item->next_in_set = first_item;
1183 }
1184 }
1185
1186 static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1187 {
1188 SSHPacketHandlerItem FAR *cur_item =
1189 pvar->ssh_state.packet_handlers[message];
1190
1191 if (cur_item == NULL) {
1192 return NULL;
1193 } else {
1194 return cur_item->handler;
1195 }
1196 }
1197
1198 /* Called only by SSH_handle_packet */
1199 static void deque_handlers(PTInstVar pvar, int message)
1200 {
1201 SSHPacketHandlerItem FAR *cur_item =
1202 pvar->ssh_state.packet_handlers[message];
1203 SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1204
1205 if (cur_item == NULL)
1206 return;
1207
1208 do {
1209 SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1210
1211 if (cur_item->active_for_message >= 0) {
1212 SSHPacketHandlerItem FAR *replacement =
1213 cur_item->next_for_message;
1214
1215 if (replacement == cur_item) {
1216 replacement = NULL;
1217 } else {
1218 replacement->active_for_message =
1219 cur_item->active_for_message;
1220 }
1221 pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1222 replacement;
1223 }
1224 cur_item->next_for_message->last_for_message =
1225 cur_item->last_for_message;
1226 cur_item->last_for_message->next_for_message =
1227 cur_item->next_for_message;
1228
1229 free(cur_item);
1230 cur_item = next_in_set;
1231 } while (cur_item != first_item_in_set);
1232 }
1233
1234 static void enque_handler(PTInstVar pvar, int message,
1235 SSHPacketHandler handler)
1236 {
1237 enque_handlers(pvar, 1, &message, &handler);
1238 }
1239
1240 static void chop_newlines(char FAR * buf)
1241 {
1242 int len = strlen(buf);
1243
1244 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1245 buf[len - 1] = 0;
1246 len--;
1247 }
1248 }
1249
1250 /********************/
1251 /* Message handlers */
1252 /********************/
1253
1254 static BOOL handle_forwarding_success(PTInstVar pvar)
1255 {
1256 return FALSE;
1257 }
1258
1259 static BOOL handle_forwarding_failure(PTInstVar pvar)
1260 {
1261 return FALSE;
1262 }
1263
1264 static void enque_forwarding_request_handlers(PTInstVar pvar)
1265 {
1266 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1267 static const SSHPacketHandler handlers[]
1268 = { handle_forwarding_success, handle_forwarding_failure };
1269
1270 enque_handlers(pvar, 2, msgs, handlers);
1271 }
1272
1273 static BOOL handle_auth_failure(PTInstVar pvar)
1274 {
1275 notify_verbose_message(pvar, "Authentication failed",
1276 LOG_LEVEL_VERBOSE);
1277
1278 // retry count������ (2005.7.15 yutaka)
1279 pvar->userauth_retry_count++;
1280
1281 AUTH_set_generic_mode(pvar);
1282 AUTH_advance_to_next_cred(pvar);
1283 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1284 try_send_credentials(pvar);
1285 return FALSE;
1286 }
1287
1288 static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1289 {
1290 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1291 if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1292 // �S�������������I������
1293 safefree(pvar->pageant_key);
1294 }
1295 else {
1296 // ������������
1297 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1298 try_send_credentials(pvar);
1299 return TRUE;
1300 }
1301 }
1302 AUTH_destroy_cur_cred(pvar);
1303 return handle_auth_failure(pvar);
1304 }
1305
1306 static BOOL handle_TIS_challenge(PTInstVar pvar)
1307 {
1308 if (grab_payload(pvar, 4)) {
1309 int len = get_payload_uint32(pvar, 0);
1310
1311 if (grab_payload(pvar, len)) {
1312 notify_verbose_message(pvar, "Received TIS challenge",
1313 LOG_LEVEL_VERBOSE);
1314
1315 AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1316 AUTH_advance_to_next_cred(pvar);
1317 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1318 try_send_credentials(pvar);
1319 }
1320 }
1321 return FALSE;
1322 }
1323
1324 static BOOL handle_auth_required(PTInstVar pvar)
1325 {
1326 notify_verbose_message(pvar, "Server requires authentication",
1327 LOG_LEVEL_VERBOSE);
1328
1329 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1330 try_send_credentials(pvar);
1331 /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1332
1333 return FALSE;
1334 }
1335
1336 static BOOL handle_ignore(PTInstVar pvar)
1337 {
1338 if (SSHv1(pvar)) {
1339 notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1340
1341 if (grab_payload(pvar, 4)
1342 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1343 /* ignore it! but it must be decompressed */
1344 }
1345 }
1346 else {
1347 notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1348
1349 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1350 // Cisco ���[�^���� (2006.11.28 maya)
1351 }
1352 return TRUE;
1353 }
1354
1355 static BOOL handle_debug(PTInstVar pvar)
1356 {
1357 BOOL always_display;
1358 char FAR *description;
1359 int description_len;
1360 char buf[2048];
1361
1362 if (SSHv1(pvar)) {
1363 notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1364
1365 if (grab_payload(pvar, 4)
1366 && grab_payload(pvar, description_len =
1367 get_payload_uint32(pvar, 0))) {
1368 always_display = FALSE;
1369 description = pvar->ssh_state.payload + 4;
1370 description[description_len] = 0;
1371 } else {
1372 return TRUE;
1373 }
1374 } else {
1375 notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1376
1377 if (grab_payload(pvar, 5)
1378 && grab_payload(pvar,
1379 (description_len = get_payload_uint32(pvar, 1)) + 4)
1380 && grab_payload(pvar,
1381 get_payload_uint32(pvar, 5 + description_len))) {
1382 always_display = pvar->ssh_state.payload[0] != 0;
1383 description = pvar->ssh_state.payload + 5;
1384 description[description_len] = 0;
1385 } else {
1386 return TRUE;
1387 }
1388 }
1389
1390 chop_newlines(description);
1391 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1392 description);
1393 if (always_display) {
1394 notify_nonfatal_error(pvar, buf);
1395 } else {
1396 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1397 }
1398 return TRUE;
1399 }
1400
1401 static BOOL handle_disconnect(PTInstVar pvar)
1402 {
1403 int reason_code;
1404 char FAR *description;
1405 int description_len;
1406 char buf[2048];
1407 char FAR *explanation = "";
1408 char uimsg[MAX_UIMSG];
1409
1410 if (SSHv1(pvar)) {
1411 notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1412
1413 if (grab_payload(pvar, 4)
1414 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1415 reason_code = -1;
1416 description = pvar->ssh_state.payload + 4;
1417 description[description_len] = 0;
1418 } else {
1419 return TRUE;
1420 }
1421 } else {
1422 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1423
1424 if (grab_payload(pvar, 8)
1425 && grab_payload(pvar,
1426 (description_len = get_payload_uint32(pvar, 4)) + 4)
1427 && grab_payload(pvar,
1428 get_payload_uint32(pvar, 8 + description_len))) {
1429 reason_code = get_payload_uint32(pvar, 0);
1430 description = pvar->ssh_state.payload + 8;
1431 description[description_len] = 0;
1432 } else {
1433 return TRUE;
1434 }
1435 }
1436
1437 chop_newlines(description);
1438 if (description[0] == 0) {
1439 description = NULL;
1440 }
1441
1442 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1443 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1444 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1445 "This often happens when someone is already forwarding that port from the server.");
1446 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1447 explanation = uimsg;
1448 }
1449
1450 if (description != NULL) {
1451 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1452 "Server disconnected with message '%s'%s");
1453 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1454 pvar->ts->UIMsg, description,
1455 explanation);
1456 } else {
1457 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1458 "Server disconnected (no reason given).%s");
1459 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1460 pvar->ts->UIMsg, explanation);
1461 }
1462 notify_fatal_error(pvar, buf);
1463
1464 return TRUE;
1465 }
1466
1467 static BOOL handle_unimplemented(PTInstVar pvar)
1468 {
1469 /* Should never receive this since we only send base 2.0 protocol messages */
1470 grab_payload(pvar, 4);
1471 return TRUE;
1472 }
1473
1474 static BOOL handle_crypt_success(PTInstVar pvar)
1475 {
1476 notify_verbose_message(pvar, "Secure mode successfully achieved",
1477 LOG_LEVEL_VERBOSE);
1478 return FALSE;
1479 }
1480
1481 static BOOL handle_noauth_success(PTInstVar pvar)
1482 {
1483 notify_verbose_message(pvar, "Server does not require authentication",
1484 LOG_LEVEL_VERBOSE);
1485 prep_compression(pvar);
1486 return FALSE;
1487 }
1488
1489 static BOOL handle_auth_success(PTInstVar pvar)
1490 {
1491 notify_verbose_message(pvar, "Authentication accepted",
1492 LOG_LEVEL_VERBOSE);
1493 prep_compression(pvar);
1494
1495 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1496 start_ssh_heartbeat_thread(pvar);
1497
1498 return FALSE;
1499 }
1500
1501 static BOOL handle_server_public_key(PTInstVar pvar)
1502 {
1503 int server_key_public_exponent_len;
1504 int server_key_public_modulus_pos;
1505 int server_key_public_modulus_len;
1506 int host_key_bits_pos;
1507 int host_key_public_exponent_len;
1508 int host_key_public_modulus_pos;
1509 int host_key_public_modulus_len;
1510 int protocol_flags_pos;
1511 int supported_ciphers;
1512 char FAR *inmsg;
1513 Key hostkey;
1514 int supported_types;
1515
1516 notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1517
1518 if (!grab_payload(pvar, 14))
1519 return FALSE;
1520 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1521
1522 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1523 return FALSE;
1524 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1525 server_key_public_modulus_len =
1526 get_mpint_len(pvar, server_key_public_modulus_pos);
1527
1528 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1529 return FALSE;
1530 host_key_bits_pos =
1531 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1532 host_key_public_exponent_len =
1533 get_mpint_len(pvar, host_key_bits_pos + 4);
1534
1535 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1536 return FALSE;
1537 host_key_public_modulus_pos =
1538 host_key_bits_pos + 6 + host_key_public_exponent_len;
1539 host_key_public_modulus_len =
1540 get_mpint_len(pvar, host_key_public_modulus_pos);
1541
1542 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1543 return FALSE;
1544 protocol_flags_pos =
1545 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1546
1547 inmsg = pvar->ssh_state.payload;
1548
1549 CRYPT_set_server_cookie(pvar, inmsg);
1550 if (!CRYPT_set_server_RSA_key(pvar,
1551 get_uint32(inmsg + 8),
1552 pvar->ssh_state.payload + 12,
1553 inmsg + server_key_public_modulus_pos))
1554 return FALSE;
1555 if (!CRYPT_set_host_RSA_key(pvar,
1556 get_uint32(inmsg + host_key_bits_pos),
1557 inmsg + host_key_bits_pos + 4,
1558 inmsg + host_key_public_modulus_pos))
1559 return FALSE;
1560 pvar->ssh_state.server_protocol_flags =
1561 get_uint32(inmsg + protocol_flags_pos);
1562
1563 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1564 if (!CRYPT_set_supported_ciphers(pvar,
1565 supported_ciphers,
1566 supported_ciphers))
1567 return FALSE;
1568
1569 // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1570 // RSA ���L������ PAGEANT ���L��������
1571 supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1572 if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1573 supported_types |= (1 << SSH_AUTH_PAGEANT);
1574 }
1575 if (!AUTH_set_supported_auth_types(pvar,
1576 supported_types))
1577 return FALSE;
1578
1579 /* this must be the LAST THING in this function, since it can cause
1580 host_is_OK to be called. */
1581 hostkey.type = KEY_RSA1;
1582 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1583 hostkey.exp = inmsg + host_key_bits_pos + 4;
1584 hostkey.mod = inmsg + host_key_public_modulus_pos;
1585 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1586
1587 return FALSE;
1588 }
1589
1590 /*
1591 The ID must have already been found to start with "SSH-". It must
1592 be null-terminated.
1593 */
1594 static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1595 {
1596 char FAR *str;
1597
1598 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1599 }
1600
1601 if (*str != '.') {
1602 return FALSE;
1603 }
1604
1605 pvar->protocol_major = atoi(ID + 4);
1606 pvar->protocol_minor = atoi(str + 1);
1607
1608 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1609 }
1610
1611 return *str == '-';
1612 }
1613
1614 /*
1615 On entry, the pvar->protocol_xxx fields hold the server's advertised
1616 protocol number. We replace the fields with the protocol number we will
1617 actually use, or return FALSE if there is no usable protocol version.
1618 */
1619 static int negotiate_protocol(PTInstVar pvar)
1620 {
1621 switch (pvar->protocol_major) {
1622 case 1:
1623 if (pvar->protocol_minor == 99 &&
1624 pvar->settings.ssh_protocol_version == 2) {
1625 // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1626 // 2.0 ����������
1627 pvar->protocol_major = 2;
1628 pvar->protocol_minor = 0;
1629 return 0;
1630 }
1631
1632 if (pvar->settings.ssh_protocol_version == 2) {
1633 // �o�[�W��������
1634 return -1;
1635 }
1636
1637 if (pvar->protocol_minor > 5) {
1638 pvar->protocol_minor = 5;
1639 }
1640
1641 return 0;
1642
1643 // for SSH2(yutaka)
1644 case 2:
1645 if (pvar->settings.ssh_protocol_version == 1) {
1646 // �o�[�W��������
1647 return -1;
1648 }
1649
1650 return 0; // SSH2 support
1651
1652 default:
1653 return 1;
1654 }
1655 }
1656
1657 static void init_protocol(PTInstVar pvar)
1658 {
1659 CRYPT_initialize_random_numbers(pvar);
1660
1661 // known_hosts�t�@�C�������z�X�g���J������������������
1662 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1663
1664 /* while we wait for a response from the server... */
1665
1666 if (SSHv1(pvar)) {
1667 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1668 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1669 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1670 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1671
1672 } else { // for SSH2(yutaka)
1673 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1674 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1675 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1676 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1677 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1678 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1679 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1680 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1681 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1682 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1683 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1684 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1685 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1686 enque_handler(pvar, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, handle_SSH2_userauth_passwd_changereq);
1687
1688 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1689
1690 // ���[�U�F�������f�B�X�p�b�`���[�`��
1691 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1692 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1693 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1694 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1695 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1696 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1697 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1698 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1699 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1700 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1701 enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1702 // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1703 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1704 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1705
1706 }
1707 }
1708
1709 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1710 {
1711 static char prefix[64];
1712 int negotiate;
1713 char uimsg[MAX_UIMSG];
1714
1715 // initialize SSH2 memory dump (2005.3.7 yutaka)
1716 init_memdump();
1717 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1718
1719 if (ID_len <= 0) {
1720 return FALSE;
1721 } else {
1722 int buf_len;
1723 char FAR *buf;
1724
1725 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1726 buf_len = strlen(prefix) + ID_len + 1;
1727 buf = (char FAR *) malloc(buf_len);
1728 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1729 strncat_s(buf, buf_len, ID, _TRUNCATE);
1730 chop_newlines(buf);
1731 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1732 free(buf);
1733
1734
1735 // ���������R�s�[������ (2005.3.9 yutaka)
1736 #if 0
1737 // for calculate SSH2 hash
1738 // �T�[�o�o�[�W�����������i���s���������������j
1739 if (ID_len >= sizeof(pvar->server_version_string))
1740 return FALSE;
1741 strncpy(pvar->server_version_string, ID, ID_len);
1742 #endif
1743
1744
1745 if (ID[ID_len - 1] != '\n') {
1746 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1747 return FALSE;
1748 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1749 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1750 return FALSE;
1751 } else if (strncmp(ID, "SSH-", 4) != 0) {
1752 return FALSE;
1753 } else {
1754 ID[ID_len - 1] = 0;
1755
1756 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1757 ID[ID_len - 2] = 0;
1758 }
1759
1760 pvar->ssh_state.server_ID = _strdup(ID);
1761
1762 if (!parse_protocol_ID(pvar, ID)) {
1763 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1764 "This program does not understand the server's version of the protocol.");
1765 notify_fatal_error(pvar, pvar->ts->UIMsg);
1766 }
1767 else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1768 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1769 "This program does not understand the server's version of the protocol.");
1770 notify_fatal_error(pvar, pvar->ts->UIMsg);
1771 }
1772 else if (negotiate == -1) {
1773 UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1774 "Protocol version mismatch. server:%d.%d client:%d");
1775 _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1776 pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1777 notify_fatal_error(pvar, uimsg);
1778 }
1779 else {
1780 char TTSSH_ID[1024];
1781 int TTSSH_ID_len;
1782 int a, b, c, d;
1783
1784 // SSH �o�[�W������ teraterm �����Z�b�g����
1785 // SCP �R�}���h������ (2008.2.3 maya)
1786 pvar->cv->isSSH = pvar->protocol_major;
1787
1788 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1789 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1790
1791 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1792 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1793 pvar->protocol_major, pvar->protocol_minor, a, b);
1794 TTSSH_ID_len = strlen(TTSSH_ID);
1795
1796 // for SSH2(yutaka)
1797 // �N���C�A���g�o�[�W�����������i���s���������������j
1798 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1799 TTSSH_ID, _TRUNCATE);
1800
1801 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1802 _snprintf_s(pvar->server_version_string,
1803 sizeof(pvar->server_version_string), _TRUNCATE,
1804 "%s", pvar->ssh_state.server_ID);
1805
1806 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1807 0) != TTSSH_ID_len) {
1808 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1809 "An error occurred while sending the SSH ID string.\n"
1810 "The connection will close.");
1811 notify_fatal_error(pvar, pvar->ts->UIMsg);
1812 } else {
1813 // ���s�R�[�h������ (2004.8.4 yutaka)
1814 pvar->client_version_string[--TTSSH_ID_len] = 0; // \n
1815 pvar->client_version_string[--TTSSH_ID_len] = 0; // \r
1816
1817 strncpy_s(prefix, sizeof(prefix), "Sent client identification string: ", _TRUNCATE);
1818 buf_len = strlen(prefix) + strlen(pvar->client_version_string) + 1;
1819 buf = (char FAR *) malloc(buf_len);
1820 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1821 strncat_s(buf, buf_len, pvar->client_version_string, _TRUNCATE);
1822 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1823 free(buf);
1824
1825 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1826 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1827
1828 // SSH�n���h�����o�^���s��
1829 init_protocol(pvar);
1830
1831 SSH2_dispatch_init(1);
1832 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1833 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1834 }
1835 }
1836
1837 return TRUE;
1838 }
1839 }
1840 }
1841
1842 static BOOL handle_exit(PTInstVar pvar)
1843 {
1844 if (grab_payload(pvar, 4)) {
1845 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1846 finish_send_packet(pvar);
1847 notify_closed_connection(pvar);
1848 }
1849 return TRUE;
1850 }
1851
1852 static BOOL handle_data(PTInstVar pvar)
1853 {
1854 if (grab_payload_limited(pvar, 4)) {
1855 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1856 pvar->ssh_state.payload_datastart = 4;
1857 }
1858 return TRUE;
1859 }
1860
1861 static BOOL handle_channel_open(PTInstVar pvar)
1862 {
1863 int host_len;
1864 int originator_len;
1865
1866 if ((pvar->ssh_state.
1867 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1868 if (grab_payload(pvar, 8)
1869 && grab_payload(pvar,
1870 8 + (host_len = get_payload_uint32(pvar, 4)))
1871 && grab_payload(pvar, originator_len =
1872 get_payload_uint32(pvar, host_len + 12))) {
1873 int local_port = get_payload_uint32(pvar, 8 + host_len);
1874
1875 pvar->ssh_state.payload[8 + host_len] = 0;
1876 FWD_open(pvar, get_payload_uint32(pvar, 0),
1877 pvar->ssh_state.payload + 8, local_port,
1878 pvar->ssh_state.payload + 16 + host_len,
1879 originator_len,
1880 NULL);
1881 }
1882 } else {
1883 if (grab_payload(pvar, 8)
1884 && grab_payload(pvar,
1885 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1886 int local_port = get_payload_uint32(pvar, 8 + host_len);
1887
1888 pvar->ssh_state.payload[8 + host_len] = 0;
1889 FWD_open(pvar, get_payload_uint32(pvar, 0),
1890 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1891 NULL);
1892 }
1893 }
1894
1895 return TRUE;
1896 }
1897
1898 static BOOL handle_X11_channel_open(PTInstVar pvar)
1899 {
1900 int originator_len;
1901
1902 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1903 if (grab_payload(pvar, 8)
1904 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1905 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1906 pvar->ssh_state.payload + 8, originator_len, NULL);
1907 }
1908 } else {
1909 if (grab_payload(pvar, 4)) {
1910 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1911 }
1912 }
1913
1914 return TRUE;
1915 }
1916
1917 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1918 {
1919 if (grab_payload(pvar, 8)) {
1920 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1921 get_payload_uint32(pvar, 4));
1922 }
1923 return FALSE;
1924 }
1925
1926 static BOOL handle_channel_open_failure(PTInstVar pvar)
1927 {
1928 if (grab_payload(pvar, 4)) {
1929 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1930 }
1931 return FALSE;
1932 }
1933
1934 static BOOL handle_channel_data(PTInstVar pvar)
1935 {
1936 int len;
1937
1938 if (grab_payload(pvar, 8)
1939 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1940 FWDChannel *channel;
1941 int local_channel_num = get_payload_uint32(pvar, 0);
1942 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1943 return FALSE;
1944 }
1945 channel = pvar->fwd_state.channels + local_channel_num;
1946 if (channel->type == TYPE_AGENT) {
1947 SSH_agent_response(pvar, NULL, local_channel_num,
1948 pvar->ssh_state.payload + 8, len);
1949 }
1950 else {
1951 FWD_received_data(pvar, local_channel_num,
1952 pvar->ssh_state.payload + 8, len);
1953 }
1954 }
1955 return TRUE;
1956 }
1957
1958 static BOOL handle_channel_input_eof(PTInstVar pvar)
1959 {
1960 if (grab_payload(pvar, 4)) {
1961 int local_channel_num = get_payload_uint32(pvar, 0);
1962 FWDChannel *channel;
1963 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1964 return FALSE;
1965 }
1966 channel = pvar->fwd_state.channels + local_channel_num;
1967 if (channel->type == TYPE_AGENT) {
1968 channel->status |= FWD_CLOSED_REMOTE_IN;
1969 SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1970 }
1971 else {
1972 FWD_channel_input_eof(pvar, local_channel_num);
1973 }
1974 }
1975 return TRUE;
1976 }
1977
1978 static BOOL handle_channel_output_eof(PTInstVar pvar)
1979 {
1980 if (grab_payload(pvar, 4)) {
1981 int local_channel_num = get_payload_uint32(pvar, 0);
1982 FWDChannel *channel;
1983 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1984 return FALSE;
1985 }
1986 channel = pvar->fwd_state.channels + local_channel_num;
1987 if (channel->type == TYPE_AGENT) {
1988 channel->status |= FWD_CLOSED_REMOTE_OUT;
1989 SSH_channel_output_eof(pvar, channel->remote_num);
1990 FWD_free_channel(pvar, local_channel_num);
1991 }
1992 else {
1993 FWD_channel_output_eof(pvar, local_channel_num);
1994 }
1995 }
1996 return TRUE;
1997 }
1998
1999 static BOOL handle_agent_open(PTInstVar pvar)
2000 {
2001 if (grab_payload(pvar, 4)) {
2002 int remote_id = get_payload_uint32(pvar, 0);
2003 int local_id;
2004
2005 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2006 local_id = FWD_agent_open(pvar, remote_id);
2007 if (local_id == -1) {
2008 SSH_fail_channel_open(pvar, remote_id);
2009 }
2010 else {
2011 SSH_confirm_channel_open(pvar, remote_id, local_id);
2012 }
2013 }
2014 else {
2015 SSH_fail_channel_open(pvar, remote_id);
2016 }
2017 }
2018 /*
2019 else {
2020 // ���m��������channel����������������������������
2021 }
2022 */
2023
2024 return TRUE;
2025 }
2026
2027
2028
2029 // �n���h�����O�������b�Z�[�W����������
2030
2031 #define HANDLE_MESSAGE_MAX 30
2032 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2033 static int handle_message_count = 0;
2034 static int handle_message_stage = 0;
2035
2036 void SSH2_dispatch_init(int stage)
2037 {
2038 handle_message_count = 0;
2039 handle_message_stage = stage;
2040 }
2041
2042 int SSH2_dispatch_enabled_check(unsigned char message)
2043 {
2044 int i;
2045
2046 for (i = 0 ; i < handle_message_count ; i++) {
2047 if (handle_messages[i] == message)
2048 return 1;
2049 }
2050 return 0;
2051 }
2052
2053 void SSH2_dispatch_add_message(unsigned char message)
2054 {
2055 int i;
2056
2057 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2058 // TODO: error check
2059 return;
2060 }
2061
2062 // �������o�^�������������b�Z�[�W������������
2063 for (i=0; i<handle_message_count; i++) {
2064 if (handle_messages[i] == message) {
2065 return;
2066 }
2067 }
2068
2069 handle_messages[handle_message_count++] = message;
2070 }
2071
2072 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2073 {
2074 unsigned char c;
2075
2076 for (c = begin ; c <= end ; c++) {
2077 SSH2_dispatch_add_message(c);
2078 }
2079 }
2080
2081
2082 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2083 int padding)
2084 {
2085 unsigned char message = prep_packet(pvar, data, len, padding);
2086
2087
2088 #ifdef SSH2_DEBUG
2089 // for SSH2(yutaka)
2090 if (SSHv2(pvar)) {
2091 if (pvar->key_done) {
2092 message = message;
2093 }
2094
2095 if (pvar->userauth_success) {
2096 message = message;
2097 }
2098
2099 if (pvar->rekeying) {
2100 message = message;
2101 }
2102 }
2103 #endif
2104
2105 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2106 if (message != SSH_MSG_NONE) {
2107 // ���b�Z�[�W�^�C�v���������n���h�����N��
2108 SSHPacketHandler handler = get_handler(pvar, message);
2109
2110 // for SSH2(yutaka)
2111 if (SSHv2(pvar)) {
2112 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2113 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2114 char buf[1024];
2115
2116 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2117 "Unexpected SSH2 message(%d) on current stage(%d)");
2118 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2119 pvar->ts->UIMsg, message, handle_message_stage);
2120 notify_fatal_error(pvar, buf);
2121 // abort
2122 }
2123 }
2124
2125 if (handler == NULL) {
2126 if (SSHv1(pvar)) {
2127 char buf[1024];
2128
2129 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2130 "Unexpected packet type received: %d");
2131 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2132 pvar->ts->UIMsg, message, handle_message_stage);
2133 notify_fatal_error(pvar, buf);
2134 } else {
2135 unsigned char FAR *outmsg =
2136 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2137
2138 set_uint32(outmsg,
2139 pvar->ssh_state.receiver_sequence_number - 1);
2140 finish_send_packet(pvar);
2141
2142 notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2143 /* XXX need to decompress incoming packet, but how? */
2144 }
2145 } else {
2146 if (!handler(pvar)) {
2147 deque_handlers(pvar, message);
2148 }
2149 }
2150 }
2151 }
2152
2153 static BOOL handle_pty_success(PTInstVar pvar)
2154 {
2155 FWD_enter_interactive_mode(pvar);
2156 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2157 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2158 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2159 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2160 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2161 handle_channel_input_eof);
2162 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2163 handle_channel_output_eof);
2164 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2165 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2166 enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2167 return FALSE;
2168 }
2169
2170 static BOOL handle_pty_failure(PTInstVar pvar)
2171 {
2172 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2173 "The server cannot allocate a pseudo-terminal. "
2174 "You may encounter some problems with the terminal.");
2175 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2176 return handle_pty_success(pvar);
2177 }
2178
2179 static void prep_pty(PTInstVar pvar)
2180 {
2181 int len = strlen(pvar->ts->TermType);
2182 unsigned char FAR *outmsg =
2183 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2184 4 + len + 16 + sizeof(ssh_ttymodes));
2185 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2186 static const SSHPacketHandler handlers[]
2187 = { handle_pty_success, handle_pty_failure };
2188
2189 set_uint32(outmsg, len);
2190 memcpy(outmsg + 4, pvar->ts->TermType, len);
2191 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2192 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2193 set_uint32(outmsg + 4 + len + 8, 0);
2194 set_uint32(outmsg + 4 + len + 12, 0);
2195 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2196 finish_send_packet(pvar);
2197
2198 enque_handlers(pvar, 2, msgs, handlers);
2199
2200 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2201 finish_send_packet(pvar);
2202 }
2203
2204 static BOOL handle_agent_request_success(PTInstVar pvar)
2205 {
2206 pvar->agentfwd_enable = TRUE;
2207 prep_pty(pvar);
2208 return FALSE;
2209 }
2210
2211 static BOOL handle_agent_request_failure(PTInstVar pvar)
2212 {
2213 prep_pty(pvar);
2214 return FALSE;
2215 }
2216
2217 static void prep_agent_request(PTInstVar pvar)
2218 {
2219 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2220 static const SSHPacketHandler handlers[]
2221 = { handle_agent_request_success, handle_agent_request_failure };
2222
2223 enque_handlers(pvar, 2, msgs, handlers);
2224
2225 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2226 finish_send_packet(pvar);
2227 }
2228
2229 static void prep_forwarding(PTInstVar pvar)
2230 {
2231 FWD_prep_forwarding(pvar);
2232
2233 if (pvar->session_settings.ForwardAgent) {
2234 prep_agent_request(pvar);
2235 }
2236 else {
2237 prep_pty(pvar);
2238 }
2239 }
2240
2241
2242 //
2243 //
2244 // (2005.7.10 yutaka)
2245 static void enable_send_compression(PTInstVar pvar)
2246 {
2247 static int initialize = 0;
2248
2249 if (initialize) {
2250 deflateEnd(&pvar->ssh_state.compress_stream);
2251 }
2252 initialize = 1;
2253
2254 pvar->ssh_state.compress_stream.zalloc = NULL;
2255 pvar->ssh_state.compress_stream.zfree = NULL;
2256 pvar->ssh_state.compress_stream.opaque = NULL;
2257 if (deflateInit
2258 (&pvar->ssh_state.compress_stream,
2259 pvar->ssh_state.compression_level) != Z_OK) {
2260 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2261 "An error occurred while setting up compression.\n"
2262 "The connection will close.");
2263 notify_fatal_error(pvar, pvar->ts->UIMsg);
2264 return;
2265 } else {
2266 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2267 if (SSHv2(pvar)) {
2268 pvar->ssh_state.compressing = FALSE;
2269 } else {
2270 pvar->ssh_state.compressing = TRUE;
2271 }
2272 }
2273 }
2274
2275 static void enable_recv_compression(PTInstVar pvar)
2276 {
2277 static int initialize = 0;
2278
2279 if (initialize) {
2280 deflateEnd(&pvar->ssh_state.decompress_stream);
2281 }
2282 initialize = 1;
2283
2284 pvar->ssh_state.decompress_stream.zalloc = NULL;
2285 pvar->ssh_state.decompress_stream.zfree = NULL;
2286 pvar->ssh_state.decompress_stream.opaque = NULL;
2287 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2288 deflateEnd(&pvar->ssh_state.compress_stream);
2289 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2290 "An error occurred while setting up compression.\n"
2291 "The connection will close.");
2292 notify_fatal_error(pvar, pvar->ts->UIMsg);
2293 return;
2294 } else {
2295 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2296 if (SSHv2(pvar)) {
2297 pvar->ssh_state.decompressing = FALSE;
2298 } else {
2299 pvar->ssh_state.decompressing = TRUE;
2300 }
2301
2302 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2303 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2304 }
2305 }
2306
2307 static void enable_compression(PTInstVar pvar)
2308 {
2309 enable_send_compression(pvar);
2310 enable_recv_compression(pvar);
2311
2312 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2313 if (SSHv2(pvar)) {
2314 pvar->ssh_state.compressing = FALSE;
2315 pvar->ssh_state.decompressing = FALSE;
2316 }
2317
2318 }
2319
2320 static BOOL handle_enable_compression(PTInstVar pvar)
2321 {
2322 enable_compression(pvar);
2323 prep_forwarding(pvar);
2324 return FALSE;
2325 }
2326
2327 static BOOL handle_disable_compression(PTInstVar pvar)
2328 {
2329 prep_forwarding(pvar);
2330 return FALSE;
2331 }
2332
2333 static void prep_compression(PTInstVar pvar)
2334 {
2335 if (pvar->session_settings.CompressionLevel > 0) {
2336 // added if statement (2005.7.10 yutaka)
2337 if (SSHv1(pvar)) {
2338 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2339 static const SSHPacketHandler handlers[]
2340 = { handle_enable_compression, handle_disable_compression };
2341
2342 unsigned char FAR *outmsg =
2343 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2344
2345 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2346 finish_send_packet(pvar);
2347
2348 enque_handlers(pvar, 2, msgs, handlers);
2349 }
2350
2351 pvar->ssh_state.compression_level =
2352 pvar->session_settings.CompressionLevel;
2353
2354 } else {
2355 // added if statement (2005.7.10 yutaka)
2356 if (SSHv1(pvar)) {
2357 prep_forwarding(pvar);
2358 }
2359 }
2360 }
2361
2362 static void enque_simple_auth_handlers(PTInstVar pvar)
2363 {
2364 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2365 static const SSHPacketHandler handlers[]
2366 = { handle_auth_success, handle_auth_failure };
2367
2368 enque_handlers(pvar, 2, msgs, handlers);
2369 }
2370
2371 static BOOL handle_rsa_challenge(PTInstVar pvar)
2372 {
2373 int challenge_bytes;
2374
2375 if (!grab_payload(pvar, 2)) {
2376 return FALSE;
2377 }
2378
2379 challenge_bytes = get_mpint_len(pvar, 0);
2380
2381 if (grab_payload(pvar, challenge_bytes)) {
2382 unsigned char FAR *outmsg =
2383 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2384
2385 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2386 if (CRYPT_generate_RSA_challenge_response
2387 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2388
2389 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2390 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2391 #if 0
2392 //AUTH_destroy_cur_cred(pvar);
2393 #endif
2394
2395 finish_send_packet(pvar);
2396
2397 enque_simple_auth_handlers(pvar);
2398 } else {
2399 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2400 "An error occurred while decrypting the RSA challenge.\n"
2401 "Perhaps the key file is corrupted.");
2402 notify_fatal_error(pvar, pvar->ts->UIMsg);
2403 }
2404 }
2405 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2406 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2407 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2408 int server_key_bytes = (server_key_bits + 7) / 8;
2409 int host_key_bytes = (host_key_bits + 7) / 8;
2410 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2411 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2412 unsigned char session_id[16];
2413
2414 unsigned char *hash;
2415 int pubkeylen, hashlen;
2416
2417 /* Pageant ���n�b�V�����v�Z���������� */
2418 // ���J��������
2419 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2420 pvar->pageant_keylistlen);
2421 // �Z�b�V����ID������
2422 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2423 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2424 session_buf + host_key_bytes);
2425 memcpy(session_buf + server_key_bytes + host_key_bytes,
2426 pvar->crypt_state.server_cookie, 8);
2427 MD5(session_buf, session_buf_len, session_id);
2428 // �n�b�V������������
2429 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2430 pubkeylen,
2431 pvar->ssh_state.payload,
2432 challenge_bytes + 2,
2433 session_id,
2434 &hashlen);
2435
2436 // �n�b�V�������M
2437 memcpy(outmsg, hash, 16);
2438 free(hash);
2439
2440 finish_send_packet(pvar);
2441
2442 enque_simple_auth_handlers(pvar);
2443 }
2444 }
2445
2446 return FALSE;
2447 }
2448
2449 static void try_send_credentials(PTInstVar pvar)
2450 {
2451 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2452 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2453 static const int RSA_msgs[] =
2454 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2455 static const SSHPacketHandler RSA_handlers[]
2456 = { handle_rsa_challenge, handle_rsa_auth_refused };
2457 static const int TIS_msgs[] =
2458 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2459 static const SSHPacketHandler TIS_handlers[]
2460 = { handle_TIS_challenge, handle_auth_failure };
2461
2462 // SSH2���������������������X�L�b�v
2463 if (SSHv2(pvar))
2464 goto skip_ssh2;
2465
2466 switch (cred->method) {
2467 case SSH_AUTH_NONE:
2468 return;
2469 case SSH_AUTH_PASSWORD:{
2470 int len = strlen(cred->password);
2471 unsigned char FAR *outmsg =
2472 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2473 4 + len);
2474
2475 notify_verbose_message(pvar,
2476 "Trying PASSWORD authentication...",
2477 LOG_LEVEL_VERBOSE);
2478
2479 set_uint32(outmsg, len);
2480 memcpy(outmsg + 4, cred->password, len);
2481
2482 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2483 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2484 #if 0
2485 //AUTH_destroy_cur_cred(pvar);
2486 #endif
2487
2488 enque_simple_auth_handlers(pvar);
2489 break;
2490 }
2491 case SSH_AUTH_RHOSTS:{
2492 int len = strlen(cred->rhosts_client_user);
2493 unsigned char FAR *outmsg =
2494 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2495
2496 notify_verbose_message(pvar,
2497 "Trying RHOSTS authentication...",
2498 LOG_LEVEL_VERBOSE);
2499
2500 set_uint32(outmsg, len);
2501 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2502 AUTH_destroy_cur_cred(pvar);
2503 enque_simple_auth_handlers(pvar);
2504 break;
2505 }
2506 case SSH_AUTH_RSA:{
2507 int len = BN_num_bytes(cred->key_pair->rsa->n);
2508 unsigned char FAR *outmsg =
2509 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2510
2511 notify_verbose_message(pvar,
2512 "Trying RSA authentication...",
2513 LOG_LEVEL_VERBOSE);
2514
2515 set_ushort16_MSBfirst(outmsg, len * 8);
2516 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2517 /* don't destroy the current credentials yet */
2518 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2519 break;
2520 }
2521 case SSH_AUTH_RHOSTS_RSA:{
2522 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2523 int name_len = strlen(cred->rhosts_client_user);
2524 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2525 int index;
2526 unsigned char FAR *outmsg =
2527 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2528 12 + mod_len + name_len + exp_len);
2529
2530 notify_verbose_message(pvar,
2531 "Trying RHOSTS+RSA authentication...",
2532 LOG_LEVEL_VERBOSE);
2533
2534 set_uint32(outmsg, name_len);
2535 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2536 index = 4 + name_len;
2537
2538 set_uint32(outmsg + index, 8 * mod_len);
2539 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2540 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2541 index += 6 + exp_len;
2542
2543 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2544 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2545 /* don't destroy the current credentials yet */
2546 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2547 break;
2548 }
2549 case SSH_AUTH_PAGEANT:{
2550 unsigned char FAR *outmsg;
2551 unsigned char *pubkey;
2552 int len, bn_bytes;
2553
2554 if (pvar->pageant_keycurrent != 0) {
2555 // ���O�������X�L�b�v
2556 pvar->pageant_curkey += 4;
2557 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2558 bn_bytes = (len + 7) / 8;
2559 pvar->pageant_curkey += 2 + bn_bytes;
2560 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2561 bn_bytes = (len + 7) / 8;
2562 pvar->pageant_curkey += 2 + bn_bytes;
2563 // ���O�������R�����g���X�L�b�v
2564 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2565 pvar->pageant_curkey += 4 + len;
2566 // �����������u������
2567 }
2568 pubkey = pvar->pageant_curkey + 4;
2569 len = get_ushort16_MSBfirst(pubkey);
2570 bn_bytes = (len + 7) / 8;
2571 pubkey += 2 + bn_bytes;
2572 len = get_ushort16_MSBfirst(pubkey);
2573 bn_bytes = (len + 7) / 8;
2574 pubkey += 2;
2575 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2576
2577 notify_verbose_message(pvar,
2578 "Trying RSA authentication...",
2579 LOG_LEVEL_VERBOSE);
2580
2581 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2582 memcpy(outmsg + 2, pubkey, bn_bytes);
2583 /* don't destroy the current credentials yet */
2584
2585 pvar->pageant_keycurrent++;
2586
2587 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2588 break;
2589 }
2590 case SSH_AUTH_TIS:{
2591 if (cred->password == NULL) {
2592 unsigned char FAR *outmsg =
2593 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2594
2595 notify_verbose_message(pvar,
2596 "Trying TIS authentication...",
2597 LOG_LEVEL_VERBOSE);
2598 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2599 } else {
2600 int len = strlen(cred->password);
2601 unsigned char FAR *outmsg =
2602 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2603 4 + len);
2604
2605 notify_verbose_message(pvar,
2606 "Sending TIS response",
2607 LOG_LEVEL_VERBOSE);
2608
2609 set_uint32(outmsg, len);
2610 memcpy(outmsg + 4, cred->password, len);
2611 enque_simple_auth_handlers(pvar);
2612 }
2613
2614 AUTH_destroy_cur_cred(pvar);
2615 break;
2616 }
2617 default:
2618 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2619 "Internal error: unsupported authentication method");
2620 notify_fatal_error(pvar, pvar->ts->UIMsg);
2621 return;
2622 }
2623
2624 finish_send_packet(pvar);
2625
2626 skip_ssh2:;
2627 destroy_packet_buf(pvar);
2628
2629 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2630 }
2631 }
2632
2633 static void try_send_user_name(PTInstVar pvar)
2634 {
2635 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2636 char FAR *username = AUTH_get_user_name(pvar);
2637
2638 if (username != NULL) {
2639 int len = strlen(username);
2640 unsigned char FAR *outmsg =
2641 begin_send_packet(pvar, SSH_CMSG_USER, 4 + len);
2642 char buf[1024] = "Sending user name: ";
2643 static const int msgs[] =
2644 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2645 static const SSHPacketHandler handlers[]
2646 = { handle_noauth_success, handle_auth_required };
2647
2648 set_uint32(outmsg, len);
2649 memcpy(outmsg + 4, username, len);
2650 finish_send_packet(pvar);
2651
2652 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2653
2654 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2655 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2656
2657 enque_handlers(pvar, 2, msgs, handlers);
2658 }
2659 }
2660 }
2661
2662 static void send_session_key(PTInstVar pvar)
2663 {
2664 int encrypted_session_key_len;
2665 unsigned char FAR *outmsg;
2666
2667 if (SSHv1(pvar)) {
2668 encrypted_session_key_len =
2669 CRYPT_get_encrypted_session_key_len(pvar);
2670 }
2671
2672 if (!CRYPT_choose_ciphers(pvar))
2673 return;
2674
2675 if (SSHv1(pvar)) {
2676 outmsg =
2677 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2678 15 + encrypted_session_key_len);
2679 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2680 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2681 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2682 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2683 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2684 return;
2685 set_uint32(outmsg + 11 + encrypted_session_key_len,
2686 SSH_PROTOFLAG_SCREEN_NUMBER |
2687 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2688 finish_send_packet(pvar);
2689 }
2690
2691 if (!CRYPT_start_encryption(pvar, 1, 1))
2692 return;
2693 notify_established_secure_connection(pvar);
2694
2695 if (SSHv1(pvar)) {
2696 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2697 }
2698
2699 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2700
2701 if (SSHv1(pvar)) {
2702 try_send_user_name(pvar);
2703 }
2704 }
2705
2706 /*************************
2707 END of message handlers
2708 ************************/
2709
2710 void SSH_init(PTInstVar pvar)
2711 {
2712 int i;
2713
2714 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2715 buf_create(&pvar->ssh_state.precompress_outbuf,
2716 &pvar->ssh_state.precompress_outbuflen);
2717 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2718 &pvar->ssh_state.postdecompress_inbuflen);
2719 pvar->ssh_state.payload = NULL;
2720 pvar->ssh_state.compressing = FALSE;
2721 pvar->ssh_state.decompressing = FALSE;
2722 pvar->ssh_state.status_flags =
2723 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2724 pvar->ssh_state.payload_datalen = 0;
2725 pvar->ssh_state.hostname = NULL;
2726 pvar->ssh_state.server_ID = NULL;
2727 pvar->ssh_state.receiver_sequence_number = 0;
2728 pvar->ssh_state.sender_sequence_number = 0;
2729 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2730 pvar->ssh_state.packet_handlers[i] = NULL;
2731 }
2732
2733 // for SSH2(yutaka)
2734 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2735 pvar->userauth_success = 0;
2736 pvar->session_nego_status = 0;
2737 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2738 pvar->rekeying = 0;
2739 pvar->key_done = 0;
2740 pvar->ssh2_autologin = 0; // autologin disabled(default)
2741 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2742 pvar->userauth_retry_count = 0;
2743 pvar->decomp_buffer = NULL;
2744 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2745 pvar->tryed_ssh2_authlist = FALSE;
2746 pvar->agentfwd_enable = FALSE;
2747
2748 }
2749
2750 void SSH_open(PTInstVar pvar)
2751 {
2752 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2753 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2754 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2755 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2756 }
2757
2758 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2759 {
2760 if (SSHv1(pvar)) {
2761 int len = reason == NULL ? 0 : strlen(reason);
2762 unsigned char FAR *outmsg =
2763 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2764
2765 set_uint32(outmsg, len);
2766 if (reason != NULL) {
2767 memcpy(outmsg + 4, reason, len);
2768 }
2769 finish_send_packet(pvar);
2770
2771 } else { // for SSH2(yutaka)
2772 buffer_t *msg;
2773 unsigned char *outmsg;
2774 int len;
2775 Channel_t *c;
2776
2777 c = ssh2_channel_lookup(pvar->shell_id);
2778 if (c == NULL)
2779 return;
2780
2781 // SSH2 server��channel close���`����
2782 msg = buffer_init();
2783 if (msg == NULL) {
2784 // TODO: error check
2785 return;
2786 }
2787 buffer_put_int(msg, c->remote_id);
2788
2789 len = buffer_len(msg);
2790 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2791 memcpy(outmsg, buffer_ptr(msg), len);
2792 finish_send_packet(pvar);
2793 buffer_free(msg);
2794
2795 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_CLOSE was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2796 }
2797
2798 }
2799
2800 void SSH_notify_host_OK(PTInstVar pvar)
2801 {
2802 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2803 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2804 send_session_key(pvar);
2805 }
2806 }
2807
2808 void get_window_pixel_size(PTInstVar pvar, int *x, int *y)
2809 {
2810 RECT r;
2811
2812 if (pvar->cv->HWin && GetWindowRect(pvar->cv->HWin, &r)) {
2813 *x = r.right - r.left;
2814 *y = r.bottom - r.top;
2815 }
2816 else {
2817 *x = 0;
2818 *y = 0;
2819 }
2820
2821 return;
2822 }
2823
2824 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2825 {
2826 int x, y;
2827
2828 pvar->ssh_state.win_cols = cols;
2829 pvar->ssh_state.win_rows = rows;
2830
2831 if (SSHv1(pvar)) {
2832 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2833 unsigned char FAR *outmsg =
2834 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2835
2836 set_uint32(outmsg, rows);
2837 set_uint32(outmsg + 4, cols);
2838 set_uint32(outmsg + 8, 0);
2839 set_uint32(outmsg + 12, 0);
2840 finish_send_packet(pvar);
2841 }
2842
2843 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2844 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2845 buffer_t *msg;
2846 char *s;
2847 unsigned char *outmsg;
2848 int len;
2849 Channel_t *c;
2850
2851 c = ssh2_channel_lookup(pvar->shell_id);
2852 if (c == NULL)
2853 return;
2854
2855 msg = buffer_init();
2856 if (msg == NULL) {
2857 // TODO: error check
2858 return;
2859 }
2860 buffer_put_int(msg, c->remote_id);
2861 s = "window-change";
2862 buffer_put_string(msg, s, strlen(s));
2863 buffer_put_char(msg, 0); // wantconfirm
2864 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2865 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2866 get_window_pixel_size(pvar, &x, &y);
2867 buffer_put_int(msg, x); // window width (pixel):
2868 buffer_put_int(msg, y); // window height (pixel):
2869 len = buffer_len(msg);
2870 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2871 memcpy(outmsg, buffer_ptr(msg), len);
2872 finish_send_packet(pvar);
2873 buffer_free(msg);
2874
2875 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2876
2877 } else {
2878 // SSH�����������������������B
2879
2880 }
2881
2882 }
2883
2884 // �u���[�N�M���������B
2885 // OpenSSH ��"~B"�����������B�������ASSH2�����B
2886 // (2010.9.27 yutaka)
2887 int SSH_notify_break_signal(PTInstVar pvar)
2888 {
2889 int ret = 0;
2890
2891 if (SSHv1(pvar)) {
2892 // �����������B
2893
2894 } else if (SSHv2(pvar)) {
2895 buffer_t *msg;
2896 char *s;
2897 unsigned char *outmsg;
2898 int len;
2899 Channel_t *c;
2900
2901 c = ssh2_channel_lookup(pvar->shell_id);
2902 if (c == NULL)
2903 goto error;
2904
2905 msg = buffer_init();
2906 if (msg == NULL) {
2907 goto error;
2908 }
2909 buffer_put_int(msg, c->remote_id);
2910 s = "break";
2911 buffer_put_string(msg, s, strlen(s));
2912 buffer_put_char(msg, 0); // wantconfirm
2913 buffer_put_int(msg, 1000);
2914 len = buffer_len(msg);
2915 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2916 memcpy(outmsg, buffer_ptr(msg), len);
2917 finish_send_packet(pvar);
2918 buffer_free(msg);
2919
2920 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_break_signal().", LOG_LEVEL_VERBOSE);
2921
2922 ret = 1;
2923
2924 } else {
2925 // SSH�����������������������B
2926
2927 }
2928
2929 error:
2930 return (ret);
2931 }
2932
2933 int SSH_get_min_packet_size(PTInstVar pvar)
2934 {
2935 if (SSHv1(pvar)) {
2936 return 12;
2937 } else {
2938 int block_size = CRYPT_get_decryption_block_size(pvar);
2939
2940 return max(16, block_size);
2941 }
2942 }
2943
2944 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2945 at least 5 bytes must be decrypted */
2946 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2947 {
2948 if (SSHv2(pvar)) {
2949 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2950 }
2951 }
2952
2953 int SSH_get_clear_MAC_size(PTInstVar pvar)
2954 {
2955 if (SSHv1(pvar)) {
2956 return 0;
2957 } else {
2958 return CRYPT_get_receiver_MAC_size(pvar);
2959 }
2960 }
2961
2962 void SSH_notify_user_name(PTInstVar pvar)
2963 {
2964 try_send_user_name(pvar);
2965 }
2966
2967 void SSH_notify_cred(PTInstVar pvar)
2968 {
2969 try_send_credentials(pvar);
2970 }
2971
2972 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2973 {
2974 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2975 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
2976 init_memdump();
2977 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2978 }
2979
2980 if (SSHv1(pvar)) {
2981 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2982 return;
2983 }
2984
2985 while (buflen > 0) {
2986 int len =
2987 buflen >
2988 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2989 unsigned char FAR *outmsg =
2990 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2991
2992 set_uint32(outmsg, len);
2993
2994 if (pvar->ssh_state.compressing) {
2995 buf_ensure_size(&pvar->ssh_state.outbuf,
2996 &pvar->ssh_state.outbuflen,
2997 len + (len >> 6) + 50);
2998 pvar->ssh_state.compress_stream.next_in =
2999 pvar->ssh_state.precompress_outbuf;
3000 pvar->ssh_state.compress_stream.avail_in = 5;
3001 pvar->ssh_state.compress_stream.next_out =
3002 pvar->ssh_state.outbuf + 12;
3003 pvar->ssh_state.compress_stream.avail_out =
3004 pvar->ssh_state.outbuflen - 12;
3005
3006 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
3007 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3008 "Error compressing packet data");
3009 notify_fatal_error(pvar, pvar->ts->UIMsg);
3010 return;
3011 }
3012
3013 pvar->ssh_state.compress_stream.next_in =
3014 (unsigned char FAR *) buf;
3015 pvar->ssh_state.compress_stream.avail_in = len;
3016
3017 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
3018 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3019 "Error compressing packet data");
3020 notify_fatal_error(pvar, pvar->ts->UIMsg);
3021 return;
3022 }
3023 } else {
3024 memcpy(outmsg + 4, buf, len);
3025 }
3026
3027 finish_send_packet_special(pvar, 1);
3028
3029 buflen -= len;
3030 buf += len;
3031 }
3032
3033 } else { // for SSH2(yutaka)
3034 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
3035 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
3036 }
3037
3038 }
3039
3040 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
3041 {
3042 int num_bytes = pvar->ssh_state.payload_datalen;
3043
3044 if (num_bytes > len) {
3045 num_bytes = len;
3046 }
3047
3048 if (!pvar->ssh_state.decompressing) {
3049 memcpy(dest,
3050 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
3051 num_bytes);
3052 pvar->ssh_state.payload_datastart += num_bytes;
3053 } else if (num_bytes > 0) {
3054 pvar->ssh_state.decompress_stream.next_out = dest;
3055 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
3056
3057 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
3058 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
3059 "Invalid compressed data in received packet");
3060 notify_fatal_error(pvar, pvar->ts->UIMsg);
3061 return 0;
3062 }
3063 }
3064
3065 pvar->ssh_state.payload_datalen -= num_bytes;
3066
3067 return num_bytes;
3068 }
3069
3070 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
3071 {
3072 char buf[1024];
3073 char buf2[1024];
3074
3075 // added support of SSH2 packet compression (2005.7.10 yutaka)
3076 // support of "Compression delayed" (2006.6.23 maya)
3077 if (pvar->ssh_state.compressing ||
3078 pvar->ctos_compression == COMP_ZLIB ||
3079 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3080 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
3081 unsigned long total_out =
3082 pvar->ssh_state.compress_stream.total_out;
3083
3084 if (total_out > 0) {
3085 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3086 "level %d; ratio %.1f (%ld:%ld)");
3087 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3088 pvar->ssh_state.compression_level,
3089 ((double) total_in) / total_out, total_in,
3090 total_out);
3091 } else {
3092 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3093 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3094 pvar->ssh_state.compression_level);
3095 }
3096 } else {
3097 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3098 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
3099 }
3100
3101 // support of "Compression delayed" (2006.6.23 maya)
3102 if (pvar->ssh_state.decompressing ||
3103 pvar->stoc_compression == COMP_ZLIB ||
3104 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3105 unsigned long total_in =
3106 pvar->ssh_state.decompress_stream.total_in;
3107 unsigned long total_out =
3108 pvar->ssh_state.decompress_stream.total_out;
3109
3110 if (total_in > 0) {
3111 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3112 "level %d; ratio %.1f (%ld:%ld)");
3113 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3114 pvar->ssh_state.compression_level,
3115 ((double) total_out) / total_in, total_out,
3116 total_in);
3117 } else {
3118 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3119 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3120 pvar->ssh_state.compression_level);
3121 }
3122 } else {
3123 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3124 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
3125 }
3126
3127 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
3128 "Upstream %s; Downstream %s");
3129 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
3130 }
3131
3132 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
3133 {
3134 strncpy_s(dest, len,
3135 pvar->ssh_state.server_ID == NULL ? "Unknown"
3136 : pvar->ssh_state.server_ID,
3137 _TRUNCATE);
3138 }
3139
3140 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
3141 int len)
3142 {
3143 if (pvar->protocol_major == 0) {
3144 strncpy_s(dest, len, "Unknown", _TRUNCATE);
3145 } else {
3146 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
3147 pvar->protocol_minor);
3148 }
3149 }
3150
3151 void SSH_end(PTInstVar pvar)
3152 {
3153 int i;
3154 int mode;
3155
3156 for (i = 0; i < 256; i++) {
3157 SSHPacketHandlerItem FAR *first_item =
3158 pvar->ssh_state.packet_handlers[i];
3159
3160 if (first_item != NULL) {
3161 SSHPacketHandlerItem FAR *item = first_item;
3162
3163 do {
3164 SSHPacketHandlerItem FAR *cur_item = item;
3165
3166 item = item->next_for_message;
3167 free(cur_item);
3168 } while (item != first_item);
3169 }
3170 pvar->ssh_state.packet_handlers[i] = NULL;
3171 }
3172
3173 free(pvar->ssh_state.hostname);
3174 pvar->ssh_state.hostname = NULL;
3175 free(pvar->ssh_state.server_ID);
3176 pvar->ssh_state.server_ID = NULL;
3177 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
3178 buf_destroy(&pvar->ssh_state.precompress_outbuf,
3179 &pvar->ssh_state.precompress_outbuflen);
3180 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
3181 &pvar->ssh_state.postdecompress_inbuflen);
3182 pvar->agentfwd_enable = FALSE;
3183
3184 // support of "Compression delayed" (2006.6.23 maya)
3185 if (pvar->ssh_state.compressing ||
3186 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3187 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3188 deflateEnd(&pvar->ssh_state.compress_stream);
3189 pvar->ssh_state.compressing = FALSE;
3190 }
3191 // support of "Compression delayed" (2006.6.23 maya)
3192 if (pvar->ssh_state.decompressing ||
3193 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3194 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3195 inflateEnd(&pvar->ssh_state.decompress_stream);
3196 pvar->ssh_state.decompressing = FALSE;
3197 }
3198
3199 #if 1
3200 // SSH2���f�[�^���������� (2004.12.27 yutaka)
3201 if (SSHv2(pvar)) {
3202 if (pvar->kexdh) {
3203 DH_free(pvar->kexdh);
3204 pvar->kexdh = NULL;
3205 }
3206 if (pvar->ecdh_client_key) {
3207 EC_KEY_free(pvar->ecdh_client_key);
3208 pvar