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 8086 - (show annotations) (download) (as text)
Sat Sep 7 12:18:28 2019 UTC (4 years, 7 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 274931 byte(s)
チケット38959
ユーザ認証ダイアログの表示タイミングをknown_hostsダイアログの後に変更した。

branches/ttssh_improvedからリビジョン8027をマージ:
ProxyやNAT経由でサーバに接続できない場合、すでに切断状態にも関わらず、
認証ダイアログが表示されたままとなる問題を修正した。



........

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