commit 177ba0f8b4265d09c321d6903eeab040faeca430 Author: Zack Weinberg zackw@cmu.edu Date: Mon Apr 23 14:49:52 2012 -0700
Thorough spring-cleaning on pdfSteg.cc; less thorough on swfSteg.cc and some other headers. Add beginnings of unit tests for pdfSteg. --- Makefile.am | 1 + src/steg/pdfSteg.cc | 389 +++++++++++++----------------------------- src/steg/pdfSteg.h | 38 +++-- src/steg/swfSteg.cc | 18 +-- src/steg/swfSteg.h | 23 +--- src/steg/zpack.h | 11 +- src/test/tinytest_macros.h | 8 +- src/test/unittest_pdfsteg.cc | 82 +++++++++ src/util.cc | 3 - src/util.h | 3 + 10 files changed, 249 insertions(+), 327 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 6ba1b51..86ed489 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,6 +49,7 @@ stegotorus_SOURCES = \
UTGROUPS = \ src/test/unittest_crypt.cc \ + src/test/unittest_pdfsteg.cc \ src/test/unittest_socks.cc \ src/test/unittest_config.cc \ src/test/unittest_transfer.cc diff --git a/src/steg/pdfSteg.cc b/src/steg/pdfSteg.cc index c67b0f8..3b4bbf0 100644 --- a/src/steg/pdfSteg.cc +++ b/src/steg/pdfSteg.cc @@ -1,7 +1,13 @@ -#include "payloads.h" +#include "util.h" #include "pdfSteg.h" +#include "connections.h" +#include "payloads.h" +#include <event2/buffer.h> + +/* pdfSteg: A PDF-based steganography module */
-void buf_dump(unsigned char* buf, int len, FILE *out); +#define PDF_DELIMITER '?' +#define PDF_DELIMITER2 '.'
#define STREAM_BEGIN ">>stream" #define STREAM_BEGIN_SIZE 8 @@ -10,45 +16,42 @@ void buf_dump(unsigned char* buf, int len, FILE *out);
#define DEBUG
- /* - * pdfSteg: A PDF-based steganography module - * - */ - - -/* - * addDelimiter processes the input buffer (inbuf) of length inbuflen, - * copies it to output buffer (outbuf) of size outbufsize, + * pdf_add_delimiter processes the input buffer (inbuf) of length + * inbuflen, copies it to output buffer (outbuf) of size outbufsize, * and adds a two-char-long, end-of-data pattern at the end of outbuf * based on delimiter1 and delimiter2. * * The end-of-data pattern consists of delimiter1 followed by a char * that is not delimiter1. Thus, delimiter1 and delimiter2 must be * different. - * - * If delimiter1 appears in the input buffer, addDelimiter puts two - * delimiter1 char in output buffer (to enable removeDelimiter to perform - * the back transformation) * - * addDelimiter returns the length of the data written to outbuf, including - * the end-of-data pattern, if the transformation succeeds; - * otherwise, it returns -1 + * If delimiter1 appears in the input buffer, pdf_add_delimiter puts two + * delimiter1 characters in the output buffer, so that the transformation + * is reversible. + * + * pdf_add_delimiter returns the length of the data written to outbuf, + * including the end-of-data pattern, if the transformation succeeds; + * otherwise, it returns -1. * */ -int -addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, - const char delimiter1, const char delimiter2) +ssize_t +pdf_add_delimiter(const char *inbuf, size_t inbuflen, + char *outbuf, size_t outbuflen, + const char delimiter1, const char delimiter2) { - int cnt; - char *ibp, ic, rc; + size_t cnt; + const char *ibp; + char ic, rc;
- if (delimiter1 == delimiter2) return -1; + log_assert(delimiter1 != delimiter2); + if (inbuflen > SIZE_T_CEILING || outbuflen > SIZE_T_CEILING) + return -1;
cnt = 0; ibp = inbuf; - while ((ibp-inbuf)<inbuflen && cnt<(outbuflen-2)) { - ic = *(ibp++); + while (size_t(ibp-inbuf) < inbuflen && cnt < outbuflen-2) { + ic = *ibp++; if (ic != delimiter1) { outbuf[cnt++] = ic; } else { @@ -57,8 +60,9 @@ addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, } }
- // error if outbuf is no large enough for storing the resulting data - if (cnt >= (outbuflen-2)) return -1; + // error if outbuf is not large enough for storing the resulting data + if (cnt >= outbuflen-2) + return -1;
// put delimiter1 and a char that is not a delimiter1 // as the end-of-data pattern at the end of outbuf @@ -75,8 +79,9 @@ addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
/* - * removeDelimiter performs the reverse transformation of addDelimiter. - * + * pdf_remove_delimiter performs the reverse transformation of + * pdf_add_delimiter. + * * returns the length of data written to outbuf, if succeed; * otherwise, it returns -1 * @@ -84,20 +89,23 @@ addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, * delimiter1 followed by non-delimiter1) is detected * * escape indicates if a dangling delimiter1 has been - * seen in the previous invocation of removeDelimiter + * seen in the previous invocation of pdf_remove_delimiter */ -int -removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, - const char delimiter1, int *endFlag, int *escape) +ssize_t +pdf_remove_delimiter(const char *inbuf, size_t inbuflen, + char *outbuf, size_t outbuflen, + char delimiter1, bool *endFlag, bool *escape) { - int cnt; - char *ibp, ic1, ic2; + size_t cnt; + const char *ibp; + char ic1, ic2;
cnt = 0; - *endFlag = 0; + *endFlag = false; ibp = inbuf;
- if (inbuflen <= 0) return -1; + if (inbuflen > SIZE_T_CEILING || outbuflen > SIZE_T_CEILING) + return -1;
// special case: 2-char, end-of-data pattern could be in two buffers // if *escape == true, we need to see if @@ -113,9 +121,9 @@ removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, } }
- *escape = 0; - while ((ibp-inbuf+1)<inbuflen && cnt<outbuflen) { - ic1 = *(ibp++); + *escape = false; + while (size_t(ibp-inbuf+1) < inbuflen && cnt < outbuflen) { + ic1 = *ibp++; if (ic1 != delimiter1) { outbuf[cnt++] = ic1; } else { @@ -125,13 +133,14 @@ removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, if (ic2 == delimiter1) { outbuf[cnt++] = delimiter1; ibp++; } else { // end-of-data pattern detected - *endFlag = 1; + *endFlag = true; return cnt; } } }
- if (ibp-inbuf == inbuflen) return cnt; + if (size_t(ibp-inbuf) == inbuflen) + return cnt;
// handling the last char in inbuf, if needed ic1 = *ibp; @@ -139,40 +148,46 @@ removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, outbuf[cnt++] = ic1; } else { // look at the next stream obj to handle the special cases - *escape = 1; + *escape = true; }
return cnt; }
- - /* - * pdfWrap embeds data of length dlen inside the stream objects of the PDF + * pdf_wrap embeds data of length dlen inside the stream objects of the PDF * document (length plen) that appears in the body of a HTTP msg, and * stores the result in the output buffer of size outsize * - * pdfWrap returns the length of the pdf document with the data embedded + * pdf_wrap returns the length of the pdf document with the data embedded * inside, if succeed; otherwise, it returns -1 to indicate an error - * - */ -int -pdfWrap (char *data, unsigned int dlen, - char *pdfTemplate, unsigned int plen, - char *outbuf, unsigned int outbufsize) + * + */ +ssize_t +pdf_wrap(const char *data, size_t dlen, + const char *pdfTemplate, size_t plen, + char *outbuf, size_t outbufsize) { char data2[dlen*2+2]; - char *tp, *dp, *op, *streamStart, *streamEnd, *plimit; - int data2len, cnt, size, size2; + const char *tp, *dp, *plimit; + char *op, *streamStart, *streamEnd; + size_t data2len, cnt, size, size2; + ssize_t rv;
- // assumption: pdfWrap is length-preserving - if (outbufsize < plen) return -1; + if (dlen > SIZE_T_CEILING || plen > SIZE_T_CEILING || + outbufsize > SIZE_T_CEILING) + return -1;
- data2len = addDelimiter(data, dlen, data2, HTTP_MSG_BUF_SIZE, PDF_DELIMITER, PDF_DELIMITER2); - if (data2len < 1) return -1; + // assumption: pdf_wrap is length-preserving + if (outbufsize < plen) return -1;
+ rv = pdf_add_delimiter(data, dlen, data2, HTTP_MSG_BUF_SIZE, + PDF_DELIMITER, PDF_DELIMITER2); + if (rv < 1) + return -1; + data2len = rv;
- op = outbuf; // current pointer for output buffer + op = outbuf; // current pointer for output buffer tp = pdfTemplate; // current pointer for http msg template dp = data2; // current pointer for data2 cnt = 0; // number of data char encoded @@ -185,7 +200,7 @@ pdfWrap (char *data, unsigned int dlen, log_warn("Cannot find stream in pdf"); return -1; } - + // copy everything between tp and "stream" (inclusive) to outbuf size = streamStart - tp + STREAM_BEGIN_SIZE; memcpy(op, tp, size); @@ -206,18 +221,17 @@ pdfWrap (char *data, unsigned int dlen, size2 = data2len - cnt; if (size < size2) { memcpy(op, dp, size); - op += size; tp += size; dp += size; + op += size; tp += size; dp += size; memcpy(op, tp, STREAM_END_SIZE); op += STREAM_END_SIZE; tp += STREAM_END_SIZE; cnt += size; } else { // done encoding data memcpy(op, dp, size2); - op += size2; tp += size2; dp += size2; + op += size2; tp += size2; dp += size2; cnt += size2; - // printf("Encoded %d char in pdf. Done encoding\n", size2); break; } - log_debug("Encoded %d char in pdf", size); + log_debug("Encoded %lu bytes in pdf", (unsigned long)size); } else { // empty stream memcpy(op, tp, STREAM_END_SIZE); op += STREAM_END_SIZE; tp += STREAM_END_SIZE; @@ -228,25 +242,27 @@ pdfWrap (char *data, unsigned int dlen,
// copy the rest of pdfTemplate to outbuf size = plimit-tp; - log_debug("copying the rest of pdfTemplate to outbuf (size %d)", size); + log_debug("copying the rest of pdfTemplate to outbuf (size %lu)", + (unsigned long)size); memcpy(op, tp, size); op += size; return (op-outbuf); }
- - - /* - * pdfUnwrap is the inverse operation of pdfWrap + * pdf_unwrap is the inverse operation of pdf_wrap */ -int -pdfUnwrap (char *data, unsigned int dlen, - char *outbuf, unsigned int outbufsize) +ssize_t +pdf_unwrap(const char *data, size_t dlen, + char *outbuf, size_t outbufsize) { - char *dp, *op, *streamStart, *streamEnd, *dlimit, *olimit; - int cnt, size, size2, endFlag; - int escape = 0; + const char *dp, *dlimit; + char *op, *streamStart, *streamEnd, *olimit; + size_t cnt, size, size2; + bool endFlag, escape = false; + + if (dlen > SIZE_T_CEILING || outbufsize > SIZE_T_CEILING) + return -1;
dp = data; // current pointer for data op = outbuf; // current pointer for outbuf @@ -272,11 +288,13 @@ pdfUnwrap (char *data, unsigned int dlen, // count the number of usable char between tp and streamEnd size = streamEnd-dp;
- if (size > 0) { - size2 = removeDelimiter(dp, size, op, olimit-op, PDF_DELIMITER, &endFlag, &escape); - if (size2 < 0) { + if (size > 0) { + ssize_t rv = pdf_remove_delimiter(dp, size, op, olimit-op, PDF_DELIMITER, + &endFlag, &escape); + if (rv < 0) return -1; - } + + size2 = rv; cnt += size2; if (endFlag) { // Done decoding break; @@ -292,22 +310,16 @@ pdfUnwrap (char *data, unsigned int dlen, return cnt; }
- - - - int -http_server_PDF_transmit (payloads& pl, struct evbuffer *source, - conn_t *conn) +http_server_PDF_transmit(payloads &pl, struct evbuffer *source, + conn_t *conn) { - struct evbuffer *dest = conn->outbound(); size_t sbuflen = evbuffer_get_length(source); unsigned int mpdf; char *pdfTemplate = NULL, *hend; int pdfTemplateSize = 0; - // char data1[HTTP_MSG_BUF_SIZE]; - char data1[(int) sbuflen]; + char data1[sbuflen]; char outbuf[HTTP_MSG_BUF_SIZE]; int cnt, hLen, outbuflen, i;
@@ -317,10 +329,6 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source, struct evbuffer_iovec *iv; int nv;
- // for debugging pdfWrap and pdfUnwrap - // char data2[(int) sbuflen]; - // int data2len; - log_debug("Entering SERVER PDF transmit with sbuflen %d", (int)sbuflen);
nv = evbuffer_peek(source, sbuflen, NULL, NULL, 0); @@ -357,8 +365,10 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source, return -1; }
- if (get_payload(pl, HTTP_CONTENT_PDF, sbuflen, &pdfTemplate, &pdfTemplateSize) == 1) { - log_debug("SERVER found the next HTTP response template with size %d", pdfTemplateSize); + if (get_payload(pl, HTTP_CONTENT_PDF, sbuflen, &pdfTemplate, + &pdfTemplateSize) == 1) { + log_debug("SERVER found the next HTTP response template with size %d", + pdfTemplateSize); } else { log_warn("SERVER couldn't find the next HTTP response template"); return -1; @@ -371,39 +381,19 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source, }
hLen = hend+4-pdfTemplate; - - log_debug("SERVER calling pdfWrap for data1 with length %d", cnt); - outbuflen = pdfWrap(data1, cnt, hend+4, pdfTemplateSize-hLen, outbuf, HTTP_MSG_BUF_SIZE); + + log_debug("SERVER calling pdf_wrap for data1 with length %d", cnt); + outbuflen = pdf_wrap(data1, cnt, hend+4, pdfTemplateSize-hLen, outbuf, + HTTP_MSG_BUF_SIZE); if (outbuflen < 0) { - log_warn("SERVER pdfWrap fails"); + log_warn("SERVER pdf_wrap fails"); return -1; } - log_debug("SERVER pdfSteg sends resp with hdr len %d body len %d", hLen, outbuflen); - - - // debugging - // buf_dump((unsigned char *)data1, cnt, stderr); - - // data2len = pdfUnwrap(outbuf, outbuflen, data2, sbuflen); - // if ((int)sbuflen == data2len) { - // log_warn("sbuflen == data2len == %d", (int)sbuflen); - // if (memcmp(data1, data2, sbuflen) == 0) { - // log_warn("data1 and data2 match"); - // } else { - // log_warn("data1 and data2 DO NOT match!! Dumping data1 ..."); - // buf_dump((unsigned char *)data1, cnt, stderr); - // log_warn("data1 and data2 DO NOT match!! Dumping data2..."); - // buf_dump((unsigned char *)data2, data2len, stderr); - // } - // } else { - // log_warn("*** sbuflen = %d, data2len = %d *** Dumping data1 ...", (int)sbuflen, data2len); - // buf_dump((unsigned char *)data1, cnt, stderr); - // log_warn("*** sbuflen = %d, data2len = %d *** Dumping data2 ...", (int)sbuflen, data2len); - // buf_dump((unsigned char *)data2, data2len, stderr); - // } - - - newHdrLen = gen_response_header((char*) "application/pdf", 0, outbuflen, newHdr, sizeof(newHdr)); + log_debug("SERVER pdfSteg sends resp with hdr len %d body len %d", + hLen, outbuflen); + + newHdrLen = gen_response_header((char*) "application/pdf", 0, + outbuflen, newHdr, sizeof(newHdr)); if (newHdrLen < 0) { log_warn("SERVER ERROR: gen_response_header fails for pdfSteg"); return -1; @@ -413,10 +403,6 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source, log_warn("SERVER ERROR: evbuffer_add() fails for newHdr"); return -1; } - // if (evbuffer_add(dest, pdfTemplate, hLen)) { - // log_warn("SERVER ERROR: evbuffer_add() fails for pdfTemplate"); - // return -1; - // }
if (evbuffer_add(dest, outbuf, outbuflen)) { log_warn("SERVER ERROR: evbuffer_add() fails for outbuf"); @@ -426,14 +412,13 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source, evbuffer_drain(source, sbuflen);
conn->cease_transmission(); - // downcast_steg(s)->have_transmitted = 1; return 0; }
- - int -http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, struct evbuffer* source) { +http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, + struct evbuffer* source) +{ struct evbuffer_ptr s2; unsigned int response_len = 0, hdrLen; char outbuf[HTTP_MSG_BUF_SIZE]; @@ -444,8 +429,8 @@ http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, st
s2 = evbuffer_search(source, "\r\n\r\n", sizeof ("\r\n\r\n") -1 , NULL); if (s2.pos == -1) { - log_warn("CLIENT Did not find end of HTTP header %d", (int) evbuffer_get_length(source)); - // evbuffer_dump(source, stderr); + log_warn("CLIENT Did not find end of HTTP header %d", + (int) evbuffer_get_length(source)); return RECV_INCOMPLETE; }
@@ -480,154 +465,26 @@ http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, st return RECV_BAD; }
- httpBody = httpHdr + hdrLen;
- - outbuflen = pdfUnwrap(httpBody, content_len, outbuf, HTTP_MSG_BUF_SIZE); + outbuflen = pdf_unwrap(httpBody, content_len, outbuf, HTTP_MSG_BUF_SIZE); if (outbuflen < 0) { - log_warn("CLIENT ERROR: pdfUnwrap fails\n"); + log_warn("CLIENT ERROR: pdf_unwrap fails\n"); return RECV_BAD; }
log_debug("CLIENT unwrapped data of length %d:", outbuflen);
- if (evbuffer_add(dest, outbuf, outbuflen)) { log_warn("CLIENT ERROR: evbuffer_add to dest fails\n"); return RECV_BAD; }
- // log_debug("Drained source for %d char\n", response_len); if (evbuffer_drain(source, response_len) == -1) { log_warn("CLIENT ERROR: failed to drain source\n"); return RECV_BAD; }
- // downcast_steg(s)->have_received = 1; conn->expect_close(); return RECV_GOOD; } - - - - -/***** -int main() { - char data1[] = "this is a test?? yes!"; - char data2[100]; - char data3[100]; - int dlen1, dlen2, dlen3, end; - char last = ' '; - printf("hello world\n"); - - dlen2 = addDelimiter(data1, strlen(data1), data2, 100, '?', '.'); - printf("dlen2 = %d\n", dlen2); - dlen3 = removeDelimiter(data2, dlen2, data3, 100, '?', &end, &last); - printf("endflag = %d", end); - printf("dlen3 = %d\n", dlen3); - if (memcmp(data1, data3, dlen3) == 0) { - data1[dlen3] = 0; - printf("removeDelimiter(addDelimiter(x)) == x for |%s|\n", data1); - } else { - printf("removeDelimiter(addDelimiter(x)) != x for |%s|\n", data1); - } - return 1; -} - *****/ - -/***** -int main() { - char data1[] = "12345"; - char data2[] = "123456789012"; - char data3[] = "12345678901"; - char data4[] = "1234567890?"; - char pdf1[] = "[PDFHDR][STUFFS1]>>streamABCDEFGHIJYYendstream[STUFFS2]>>streamABCDEFGHIJYYendstream[STUFF3][PDFTRAILER]"; - char out[200]; - char orig[200]; - int r1, r2; - - printf("********************\n"); - printf("pdfwrap for %s\n", data1); - printf("strlen(pdf1) = %d\n", (int)strlen(pdf1)); - r1 = pdfWrap(data1, strlen(data1), pdf1, strlen(pdf1), out, (int)sizeof(out)); - if (r1 > 0) { - printf("pdfWrap returns %d\n", r1); - out[r1] = 0; - printf("out[] contains |%s|\n", out); - } else { - printf("pdfWrap returns %d\n", r1); - } - - r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig)); - if (r2 > 0) { - printf("pdfUnwrap returns %d\n", r2); - orig[r2] = 0; - printf("orig[] contains |%s|\n", orig); - } else { - printf("pdfUnwrap returns %d\n", r2); - } - - printf("********************\n"); - printf("pdfwrap for %s\n", data2); - r1 = pdfWrap(data2, strlen(data2), pdf1, strlen(pdf1), out, (int)sizeof(out)); - if (r1 > 0) { - printf("pdfWrap returns %d\n", r1); - out[r1] = 0; - printf("out[] contains |%s|\n", out); - } else { - printf("pdfWrap returns %d\n", r1); - } - - r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig)); - if (r2 > 0) { - printf("pdfUnwrap returns %d\n", r2); - orig[r2] = 0; - printf("orig[] contains |%s|\n", orig); - } else { - printf("pdfUnwrap returns %d\n", r2); - } - - printf("********************\n"); - printf("pdfwrap for %s\n", data3); - r1 = pdfWrap(data3, strlen(data3), pdf1, strlen(pdf1), out, (int)sizeof(out)); - if (r1 > 0) { - printf("pdfWrap returns %d\n", r1); - out[r1] = 0; - printf("out[] contains |%s|\n", out); - } else { - printf("pdfWrap returns %d\n", r1); - } - - r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig)); - if (r2 > 0) { - printf("pdfUnwrap returns %d\n", r2); - orig[r2] = 0; - printf("orig[] contains |%s|\n", orig); - } else { - printf("pdfUnwrap returns %d\n", r2); - } - - printf("********************\n"); - printf("pdfwrap for %s\n", data4); - r1 = pdfWrap(data4, strlen(data4), pdf1, strlen(pdf1), out, (int)sizeof(out)); - if (r1 > 0) { - printf("pdfWrap returns %d\n", r1); - out[r1] = 0; - printf("out[] contains |%s|\n", out); - } else { - printf("pdfWrap returns %d\n", r1); - } - - r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig)); - if (r2 > 0) { - printf("pdfUnwrap returns %d\n", r2); - orig[r2] = 0; - printf("orig[] contains |%s|\n", orig); - } else { - printf("pdfUnwrap returns %d\n", r2); - } - - return 0; -} - *****/ diff --git a/src/steg/pdfSteg.h b/src/steg/pdfSteg.h index 3d494e1..0bd3a43 100644 --- a/src/steg/pdfSteg.h +++ b/src/steg/pdfSteg.h @@ -1,29 +1,31 @@ #ifndef _PDFSTEG_H #define _PDFSTEG_H
+struct payloads;
-#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include "util.h" -#include "connections.h" -#include "steg.h" -#include <event2/buffer.h> +// These are the public interface.
-struct payloads; +int http_server_PDF_transmit(payloads &pl, struct evbuffer *source, + conn_t *conn); +int http_handle_client_PDF_receive(steg_t *s, conn_t *conn, + struct evbuffer *dest, + struct evbuffer* source);
-#define PDF_DELIMITER '?' -#define PDF_DELIMITER2 '.' +// These are exposed only for the sake of unit tests.
-int pdfWrap (char *data, unsigned int dlen, char *pdfTemplate, unsigned int plen, char *outbuf, unsigned int outbufsize); -int pdfUnwrap (char *data, unsigned int dlen, char *outbuf, unsigned int outbufsize); +ssize_t pdf_add_delimiter(const char *inbuf, size_t inbuflen, + char *outbuf, size_t outbuflen, + char delimiter1, char delimiter2);
-int addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, const char delimiter1, const char delimiter2); -int removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, const char delimiter1, int* endFlag, int* escape); +ssize_t pdf_remove_delimiter(const char *inbuf, size_t inbuflen, + char *outbuf, size_t outbuflen, + char delimiter1, bool *endFlag, bool *escape);
-int http_server_PDF_transmit (payloads& pl, struct evbuffer *source, conn_t *conn); -int -http_handle_client_PDF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source); +ssize_t pdf_wrap(const char *data, size_t dlen, + const char *pdfTemplate, size_t plen, + char *outbuf, size_t outbufsize);
-#endif +ssize_t pdf_unwrap(const char *data, size_t dlen, + char *outbuf, size_t outbufsize);
+#endif diff --git a/src/steg/swfSteg.cc b/src/steg/swfSteg.cc index cd371f3..c8a18c1 100644 --- a/src/steg/swfSteg.cc +++ b/src/steg/swfSteg.cc @@ -1,5 +1,11 @@ +#include "util.h" #include "swfSteg.h" +#include "connections.h" +#include "payloads.h" +#include "zlib.h" +#include "zpack.h"
+#include <event2/buffer.h>
static const char http_response_1[] = "HTTP/1.1 200 OK\r\n" @@ -9,17 +15,7 @@ static const char http_response_1[] = "Content-Type: application/x-shockwave-flash\r\n" "Content-Length: ";
- - - - - - - - - - -unsigned int +unsigned int swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz) {
char* swf; diff --git a/src/steg/swfSteg.h b/src/steg/swfSteg.h index 712a3a3..b8336b2 100644 --- a/src/steg/swfSteg.h +++ b/src/steg/swfSteg.h @@ -1,38 +1,21 @@ #ifndef _SWFSTEG_H #define _SWFSTEG_H
- -#include "util.h" -#include "connections.h" -#include "steg.h" -#include "payloads.h" -#include "cookies.h" -#include "pdfSteg.h" -#include "zpack.h" - - -#include <event2/buffer.h> -#include <stdio.h> - struct payloads;
#define SWF_SAVE_HEADER_LEN 1500 #define SWF_SAVE_FOOTER_LEN 1500
- -unsigned int +unsigned int swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz);
-unsigned int +unsigned int swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz);
-int +int http_server_SWF_transmit(payloads& pl, struct evbuffer *source, conn_t *conn);
- int http_handle_client_SWF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
#endif - - diff --git a/src/steg/zpack.h b/src/steg/zpack.h index 65cd28d..d0e5cb2 100644 --- a/src/steg/zpack.h +++ b/src/steg/zpack.h @@ -1,10 +1,5 @@ -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <time.h> -#include <stdlib.h> -#include "zlib.h" - +#ifndef _ZPACK_H +#define _ZPACK_H
int def(char *source, int slen, char *dest, int dlen, int level); int inf(char *source, int slen, char *dest, int dlen); @@ -12,3 +7,5 @@ void zerr(int ret); int gzInflate(char *source, int slen, char *dest, int dlen); int gzDeflate(char* start, off_t insz, char *buf, off_t outsz, time_t mtime); unsigned int generate_crc32c(char *buffer, size_t length); + +#endif diff --git a/src/test/tinytest_macros.h b/src/test/tinytest_macros.h index 40d17e2..cf5a2a2 100644 --- a/src/test/tinytest_macros.h +++ b/src/test/tinytest_macros.h @@ -168,6 +168,10 @@ tt_assert_test_type(a,b,#a" "#op" "#b,void*, \ (_val1 op _val2),"%p")
+#define tt_char_op(a,op,b) \ + tt_assert_test_type(a,b,#a" "#op" "#b,int, \ + (_val1 op _val2),"'%c'") + #define tt_str_op(a,op,b) \ tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \ (strcmp(_val1,_val2) op 0),"<%s>") @@ -176,7 +180,7 @@ tt_assert_test_fmt_type(a,b,#a" "#op" "#b, \ const char *, \ (strncmp(_val1, _val2, len) op 0), \ - char *, "%s", \ + char *, "<%s>", \ { _print = xstrndup(_value, len); }, \ { free(_print); } \ ); @@ -185,7 +189,7 @@ tt_assert_test_fmt_type(a,b,#a" "#op" "#b, \ const char *, \ (memcmp(_val1, _val2, len) op 0), \ - char *, "%s", \ + char *, "<%s>", \ { _print = tt_base16_encode(_value, len); }, \ { free(_print); } \ ); diff --git a/src/test/unittest_pdfsteg.cc b/src/test/unittest_pdfsteg.cc new file mode 100644 index 0000000..cf9e97d --- /dev/null +++ b/src/test/unittest_pdfsteg.cc @@ -0,0 +1,82 @@ +/* Copyright 2011, 2012 SRI International + See LICENSE for other credits and copying information */ + +#include "util.h" +#include "unittest.h" +#include "../steg/pdfSteg.h" + +static void +test_pdf_add_remove_delimiters(void *) +{ + const char *data1 = "this is a test?? yes!"; + char data2[100]; + char data3[100]; + int dlen2, dlen3; + bool end = false, escape = false; + + memset(data2, 0, sizeof data2); + memset(data3, 0, sizeof data3); + + dlen2 = pdf_add_delimiter(data1, strlen(data1), data2, 100, '?', '.'); + tt_int_op(dlen2, ==, 25); + tt_stn_op(data2, ==, "this is a test???? yes!?", 24); + tt_char_op(data2[24], !=, '?'); + + dlen3 = pdf_remove_delimiter(data2, dlen2, data3, 100, '?', &end, &escape); + tt_int_op(dlen3, ==, 21); + tt_str_op(data3, ==, data1); + tt_bool_op(end, ==, true); + tt_bool_op(escape, ==, false); + + end:; +} + +static void +test_pdf_wrap_unwrap(void *) +{ + const char *pdf = + "[PDFHDR][STUFFS1]>>streamABCDEFGHIJYYendstream" + "[STUFFS2]>>streamABCDEFGHIJYYendstream[STUFF3][PDFTRAILER]"; + + const char *const tests[] = { + "12345", + "123456789012", + "12345678901", + "1234567890?", + 0 + }; + + char out[200]; + char orig[200]; + int i; + size_t r1, r2; + ssize_t rv; + + for (i = 0; tests[i]; i++) { + memset(out, 0, sizeof out); + memset(orig, 0, sizeof out); + rv = pdf_wrap(tests[i], strlen(tests[i]), + pdf, strlen(pdf), + out, sizeof out); + tt_int_op(rv, >, 0); + r1 = rv; + tt_int_op(r1, ==, strlen(pdf)); + + rv = pdf_unwrap(out, r1, orig, sizeof orig); + tt_int_op(rv, >, 0); + r2 = rv; + tt_int_op(r2, ==, strlen(tests[i])); + tt_stn_op(orig, ==, tests[i], r2); + } + + end:; +} + +#define T(name) \ + { #name, test_pdf_##name, 0, 0, 0 } + +struct testcase_t pdf_tests[] = { + T(add_remove_delimiters), + T(wrap_unwrap), + END_OF_TESTCASES +}; diff --git a/src/util.cc b/src/util.cc index b813ae9..a667abd 100644 --- a/src/util.cc +++ b/src/util.cc @@ -17,9 +17,6 @@ #include <sys/un.h> #endif
-/** Any size_t larger than this amount is likely to be an underflow. */ -#define SIZE_T_CEILING (SIZE_MAX/2 - 16) - /**************************** Memory Allocation ******************************/
static void ATTR_NORETURN diff --git a/src/util.h b/src/util.h index 05bc6d0..167af8e 100644 --- a/src/util.h +++ b/src/util.h @@ -57,6 +57,9 @@ struct event_base;
/***** Memory allocation. *****/
+/** Any size_t larger than this amount is likely to be an underflow. */ +#define SIZE_T_CEILING (SIZE_MAX/2 - 16) + /* Because this isn't Tor and functions named "tor_whatever" would be confusing, I am instead following the GNU convention of naming allocate-memory-or-crash functions "xwhatever". Also, at this time
tor-commits@lists.torproject.org