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