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