Browse code

ClamSubmit: Fix __cfduid cookie failure

Cloudflare deprecated the __cfduid cookie which caused ClamSubmit
failures on systems that stopped receiving the cookie.

This commit removes support for the __cfduid cookie.
Also made the session cookie optional, in case that disappears too.

Changed error messages over to use the logg() function like our other apps.

Tidied up some of the logic, and changed "cleanup" label to "done" to
match other code.

Micah Snyder authored on 2021/05/25 08:07:17
Showing 2 changed files
... ...
@@ -1,3 +1,30 @@
1
+/*
2
+ *  ClamAV Malware and False Positive Reporting Tool
3
+ *
4
+ *  Copyright (C) 2014-2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5
+ *
6
+ *  Authors: Shawn Webb, Steve Morgan
7
+ *
8
+ *  This program is free software; you can redistribute it and/or modify
9
+ *  it under the terms of the GNU General Public License version 2 as
10
+ *  published by the Free Software Foundation.
11
+ *
12
+ *  This program is distributed in the hope that it will be useful,
13
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ *  GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License
18
+ *  along with this program; if not, write to the Free Software
19
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ *  MA 02110-1301, USA.
21
+ */
22
+
23
+#ifdef HAVE_CONFIG_H
24
+#include "clamav-config.h"
25
+#endif
26
+
27
+#include <stdbool.h>
1 28
 #include <stdio.h>
2 29
 #include <stdlib.h>
3 30
 #if HAVE_UNISTD_H
... ...
@@ -23,6 +50,7 @@
23 23
 #include "misc.h"
24 24
 #include "getopt.h"
25 25
 #include "cert_util.h"
26
+#include "output.h"
26 27
 
27 28
 #define OPTS "e:p:n:N:V:H:h?v?d"
28 29
 
... ...
@@ -32,7 +60,6 @@ void version(void);
32 32
 
33 33
 typedef struct _header_data {
34 34
     int len;
35
-    char *cfduid;
36 35
     char *session;
37 36
 } header_data;
38 37
 
... ...
@@ -41,7 +68,7 @@ typedef struct _write_data {
41 41
     char *str;
42 42
 } write_data;
43 43
 
44
-int g_debug = 0;
44
+bool g_debug = false;
45 45
 
46 46
 void usage(char *name)
47 47
 {
... ...
@@ -85,22 +112,22 @@ size_t header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
85 85
         sp = ptr + clen + 1;
86 86
         ep = strchr(sp, ';');
87 87
         if (ep == NULL) {
88
-            fprintf(stderr, "header_cb(): malformed cookie\n");
88
+            logg("!header_cb(): malformed cookie\n");
89 89
             return 0;
90 90
         }
91 91
         mem = malloc(ep - sp + 1);
92 92
         if (mem == NULL) {
93
-            fprintf(stderr, "header_cb(): malloc failed\n");
93
+            logg("!header_cb(): malloc failed\n");
94 94
             return 0;
95 95
         }
96 96
         memcpy(mem, sp, ep - sp);
97 97
         mem[ep - sp] = '\0';
98
-        if (!strncmp(mem, "__cfduid", 8))
99
-            hd->cfduid = mem;
100
-        else if (!strncmp(mem, "_clamav-net_session", strlen("_clamav-net_session")))
98
+        if (!strncmp(mem, "_clamav-net_session", strlen("_clamav-net_session")))
101 99
             hd->session = mem;
102
-        else
103
-            fprintf(stderr, "header_cb(): unrecognized cookie\n");
100
+        else {
101
+            logg("!header_cb(): unrecognized cookie\n");
102
+            free(mem);
103
+        }
104 104
     }
105 105
     return len;
106 106
 }
