Skip to content

Commit

Permalink
Provide cf-ray ids to user when freshclam fails
Browse files Browse the repository at this point in the history
Providing cf-ray ids to the user when freshclam fails will skip the step
of having to ask them for the ids.  This should save some time when the
user is not in the same time zone.
  • Loading branch information
ragusaa committed Mar 5, 2024
1 parent 24226f7 commit da69ec8
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 4 deletions.
53 changes: 52 additions & 1 deletion libfreshclam/libfreshclam.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,22 @@ fc_error_t fc_update_database(
&dbFilename,
bUpdated);

#if 0
if (FC_ERETRYLATER == ret){
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s::%d::FIXME::TAKE THIS OUT\n", __FUNCTION__, __LINE__);
ret = FC_EFORBIDDEN;
}
#endif

switch (ret) {
case FC_SUCCESS: {
if (*bUpdated) {
Expand Down Expand Up @@ -693,9 +709,19 @@ fc_error_t fc_update_database(
logg(LOGG_INFO, " In order to rectify this please check that you are:\n");
logg(LOGG_INFO, " a. Running an up-to-date version of FreshClam\n");
logg(LOGG_INFO, " b. Running FreshClam no more than once an hour\n");
logg(LOGG_INFO, " c. If you have checked (a) and (b), please open a ticket at\n");
logg(LOGG_INFO, " c. Connecting from an IP in a blocked region\n");
logg(LOGG_INFO, " Please see https://www.cisco.com/c/m/en_us/crisissupport.html\n");
logg(LOGG_INFO, " d. If you have checked (a), (b) and (c), please open a ticket at\n");
logg(LOGG_INFO, " https://github.com/Cisco-Talos/clamav/issues\n");
logg(LOGG_INFO, " and we will investigate why your network is blocked.\n");
if (g_rayLst.cnt > 0) {
logg(LOGG_INFO, " Please provide the following cf-ray ids with your ticket.\n");
logg(LOGG_INFO, "\n CF-RAYS=========================================================================\n");
for (i = 0; i < g_rayLst.cnt; i++) {
logg(LOGG_INFO, " cf-ray: %s\n", g_rayLst.ids[i]);
}
logg(LOGG_INFO, "\n");
}
logg(LOGG_WARNING, "You are on cool-down until after: %s\n", retry_after_string);
status = ret;
goto done;
Expand Down Expand Up @@ -795,7 +821,18 @@ fc_error_t fc_update_databases(
logg(LOGG_INFO, " CDN and your own network.\n");
logg(LOGG_INFO, " 4. Please do not open a ticket asking for an exemption from the rate limit,\n");
logg(LOGG_INFO, " it will not be granted.\n");
if (g_rayLst.cnt > 0) {
logg(LOGG_INFO, " 5. If you have verified that you are not blocked due to your region, and have\n");
logg(LOGG_INFO, " not exceeded the rate limit, please provide the following cf-ray ids when\n");
logg(LOGG_INFO, " submitting a ticket.\n");
logg(LOGG_INFO, "\n CF-RAYS=========================================================================\n");
for (i = 0; i < g_rayLst.cnt; i++) {
logg(LOGG_INFO, " cf-ray: %s\n", g_rayLst.ids[i]);
}
logg(LOGG_INFO, "\n");
}
logg(LOGG_WARNING, "You are still on cool-down until after: %s\n", retry_after_string);

status = FC_SUCCESS;
goto done;
} else {
Expand All @@ -805,6 +842,10 @@ fc_error_t fc_update_databases(
}
}

/*Clear the old cf-ray ids. This is really only so that
* we don't have stale ones when we are running in daemon mode.*/
memset(&g_rayLst, 0, sizeof(g_rayLst));

for (i = 0; i < nDatabases; i++) {
if (FC_SUCCESS != (ret = fc_update_database(
databaseList[i],
Expand Down Expand Up @@ -914,7 +955,17 @@ fc_error_t fc_download_url_database(
logg(LOGG_INFO, " c. If you have checked (a) and (b), please open a ticket at\n");
logg(LOGG_INFO, " https://github.com/Cisco-Talos/clamav/issues\n");
logg(LOGG_INFO, " and we will investigate why your network is blocked.\n");
if (g_rayLst.cnt > 0) {
size_t i;
logg(LOGG_INFO, " Please provide the following cf-ray ids with your ticket.\n");
logg(LOGG_INFO, "\n CF-RAYS=========================================================================\n");
for (i = 0; i < g_rayLst.cnt; i++) {
logg(LOGG_INFO, " cf-ray: %s\n", g_rayLst.ids[i]);
}
logg(LOGG_INFO, "\n");
}
logg(LOGG_WARNING, "You are on cool-down until after: %s\n", retry_after_string);

status = ret;
goto done;
break;
Expand Down
13 changes: 13 additions & 0 deletions libfreshclam/libfreshclam.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,19 @@ fc_error_t fc_update_databases(
void *context,
uint32_t *nUpdated);

#define MAX_CFRAYS 10
#define CFRAY_LEN 20
typedef struct fc_cfray_list_ {
uint8_t ids[MAX_CFRAYS][CFRAY_LEN + 1];
uint32_t cnt;
} fc_cfray_list;
#define INSERT_CFRAY(lst, ray) \
{ \
if (lst->cnt < MAX_CFRAYS) { \
memcpy(lst->ids[lst->cnt++], ray, CFRAY_LEN); \
} \
}

/* ----------------------------------------------------------------------------
* Callback function type definitions.
*/
Expand Down
45 changes: 42 additions & 3 deletions libfreshclam/libfreshclam_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ uint32_t g_bCompressLocalDatabase = 0;

freshclam_dat_v1_t *g_freshclamDat = NULL;

fc_cfray_list g_rayLst = {0};

/** @brief Generate a Version 4 UUID according to RFC-4122
*
* Uses the openssl RAND_bytes function to generate a Version 4 UUID.
Expand Down Expand Up @@ -217,8 +219,9 @@ fc_error_t load_freshclam_dat(void)
/* Verify that file size is as expected. */
off_t file_size = lseek(handle, 0L, SEEK_END);

if (strlen(MIRRORS_DAT_MAGIC) + sizeof(freshclam_dat_v1_t) != (size_t)file_size) {
logg(LOGG_DEBUG, "freshclam.dat is bigger than expected: %zu != %ld\n", sizeof(freshclam_dat_v1_t), file_size);
size_t minSize = strlen(MIRRORS_DAT_MAGIC) + sizeof(freshclam_dat_v1_t);
if (minSize > (size_t)file_size) {
logg(LOGG_DEBUG, "freshclam.dat is smaller than expected: %zu != %ld\n", sizeof(freshclam_dat_v1_t), file_size);
goto done;
}

Expand All @@ -244,6 +247,13 @@ fc_error_t load_freshclam_dat(void)
goto done;
}

if (sizeof(fc_cfray_list) != (bread = read(handle, &g_rayLst, sizeof(fc_cfray_list)))) {
char error_message[260];
cli_strerror(errno, error_message, 260);
logg(LOGG_ERROR, "Can't read from freshclam.dat. Bytes read: %zi, error: %s\n", bread, error_message);
goto done;
}

/* Got it. */
close(handle);
handle = -1;
Expand Down Expand Up @@ -329,6 +339,10 @@ fc_error_t save_freshclam_dat(void)

logg(LOGG_DEBUG, "Saved freshclam.dat\n");

if (-1 == write(handle, &g_rayLst, sizeof(fc_cfray_list))) {
logg(LOGG_ERROR, "Can't write to freshclam.dat\n");
}

status = FC_SUCCESS;
done:
if (-1 != handle) {
Expand Down Expand Up @@ -801,6 +815,24 @@ static size_t WriteFileCallback(void *contents, size_t size, size_t nmemb, void
return bytes_written;
}

size_t HeaderCallback(char *buffer,
size_t size,
size_t nitems,
void *userdata)
{

const char *const needle = "cf-ray: ";
size_t totBytes = size * nitems;
if (totBytes >= strlen(needle) + CFRAY_LEN) {
if (0 == strncmp(needle, buffer, strlen(needle))) {
fc_cfray_list *rays = (fc_cfray_list *)userdata;
INSERT_CFRAY(rays, &(buffer[strlen(needle)]));
}
}

return size * nitems;
}

/**
* @brief Get the cvd header info struct for the newest available database.
*
Expand Down Expand Up @@ -1283,6 +1315,14 @@ static fc_error_t downloadFile(
logg(LOGG_ERROR, "downloadFile: Failed to set write-data file handle for curl session.\n");
}

if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HEADERDATA, &g_rayLst)) {
logg(LOGG_ERROR, "downloadFile: Failed to set header-data for header callback for curl session.\n");
}

if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback)) {
logg(LOGG_ERROR, "downloadFile: Failed to set header-data callback function for curl session.\n");
}

logg(LOGG_DEBUG, "downloadFile: Download source: %s\n", url);
logg(LOGG_DEBUG, "downloadFile: Download destination: %s\n", destfile);

Expand Down Expand Up @@ -1380,7 +1420,6 @@ static fc_error_t downloadFile(
}

done:

if (NULL != slist) {
curl_slist_free_all(slist);
}
Expand Down
1 change: 1 addition & 0 deletions libfreshclam/libfreshclam_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ extern uint32_t g_requestTimeout;
extern uint32_t g_bCompressLocalDatabase;

extern freshclam_dat_v1_t *g_freshclamDat;
extern fc_cfray_list g_rayLst;

fc_error_t load_freshclam_dat(void);
fc_error_t save_freshclam_dat(void);
Expand Down

0 comments on commit da69ec8

Please sign in to comment.