[tor-commits] [stegotorus/master] Thorough spring-cleaning on pdfSteg.cc; less thorough on swfSteg.cc
zwol at torproject.org
zwol at torproject.org
Fri Jul 20 23:17:07 UTC 2012
commit 177ba0f8b4265d09c321d6903eeab040faeca430
Author: Zack Weinberg <zackw at 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
More information about the tor-commits
mailing list