Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/ttssh2/ttxssh/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9048 - (hide annotations) (download) (as text)
Wed Dec 16 12:24:13 2020 UTC (3 years, 3 months ago) by nmaya
File MIME type: text/x-csrc
File size: 13846 byte(s)
ソースファイルの著作権表記の "最後の発行の年" を削除

ticket #40996
1 doda 6841 /*
2 nmaya 9048 * Copyright (C) 2004- TeraTerm Project
3 doda 6841 * All rights reserved.
4     *
5     * Redistribution and use in source and binary forms, with or without
6     * modification, are permitted provided that the following conditions
7     * are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     * 2. Redistributions in binary form must reproduce the above copyright
12     * notice, this list of conditions and the following disclaimer in the
13     * documentation and/or other materials provided with the distribution.
14     * 3. The name of the author may not be used to endorse or promote products
15     * derived from this software without specific prior written permission.
16     *
17     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28 maya 3227 //
29     // buffer.c
30     //
31    
32     #include <winsock2.h>
33     #include <malloc.h>
34     #include "buffer.h"
35     #include "ttxssh.h"
36     #include "util.h"
37     #include <openssl/bn.h>
38 maya 4314 #include <openssl/ec.h>
39 maya 3227 #include <zlib.h>
40    
41 yutakapon 4928 // �o�b�t�@���I�t�Z�b�g�����������A���������������������������B
42     // Tera Term(TTSSH)�I���W�i�������B
43     void buffer_rewind(buffer_t *buf)
44     {
45     buf->offset = 0;
46     }
47    
48 maya 3227 void buffer_clear(buffer_t *buf)
49     {
50     buf->offset = 0;
51     buf->len = 0;
52     }
53    
54     buffer_t *buffer_init(void)
55     {
56     void *ptr;
57     buffer_t *buf;
58 doda 6711 unsigned int size = 4096;
59 maya 3227
60     buf = malloc(sizeof(buffer_t));
61     ptr = malloc(size);
62     if (buf && ptr) {
63     memset(buf, 0, sizeof(buffer_t));
64     memset(ptr, 0, size);
65     buf->buf = ptr;
66     buf->maxlen = size;
67     buf->len = 0;
68     buf->offset = 0;
69    
70     } else {
71     ptr = NULL; *(char *)ptr = 0;
72     }
73    
74     return (buf);
75     }
76    
77     void buffer_free(buffer_t * buf)
78     {
79     if (buf != NULL) {
80     // �Z�L�����e�B���� (2006.8.3 yutaka)
81     int len = buffer_len(buf);
82 yutakapon 6229 SecureZeroMemory(buf->buf, len);
83 maya 3227 free(buf->buf);
84     free(buf);
85     }
86     }
87    
88 yutakapon 5545 // �o�b�t�@�������g�����s���B
89     // return: �g���O���o�b�t�@�|�C���^�[
90 doda 6711 void *buffer_append_space(buffer_t * buf, size_t size)
91 yutakapon 4492 {
92 doda 6711 unsigned int n;
93     unsigned int newlen;
94 yutakapon 5545 void *p;
95 yutakapon 4492
96     n = buf->offset + size;
97     if (n < buf->maxlen) {
98     //
99     } else {
100     // �o�b�t�@�����������������[�����B(2005.7.2 yutaka)
101 doda 6706 newlen = buf->maxlen + size + BUFFER_INCREASE_MARGIN;
102     if (newlen > BUFFER_SIZE_MAX) {
103 yutakapon 4492 goto panic;
104     }
105     buf->buf = realloc(buf->buf, newlen);
106     if (buf->buf == NULL)
107     goto panic;
108     buf->maxlen = newlen;
109     }
110    
111 yutakapon 5545 p = buf->buf + buf->offset;
112     //buf->offset += size;
113     buf->len = buf->offset + size;
114 yutakapon 4492
115 yutakapon 5545 return (p);
116    
117 yutakapon 4492 panic:
118 doda 7015 abort();
119 yutakapon 5545 return (NULL);
120 yutakapon 4492 }
121    
122 maya 3227 int buffer_append(buffer_t * buf, char *ptr, int size)
123     {
124 doda 6711 unsigned int n;
125 maya 3227 int ret = -1;
126 doda 6711 unsigned int newlen;
127 maya 3227
128     for (;;) {
129     n = buf->offset + size;
130     if (n < buf->maxlen) {
131     memcpy(buf->buf + buf->offset, ptr, size);
132     buf->offset += size;
133     buf->len = buf->offset;
134     ret = 0;
135     break;
136    
137     } else {
138     // �o�b�t�@�����������������[�����B(2005.7.2 yutaka)
139 doda 6706 newlen = buf->maxlen + size + BUFFER_INCREASE_MARGIN;
140     if (newlen > BUFFER_SIZE_MAX) {
141 maya 3227 goto panic;
142     }
143     buf->buf = realloc(buf->buf, newlen);
144     if (buf->buf == NULL)
145     goto panic;
146     buf->maxlen = newlen;
147     }
148     }
149    
150     return (ret);
151    
152     panic:
153 doda 7015 abort();
154 maya 3227 return (ret);
155     }
156    
157     int buffer_append_length(buffer_t * msg, char *ptr, int size)
158     {
159     char buf[4];
160     int val;
161     int ret = -1;
162    
163     val = htonl(size);
164     memcpy(buf, &val, sizeof(val));
165     ret = buffer_append(msg, buf, sizeof(buf));
166     if (ptr != NULL) {
167     ret = buffer_append(msg, ptr, size);
168     }
169    
170     return (ret);
171     }
172    
173     void buffer_put_raw(buffer_t *msg, char *ptr, int size)
174     {
175     int ret = -1;
176    
177     ret = buffer_append(msg, ptr, size);
178     }
179    
180 doda 6711 int buffer_get_ret(buffer_t *msg, void *buf, size_t len)
181 yutakapon 4929 {
182     if (len > msg->len - msg->offset) {
183     // TODO: �G���[����
184 doda 6711 OutputDebugPrintf("buffer_get_ret: trying to get more bytes %u than in buffer %u",
185 yutakapon 4929 len, msg->len - msg->offset);
186     return (-1);
187     }
188     memcpy(buf, msg->buf + msg->offset, len);
189     msg->offset += len;
190     return (0);
191 yutakapon 4928 }
192    
193 doda 6711 int buffer_get_int_ret(unsigned int *ret, buffer_t *msg)
194 yutakapon 4929 {
195     unsigned char buf[4];
196    
197     if (buffer_get_ret(msg, (char *) buf, 4) == -1)
198     return (-1);
199     if (ret != NULL)
200     *ret = get_uint32(buf);
201     return (0);
202 yutakapon 4928 }
203    
204 doda 6711 unsigned int buffer_get_int(buffer_t *msg)
205 yutakapon 4928 {
206 doda 6711 unsigned int ret = 0;
207 yutakapon 4928
208     if (buffer_get_int_ret(&ret, msg) == -1) {
209     // TODO: �G���[����
210 doda 6808 logprintf(LOG_LEVEL_ERROR, "buffer_get_int: buffer error");
211 yutakapon 4928 }
212     return (ret);
213     }
214    
215 yutakapon 4929 int buffer_get_char_ret(char *ret, buffer_t *msg)
216     {
217     if (buffer_get_ret(msg, ret, 1) == -1)
218     return (-1);
219     return (0);
220 yutakapon 4928 }
221    
222     int buffer_get_char(buffer_t *msg)
223     {
224     char ch;
225    
226     if (buffer_get_char_ret(&ch, msg) == -1) {
227     // TODO: �G���[����
228     OutputDebugPrintf("buffer_get_char: buffer error");
229     }
230     return (unsigned char)ch;
231     }
232    
233 maya 3227 // getting string buffer.
234     // NOTE: You should free the return pointer if it's unused.
235     // (2005.6.26 yutaka)
236     char *buffer_get_string(char **data_ptr, int *buflen_ptr)
237     {
238     char *data = *data_ptr;
239     char *ptr;
240 yutakapon 4152 unsigned int buflen;
241 maya 3227
242     buflen = get_uint32_MSBfirst(data);
243     data += 4;
244 yutakapon 4152 // buflen == 0�����������A'\0'�����m�����Adata_ptr���i���A���^�[�������B
245     // if (buflen <= 0)
246     // return NULL;
247 maya 3227
248     ptr = malloc(buflen + 1);
249     if (ptr == NULL) {
250 zmatsuo 7649 logprintf(LOG_LEVEL_ERROR, "%s: malloc failed.", __FUNCTION__);
251 maya 3227 if (buflen_ptr != NULL)
252     *buflen_ptr = 0;
253     return NULL;
254     }
255     memcpy(ptr, data, buflen);
256     ptr[buflen] = '\0'; // null-terminate
257     data += buflen;
258    
259     *data_ptr = data;
260     if (buflen_ptr != NULL)
261     *buflen_ptr = buflen;
262    
263     return(ptr);
264     }
265    
266 yutakapon 4929 // buffer_get_string() �� buffer_t ���B�{������������ OpenSSH �X�^�C���B
267     // NOTE: You should free the return pointer if it's unused.
268     void *buffer_get_string_msg(buffer_t *msg, int *buflen_ptr)
269     {
270     char *data, *olddata;
271 yutakapon 5837 void *ret = NULL;
272 yutakapon 4929 int off;
273 yutakapon 5837 int len, datalen;
274 yutakapon 4929
275 yutakapon 5837 // Check size
276     len = buffer_remain_len(msg);
277     if (len < 4)
278     goto error;
279    
280 yutakapon 4929 data = olddata = buffer_tail_ptr(msg);
281 yutakapon 5837 datalen = get_uint32_MSBfirst(data);
282     if (len - 4 < datalen)
283     goto error;
284    
285 yutakapon 4929 ret = buffer_get_string(&data, buflen_ptr);
286     off = data - olddata;
287     msg->offset += off;
288 yutakapon 5837
289     error:;
290 yutakapon 4929 return (ret);
291     }
292    
293 maya 3227 void buffer_put_string(buffer_t *msg, char *ptr, int size)
294     {
295     char buf[4];
296     int val;
297     int ret = -1;
298    
299     // �u�T�C�Y�{�������v�����������B�T�C�Y��4byte��big-endian�B
300     val = htonl(size);
301     memcpy(buf, &val, sizeof(val));
302     ret = buffer_append(msg, buf, sizeof(buf));
303     if (ptr != NULL) {
304     ret = buffer_append(msg, ptr, size);
305     }
306     }
307    
308 yutakapon 5545 void buffer_put_cstring(buffer_t *msg, char *ptr)
309     {
310     buffer_put_string(msg, ptr, strlen(ptr));
311     }
312    
313 maya 3227 void buffer_put_char(buffer_t *msg, int value)
314     {
315     char ch = value;
316    
317     buffer_append(msg, &ch, 1);
318     }
319    
320     void buffer_put_padding(buffer_t *msg, int size)
321     {
322     char ch = ' ';
323     int i;
324    
325     for (i = 0 ; i < size ; i++) {
326     buffer_append(msg, &ch, 1);
327     }
328     }
329    
330     void buffer_put_int(buffer_t *msg, int value)
331     {
332     char buf[4];
333    
334     set_uint32_MSBfirst(buf, value);
335     buffer_append(msg, buf, sizeof(buf));
336     }
337    
338     int buffer_len(buffer_t *msg)
339     {
340     return (msg->len);
341     }
342    
343 yutakapon 4929 // ���������������������c�����T�C�Y�������B�{������������ OpenSSH �X�^�C���B
344     int buffer_remain_len(buffer_t *msg)
345     {
346     return (msg->len - msg->offset);
347     }
348    
349 yutakapon 4498 // buffer_append() �� buffer_append_space() �����b�Z�[�W�o�b�t�@���������s�����A
350     // ������ realloc() �������o�b�t�@�|�C���^���������������������������B
351     // ���b�Z�[�W�o�b�t�@���|�C���^���������������A�o�b�t�@������������������
352     // �s�����������ABOF���������B
353 maya 3227 char *buffer_ptr(buffer_t *msg)
354     {
355     return (msg->buf);
356     }
357    
358     char *buffer_tail_ptr(buffer_t *msg)
359     {
360     return (char *)(msg->buf + msg->offset);
361     }
362    
363     int buffer_overflow_verify(buffer_t *msg, int len)
364     {
365     if (msg->offset + len > msg->maxlen) {
366     return -1; // error
367     }
368     return 0; // no problem
369     }
370    
371     // for SSH1
372     void buffer_put_bignum(buffer_t *buffer, BIGNUM *value)
373     {
374     unsigned int bits, bin_size;
375     unsigned char *buf;
376     int oi;
377     char msg[2];
378    
379     bits = BN_num_bits(value);
380     bin_size = (bits + 7) / 8;
381     buf = malloc(bin_size);
382     if (buf == NULL) {
383     *buf = 0;
384     goto error;
385     }
386    
387     buf[0] = '\0';
388     /* Get the value of in binary */
389     oi = BN_bn2bin(value, buf);
390     if (oi != bin_size) {
391     goto error;
392     }
393    
394     /* Store the number of bits in the buffer in two bytes, msb first. */
395     set_ushort16_MSBfirst(msg, bits);
396     buffer_append(buffer, msg, 2);
397    
398     /* Store the binary data. */
399     buffer_append(buffer, (char *)buf, oi);
400    
401     error:
402     free(buf);
403     }
404    
405     // for SSH2
406     void buffer_put_bignum2(buffer_t *msg, BIGNUM *value)
407     {
408     unsigned int bytes;
409     unsigned char *buf;
410     int oi;
411     unsigned int hasnohigh = 0;
412    
413     bytes = BN_num_bytes(value) + 1; /* extra padding byte */
414     buf = malloc(bytes);
415     if (buf == NULL) {
416     *buf = 0;
417     goto error;
418     }
419    
420     buf[0] = '\0';
421     /* Get the value of in binary */
422     oi = BN_bn2bin(value, buf+1);
423     hasnohigh = (buf[1] & 0x80) ? 0 : 1;
424     buffer_put_string(msg, buf+hasnohigh, bytes-hasnohigh);
425     //memset(buf, 0, bytes);
426    
427     error:
428     free(buf);
429     }
430    
431     void buffer_get_bignum2(char **data, BIGNUM *value)
432     {
433     char *buf = *data;
434     int len;
435    
436     len = get_uint32_MSBfirst(buf);
437     buf += 4;
438     BN_bin2bn(buf, len, value);
439     buf += len;
440    
441     *data = buf;
442     }
443    
444 yutakapon 5545 void buffer_get_bignum2_msg(buffer_t *msg, BIGNUM *value)
445     {
446     char *data, *olddata;
447     int off;
448    
449     data = olddata = buffer_tail_ptr(msg);
450     buffer_get_bignum2(&data, value);
451     off = data - olddata;
452     msg->offset += off;
453     }
454    
455 maya 5056 void buffer_get_bignum_SECSH(buffer_t *buffer, BIGNUM *value)
456     {
457     char *buf;
458 doda 6711 unsigned int bits, bytes;
459 maya 5056
460     bits = buffer_get_int(buffer);
461     bytes = (bits + 7) / 8;
462    
463     if ((buffer->len - buffer->offset) < bytes) {
464     return;
465     }
466     buf = buffer->buf + buffer->offset;
467     if ((*buf & 0x80) != 0) {
468     char *tmp = (char *)malloc(bytes + 1);
469     tmp[0] = '\0';
470     memcpy(tmp + 1, buf, bytes);
471     BN_bin2bn(tmp, bytes + 1, value);
472     free(tmp);
473     }
474     else {
475     BN_bin2bn(buf, bytes, value);
476     }
477    
478     buffer->offset += bytes;
479     }
480    
481 maya 4314 void buffer_put_ecpoint(buffer_t *msg, const EC_GROUP *curve, const EC_POINT *point)
482     {
483     unsigned char *buf = NULL;
484     size_t len;
485     BN_CTX *bnctx;
486    
487     /* Determine length */
488     bnctx = BN_CTX_new();
489     len = EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
490     NULL, 0, bnctx);
491     /* Convert */
492     buf = malloc(len);
493     if (buf == NULL) {
494     *buf = 0;
495     goto error;
496     }
497     if (EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
498     buf, len, bnctx) != len) {
499     goto error;
500     }
501     /* Append */
502     buffer_put_string(msg, buf, len);
503    
504     error:
505     free(buf);
506     BN_CTX_free(bnctx);
507     }
508    
509     void buffer_get_ecpoint(char **data, const EC_GROUP *curve, EC_POINT *point)
510     {
511     char *buf = *data;
512     size_t len;
513     BN_CTX *bnctx;
514    
515     bnctx = BN_CTX_new();
516    
517     len = get_uint32_MSBfirst(buf);
518     buf += 4;
519     EC_POINT_oct2point(curve, point, buf, len, bnctx);
520     buf += len;
521    
522     *data = buf;
523    
524     BN_CTX_free(bnctx);
525     }
526    
527 yutakapon 5545 void buffer_get_ecpoint_msg(buffer_t *msg, const EC_GROUP *curve, EC_POINT *point)
528     {
529     char *data, *olddata;
530     int off;
531    
532     data = olddata = buffer_tail_ptr(msg);
533     buffer_get_ecpoint(&data, curve, point);
534     off = data - olddata;
535     msg->offset += off;
536     }
537    
538 maya 3227 void buffer_dump(FILE *fp, buffer_t *buf)
539     {
540     int i;
541     char *ch = buffer_ptr(buf);
542    
543     for (i = 0 ; i < buffer_len(buf) ; i++) {
544     fprintf(fp, "%02x", ch[i] & 0xff);
545     if (i % 16 == 15)
546     fprintf(fp, "\n");
547     else if (i % 2 == 1)
548     fprintf(fp, " ");
549     }
550     fprintf(fp, "\n");
551     }
552    
553     // �o�b�t�@���I�t�Z�b�g���i�����B
554 doda 6711 void buffer_consume(buffer_t *buf, size_t shift_byte)
555 maya 3227 {
556 yutakapon 5545 if (shift_byte > buf->len - buf->offset) {
557     // TODO: fatal error
558     } else {
559     buf->offset += shift_byte;
560     // len�����������B
561     }
562     }
563 maya 3227
564 yutakapon 5545 // �o�b�t�@���������k�������B
565 doda 6711 void buffer_consume_end(buffer_t *buf, size_t shift_byte)
566 yutakapon 5545 {
567     if (shift_byte > buf->len - buf->offset) {
568     // TODO: fatal error
569 maya 3227 } else {
570 yutakapon 5545 buf->len -= shift_byte;
571     // offset�����������B
572 maya 3227 }
573     }
574    
575 yutakapon 5545
576 maya 3227 // �p�P�b�g�����k
577     int buffer_compress(z_stream *zstream, char *payload, int len, buffer_t *compbuf)
578     {
579     unsigned char buf[4096];
580     int status;
581    
582     // input buffer
583     zstream->next_in = payload;
584     zstream->avail_in = len;
585    
586     do {
587     // output buffer
588     zstream->next_out = buf;
589     zstream->avail_out = sizeof(buf);
590    
591     // �o�b�t�@�����k�����B���k�������A�t���T�C�Y�������������������l�����������B
592     status = deflate(zstream, Z_PARTIAL_FLUSH);
593     if (status == Z_OK) {
594     buffer_append(compbuf, buf, sizeof(buf) - zstream->avail_out);
595     } else {
596     return -1; // error
597     }
598     } while (zstream->avail_out == 0);
599    
600     return 0; // success
601     }
602    
603     // �p�P�b�g���W�J
604     int buffer_decompress(z_stream *zstream, char *payload, int len, buffer_t *compbuf)
605     {
606     unsigned char buf[4096];
607     int status;
608    
609     // input buffer
610     zstream->next_in = payload;
611     zstream->avail_in = len;
612    
613     do {
614     // output buffer
615     zstream->next_out = buf;
616     zstream->avail_out = sizeof(buf);
617    
618     // �o�b�t�@���W�J�����B
619     status = inflate(zstream, Z_PARTIAL_FLUSH);
620     if (status == Z_OK) {
621     buffer_append(compbuf, buf, sizeof(buf) - zstream->avail_out);
622    
623     } else if (status == Z_OK) {
624     break;
625    
626     } else {
627     return -1; // error
628     }
629     } while (zstream->avail_out == 0);
630    
631     return 0; // success
632     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26