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