Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3221 by maya, Tue Mar 24 09:37:20 2009 UTC revision 3227 by maya, Tue Mar 24 15:10:33 2009 UTC
# Line 1  Line 1 
1  //  //
2  // buffer.c  // buffer.c
3  //  //
4    
5  #include <winsock2.h>  #include <winsock2.h>
6  #include <malloc.h>  #include <malloc.h>
7  #include "buffer.h"  #include "buffer.h"
8  #include "ttxssh.h"  #include "ttxssh.h"
9  #include "util.h"  #include "util.h"
10  #include <openssl/bn.h>  #include <openssl/bn.h>
11  #include <zlib.h>  #include <zlib.h>
12    
13  void buffer_clear(buffer_t *buf)  void buffer_clear(buffer_t *buf)
14  {  {
15          buf->offset = 0;          buf->offset = 0;
16          buf->len = 0;          buf->len = 0;
17  }  }
18    
19  buffer_t *buffer_init(void)  buffer_t *buffer_init(void)
20  {  {
21          void *ptr;          void *ptr;
22          buffer_t *buf;          buffer_t *buf;
23          int size = 4096;          int size = 4096;
24    
25          buf = malloc(sizeof(buffer_t));          buf = malloc(sizeof(buffer_t));
26          ptr = malloc(size);          ptr = malloc(size);
27          if (buf && ptr) {          if (buf && ptr) {
28                  memset(buf, 0, sizeof(buffer_t));                  memset(buf, 0, sizeof(buffer_t));
29                  memset(ptr, 0, size);                  memset(ptr, 0, size);
30                  buf->buf = ptr;                  buf->buf = ptr;
31                  buf->maxlen = size;                  buf->maxlen = size;
32                  buf->len = 0;                  buf->len = 0;
33                  buf->offset = 0;                  buf->offset = 0;
34    
35          } else {          } else {
36                  ptr = NULL; *(char *)ptr = 0;                  ptr = NULL; *(char *)ptr = 0;
37          }          }
38    
39          return (buf);          return (buf);
40  }  }
41    
42  void buffer_free(buffer_t * buf)  void buffer_free(buffer_t * buf)
43  {  {
44          if (buf != NULL) {          if (buf != NULL) {
45                  // セキュリティ対策 (2006.8.3 yutaka)                  // セキュリティ対策 (2006.8.3 yutaka)
46                  int len =  buffer_len(buf);                  int len =  buffer_len(buf);
47                  memset(buf->buf, 'x', len);                  memset(buf->buf, 'x', len);
48                  free(buf->buf);                  free(buf->buf);
49                  free(buf);                  free(buf);
50          }          }
51  }  }
52    
53  int buffer_append(buffer_t * buf, char *ptr, int size)  int buffer_append(buffer_t * buf, char *ptr, int size)
54  {  {
55          int n;          int n;
56          int ret = -1;          int ret = -1;
57          int newlen;          int newlen;
58    
59          for (;;) {          for (;;) {
60                  n = buf->offset + size;                  n = buf->offset + size;
61                  if (n < buf->maxlen) {                  if (n < buf->maxlen) {
62                          memcpy(buf->buf + buf->offset, ptr, size);                          memcpy(buf->buf + buf->offset, ptr, size);
63                          buf->offset += size;                          buf->offset += size;
64                          buf->len = buf->offset;                          buf->len = buf->offset;
65                          ret = 0;                          ret = 0;
66                          break;                          break;
67    
68                  } else {                  } else {
69                          // バッファが足りないので補充する。(2005.7.2 yutaka)                          // バッファが足りないので補充する。(2005.7.2 yutaka)
70                          newlen = buf->maxlen + size + 32*1024;                          newlen = buf->maxlen + size + 32*1024;
71                          if (newlen > 0xa00000) { // 1MB over is not supported                          if (newlen > 0xa00000) { // 1MB over is not supported
72                                  goto panic;                                  goto panic;
73                          }                          }
74                          buf->buf = realloc(buf->buf, newlen);                          buf->buf = realloc(buf->buf, newlen);
75                          if (buf->buf == NULL)                          if (buf->buf == NULL)
76                                  goto panic;                                  goto panic;
77                          buf->maxlen = newlen;                          buf->maxlen = newlen;
78                  }                  }
79          }          }
80    
81          return (ret);          return (ret);
82    
83  panic:  panic:
84          {          {
85          char *p = NULL;          char *p = NULL;
86          *p = 0; // application fault          *p = 0; // application fault
87          }          }
88    
89          return (ret);          return (ret);
90  }  }
91    
92  int buffer_append_length(buffer_t * msg, char *ptr, int size)  int buffer_append_length(buffer_t * msg, char *ptr, int size)
93  {  {
94          char buf[4];          char buf[4];
95          int val;          int val;
96          int ret = -1;          int ret = -1;
97    
98          val = htonl(size);          val = htonl(size);
99          memcpy(buf, &val, sizeof(val));          memcpy(buf, &val, sizeof(val));
100          ret = buffer_append(msg, buf, sizeof(buf));          ret = buffer_append(msg, buf, sizeof(buf));
101          if (ptr != NULL) {          if (ptr != NULL) {
102                  ret = buffer_append(msg, ptr, size);                  ret = buffer_append(msg, ptr, size);
103          }          }
104    
105          return (ret);          return (ret);
106  }  }
107    
108  void buffer_put_raw(buffer_t *msg, char *ptr, int size)  void buffer_put_raw(buffer_t *msg, char *ptr, int size)
109  {  {
110          int ret = -1;          int ret = -1;
111    
112          ret = buffer_append(msg, ptr, size);          ret = buffer_append(msg, ptr, size);
113  }  }
114    
115  // getting string buffer.  // getting string buffer.
116  // NOTE: You should free the return pointer if it's unused.  // NOTE: You should free the return pointer if it's unused.
117  // (2005.6.26 yutaka)  // (2005.6.26 yutaka)
118  char *buffer_get_string(char **data_ptr, int *buflen_ptr)  char *buffer_get_string(char **data_ptr, int *buflen_ptr)
119  {  {
120          char *data = *data_ptr;          char *data = *data_ptr;
121          char *ptr;          char *ptr;
122          int buflen;          int buflen;
123    
124          buflen = get_uint32_MSBfirst(data);          buflen = get_uint32_MSBfirst(data);
125          data += 4;          data += 4;
126          if (buflen <= 0)          if (buflen <= 0)
127                  return NULL;                  return NULL;
128    
129          ptr = malloc(buflen + 1);          ptr = malloc(buflen + 1);
130          if (ptr == NULL) {          if (ptr == NULL) {
131                  if (buflen_ptr != NULL)                  if (buflen_ptr != NULL)
132                          *buflen_ptr = 0;                          *buflen_ptr = 0;
133                  return NULL;                  return NULL;
134          }          }
135          memcpy(ptr, data, buflen);          memcpy(ptr, data, buflen);
136          ptr[buflen] = '\0'; // null-terminate          ptr[buflen] = '\0'; // null-terminate
137          data += buflen;          data += buflen;
138    
139          *data_ptr = data;          *data_ptr = data;
140          if (buflen_ptr != NULL)          if (buflen_ptr != NULL)
141                  *buflen_ptr = buflen;                  *buflen_ptr = buflen;
142    
143          return(ptr);          return(ptr);
144  }  }
145    
146  void buffer_put_string(buffer_t *msg, char *ptr, int size)  void buffer_put_string(buffer_t *msg, char *ptr, int size)
147  {  {
148          char buf[4];          char buf[4];
149          int val;          int val;
150          int ret = -1;          int ret = -1;
151    
152          // 「サイズ+文字列」で書き込む。サイズは4byteのbig-endian。          // 「サイズ+文字列」で書き込む。サイズは4byteのbig-endian。
153          val = htonl(size);          val = htonl(size);
154          memcpy(buf, &val, sizeof(val));          memcpy(buf, &val, sizeof(val));
155          ret = buffer_append(msg, buf, sizeof(buf));          ret = buffer_append(msg, buf, sizeof(buf));
156          if (ptr != NULL) {          if (ptr != NULL) {
157                  ret = buffer_append(msg, ptr, size);                  ret = buffer_append(msg, ptr, size);
158          }          }
159  }  }
160    
161  void buffer_put_char(buffer_t *msg, int value)  void buffer_put_char(buffer_t *msg, int value)
162  {  {
163          char ch = value;          char ch = value;
164    
165          buffer_append(msg, &ch, 1);          buffer_append(msg, &ch, 1);
166  }  }
167    
168  void buffer_put_padding(buffer_t *msg, int size)  void buffer_put_padding(buffer_t *msg, int size)
169  {  {
170          char ch = ' ';          char ch = ' ';
171          int i;          int i;
172    
173          for (i = 0 ; i < size ; i++) {          for (i = 0 ; i < size ; i++) {
174                  buffer_append(msg, &ch, 1);                  buffer_append(msg, &ch, 1);
175          }          }
176  }  }
177    
178  void buffer_put_int(buffer_t *msg, int value)  void buffer_put_int(buffer_t *msg, int value)
179  {  {
180          char buf[4];          char buf[4];
181    
182          set_uint32_MSBfirst(buf, value);          set_uint32_MSBfirst(buf, value);
183          buffer_append(msg, buf, sizeof(buf));          buffer_append(msg, buf, sizeof(buf));
184  }  }
185    
186  int buffer_len(buffer_t *msg)  int buffer_len(buffer_t *msg)
187  {  {
188          return (msg->len);          return (msg->len);
189  }  }
190    
191  char *buffer_ptr(buffer_t *msg)  char *buffer_ptr(buffer_t *msg)
192  {  {
193          return (msg->buf);          return (msg->buf);
194  }  }
195    
196  char *buffer_tail_ptr(buffer_t *msg)  char *buffer_tail_ptr(buffer_t *msg)
197  {  {
198          return (char *)(msg->buf + msg->offset);          return (char *)(msg->buf + msg->offset);
199  }  }
200    
201  int buffer_overflow_verify(buffer_t *msg, int len)  int buffer_overflow_verify(buffer_t *msg, int len)
202  {  {
203          if (msg->offset + len > msg->maxlen) {          if (msg->offset + len > msg->maxlen) {
204                  return -1;  // error                  return -1;  // error
205          }          }
206          return 0; // no problem          return 0; // no problem
207  }  }
208    
209  // for SSH1  // for SSH1
210  void buffer_put_bignum(buffer_t *buffer, BIGNUM *value)  void buffer_put_bignum(buffer_t *buffer, BIGNUM *value)
211  {  {
212          unsigned int bits, bin_size;          unsigned int bits, bin_size;
213          unsigned char *buf;          unsigned char *buf;
214          int oi;          int oi;
215          char msg[2];          char msg[2];
216                    
217          bits = BN_num_bits(value);          bits = BN_num_bits(value);
218          bin_size = (bits + 7) / 8;          bin_size = (bits + 7) / 8;
219          buf = malloc(bin_size);          buf = malloc(bin_size);
220          if (buf == NULL) {          if (buf == NULL) {
221                  *buf = 0;                  *buf = 0;
222                  goto error;                  goto error;
223          }          }
224    
225          buf[0] = '\0';          buf[0] = '\0';
226          /* Get the value of in binary */          /* Get the value of in binary */
227          oi = BN_bn2bin(value, buf);          oi = BN_bn2bin(value, buf);
228          if (oi != bin_size) {          if (oi != bin_size) {
229                  goto error;                  goto error;
230          }          }
231    
232          /* Store the number of bits in the buffer in two bytes, msb first. */          /* Store the number of bits in the buffer in two bytes, msb first. */
233          set_ushort16_MSBfirst(msg, bits);          set_ushort16_MSBfirst(msg, bits);
234          buffer_append(buffer, msg, 2);          buffer_append(buffer, msg, 2);
235    
236          /* Store the binary data. */          /* Store the binary data. */
237          buffer_append(buffer, (char *)buf, oi);          buffer_append(buffer, (char *)buf, oi);
238    
239  error:  error:
240          free(buf);          free(buf);
241  }  }
242    
243  // for SSH2  // for SSH2
244  void buffer_put_bignum2(buffer_t *msg, BIGNUM *value)  void buffer_put_bignum2(buffer_t *msg, BIGNUM *value)
245  {  {
246          unsigned int bytes;          unsigned int bytes;
247          unsigned char *buf;          unsigned char *buf;
248          int oi;          int oi;
249          unsigned int hasnohigh = 0;          unsigned int hasnohigh = 0;
250    
251          bytes = BN_num_bytes(value) + 1; /* extra padding byte */          bytes = BN_num_bytes(value) + 1; /* extra padding byte */
252          buf = malloc(bytes);          buf = malloc(bytes);
253          if (buf == NULL) {          if (buf == NULL) {
254                  *buf = 0;                  *buf = 0;
255                  goto error;                  goto error;
256          }          }
257    
258          buf[0] = '\0';          buf[0] = '\0';
259          /* Get the value of in binary */          /* Get the value of in binary */
260          oi = BN_bn2bin(value, buf+1);          oi = BN_bn2bin(value, buf+1);
261          hasnohigh = (buf[1] & 0x80) ? 0 : 1;          hasnohigh = (buf[1] & 0x80) ? 0 : 1;
262          buffer_put_string(msg, buf+hasnohigh, bytes-hasnohigh);          buffer_put_string(msg, buf+hasnohigh, bytes-hasnohigh);
263          //memset(buf, 0, bytes);          //memset(buf, 0, bytes);
264    
265  error:  error:
266          free(buf);          free(buf);
267  }  }
268    
269  void buffer_get_bignum2(char **data, BIGNUM *value)  void buffer_get_bignum2(char **data, BIGNUM *value)
270  {  {
271          char *buf = *data;          char *buf = *data;
272          int len;          int len;
273    
274          len = get_uint32_MSBfirst(buf);          len = get_uint32_MSBfirst(buf);
275          buf += 4;          buf += 4;
276          BN_bin2bn(buf, len, value);          BN_bin2bn(buf, len, value);
277          buf += len;          buf += len;
278    
279          *data = buf;          *data = buf;
280  }  }
281    
282  void buffer_dump(FILE *fp, buffer_t *buf)  void buffer_dump(FILE *fp, buffer_t *buf)
283  {  {
284          int i;          int i;
285          char *ch = buffer_ptr(buf);          char *ch = buffer_ptr(buf);
286    
287          for (i = 0 ; i < buffer_len(buf) ; i++) {          for (i = 0 ; i < buffer_len(buf) ; i++) {
288                  fprintf(fp, "%02x", ch[i] & 0xff);                  fprintf(fp, "%02x", ch[i] & 0xff);
289                  if (i % 16 == 15)                  if (i % 16 == 15)
290                          fprintf(fp, "\n");                          fprintf(fp, "\n");
291                  else if (i % 2 == 1)                  else if (i % 2 == 1)
292                          fprintf(fp, " ");                          fprintf(fp, " ");
293          }          }
294          fprintf(fp, "\n");          fprintf(fp, "\n");
295  }  }
296    
297  // バッファのオフセットを進める。  // バッファのオフセットを進める。
298  void buffer_consume(buffer_t *buf, int shift_byte)  void buffer_consume(buffer_t *buf, int shift_byte)
299  {  {
300          int n;          int n;
301    
302          n = buf->offset + shift_byte;          n = buf->offset + shift_byte;
303          if (n < buf->maxlen) {          if (n < buf->maxlen) {
304                  buf->offset += shift_byte;                  buf->offset += shift_byte;
305          } else {          } else {
306                  // TODO: fatal error                  // TODO: fatal error
307          }          }
308  }  }
309    
310  // パケットの圧縮  // パケットの圧縮
311  int buffer_compress(z_stream *zstream, char *payload, int len, buffer_t *compbuf)  int buffer_compress(z_stream *zstream, char *payload, int len, buffer_t *compbuf)
312  {  {
313          unsigned char buf[4096];          unsigned char buf[4096];
314          int status;          int status;
315    
316          // input buffer          // input buffer
317          zstream->next_in = payload;          zstream->next_in = payload;
318          zstream->avail_in = len;          zstream->avail_in = len;
319    
320          do {          do {
321                  // output buffer                  // output buffer
322                  zstream->next_out = buf;                  zstream->next_out = buf;
323                  zstream->avail_out = sizeof(buf);                  zstream->avail_out = sizeof(buf);
324    
325                  // バッファを圧縮する。圧縮すると、逆にサイズが大きくなることも考慮すること。                  // バッファを圧縮する。圧縮すると、逆にサイズが大きくなることも考慮すること。
326                  status = deflate(zstream, Z_PARTIAL_FLUSH);                  status = deflate(zstream, Z_PARTIAL_FLUSH);
327                  if (status == Z_OK) {                  if (status == Z_OK) {
328                          buffer_append(compbuf, buf, sizeof(buf) - zstream->avail_out);                          buffer_append(compbuf, buf, sizeof(buf) - zstream->avail_out);
329                  } else {                  } else {
330                          return -1; // error                          return -1; // error
331                  }                  }
332          } while (zstream->avail_out == 0);          } while (zstream->avail_out == 0);
333    
334          return 0; // success          return 0; // success
335  }  }
336    
337  // パケットの展開  // パケットの展開
338  int buffer_decompress(z_stream *zstream, char *payload, int len, buffer_t *compbuf)  int buffer_decompress(z_stream *zstream, char *payload, int len, buffer_t *compbuf)
339  {  {
340          unsigned char buf[4096];          unsigned char buf[4096];
341          int status;          int status;
342    
343          // input buffer          // input buffer
344          zstream->next_in = payload;          zstream->next_in = payload;
345          zstream->avail_in = len;          zstream->avail_in = len;
346    
347          do {          do {
348                  // output buffer                  // output buffer
349                  zstream->next_out = buf;                  zstream->next_out = buf;
350                  zstream->avail_out = sizeof(buf);                  zstream->avail_out = sizeof(buf);
351    
352                  // バッファを展開する。                  // バッファを展開する。
353                  status = inflate(zstream, Z_PARTIAL_FLUSH);                  status = inflate(zstream, Z_PARTIAL_FLUSH);
354                  if (status == Z_OK) {                  if (status == Z_OK) {
355                          buffer_append(compbuf, buf, sizeof(buf) - zstream->avail_out);                          buffer_append(compbuf, buf, sizeof(buf) - zstream->avail_out);
356    
357                  } else if (status == Z_OK) {                  } else if (status == Z_OK) {
358                          break;                          break;
359    
360                  } else {                  } else {
361                          return -1; // error                          return -1; // error
362                  }                  }
363          } while (zstream->avail_out == 0);          } while (zstream->avail_out == 0);
364    
365          return 0; // success          return 0; // success
366  }  }

Legend:
Removed from v.3221  
changed lines
  Added in v.3227

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