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 11021 - (show annotations) (download) (as text)
Sun Oct 22 04:13:04 2023 UTC (5 months, 2 weeks ago) by zmatsuo
File MIME type: text/x-csrc
File size: 282370 byte(s)
SCP送受信ダイアログのファイル名に漢字等が含まれていると送受信できない問題を修正

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