Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9255 - (show annotations) (download) (as text)
Wed May 19 14:11:26 2021 UTC (2 years, 9 months ago) by nmaya
File MIME type: text/x-csrc
File size: 281293 byte(s)
SSH2 暗号化方式 chacha20-poly1305@openssh.com をサポート

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