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 6657 - (show annotations) (download) (as text)
Thu Mar 23 12:55:00 2017 UTC (7 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 262084 byte(s)
SSH2 メッセージ 60 番の処理を変更

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