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 6958 - (show annotations) (download) (as text)
Tue Oct 24 12:05:11 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 267181 byte(s)
SSH 接続で通知する端末速度の値を設定可能にした。 #37598

TELNET TERMINAL SPEED OPTION と共通の設定にする為、設定は [Tera Term]
セクションに置く。

設定例:

[Tera Term]
TerminalSpeed=38400		; In/Out 共に 38400bps
; TerminalSped=38400,9600	; In が38400bps, Out が 9600bps

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