Browse code

Changing urls to https, improved error checking, and adding additional cleanup step at the end.

Micah Snyder authored on 2018/05/24 05:23:27
Showing 1 changed files
... ...
@@ -108,6 +108,13 @@ size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
108 108
     return len;
109 109
 }
110 110
 
111
+/**
112
+ * @brief Parse a value from a JSON object, given a key.
113
+ * 
114
+ * @param ps_json_obj   The JSON object
115
+ * @param key           The Key
116
+ * @return const char*  The Value on Success, NULL on Failure.
117
+ */
111 118
 const char* presigned_get_string(json_object * ps_json_obj, char * key)
112 119
 {
113 120
     json_object * json_obj = NULL;
... ...
@@ -117,18 +124,17 @@ const char* presigned_get_string(json_object * ps_json_obj, char * key)
117 117
         json_str = json_object_get_string(json_obj);
118 118
         if (json_str == NULL) {
119 119
             fprintf(stderr, "Error: json_object_get_string() for %s.\n", key);
120
-            exit(1);
121 120
         }
122 121
     } else {
123 122
         fprintf(stderr, "Error: json_object_object_get_ex() for %s.\n", key);
124
-        exit(1);
125 123
     }
126 124
     return json_str;
127 125
 }
128 126
 
129 127
 int main(int argc, char *argv[])
130 128
 {
131
-    CURL *clam_curl, *aws_curl;
129
+    int status = 1;
130
+    CURL *clam_curl = NULL, *aws_curl = NULL;
132 131
     CURLcode res;
133 132
     int ch;
134 133
     struct curl_httppost *post=NULL, *last=NULL;
... ...
@@ -146,7 +152,7 @@ int main(int argc, char *argv[])
146 146
     char * submissionID = NULL;
147 147
     char * fpvname = NULL;
148 148
     char *sp, *ep, *str;
149
-    char * authenticity_token;
149
+    char * authenticity_token = NULL;
150 150
     char * urlp;
151 151
 
152 152
     curl_global_init(CURL_GLOBAL_ALL);
... ...
@@ -154,7 +160,7 @@ int main(int argc, char *argv[])
154 154
     clam_curl = curl_easy_init();
155 155
     if (clam_curl == NULL) {
156 156
         fprintf(stderr, "ERROR: Could not initialize libcurl.\n");
157
-        exit(1);
157
+        goto cleanup;
158 158
     }
159 159
 
160 160
     while ((ch = my_getopt(argc, argv, OPTS)) > 0) {
... ...
@@ -200,7 +206,7 @@ int main(int argc, char *argv[])
200 200
         filename = read_stream();
201 201
         if (!(filename)) {
202 202
             fprintf(stderr, "ERROR: Unable to read stream\n");
203
-            exit(1);
203
+            goto cleanup;
204 204
         }
205 205
         fromStream=1;
206 206
     }
... ...
@@ -208,9 +214,9 @@ int main(int argc, char *argv[])
208 208
 
209 209
     /*** The GET malware|fp ***/
210 210
     if (malware == 1)
211
-        urlp = "http://www.clamav.net/reports/malware";
211
+        urlp = "https://www.clamav.net/reports/malware";
212 212
     else
213
-        urlp = "http://www.clamav.net/reports/fp";
213
+        urlp = "https://www.clamav.net/reports/fp";
214 214
     curl_easy_setopt(clam_curl, CURLOPT_URL, urlp);
215 215
     curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1);
216 216
     curl_easy_setopt(clam_curl, CURLOPT_WRITEDATA, &wd);
... ...
@@ -218,31 +224,31 @@ int main(int argc, char *argv[])
218 218
     curl_easy_setopt(clam_curl, CURLOPT_HEADERDATA, &hd_malware);
219 219
     curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
220 220
     res = curl_easy_perform(clam_curl);