... ...
@@ -114,7 +141,7 @@ size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
114 114
     if (len) {
115 115
         str = realloc(wd->str, wd->len + len + 1);
116 116
         if (str == NULL) {
117
-            fprintf(stderr, "write_cb() realloc failure\n");
117
+            logg("!write_cb() realloc failure\n");
118 118
             return 0;
119 119
         }
120 120
         memcpy(str + wd->len, ptr, len);
... ...
@@ -140,10 +167,10 @@ const char *presigned_get_string(json_object *ps_json_obj, char *key)
140 140
     if (json_object_object_get_ex(ps_json_obj, key, &json_obj)) {
141 141
         json_str = json_object_get_string(json_obj);
142 142
         if (json_str == NULL) {
143
-            fprintf(stderr, "Error: json_object_get_string() for %s.\n", key);
143
+            logg("!Error: json_object_get_string() for %s.\n", key);
144 144
         }
145 145
     } else {
146
-        fprintf(stderr, "Error: json_object_object_get_ex() for %s.\n", key);
146
+        logg("!Error: json_object_object_get_ex() for %s.\n", key);
147 147
     }
148 148
     return json_str;
149 149
 }
... ...
@@ -161,23 +188,28 @@ int main(int argc, char *argv[])
161 161
     int setURL = 0, fromStream = 0;
162 162
     const char *json_str;
163 163
     write_data wd            = {0, NULL};
164
-    header_data hd_malware   = {0, NULL, NULL};
165
-    header_data hd_presigned = {0, NULL, NULL};
164
+    header_data hd_malware   = {0, NULL};
165
+    header_data hd_presigned = {0, NULL};
166 166
     json_object *ps_json_obj = NULL;
167
-    int malware              = 0;
167
+    bool malware             = false;
168 168
     int len                  = 0;
169 169
     char *submissionID       = NULL;
170 170
     char *fpvname            = NULL;
171
-    char *sp, *ep, *str;
172
-    char *authenticity_token = NULL;
173
-    char *urlp;
171
+    char *sp, *ep;
172
+
173
+    char *authenticity_token_header = NULL;
174
+    char *authenticity_token        = NULL;
175
+    char *session_cookie            = NULL;
176
+
177
+    char *url_for_auth_token;
178
+    char *url_for_presigned_cookie;
174 179
 
175 180
     curl_global_init(CURL_GLOBAL_ALL);
176 181
 
177 182
     clam_curl = curl_easy_init();
178 183
     if (clam_curl == NULL) {
179
-        fprintf(stderr, "ERROR: Could not initialize libcurl.\n");
180
-        goto cleanup;
184
+        logg("!ERROR: Could not initialize libcurl.\n");
185
+        goto done;
181 186
     }
182 187
 
183 188
     memset(userAgent, 0, sizeof(userAgent));
... ...
@@ -187,7 +219,7 @@ int main(int argc, char *argv[])
187 187
     userAgent[sizeof(userAgent) - 1] = 0;
188 188
 
189 189
     if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_USERAGENT, userAgent)) {
190
-        fprintf(stderr, "!create_curl_handle: Failed to set CURLOPT_USERAGENT (%s)!\n", userAgent);
190
+        logg("!!create_curl_handle: Failed to set CURLOPT_USERAGENT (%s)!\n", userAgent);
191 191
     }
192 192
 
