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 6983 - (show annotations) (download) (as text)
Sat Nov 25 15:26:35 2017 UTC (6 years, 4 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 267712 byte(s)
padding 長の取得関連を修正

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