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 6779 - (show annotations) (download) (as text)
Tue Jun 6 08:39:15 2017 UTC (6 years, 10 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 265727 byte(s)
ログ出力強化 (エージェント転送関連)

・エラーをデバッグログに記録するようにした
・不正な(大きすぎる)エージェント要求を通知するようにした
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
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 FAR * 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 FAR *begin_send_packet(PTInstVar pvar, int type, int len)
861 {
862 unsigned char FAR *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 FAR * 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 FAR * 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 FAR *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 FAR * messages,
1155 const SSHPacketHandler FAR * handlers)
1156 {
1157 SSHPacketHandlerItem FAR *first_item;
1158 SSHPacketHandlerItem FAR *last_item = NULL;
1159 int i;
1160
1161 for (i = 0; i < num_msgs; i++) {
1162 SSHPacketHandlerItem FAR *item =
1163 (SSHPacketHandlerItem FAR *)
1164 malloc(sizeof(SSHPacketHandlerItem));
1165 SSHPacketHandlerItem FAR *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 FAR *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 FAR *cur_item =
1212 pvar->ssh_state.packet_handlers[message];
1213 SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1214
1215 if (cur_item == NULL)
1216 return;
1217
1218 do {
1219 SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1220
1221 if (cur_item->active_for_message >= 0) {
1222 SSHPacketHandlerItem FAR *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 FAR * 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 FAR *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 FAR *description;
1415 int description_len;
1416 char buf[2048];
1417 char FAR *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 FAR *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 FAR * ID)
1613 {
1614 char FAR *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 FAR * 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 FAR *buf;
1761
1762 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1763 buf_len = strlen(prefix) + ID_len + 1;
1764 buf = (char FAR *) 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 FAR *) 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 FAR * 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 FAR *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 FAR *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
2201 set_uint32(outmsg, len);
2202 memcpy(outmsg + 4, pvar->ts->TermType, len);
2203 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2204 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2205 set_uint32(outmsg + 4 + len + 8, 0);
2206 set_uint32(outmsg + 4 + len + 12, 0);
2207 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2208 finish_send_packet(pvar);
2209
2210 enque_handlers(pvar, 2, msgs, handlers);
2211
2212 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2213 finish_send_packet(pvar);
2214 }
2215
2216 static BOOL handle_agent_request_success(PTInstVar pvar)
2217 {
2218 pvar->agentfwd_enable = TRUE;
2219 prep_pty(pvar);
2220 return FALSE;
2221 }
2222
2223 static BOOL handle_agent_request_failure(PTInstVar pvar)
2224 {
2225 prep_pty(pvar);
2226 return FALSE;
2227 }
2228
2229 static void prep_agent_request(PTInstVar pvar)
2230 {
2231 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2232 static const SSHPacketHandler handlers[]
2233 = { handle_agent_request_success, handle_agent_request_failure };
2234
2235 enque_handlers(pvar, 2, msgs, handlers);
2236
2237 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2238 finish_send_packet(pvar);
2239 }
2240
2241 static void prep_forwarding(PTInstVar pvar)
2242 {
2243 FWD_prep_forwarding(pvar);
2244
2245 if (pvar->session_settings.ForwardAgent) {
2246 prep_agent_request(pvar);
2247 }
2248 else {
2249 prep_pty(pvar);
2250 }
2251 }
2252
2253
2254 //
2255 //
2256 // (2005.7.10 yutaka)
2257 static void enable_send_compression(PTInstVar pvar)
2258 {
2259 static int initialize = 0;
2260
2261 if (initialize) {
2262 deflateEnd(&pvar->ssh_state.compress_stream);
2263 }
2264 initialize = 1;
2265
2266 pvar->ssh_state.compress_stream.zalloc = NULL;
2267 pvar->ssh_state.compress_stream.zfree = NULL;
2268 pvar->ssh_state.compress_stream.opaque = NULL;
2269 if (deflateInit
2270 (&pvar->ssh_state.compress_stream,
2271 pvar->ssh_state.compression_level) != Z_OK) {
2272 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2273 "An error occurred while setting up compression.\n"
2274 "The connection will close.");
2275 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2276 return;
2277 } else {
2278 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2279 if (SSHv2(pvar)) {
2280 pvar->ssh_state.compressing = FALSE;
2281 } else {
2282 pvar->ssh_state.compressing = TRUE;
2283 }
2284 }
2285 }
2286
2287 static void enable_recv_compression(PTInstVar pvar)
2288 {
2289 static int initialize = 0;
2290
2291 if (initialize) {
2292 deflateEnd(&pvar->ssh_state.decompress_stream);
2293 }
2294 initialize = 1;
2295
2296 pvar->ssh_state.decompress_stream.zalloc = NULL;
2297 pvar->ssh_state.decompress_stream.zfree = NULL;
2298 pvar->ssh_state.decompress_stream.opaque = NULL;
2299 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2300 deflateEnd(&pvar->ssh_state.compress_stream);
2301 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2302 "An error occurred while setting up compression.\n"
2303 "The connection will close.");
2304 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2305 return;
2306 } else {
2307 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2308 if (SSHv2(pvar)) {
2309 pvar->ssh_state.decompressing = FALSE;
2310 } else {
2311 pvar->ssh_state.decompressing = TRUE;
2312 }
2313
2314 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2315 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2316 }
2317 }
2318
2319 static void enable_compression(PTInstVar pvar)
2320 {
2321 enable_send_compression(pvar);
2322 enable_recv_compression(pvar);
2323
2324 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2325 if (SSHv2(pvar)) {
2326 pvar->ssh_state.compressing = FALSE;
2327 pvar->ssh_state.decompressing = FALSE;
2328 }
2329
2330 }
2331
2332 static BOOL handle_enable_compression(PTInstVar pvar)
2333 {
2334 enable_compression(pvar);
2335 prep_forwarding(pvar);
2336 return FALSE;
2337 }
2338
2339 static BOOL handle_disable_compression(PTInstVar pvar)
2340 {
2341 prep_forwarding(pvar);
2342 return FALSE;
2343 }
2344
2345 static void prep_compression(PTInstVar pvar)
2346 {
2347 if (pvar->session_settings.CompressionLevel > 0) {
2348 // added if statement (2005.7.10 yutaka)
2349 if (SSHv1(pvar)) {
2350 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2351 static const SSHPacketHandler handlers[]
2352 = { handle_enable_compression, handle_disable_compression };
2353
2354 unsigned char FAR *outmsg =
2355 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2356
2357 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2358 finish_send_packet(pvar);
2359
2360 enque_handlers(pvar, 2, msgs, handlers);
2361 }
2362
2363 pvar->ssh_state.compression_level =
2364 pvar->session_settings.CompressionLevel;
2365
2366 } else {
2367 // added if statement (2005.7.10 yutaka)
2368 if (SSHv1(pvar)) {
2369 prep_forwarding(pvar);
2370 }
2371 }
2372 }
2373
2374 static void enque_simple_auth_handlers(PTInstVar pvar)
2375 {
2376 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2377 static const SSHPacketHandler handlers[]
2378 = { handle_auth_success, handle_auth_failure };
2379
2380 enque_handlers(pvar, 2, msgs, handlers);
2381 }
2382
2383 static BOOL handle_rsa_challenge(PTInstVar pvar)
2384 {
2385 int challenge_bytes;
2386
2387 if (!grab_payload(pvar, 2)) {
2388 return FALSE;
2389 }
2390
2391 challenge_bytes = get_mpint_len(pvar, 0);
2392
2393 if (grab_payload(pvar, challenge_bytes)) {
2394 unsigned char FAR *outmsg =
2395 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2396
2397 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2398 if (CRYPT_generate_RSA_challenge_response
2399 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2400
2401 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2402 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2403 #if 0
2404 //AUTH_destroy_cur_cred(pvar);
2405 #endif
2406
2407 finish_send_packet(pvar);
2408
2409 enque_simple_auth_handlers(pvar);
2410 } else {
2411 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2412 "An error occurred while decrypting the RSA challenge.\n"
2413 "Perhaps the key file is corrupted.");
2414 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2415 }
2416 }
2417 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2418 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2419 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2420 int server_key_bytes = (server_key_bits + 7) / 8;
2421 int host_key_bytes = (host_key_bits + 7) / 8;
2422 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2423 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2424 unsigned char session_id[16];
2425
2426 unsigned char *hash;
2427 int pubkeylen, hashlen;
2428
2429 /* Pageant ���n�b�V�����v�Z���������� */
2430 // ���J��������
2431 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2432 pvar->pageant_keylistlen);
2433 // �Z�b�V����ID������
2434 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2435 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2436 session_buf + host_key_bytes);
2437 memcpy(session_buf + server_key_bytes + host_key_bytes,
2438 pvar->crypt_state.server_cookie, 8);
2439 MD5(session_buf, session_buf_len, session_id);
2440 // �n�b�V������������
2441 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2442 pubkeylen,
2443 pvar->ssh_state.payload,
2444 challenge_bytes + 2,
2445 session_id,
2446 &hashlen);
2447
2448 // �n�b�V�������M
2449 memcpy(outmsg, hash, 16);
2450 free(hash);
2451
2452 finish_send_packet(pvar);
2453
2454 enque_simple_auth_handlers(pvar);
2455 }
2456 }
2457
2458 return FALSE;
2459 }
2460
2461 static void try_send_credentials(PTInstVar pvar)
2462 {
2463 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2464 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2465 static const int RSA_msgs[] =
2466 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2467 static const SSHPacketHandler RSA_handlers[]
2468 = { handle_rsa_challenge, handle_rsa_auth_refused };
2469 static const int TIS_msgs[] =
2470 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2471 static const SSHPacketHandler TIS_handlers[]
2472 = { handle_TIS_challenge, handle_auth_failure };
2473
2474 // SSH2���������������������X�L�b�v
2475 if (SSHv2(pvar))
2476 goto skip_ssh2;
2477
2478 switch (cred->method) {
2479 case SSH_AUTH_NONE:
2480 return;
2481 case SSH_AUTH_PASSWORD:{
2482 int len = strlen(cred->password);
2483 unsigned char FAR *outmsg =
2484 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2485 4 + len);
2486
2487 notify_verbose_message(pvar,
2488 "Trying PASSWORD authentication...",
2489 LOG_LEVEL_VERBOSE);
2490
2491 set_uint32(outmsg, len);
2492 memcpy(outmsg + 4, cred->password, len);
2493
2494 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2495 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2496 #if 0
2497 //AUTH_destroy_cur_cred(pvar);
2498 #endif
2499
2500 enque_simple_auth_handlers(pvar);
2501 break;
2502 }
2503 case SSH_AUTH_RHOSTS:{
2504 int len = strlen(cred->rhosts_client_user);
2505 unsigned char FAR *outmsg =
2506 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2507
2508 notify_verbose_message(pvar,
2509 "Trying RHOSTS authentication...",
2510 LOG_LEVEL_VERBOSE);
2511
2512 set_uint32(outmsg, len);
2513 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2514 AUTH_destroy_cur_cred(pvar);
2515 enque_simple_auth_handlers(pvar);
2516 break;
2517 }
2518 case SSH_AUTH_RSA:{
2519 int len = BN_num_bytes(cred->key_pair->rsa->n);
2520 unsigned char FAR *outmsg =
2521 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2522
2523 notify_verbose_message(pvar,
2524 "Trying RSA authentication...",
2525 LOG_LEVEL_VERBOSE);
2526
2527 set_ushort16_MSBfirst(outmsg, len * 8);
2528 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2529 /* don't destroy the current credentials yet */
2530 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2531 break;
2532 }
2533 case SSH_AUTH_RHOSTS_RSA:{
2534 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2535 int name_len = strlen(cred->rhosts_client_user);
2536 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2537 int index;
2538 unsigned char FAR *outmsg =
2539 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2540 12 + mod_len + name_len + exp_len);
2541
2542 notify_verbose_message(pvar,
2543 "Trying RHOSTS+RSA authentication...",
2544 LOG_LEVEL_VERBOSE);
2545
2546 set_uint32(outmsg, name_len);
2547 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2548 index = 4 + name_len;
2549
2550 set_uint32(outmsg + index, 8 * mod_len);
2551 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2552 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2553 index += 6 + exp_len;
2554
2555 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2556 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2557 /* don't destroy the current credentials yet */
2558 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2559 break;
2560 }
2561 case SSH_AUTH_PAGEANT:{
2562 unsigned char FAR *outmsg;
2563 unsigned char *pubkey;
2564 int len, bn_bytes;
2565
2566 if (pvar->pageant_keycurrent != 0) {
2567 // ���O�������X�L�b�v
2568 pvar->pageant_curkey += 4;
2569 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2570 bn_bytes = (len + 7) / 8;
2571 pvar->pageant_curkey += 2 + bn_bytes;
2572 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2573 bn_bytes = (len + 7) / 8;
2574 pvar->pageant_curkey += 2 + bn_bytes;
2575 // ���O�������R�����g���X�L�b�v
2576 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2577 pvar->pageant_curkey += 4 + len;
2578 // �����������u������
2579 }
2580 pubkey = pvar->pageant_curkey + 4;
2581 len = get_ushort16_MSBfirst(pubkey);
2582 bn_bytes = (len + 7) / 8;
2583 pubkey += 2 + bn_bytes;
2584 len = get_ushort16_MSBfirst(pubkey);
2585 bn_bytes = (len + 7) / 8;
2586 pubkey += 2;
2587 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2588
2589 notify_verbose_message(pvar,
2590 "Trying RSA authentication...",
2591 LOG_LEVEL_VERBOSE);
2592
2593 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2594 memcpy(outmsg + 2, pubkey, bn_bytes);
2595 /* don't destroy the current credentials yet */
2596
2597 pvar->pageant_keycurrent++;
2598
2599 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2600 break;
2601 }
2602 case SSH_AUTH_TIS:{
2603 if (cred->password == NULL) {
2604 unsigned char FAR *outmsg =
2605 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2606
2607 notify_verbose_message(pvar,
2608 "Trying TIS authentication...",
2609 LOG_LEVEL_VERBOSE);
2610 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2611 } else {
2612 int len = strlen(cred->password);
2613 unsigned char FAR *outmsg =
2614 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2615 4 + len);
2616
2617 notify_verbose_message(pvar,
2618 "Sending TIS response",
2619 LOG_LEVEL_VERBOSE);
2620
2621 set_uint32(outmsg, len);
2622 memcpy(outmsg + 4, cred->password, len);
2623 enque_simple_auth_handlers(pvar);
2624 }
2625
2626 AUTH_destroy_cur_cred(pvar);
2627 break;
2628 }
2629 default:
2630 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2631 "Internal error: unsupported authentication method");
2632 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2633 return;
2634 }
2635
2636 finish_send_packet(pvar);
2637
2638 skip_ssh2:;
2639 destroy_packet_buf(pvar);
2640
2641 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2642 }
2643 }
2644
2645 static void try_send_user_name(PTInstVar pvar)
2646 {
2647 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2648 char FAR *username = AUTH_get_user_name(pvar);
2649
2650 if (username != NULL) {
2651 int len = strlen(username);
2652 unsigned char FAR *outmsg =
2653 begin_send_packet(pvar, SSH_CMSG_USER, 4 + len);
2654 char buf[1024] = "Sending user name: ";
2655 static const int msgs[] =
2656 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2657 static const SSHPacketHandler handlers[]
2658 = { handle_noauth_success, handle_auth_required };
2659
2660 set_uint32(outmsg, len);
2661 memcpy(outmsg + 4, username, len);
2662 finish_send_packet(pvar);
2663
2664 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2665
2666 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2667 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2668
2669 enque_handlers(pvar, 2, msgs, handlers);
2670 }
2671 }
2672 }
2673
2674 static void send_session_key(PTInstVar pvar)
2675 {
2676 int encrypted_session_key_len;
2677 unsigned char FAR *outmsg;
2678
2679 if (SSHv1(pvar)) {
2680 encrypted_session_key_len =
2681 CRYPT_get_encrypted_session_key_len(pvar);
2682 }
2683
2684 if (!CRYPT_choose_ciphers(pvar))
2685 return;
2686
2687 if (SSHv1(pvar)) {
2688 outmsg =
2689 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2690 15 + encrypted_session_key_len);
2691 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2692 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2693 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2694 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2695 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2696 return;
2697 set_uint32(outmsg + 11 + encrypted_session_key_len,
2698 SSH_PROTOFLAG_SCREEN_NUMBER |
2699 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2700 finish_send_packet(pvar);
2701 }
2702
2703 if (!CRYPT_start_encryption(pvar, 1, 1))
2704 return;
2705 notify_established_secure_connection(pvar);
2706
2707 if (SSHv1(pvar)) {
2708 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2709 }
2710
2711 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2712
2713 if (SSHv1(pvar)) {
2714 try_send_user_name(pvar);
2715 }
2716 }
2717
2718 /*************************
2719 END of message handlers
2720 ************************/
2721
2722 void SSH_init(PTInstVar pvar)
2723 {
2724 int i;
2725
2726 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2727 buf_create(&pvar->ssh_state.precompress_outbuf,
2728 &pvar->ssh_state.precompress_outbuflen);
2729 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2730 &pvar->ssh_state.postdecompress_inbuflen);
2731 pvar->ssh_state.payload = NULL;
2732 pvar->ssh_state.compressing = FALSE;
2733 pvar->ssh_state.decompressing = FALSE;
2734 pvar->ssh_state.status_flags =
2735 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2736 pvar->ssh_state.payload_datalen = 0;
2737 pvar->ssh_state.hostname = NULL;
2738 pvar->ssh_state.server_ID = NULL;
2739 pvar->ssh_state.receiver_sequence_number = 0;
2740 pvar->ssh_state.sender_sequence_number = 0;
2741 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2742 pvar->ssh_state.packet_handlers[i] = NULL;
2743 }
2744
2745 // for SSH2(yutaka)
2746 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2747 pvar->userauth_success = 0;
2748 pvar->session_nego_status = 0;
2749 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2750 pvar->rekeying = 0;
2751 pvar->key_done = 0;
2752 pvar->ssh2_autologin = 0; // autologin disabled(default)
2753 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2754 pvar->userauth_retry_count = 0;
2755 pvar->decomp_buffer = NULL;
2756 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2757 pvar->tryed_ssh2_authlist = FALSE;
2758 pvar->agentfwd_enable = FALSE;
2759
2760 }
2761
2762 void SSH_open(PTInstVar pvar)
2763 {
2764 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2765 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2766 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2767 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2768 }
2769
2770 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2771 {
2772 if (SSHv1(pvar)) {
2773 int len = reason == NULL ? 0 : strlen(reason);
2774 unsigned char FAR *outmsg =
2775 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2776
2777 set_uint32(outmsg, len);
2778 if (reason != NULL) {
2779 memcpy(outmsg + 4, reason, len);
2780 }
2781 finish_send_packet(pvar);
2782
2783 } else { // for SSH2(yutaka)
2784 buffer_t *msg;
2785 unsigned char *outmsg;
2786 char *s;
2787 int len;
2788
2789 // SSH2 server��disconnect���`����
2790 msg = buffer_init();
2791 if (msg == NULL) {
2792 // TODO: error check
2793 return;
2794 }
2795 buffer_put_int(msg, SSH2_DISCONNECT_BY_APPLICATION);
2796 buffer_put_string(msg, reason, strlen(reason));
2797 s = "";
2798 buffer_put_string(msg, s, strlen(s));
2799
2800 len = buffer_len(msg);
2801 outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len);
2802 memcpy(outmsg, buffer_ptr(msg), len);
2803 finish_send_packet(pvar);
2804 buffer_free(msg);
2805
2806 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2807 }
2808 }
2809
2810 void SSH_notify_host_OK(PTInstVar pvar)
2811 {
2812 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2813 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2814 send_session_key(pvar);
2815 }
2816 }
2817
2818 void get_window_pixel_size(PTInstVar pvar, int *x, int *y)
2819 {
2820 RECT r;
2821
2822 if (pvar->cv->HWin && GetWindowRect(pvar->cv->HWin, &r)) {
2823 *x = r.right - r.left;
2824 *y = r.bottom - r.top;
2825 }
2826 else {
2827 *x = 0;
2828 *y = 0;
2829 }
2830
2831 return;
2832 }
2833
2834 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2835 {
2836 int x, y;
2837
2838 pvar->ssh_state.win_cols = cols;
2839 pvar->ssh_state.win_rows = rows;
2840
2841 if (SSHv1(pvar)) {
2842 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2843 unsigned char FAR *outmsg =
2844 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2845
2846 set_uint32(outmsg, rows);
2847 set_uint32(outmsg + 4, cols);
2848 set_uint32(outmsg + 8, 0);
2849 set_uint32(outmsg + 12, 0);
2850 finish_send_packet(pvar);
2851 }
2852
2853 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2854 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2855 buffer_t *msg;
2856 char *s;
2857 unsigned char *outmsg;
2858 int len;
2859 Channel_t *c;
2860
2861 c = ssh2_channel_lookup(pvar->shell_id);
2862 if (c == NULL)
2863 return;
2864
2865 msg = buffer_init();
2866 if (msg == NULL) {
2867 // TODO: error check
2868 return;
2869 }
2870 buffer_put_int(msg, c->remote_id);
2871 s = "window-change";
2872 buffer_put_string(msg, s, strlen(s));
2873 buffer_put_char(msg, 0); // wantconfirm
2874 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2875 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2876 get_window_pixel_size(pvar, &x, &y);
2877 buffer_put_int(msg, x); // window width (pixel):
2878 buffer_put_int(msg, y); // window height (pixel):
2879 len = buffer_len(msg);
2880 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2881 memcpy(outmsg, buffer_ptr(msg), len);
2882 finish_send_packet(pvar);
2883 buffer_free(msg);
2884
2885 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2886
2887 } else {
2888 // SSH�����������������������B
2889
2890 }
2891
2892 }
2893
2894 // �u���[�N�M���������B
2895 // OpenSSH ��"~B"�����������B�������ASSH2�����B
2896 // (2010.9.27 yutaka)
2897 int SSH_notify_break_signal(PTInstVar pvar)
2898 {
2899 int ret = 0;
2900
2901 if (SSHv1(pvar)) {
2902 // �����������B
2903
2904 } else if (SSHv2(pvar)) {
2905 buffer_t *msg;
2906 char *s;
2907 unsigned char *outmsg;
2908 int len;
2909 Channel_t *c;
2910
2911 c = ssh2_channel_lookup(pvar->shell_id);
2912 if (c == NULL)
2913 goto error;
2914
2915 msg = buffer_init();
2916 if (msg == NULL) {
2917 goto error;
2918 }
2919 buffer_put_int(msg, c->remote_id);
2920 s = "break";
2921 buffer_put_string(msg, s, strlen(s));
2922 buffer_put_char(msg, 0); // wantconfirm
2923 buffer_put_int(msg, 1000);
2924 len = buffer_len(msg);
2925 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2926 memcpy(outmsg, buffer_ptr(msg), len);
2927 finish_send_packet(pvar);
2928 buffer_free(msg);
2929
2930 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_break_signal().", LOG_LEVEL_VERBOSE);
2931
2932 ret = 1;
2933
2934 } else {
2935 // SSH�����������������������B
2936
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 FAR * 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 FAR * 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 FAR *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 FAR *) 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 FAR * 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 FAR * 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 FAR * 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 FAR * 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 FAR * 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 FAR *first_item =
3177 pvar->ssh_state.packet_handlers[i];
3178
3179 if (first_item != NULL) {
3180 SSHPacketHandlerItem FAR *item = first_item;
3181
3182 do {
3183 SSHPacketHandlerItem FAR *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[i] = NULL;
3190 }
3191
3192 free(pvar->