193 193
     while ((ch = my_getopt(argc, argv, OPTS)) > 0) {
... ...
@@ -209,14 +241,14 @@ int main(int argc, char *argv[])
209 209
             case 'n':
210 210
                 if (setURL)
211 211
                     usage(argv[0]);
212
-                malware  = 1;
212
+                malware  = true;
213 213
                 filename = optarg;
214 214
                 break;
215 215
             case 'V':
216 216
                 fpvname = optarg;
217 217
                 break;
218 218
             case 'd':
219
-                g_debug = 1;
219
+                g_debug = true;
220 220
                 break;
221 221
             case 'h':
222 222
             case '?':
... ...
@@ -228,15 +260,15 @@ int main(int argc, char *argv[])
228 228
     if (!(name) || !(email) || !(filename))
229 229
         usage(argv[0]);
230 230
 
231
-    if (malware == 0 && fpvname == NULL) {
232
-        fprintf(stderr, "Detected virus name(-V) required for false positive submissions.\n");
231
+    if (malware == false && fpvname == NULL) {
232
+        logg("!Detected virus name(-V) required for false positive submissions.\n");
233 233
         usage(argv[0]);
234 234
     }
235 235
     if (strlen(filename) == 1 && filename[0] == '-') {
236 236
         filename = read_stream();
237 237
         if (!(filename)) {
238
-            fprintf(stderr, "ERROR: Unable to read stream\n");
239
-            goto cleanup;
238
+            logg("!ERROR: Unable to read stream\n");
239
+            goto done;
240 240
         }
241 241
         fromStream = 1;
242 242
     }
... ...
@@ -244,31 +276,34 @@ int main(int argc, char *argv[])
244 244
     if (g_debug) {
245 245
         /* ask libcurl to show us the verbose output */
246 246
         if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_VERBOSE, 1L)) {
247
-            fprintf(stderr, "!ERROR: Failed to set CURLOPT_VERBOSE!\n");
247
+            logg("!!ERROR: Failed to set CURLOPT_VERBOSE!\n");
248 248
         }
249 249
         if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_STDERR, stdout)) {
250
-            fprintf(stderr, "!ERROR: Failed to direct curl debug output to stdout!\n");
250
+            logg("!!ERROR: Failed to direct curl debug output to stdout!\n");
251 251
         }
252 252
     }
253 253
 
254 254
     if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1)) {
255
-        fprintf(stderr, "ERROR: Failed to set HTTP version to 1.1 (to prevent 2.0 responses which we don't yet parse properly)!\n");
255
+        logg("!ERROR: Failed to set HTTP version to 1.1 (to prevent 2.0 responses which we don't yet parse properly)!\n");
256 256
     }
257 257
 
258 258
 #if defined(C_DARWIN) || defined(_WIN32)
259 259
     if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function)) {
260
-        fprintf(stderr, "ERROR: Failed to set SSL CTX function!\n");
260
+        logg("!ERROR: Failed to set SSL CTX function!\n");
261 261
     }
262 262
 #else
263 263
     set_tls_ca_bundle(clam_curl);
264 264
 #endif
265 265
 
266
-    /*** The GET malware|fp ***/
267
-    if (malware == 1)
268
-        urlp = "https://www.clamav.net/reports/malware";
269
-    else
270
-        urlp = "https://www.clamav.net/reports/fp";
271
-    curl_easy_setopt(clam_curl, CURLOPT_URL, urlp);
266
+    /*
267
+     * GET authenticity token
268
+     */
269
+    if (malware == true) {
270
+        url_for_auth_token = "https://www.clamav.net/reports/malware";
271
+    } else {
272
+        url_for_auth_token = "https://www.clamav.net/reports/fp";
273
+    }
274
+    curl_easy_setopt(clam_curl, CURLOPT_URL, url_for_auth_token);
272 275
     curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1);
273 276
     curl_easy_setopt(clam_curl, CURLOPT_WRITEDATA, &wd);
274 277
     curl_easy_setopt(clam_curl, CURLOPT_WRITEFUNCTION, write_cb);
... ...
@@ -276,30 +311,30 @@ int main(int argc, char *argv[])
276 276
     curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
277 277
     res = curl_easy_perform(clam_curl);
278 278
     if (res != CURLE_OK) {
279
-        fprintf(stderr, "Error in GET %s: %s\n", urlp, curl_easy_strerror(res));
280
-        goto cleanup;
279
+        logg("!Error in GET %s: %s\n", url_for_auth_token, curl_easy_strerror(res));
280
+        goto done;
281 281
     }
