Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9210 - (show annotations) (download) (as text)
Sat Apr 17 08:36:59 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 280309 byte(s)
ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート

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