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 6813 - (show annotations) (download) (as text)
Wed Jun 21 10:08:55 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 261890 byte(s)
session_settings.LogLevel を外に見せないようにする為、LogLevel() マクロ経由でアクセスするようにした。

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