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