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