282 282
     if (wd.str != NULL) {
283 283
         sp = strstr(wd.str, "name=\"authenticity_token\"");
284 284
         if (sp == NULL) {
285
-            fprintf(stderr, "Authenticity token element not found.\n");
286
-            goto cleanup;
285
+            logg("!Authenticity token element not found.\n");
286
+            goto done;
287 287
         }
288 288
         sp = strstr(sp, "value=");
289 289
         if (sp == NULL) {
290
-            fprintf(stderr, "Authenticity token value not found.\n");
291
-            goto cleanup;
290
+            logg("!Authenticity token value not found.\n");
291
+            goto done;
292 292
         }
293 293
         sp += 7;
294 294
         ep = strchr(sp, '"');
295 295
         if (ep == NULL) {
296
-            fprintf(stderr, "Authenticity token malformed.\n");
297
-            goto cleanup;
296
+            logg("!Authenticity token malformed.\n");
297
+            goto done;
298 298
         }
299 299
         authenticity_token = malloc(ep - sp + 1);
300 300
         if (authenticity_token == NULL) {
301
-            fprintf(stderr, "no memory for authenticity token.\n");
302
-            goto cleanup;
301
+            logg("!no memory for authenticity token.\n");
302
+            goto done;
303 303
         }
304 304
         memcpy(authenticity_token, sp, ep - sp);
305 305
         authenticity_token[ep - sp] = '\0';
... ...
@@ -307,120 +342,128 @@ int main(int argc, char *argv[])
307 307
         wd.str = NULL;
308 308
     }
309 309
     wd.len = 0;
310
-    urlp   = NULL;
311 310
 
312
-    /*** The GET presigned ***/
313
-    if (malware == 1)
314
-        curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=malware");
315
-    else
316
-        curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=fp");
311
+    /* record the session cookie for later use, if exists */
312
+    if (NULL == hd_malware.session) {
313
+        logg("!clamav.net/presigned response missing session ID cookie.\nWill try without the cookie.\n");
314
+        // goto done; // Note: unclear if the session cookie is required. Can't hurt to try w/out it?
315
+    } else {
316
+        len            = strlen(hd_malware.session) + 3;
317
+        session_cookie = malloc(len);
318
+        if (session_cookie == NULL) {
319
+            logg("!No memory for GET presigned cookies\n");
320
+            goto done;
321
+        }
322
+        if (snprintf(session_cookie, len, "%s;", hd_malware.session) > len) {
323
+            logg("!snprintf() failed formatting GET presigned cookies\n");
324
+            goto done;
325
+        }
326
+    }
327
+
328
+    /*
329
+     * GET presigned cookie
330
+     */
331
+    if (malware == true) {
332
+        url_for_presigned_cookie = "https://www.clamav.net/presigned?type=malware";
333
+    } else {
334
+        url_for_presigned_cookie = "https://www.clamav.net/presigned?type=fp";
335
+    }
336
+
337
+    curl_easy_setopt(clam_curl, CURLOPT_URL, url_for_presigned_cookie);
317 338
     curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1);
318 339
 
319
-    if (NULL == hd_malware.cfduid || NULL == hd_malware.session) {
320
-        fprintf(stderr, "invalid cfduid and/or session id values provided by clamav.net/presigned. Unable to continue submission.");
321
-        goto cleanup;
322
-    }
323
-
324
-    len = strlen(hd_malware.cfduid) + strlen(hd_malware.session) + 3;
325
-    str = malloc(len);
326
-    if (str == NULL) {
327
-        fprintf(stderr, "No memory for GET presigned cookies\n");
328
-        goto cleanup;
329
-    }
330
-    if (snprintf(str, len, "%s; %s;", hd_malware.cfduid, hd_malware.session) > len) {
331
-        fprintf(stderr, "snprintf() failed formatting GET presigned cookies\n");
332
-        free(str);
333
-        goto cleanup;
334
-    }
335
-    curl_easy_setopt(clam_curl, CURLOPT_COOKIE, str);
336
-    free(str);
337
-    len = strlen(authenticity_token) + 15;
338
-    str = malloc(len);
339
-    if (str == NULL) {
340
-        fprintf(stderr, "No memory for GET presigned X-CSRF-Token\n");
341
-        goto cleanup;
342
-    }
343
-    if (snprintf(str, len, "X-CSRF-Token: %s", authenticity_token) > len) {
344
-        fprintf(stderr, "snprintf() failed for GET presigned X-CSRF-Token\n");
345
-        free(str);
346
-        goto cleanup;
347
-    }
348
-    slist = curl_slist_append(slist, str);
349
-    free(str);
340
+    if (NULL != session_cookie) {
341
+        curl_easy_setopt(clam_curl, CURLOPT_COOKIE, session_cookie);
342
+    }
343
+
344
+    /* Include an X-CSRF-Token header using the authenticity token retrieved with the presigned GET request */
345
+    len                       = strlen(authenticity_token) + strlen("X-CSRF-Token: ") + 1;
346
+    authenticity_token_header = malloc(len);
347
+    if (authenticity_token_header == NULL) {
348
+        logg("!No memory for GET presigned X-CSRF-Token\n");
349
+        goto done;
350
+    }
351
+    if (snprintf(authenticity_token_header, len, "X-CSRF-Token: %s", authenticity_token) > len) {
352
+        logg("!snprintf() failed for GET presigned X-CSRF-Token\n");
353
+        goto done;
354
+    }
355
+    slist = curl_slist_append(slist, authenticity_token_header);
356
+    free(authenticity_token_header);
357
+    authenticity_token_header = NULL;
358
+
350 359
     curl_easy_setopt(clam_curl, CURLOPT_HTTPHEADER, slist);
