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