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 7011 - (show annotations) (download) (as text)
Tue Dec 26 09:13:38 2017 UTC (6 years, 3 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 261165 byte(s)
必須のメッセージは常に処理されるように SSH2_dispatch_init() 内で有効にする。

対象メッセージ:

・SSH2_MSG_DISCONNECT
・SSH2_MSG_IGNORE
・SSH2_MSG_DEBUG
・SSH2_MSG_UNIMPLEMENTED

RFC 4253 では、これらの Additional Messages について以下の記述がある。

| 11.  Additional Messages
|
|    Either party may send any of the following messages at any time.

RFC 4253 では SSH2_MSG_IGNORE, SSH2_MSG_DISCONNECT, SSH2_MSG_DEBUG は
処理が出来る必要がある。(MUST understand / MUST be able to process)
これらのメッセージを確実に処理する為に、SSH2_dispatch_init() 内で
ハンドラを有効にするようにした。

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