351 360
     curl_easy_setopt(clam_curl, CURLOPT_HEADERDATA, &hd_presigned);
352 361
     curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
353
-    if (malware == 1)
354
-        curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/malware");
355
-    else
356
-        curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/fp");
362
+    curl_easy_setopt(clam_curl, CURLOPT_REFERER, url_for_auth_token);
357 363
 
358 364
     res = curl_easy_perform(clam_curl);
359 365
     if (res != CURLE_OK) {
360
-        fprintf(stderr, "Error in GET presigned: %s\n", curl_easy_strerror(res));
361
-        goto cleanup;
366
+        logg("!Error in GET reports: %s\n", curl_easy_strerror(res));
367
+        goto done;
362 368
     }
363 369
     curl_slist_free_all(slist);
364 370
     slist = NULL;
365 371
 
366
-    /*** The POST to AWS ***/
372
+    /*
373
+     * POST the report to AWS
374
+     */
367 375
     ps_json_obj = json_tokener_parse(wd.str);
368 376
     if (ps_json_obj == NULL) {
369
-        fprintf(stderr, "Error in json_tokener_parse of %.*s\n", wd.len, wd.str);
370
-        goto cleanup;
377
+        logg("!Error in json_tokener_parse of %.*s\n", wd.len, wd.str);
378
+        goto done;
371 379
     }
372 380
     json_str = presigned_get_string(ps_json_obj, "key");
373 381
     if (json_str == NULL) {
374
-        fprintf(stderr, "Error in presigned_get_string parsing key from json object\n");
375
-        goto cleanup;
382
+        logg("!Error in presigned_get_string parsing key from json object\n");
383
+        goto done;
376 384
     }
377 385
     sp = strchr(json_str, '/');
378 386
     if (sp == NULL) {
379
-        fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '/'.\n");
380
-        goto cleanup;
387
+        logg("!Error: malformed 'key' string in GET presigned response (missing '/'.\n");
388
+        goto done;
381 389
     }
382 390
     sp++;
383 391
     ep = strchr(sp, '-');
384 392
     if (ep == NULL) {
385
-        fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '-'.\n");
386
-        goto cleanup;
393
+        logg("!Error: malformed 'key' string in GET presigned response (missing '-'.\n");
394
+        goto done;
387 395
     }
388 396
 
389 397
     submissionID = malloc(ep - sp + 1);
390 398
     if (submissionID == NULL) {
391
-        fprintf(stderr, "Error: malloc submissionID.\n");
392
-        goto cleanup;
399
+        logg("!Error: malloc submissionID.\n");
400
+        goto done;
393 401
     }
394 402
     memcpy(submissionID, sp, ep - sp);
395 403
     submissionID[ep - sp] = '\0';
396 404
 
397 405
     aws_curl = curl_easy_init();
398 406
     if (!(aws_curl)) {
399
-        fprintf(stderr, "ERROR: Could not initialize libcurl POST presigned\n");
400
-        goto cleanup;
407
+        logg("!ERROR: Could not initialize libcurl POST presigned\n");
408
+        goto done;
401 409
     }
