aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_strings_lib.h29
-rw-r--r--src/transport/plugin_transport_smtp.c151
-rw-r--r--src/util/strings.c140
3 files changed, 169 insertions, 151 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 686be93ad..f93148df5 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -317,6 +317,31 @@ GNUNET_STRINGS_string_to_data (const char *enc,
317 317
318 318
319/** 319/**
320 * Encode into Base64.
321 *
322 * @param data the data to encode
323 * @param len the length of the input
324 * @param output where to write the output (*output should be NULL,
325 * is allocated)
326 * @return the size of the output
327 */
328size_t
329GNUNET_STRINGS_base64_encode (const char *data, size_t len, char **output);
330
331/**
332 * Decode from Base64.
333 *
334 * @param data the data to encode
335 * @param len the length of the input
336 * @param output where to write the output (*output should be NULL,
337 * is allocated)
338 * @return the size of the output
339 */
340size_t
341GNUNET_STRINGS_base64_decode (const char *data, size_t len, char **output);
342
343
344/**
320 * Parse a path that might be an URI. 345 * Parse a path that might be an URI.
321 * 346 *
322 * @param path path to parse. Must be NULL-terminated. 347 * @param path path to parse. Must be NULL-terminated.
@@ -392,8 +417,8 @@ enum GNUNET_STRINGS_FilenameCheck
392 * 417 *
393 * @param filename file to check 418 * @param filename file to check
394 * @param checks checks to perform 419 * @param checks checks to perform
395 * @return GNUNET_YES if all checks pass, GNUNET_NO if at least one of them 420 * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them
396 * fails, GNUNET_SYSERR when a check can't be performed 421 * fails, #GNUNET_SYSERR when a check can't be performed
397 */ 422 */
398int 423int
399GNUNET_STRINGS_check_filename (const char *filename, 424GNUNET_STRINGS_check_filename (const char *filename,
diff --git a/src/transport/plugin_transport_smtp.c b/src/transport/plugin_transport_smtp.c
index fa0c787d1..828a0b884 100644
--- a/src/transport/plugin_transport_smtp.c
+++ b/src/transport/plugin_transport_smtp.c
@@ -145,153 +145,6 @@ static unsigned long long rate_limit;
145 145
146static GNUNET_CronTime last_transmission; 146static GNUNET_CronTime last_transmission;
147 147
148/** ******************** Base64 encoding ***********/
149
150#define FILLCHAR '='
151static char *cvt =
152 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
153
154/**
155 * Encode into Base64.
156 *
157 * @param data the data to encode
158 * @param len the length of the input
159 * @param output where to write the output (*output should be NULL,
160 * is allocated)
161 * @return the size of the output
162 */
163static unsigned int
164base64_encode (const char *data, unsigned int len, char **output)
165{
166 unsigned int i;
167 char c;
168 unsigned int ret;
169 char *opt;
170
171/* (*output)[ret++] = '\r'; \*/
172#define CHECKLINE \
173 if ( (ret % MAX_CHAR_PER_LINE) == 0) { \
174 (*output)[ret++] = '\n'; \
175 }
176 ret = 0;
177 opt =
178 GNUNET_malloc (2 +
179 (((len * 4 / 3) + 8) * (MAX_CHAR_PER_LINE +
180 2)) / MAX_CHAR_PER_LINE);
181 /* message must start with \r\n for libesmtp */
182 *output = opt;
183 opt[0] = '\r';
184 opt[1] = '\n';
185 ret += 2;
186 for (i = 0; i < len; ++i)
187 {
188 c = (data[i] >> 2) & 0x3f;
189 opt[ret++] = cvt[(int) c];
190 CHECKLINE;
191 c = (data[i] << 4) & 0x3f;
192 if (++i < len)
193 c |= (data[i] >> 4) & 0x0f;
194 opt[ret++] = cvt[(int) c];
195 CHECKLINE;
196 if (i < len)
197 {
198 c = (data[i] << 2) & 0x3f;
199 if (++i < len)
200 c |= (data[i] >> 6) & 0x03;
201 opt[ret++] = cvt[(int) c];
202 CHECKLINE;
203 }
204 else
205 {
206 ++i;
207 opt[ret++] = FILLCHAR;
208 CHECKLINE;
209 }
210 if (i < len)
211 {
212 c = data[i] & 0x3f;
213 opt[ret++] = cvt[(int) c];
214 CHECKLINE;
215 }
216 else
217 {
218 opt[ret++] = FILLCHAR;
219 CHECKLINE;
220 }
221 }
222 opt[ret++] = FILLCHAR;
223 return ret;
224}
225
226#define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\
227 :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\
228 :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\
229 :((a) == '+') ? 62\
230 :((a) == '/') ? 63 : -1)
231/**
232 * Decode from Base64.
233 *
234 * @param data the data to encode
235 * @param len the length of the input
236 * @param output where to write the output (*output should be NULL,
237 * is allocated)
238 * @return the size of the output
239 */
240static unsigned int
241base64_decode (const char *data, unsigned int len, char **output)
242{
243 unsigned int i;
244 char c;
245 char c1;
246 unsigned int ret = 0;
247
248#define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\
249 GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "ignoring CR/LF\n"); \
250 i++; \
251 if (i >= len) goto END; \
252 }
253
254 *output = GNUNET_malloc ((len * 3 / 4) + 8);
255#if DEBUG_SMTP
256 GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
257 "base64_decode decoding len=%d\n", len);
258#endif
259 for (i = 0; i < len; ++i)
260 {
261 CHECK_CRLF;
262 if (data[i] == FILLCHAR)
263 break;
264 c = (char) cvtfind (data[i]);
265 ++i;
266 CHECK_CRLF;
267 c1 = (char) cvtfind (data[i]);
268 c = (c << 2) | ((c1 >> 4) & 0x3);
269 (*output)[ret++] = c;
270 if (++i < len)
271 {
272 CHECK_CRLF;
273 c = data[i];
274 if (FILLCHAR == c)
275 break;
276 c = (char) cvtfind (c);
277 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
278 (*output)[ret++] = c1;
279 }
280 if (++i < len)
281 {
282 CHECK_CRLF;
283 c1 = data[i];
284 if (FILLCHAR == c1)
285 break;
286
287 c1 = (char) cvtfind (c1);
288 c = ((c << 6) & 0xc0) | c1;
289 (*output)[ret++] = c;
290 }
291 }
292END:
293 return ret;
294}
295 148
296/* ********************* the real stuff ******************* */ 149/* ********************* the real stuff ******************* */
297 150
@@ -354,7 +207,7 @@ listenAndDistribute (void *unused)
354 if ((line[pos] == '\r') || (line[pos] == '\n')) 207 if ((line[pos] == '\r') || (line[pos] == '\n'))
355 break; /* empty line => end of message! */ 208 break; /* empty line => end of message! */
356 } 209 }
357 size = base64_decode (line, pos, &out); 210 size = GNUNET_STRINGS_base64_decode (line, pos, &out);
358 if (size < sizeof (SMTPMessage)) 211 if (size < sizeof (SMTPMessage))
359 { 212 {
360 GNUNET_GE_BREAK (ectx, 0); 213 GNUNET_GE_BREAK (ectx, 0);
@@ -617,7 +470,7 @@ api_send (GNUNET_TSession * tsession, const void *msg, const unsigned int size,
617 mp->sender = *core_api->my_identity; 470 mp->sender = *core_api->my_identity;
618 gm_cls.ebody = NULL; 471 gm_cls.ebody = NULL;
619 gm_cls.pos = 0; 472 gm_cls.pos = 0;
620 gm_cls.esize = base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody); 473 gm_cls.esize = GNUNET_STRINGS_base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody);
621 GNUNET_free (m); 474 GNUNET_free (m);
622 if (0 == smtp_size_set_estimate (message, gm_cls.esize)) 475 if (0 == smtp_size_set_estimate (message, gm_cls.esize))
623 { 476 {
diff --git a/src/util/strings.c b/src/util/strings.c
index 85c6a1cc6..70a1160dd 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -1743,4 +1743,144 @@ GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX)
1743} 1743}
1744 1744
1745 1745
1746
1747/** ******************** Base64 encoding ***********/
1748
1749#define FILLCHAR '='
1750static char *cvt =
1751 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
1752
1753
1754/**
1755 * Encode into Base64.
1756 *
1757 * @param data the data to encode
1758 * @param len the length of the input
1759 * @param output where to write the output (*output should be NULL,
1760 * is allocated)
1761 * @return the size of the output
1762 */
1763size_t
1764GNUNET_STRINGS_base64_encode (const char *data,
1765 size_t len,
1766 char **output)
1767{
1768 size_t i;
1769 char c;
1770 size_t ret;
1771 char *opt;
1772
1773 ret = 0;
1774 opt = GNUNET_malloc (2 + (len * 4 / 3) + 8);
1775 *output = opt;
1776 for (i = 0; i < len; ++i)
1777 {
1778 c = (data[i] >> 2) & 0x3f;
1779 opt[ret++] = cvt[(int) c];
1780 c = (data[i] << 4) & 0x3f;
1781 if (++i < len)
1782 c |= (data[i] >> 4) & 0x0f;
1783 opt[ret++] = cvt[(int) c];
1784 if (i < len)
1785 {
1786 c = (data[i] << 2) & 0x3f;
1787 if (++i < len)
1788 c |= (data[i] >> 6) & 0x03;
1789 opt[ret++] = cvt[(int) c];
1790 }
1791 else
1792 {
1793 ++i;
1794 opt[ret++] = FILLCHAR;
1795 }
1796 if (i < len)
1797 {
1798 c = data[i] & 0x3f;
1799 opt[ret++] = cvt[(int) c];
1800 }
1801 else
1802 {
1803 opt[ret++] = FILLCHAR;
1804 }
1805 }
1806 opt[ret++] = FILLCHAR;
1807 return ret;
1808}
1809
1810#define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\
1811 :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\
1812 :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\
1813 :((a) == '+') ? 62\
1814 :((a) == '/') ? 63 : -1)
1815
1816
1817/**
1818 * Decode from Base64.
1819 *
1820 * @param data the data to encode
1821 * @param len the length of the input
1822 * @param output where to write the output (*output should be NULL,
1823 * is allocated)
1824 * @return the size of the output
1825 */
1826size_t
1827GNUNET_STRINGS_base64_decode (const char *data,
1828 size_t len, char **output)
1829{
1830 size_t i;
1831 char c;
1832 char c1;
1833 size_t ret = 0;
1834
1835#define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\
1836 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "ignoring CR/LF\n"); \
1837 i++; \
1838 if (i >= len) goto END; \
1839 }
1840
1841 *output = GNUNET_malloc ((len * 3 / 4) + 8);
1842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1843 "base64_decode decoding len=%d\n",
1844 (int) len);
1845 for (i = 0; i < len; ++i)
1846 {
1847 CHECK_CRLF;
1848 if (FILLCHAR == data[i])
1849 break;
1850 c = (char) cvtfind (data[i]);
1851 ++i;
1852 CHECK_CRLF;
1853 c1 = (char) cvtfind (data[i]);
1854 c = (c << 2) | ((c1 >> 4) & 0x3);
1855 (*output)[ret++] = c;
1856 if (++i < len)
1857 {
1858 CHECK_CRLF;
1859 c = data[i];
1860 if (FILLCHAR == c)
1861 break;
1862 c = (char) cvtfind (c);
1863 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1864 (*output)[ret++] = c1;
1865 }
1866 if (++i < len)
1867 {
1868 CHECK_CRLF;
1869 c1 = data[i];
1870 if (FILLCHAR == c1)
1871 break;
1872
1873 c1 = (char) cvtfind (c1);
1874 c = ((c << 6) & 0xc0) | c1;
1875 (*output)[ret++] = c;
1876 }
1877 }
1878END:
1879 return ret;
1880}
1881
1882
1883
1884
1885
1746/* end of strings.c */ 1886/* end of strings.c */