f3107383 |
#include <stdio.h> |
2682e7dd |
#include <stdlib.h> |
694e7882 |
#if HAVE_UNISTD_H |
2682e7dd |
#include <unistd.h> |
694e7882 |
#endif |
2682e7dd |
#include <string.h>
|
694e7882 |
#ifdef _WIN32
#include <Windows.h>
#include <wincrypt.h>
#endif
|
2682e7dd |
#include <curl/curl.h>
|
0df117dd |
#include "target.h" |
2682e7dd |
#include "libclamav/clamav.h"
#include "libclamav/others.h" |
2f91ff37 |
#include "shared/misc.h" |
76cab989 |
#include "shared/getopt.h" |
80687264 |
#if defined(C_DARWIN) || defined(_WIN32)
#include "shared/cert_util.h"
#endif |
2682e7dd |
|
3733023f |
#define OPTS "e:p:n:N:V:H:h?v?d" |
542d8518 |
|
a7cba048 |
char *read_stream(void); |
6df13d04 |
void usage(char *name);
void version(void); |
a7cba048 |
|
5c866010 |
typedef struct _header_data {
int len; |
288057e9 |
char *cfduid;
char *session; |
5c866010 |
} header_data;
typedef struct _write_data {
int len; |
288057e9 |
char *str; |
5c866010 |
} write_data;
|
694e7882 |
int g_debug = 0;
|
2682e7dd |
void usage(char *name)
{ |
e098cdc5 |
printf("\n"); |
694e7882 |
printf(" Clam AntiVirus: Malware and False Positive Reporting Tool %s\n", get_version()); |
964a1e73 |
printf(" By The ClamAV Team: https://www.clamav.net/about.html#credits\n"); |
e1cbc270 |
printf(" (C) 2019 Cisco Systems, Inc.\n"); |
e098cdc5 |
printf("\n"); |
694e7882 |
printf(" %s -hHinpVvd?\n", name); |
e098cdc5 |
printf("\n");
printf(" -h or -? Show this help\n");
printf(" -v Show version\n");
printf(" -e [EMAIL] Your email address (required)\n");
printf(" -n [FILE/-] Submit a false negative (FN)\n");
printf(" -N [NAME] Your name contained in quotation marks (required)\n");
printf(" -p [FILE/-] Submit a false positive (FP)\n");
printf(" -V [VIRUS] Detected virus name (required with -p)\n"); |
694e7882 |
printf(" -d Enable debug output\n"); |
e098cdc5 |
printf("\n");
printf("You must specify -n or -p. Both are mutually exclusive. Pass in - as the filename for stdin.\n\n"); |
2682e7dd |
exit(0);
} |
f3107383 |
|
2f91ff37 |
void version(void)
{
print_version(NULL);
exit(0);
}
|
5c866010 |
size_t header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{ |
288057e9 |
int len = size * nmemb; |
5c866010 |
char *sp, *ep, *mem; |
288057e9 |
header_data *hd = (header_data *)userdata; |
5c866010 |
const char *set_cookie = "Set-Cookie:"; |
288057e9 |
int clen = strlen(set_cookie); |
5c866010 |
if (len > clen) {
if (strncmp(ptr, set_cookie, clen))
return len;
sp = ptr + clen + 1;
ep = strchr(sp, ';');
if (ep == NULL) {
fprintf(stderr, "header_cb(): malformed cookie\n");
return 0;
} |
288057e9 |
mem = malloc(ep - sp + 1); |
5c866010 |
if (mem == NULL) {
fprintf(stderr, "header_cb(): malloc failed\n");
return 0;
} |
288057e9 |
memcpy(mem, sp, ep - sp);
mem[ep - sp] = '\0'; |
5c866010 |
if (!strncmp(mem, "__cfduid", 8))
hd->cfduid = mem;
else if (!strncmp(mem, "_clamav-net_session", strlen("_clamav-net_session")))
hd->session = mem;
else
fprintf(stderr, "header_cb(): unrecognized cookie\n");
}
return len;
}
size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{ |
288057e9 |
int len = size * nmemb;
char *str;
write_data *wd = (write_data *)userdata; |
5c866010 |
if (len) {
str = realloc(wd->str, wd->len + len + 1);
if (str == NULL) { |
288057e9 |
fprintf(stderr, "write_cb() realloc failure\n"); |
5c866010 |
return 0;
}
memcpy(str + wd->len, ptr, len);
str[wd->len + len] = '\0'; |
288057e9 |
wd->str = str; |
5c866010 |
wd->len += len;
}
return len;
}
|
ab9114a3 |
/**
* @brief Parse a value from a JSON object, given a key. |
694e7882 |
* |
ab9114a3 |
* @param ps_json_obj The JSON object
* @param key The Key
* @return const char* The Value on Success, NULL on Failure.
*/ |
288057e9 |
const char *presigned_get_string(json_object *ps_json_obj, char *key) |
5c866010 |
{ |
288057e9 |
json_object *json_obj = NULL;
const char *json_str = NULL; |
5c866010 |
if (json_object_object_get_ex(ps_json_obj, key, &json_obj)) {
json_str = json_object_get_string(json_obj);
if (json_str == NULL) {
fprintf(stderr, "Error: json_object_get_string() for %s.\n", key);
}
} else {
fprintf(stderr, "Error: json_object_object_get_ex() for %s.\n", key);
}
return json_str;
}
|
f3107383 |
int main(int argc, char *argv[])
{ |
0df117dd |
int status = 1;
char userAgent[128]; |
ab9114a3 |
CURL *clam_curl = NULL, *aws_curl = NULL; |
2682e7dd |
CURLcode res;
int ch; |
288057e9 |
struct curl_httppost *post = NULL, *last = NULL; |
2682e7dd |
struct curl_slist *slist = NULL; |
288057e9 |
char *name = NULL, *email = NULL, *filename = NULL;
int setURL = 0, fromStream = 0;
const char *json_str;
write_data wd = {0, NULL};
header_data hd_malware = {0, NULL, NULL}; |
5c866010 |
header_data hd_presigned = {0, NULL, NULL}; |
288057e9 |
json_object *ps_json_obj = NULL;
int malware = 0;
int len = 0;
char *submissionID = NULL;
char *fpvname = NULL; |
5c866010 |
char *sp, *ep, *str; |
288057e9 |
char *authenticity_token = NULL;
char *urlp; |
a7cba048 |
curl_global_init(CURL_GLOBAL_ALL);
|
5c866010 |
clam_curl = curl_easy_init();
if (clam_curl == NULL) {
fprintf(stderr, "ERROR: Could not initialize libcurl.\n"); |
ab9114a3 |
goto cleanup; |
a7cba048 |
} |
2682e7dd |
|
0df117dd |
memset(userAgent, 0, sizeof(userAgent));
snprintf(userAgent, sizeof(userAgent),
PACKAGE "/%s (OS: " TARGET_OS_TYPE ", ARCH: " TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE ")",
get_version());
userAgent[sizeof(userAgent) - 1] = 0;
if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_USERAGENT, userAgent)) {
fprintf(stderr, "!create_curl_handle: Failed to set CURLOPT_USERAGENT (%s)!\n", userAgent);
}
|
542d8518 |
while ((ch = my_getopt(argc, argv, OPTS)) > 0) { |
b28c454e |
switch (ch) { |
2f91ff37 |
case 'v':
version(); |
5c866010 |
break; |
b28c454e |
case 'e':
email = optarg;
break;
case 'N':
name = optarg;
break; |
a7cba048 |
case 'p':
if (setURL)
usage(argv[0]);
filename = optarg;
break;
case 'n':
if (setURL)
usage(argv[0]); |
288057e9 |
malware = 1; |
a7cba048 |
filename = optarg; |
5c866010 |
break;
case 'V':
fpvname = optarg; |
a7cba048 |
break; |
694e7882 |
case 'd':
g_debug = 1;
break; |
b28c454e |
case 'h':
case '?': |
a7cba048 |
default: |
b28c454e |
usage(argv[0]);
} |
2682e7dd |
}
|
a7cba048 |
if (!(name) || !(email) || !(filename)) |
b28c454e |
usage(argv[0]);
|
5c866010 |
if (malware == 0 && fpvname == NULL) {
fprintf(stderr, "Detected virus name(-V) required for false positive submissions.\n");
usage(argv[0]);
} |
a7cba048 |
if (strlen(filename) == 1 && filename[0] == '-') {
filename = read_stream();
if (!(filename)) {
fprintf(stderr, "ERROR: Unable to read stream\n"); |
ab9114a3 |
goto cleanup; |
a7cba048 |
} |
288057e9 |
fromStream = 1; |
a7cba048 |
} |
2682e7dd |
|
43422579 |
if (g_debug) {
/* ask libcurl to show us the verbose output */
if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_VERBOSE, 1L)) {
fprintf(stderr, "!ERROR: Failed to set CURLOPT_VERBOSE!\n");
}
if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_STDERR, stdout)) {
fprintf(stderr, "!ERROR: Failed to direct curl debug output to stdout!\n");
}
}
if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1)) {
fprintf(stderr, "ERROR: Failed to set HTTP version to 1.1 (to prevent 2.0 responses which we don't yet parse properly)!\n");
} |
3733023f |
|
80687264 |
#if defined(C_DARWIN) || defined(_WIN32) |
3733023f |
if (CURLE_OK != curl_easy_setopt(clam_curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function)) { |
694e7882 |
fprintf(stderr, "ERROR: Failed to set SSL CTX function!\n");
}
#endif
|
5c866010 |
/*** The GET malware|fp ***/
if (malware == 1) |
ab9114a3 |
urlp = "https://www.clamav.net/reports/malware"; |
5c866010 |
else |
ab9114a3 |
urlp = "https://www.clamav.net/reports/fp"; |
5c866010 |
curl_easy_setopt(clam_curl, CURLOPT_URL, urlp);
curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(clam_curl, CURLOPT_WRITEDATA, &wd);
curl_easy_setopt(clam_curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(clam_curl, CURLOPT_HEADERDATA, &hd_malware);
curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
res = curl_easy_perform(clam_curl); |
ab9114a3 |
if (res != CURLE_OK) { |
288057e9 |
fprintf(stderr, "Error in GET %s: %s\n", urlp, curl_easy_strerror(res)); |
ab9114a3 |
goto cleanup; |
a7cba048 |
} |
5c866010 |
if (wd.str != NULL) {
sp = strstr(wd.str, "name=\"authenticity_token\"");
if (sp == NULL) { |
288057e9 |
fprintf(stderr, "Authenticity token element not found.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
sp = strstr(sp, "value=");
if (sp == NULL) { |
288057e9 |
fprintf(stderr, "Authenticity token value not found.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
sp += 7;
ep = strchr(sp, '"');
if (ep == NULL) { |
288057e9 |
fprintf(stderr, "Authenticity token malformed.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
} |
288057e9 |
authenticity_token = malloc(ep - sp + 1); |
5c866010 |
if (authenticity_token == NULL) { |
288057e9 |
fprintf(stderr, "no memory for authenticity token.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
} |
288057e9 |
memcpy(authenticity_token, sp, ep - sp);
authenticity_token[ep - sp] = '\0';
free(wd.str); |
5c866010 |
wd.str = NULL; |
a7cba048 |
} |
5c866010 |
wd.len = 0; |
288057e9 |
urlp = NULL; |
5c866010 |
/*** The GET presigned ***/
if (malware == 1) |
ab9114a3 |
curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=malware"); |
5c866010 |
else |
ab9114a3 |
curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=fp"); |
5c866010 |
curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1); |
0a29bc85 |
if (NULL == hd_malware.cfduid || NULL == hd_malware.session) { |
288057e9 |
fprintf(stderr, "invalid cfduid and/or session id values provided by clamav.net/presigned. Unable to continue submission."); |
ab9114a3 |
goto cleanup; |
0a29bc85 |
}
|
5c866010 |
len = strlen(hd_malware.cfduid) + strlen(hd_malware.session) + 3;
str = malloc(len);
if (str == NULL) {
fprintf(stderr, "No memory for GET presigned cookies\n"); |
ab9114a3 |
goto cleanup; |
a7cba048 |
} |
5c866010 |
if (snprintf(str, len, "%s; %s;", hd_malware.cfduid, hd_malware.session) > len) {
fprintf(stderr, "snprintf() failed formatting GET presigned cookies\n"); |
9267de60 |
free(str); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
curl_easy_setopt(clam_curl, CURLOPT_COOKIE, str);
free(str);
len = strlen(authenticity_token) + 15;
str = malloc(len);
if (str == NULL) {
fprintf(stderr, "No memory for GET presigned X-CSRF-Token\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
if (snprintf(str, len, "X-CSRF-Token: %s", authenticity_token) > len) {
fprintf(stderr, "snprintf() failed for GET presigned X-CSRF-Token\n"); |
ab9114a3 |
free(str);
goto cleanup; |
5c866010 |
}
slist = curl_slist_append(slist, str);
free(str);
curl_easy_setopt(clam_curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(clam_curl, CURLOPT_HEADERDATA, &hd_presigned);
curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb); |
288057e9 |
if (malware == 1) |
ab9114a3 |
curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/malware"); |
5c866010 |
else |
ab9114a3 |
curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/fp"); |
5c866010 |
res = curl_easy_perform(clam_curl); |
ab9114a3 |
if (res != CURLE_OK) { |
5c866010 |
fprintf(stderr, "Error in GET presigned: %s\n", curl_easy_strerror(res)); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
curl_slist_free_all(slist);
slist = NULL; |
2682e7dd |
|
5c866010 |
/*** The POST to AWS ***/
ps_json_obj = json_tokener_parse(wd.str);
if (ps_json_obj == NULL) {
fprintf(stderr, "Error in json_tokener_parse of %.*s\n", wd.len, wd.str); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
json_str = presigned_get_string(ps_json_obj, "key"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing key from json object\n");
goto cleanup;
} |
5c866010 |
sp = strchr(json_str, '/');
if (sp == NULL) {
fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '/'.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
sp++;
ep = strchr(sp, '-');
if (ep == NULL) {
fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '-'.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
} |
3733023f |
|
288057e9 |
submissionID = malloc(ep - sp + 1); |
5c866010 |
if (submissionID == NULL) {
fprintf(stderr, "Error: malloc submissionID.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
} |
288057e9 |
memcpy(submissionID, sp, ep - sp);
submissionID[ep - sp] = '\0'; |
3733023f |
|
43422579 |
aws_curl = curl_easy_init(); |
5c866010 |
if (!(aws_curl)) {
fprintf(stderr, "ERROR: Could not initialize libcurl POST presigned\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
} |
3733023f |
|
0df117dd |
if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_USERAGENT, userAgent)) {
fprintf(stderr, "!create_curl_handle: Failed to set CURLOPT_USERAGENT (%s)!\n", userAgent);
}
|
43422579 |
if (g_debug) {
/* ask libcurl to show us the verbose output */
if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_VERBOSE, 1L)) {
fprintf(stderr, "!ERROR: Failed to set CURLOPT_VERBOSE!\n");
}
if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_STDERR, stdout)) {
fprintf(stderr, "!ERROR: Failed to direct curl debug output to stdout!\n");
}
} |
3733023f |
|
43422579 |
if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1)) {
fprintf(stderr, "ERROR: Failed to set HTTP version to 1.1 (to prevent 2.0 responses which we don't yet parse properly)!\n");
} |
3733023f |
|
0df117dd |
#if defined(C_DARWIN) || defined(_WIN32) |
43422579 |
if (CURLE_OK != curl_easy_setopt(aws_curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function)) {
fprintf(stderr, "ERROR: Failed to set SSL CTX function!\n");
} |
3733023f |
#endif
|
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "key", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "acl"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing acl from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "acl", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "policy"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing policy from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "policy", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "x-amz-meta-original-filename"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing x-amz-meta-original-filename from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-meta-original-filename", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "x-amz-credential"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing x-amz-credential from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-credential", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "x-amz-algorithm"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing x-amz-algorithm from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-algorithm", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "x-amz-date"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing x-amz-date from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-date", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
json_str = presigned_get_string(ps_json_obj, "x-amz-signature"); |
ab9114a3 |
if (json_str == NULL) {
fprintf(stderr, "Error in presigned_get_string parsing x-amz-signature from json object\n");
goto cleanup;
} |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "x-amz-signature", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, filename, CURLFORM_END); |
ab9114a3 |
|
5c866010 |
slist = curl_slist_append(slist, "Expect:");
curl_easy_setopt(aws_curl, CURLOPT_HTTPHEADER, slist); |
ab9114a3 |
curl_easy_setopt(aws_curl, CURLOPT_URL, "https://clamav-site.s3.amazonaws.com/"); |
5c866010 |
curl_easy_setopt(aws_curl, CURLOPT_HTTPPOST, post); |
2682e7dd |
|
5c866010 |
res = curl_easy_perform(aws_curl); |
ab9114a3 |
if (res != CURLE_OK) { |
5c866010 |
fprintf(stderr, "Error in POST AWS: %s\n", curl_easy_strerror(res)); |
ab9114a3 |
goto cleanup; |
a7cba048 |
} |
5c866010 |
curl_slist_free_all(slist);
slist = NULL;
curl_formfree(post);
post = NULL;
last = NULL;
curl_easy_cleanup(aws_curl); |
ce959ca5 |
aws_curl = NULL; |
5c866010 |
json_object_put(ps_json_obj);
free(wd.str);
wd.str = NULL;
wd.len = 0;
/*** The POST submit to clamav.net ***/
slist = curl_slist_append(slist, "Expect:"); |
288057e9 |
len = strlen(hd_malware.cfduid) + strlen(hd_malware.session) + 3;
str = malloc(len); |
5c866010 |
if (str == NULL) {
fprintf(stderr, "No memory for POST submit cookies.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
} |
0a29bc85 |
if (snprintf(str, len, "%s; %s;", hd_malware.cfduid, hd_malware.session) > len) { |
5c866010 |
fprintf(stderr, "snprintf() failed formatting POST submit cookies\n"); |
9267de60 |
free(str); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
curl_easy_setopt(clam_curl, CURLOPT_COOKIE, str);
free(str); |
27948a03 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "utf8", CURLFORM_COPYCONTENTS, "\x27\x13", CURLFORM_END); |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "authenticity_token", CURLFORM_COPYCONTENTS, authenticity_token, CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "submissionID", CURLFORM_COPYCONTENTS, submissionID, CURLFORM_END); |
288057e9 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "type", CURLFORM_COPYCONTENTS, malware ? "malware" : "fp", CURLFORM_END); |
5c866010 |
curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendername", CURLFORM_COPYCONTENTS, name, CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "email", CURLFORM_COPYCONTENTS, email, CURLFORM_END);
if (malware == 0) {
curl_formadd(&post, &last, CURLFORM_COPYNAME, "virusname", CURLFORM_COPYCONTENTS, fpvname, CURLFORM_END);
} else { |
288057e9 |
if (malware == 1)
curl_formadd(&post, &last, CURLFORM_COPYNAME, "shareSample", CURLFORM_COPYCONTENTS, "on", CURLFORM_END); |
5c866010 |
}
curl_formadd(&post, &last, CURLFORM_COPYNAME, "description", CURLFORM_COPYCONTENTS, "clamsubmit", CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "notify", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "privacy", CURLFORM_COPYCONTENTS, "on", CURLFORM_END);
curl_easy_setopt(clam_curl, CURLOPT_HTTPHEADER, slist); |
ab9114a3 |
curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/reports/submit"); |
5c866010 |
curl_easy_setopt(clam_curl, CURLOPT_HTTPPOST, post);
curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, NULL);
res = curl_easy_perform(clam_curl); |
ab9114a3 |
if (res != CURLE_OK) { |
5c866010 |
fprintf(stderr, "Error in POST submit: %s\n", curl_easy_strerror(res)); |
ab9114a3 |
goto cleanup; |
5c866010 |
} else {
long response_code;
curl_easy_getinfo(clam_curl, CURLINFO_RESPONSE_CODE, &response_code); |
288057e9 |
if (response_code / 100 == 3) { |
5c866010 |
curl_easy_getinfo(clam_curl, CURLINFO_REDIRECT_URL, &urlp);
if (urlp == NULL) {
fprintf(stderr, "POST submit Location URL is NULL.\n"); |
ab9114a3 |
goto cleanup; |
5c866010 |
}
sp = strstr(urlp, "/reports/");
if (sp == NULL) {
fprintf(stderr, "POST submit Location URL is malformed.\n"); |
288057e9 |
} else if (!strcmp(sp, "/reports/success")) { |
5c866010 |
fprintf(stdout, "Submission success!\n"); |
ab9114a3 |
status = 0; |
288057e9 |
} else if (!strcmp(sp, "/reports/failure")) { |
5c866010 |
fprintf(stdout, "Submission failed\n"); |
288057e9 |
} else { |
5c866010 |
fprintf(stdout, "Unknown submission status %s\n", sp); |
ab9114a3 |
} |
288057e9 |
} else { |
5c866010 |
fprintf(stderr, "Unexpected POST submit response code: %li\n", response_code); |
ab9114a3 |
} |
5c866010 |
} |
ab9114a3 |
cleanup: |
694e7882 |
/* |
ab9114a3 |
* Cleanup
*/
if (slist != NULL) {
curl_slist_free_all(slist);
}
if (post != NULL) {
curl_formfree(post);
}
if (clam_curl != NULL) {
curl_easy_cleanup(clam_curl);
}
if (aws_curl != NULL) {
curl_easy_cleanup(aws_curl);
}
curl_global_cleanup();
|
5c866010 |
if (wd.str != NULL) {
free(wd.str);
wd.str = NULL;
wd.len = 0;
} |
ab9114a3 |
if (hd_malware.cfduid != NULL) {
free(hd_malware.cfduid);
}
if (hd_malware.session != NULL) {
free(hd_malware.session);
}
if (hd_presigned.cfduid != NULL) {
free(hd_presigned.cfduid);
}
if (hd_presigned.session != NULL) {
free(hd_presigned.session);
}
if (submissionID != NULL) {
free(submissionID); |
288057e9 |
} |
ab9114a3 |
if (authenticity_token != NULL) {
free(authenticity_token);
}
if ((fromStream != 0) && (filename != NULL)) { |
a7cba048 |
remove(filename);
free(filename);
} |
b28c454e |
|
ab9114a3 |
return status; |
a7cba048 |
} |
2682e7dd |
|
a7cba048 |
char *read_stream(void)
{
char *filename;
char buf[512];
size_t nread, nwritten;
FILE *fp;
filename = cli_gentemp(NULL);
if (!(filename)) {
return NULL;
}
fp = fopen(filename, "w");
if (!(fp)) {
free(filename);
return NULL;
}
while (!feof(stdin)) {
nwritten = 0; |
288057e9 |
nread = fread(buf, 1, sizeof(buf), stdin); |
a7cba048 |
if (nread == 0) {
fclose(fp);
remove(filename);
free(filename);
return NULL;
}
while (nwritten < nread) {
size_t i;
i = fwrite(buf, 1, nread, fp);
if (i == 0) {
fclose(fp);
remove(filename);
free(filename);
return NULL;
}
nwritten += i; |
2682e7dd |
}
}
|
a7cba048 |
fclose(fp); |
2682e7dd |
|
a7cba048 |
return filename; |
f3107383 |
} |