402 410
 
403 411
     if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_USERAGENT, userAgent)) {
404
-        fprintf(stderr, "!create_curl_handle: Failed to set CURLOPT_USERAGENT (%s)!\n", userAgent);
412
+        logg("!!create_curl_handle: Failed to set CURLOPT_USERAGENT (%s)!\n", userAgent);
405 413
     }
406 414
 
407 415
     if (g_debug) {
408 416
         /* ask libcurl to show us the verbose output */
409 417
         if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_VERBOSE, 1L)) {
410
-            fprintf(stderr, "!ERROR: Failed to set CURLOPT_VERBOSE!\n");
418
+            logg("!!ERROR: Failed to set CURLOPT_VERBOSE!\n");
411 419
         }
412 420
         if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_STDERR, stdout)) {
413
-            fprintf(stderr, "!ERROR: Failed to direct curl debug output to stdout!\n");
421
+            logg("!!ERROR: Failed to direct curl debug output to stdout!\n");
414 422
         }
415 423
     }
416 424
 
417 425
     if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1)) {
418
-        fprintf(stderr, "ERROR: Failed to set HTTP version to 1.1 (to prevent 2.0 responses which we don't yet parse properly)!\n");
426
+        logg("!ERROR: Failed to set HTTP version to 1.1 (to prevent 2.0 responses which we don't yet parse properly)!\n");
419 427
     }
420 428
 
421 429
 #if defined(C_DARWIN) || defined(_WIN32)
422 430
     if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function)) {
423
-        fprintf(stderr, "ERROR: Failed to set SSL CTX function!\n");
431
+        logg("!ERROR: Failed to set SSL CTX function!\n");
424 432
     }
425 433
 #else
426 434
     set_tls_ca_bundle(aws_curl);
... ...
@@ -430,50 +473,50 @@ int main(int argc, char *argv[])
430 430
 
431 431
     json_str = presigned_get_string(ps_json_obj, "acl");
432 432
     if (json_str == NULL) {
433
-        fprintf(stderr, "Error in presigned_get_string parsing acl from json object\n");
434
-        goto cleanup;
433
+        logg("!Error in presigned_get_string parsing acl from json object\n");
434
+        goto done;
435 435
     }
436 436
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "acl", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
437 437
 
438 438
     json_str = presigned_get_string(ps_json_obj, "policy");
439 439
     if (json_str == NULL) {
440
-        fprintf(stderr, "Error in presigned_get_string parsing policy from json object\n");
441
-        goto cleanup;
440
+        logg("!Error in presigned_get_string parsing policy from json object\n");
441
+        goto done;
442 442
     }
443 443
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "policy", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
444 444
 
445 445
     json_str = presigned_get_string(ps_json_obj, "x-amz-meta-original-filename");
446 446
     if (json_str == NULL) {
447
-        fprintf(stderr, "Error in presigned_get_string parsing x-amz-meta-original-filename from json object\n");
448
-        goto cleanup;
447
+        logg("!Error in presigned_get_string parsing x-amz-meta-original-filename from json object\n");
448
+        goto done;
449 449
     }
450 450
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-meta-original-filename", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
451 451
 
452 452
     json_str = presigned_get_string(ps_json_obj, "x-amz-credential");
453 453
     if (json_str == NULL) {
454
-        fprintf(stderr, "Error in presigned_get_string parsing x-amz-credential from json object\n");
455
-        goto cleanup;
454
+        logg("!Error in presigned_get_string parsing x-amz-credential from json object\n");
455
+        goto done;
456 456
     }
457 457
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-credential", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
458 458
 
459 459
     json_str = presigned_get_string(ps_json_obj, "x-amz-algorithm");
460 460
     if (json_str == NULL) {
461
-        fprintf(stderr, "Error in presigned_get_string parsing x-amz-algorithm from json object\n");
462
-        goto cleanup;
461
+        logg("!Error in presigned_get_string parsing x-amz-algorithm from json object\n");
462
+        goto done;
463 463
     }
