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 6654 - (show annotations) (download) (as text)
Thu Mar 23 12:54:48 2017 UTC (7 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 261889 byte(s)
不使用になった変数の削除漏れ対応
1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 The name of Robert O'Callahan may not be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "util.h"
32 #include "resource.h"
33 #include "libputty.h"
34 #include "key.h"
35
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 #if 0
770 CRYPT_decrypt(pvar, data + already_decrypted,
771 len - already_decrypted);
772 #else
773 CRYPT_decrypt(pvar, data + already_decrypted,
774 (4 + len) - already_decrypted);
775 #endif
776
777 if (!CRYPT_verify_receiver_MAC
778 (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
779 data + len + 4)) {
780 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
781 "Detected corrupted data; connection terminating.");
782 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
783 return SSH_MSG_NONE;
784 }
785
786 pvar->ssh_state.payload++;
787 pvar->ssh_state.payloadlen -= padding + 1;
788 }
789
790 pvar->ssh_state.payload_grabbed = 0;
791
792 if (SSHv1(pvar)) {
793 if (pvar->ssh_state.decompressing) {
794 if (pvar->ssh_state.decompress_stream.avail_in != 0) {
795 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
796 "Internal error: a packet was not fully decompressed.\n"
797 "This is a bug, please report it.");
798 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
799 }
800
801 pvar->ssh_state.decompress_stream.next_in =
802 pvar->ssh_state.payload;
803 pvar->ssh_state.decompress_stream.avail_in =
804 pvar->ssh_state.payloadlen;
805 pvar->ssh_state.decompress_stream.next_out =
806 pvar->ssh_state.postdecompress_inbuf;
807 pvar->ssh_state.payloadlen = -1;
808 } else {
809 pvar->ssh_state.payload++;
810 }
811
812 if (!grab_payload_limited(pvar, 1)) {
813 return SSH_MSG_NONE;
814 }
815
816 } else {
817 // support of SSH2 packet compression (2005.7.9 yutaka)
818 // support of "Compression delayed" (2006.6.23 maya)
819 if ((pvar->stoc_compression == COMP_ZLIB ||
820 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
821 pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
822 int ret;
823
824 if (pvar->decomp_buffer == NULL) {
825 pvar->decomp_buffer = buffer_init();
826 if (pvar->decomp_buffer == NULL)
827 return SSH_MSG_NONE;
828 }
829 // ���x�m�������o�b�t�@���g�������������������Y�������B
830 buffer_clear(pvar->decomp_buffer);
831
832 // packet size��padding�������������y�C���[�h�����������W�J�����B
833 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
834 pvar->ssh_state.payload,
835 pvar->ssh_state.payloadlen,
836 pvar->decomp_buffer);
837
838 // �|�C���^���X�V�B
839 pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
840 pvar->ssh_state.payload++;
841 pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
842
843 } else {
844 pvar->ssh_state.payload++;
845 }
846
847 if (!grab_payload_limited(pvar, 1)) {
848 return SSH_MSG_NONE;
849 }
850
851 }
852
853 pvar->ssh_state.receiver_sequence_number++;
854
855 return pvar->ssh_state.payload[-1];
856 }
857
858 /* Create a packet to be sent. The SSH protocol packet type is in 'type';
859 'len' contains the length of the packet payload, in bytes (this
860 does not include the space for any of the packet headers or padding,
861 or for the packet type byte).
862 Returns a pointer to the payload data area, a region of length 'len',
863 to be filled by the caller. */
864 unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
865 {
866 unsigned char FAR *buf;
867
868 pvar->ssh_state.outgoing_packet_len = len + 1;
869
870 if (pvar->ssh_state.compressing) {
871 buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
872 &pvar->ssh_state.precompress_outbuflen, 1 + len);
873 buf = pvar->ssh_state.precompress_outbuf;
874 } else {
875 /* For SSHv2,
876 Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
877 + len(payload) + 4(minpadding), rounded up to nearest block_size
878 We only need a reasonable upper bound for the buffer size */
879 buf_ensure_size(&pvar->ssh_state.outbuf,
880 &pvar->ssh_state.outbuflen,
881 len + 30 + CRYPT_get_sender_MAC_size(pvar) +
882 CRYPT_get_encryption_block_size(pvar));
883 buf = pvar->ssh_state.outbuf + 12;
884 }
885
886 buf[0] = (unsigned char) type;
887 return buf + 1;
888 }
889
890
891 // ���M���g���C����������
892 //
893 // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
894 // ���������������A�����������G���[���������B
895 // �����������ATCP�R�l�N�V�������f�������o���h���B
896 // (2006.12.9 yutaka)
897 static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
898 {
899 int n;
900 int err;
901
902 while (len > 0) {
903 n = (pvar->Psend)(pvar->socket, data, len, 0);
904
905 if (n < 0) {
906 err = WSAGetLastError();
907 if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
908 // send()�����l��0�������A�����G���[������ 10000 �������������A
909 // ���������������������B
910 // PuTTY 0.58���������Q�l�B
911 // (2007.2.4 yutak)
912 return 0; // success
913 }
914 return 1; // error
915 }
916
917 len -= n;
918 data += n;
919 }
920
921 return 0; // success
922 }
923
924 static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
925 {
926 // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
927 // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
928 // ���������������������������������B(2007.10.30 yutaka)
929 u_long do_block = 0;
930 int code = 0;
931 char *kind = NULL, buf[256];
932
933 #if 0
934 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
935 0, 0) == SOCKET_ERROR
936 || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
937 || retry_send_packet(pvar, data, len)
938 || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
939 pvar->notification_msg,
940 pvar->notification_events) ==
941 SOCKET_ERROR) {
942 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
943 "A communications error occurred while sending an SSH packet.\n"
944 "The connection will close.");
945 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
946 return FALSE;
947 } else {
948 return TRUE;
949 }
950 #else
951 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
952 0, 0) == SOCKET_ERROR) {
953 code = WSAGetLastError();
954 kind = "WSAAsyncSelect1";
955 goto error;
956 }
957 if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
958 code = WSAGetLastError();
959 kind = "ioctlsocket";
960 goto error;
961 }
962 if (retry_send_packet(pvar, data, len) != 0) {
963 code = WSAGetLastError();
964 kind = "retry_send_packet";
965 goto error;
966 }
967 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
968 pvar->notification_msg,
969 pvar->notification_events) ==
970 SOCKET_ERROR) {
971 code = WSAGetLastError();
972 kind = "WSAAsyncSelect2";
973 goto error;
974 }
975 return TRUE;
976
977 error:
978 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
979 "A communications error occurred while sending an SSH packet.\n"
980 "The connection will close. (%s:%d)");
981 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
982 kind, code);
983 notify_fatal_error(pvar, buf, TRUE);
984 return FALSE;
985 #endif
986 }
987
988 /* if skip_compress is true, then the data has already been compressed
989 into outbuf + 12 */
990 void finish_send_packet_special(PTInstVar pvar, int skip_compress)
991 {
992 unsigned int len = pvar->ssh_state.outgoing_packet_len;
993 unsigned char FAR *data;
994 unsigned int data_length;
995 buffer_t *msg = NULL; // for SSH2 packet compression
996
997 if (pvar->ssh_state.compressing) {
998 if (!skip_compress) {
999 buf_ensure_size(&pvar->ssh_state.outbuf,
1000 &pvar->ssh_state.outbuflen,
1001 (int)(len + (len >> 6) + 50 +
1002 CRYPT_get_sender_MAC_size(pvar)));
1003 pvar->ssh_state.compress_stream.next_in =
1004 pvar->ssh_state.precompress_outbuf;
1005 pvar->ssh_state.compress_stream.avail_in = len;
1006 pvar->ssh_state.compress_stream.next_out =
1007 pvar->ssh_state.outbuf + 12;
1008 pvar->ssh_state.compress_stream.avail_out =
1009 pvar->ssh_state.outbuflen - 12;
1010
1011 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
1012 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1013 "An error occurred while compressing packet data.\n"
1014 "The connection will close.");
1015 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1016 return;
1017 }
1018 }
1019
1020 len =
1021 pvar->ssh_state.outbuflen - 12 -
1022 pvar->ssh_state.compress_stream.avail_out;
1023 }
1024
1025 if (SSHv1(pvar)) {
1026 int padding = 8 - ((len + 4) % 8);
1027
1028 data = pvar->ssh_state.outbuf + 8 - padding;
1029 data_length = padding + len + 8;
1030
1031 set_uint32(data, len + 4);
1032 if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
1033 CRYPT_set_random_data(pvar, data + 4, padding);
1034 } else {
1035 memset(data + 4, 0, padding);
1036 }
1037 set_uint32(data + data_length - 4,
1038 do_crc(data + 4, data_length - 8));
1039 CRYPT_encrypt(pvar, data + 4, data_length - 4);
1040 } else { //for SSH2(yutaka)
1041 int block_size = CRYPT_get_encryption_block_size(pvar);
1042 unsigned int encryption_size;
1043 unsigned int padding;
1044 BOOL ret;
1045
1046 /*
1047 �f�[�^�\��
1048 pvar->ssh_state.outbuf:
1049 offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
1050 <--ignore---> ^^^^^^^^ <---- payload --->
1051 packet length
1052
1053 ^^padding
1054
1055 <---------------------------->
1056 SSH2 sending data on TCP
1057
1058 NOTE:
1059 payload = type(1) + raw-data
1060 len = ssh_state.outgoing_packet_len = payload size
1061 */
1062 // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1063 // support of "Compression delayed" (2006.6.23 maya)
1064 if ((pvar->ctos_compression == COMP_ZLIB ||
1065 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1066 pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1067 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1068 msg = buffer_init();
1069 if (msg == NULL) {
1070 // TODO: error check
1071 return;
1072 }
1073
1074 // ���k�������w�b�_�������y�C���[�h�����B
1075 buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1076 if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1077 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1078 "An error occurred while compressing packet data.\n"
1079 "The connection will close.");
1080 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1081 return;
1082 }
1083 data = buffer_ptr(msg);
1084 len = buffer_len(msg) - 5; // 'len' is overwritten.
1085
1086 } else {
1087 // �����k
1088 data = pvar->ssh_state.outbuf + 7;
1089
1090 }
1091
1092 // ���M�p�P�b�g�\�z(input parameter: data, len)
1093 if (block_size < 8) {
1094 block_size = 8;
1095 }
1096 #if 0
1097 encryption_size = ((len + 8) / block_size + 1) * block_size;
1098 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1099
1100 set_uint32(data, encryption_size - 4);
1101 padding = encryption_size - len - 5;
1102 data[4] = (unsigned char) padding;
1103 #else
1104 // �������p�P�b�g�����������������A�T�[�o����"Bad packet length"���������������������������B
1105 // (2007.10.29 yutaka)
1106 encryption_size = 4 + 1 + len;
1107 padding = block_size - (encryption_size % block_size);
1108 if (padding < 4)
1109 padding += block_size;
1110 encryption_size += padding;
1111 set_uint32(data, encryption_size - 4);
1112 data[4] = (unsigned char) padding;
1113 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1114 if (msg) {
1115 // �p�P�b�g���k�������A�o�b�t�@���g�������B(2011.6.10 yutaka)
1116 buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
1117 // realloc()���������A�|�C���^�����������\�������������A���x���������B
1118 data = buffer_ptr(msg);
1119 }
1120 #endif
1121 //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1122 CRYPT_set_random_data(pvar, data + 5 + len, padding);
1123 ret = CRYPT_build_sender_MAC(pvar,
1124 pvar->ssh_state.sender_sequence_number,
1125 data, encryption_size,
1126 data + encryption_size);
1127 if (ret == FALSE) { // MAC��������������������������
1128 data_length = encryption_size;
1129 }
1130
1131 // �p�P�b�g�������������BMAC���~�������������O�B
1132 CRYPT_encrypt(pvar, data, encryption_size);
1133 }
1134
1135 send_packet_blocking(pvar, data, data_length);
1136
1137 buffer_free(msg);
1138
1139 pvar->ssh_state.sender_sequence_number++;
1140
1141 // ���M�������L�^
1142 pvar->ssh_heartbeat_tick = time(NULL);
1143 }
1144
1145 static void destroy_packet_buf(PTInstVar pvar)
1146 {
1147 memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1148 if (pvar->ssh_state.compressing) {
1149 memset(pvar->ssh_state.precompress_outbuf, 0,
1150 pvar->ssh_state.precompress_outbuflen);
1151 }
1152 }
1153
1154 /* The handlers are added to the queue for each message. When one of the
1155 handlers fires, if it returns FALSE, then all handlers in the set are
1156 removed from their queues. */
1157 static void enque_handlers(PTInstVar pvar, int num_msgs,
1158 const int FAR * messages,
1159 const SSHPacketHandler FAR * handlers)
1160 {
1161 SSHPacketHandlerItem FAR *first_item;
1162 SSHPacketHandlerItem FAR *last_item = NULL;
1163 int i;
1164
1165 for (i = 0; i < num_msgs; i++) {
1166 SSHPacketHandlerItem FAR *item =
1167 (SSHPacketHandlerItem FAR *)
1168 malloc(sizeof(SSHPacketHandlerItem));
1169 SSHPacketHandlerItem FAR *cur_item =
1170 pvar->ssh_state.packet_handlers[messages[i]];
1171
1172 item->handler = handlers[i];
1173
1174 if (cur_item == NULL) {
1175 pvar->ssh_state.packet_handlers[messages[i]] = item;
1176 item->next_for_message = item;
1177 item->last_for_message = item;
1178 item->active_for_message = messages[i];
1179 } else {
1180 item->next_for_message = cur_item;
1181 item->last_for_message = cur_item->last_for_message;
1182 cur_item->last_for_message->next_for_message = item;
1183 cur_item->last_for_message = item;
1184 item->active_for_message = -1;
1185 }
1186
1187 if (last_item != NULL) {
1188 last_item->next_in_set = item;
1189 } else {
1190 first_item = item;
1191 }
1192 last_item = item;
1193 }
1194
1195 if (last_item != NULL) {
1196 last_item->next_in_set = first_item;
1197 }
1198 }
1199
1200 static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1201 {
1202 SSHPacketHandlerItem FAR *cur_item =
1203 pvar->ssh_state.packet_handlers[message];
1204
1205 if (cur_item == NULL) {
1206 return NULL;
1207 } else {
1208 return cur_item->handler;
1209 }
1210 }
1211
1212 /* Called only by SSH_handle_packet */
1213 static void deque_handlers(PTInstVar pvar, int message)
1214 {
1215 SSHPacketHandlerItem FAR *cur_item =
1216 pvar->ssh_state.packet_handlers[message];
1217 SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1218
1219 if (cur_item == NULL)
1220 return;
1221
1222 do {
1223 SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1224
1225 if (cur_item->active_for_message >= 0) {
1226 SSHPacketHandlerItem FAR *replacement =
1227 cur_item->next_for_message;
1228
1229 if (replacement == cur_item) {
1230 replacement = NULL;
1231 } else {
1232 replacement->active_for_message =
1233 cur_item->active_for_message;
1234 }
1235 pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1236 replacement;
1237 }
1238 cur_item->next_for_message->last_for_message =
1239 cur_item->last_for_message;
1240 cur_item->last_for_message->next_for_message =
1241 cur_item->next_for_message;
1242
1243 free(cur_item);
1244 cur_item = next_in_set;
1245 } while (cur_item != first_item_in_set);
1246 }
1247
1248 static void enque_handler(PTInstVar pvar, int message,
1249 SSHPacketHandler handler)
1250 {
1251 enque_handlers(pvar, 1, &message, &handler);
1252 }
1253
1254 static void chop_newlines(char FAR * buf)
1255 {
1256 int len = strlen(buf);
1257
1258 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1259 buf[len - 1] = 0;
1260 len--;
1261 }
1262 }
1263
1264 /********************/
1265 /* Message handlers */
1266 /********************/
1267
1268 static BOOL handle_forwarding_success(PTInstVar pvar)
1269 {
1270 return FALSE;
1271 }
1272
1273 static BOOL handle_forwarding_failure(PTInstVar pvar)
1274 {
1275 return FALSE;
1276 }
1277
1278 static void enque_forwarding_request_handlers(PTInstVar pvar)
1279 {
1280 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1281 static const SSHPacketHandler handlers[]
1282 = { handle_forwarding_success, handle_forwarding_failure };
1283
1284 enque_handlers(pvar, 2, msgs, handlers);
1285 }
1286
1287 static BOOL handle_auth_failure(PTInstVar pvar)
1288 {
1289 notify_verbose_message(pvar, "Authentication failed",
1290 LOG_LEVEL_VERBOSE);
1291
1292 // retry count������ (2005.7.15 yutaka)
1293 pvar->userauth_retry_count++;
1294
1295 AUTH_set_generic_mode(pvar);
1296 AUTH_advance_to_next_cred(pvar);
1297 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1298 try_send_credentials(pvar);
1299 return FALSE;
1300 }
1301
1302 static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1303 {
1304 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1305 if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1306 // �S�������������I������
1307 safefree(pvar->pageant_key);
1308 }
1309 else {
1310 // ������������
1311 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1312 try_send_credentials(pvar);
1313 return TRUE;
1314 }
1315 }
1316 AUTH_destroy_cur_cred(pvar);
1317 return handle_auth_failure(pvar);
1318 }
1319
1320 static BOOL handle_TIS_challenge(PTInstVar pvar)
1321 {
1322 if (grab_payload(pvar, 4)) {
1323 int len = get_payload_uint32(pvar, 0);
1324
1325 if (grab_payload(pvar, len)) {
1326 notify_verbose_message(pvar, "Received TIS challenge",
1327 LOG_LEVEL_VERBOSE);
1328
1329 AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1330 AUTH_advance_to_next_cred(pvar);
1331 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1332 try_send_credentials(pvar);
1333 }
1334 }
1335 return FALSE;
1336 }
1337
1338 static BOOL handle_auth_required(PTInstVar pvar)
1339 {
1340 notify_verbose_message(pvar, "Server requires authentication",
1341 LOG_LEVEL_VERBOSE);
1342
1343 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1344 try_send_credentials(pvar);
1345 /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1346
1347 return FALSE;
1348 }
1349
1350 static BOOL handle_ignore(PTInstVar pvar)
1351 {
1352 if (SSHv1(pvar)) {
1353 notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1354
1355 if (grab_payload(pvar, 4)
1356 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1357 /* ignore it! but it must be decompressed */
1358 }
1359 }
1360 else {
1361 notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1362
1363 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1364 // Cisco ���[�^���� (2006.11.28 maya)
1365 }
1366 return TRUE;
1367 }
1368
1369 static BOOL handle_debug(PTInstVar pvar)
1370 {
1371 BOOL always_display;
1372 char FAR *description;
1373 int description_len;
1374 char buf[2048];
1375
1376 if (SSHv1(pvar)) {
1377 notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1378
1379 if (grab_payload(pvar, 4)
1380 && grab_payload(pvar, description_len =
1381 get_payload_uint32(pvar, 0))) {
1382 always_display = FALSE;
1383 description = pvar->ssh_state.payload + 4;
1384 description[description_len] = 0;
1385 } else {
1386 return TRUE;
1387 }
1388 } else {
1389 notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1390
1391 if (grab_payload(pvar, 5)
1392 && grab_payload(pvar,
1393 (description_len = get_payload_uint32(pvar, 1)) + 4)
1394 && grab_payload(pvar,
1395 get_payload_uint32(pvar, 5 + description_len))) {
1396 always_display = pvar->ssh_state.payload[0] != 0;
1397 description = pvar->ssh_state.payload + 5;
1398 description[description_len] = 0;
1399 } else {
1400 return TRUE;
1401 }
1402 }
1403
1404 chop_newlines(description);
1405 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1406 description);
1407 if (always_display) {
1408 notify_nonfatal_error(pvar, buf);
1409 } else {
1410 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1411 }
1412 return TRUE;
1413 }
1414
1415 static BOOL handle_disconnect(PTInstVar pvar)
1416 {
1417 int reason_code;
1418 char FAR *description;
1419 int description_len;
1420 char buf[2048];
1421 char FAR *explanation = "";
1422 char uimsg[MAX_UIMSG];
1423
1424 if (SSHv1(pvar)) {
1425 notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1426
1427 if (grab_payload(pvar, 4)
1428 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1429 reason_code = -1;
1430 description = pvar->ssh_state.payload + 4;
1431 description[description_len] = 0;
1432 } else {
1433 return TRUE;
1434 }
1435 } else {
1436 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1437
1438 if (grab_payload(pvar, 8)
1439 && grab_payload(pvar,
1440 (description_len = get_payload_uint32(pvar, 4)) + 4)
1441 && grab_payload(pvar,
1442 get_payload_uint32(pvar, 8 + description_len))) {
1443 reason_code = get_payload_uint32(pvar, 0);
1444 description = pvar->ssh_state.payload + 8;
1445 description[description_len] = 0;
1446 } else {
1447 return TRUE;
1448 }
1449 }
1450
1451 chop_newlines(description);
1452 if (description[0] == 0) {
1453 description = NULL;
1454 }
1455
1456 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1457 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1458 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1459 "This often happens when someone is already forwarding that port from the server.");
1460 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1461 explanation = uimsg;
1462 }
1463
1464 if (description != NULL) {
1465 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1466 "Server disconnected with message '%s'%s");
1467 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1468 pvar->ts->UIMsg, description,
1469 explanation);
1470 } else {
1471 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1472 "Server disconnected (no reason given).%s");
1473 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1474 pvar->ts->UIMsg, explanation);
1475 }
1476
1477 if (SSHv2(pvar)) {
1478 // SSH2_MSG_DISCONNECT �������������������������M��������������
1479 notify_fatal_error(pvar, buf, FALSE);
1480 }
1481 else {
1482 // SSH1 ���������d�l�����������������A���O����������������
1483 notify_fatal_error(pvar, buf, TRUE);
1484 }
1485
1486 return TRUE;
1487 }
1488
1489 static BOOL handle_unimplemented(PTInstVar pvar)
1490 {
1491 /* Should never receive this since we only send base 2.0 protocol messages */
1492 grab_payload(pvar, 4);
1493 return TRUE;
1494 }
1495
1496 static BOOL handle_crypt_success(PTInstVar pvar)
1497 {
1498 notify_verbose_message(pvar, "Secure mode successfully achieved",
1499 LOG_LEVEL_VERBOSE);
1500 return FALSE;
1501 }
1502
1503 static BOOL handle_noauth_success(PTInstVar pvar)
1504 {
1505 notify_verbose_message(pvar, "Server does not require authentication",
1506 LOG_LEVEL_VERBOSE);
1507 prep_compression(pvar);
1508 return FALSE;
1509 }
1510
1511 static BOOL handle_auth_success(PTInstVar pvar)
1512 {
1513 notify_verbose_message(pvar, "Authentication accepted",
1514 LOG_LEVEL_VERBOSE);
1515 prep_compression(pvar);
1516
1517 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1518 start_ssh_heartbeat_thread(pvar);
1519
1520 return FALSE;
1521 }
1522
1523 static BOOL handle_server_public_key(PTInstVar pvar)
1524 {
1525 int server_key_public_exponent_len;
1526 int server_key_public_modulus_pos;
1527 int server_key_public_modulus_len;
1528 int host_key_bits_pos;
1529 int host_key_public_exponent_len;
1530 int host_key_public_modulus_pos;
1531 int host_key_public_modulus_len;
1532 int protocol_flags_pos;
1533 int supported_ciphers;
1534 char FAR *inmsg;
1535 Key hostkey;
1536 int supported_types;
1537
1538 notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1539
1540 if (!grab_payload(pvar, 14))
1541 return FALSE;
1542 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1543
1544 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1545 return FALSE;
1546 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1547 server_key_public_modulus_len =
1548 get_mpint_len(pvar, server_key_public_modulus_pos);
1549
1550 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1551 return FALSE;
1552 host_key_bits_pos =
1553 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1554 host_key_public_exponent_len =
1555 get_mpint_len(pvar, host_key_bits_pos + 4);
1556
1557 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1558 return FALSE;
1559 host_key_public_modulus_pos =
1560 host_key_bits_pos + 6 + host_key_public_exponent_len;
1561 host_key_public_modulus_len =
1562 get_mpint_len(pvar, host_key_public_modulus_pos);
1563
1564 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1565 return FALSE;
1566 protocol_flags_pos =
1567 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1568
1569 inmsg = pvar->ssh_state.payload;
1570
1571 CRYPT_set_server_cookie(pvar, inmsg);
1572 if (!CRYPT_set_server_RSA_key(pvar,
1573 get_uint32(inmsg + 8),
1574 pvar->ssh_state.payload + 12,
1575 inmsg + server_key_public_modulus_pos))
1576 return FALSE;
1577 if (!CRYPT_set_host_RSA_key(pvar,
1578 get_uint32(inmsg + host_key_bits_pos),
1579 inmsg + host_key_bits_pos + 4,
1580 inmsg + host_key_public_modulus_pos))
1581 return FALSE;
1582 pvar->ssh_state.server_protocol_flags =
1583 get_uint32(inmsg + protocol_flags_pos);
1584
1585 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1586 if (!CRYPT_set_supported_ciphers(pvar,
1587 supported_ciphers,
1588 supported_ciphers))
1589 return FALSE;
1590
1591 // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1592 // RSA ���L������ PAGEANT ���L��������
1593 supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1594 if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1595 supported_types |= (1 << SSH_AUTH_PAGEANT);
1596 }
1597 if (!AUTH_set_supported_auth_types(pvar,
1598 supported_types))
1599 return FALSE;
1600
1601 /* this must be the LAST THING in this function, since it can cause
1602 host_is_OK to be called. */
1603 hostkey.type = KEY_RSA1;
1604 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1605 hostkey.exp = inmsg + host_key_bits_pos + 4;
1606 hostkey.mod = inmsg + host_key_public_modulus_pos;
1607 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1608
1609 return FALSE;
1610 }
1611
1612 /*
1613 The ID must have already been found to start with "SSH-". It must
1614 be null-terminated.
1615 */
1616 static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1617 {
1618 char FAR *str;
1619
1620 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1621 }
1622
1623 if (*str != '.') {
1624 return FALSE;
1625 }
1626
1627 pvar->protocol_major = atoi(ID + 4);
1628 pvar->protocol_minor = atoi(str + 1);
1629
1630 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1631 }
1632
1633 return *str == '-';
1634 }
1635
1636 /*
1637 On entry, the pvar->protocol_xxx fields hold the server's advertised
1638 protocol number. We replace the fields with the protocol number we will
1639 actually use, or return FALSE if there is no usable protocol version.
1640 */
1641 static int negotiate_protocol(PTInstVar pvar)
1642 {
1643 switch (pvar->protocol_major) {
1644 case 1:
1645 if (pvar->protocol_minor == 99 &&
1646 pvar->settings.ssh_protocol_version == 2) {
1647 // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1648 // 2.0 ����������
1649 pvar->protocol_major = 2;
1650 pvar->protocol_minor = 0;
1651 return 0;
1652 }
1653
1654 if (pvar->settings.ssh_protocol_version == 2) {
1655 // �o�[�W��������
1656 return -1;
1657 }
1658
1659 if (pvar->protocol_minor > 5) {
1660 pvar->protocol_minor = 5;
1661 }
1662
1663 return 0;
1664
1665 // for SSH2(yutaka)
1666 case 2:
1667 if (pvar->settings.ssh_protocol_version == 1) {
1668 // �o�[�W��������
1669 return -1;
1670 }
1671
1672 return 0; // SSH2 support
1673
1674 default:
1675 return 1;
1676 }
1677 }
1678
1679 static void init_protocol(PTInstVar pvar)
1680 {
1681 CRYPT_initialize_random_numbers(pvar);
1682
1683 // known_hosts�t�@�C�������z�X�g���J������������������
1684 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1685
1686 /* while we wait for a response from the server... */
1687
1688 if (SSHv1(pvar)) {
1689 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1690 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1691 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1692 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1693
1694 } else { // for SSH2(yutaka)
1695 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1696 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1697 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1698 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1699 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1700 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1701 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1702 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1703 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1704 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1705 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1706 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1707 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1708 enque_handler(pvar, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, handle_SSH2_userauth_passwd_changereq);
1709
1710 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1711
1712 // ���[�U�F�������f�B�X�p�b�`���[�`��
1713 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1714 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1715 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1716 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1717 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1718 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1719 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1720 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1721 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1722 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1723 enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1724 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1725 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1726 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1727
1728 client_init_global_confirm();
1729
1730 }
1731 }
1732
1733 void server_version_check(PTInstVar pvar)
1734 {
1735 char *server_swver;
1736
1737 pvar->server_compat_flag = 0;
1738
1739 if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1740 notify_verbose_message(pvar, "Can't get server software version string.", LOG_LEVEL_WARNING);
1741 return;
1742 }
1743 server_swver++;
1744
1745 if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1746 pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1747 notify_verbose_message(pvar, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.", LOG_LEVEL_INFO);
1748 }
1749 }
1750
1751 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1752 {
1753 static char prefix[64];
1754 int negotiate;
1755 char uimsg[MAX_UIMSG];
1756
1757 // initialize SSH2 memory dump (2005.3.7 yutaka)
1758 init_memdump();
1759 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1760
1761 if (ID_len <= 0) {
1762 return FALSE;
1763 } else {
1764 int buf_len;
1765 char FAR *buf;
1766
1767 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1768 buf_len = strlen(prefix) + ID_len + 1;
1769 buf = (char FAR *) malloc(buf_len);
1770 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1771 strncat_s(buf, buf_len, ID, _TRUNCATE);
1772 chop_newlines(buf);
1773 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1774 free(buf);
1775
1776 if (ID[ID_len - 1] != '\n') {
1777 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1778 return FALSE;
1779 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1780 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1781 return FALSE;
1782 } else if (strncmp(ID, "SSH-", 4) != 0) {
1783 return FALSE;
1784 } else {
1785 ID[ID_len - 1] = 0;
1786
1787 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1788 ID[ID_len - 2] = 0;
1789 }
1790
1791 pvar->ssh_state.server_ID = _strdup(ID);
1792
1793 if (!parse_protocol_ID(pvar, ID)) {
1794 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1795 "This program does not understand the server's version of the protocol.");
1796 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1797 }
1798 else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1799 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1800 "This program does not understand the server's version of the protocol.");
1801 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1802 }
1803 else if (negotiate == -1) {
1804 UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1805 "Protocol version mismatch. server:%d.%d client:%d");
1806 _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1807 pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1808 notify_fatal_error(pvar, uimsg, TRUE);
1809 }
1810 else {
1811 char TTSSH_ID[1024];
1812 int TTSSH_ID_len;
1813 int a, b, c, d;
1814
1815 // SSH �o�[�W������ teraterm �����Z�b�g����
1816 // SCP �R�}���h������ (2008.2.3 maya)
1817 pvar->cv->isSSH = pvar->protocol_major;
1818
1819 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1820 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1821
1822 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1823 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1824 pvar->protocol_major, pvar->protocol_minor, a, b);
1825 TTSSH_ID_len = strlen(TTSSH_ID);
1826
1827 // for SSH2(yutaka)
1828 // �N���C�A���g�o�[�W�����������i���s���������������j
1829 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1830 TTSSH_ID, _TRUNCATE);
1831
1832 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1833 _snprintf_s(pvar->server_version_string,
1834 sizeof(pvar->server_version_string), _TRUNCATE,
1835 "%s", pvar->ssh_state.server_ID);
1836
1837 // �T�[�o�o�[�W�������`�F�b�N
1838 server_version_check(pvar);
1839
1840 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1841 0) != TTSSH_ID_len) {
1842 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1843 "An error occurred while sending the SSH ID string.\n"
1844 "The connection will close.");
1845 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1846 } else {
1847 // ���s�R�[�h������ (2004.8.4 yutaka)
1848 pvar->client_version_string[--TTSSH_ID_len] = 0; // \n
1849 pvar->client_version_string[--TTSSH_ID_len] = 0; // \r
1850
1851 strncpy_s(prefix, sizeof(prefix), "Sent client identification string: ", _TRUNCATE);
1852 buf_len = strlen(prefix) + strlen(pvar->client_version_string) + 1;
1853 buf = (char FAR *) malloc(buf_len);
1854 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1855 strncat_s(buf, buf_len, pvar->client_version_string, _TRUNCATE);
1856 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1857 free(buf);
1858
1859 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1860 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1861
1862 // SSH�n���h�����o�^���s��
1863 init_protocol(pvar);
1864
1865 SSH2_dispatch_init(1);
1866 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1867 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1868 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1869 }
1870 }
1871
1872 return TRUE;
1873 }
1874 }
1875 }
1876
1877 static BOOL handle_exit(PTInstVar pvar)
1878 {
1879 if (grab_payload(pvar, 4)) {
1880 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1881 finish_send_packet(pvar);
1882 notify_closed_connection(pvar, "disconnected by server request");
1883 }
1884 return TRUE;
1885 }
1886
1887 static BOOL handle_data(PTInstVar pvar)
1888 {
1889 if (grab_payload_limited(pvar, 4)) {
1890 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1891 pvar->ssh_state.payload_datastart = 4;
1892 }
1893 return TRUE;
1894 }
1895
1896 static BOOL handle_channel_open(PTInstVar pvar)
1897 {
1898 int host_len;
1899 int originator_len;
1900
1901 if ((pvar->ssh_state.
1902 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1903 if (grab_payload(pvar, 8)
1904 && grab_payload(pvar,
1905 8 + (host_len = get_payload_uint32(pvar, 4)))
1906 && grab_payload(pvar, originator_len =
1907 get_payload_uint32(pvar, host_len + 12))) {
1908 int local_port = get_payload_uint32(pvar, 8 + host_len);
1909
1910 pvar->ssh_state.payload[8 + host_len] = 0;
1911 FWD_open(pvar, get_payload_uint32(pvar, 0),
1912 pvar->ssh_state.payload + 8, local_port,
1913 pvar->ssh_state.payload + 16 + host_len,
1914 originator_len,
1915 NULL);
1916 }
1917 } else {
1918 if (grab_payload(pvar, 8)
1919 && grab_payload(pvar,
1920 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1921 int local_port = get_payload_uint32(pvar, 8 + host_len);
1922
1923 pvar->ssh_state.payload[8 + host_len] = 0;
1924 FWD_open(pvar, get_payload_uint32(pvar, 0),
1925 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1926 NULL);
1927 }
1928 }
1929
1930 return TRUE;
1931 }
1932
1933 static BOOL handle_X11_channel_open(PTInstVar pvar)
1934 {
1935 int originator_len;
1936
1937 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1938 if (grab_payload(pvar, 8)
1939 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1940 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1941 pvar->ssh_state.payload + 8, originator_len, NULL);
1942 }
1943 } else {
1944 if (grab_payload(pvar, 4)) {
1945 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1946 }
1947 }
1948
1949 return TRUE;
1950 }
1951
1952 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1953 {
1954 if (grab_payload(pvar, 8)) {
1955 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1956 get_payload_uint32(pvar, 4));
1957 }
1958 return FALSE;
1959 }
1960
1961 static BOOL handle_channel_open_failure(PTInstVar pvar)
1962 {
1963 if (grab_payload(pvar, 4)) {
1964 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1965 }
1966 return FALSE;
1967 }
1968
1969 static BOOL handle_channel_data(PTInstVar pvar)
1970 {
1971 int len;
1972
1973 if (grab_payload(pvar, 8)
1974 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1975 FWDChannel *channel;
1976 int local_channel_num = get_payload_uint32(pvar, 0);
1977 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1978 return FALSE;
1979 }
1980 channel = pvar->fwd_state.channels + local_channel_num;
1981 if (channel->type == TYPE_AGENT) {
1982 SSH_agent_response(pvar, NULL, local_channel_num,
1983 pvar->ssh_state.payload + 8, len);
1984 }
1985 else {
1986 FWD_received_data(pvar, local_channel_num,
1987 pvar->ssh_state.payload + 8, len);
1988 }
1989 }
1990 return TRUE;
1991 }
1992
1993 static BOOL handle_channel_input_eof(PTInstVar pvar)
1994 {
1995 if (grab_payload(pvar, 4)) {
1996 int local_channel_num = get_payload_uint32(pvar, 0);
1997 FWDChannel *channel;
1998 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1999 return FALSE;
2000 }
2001 channel = pvar->fwd_state.channels + local_channel_num;
2002 if (channel->type == TYPE_AGENT) {
2003 channel->status |= FWD_CLOSED_REMOTE_IN;
2004 SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
2005 }
2006 else {
2007 FWD_channel_input_eof(pvar, local_channel_num);
2008 }
2009 }
2010 return TRUE;
2011 }
2012
2013 static BOOL handle_channel_output_eof(PTInstVar pvar)
2014 {
2015 if (grab_payload(pvar, 4)) {
2016 int local_channel_num = get_payload_uint32(pvar, 0);
2017 FWDChannel *channel;
2018 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
2019 return FALSE;
2020 }
2021 channel = pvar->fwd_state.channels + local_channel_num;
2022 if (channel->type == TYPE_AGENT) {
2023 channel->status |= FWD_CLOSED_REMOTE_OUT;
2024 SSH_channel_output_eof(pvar, channel->remote_num);
2025 FWD_free_channel(pvar, local_channel_num);
2026 }
2027 else {
2028 FWD_channel_output_eof(pvar, local_channel_num);
2029 }
2030 }
2031 return TRUE;
2032 }
2033
2034 static BOOL handle_agent_open(PTInstVar pvar)
2035 {
2036 if (grab_payload(pvar, 4)) {
2037 int remote_id = get_payload_uint32(pvar, 0);
2038 int local_id;
2039
2040 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2041 local_id = FWD_agent_open(pvar, remote_id);
2042 if (local_id == -1) {
2043 SSH_fail_channel_open(pvar, remote_id);
2044 }
2045 else {
2046 SSH_confirm_channel_open(pvar, remote_id, local_id);
2047 }
2048 }
2049 else {
2050 SSH_fail_channel_open(pvar, remote_id);
2051 }
2052 }
2053 /*
2054 else {
2055 // ���m��������channel����������������������������
2056 }
2057 */
2058
2059 return TRUE;
2060 }
2061
2062
2063
2064 // �n���h�����O�������b�Z�[�W����������
2065
2066 #define HANDLE_MESSAGE_MAX 30
2067 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2068 static int handle_message_count = 0;
2069 static int handle_message_stage = 0;
2070
2071 void SSH2_dispatch_init(int stage)
2072 {
2073 handle_message_count = 0;
2074 handle_message_stage = stage;
2075 }
2076
2077 int SSH2_dispatch_enabled_check(unsigned char message)
2078 {
2079 int i;
2080
2081 for (i = 0 ; i < handle_message_count ; i++) {
2082 if (handle_messages[i] == message)
2083 return 1;
2084 }
2085 return 0;
2086 }
2087
2088 void SSH2_dispatch_add_message(unsigned char message)
2089 {
2090 int i;
2091
2092 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2093 // TODO: error check
2094 return;
2095 }
2096
2097 // �������o�^�������������b�Z�[�W������������
2098 for (i=0; i<handle_message_count; i++) {
2099 if (handle_messages[i] == message) {
2100 return;
2101 }
2102 }
2103
2104 handle_messages[handle_message_count++] = message;
2105 }
2106
2107 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2108 {
2109 unsigned char c;
2110
2111 for (c = begin ; c <= end ; c++) {
2112 SSH2_dispatch_add_message(c);
2113 }
2114 }
2115
2116
2117 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2118 int padding)
2119 {
2120 unsigned char message = prep_packet(pvar, data, len, padding);
2121
2122
2123 #ifdef SSH2_DEBUG
2124 // for SSH2(yutaka)
2125 if (SSHv2(pvar)) {
2126 if (pvar->key_done) {
2127 message = message;
2128 }
2129
2130 if (pvar->userauth_success) {
2131 message = message;
2132 }
2133
2134 if (pvar->rekeying) {
2135 message = message;
2136 }
2137 }
2138 #endif
2139
2140 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2141 if (message != SSH_MSG_NONE) {
2142 // ���b�Z�[�W�^�C�v���������n���h�����N��
2143 SSHPacketHandler handler = get_handler(pvar, message);
2144
2145 // for SSH2(yutaka)
2146 if (SSHv2(pvar)) {
2147 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2148 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2149 char buf[1024];
2150
2151 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2152 "Unexpected SSH2 message(%d) on current stage(%d)");
2153 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2154 pvar->ts->UIMsg, message, handle_message_stage);
2155 notify_fatal_error(pvar, buf, TRUE);
2156 // abort
2157 }
2158 }
2159
2160 if (handler == NULL) {
2161 if (SSHv1(pvar)) {
2162 char buf[1024];
2163
2164 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2165 "Unexpected packet type received: %d");
2166 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2167 pvar->ts->UIMsg, message, handle_message_stage);
2168 notify_fatal_error(pvar, buf, TRUE);
2169 } else {
2170 unsigned char FAR *outmsg =
2171 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2172
2173 set_uint32(outmsg,
2174 pvar->ssh_state.receiver_sequence_number - 1);
2175 finish_send_packet(pvar);
2176
2177 notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2178 /* XXX need to decompress incoming packet, but how? */
2179 }
2180 } else {
2181 if (!handler(pvar)) {
2182 deque_handlers(pvar, message);
2183 }
2184 }
2185 }
2186 }
2187
2188 static BOOL handle_pty_success(PTInstVar pvar)
2189 {
2190 FWD_enter_interactive_mode(pvar);
2191 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2192 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2193 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2194 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2195 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2196 handle_channel_input_eof);
2197 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2198 handle_channel_output_eof);
2199 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2200 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2201 enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2202 return FALSE;
2203 }
2204
2205 static BOOL handle_pty_failure(PTInstVar pvar)
2206 {
2207 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2208 "The server cannot allocate a pseudo-terminal. "
2209 "You may encounter some problems with the terminal.");
2210 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2211 return handle_pty_success(pvar);
2212 }
2213
2214 static void prep_pty(PTInstVar pvar)
2215 {
2216 int len = strlen(pvar->ts->TermType);
2217 unsigned char FAR *outmsg =
2218 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2219 4 + len + 16 + sizeof(ssh_ttymodes));
2220 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2221 static const SSHPacketHandler handlers[]
2222 = { handle_pty_success, handle_pty_failure };
2223
2224 set_uint32(outmsg, len);
2225 memcpy(outmsg + 4, pvar->ts->TermType, len);
2226 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2227 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2228 set_uint32(outmsg + 4 + len + 8, 0);
2229 set_uint32(outmsg + 4 + len + 12, 0);
2230 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2231 finish_send_packet(pvar);
2232
2233 enque_handlers(pvar, 2, msgs, handlers);
2234
2235 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2236 finish_send_packet(pvar);
2237 }
2238
2239 static BOOL handle_agent_request_success(PTInstVar pvar)
2240 {
2241 pvar->agentfwd_enable = TRUE;
2242 prep_pty(pvar);
2243 return FALSE;
2244 }
2245
2246 static BOOL handle_agent_request_failure(PTInstVar pvar)
2247 {
2248 prep_pty(pvar);
2249 return FALSE;
2250 }
2251
2252 static void prep_agent_request(PTInstVar pvar)
2253 {
2254 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2255 static const SSHPacketHandler handlers[]
2256 = { handle_agent_request_success, handle_agent_request_failure };
2257
2258 enque_handlers(pvar, 2, msgs, handlers);
2259
2260 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2261 finish_send_packet(pvar);
2262 }
2263
2264 static void prep_forwarding(PTInstVar pvar)
2265 {
2266 FWD_prep_forwarding(pvar);
2267
2268 if (pvar->session_settings.ForwardAgent) {
2269 prep_agent_request(pvar);
2270 }
2271 else {
2272 prep_pty(pvar);
2273 }
2274 }
2275
2276
2277 //
2278 //
2279 // (2005.7.10 yutaka)
2280 static void enable_send_compression(PTInstVar pvar)
2281 {
2282 static int initialize = 0;
2283
2284 if (initialize) {
2285 deflateEnd(&pvar->ssh_state.compress_stream);
2286 }
2287 initialize = 1;
2288
2289 pvar->ssh_state.compress_stream.zalloc = NULL;
2290 pvar->ssh_state.compress_stream.zfree = NULL;
2291 pvar->ssh_state.compress_stream.opaque = NULL;
2292 if (deflateInit
2293 (&pvar->ssh_state.compress_stream,
2294 pvar->ssh_state.compression_level) != Z_OK) {
2295 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2296 "An error occurred while setting up compression.\n"
2297 "The connection will close.");
2298 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2299 return;
2300 } else {
2301 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2302 if (SSHv2(pvar)) {
2303 pvar->ssh_state.compressing = FALSE;
2304 } else {
2305 pvar->ssh_state.compressing = TRUE;
2306 }
2307 }
2308 }
2309
2310 static void enable_recv_compression(PTInstVar pvar)
2311 {
2312 static int initialize = 0;
2313
2314 if (initialize) {
2315 deflateEnd(&pvar->ssh_state.decompress_stream);
2316 }
2317 initialize = 1;
2318
2319 pvar->ssh_state.decompress_stream.zalloc = NULL;
2320 pvar->ssh_state.decompress_stream.zfree = NULL;
2321 pvar->ssh_state.decompress_stream.opaque = NULL;
2322 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2323 deflateEnd(&pvar->ssh_state.compress_stream);
2324 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2325 "An error occurred while setting up compression.\n"
2326 "The connection will close.");
2327 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2328 return;
2329 } else {
2330 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2331 if (SSHv2(pvar)) {
2332 pvar->ssh_state.decompressing = FALSE;
2333 } else {
2334 pvar->ssh_state.decompressing = TRUE;
2335 }
2336
2337 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2338 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2339 }
2340 }
2341
2342 static void enable_compression(PTInstVar pvar)
2343 {
2344 enable_send_compression(pvar);
2345 enable_recv_compression(pvar);
2346
2347 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2348 if (SSHv2(pvar)) {
2349 pvar->ssh_state.compressing = FALSE;
2350 pvar->ssh_state.decompressing = FALSE;
2351 }
2352
2353 }
2354
2355 static BOOL handle_enable_compression(PTInstVar pvar)
2356 {
2357 enable_compression(pvar);
2358 prep_forwarding(pvar);
2359 return FALSE;
2360 }
2361
2362 static BOOL handle_disable_compression(PTInstVar pvar)
2363 {
2364 prep_forwarding(pvar);
2365 return FALSE;
2366 }
2367
2368 static void prep_compression(PTInstVar pvar)
2369 {
2370 if (pvar->session_settings.CompressionLevel > 0) {
2371 // added if statement (2005.7.10 yutaka)
2372 if (SSHv1(pvar)) {
2373 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2374 static const SSHPacketHandler handlers[]
2375 = { handle_enable_compression, handle_disable_compression };
2376
2377 unsigned char FAR *outmsg =
2378 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2379
2380 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2381 finish_send_packet(pvar);
2382
2383 enque_handlers(pvar, 2, msgs, handlers);
2384 }
2385
2386 pvar->ssh_state.compression_level =
2387 pvar->session_settings.CompressionLevel;
2388
2389 } else {
2390 // added if statement (2005.7.10 yutaka)
2391 if (SSHv1(pvar)) {
2392 prep_forwarding(pvar);
2393 }
2394 }
2395 }
2396
2397 static void enque_simple_auth_handlers(PTInstVar pvar)
2398 {
2399 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2400 static const SSHPacketHandler handlers[]
2401 = { handle_auth_success, handle_auth_failure };
2402
2403 enque_handlers(pvar, 2, msgs, handlers);
2404 }
2405
2406 static BOOL handle_rsa_challenge(PTInstVar pvar)
2407 {
2408 int challenge_bytes;
2409
2410 if (!grab_payload(pvar, 2)) {
2411 return FALSE;
2412 }
2413
2414 challenge_bytes = get_mpint_len(pvar, 0);
2415
2416 if (grab_payload(pvar, challenge_bytes)) {
2417 unsigned char FAR *outmsg =
2418 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2419
2420 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2421 if (CRYPT_generate_RSA_challenge_response
2422 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2423
2424 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2425 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2426 #if 0
2427 //AUTH_destroy_cur_cred(pvar);
2428 #endif
2429
2430 finish_send_packet(pvar);
2431
2432 enque_simple_auth_handlers(pvar);
2433 } else {
2434 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2435 "An error occurred while decrypting the RSA challenge.\n"
2436 "Perhaps the key file is corrupted.");
2437 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2438 }
2439 }
2440 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2441 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2442 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2443 int server_key_bytes = (server_key_bits + 7) / 8;
2444 int host_key_bytes = (host_key_bits + 7) / 8;
2445 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2446 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2447 unsigned char session_id[16];
2448
2449 unsigned char *hash;
2450 int pubkeylen, hashlen;
2451
2452 /* Pageant ���n�b�V�����v�Z���������� */
2453 // ���J��������
2454 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2455 pvar->pageant_keylistlen);
2456 // �Z�b�V����ID������
2457 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2458 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2459 session_buf + host_key_bytes);
2460 memcpy(session_buf + server_key_bytes + host_key_bytes,
2461 pvar->crypt_state.server_cookie, 8);
2462 MD5(session_buf, session_buf_len, session_id);
2463 // �n�b�V������������
2464 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2465 pubkeylen,
2466 pvar->ssh_state.payload,
2467 challenge_bytes + 2,
2468 session_id,
2469 &hashlen);
2470
2471 // �n�b�V�������M
2472 memcpy(outmsg, hash, 16);
2473 free(hash);
2474
2475 finish_send_packet(pvar);
2476
2477 enque_simple_auth_handlers(pvar);
2478 }
2479 }
2480
2481 return FALSE;
2482 }
2483
2484 static void try_send_credentials(PTInstVar pvar)
2485 {
2486 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2487 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2488 static const int RSA_msgs[] =
2489 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2490 static const SSHPacketHandler RSA_handlers[]
2491 = { handle_rsa_challenge, handle_rsa_auth_refused };
2492 static const int TIS_msgs[] =
2493 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2494 static const SSHPacketHandler TIS_handlers[]
2495 = { handle_TIS_challenge, handle_auth_failure };
2496
2497 // SSH2���������������������X�L�b�v
2498 if (SSHv2(pvar))
2499 goto skip_ssh2;
2500
2501 switch (cred->method) {
2502 case SSH_AUTH_NONE:
2503 return;
2504 case SSH_AUTH_PASSWORD:{
2505 int len = strlen(cred->password);
2506 unsigned char FAR *outmsg =
2507 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2508 4 + len);
2509
2510 notify_verbose_message(pvar,
2511 "Trying PASSWORD authentication...",
2512 LOG_LEVEL_VERBOSE);
2513
2514 set_uint32(outmsg, len);
2515 memcpy(outmsg + 4, cred->password, len);
2516
2517 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2518 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2519 #if 0
2520 //AUTH_destroy_cur_cred(pvar);
2521 #endif
2522
2523 enque_simple_auth_handlers(pvar);
2524 break;
2525 }
2526 case SSH_AUTH_RHOSTS:{
2527 int len = strlen(cred->rhosts_client_user);
2528 unsigned char FAR *outmsg =
2529 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2530
2531 notify_verbose_message(pvar,
2532 "Trying RHOSTS authentication...",
2533 LOG_LEVEL_VERBOSE);
2534
2535 set_uint32(outmsg, len);
2536 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2537 AUTH_destroy_cur_cred(pvar);
2538 enque_simple_auth_handlers(pvar);
2539 break;
2540 }
2541 case SSH_AUTH_RSA:{
2542 int len = BN_num_bytes(cred->key_pair->rsa->n);
2543 unsigned char FAR *outmsg =
2544 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2545
2546 notify_verbose_message(pvar,
2547 "Trying RSA authentication...",
2548 LOG_LEVEL_VERBOSE);
2549
2550 set_ushort16_MSBfirst(outmsg, len * 8);
2551 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2552 /* don't destroy the current credentials yet */
2553 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2554 break;
2555 }
2556 case SSH_AUTH_RHOSTS_RSA:{
2557 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2558 int name_len = strlen(cred->rhosts_client_user);
2559 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2560 int index;
2561 unsigned char FAR *outmsg =
2562 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2563 12 + mod_len + name_len + exp_len);
2564
2565 notify_verbose_message(pvar,
2566 "Trying RHOSTS+RSA authentication...",
2567 LOG_LEVEL_VERBOSE);
2568
2569 set_uint32(outmsg, name_len);
2570 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2571 index = 4 + name_len;
2572
2573 set_uint32(outmsg + index, 8 * mod_len);
2574 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2575 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2576 index += 6 + exp_len;
2577
2578 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2579 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2580 /* don't destroy the current credentials yet */
2581 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2582 break;
2583 }
2584 case SSH_AUTH_PAGEANT:{
2585 unsigned char FAR *outmsg;
2586 unsigned char *pubkey;
2587 int len, bn_bytes;
2588
2589 if (pvar->pageant_keycurrent != 0) {
2590 // ���O�������X�L�b�v
2591 pvar->pageant_curkey += 4;
2592 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2593 bn_bytes = (len + 7) / 8;
2594 pvar->pageant_curkey += 2 + bn_bytes;
2595 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2596 bn_bytes = (len + 7) / 8;
2597 pvar->pageant_curkey += 2 + bn_bytes;
2598 // ���O�������R�����g���X�L�b�v
2599 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2600 pvar->pageant_curkey += 4 + len;
2601 // �����������u������
2602 }
2603 pubkey = pvar->pageant_curkey + 4;
2604 len = get_ushort16_MSBfirst(pubkey);
2605 bn_bytes = (len + 7) / 8;
2606 pubkey += 2 + bn_bytes;
2607 len = get_ushort16_MSBfirst(pubkey);
2608 bn_bytes = (len + 7) / 8;
2609 pubkey += 2;
2610 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2611
2612 notify_verbose_message(pvar,
2613 "Trying RSA authentication...",
2614 LOG_LEVEL_VERBOSE);
2615
2616 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2617 memcpy(outmsg + 2, pubkey, bn_bytes);
2618 /* don't destroy the current credentials yet */
2619
2620 pvar->pageant_keycurrent++;
2621
2622 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2623 break;
2624 }
2625 case SSH_AUTH_TIS:{
2626 if (cred->password == NULL) {
2627 unsigned char FAR *outmsg =
2628 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2629
2630 notify_verbose_message(pvar,
2631 "Trying TIS authentication...",
2632 LOG_LEVEL_VERBOSE);
2633 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2634 } else {
2635 int len = strlen(cred->password);
2636 unsigned char FAR *outmsg =
2637 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2638 4 + len);
2639
2640 notify_verbose_message(pvar,
2641 "Sending TIS response",
2642 LOG_LEVEL_VERBOSE);
2643
2644 set_uint32(outmsg, len);
2645 memcpy(outmsg + 4, cred->password, len);
2646 enque_simple_auth_handlers(pvar);
2647 }
2648
2649 AUTH_destroy_cur_cred(pvar);
2650 break;
2651 }
2652 default:
2653 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2654 "Internal error: unsupported authentication method");
2655 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2656 return;
2657 }
2658
2659 finish_send_packet(pvar);
2660
2661 skip_ssh2:;
2662 destroy_packet_buf(pvar);
2663
2664 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2665 }
2666 }
2667
2668 static void try_send_user_name(PTInstVar pvar)
2669 {
2670 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2671 char FAR *username = AUTH_get_user_name(pvar);
2672
2673 if (username != NULL) {
2674 int len = strlen(username);
2675 unsigned char FAR *outmsg =
2676 begin_send_packet(pvar, SSH_CMSG_USER, 4 + len);
2677 char buf[1024] = "Sending user name: ";
2678 static const int msgs[] =
2679 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2680 static const SSHPacketHandler handlers[]
2681 = { handle_noauth_success, handle_auth_required };
2682
2683 set_uint32(outmsg, len);
2684 memcpy(outmsg + 4, username, len);
2685 finish_send_packet(pvar);
2686
2687 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2688
2689 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2690 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2691
2692 enque_handlers(pvar, 2, msgs, handlers);
2693 }
2694 }
2695 }
2696
2697 static void send_session_key(PTInstVar pvar)
2698 {
2699 int encrypted_session_key_len;
2700 unsigned char FAR *outmsg;
2701
2702 if (SSHv1(pvar)) {
2703 encrypted_session_key_len =
2704 CRYPT_get_encrypted_session_key_len(pvar);
2705 }
2706
2707 if (!CRYPT_choose_ciphers(pvar))
2708 return;
2709
2710 if (SSHv1(pvar)) {
2711 outmsg =
2712 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2713 15 + encrypted_session_key_len);
2714 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2715 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2716 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2717 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2718 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2719 return;
2720 set_uint32(outmsg + 11 + encrypted_session_key_len,
2721 SSH_PROTOFLAG_SCREEN_NUMBER |
2722 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2723 finish_send_packet(pvar);
2724 }
2725
2726 if (!CRYPT_start_encryption(pvar, 1, 1))
2727 return;
2728 notify_established_secure_connection(pvar);
2729
2730 if (SSHv1(pvar)) {
2731 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2732 }
2733
2734 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2735
2736 if (SSHv1(pvar)) {
2737 try_send_user_name(pvar);
2738 }
2739 }
2740
2741 /*************************
2742 END of message handlers
2743 ************************/
2744
2745 void SSH_init(PTInstVar pvar)
2746 {
2747 int i;
2748
2749 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2750 buf_create(&pvar->ssh_state.precompress_outbuf,
2751 &pvar->ssh_state.precompress_outbuflen);
2752 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2753 &pvar->ssh_state.postdecompress_inbuflen);
2754 pvar->ssh_state.payload = NULL;
2755 pvar->ssh_state.compressing = FALSE;
2756 pvar->ssh_state.decompressing = FALSE;
2757 pvar->ssh_state.status_flags =
2758 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2759 pvar->ssh_state.payload_datalen = 0;
2760 pvar->ssh_state.hostname = NULL;
2761 pvar->ssh_state.server_ID = NULL;
2762 pvar->ssh_state.receiver_sequence_number = 0;
2763 pvar->ssh_state.sender_sequence_number = 0;
2764 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2765 pvar->ssh_state.packet_handlers[i] = NULL;
2766 }
2767
2768 // for SSH2(yutaka)
2769 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2770 pvar->userauth_success = 0;
2771 pvar->session_nego_status = 0;
2772 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2773 pvar->rekeying = 0;
2774 pvar->key_done = 0;
2775 pvar->ssh2_autologin = 0; // autologin disabled(default)
2776 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2777 pvar->userauth_retry_count = 0;
2778 pvar->decomp_buffer = NULL;
2779 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2780 pvar->tryed_ssh2_authlist = FALSE;
2781 pvar->agentfwd_enable = FALSE;
2782
2783 }
2784
2785 void SSH_open(PTInstVar pvar)
2786 {
2787 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2788 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2789 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2790 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2791 }
2792
2793 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2794 {
2795 if (SSHv1(pvar)) {
2796 int len = reason == NULL ? 0 : strlen(reason);
2797 unsigned char FAR *outmsg =
2798 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2799
2800 set_uint32(outmsg, len);
2801 if (reason != NULL) {
2802 memcpy(outmsg + 4, reason, len);
2803 }
2804 finish_send_packet(pvar);
2805
2806 } else { // for SSH2(yutaka)
2807 buffer_t *msg;
2808 unsigned char *outmsg;
2809 char *s;
2810 int len;
2811
2812 // SSH2 server��disconnect���`����
2813 msg = buffer_init();
2814 if (msg == NULL) {
2815 // TODO: error check
2816 return;
2817 }
2818 buffer_put_int(msg, SSH2_DISCONNECT_BY_APPLICATION);
2819 buffer_put_string(msg, reason, strlen(reason));
2820 s = "";
2821 buffer_put_string(msg, s, strlen(s));
2822
2823 len = buffer_len(msg);
2824 outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len);
2825 memcpy(outmsg, buffer_ptr(msg), len);
2826 finish_send_packet(pvar);
2827 buffer_free(msg);
2828
2829 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2830 }
2831 }
2832
2833 void SSH_notify_host_OK(PTInstVar pvar)
2834 {
2835 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2836 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2837 send_session_key(pvar);
2838 }
2839 }
2840
2841 void get_window_pixel_size(PTInstVar pvar, int *x, int *y)
2842 {
2843 RECT r;
2844
2845 if (pvar->cv->HWin && GetWindowRect(pvar->cv->HWin, &r)) {
2846 *x = r.right - r.left;
2847 *y = r.bottom - r.top;
2848 }
2849 else {
2850 *x = 0;
2851 *y = 0;
2852 }
2853
2854 return;
2855 }
2856
2857 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2858 {
2859 int x, y;
2860
2861 pvar->ssh_state.win_cols = cols;
2862 pvar->ssh_state.win_rows = rows;
2863
2864 if (SSHv1(pvar)) {
2865 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2866 unsigned char FAR *outmsg =
2867 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2868
2869 set_uint32(outmsg, rows);
2870 set_uint32(outmsg + 4, cols);
2871 set_uint32(outmsg + 8, 0);
2872 set_uint32(outmsg + 12, 0);
2873 finish_send_packet(pvar);
2874 }
2875
2876 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2877 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2878 buffer_t *msg;
2879 char *s;
2880 unsigned char *outmsg;
2881 int len;
2882 Channel_t *c;
2883
2884 c = ssh2_channel_lookup(pvar->shell_id);
2885 if (c == NULL)
2886 return;
2887
2888 msg = buffer_init();
2889 if (msg == NULL) {
2890 // TODO: error check
2891 return;
2892 }
2893 buffer_put_int(msg, c->remote_id);
2894 s = "window-change";
2895 buffer_put_string(msg, s, strlen(s));
2896 buffer_put_char(msg, 0); // wantconfirm
2897 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2898 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2899 get_window_pixel_size(pvar, &x, &y);
2900 buffer_put_int(msg, x); // window width (pixel):
2901 buffer_put_int(msg, y); // window height (pixel):
2902 len = buffer_len(msg);
2903 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2904 memcpy(outmsg, buffer_ptr(msg), len);
2905 finish_send_packet(pvar);
2906 buffer_free(msg);
2907
2908 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2909
2910 } else {
2911 // SSH�����������������������B
2912
2913 }
2914
2915 }
2916
2917 // �u���[�N�M���������B
2918 // OpenSSH ��"~B"�����������B�������ASSH2�����B
2919 // (2010.9.27 yutaka)
2920 int SSH_notify_break_signal(PTInstVar pvar)
2921 {
2922 int ret = 0;
2923
2924 if (SSHv1(pvar)) {
2925 // �����������B
2926
2927 } else if (SSHv2(pvar)) {
2928 buffer_t *msg;
2929 char *s;
2930 unsigned char *outmsg;
2931 int len;
2932 Channel_t *c;
2933
2934 c = ssh2_channel_lookup(pvar->shell_id);
2935 if (c == NULL)
2936 goto error;
2937
2938 msg = buffer_init();
2939 if (msg == NULL) {
2940 goto error;
2941 }
2942 buffer_put_int(msg, c->remote_id);
2943 s = "break";
2944 buffer_put_string(msg, s, strlen(s));
2945 buffer_put_char(msg, 0); // wantconfirm
2946 buffer_put_int(msg, 1000);
2947 len = buffer_len(msg);
2948 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2949 memcpy(outmsg, buffer_ptr(msg), len);
2950 finish_send_packet(pvar);
2951 buffer_free(msg);
2952
2953 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_break_signal().", LOG_LEVEL_VERBOSE);
2954
2955 ret = 1;
2956
2957 } else {
2958 // SSH�����������������������B
2959
2960 }
2961
2962 error:
2963 return (ret);
2964 }
2965
2966 int SSH_get_min_packet_size(PTInstVar pvar)
2967 {
2968 if (SSHv1(pvar)) {
2969 return 12;
2970 } else {
2971 int block_size = CRYPT_get_decryption_block_size(pvar);
2972
2973 return max(16, block_size);
2974 }
2975 }
2976
2977 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2978 at least 5 bytes must be decrypted */
2979 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2980 {
2981 if (SSHv2(pvar)) {
2982 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2983 }
2984 }
2985
2986 int SSH_get_clear_MAC_size(PTInstVar pvar)
2987 {
2988 if (SSHv1(pvar)) {
2989 return 0;
2990 } else {
2991 return CRYPT_get_receiver_MAC_size(pvar);
2992 }
2993 }
2994
2995 void SSH_notify_user_name(PTInstVar pvar)
2996 {
2997 try_send_user_name(pvar);
2998 }
2999
3000 void SSH_notify_cred(PTInstVar pvar)
3001 {
3002 try_send_credentials(pvar);
3003 }
3004
3005 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
3006 {
3007 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
3008 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
3009 init_memdump();
3010 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
3011 }
3012
3013 if (SSHv1(pvar)) {
3014 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
3015 return;
3016 }
3017
3018 while (buflen > 0) {
3019 int len =
3020 buflen >
3021 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
3022 unsigned char FAR *outmsg =
3023 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
3024
3025 set_uint32(outmsg, len);
3026
3027 if (pvar->ssh_state.compressing) {
3028 buf_ensure_size(&pvar->ssh_state.outbuf,
3029 &pvar->ssh_state.outbuflen,
3030 len + (len >> 6) + 50);
3031 pvar->ssh_state.compress_stream.next_in =
3032 pvar->ssh_state.precompress_outbuf;
3033 pvar->ssh_state.compress_stream.avail_in = 5;
3034 pvar->ssh_state.compress_stream.next_out =
3035 pvar->ssh_state.outbuf + 12;
3036 pvar->ssh_state.compress_stream.avail_out =
3037 pvar->ssh_state.outbuflen - 12;
3038
3039 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
3040 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3041 "Error compressing packet data");
3042 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
3043 return;
3044 }
3045
3046 pvar->ssh_state.compress_stream.next_in =
3047 (unsigned char FAR *) buf;
3048 pvar->ssh_state.compress_stream.avail_in = len;
3049
3050 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
3051 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3052 "Error compressing packet data");
3053 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
3054 return;
3055 }
3056 } else {
3057 memcpy(outmsg + 4, buf, len);
3058 }
3059
3060 finish_send_packet_special(pvar, 1);
3061
3062 buflen -= len;
3063 buf += len;
3064 }
3065
3066 } else { // for SSH2(yutaka)
3067 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
3068 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen, 0);
3069 }
3070
3071 }
3072
3073 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
3074 {
3075 int num_bytes = pvar->ssh_state.payload_datalen;
3076
3077 if (num_bytes > len) {
3078 num_bytes = len;
3079 }
3080
3081 if (!pvar->ssh_state.decompressing) {
3082 memcpy(dest,
3083 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
3084 num_bytes);
3085 pvar->ssh_state.payload_datastart += num_bytes;
3086 } else if (num_bytes > 0) {
3087 pvar->ssh_state.decompress_stream.next_out = dest;
3088 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
3089
3090 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
3091 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
3092 "Invalid compressed data in received packet");
3093 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
3094 return 0;
3095 }
3096 }
3097
3098 pvar->ssh_state.payload_datalen -= num_bytes;
3099
3100 return num_bytes;
3101 }
3102
3103 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
3104 {
3105 char buf[1024];
3106 char buf2[1024];
3107
3108 // added support of SSH2 packet compression (2005.7.10 yutaka)
3109 // support of "Compression delayed" (2006.6.23 maya)
3110 if (pvar->ssh_state.compressing ||
3111 pvar->ctos_compression == COMP_ZLIB ||
3112 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3113 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
3114 unsigned long total_out =
3115 pvar->ssh_state.compress_stream.total_out;
3116
3117 if (total_out > 0) {
3118 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3119 "level %d; ratio %.1f (%ld:%ld)");
3120 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3121 pvar->ssh_state.compression_level,
3122 ((double) total_in) / total_out, total_in,
3123 total_out);
3124 } else {
3125 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3126 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3127 pvar->ssh_state.compression_level);
3128 }
3129 } else {
3130 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3131 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
3132 }
3133
3134 // support of "Compression delayed" (2006.6.23 maya)
3135 if (pvar->ssh_state.decompressing ||
3136 pvar->stoc_compression == COMP_ZLIB ||
3137 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3138 unsigned long total_in =
3139 pvar->ssh_state.decompress_stream.total_in;
3140 unsigned long total_out =
3141 pvar->ssh_state.decompress_stream.total_out;
3142
3143 if (total_in > 0) {
3144 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3145 "level %d; ratio %.1f (%ld:%ld)");
3146 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3147 pvar->ssh_state.compression_level,
3148 ((double) total_out) / total_in, total_out,
3149 total_in);
3150 } else {
3151 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3152 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3153 pvar->ssh_state.compression_level);
3154 }
3155 } else {
3156 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3157 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
3158 }
3159
3160 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
3161 "Upstream %s; Downstream %s");
3162 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
3163 }
3164
3165 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
3166 {
3167 strncpy_s(dest, len,
3168 pvar->ssh_state.server_ID == NULL ? "Unknown"
3169 : pvar->ssh_state.server_ID,
3170 _TRUNCATE);
3171 }
3172
3173 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
3174 int len)
3175 {
3176 if (pvar->protocol_major == 0) {
3177 strncpy_s(dest, len, "Unknown", _TRUNCATE);
3178 } else {
3179 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
3180 pvar->protocol_minor);
3181 }
3182 }
3183
3184 void SSH_get_mac_info(PTInstVar pvar, char FAR * dest, int len)
3185 {
3186 UTIL_get_lang_msg("DLG_ABOUT_MAC_INFO", pvar,
3187 "%s to server, %s from server");
3188 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg,
3189 get_ssh2_mac_name(pvar->ctos_hmac),
3190 get_ssh2_mac_name(pvar->stoc_hmac));
3191 }