221
-    if (res) {
221
+    if (res != CURLE_OK) {
222 222
         fprintf(stderr, "Error in GET %s: %s\n", urlp , curl_easy_strerror(res));
223
-        exit(1);
223
+        goto cleanup;
224 224
     }
225 225
     if (wd.str != NULL) {
226 226
         sp = strstr(wd.str, "name=\"authenticity_token\"");
227 227
         if (sp == NULL) {
228 228
             fprintf (stderr, "Authenticity token element not found.\n");
229
-            exit(1);
229
+            goto cleanup;
230 230
         }
231 231
         sp = strstr(sp, "value=");
232 232
         if (sp == NULL) {
233 233
             fprintf (stderr, "Authenticity token value not found.\n");
234
-            exit(1);
234
+            goto cleanup;
235 235
         }
236 236
         sp += 7;
237 237
         ep = strchr(sp, '"');
238 238
         if (ep == NULL) {
239 239
             fprintf (stderr, "Authenticity token malformed.\n");
240
-            exit(1);
240
+            goto cleanup;
241 241
         }
242 242
         authenticity_token = malloc(ep-sp+1);
243 243
         if (authenticity_token == NULL) {
244 244
             fprintf (stderr, "no memory for authenticity token.\n");
245
-            exit(1);
245
+            goto cleanup;
246 246
         }
247 247
         memcpy(authenticity_token, sp, ep-sp);
248 248
         authenticity_token[ep-sp] = '\0';
... ...
@@ -255,25 +261,25 @@ int main(int argc, char *argv[])
255 255
 
256 256
     /*** The GET presigned ***/
257 257
     if (malware == 1)
258
-        curl_easy_setopt(clam_curl, CURLOPT_URL, "http://www.clamav.net/presigned?type=malware");
258
+        curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=malware");
259 259
     else
260
-        curl_easy_setopt(clam_curl, CURLOPT_URL, "http://www.clamav.net/presigned?type=fp");
260
+        curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=fp");
261 261
     curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1);
262 262
 
263 263
     if (NULL == hd_malware.cfduid || NULL == hd_malware.session) {
264 264
         fprintf (stderr, "invalid cfduid and/or session id values provided by clamav.net/presigned. Unable to continue submission.");
265
-        exit(1);
265
+        goto cleanup;
266 266
     }
267 267
 
268 268
     len = strlen(hd_malware.cfduid) + strlen(hd_malware.session) + 3;
269 269
     str = malloc(len);
270 270
     if (str == NULL) {
271 271
         fprintf(stderr, "No memory for GET presigned cookies\n");
272
-        exit(1);
272
+        goto cleanup;
273 273
     }
274 274
     if (snprintf(str, len, "%s; %s;", hd_malware.cfduid, hd_malware.session) > len) {
275 275
         fprintf(stderr, "snprintf() failed formatting GET presigned cookies\n");
276
-        exit(1);
276
+        goto cleanup;
277 277
     }
278 278
     curl_easy_setopt(clam_curl, CURLOPT_COOKIE, str);
279 279
     free(str);
... ...
@@ -281,11 +287,12 @@ int main(int argc, char *argv[])
281 281
     str = malloc(len);
282 282
     if (str == NULL) {
283 283
         fprintf(stderr, "No memory for GET presigned X-CSRF-Token\n");
284
-        exit(1);
284
+        goto cleanup;
285 285
     }
286 286
     if (snprintf(str, len, "X-CSRF-Token: %s", authenticity_token) > len) {
287 287
         fprintf(stderr, "snprintf() failed for GET presigned X-CSRF-Token\n");
288
-        exit(1);
288
+        free(str);
289
+        goto cleanup;
289 290
     }
290 291
     slist = curl_slist_append(slist, str);
291 292
     free(str);
... ...
@@ -293,14 +300,14 @@ int main(int argc, char *argv[])
293 293
     curl_easy_setopt(clam_curl, CURLOPT_HEADERDATA, &hd_presigned);
294 294
     curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
295 295
     if (malware ==1)
296
-        curl_easy_setopt(clam_curl, CURLOPT_REFERER, "http://www.clamav.net/reports/malware");
296
+        curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/malware");
297 297
     else
298
-        curl_easy_setopt(clam_curl, CURLOPT_REFERER, "http://www.clamav.net/reports/fp");
298
+        curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/fp");
299 299
 
300 300
     res = curl_easy_perform(clam_curl);
301
-    if (res) {
301
+    if (res != CURLE_OK) {
302 302
         fprintf(stderr, "Error in GET presigned: %s\n", curl_easy_strerror(res));
303
-        exit(1);
303
+        goto cleanup;
304 304
     }
305 305
     curl_slist_free_all(slist);
306 306
     slist = NULL;
... ...
@@ -310,58 +317,99 @@ int main(int argc, char *argv[])
310 310
     ps_json_obj = json_tokener_parse(wd.str);
311 311
     if (ps_json_obj == NULL) {
312 312
         fprintf(stderr, "Error in json_tokener_parse of %.*s\n", wd.len, wd.str);
313
-        exit(1);
313
+        goto cleanup;
314 314
     }
315 315
     json_str = presigned_get_string(ps_json_obj, "key");
316
+    if (json_str == NULL) {
317
+        fprintf(stderr, "Error in presigned_get_string parsing key from json object\n");
318
+        goto cleanup;
319
+    }
316 320
     sp = strchr(json_str, '/');
317 321
     if (sp == NULL) {
318 322
         fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '/'.\n");
319
-        exit (1);
323
+        goto cleanup;
320 324
     }
321 325
     sp++;
322 326
     ep = strchr(sp, '-');
323 327
     if (ep == NULL) {
324 328
         fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '-'.\n");
325
-        exit (1);
329
+        goto cleanup;
326 330
     }
327 331
     submissionID = malloc(ep-sp+1);
328 332
     if (submissionID == NULL) {
329 333
         fprintf(stderr, "Error: malloc submissionID.\n");
330
-        exit (1);
334
+        goto cleanup;
331 335
     }
332 336
     memcpy(submissionID, sp, ep-sp);
333 337
     submissionID[ep-sp] = '\0';
334 338
     aws_curl = curl_easy_init();
335 339
     if (!(aws_curl)) {
336 340
         fprintf(stderr, "ERROR: Could not initialize libcurl POST presigned\n");
337
-        exit(1);
341
+        goto cleanup;
338 342
     }
339 343
     submissionID[ep-sp] = '\0';
340 344
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "key", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
345
+
341 346
     json_str = presigned_get_string(ps_json_obj, "acl");
347
+    if (json_str == NULL) {
348
+        fprintf(stderr, "Error in presigned_get_string parsing acl from json object\n");
349
+        goto cleanup;
350
+    }
342 351
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "acl", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
352
+
343 353
     json_str = presigned_get_string(ps_json_obj, "policy");
354
+    if (json_str == NULL) {
355
+        fprintf(stderr, "Error in presigned_get_string parsing policy from json object\n");
356
+        goto cleanup;
357
+    }
344 358
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "policy", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
359
+
345 360
     json_str = presigned_get_string(ps_json_obj, "x-amz-meta-original-filename");
361
+    if (json_str == NULL) {
362
+        fprintf(stderr, "Error in presigned_get_string parsing x-amz-meta-original-filename from json object\n");
363
+        goto cleanup;
364
+    }
346 365
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-meta-original-filename", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
366
+
347 367
     json_str = presigned_get_string(ps_json_obj, "x-amz-credential");
368
+    if (json_str == NULL) {
369
+        fprintf(stderr, "Error in presigned_get_string parsing x-amz-credential from json object\n");
370
+        goto cleanup;
371
+    }
348 372
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-credential", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
373
+
349 374
     json_str = presigned_get_string(ps_json_obj, "x-amz-algorithm");
375
+    if (json_str == NULL) {
376
+        fprintf(stderr, "Error in presigned_get_string parsing x-amz-algorithm from json object\n");
377
+        goto cleanup;
378
+    }
350 379
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-algorithm", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
380
+
351 381
     json_str = presigned_get_string(ps_json_obj, "x-amz-date");
382
+    if (json_str == NULL) {
383
+        fprintf(stderr, "Error in presigned_get_string parsing x-amz-date from json object\n");
384
+        goto cleanup;
385
+    }
352 386
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-date", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
387
+
353 388
     json_str = presigned_get_string(ps_json_obj, "x-amz-signature");
389
+    if (json_str == NULL) {
390
+        fprintf(stderr, "Error in presigned_get_string parsing x-amz-signature from json object\n");
391
+        goto cleanup;
392
+    }
354 393
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-signature", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
394
+
355 395
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, filename, CURLFORM_END);
396
+
356 397
     slist = curl_slist_append(slist, "Expect:");
357 398
     curl_easy_setopt(aws_curl, CURLOPT_HTTPHEADER, slist);
358
-    curl_easy_setopt(aws_curl, CURLOPT_URL, "http://clamav-site.s3.amazonaws.com/");
399
+    curl_easy_setopt(aws_curl, CURLOPT_URL, "https://clamav-site.s3.amazonaws.com/");
359 400
     curl_easy_setopt(aws_curl, CURLOPT_HTTPPOST, post);
360 401
 
361 402
     res = curl_easy_perform(aws_curl);
362
-    if (res) {
403
+    if (res != CURLE_OK) {
363 404
         fprintf(stderr, "Error in POST AWS: %s\n", curl_easy_strerror(res));
364
-        exit(1);
405
+        goto cleanup;
365 406
     }
366 407
     curl_slist_free_all(slist);
367 408
     slist = NULL;
... ...
@@ -381,11 +429,11 @@ int main(int argc, char *argv[])
381 381
     str = malloc(len);
382 382
     if (str == NULL) {
383 383
         fprintf(stderr, "No memory for POST submit cookies.\n");
384
-        exit(1);
384
+        goto cleanup;
385 385
     }
386 386
     if (snprintf(str, len, "%s; %s;", hd_malware.cfduid, hd_malware.session) > len) {
387 387
         fprintf(stderr, "snprintf() failed formatting POST submit cookies\n");
388
-        exit(1);
388
+        goto cleanup;
389 389
     }
390 390
     curl_easy_setopt(clam_curl, CURLOPT_COOKIE, str);
391 391
     free(str);
... ...
@@ -405,13 +453,13 @@ int main(int argc, char *argv[])
405 405
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "notify", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
406 406
     curl_formadd(&post, &last, CURLFORM_COPYNAME, "privacy", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
407 407
     curl_easy_setopt(clam_curl, CURLOPT_HTTPHEADER, slist);
408
-    curl_easy_setopt(clam_curl, CURLOPT_URL, "http://www.clamav.net/reports/submit");
408
+    curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/reports/submit");
409 409
     curl_easy_setopt(clam_curl, CURLOPT_HTTPPOST, post);
410 410
     curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, NULL);
411 411
     res = curl_easy_perform(clam_curl);
412
-    if (res) {
412
+    if (res != CURLE_OK) {
413 413
         fprintf(stderr, "Error in POST submit: %s\n", curl_easy_strerror(res));
414
-        exit(1);
414
+        goto cleanup;
415 415
     } else {
416 416
         long response_code;
417 417
         curl_easy_getinfo(clam_curl, CURLINFO_RESPONSE_CODE, &response_code);
... ...
@@ -419,43 +467,75 @@ int main(int argc, char *argv[])
419 419
             curl_easy_getinfo(clam_curl, CURLINFO_REDIRECT_URL, &urlp);
420 420
             if (urlp == NULL) {
421 421
                 fprintf(stderr, "POST submit Location URL is NULL.\n");
422
-                exit(1);
422
+                goto cleanup;
423 423
             }
424 424
             sp = strstr(urlp, "/reports/");
425 425
             if (sp == NULL) {
426 426
                 fprintf(stderr, "POST submit Location URL is malformed.\n");
427
-                exit(1);
428 427
             }
429
-            if (!strcmp(sp, "/reports/success"))
428
+            else if (!strcmp(sp, "/reports/success")) {
430 429
                 fprintf(stdout, "Submission success!\n");
431
-            else if (!strcmp(sp, "/reports/failure"))
430
+                status = 0;
431
+            }
432
+            else if (!strcmp(sp, "/reports/failure")) {
432 433
                 fprintf(stdout, "Submission failed\n");
433
-            else
434
+            }
435
+            else {
434 436
                 fprintf(stdout, "Unknown submission status %s\n", sp);
437
+            }
435 438
         }
436
-        else
439
+        else {
437 440
             fprintf(stderr, "Unexpected POST submit response code: %li\n", response_code);
441
+        }
438 442
     }
439
-    curl_slist_free_all(slist);
440
-    curl_formfree(post);
441
-    curl_easy_cleanup(clam_curl);
443
+
444
+cleanup:
445
+    /* 
446
+     * Cleanup
447
+     */
448
+    if (slist != NULL) {
449
+        curl_slist_free_all(slist);
450
+    }
451
+    if (post != NULL) {
452
+        curl_formfree(post);
453
+    }
454
+    if (clam_curl != NULL) {
455
+        curl_easy_cleanup(clam_curl);
456
+    }
457
+    if (aws_curl != NULL) {
458
+        curl_easy_cleanup(aws_curl);
459
+    }
460
+    curl_global_cleanup();
461
+
442 462
     if (wd.str != NULL) {
443 463
         free(wd.str);
444 464
         wd.str = NULL;
445 465
         wd.len = 0;
446 466
     }
447
-    free(hd_malware.cfduid);
448
-    free(hd_malware.session);
449
-    free(hd_presigned.cfduid);
450
-    free(hd_presigned.session);
451
-    free(submissionID);
452
-    free(authenticity_token);
453
-    if (fromStream) {
467
+    if (hd_malware.cfduid != NULL) {
468
+        free(hd_malware.cfduid);
469
+    }
470
+    if (hd_malware.session != NULL) {
471
+        free(hd_malware.session);
472
+    }
473
+    if (hd_presigned.cfduid != NULL) {
474
+        free(hd_presigned.cfduid);
475
+    }
476
+    if (hd_presigned.session != NULL) {
477
+        free(hd_presigned.session);
478
+    }
479
+    if (submissionID != NULL) {
480
+        free(submissionID);
481
+    } 
482
+    if (authenticity_token != NULL) {
483
+        free(authenticity_token);
484
+    }
485
+    if ((fromStream != 0) && (filename != NULL)) {
454 486
         remove(filename);
455 487
         free(filename);
456 488
     }
457 489
 
458
-    return 0;
490
+    return status;
459 491
 }
460 492
 
461 493