464 464
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-algorithm", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
465 465
 
466 466
     json_str = presigned_get_string(ps_json_obj, "x-amz-date");
467 467
     if (json_str == NULL) {
468
-        fprintf(stderr, "Error in presigned_get_string parsing x-amz-date from json object\n");
469
-        goto cleanup;
468
+        logg("!Error in presigned_get_string parsing x-amz-date from json object\n");
469
+        goto done;
470 470
     }
471 471
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-date", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
472 472
 
473 473
     json_str = presigned_get_string(ps_json_obj, "x-amz-signature");
474 474
     if (json_str == NULL) {
475
-        fprintf(stderr, "Error in presigned_get_string parsing x-amz-signature from json object\n");
476
-        goto cleanup;
475
+        logg("!Error in presigned_get_string parsing x-amz-signature from json object\n");
476
+        goto done;
477 477
     }
478 478
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-signature", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
479 479
 
... ...
@@ -486,8 +529,8 @@ int main(int argc, char *argv[])
486 486
 
487 487
     res = curl_easy_perform(aws_curl);
488 488
     if (res != CURLE_OK) {
489
-        fprintf(stderr, "Error in POST AWS: %s\n", curl_easy_strerror(res));
490
-        goto cleanup;
489
+        logg("!Error in POST AWS: %s\n", curl_easy_strerror(res));
490
+        goto done;
491 491
     }
492 492
     curl_slist_free_all(slist);
493 493
     slist = NULL;
... ...
@@ -497,36 +540,30 @@ int main(int argc, char *argv[])
497 497
     curl_easy_cleanup(aws_curl);
498 498
     aws_curl = NULL;
499 499
     json_object_put(ps_json_obj);
500
-    free(wd.str);
501
-    wd.str = NULL;
500
+
501
+    if (wd.str != NULL) {
502
+        free(wd.str);
503
+        wd.str = NULL;
504
+    }
502 505
     wd.len = 0;
503 506
 
504 507
     /*** The POST submit to clamav.net ***/
505 508
     slist = curl_slist_append(slist, "Expect:");
