aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_smtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_smtp.c')
-rw-r--r--src/transport/plugin_transport_smtp.c151
1 files changed, 2 insertions, 149 deletions
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 {