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 4888 - (show annotations) (download) (as text)
Mon Apr 9 16:54:49 2012 UTC (12 years ago) by maya
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 249215 byte(s)
~/hoge/ のようなパスを HOME と認識しないようにした
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 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1835 }
1836 }
1837
1838 return TRUE;
1839 }
1840 }
1841 }
1842
1843 static BOOL handle_exit(PTInstVar pvar)
1844 {
1845 if (grab_payload(pvar, 4)) {
1846 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1847 finish_send_packet(pvar);
1848 notify_closed_connection(pvar);
1849 }
1850 return TRUE;
1851 }
1852
1853 static BOOL handle_data(PTInstVar pvar)
1854 {
1855 if (grab_payload_limited(pvar, 4)) {
1856 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1857 pvar->ssh_state.payload_datastart = 4;
1858 }
1859 return TRUE;
1860 }
1861
1862 static BOOL handle_channel_open(PTInstVar pvar)
1863 {
1864 int host_len;
1865 int originator_len;
1866
1867 if ((pvar->ssh_state.
1868 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1869 if (grab_payload(pvar, 8)
1870 && grab_payload(pvar,
1871 8 + (host_len = get_payload_uint32(pvar, 4)))
1872 && grab_payload(pvar, originator_len =
1873 get_payload_uint32(pvar, host_len + 12))) {
1874 int local_port = get_payload_uint32(pvar, 8 + host_len);
1875
1876 pvar->ssh_state.payload[8 + host_len] = 0;
1877 FWD_open(pvar, get_payload_uint32(pvar, 0),
1878 pvar->ssh_state.payload + 8, local_port,
1879 pvar->ssh_state.payload + 16 + host_len,
1880 originator_len,
1881 NULL);
1882 }
1883 } else {
1884 if (grab_payload(pvar, 8)
1885 && grab_payload(pvar,
1886 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1887 int local_port = get_payload_uint32(pvar, 8 + host_len);
1888
1889 pvar->ssh_state.payload[8 + host_len] = 0;
1890 FWD_open(pvar, get_payload_uint32(pvar, 0),
1891 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1892 NULL);
1893 }
1894 }
1895
1896 return TRUE;
1897 }
1898
1899 static BOOL handle_X11_channel_open(PTInstVar pvar)
1900 {
1901 int originator_len;
1902
1903 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1904 if (grab_payload(pvar, 8)
1905 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1906 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1907 pvar->ssh_state.payload + 8, originator_len, NULL);
1908 }
1909 } else {
1910 if (grab_payload(pvar, 4)) {
1911 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1912 }
1913 }
1914
1915 return TRUE;
1916 }
1917
1918 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1919 {
1920 if (grab_payload(pvar, 8)) {
1921 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1922 get_payload_uint32(pvar, 4));
1923 }
1924 return FALSE;
1925 }
1926
1927 static BOOL handle_channel_open_failure(PTInstVar pvar)
1928 {
1929 if (grab_payload(pvar, 4)) {
1930 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1931 }
1932 return FALSE;
1933 }
1934
1935 static BOOL handle_channel_data(PTInstVar pvar)
1936 {
1937 int len;
1938
1939 if (grab_payload(pvar, 8)
1940 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1941 FWDChannel *channel;
1942 int local_channel_num = get_payload_uint32(pvar, 0);
1943 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1944 return FALSE;
1945 }
1946 channel = pvar->fwd_state.channels + local_channel_num;
1947 if (channel->type == TYPE_AGENT) {
1948 SSH_agent_response(pvar, NULL, local_channel_num,
1949 pvar->ssh_state.payload + 8, len);
1950 }
1951 else {
1952 FWD_received_data(pvar, local_channel_num,
1953 pvar->ssh_state.payload + 8, len);
1954 }
1955 }
1956 return TRUE;
1957 }
1958
1959 static BOOL handle_channel_input_eof(PTInstVar pvar)
1960 {
1961 if (grab_payload(pvar, 4)) {
1962 int local_channel_num = get_payload_uint32(pvar, 0);
1963 FWDChannel *channel;
1964 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1965 return FALSE;
1966 }
1967 channel = pvar->fwd_state.channels + local_channel_num;
1968 if (channel->type == TYPE_AGENT) {
1969 channel->status |= FWD_CLOSED_REMOTE_IN;
1970 SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1971 }
1972 else {
1973 FWD_channel_input_eof(pvar, local_channel_num);
1974 }
1975 }
1976 return TRUE;
1977 }
1978
1979 static BOOL handle_channel_output_eof(PTInstVar pvar)
1980 {
1981 if (grab_payload(pvar, 4)) {
1982 int local_channel_num = get_payload_uint32(pvar, 0);
1983 FWDChannel *channel;
1984 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1985 return FALSE;
1986 }
1987 channel = pvar->fwd_state.channels + local_channel_num;
1988 if (channel->type == TYPE_AGENT) {
1989 channel->status |= FWD_CLOSED_REMOTE_OUT;
1990 SSH_channel_output_eof(pvar, channel->remote_num);
1991 FWD_free_channel(pvar, local_channel_num);
1992 }
1993 else {
1994 FWD_channel_output_eof(pvar, local_channel_num);
1995 }
1996 }
1997 return TRUE;
1998 }
1999
2000 static BOOL handle_agent_open(PTInstVar pvar)
2001 {
2002 if (grab_payload(pvar, 4)) {
2003 int remote_id = get_payload_uint32(pvar, 0);
2004 int local_id;
2005
2006 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2007 local_id = FWD_agent_open(pvar, remote_id);
2008 if (local_id == -1) {
2009 SSH_fail_channel_open(pvar, remote_id);
2010 }
2011 else {
2012 SSH_confirm_channel_open(pvar, remote_id, local_id);
2013 }
2014 }
2015 else {
2016 SSH_fail_channel_open(pvar, remote_id);
2017 }
2018 }
2019 /*
2020 else {
2021 // ���m��������channel����������������������������
2022 }
2023 */
2024
2025 return TRUE;
2026 }
2027
2028
2029
2030 // �n���h�����O�������b�Z�[�W����������
2031
2032 #define HANDLE_MESSAGE_MAX 30
2033 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2034 static int handle_message_count = 0;
2035 static int handle_message_stage = 0;
2036
2037 void SSH2_dispatch_init(int stage)
2038 {
2039 handle_message_count = 0;
2040 handle_message_stage = stage;
2041 }
2042
2043 int SSH2_dispatch_enabled_check(unsigned char message)
2044 {
2045 int i;
2046
2047 for (i = 0 ; i < handle_message_count ; i++) {
2048 if (handle_messages[i] == message)
2049 return 1;
2050 }
2051 return 0;
2052 }
2053
2054 void SSH2_dispatch_add_message(unsigned char message)
2055 {
2056 int i;
2057
2058 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2059 // TODO: error check
2060 return;
2061 }
2062
2063 // �������o�^�������������b�Z�[�W������������
2064 for (i=0; i<handle_message_count; i++) {
2065 if (handle_messages[i] == message) {
2066 return;
2067 }
2068 }
2069
2070 handle_messages[handle_message_count++] = message;
2071 }
2072
2073 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2074 {
2075 unsigned char c;
2076
2077 for (c = begin ; c <= end ; c++) {
2078 SSH2_dispatch_add_message(c);
2079 }
2080 }
2081
2082
2083 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2084 int padding)
2085 {
2086 unsigned char message = prep_packet(pvar, data, len, padding);
2087
2088
2089 #ifdef SSH2_DEBUG
2090 // for SSH2(yutaka)
2091 if (SSHv2(pvar)) {
2092 if (pvar->key_done) {
2093 message = message;
2094 }
2095
2096 if (pvar->userauth_success) {
2097 message = message;
2098 }
2099
2100 if (pvar->rekeying) {
2101 message = message;
2102 }
2103 }
2104 #endif
2105
2106 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2107 if (message != SSH_MSG_NONE) {
2108 // ���b�Z�[�W�^�C�v���������n���h�����N��
2109 SSHPacketHandler handler = get_handler(pvar, message);
2110
2111 // for SSH2(yutaka)
2112 if (SSHv2(pvar)) {
2113 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2114 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2115 char buf[1024];
2116
2117 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2118 "Unexpected SSH2 message(%d) on current stage(%d)");
2119 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2120 pvar->ts->UIMsg, message, handle_message_stage);
2121 notify_fatal_error(pvar, buf);
2122 // abort
2123 }
2124 }
2125
2126 if (handler == NULL) {
2127 if (SSHv1(pvar)) {
2128 char buf[1024];
2129
2130 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2131 "Unexpected packet type received: %d");
2132 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2133 pvar->ts->UIMsg, message, handle_message_stage);
2134 notify_fatal_error(pvar, buf);
2135 } else {
2136 unsigned char FAR *outmsg =
2137 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2138
2139 set_uint32(outmsg,
2140 pvar->ssh_state.receiver_sequence_number - 1);
2141 finish_send_packet(pvar);
2142
2143 notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2144 /* XXX need to decompress incoming packet, but how? */
2145 }
2146 } else {
2147 if (!handler(pvar)) {
2148 deque_handlers(pvar, message);
2149 }
2150 }
2151 }
2152 }
2153
2154 static BOOL handle_pty_success(PTInstVar pvar)
2155 {
2156 FWD_enter_interactive_mode(pvar);
2157 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2158 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2159 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2160 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2161 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2162 handle_channel_input_eof);
2163 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2164 handle_channel_output_eof);
2165 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2166 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2167 enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2168 return FALSE;
2169 }
2170
2171 static BOOL handle_pty_failure(PTInstVar pvar)
2172 {
2173 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2174 "The server cannot allocate a pseudo-terminal. "
2175 "You may encounter some problems with the terminal.");
2176 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2177 return handle_pty_success(pvar);
2178 }
2179
2180 static void prep_pty(PTInstVar pvar)
2181 {
2182 int len = strlen(pvar->ts->TermType);
2183 unsigned char FAR *outmsg =
2184 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2185 4 + len + 16 + sizeof(ssh_ttymodes));
2186 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2187 static const SSHPacketHandler handlers[]
2188 = { handle_pty_success, handle_pty_failure };
2189
2190 set_uint32(outmsg, len);
2191 memcpy(outmsg + 4, pvar->ts->TermType, len);
2192 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2193 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2194 set_uint32(outmsg + 4 + len + 8, 0);
2195 set_uint32(outmsg + 4 + len + 12, 0);
2196 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2197 finish_send_packet(pvar);
2198
2199 enque_handlers(pvar, 2, msgs, handlers);
2200
2201 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2202 finish_send_packet(pvar);
2203 }
2204
2205 static BOOL handle_agent_request_success(PTInstVar pvar)
2206 {
2207 pvar->agentfwd_enable = TRUE;
2208 prep_pty(pvar);
2209 return FALSE;
2210 }
2211
2212 static BOOL handle_agent_request_failure(PTInstVar pvar)
2213 {
2214 prep_pty(pvar);
2215 return FALSE;
2216 }
2217
2218 static void prep_agent_request(PTInstVar pvar)
2219 {
2220 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2221 static const SSHPacketHandler handlers[]
2222 = { handle_agent_request_success, handle_agent_request_failure };
2223
2224 enque_handlers(pvar, 2, msgs, handlers);
2225
2226 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2227 finish_send_packet(pvar);
2228 }
2229
2230 static void prep_forwarding(PTInstVar pvar)
2231 {
2232 FWD_prep_forwarding(pvar);
2233
2234 if (pvar->session_settings.ForwardAgent) {
2235 prep_agent_request(pvar);
2236 }
2237 else {
2238 prep_pty(pvar);
2239 }
2240 }
2241
2242
2243 //
2244 //
2245 // (2005.7.10 yutaka)
2246 static void enable_send_compression(PTInstVar pvar)
2247 {
2248 static int initialize = 0;
2249
2250 if (initialize) {
2251 deflateEnd(&pvar->ssh_state.compress_stream);
2252 }
2253 initialize = 1;
2254
2255 pvar->ssh_state.compress_stream.zalloc = NULL;
2256 pvar->ssh_state.compress_stream.zfree = NULL;
2257 pvar->ssh_state.compress_stream.opaque = NULL;
2258 if (deflateInit
2259 (&pvar->ssh_state.compress_stream,
2260 pvar->ssh_state.compression_level) != Z_OK) {
2261 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2262 "An error occurred while setting up compression.\n"
2263 "The connection will close.");
2264 notify_fatal_error(pvar, pvar->ts->UIMsg);
2265 return;
2266 } else {
2267 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2268 if (SSHv2(pvar)) {
2269 pvar->ssh_state.compressing = FALSE;
2270 } else {
2271 pvar->ssh_state.compressing = TRUE;
2272 }
2273 }
2274 }
2275
2276 static void enable_recv_compression(PTInstVar pvar)
2277 {
2278 static int initialize = 0;
2279
2280 if (initialize) {
2281 deflateEnd(&pvar->ssh_state.decompress_stream);
2282 }
2283 initialize = 1;
2284
2285 pvar->ssh_state.decompress_stream.zalloc = NULL;
2286 pvar->ssh_state.decompress_stream.zfree = NULL;
2287 pvar->ssh_state.decompress_stream.opaque = NULL;
2288 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2289 deflateEnd(&pvar->ssh_state.compress_stream);
2290 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2291 "An error occurred while setting up compression.\n"
2292 "The connection will close.");
2293 notify_fatal_error(pvar, pvar->ts->UIMsg);
2294 return;
2295 } else {
2296 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2297 if (SSHv2(pvar)) {
2298 pvar->ssh_state.decompressing = FALSE;
2299 } else {
2300 pvar->ssh_state.decompressing = TRUE;
2301 }
2302
2303 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2304 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2305 }
2306 }
2307
2308 static void enable_compression(PTInstVar pvar)
2309 {
2310 enable_send_compression(pvar);
2311 enable_recv_compression(pvar);
2312
2313 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2314 if (SSHv2(pvar)) {
2315 pvar->ssh_state.compressing = FALSE;
2316 pvar->ssh_state.decompressing = FALSE;
2317 }
2318
2319 }
2320
2321 static BOOL handle_enable_compression(PTInstVar pvar)
2322 {
2323 enable_compression(pvar);
2324 prep_forwarding(pvar);
2325 return FALSE;
2326 }
2327
2328 static BOOL handle_disable_compression(PTInstVar pvar)
2329 {
2330 prep_forwarding(pvar);
2331 return FALSE;
2332 }
2333
2334 static void prep_compression(PTInstVar pvar)
2335 {
2336 if (pvar->session_settings.CompressionLevel > 0) {
2337 // added if statement (2005.7.10 yutaka)
2338 if (SSHv1(pvar)) {
2339 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2340 static const SSHPacketHandler handlers[]
2341 = { handle_enable_compression, handle_disable_compression };
2342
2343 unsigned char FAR *outmsg =
2344 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2345
2346 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2347 finish_send_packet(pvar);
2348
2349 enque_handlers(pvar, 2, msgs, handlers);
2350 }
2351
2352 pvar->ssh_state.compression_level =
2353 pvar->session_settings.CompressionLevel;
2354
2355 } else {
2356 // added if statement (2005.7.10 yutaka)
2357 if (SSHv1(pvar)) {
2358 prep_forwarding(pvar);
2359 }
2360 }
2361 }
2362
2363 static void enque_simple_auth_handlers(PTInstVar pvar)
2364 {
2365 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2366 static const SSHPacketHandler handlers[]
2367 = { handle_auth_success, handle_auth_failure };
2368
2369 enque_handlers(pvar, 2, msgs, handlers);
2370 }
2371
2372 static BOOL handle_rsa_challenge(PTInstVar pvar)
2373 {
2374 int challenge_bytes;
2375
2376 if (!grab_payload(pvar, 2)) {
2377 return FALSE;
2378 }
2379
2380 challenge_bytes = get_mpint_len(pvar, 0);
2381
2382 if (grab_payload(pvar, challenge_bytes)) {
2383 unsigned char FAR *outmsg =
2384 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2385
2386 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2387 if (CRYPT_generate_RSA_challenge_response
2388 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2389
2390 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2391 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2392 #if 0
2393 //AUTH_destroy_cur_cred(pvar);
2394 #endif
2395
2396 finish_send_packet(pvar);
2397
2398 enque_simple_auth_handlers(pvar);
2399 } else {
2400 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2401 "An error occurred while decrypting the RSA challenge.\n"
2402 "Perhaps the key file is corrupted.");
2403 notify_fatal_error(pvar, pvar->ts->UIMsg);
2404 }
2405 }
2406 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2407 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2408 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2409 int server_key_bytes = (server_key_bits + 7) / 8;
2410 int host_key_bytes = (host_key_bits + 7) / 8;
2411 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2412 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2413 unsigned char session_id[16];
2414
2415 unsigned char *hash;
2416 int pubkeylen, hashlen;
2417
2418 /* Pageant ���n�b�V�����v�Z���������� */
2419 // ���J��������
2420 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2421 pvar->pageant_keylistlen);
2422 // �Z�b�V����ID������
2423 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2424 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2425 session_buf + host_key_bytes);
2426 memcpy(session_buf + server_key_bytes + host_key_bytes,
2427 pvar->crypt_state.server_cookie, 8);
2428 MD5(session_buf, session_buf_len, session_id);
2429 // �n�b�V������������
2430 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2431 pubkeylen,
2432 pvar->ssh_state.payload,
2433 challenge_bytes + 2,
2434 session_id,
2435 &hashlen);
2436
2437 // �n�b�V�������M
2438 memcpy(outmsg, hash, 16);
2439 free(hash);
2440
2441 finish_send_packet(pvar);
2442
2443 enque_simple_auth_handlers(pvar);
2444 }
2445 }
2446
2447 return FALSE;
2448 }
2449
2450 static void try_send_credentials(PTInstVar pvar)
2451 {
2452 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2453 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2454 static const int RSA_msgs[] =
2455 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2456 static const SSHPacketHandler RSA_handlers[]
2457 = { handle_rsa_challenge, handle_rsa_auth_refused };
2458 static const int TIS_msgs[] =
2459 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2460 static const SSHPacketHandler TIS_handlers[]
2461 = { handle_TIS_challenge, handle_auth_failure };
2462
2463 // SSH2���������������������X�L�b�v
2464 if (SSHv2(pvar))
2465 goto skip_ssh2;
2466
2467 switch (cred->method) {
2468 case SSH_AUTH_NONE:
2469 return;
2470 case SSH_AUTH_PASSWORD:{
2471 int len = strlen(cred->password);
2472 unsigned char FAR *outmsg =
2473 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2474 4 + len);
2475
2476 notify_verbose_message(pvar,
2477 "Trying PASSWORD authentication...",
2478 LOG_LEVEL_VERBOSE);
2479
2480 set_uint32(outmsg, len);
2481 memcpy(outmsg + 4, cred->password, len);
2482
2483 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2484 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2485 #if 0
2486 //AUTH_destroy_cur_cred(pvar);
2487 #endif
2488
2489 enque_simple_auth_handlers(pvar);
2490 break;
2491 }
2492 case SSH_AUTH_RHOSTS:{
2493 int len = strlen(cred->rhosts_client_user);
2494 unsigned char FAR *outmsg =
2495 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2496
2497 notify_verbose_message(pvar,
2498 "Trying RHOSTS authentication...",
2499 LOG_LEVEL_VERBOSE);
2500
2501 set_uint32(outmsg, len);
2502 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2503 AUTH_destroy_cur_cred(pvar);
2504 enque_simple_auth_handlers(pvar);
2505 break;
2506 }
2507 case SSH_AUTH_RSA:{
2508 int len = BN_num_bytes(cred->key_pair->rsa->n);
2509 unsigned char FAR *outmsg =
2510 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2511
2512 notify_verbose_message(pvar,
2513 "Trying RSA authentication...",
2514 LOG_LEVEL_VERBOSE);
2515
2516 set_ushort16_MSBfirst(outmsg, len * 8);
2517 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2518 /* don't destroy the current credentials yet */
2519 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2520 break;
2521 }
2522 case SSH_AUTH_RHOSTS_RSA:{
2523 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2524 int name_len = strlen(cred->rhosts_client_user);
2525 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2526 int index;
2527 unsigned char FAR *outmsg =
2528 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2529 12 + mod_len + name_len + exp_len);
2530
2531 notify_verbose_message(pvar,
2532 "Trying RHOSTS+RSA authentication...",
2533 LOG_LEVEL_VERBOSE);
2534
2535 set_uint32(outmsg, name_len);
2536 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2537 index = 4 + name_len;
2538
2539 set_uint32(outmsg + index, 8 * mod_len);
2540 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2541 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2542 index += 6 + exp_len;
2543
2544 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2545 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2546 /* don't destroy the current credentials yet */
2547 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2548 break;
2549 }
2550 case SSH_AUTH_PAGEANT:{
2551 unsigned char FAR *outmsg;
2552 unsigned char *pubkey;
2553 int len, bn_bytes;
2554
2555 if (pvar->pageant_keycurrent != 0) {
2556 // ���O�������X�L�b�v
2557 pvar->pageant_curkey += 4;
2558 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2559 bn_bytes = (len + 7) / 8;
2560 pvar->pageant_curkey += 2 + bn_bytes;
2561 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2562 bn_bytes = (len + 7) / 8;
2563 pvar->pageant_curkey += 2 + bn_bytes;
2564 // ���O�������R�����g���X�L�b�v
2565 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2566 pvar->pageant_curkey += 4 + len;
2567 // �����������u������
2568 }
2569 pubkey = pvar->pageant_curkey + 4;
2570 len = get_ushort16_MSBfirst(pubkey);
2571 bn_bytes = (len + 7) / 8;
2572 pubkey += 2 + bn_bytes;
2573 len = get_ushort16_MSBfirst(pubkey);
2574 bn_bytes = (len + 7) / 8;
2575 pubkey += 2;
2576 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2577
2578 notify_verbose_message(pvar,
2579 "Trying RSA authentication...",
2580 LOG_LEVEL_VERBOSE);
2581
2582 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2583 memcpy(outmsg + 2, pubkey, bn_bytes);
2584 /* don't destroy the current credentials yet */
2585
2586 pvar->pageant_keycurrent++;
2587
2588 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2589 break;
2590 }
2591 case SSH_AUTH_TIS:{
2592 if (cred->password == NULL) {
2593 unsigned char FAR *outmsg =
2594 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2595
2596 notify_verbose_message(pvar,
2597 "Trying TIS authentication...",
2598 LOG_LEVEL_VERBOSE);
2599 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2600 } else {
2601 int len = strlen(cred->password);
2602 unsigned char FAR *outmsg =
2603 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2604 4 + len);
2605
2606 notify_verbose_message(pvar,
2607 "Sending TIS response",
2608 LOG_LEVEL_VERBOSE);
2609
2610 set_uint32(outmsg, len);
2611 memcpy(outmsg + 4, cred->password, len);
2612 enque_simple_auth_handlers(pvar);
2613 }
2614
2615 AUTH_destroy_cur_cred(pvar);
2616 break;
2617 }
2618 default:
2619 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2620 "Internal error: unsupported authentication method");
2621 notify_fatal_error(pvar, pvar->ts->UIMsg);
2622 return;
2623 }
2624
2625 finish_send_packet(pvar);
2626
2627 skip_ssh2:;
2628 destroy_packet_buf(pvar);
2629
2630 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2631 }
2632 }
2633
2634 static void try_send_user_name(PTInstVar pvar)
2635 {
2636 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2637 char FAR *username = AUTH_get_user_name(pvar);
2638
2639 if (username != NULL) {
2640 int len = strlen(username);
2641 unsigned char FAR *outmsg =
2642 begin_send_packet(pvar, SSH_CMSG_USER, 4 + len);
2643 char buf[1024] = "Sending user name: ";
2644 static const int msgs[] =
2645 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2646 static const SSHPacketHandler handlers[]
2647 = { handle_noauth_success, handle_auth_required };
2648
2649 set_uint32(outmsg, len);
2650 memcpy(outmsg + 4, username, len);
2651 finish_send_packet(pvar);
2652
2653 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2654
2655 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2656 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2657
2658 enque_handlers(pvar, 2, msgs, handlers);
2659 }
2660 }
2661 }
2662
2663 static void send_session_key(PTInstVar pvar)
2664 {
2665 int encrypted_session_key_len;
2666 unsigned char FAR *outmsg;
2667
2668 if (SSHv1(pvar)) {
2669 encrypted_session_key_len =
2670 CRYPT_get_encrypted_session_key_len(pvar);
2671 }
2672
2673 if (!CRYPT_choose_ciphers(pvar))
2674 return;
2675
2676 if (SSHv1(pvar)) {
2677 outmsg =
2678 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2679 15 + encrypted_session_key_len);
2680 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2681 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2682 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2683 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2684 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2685 return;
2686 set_uint32(outmsg + 11 + encrypted_session_key_len,
2687 SSH_PROTOFLAG_SCREEN_NUMBER |
2688 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2689 finish_send_packet(pvar);
2690 }
2691
2692 if (!CRYPT_start_encryption(pvar, 1, 1))
2693 return;
2694 notify_established_secure_connection(pvar);
2695
2696 if (SSHv1(pvar)) {
2697 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2698 }
2699
2700 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2701
2702 if (SSHv1(pvar)) {
2703 try_send_user_name(pvar);
2704 }
2705 }
2706
2707 /*************************
2708 END of message handlers
2709 ************************/
2710
2711 void SSH_init(PTInstVar pvar)
2712 {
2713 int i;
2714
2715 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2716 buf_create(&pvar->ssh_state.precompress_outbuf,
2717 &pvar->ssh_state.precompress_outbuflen);
2718 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2719 &pvar->ssh_state.postdecompress_inbuflen);
2720 pvar->ssh_state.payload = NULL;
2721 pvar->ssh_state.compressing = FALSE;
2722 pvar->ssh_state.decompressing = FALSE;
2723 pvar->ssh_state.status_flags =
2724 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2725 pvar->ssh_state.payload_datalen = 0;
2726 pvar->ssh_state.hostname = NULL;
2727 pvar->ssh_state.server_ID = NULL;
2728 pvar->ssh_state.receiver_sequence_number = 0;
2729 pvar->ssh_state.sender_sequence_number = 0;
2730 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2731 pvar->ssh_state.packet_handlers[i] = NULL;
2732 }
2733
2734 // for SSH2(yutaka)
2735 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2736 pvar->userauth_success = 0;
2737 pvar->session_nego_status = 0;
2738 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2739 pvar->rekeying = 0;
2740 pvar->key_done = 0;
2741 pvar->ssh2_autologin = 0; // autologin disabled(default)
2742 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2743 pvar->userauth_retry_count = 0;
2744 pvar->decomp_buffer = NULL;
2745 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2746 pvar->tryed_ssh2_authlist = FALSE;
2747 pvar->agentfwd_enable = FALSE;
2748
2749 }
2750
2751 void SSH_open(PTInstVar pvar)
2752 {
2753 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2754 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2755 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2756 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2757 }
2758
2759 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2760 {
2761 if (SSHv1(pvar)) {
2762 int len = reason == NULL ? 0 : strlen(reason);
2763 unsigned char FAR *outmsg =
2764 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2765
2766 set_uint32(outmsg, len);
2767 if (reason != NULL) {
2768 memcpy(outmsg + 4, reason, len);
2769 }
2770 finish_send_packet(pvar);
2771
2772 } else { // for SSH2(yutaka)
2773 buffer_t *msg;
2774 unsigned char *outmsg;
2775 int len;
2776 Channel_t *c;
2777
2778 c = ssh2_channel_lookup(pvar->shell_id);
2779 if (c == NULL)
2780 return;
2781
2782 // SSH2 server��channel close���`����
2783 msg = buffer_init();
2784 if (msg == NULL) {
2785 // TODO: error check
2786 return;
2787 }
2788 buffer_put_int(msg, c->remote_id);
2789
2790 len = buffer_len(msg);
2791 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2792 memcpy(outmsg, buffer_ptr(msg), len);
2793 finish_send_packet(pvar);
2794 buffer_free(msg);
2795
2796 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_CLOSE was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2797 }
2798
2799 }
2800
2801 void SSH_notify_host_OK(PTInstVar pvar)
2802 {
2803 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2804 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2805 send_session_key(pvar);
2806 }
2807 }
2808
2809 void get_window_pixel_size(PTInstVar pvar, int *x, int *y)
2810 {
2811 RECT r;
2812
2813 if (pvar->cv->HWin && GetWindowRect(pvar->cv->HWin, &r)) {
2814 *x = r.right - r.left;
2815 *y = r.bottom - r.top;
2816 }
2817 else {
2818 *x = 0;
2819 *y = 0;
2820 }
2821
2822 return;
2823 }
2824
2825 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2826 {
2827 int x, y;
2828
2829 pvar->ssh_state.win_cols = cols;
2830 pvar->ssh_state.win_rows = rows;
2831
2832 if (SSHv1(pvar)) {
2833 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2834 unsigned char FAR *outmsg =
2835 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2836
2837 set_uint32(outmsg, rows);
2838 set_uint32(outmsg + 4, cols);
2839 set_uint32(outmsg + 8, 0);
2840 set_uint32(outmsg + 12, 0);
2841 finish_send_packet(pvar);
2842 }
2843
2844 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2845 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2846 buffer_t *msg;
2847 char *s;
2848 unsigned char *outmsg;
2849 int len;
2850 Channel_t *c;
2851
2852 c = ssh2_channel_lookup(pvar->shell_id);
2853 if (c == NULL)
2854 return;
2855
2856 msg = buffer_init();
2857 if (msg == NULL) {
2858 // TODO: error check
2859 return;
2860 }
2861 buffer_put_int(msg, c->remote_id);
2862 s = "window-change";
2863 buffer_put_string(msg, s, strlen(s));
2864 buffer_put_char(msg, 0); // wantconfirm
2865 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2866 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2867 get_window_pixel_size(pvar, &x, &y);
2868 buffer_put_int(msg, x); // window width (pixel):
2869 buffer_put_int(msg, y); // window height (pixel):
2870 len = buffer_len(msg);
2871 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2872 memcpy(outmsg, buffer_ptr(msg), len);
2873 finish_send_packet(pvar);
2874 buffer_free(msg);
2875
2876 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2877
2878 } else {
2879 // SSH�����������������������B
2880
2881 }
2882
2883 }
2884
2885 // �u���[�N�M���������B
2886 // OpenSSH ��"~B"�����������B�������ASSH2�����B
2887 // (2010.9.27 yutaka)
2888 int SSH_notify_break_signal(PTInstVar pvar)
2889 {
2890 int ret = 0;
2891
2892 if (SSHv1(pvar)) {
2893 // �����������B
2894
2895 } else if (SSHv2(pvar)) {
2896 buffer_t *msg;
2897 char *s;
2898 unsigned char *outmsg;
2899 int len;
2900 Channel_t *c;
2901
2902 c = ssh2_channel_lookup(pvar->shell_id);
2903 if (c == NULL)
2904 goto error;
2905
2906 msg = buffer_init();
2907 if (msg == NULL) {
2908 goto error;
2909 }
2910 buffer_put_int(msg, c->remote_id);
2911 s = "break";
2912 buffer_put_string(msg, s, strlen(s));
2913 buffer_put_char(msg, 0); // wantconfirm
2914 buffer_put_int(msg, 1000);
2915 len = buffer_len(msg);
2916 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2917 memcpy(outmsg, buffer_ptr(msg), len);
2918 finish_send_packet(pvar);
2919 buffer_free(msg);
2920
2921 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_break_signal().", LOG_LEVEL_VERBOSE);
2922
2923 ret = 1;
2924
2925 } else {
2926 // SSH�����������������������B
2927
2928 }
2929
2930 error:
2931 return (ret);
2932 }
2933
2934 int SSH_get_min_packet_size(PTInstVar pvar)
2935 {
2936 if (SSHv1(pvar)) {
2937 return 12;
2938 } else {
2939 int block_size = CRYPT_get_decryption_block_size(pvar);
2940
2941 return max(16, block_size);
2942 }
2943 }
2944
2945 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2946 at least 5 bytes must be decrypted */
2947 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2948 {
2949 if (SSHv2(pvar)) {
2950 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2951 }
2952 }
2953
2954 int SSH_get_clear_MAC_size(PTInstVar pvar)
2955 {
2956 if (SSHv1(pvar)) {
2957 return 0;
2958 } else {
2959 return CRYPT_get_receiver_MAC_size(pvar);
2960 }
2961 }
2962
2963 void SSH_notify_user_name(PTInstVar pvar)
2964 {
2965 try_send_user_name(pvar);
2966 }
2967
2968 void SSH_notify_cred(PTInstVar pvar)
2969 {
2970 try_send_credentials(pvar);
2971 }
2972
2973 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2974 {
2975 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2976 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
2977 init_memdump();
2978 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2979 }
2980
2981 if (SSHv1(pvar)) {
2982 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2983 return;
2984 }
2985
2986 while (buflen > 0) {
2987 int len =
2988 buflen >
2989 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2990 unsigned char FAR *outmsg =
2991 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2992
2993 set_uint32(outmsg, len);
2994
2995 if (pvar->ssh_state.compressing) {
2996 buf_ensure_size(&pvar->ssh_state.outbuf,
2997 &pvar->ssh_state.outbuflen,
2998 len + (len >> 6) + 50);
2999 pvar->ssh_state.compress_stream.next_in =
3000 pvar->ssh_state.precompress_outbuf;
3001 pvar->ssh_state.compress_stream.avail_in = 5;
3002 pvar->ssh_state.compress_stream.next_out =
3003 pvar->ssh_state.outbuf + 12;
3004 pvar->ssh_state.compress_stream.avail_out =
3005 pvar->ssh_state.outbuflen - 12;
3006
3007 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
3008 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3009 "Error compressing packet data");
3010 notify_fatal_error(pvar, pvar->ts->UIMsg);
3011 return;
3012 }
3013
3014 pvar->ssh_state.compress_stream.next_in =
3015 (unsigned char FAR *) buf;
3016 pvar->ssh_state.compress_stream.avail_in = len;
3017
3018 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
3019 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3020 "Error compressing packet data");
3021 notify_fatal_error(pvar, pvar->ts->UIMsg);
3022 return;
3023 }
3024 } else {
3025 memcpy(outmsg + 4, buf, len);
3026 }
3027
3028 finish_send_packet_special(pvar, 1);
3029
3030 buflen -= len;
3031 buf += len;
3032 }
3033
3034 } else { // for SSH2(yutaka)
3035 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
3036 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
3037 }
3038
3039 }
3040
3041 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
3042 {
3043 int num_bytes = pvar->ssh_state.payload_datalen;
3044
3045 if (num_bytes > len) {
3046 num_bytes = len;
3047 }
3048
3049 if (!pvar->ssh_state.decompressing) {
3050 memcpy(dest,
3051 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
3052 num_bytes);
3053 pvar->ssh_state.payload_datastart += num_bytes;
3054 } else if (num_bytes > 0) {
3055 pvar->ssh_state.decompress_stream.next_out = dest;
3056 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
3057
3058 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
3059 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
3060 "Invalid compressed data in received packet");
3061 notify_fatal_error(pvar, pvar->ts->UIMsg);
3062 return 0;
3063 }
3064 }
3065
3066 pvar->ssh_state.payload_datalen -= num_bytes;
3067
3068 return num_bytes;
3069 }
3070
3071 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
3072 {
3073 char buf[1024];
3074 char buf2[1024];
3075
3076 // added support of SSH2 packet compression (2005.7.10 yutaka)
3077 // support of "Compression delayed" (2006.6.23 maya)
3078 if (pvar->ssh_state.compressing ||
3079 pvar->ctos_compression == COMP_ZLIB ||
3080 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3081 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
3082 unsigned long total_out =
3083 pvar->ssh_state.compress_stream.total_out;
3084
3085 if (total_out > 0) {
3086 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3087 "level %d; ratio %.1f (%ld:%ld)");
3088 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3089 pvar->ssh_state.compression_level,
3090 ((double) total_in) / total_out, total_in,
3091 total_out);
3092 } else {
3093 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3094 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3095 pvar->ssh_state.compression_level);
3096 }
3097 } else {
3098 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3099 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
3100 }
3101
3102 // support of "Compression delayed" (2006.6.23 maya)
3103 if (pvar->ssh_state.decompressing ||
3104 pvar->stoc_compression == COMP_ZLIB ||
3105 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3106 unsigned long total_in =
3107 pvar->ssh_state.decompress_stream.total_in;
3108 unsigned long total_out =
3109 pvar->ssh_state.decompress_stream.total_out;
3110
3111 if (total_in > 0) {
3112 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3113 "level %d; ratio %.1f (%ld:%ld)");
3114 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3115 pvar->ssh_state.compression_level,
3116 ((double) total_out) / total_in, total_out,
3117 total_in);
3118 } else {
3119 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3120 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3121 pvar->ssh_state.compression_level);
3122 }
3123 } else {
3124 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3125 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
3126 }
3127
3128 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
3129 "Upstream %s; Downstream %s");
3130 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
3131 }
3132
3133 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
3134 {
3135 strncpy_s(dest, len,
3136 pvar->ssh_state.server_ID == NULL ? "Unknown"
3137 : pvar->ssh_state.server_ID,
3138 _TRUNCATE);
3139 }
3140
3141 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
3142 int len)
3143 {
3144 if (pvar->protocol_major == 0) {
3145 strncpy_s(dest, len, "Unknown", _TRUNCATE);
3146 } else {
3147 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
3148 pvar->protocol_minor);
3149 }
3150 }
3151
3152 void SSH_end(PTInstVar pvar)
3153 {
3154 int i;
3155 int mode;
3156
3157 for (i = 0; i < 256; i++) {
3158 SSHPacketHandlerItem FAR *first_item =
3159 pvar->ssh_state.packet_handlers[i];
3160
3161 if (first_item != NULL) {
3162 SSHPacketHandlerItem FAR *item = first_item;
3163
3164 do {
3165 SSHPacketHandlerItem FAR *cur_item = item;
3166
3167 item = item->next_for_message;
3168 free(cur_item);
3169 } while (item != first_item);
3170 }
3171 pvar->ssh_state.packet_handlers[i] = NULL;
3172 }
3173
3174 free(pvar->ssh_state.hostname);
3175 pvar->ssh_state.hostname = NULL;
3176 free(pvar->ssh_state.server_ID);
3177 pvar->ssh_state.server_ID = NULL;
3178 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
3179 buf_destroy(&pvar->ssh_state.precompress_outbuf,
3180 &pvar->ssh_state.precompress_outbuflen);
3181 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
3182 &pvar->ssh_state.postdecompress_inbuflen);
3183 pvar->agentfwd_enable = FALSE;
3184
3185 // support of "Compression delayed" (2006.6.23 maya)
3186 if (pvar->ssh_state.compressing ||
3187 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3188 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3189 deflateEnd(&pvar->ssh_state.compress_stream);
3190 pvar->ssh_state.compressing = FALSE;
3191 }
3192 // support of "Compression delayed" (2006.6.23 maya)
3193 if (pvar->ssh_state.decompressing ||
3194 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3195 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3196 inflateEnd(&pvar->ssh_state.decompress_stream);
3197 pvar->ssh_state.decompressing = FALSE;
3198 }
3199
3200 #if 1
3201 // SSH2���f�[�^���������� (2004.12.27 yutaka)
3202 if (SSHv2(pvar)) {
3203 if (pvar->kexdh) {
3204 DH_free(pvar->kexdh);