506
-    len   = strlen(hd_malware.cfduid) + strlen(hd_malware.session) + 3;
507
-    str   = malloc(len);
508
-    if (str == NULL) {
509
-        fprintf(stderr, "No memory for POST submit cookies.\n");
510
-        goto cleanup;
511
-    }
512
-    if (snprintf(str, len, "%s; %s;", hd_malware.cfduid, hd_malware.session) > len) {
513
-        fprintf(stderr, "snprintf() failed formatting POST submit cookies\n");
514
-        free(str);
515
-        goto cleanup;
516
-    }
517
-    curl_easy_setopt(clam_curl, CURLOPT_COOKIE, str);
518
-    free(str);
509
+
510
+    if (NULL != session_cookie) {
511
+        curl_easy_setopt(clam_curl, CURLOPT_COOKIE, session_cookie);
512
+    }
513
+
519 514
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "utf8", CURLFORM_COPYCONTENTS, "\x27\x13", CURLFORM_END);
520 515
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "authenticity_token", CURLFORM_COPYCONTENTS, authenticity_token, CURLFORM_END);
521 516
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "submissionID", CURLFORM_COPYCONTENTS, submissionID, CURLFORM_END);
522 517
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "type", CURLFORM_COPYCONTENTS, malware ? "malware" : "fp", CURLFORM_END);
523 518
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendername", CURLFORM_COPYCONTENTS, name, CURLFORM_END);
524 519
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "email", CURLFORM_COPYCONTENTS, email, CURLFORM_END);
525
-    if (malware == 0) {
526
-        curl_formadd(&post, &last, CURLFORM_COPYNAME, "virusname", CURLFORM_COPYCONTENTS, fpvname, CURLFORM_END);
520
+    if (malware == true) {
521
+        curl_formadd(&post, &last, CURLFORM_COPYNAME, "shareSample", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
527 522
     } else {
528
-        if (malware == 1)
529
-            curl_formadd(&post, &last, CURLFORM_COPYNAME, "shareSample", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
523
+        curl_formadd(&post, &last, CURLFORM_COPYNAME, "virusname", CURLFORM_COPYCONTENTS, fpvname, CURLFORM_END);
530 524
     }
531 525
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "description", CURLFORM_COPYCONTENTS, "clamsubmit", CURLFORM_END);
532 526
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "notify", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
... ...
@@ -537,37 +574,43 @@ int main(int argc, char *argv[])
537 537
     curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, NULL);
538 538
     res = curl_easy_perform(clam_curl);
539 539
     if (res != CURLE_OK) {
540
-        fprintf(stderr, "Error in POST submit: %s\n", curl_easy_strerror(res));
541
-        goto cleanup;
540
+        logg("!Error in POST submit: %s\n", curl_easy_strerror(res));
541
+        goto done;
542 542
     } else {
543 543
         long response_code;
544 544
         curl_easy_getinfo(clam_curl, CURLINFO_RESPONSE_CODE, &response_code);
545 545
         if (response_code / 100 == 3) {
546
-            curl_easy_getinfo(clam_curl, CURLINFO_REDIRECT_URL, &urlp);
547
-            if (urlp == NULL) {
548
-                fprintf(stderr, "POST submit Location URL is NULL.\n");
549
-                goto cleanup;
546
+            curl_easy_getinfo(clam_curl, CURLINFO_REDIRECT_URL, &url_for_auth_token);
547
+            if (url_for_auth_token == NULL) {
548
+                logg("!POST submit Location URL is NULL.\n");
549
+                goto done;
550 550
             }
551
-            sp = strstr(urlp, "/reports/");
551
+            sp = strstr(url_for_auth_token, "/reports/");
552 552
             if (sp == NULL) {
553
-                fprintf(stderr, "POST submit Location URL is malformed.\n");
553
+                logg("!POST submit Location URL is malformed.\n");
554 554
             } else if (!strcmp(sp, "/reports/success")) {
555
-                fprintf(stdout, "Submission success!\n");
555
+                logg("Submission success!\n");
556 556
                 status = 0;
557 557
             } else if (!strcmp(sp, "/reports/failure")) {
558
-                fprintf(stdout, "Submission failed\n");
558
+                logg("Submission failed\n");
559 559
             } else {
560
-                fprintf(stdout, "Unknown submission status %s\n", sp);
560
+                logg("Unknown submission status %s\n", sp);
561 561
             }
562 562
         } else {
563
-            fprintf(stderr, "Unexpected POST submit response code: %li\n", response_code);
563
+            logg("!Unexpected POST submit response code: %li\n", response_code);
564 564
         }
565 565
     }
566 566
 
567
-cleanup:
567
+done:
568 568
     /*
569 569
      * Cleanup
570 570
      */
571
+    if (authenticity_token_header != NULL) {
572
+        free(authenticity_token_header);
573
+    }
574
+    if (session_cookie != NULL) {
575
+        free(session_cookie);
576
+    }
571 577
     if (slist != NULL) {
572 578
         curl_slist_free_all(slist);
573 579
     }
... ...
@@ -587,15 +630,9 @@ cleanup:
587 587
         wd.str = NULL;
588 588
         wd.len = 0;
589 589
     }
590
-    if (hd_malware.cfduid != NULL) {
591
-        free(hd_malware.cfduid);
592
-    }
593 590
     if (hd_malware.session != NULL) {
594 591
         free(hd_malware.session);
595 592
     }
596
-    if (hd_presigned.cfduid != NULL) {
597
-        free(hd_presigned.cfduid);
598
-    }
599 593
     if (hd_presigned.session != NULL) {
600 594
         free(hd_presigned.session);
601 595
     }
... ...
@@ -24,7 +24,9 @@
24 24
 #include <stdio.h>
25 25
 #include <stdlib.h>
26 26
 #include <string.h>
27
+#ifndef _WIN32
27 28
 #include <unistd.h>
29
+#endif
28 30
 #include <sys/types.h>
29 31
 #include <sys/stat.h>
30 32
 #include <fcntl.h>