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