Added special warning messages for 403 and 429 HTTP codes.
For 403, FreshClam will fail (non-zero exit code) if not in daemon-mode.
For 429, FreshClam will succeed (exit 0) if not in daemon-mode.
Adds If-Modified-Since header for CVD downloads (not just CVD-head)
which should reduce data usage if DNS is advertising a newer version
than is actually available, which seems to happen sometimes due to
caching issues, it should still fail out when this happens - it just
won't have to download the older CVD, and should detect the HTTP 304
(Not-Modified) response instead.
Also replaced "Freshclam" with "FreshClam" in a few places, for
consistency.
... | ... |
@@ -427,7 +427,7 @@ ClamAV 0.102.2 is a bug patch release to address the following issues. |
427 | 427 |
|
428 | 428 |
- Fixed an issue where running freshclam manually causes a daemonized freshclam |
429 | 429 |
process to fail when it updates because the manual instance deletes the |
430 |
- temporary download directory. Freshclam temporary files will now download to a |
|
430 |
+ temporary download directory. FreshClam temporary files will now download to a |
|
431 | 431 |
unique directory created at the time of an update instead of using a hardcoded |
432 | 432 |
directory created/destroyed at the program start/exit. |
433 | 433 |
|
... | ... |
@@ -916,7 +916,7 @@ we've cooked up over the past 6 months. |
916 | 916 |
numeric value. You can read more about this feature, see how it works, and |
917 | 917 |
look over examples in [our documentation](docs/UserManual/Signatures.md). |
918 | 918 |
- Backwards compatibility improvements for detecting the OpenSSL dependency. |
919 |
-- Freshclam updated to match exit codes defined in the freshclam.1 man page. |
|
919 |
+- FreshClam updated to match exit codes defined in the freshclam.1 man page. |
|
920 | 920 |
- Upgrade from libmspack 0.5alpha to libmspack 0.7.1alpha. As a reminder, we |
921 | 921 |
support system-installed versions of libmspack. _However_, at this time the |
922 | 922 |
ClamAV-provided version of libmspack provides additional abilities to parse |
... | ... |
@@ -1491,7 +1491,7 @@ ClamAV 0.98.4 is a bug fix release. The following issues are now resolved: |
1491 | 1491 |
- Crashes of clamd on Windows and Mac OS X platforms when reloading |
1492 | 1492 |
the virus signature database. |
1493 | 1493 |
- Infinite loop in clamdscan when clamd is not running. |
1494 |
-- Freshclam failure on Solaris 10. |
|
1494 |
+- FreshClam failure on Solaris 10. |
|
1495 | 1495 |
- Buffer underruns when handling multi-part MIME email attachments. |
1496 | 1496 |
- Configuration of OpenSSL on various platforms. |
1497 | 1497 |
- Name collisions on Ubuntu 14.04, Debian sid, and Slackware 14.1. |
... | ... |
@@ -1951,7 +1951,7 @@ version: |
1951 | 1951 |
Numbers and credit card numbers (clamd: StructuredDataDetection, |
1952 | 1952 |
clamscan: --detect-structured; additional fine-tuning options are available) |
1953 | 1953 |
|
1954 |
-- IPv6 Support: Freshclam now supports IPv6 |
|
1954 |
+- IPv6 Support: FreshClam now supports IPv6 |
|
1955 | 1955 |
|
1956 | 1956 |
- Improved Scanning of Scripts: The normalization of scripts now covers |
1957 | 1957 |
JavaScript |
... | ... |
@@ -3240,7 +3240,7 @@ News from ClamAV world: |
3240 | 3240 |
- clamav.linux-sxs.org: database mirror - rsync from clamav.ozforces.com |
3241 | 3241 |
(thanks to Douglas J Hunley <doug@hunley.homeip.net>) |
3242 | 3242 |
|
3243 |
- Freshclam will automatically use them when the main server is not |
|
3243 |
+ FreshClam will automatically use them when the main server is not |
|
3244 | 3244 |
accessible. |
3245 | 3245 |
|
3246 | 3246 |
- Official port in FreeBSD available ! (maintained by Masahiro Teramoto |
... | ... |
@@ -147,7 +147,7 @@ m4_include([m4/reorganization/bsd.m4]) |
147 | 147 |
dnl Clamonacc loading |
148 | 148 |
m4_include([m4/reorganization/clamonacc.m4]) |
149 | 149 |
|
150 |
-dnl Freshclam dependencies |
|
150 |
+dnl FreshClam dependencies |
|
151 | 151 |
m4_include([m4/reorganization/libs/curl.m4]) |
152 | 152 |
m4_include([m4/reorganization/substitutions.m4]) |
153 | 153 |
m4_include([m4/reorganization/strni.m4]) |
... | ... |
@@ -10,7 +10,7 @@ freshclam [options] |
10 | 10 |
freshclam is a virus database update tool for ClamAV. |
11 | 11 |
.SH "OPTIONS" |
12 | 12 |
.LP |
13 |
-Freshclam reads its configuration from freshclam.conf. The settings can be overwritten with command line options. |
|
13 |
+FreshClam reads its configuration from freshclam.conf. The settings can be overwritten with command line options. |
|
14 | 14 |
.TP |
15 | 15 |
\fB\-h, \-\-help\fR |
16 | 16 |
Output help information and exit. |
... | ... |
@@ -92,7 +92,7 @@ Number of database checks per day. |
92 | 92 |
Default: 12 |
93 | 93 |
.TP |
94 | 94 |
\fBDNSDatabaseInfo STRING\fR |
95 |
-Use DNS to verify the virus database version. Freshclam uses DNS TXT records to verify the versions of the database and software itself. With this directive you can change the database verification domain. |
|
95 |
+Use DNS to verify the virus database version. FreshClam uses DNS TXT records to verify the versions of the database and software itself. With this directive you can change the database verification domain. |
|
96 | 96 |
.br |
97 | 97 |
\fBWARNING:\fR Please don't change it unless you're configuring freshclam to use your own database verification domain. |
98 | 98 |
.br |
... | ... |
@@ -58,7 +58,7 @@ Example |
58 | 58 |
# Default: clamav (may depend on installation options) |
59 | 59 |
#DatabaseOwner clamav |
60 | 60 |
|
61 |
-# Use DNS to verify virus database version. Freshclam uses DNS TXT records |
|
61 |
+# Use DNS to verify virus database version. FreshClam uses DNS TXT records |
|
62 | 62 |
# to verify database and software versions. With this directive you can change |
63 | 63 |
# the database verification domain. |
64 | 64 |
# WARNING: Do not touch it unless you're configuring freshclam to use your |
... | ... |
@@ -1,4 +1,4 @@ |
1 |
-PROJECT_NAME = ClamAV - Freshclam |
|
1 |
+PROJECT_NAME = ClamAV - FreshClam |
|
2 | 2 |
OUTPUT_DIRECTORY = ../docs/freshclam |
3 | 3 |
WARNINGS = YES |
4 | 4 |
FILE_PATTERNS = *.c *.h |
... | ... |
@@ -18,4 +18,4 @@ DOT_CLEANUP=NO |
18 | 18 |
MAX_DOT_GRAPH_DEPTH=3 |
19 | 19 |
|
20 | 20 |
EXTRACT_ALL=YES |
21 |
-INPUT = . |
|
21 |
+INPUT = . |
... | ... |
@@ -261,7 +261,7 @@ fc_error_t download_complete_callback(const char *dbFilename, void *context) |
261 | 261 |
ret = FC_ETESTFAIL; |
262 | 262 |
} |
263 | 263 |
if (FC_SUCCESS != ret) { |
264 |
- logg("^Database load exited with \"%s\" (%d)\n", fc_strerror(ret), ret); |
|
264 |
+ logg("^Database load exited with \"%s\"\n", fc_strerror(ret)); |
|
265 | 265 |
status = FC_ETESTFAIL; |
266 | 266 |
goto done; |
267 | 267 |
} |
... | ... |
@@ -276,7 +276,7 @@ fc_error_t download_complete_callback(const char *dbFilename, void *context) |
276 | 276 |
logg("^pipe() failed: %s\n", strerror(errno)); |
277 | 277 |
ret = fc_test_database(dbFilename, fc_context->bBytecodeEnabled); |
278 | 278 |
if (FC_SUCCESS != ret) { |
279 |
- logg("^Database load exited with \"%s\" (%d)\n", fc_strerror(ret), ret); |
|
279 |
+ logg("^Database load exited with \"%s\"\n", fc_strerror(ret)); |
|
280 | 280 |
status = FC_ETESTFAIL; |
281 | 281 |
goto done; |
282 | 282 |
} |
... | ... |
@@ -302,7 +302,7 @@ fc_error_t download_complete_callback(const char *dbFilename, void *context) |
302 | 302 |
/* Test the database without forking. */ |
303 | 303 |
ret = fc_test_database(dbFilename, fc_context->bBytecodeEnabled); |
304 | 304 |
if (FC_SUCCESS != ret) { |
305 |
- logg("^Database load exited with \"%s\" (%d)\n", fc_strerror(ret), ret); |
|
305 |
+ logg("^Database load exited with \"%s\"\n", fc_strerror(ret)); |
|
306 | 306 |
status = FC_ETESTFAIL; |
307 | 307 |
goto done; |
308 | 308 |
} |
... | ... |
@@ -367,7 +367,7 @@ fc_error_t download_complete_callback(const char *dbFilename, void *context) |
367 | 367 |
if (WIFEXITED(stat_loc)) { |
368 | 368 |
ret = (fc_error_t)WEXITSTATUS(stat_loc); |
369 | 369 |
if (FC_SUCCESS != ret) { |
370 |
- logg("^Database load exited with \"%s\" (%d)\n", fc_strerror(ret), ret); |
|
370 |
+ logg("^Database load exited with \"%s\"\n", fc_strerror(ret)); |
|
371 | 371 |
status = FC_ETESTFAIL; |
372 | 372 |
goto done; |
373 | 373 |
} |
... | ... |
@@ -555,7 +555,7 @@ static void free_string_list(char **stringList, uint32_t nListItems) |
555 | 555 |
/** |
556 | 556 |
* @brief Get the database server list object |
557 | 557 |
* |
558 |
- * @param opts Freshclam options struct. |
|
558 |
+ * @param opts FreshClam options struct. |
|
559 | 559 |
* @param serverList [out] List of servers. |
560 | 560 |
* @param nServers [out] Number of servers in list. |
561 | 561 |
* @param bPrivate [out] Non-zero if PrivateMirror servers were selected. |
... | ... |
@@ -1463,7 +1463,7 @@ fc_error_t perform_database_update( |
1463 | 1463 |
(void *)fc_context, |
1464 | 1464 |
&nUpdated); |
1465 | 1465 |
if (FC_SUCCESS != ret) { |
1466 |
- logg("!Database update process failed: %s (%d)\n", fc_strerror(ret), ret); |
|
1466 |
+ logg("!Database update process failed: %s\n", fc_strerror(ret)); |
|
1467 | 1467 |
status = ret; |
1468 | 1468 |
goto done; |
1469 | 1469 |
} |
... | ... |
@@ -1480,7 +1480,7 @@ fc_error_t perform_database_update( |
1480 | 1480 |
(void *)fc_context, |
1481 | 1481 |
&nUpdated); |
1482 | 1482 |
if (FC_SUCCESS != ret) { |
1483 |
- logg("!Database update process failed: %s (%d)\n", fc_strerror(ret), ret); |
|
1483 |
+ logg("!Database update process failed: %s\n", fc_strerror(ret)); |
|
1484 | 1484 |
status = ret; |
1485 | 1485 |
goto done; |
1486 | 1486 |
} |
... | ... |
@@ -1,4 +1,4 @@ |
1 |
-PROJECT_NAME = ClamAV - Freshclam |
|
1 |
+PROJECT_NAME = ClamAV - FreshClam |
|
2 | 2 |
OUTPUT_DIRECTORY = ../docs/freshclam |
3 | 3 |
WARNINGS = YES |
4 | 4 |
FILE_PATTERNS = *.c *.h |
... | ... |
@@ -18,4 +18,4 @@ DOT_CLEANUP=NO |
18 | 18 |
MAX_DOT_GRAPH_DEPTH=3 |
19 | 19 |
|
20 | 20 |
EXTRACT_ALL=YES |
21 |
-INPUT = . |
|
21 |
+INPUT = . |
... | ... |
@@ -113,6 +113,10 @@ const char *fc_strerror(fc_error_t fcerror) |
113 | 113 |
return "Memory allocation error"; |
114 | 114 |
case FC_EARG: |
115 | 115 |
return "Invalid argument(s)"; |
116 |
+ case FC_EFORBIDDEN: |
|
117 |
+ return "Forbidden, Blocked by CDN"; |
|
118 |
+ case FC_ERETRYLATER: |
|
119 |
+ return "Too-many-requests, Retry later"; |
|
116 | 120 |
default: |
117 | 121 |
return "Unknown libfreshclam error code!"; |
118 | 122 |
} |
... | ... |
@@ -627,8 +631,7 @@ fc_error_t fc_update_database( |
627 | 627 |
} |
628 | 628 |
case FC_ECONNECTION: |
629 | 629 |
case FC_EBADCVD: |
630 |
- case FC_EFAILEDGET: |
|
631 |
- case FC_EMIRRORNOTSYNC: { |
|
630 |
+ case FC_EFAILEDGET: { |
|
632 | 631 |
if (attempt < g_maxAttempts) { |
633 | 632 |
logg("Trying again in 5 secs...\n"); |
634 | 633 |
sleep(5); |
... | ... |
@@ -642,8 +645,43 @@ fc_error_t fc_update_database( |
642 | 642 |
} |
643 | 643 |
break; |
644 | 644 |
} |
645 |
+ case FC_EMIRRORNOTSYNC: { |
|
646 |
+ logg("!Update failed for database: %s\n", database); |
|
647 |
+ status = ret; |
|
648 |
+ goto done; |
|
649 |
+ } |
|
650 |
+ case FC_EFORBIDDEN: { |
|
651 |
+ logg("^FreshClam received error code 403 from the ClamAV Content Delivery Network (CDN).\n"); |
|
652 |
+ logg("This could mean several things:\n"); |
|
653 |
+ logg(" 1. You are running an out of date version of ClamAV / FreshClam.\n"); |
|
654 |
+ logg(" Ensure you are the most updated version by visiting https://www.clamav.net/downloads\n"); |
|
655 |
+ logg(" 2. Your network is explicitly denied by the FreshClam CDN.\n"); |
|
656 |
+ logg(" In order to rectify this please check that you are:\n"); |
|
657 |
+ logg(" a. Running an up to date version of FreshClam\n"); |
|
658 |
+ logg(" b. Running FreshClam no more than once an hour\n"); |
|
659 |
+ logg(" c. If you have checked (a) and (b), please open a ticket at\n"); |
|
660 |
+ logg(" https://bugzilla.clamav.net under the “Mirrors” component\n"); |
|
661 |
+ logg(" and we will investigate why your network is blocked.\n"); |
|
662 |
+ status = ret; |
|
663 |
+ goto done; |
|
664 |
+ break; |
|
665 |
+ } |
|
666 |
+ case FC_ERETRYLATER: { |
|
667 |
+ logg("^FreshClam received error code 429 from the ClamAV Content Delivery Network (CDN).\n"); |
|
668 |
+ logg("This means that you have been rate limited by the CDN.\n"); |
|
669 |
+ logg(" 1. Run FreshClam no more than once an hour to check for updates.\n"); |
|
670 |
+ logg(" Freshclam should check DNS first to see if an update is needed.\n"); |
|
671 |
+ logg(" 2. If you have more than 10 hosts on your network attempting to download,\n"); |
|
672 |
+ logg(" it is recommended that you set up a private mirror on your network using\n"); |
|
673 |
+ logg(" cvdupdate (https://pypi.org/project/cvdupdate/) to save bandwidth on the\n"); |
|
674 |
+ logg(" CDN and your own network.\n"); |
|
675 |
+ logg(" 3. Please do not open a ticket asking for an exemption from the rate limit,\n"); |
|
676 |
+ logg(" it will not be granted.\n"); |
|
677 |
+ goto success; |
|
678 |
+ break; |
|
679 |
+ } |
|
645 | 680 |
default: { |
646 |
- logg("!Unexpected error when attempting to update database: %s\n", database); |
|
681 |
+ logg("!Unexpected error when attempting to update %s: %s\n", database, fc_strerror(ret)); |
|
647 | 682 |
status = ret; |
648 | 683 |
goto done; |
649 | 684 |
} |
... | ... |
@@ -698,7 +736,6 @@ fc_error_t fc_update_databases( |
698 | 698 |
bScriptedUpdates, |
699 | 699 |
context, |
700 | 700 |
&bUpdated))) { |
701 |
- logg("^fc_update_databases: fc_update_database failed: %s (%d)\n", fc_strerror(ret), ret); |
|
702 | 701 |
status = ret; |
703 | 702 |
goto done; |
704 | 703 |
} |
... | ... |
@@ -24,7 +24,7 @@ |
24 | 24 |
#include "clamav-types.h" |
25 | 25 |
|
26 | 26 |
/* |
27 |
- * Freshclam configuration flag options. |
|
27 |
+ * FreshClam configuration flag options. |
|
28 | 28 |
*/ |
29 | 29 |
// clang-format off |
30 | 30 |
#define FC_CONFIG_MSG_DEBUG 0x1 // Enable debug messages. |
... | ... |
@@ -79,7 +79,9 @@ typedef enum fc_error_tag { |
79 | 79 |
FC_ELOGGING, |
80 | 80 |
FC_EFAILEDUPDATE, |
81 | 81 |
FC_EMEM, |
82 |
- FC_EARG |
|
82 |
+ FC_EARG, |
|
83 |
+ FC_EFORBIDDEN, |
|
84 |
+ FC_ERETRYLATER |
|
83 | 85 |
} fc_error_t; |
84 | 86 |
|
85 | 87 |
/** |
... | ... |
@@ -240,7 +242,7 @@ fc_error_t fc_update_databases( |
240 | 240 |
*/ |
241 | 241 |
|
242 | 242 |
/** |
243 |
- * @brief Freshclam callback Download Complete |
|
243 |
+ * @brief FreshClam callback Download Complete |
|
244 | 244 |
* |
245 | 245 |
* Called after each database has been downloaded or updated. |
246 | 246 |
* |
... | ... |
@@ -575,13 +575,11 @@ static fc_error_t remote_cvdhead( |
575 | 575 |
/* |
576 | 576 |
* Request CVD header. |
577 | 577 |
*/ |
578 |
- logg("Reading CVD header (%s): ", cvdfile); |
|
579 |
- |
|
580 | 578 |
urlLen = strlen(server) + strlen("/") + strlen(cvdfile); |
581 | 579 |
url = malloc(urlLen + 1); |
582 | 580 |
snprintf(url, urlLen + 1, "%s/%s", server, cvdfile); |
583 | 581 |
|
584 |
- logg("*Trying to retrieve CVD header from %s\n", url); |
|
582 |
+ logg("Trying to retrieve CVD header from %s\n", url); |
|
585 | 583 |
|
586 | 584 |
if (FC_SUCCESS != (ret = create_curl_handle( |
587 | 585 |
bHttpServer, // Set extra HTTP-specific headers. |
... | ... |
@@ -1000,6 +998,14 @@ static fc_error_t downloadFile( |
1000 | 1000 |
status = FC_UPTODATE; |
1001 | 1001 |
break; |
1002 | 1002 |
} |
1003 |
+ case 403: { |
|
1004 |
+ status = FC_EFORBIDDEN; |
|
1005 |
+ break; |
|
1006 |
+ } |
|
1007 |
+ case 429: { |
|
1008 |
+ status = FC_ERETRYLATER; |
|
1009 |
+ break; |
|
1010 |
+ } |
|
1003 | 1011 |
case 404: { |
1004 | 1012 |
if (g_proxyServer) |
1005 | 1013 |
logg("^downloadFile: file not found: %s (Proxy: %s:%u)\n", url, g_proxyServer, g_proxyPort); |
... | ... |
@@ -1050,6 +1056,7 @@ static fc_error_t getcvd( |
1050 | 1050 |
const char *cvdfile, |
1051 | 1051 |
const char *tmpfile, |
1052 | 1052 |
char *server, |
1053 |
+ uint32_t ifModifiedSince, |
|
1053 | 1054 |
unsigned int remoteVersion, |
1054 | 1055 |
int logerr) |
1055 | 1056 |
{ |
... | ... |
@@ -1071,8 +1078,13 @@ static fc_error_t getcvd( |
1071 | 1071 |
url = malloc(urlLen + 1); |
1072 | 1072 |
snprintf(url, urlLen + 1, "%s/%s", server, cvdfile); |
1073 | 1073 |
|
1074 |
- if (FC_SUCCESS != (ret = downloadFile(url, tmpfile, 1, logerr, 0))) { |
|
1075 |
- logg("%cgetcvd: Can't download %s from %s\n", logerr ? '!' : '^', cvdfile, url); |
|
1074 |
+ ret = downloadFile(url, tmpfile, 1, logerr, ifModifiedSince); |
|
1075 |
+ if (ret == FC_UPTODATE) { |
|
1076 |
+ logg("%s is up to date.\n", cvdfile); |
|
1077 |
+ status = ret; |
|
1078 |
+ goto done; |
|
1079 |
+ } else if (ret > FC_UPTODATE) { |
|
1080 |
+ logg("%cCan't download %s from %s\n", logerr ? '!' : '^', cvdfile, url); |
|
1076 | 1081 |
status = ret; |
1077 | 1082 |
goto done; |
1078 | 1083 |
} |
... | ... |
@@ -1080,32 +1092,32 @@ static fc_error_t getcvd( |
1080 | 1080 |
/* Temporarily rename file to correct extension for verification. */ |
1081 | 1081 |
tmpfile_with_extension = strdup(tmpfile); |
1082 | 1082 |
if (!tmpfile_with_extension) { |
1083 |
- logg("!getcvd: Can't allocate memory for temp file with extension!\n"); |
|
1083 |
+ logg("!Can't allocate memory for temp file with extension!\n"); |
|
1084 | 1084 |
status = FC_EMEM; |
1085 | 1085 |
goto done; |
1086 | 1086 |
} |
1087 | 1087 |
strncpy(tmpfile_with_extension + strlen(tmpfile_with_extension) - 4, cvdfile + strlen(cvdfile) - 4, 4); |
1088 | 1088 |
if (rename(tmpfile, tmpfile_with_extension) == -1) { |
1089 |
- logg("!getcvd: Can't rename %s to %s: %s\n", tmpfile, tmpfile_with_extension, strerror(errno)); |
|
1089 |
+ logg("!Can't rename %s to %s: %s\n", tmpfile, tmpfile_with_extension, strerror(errno)); |
|
1090 | 1090 |
status = FC_EDBDIRACCESS; |
1091 | 1091 |
goto done; |
1092 | 1092 |
} |
1093 | 1093 |
|
1094 | 1094 |
if (CL_SUCCESS != (cl_ret = cl_cvdverify(tmpfile_with_extension))) { |
1095 |
- logg("!getcvd: Verification: %s\n", cl_strerror(cl_ret)); |
|
1095 |
+ logg("!Verification: %s\n", cl_strerror(cl_ret)); |
|
1096 | 1096 |
status = FC_EBADCVD; |
1097 | 1097 |
goto done; |
1098 | 1098 |
} |
1099 | 1099 |
|
1100 | 1100 |
if (NULL == (cvd = cl_cvdhead(tmpfile_with_extension))) { |
1101 |
- logg("!getcvd: Can't read CVD header of new %s database.\n", cvdfile); |
|
1101 |
+ logg("!Can't read CVD header of new %s database.\n", cvdfile); |
|
1102 | 1102 |
status = FC_EBADCVD; |
1103 | 1103 |
goto done; |
1104 | 1104 |
} |
1105 | 1105 |
|
1106 | 1106 |
/* Rename the file back to the original, since verification passed. */ |
1107 | 1107 |
if (rename(tmpfile_with_extension, tmpfile) == -1) { |
1108 |
- logg("!getcvd: Can't rename %s to %s: %s\n", tmpfile_with_extension, tmpfile, strerror(errno)); |
|
1108 |
+ logg("!Can't rename %s to %s: %s\n", tmpfile_with_extension, tmpfile, strerror(errno)); |
|
1109 | 1109 |
status = FC_EDBDIRACCESS; |
1110 | 1110 |
goto done; |
1111 | 1111 |
} |
... | ... |
@@ -1719,7 +1731,8 @@ static fc_error_t check_for_new_database_version( |
1719 | 1719 |
uint32_t *localVersion, |
1720 | 1720 |
uint32_t *remoteVersion, |
1721 | 1721 |
char **localFilename, |
1722 |
- char **remoteFilename) |
|
1722 |
+ char **remoteFilename, |
|
1723 |
+ uint32_t *localTimestamp) |
|
1723 | 1724 |
{ |
1724 | 1725 |
fc_error_t ret; |
1725 | 1726 |
fc_error_t status = FC_EARG; |
... | ... |
@@ -1728,13 +1741,13 @@ static fc_error_t check_for_new_database_version( |
1728 | 1728 |
struct cl_cvd *local_database = NULL; |
1729 | 1729 |
char *remotename = NULL; |
1730 | 1730 |
|
1731 |
- uint32_t localver = 0; |
|
1732 |
- uint32_t localTimestamp = 0; |
|
1733 |
- uint32_t remotever = 0; |
|
1731 |
+ uint32_t localver = 0; |
|
1732 |
+ uint32_t remotever = 0; |
|
1734 | 1733 |
|
1735 | 1734 |
if ((NULL == database) || (NULL == server) || |
1736 | 1735 |
(NULL == localVersion) || (NULL == remoteVersion) || |
1737 |
- (NULL == localFilename) || (NULL == remoteFilename)) { |
|
1736 |
+ (NULL == localFilename) || (NULL == remoteFilename) || |
|
1737 |
+ (NULL == localTimestamp)) { |
|
1738 | 1738 |
logg("!check_for_new_database_version: Invalid args!\n"); |
1739 | 1739 |
goto done; |
1740 | 1740 |
} |
... | ... |
@@ -1743,6 +1756,7 @@ static fc_error_t check_for_new_database_version( |
1743 | 1743 |
*remoteVersion = 0; |
1744 | 1744 |
*localFilename = NULL; |
1745 | 1745 |
*remoteFilename = NULL; |
1746 |
+ *localTimestamp = 0; |
|
1746 | 1747 |
|
1747 | 1748 |
/* |
1748 | 1749 |
* Check local database version (if exists) |
... | ... |
@@ -1751,8 +1765,8 @@ static fc_error_t check_for_new_database_version( |
1751 | 1751 |
logg("*check_for_new_database_version: No local copy of \"%s\" database.\n", database); |
1752 | 1752 |
} else { |
1753 | 1753 |
logg("*check_for_new_database_version: Local copy of %s found: %s.\n", database, localname); |
1754 |
- localTimestamp = local_database->stime; |
|
1755 |
- localver = local_database->version; |
|
1754 |
+ *localTimestamp = local_database->stime; |
|
1755 |
+ localver = local_database->version; |
|
1756 | 1756 |
} |
1757 | 1757 |
|
1758 | 1758 |
/* |
... | ... |
@@ -1760,7 +1774,7 @@ static fc_error_t check_for_new_database_version( |
1760 | 1760 |
*/ |
1761 | 1761 |
ret = query_remote_database_version( |
1762 | 1762 |
database, |
1763 |
- localTimestamp, |
|
1763 |
+ *localTimestamp, |
|
1764 | 1764 |
dnsUpdateInfo, |
1765 | 1765 |
server, |
1766 | 1766 |
bPrivateMirror, |
... | ... |
@@ -1858,11 +1872,12 @@ fc_error_t updatedb( |
1858 | 1858 |
|
1859 | 1859 |
struct cl_cvd *cvd = NULL; |
1860 | 1860 |
|
1861 |
- uint32_t localVersion = 0; |
|
1862 |
- uint32_t remoteVersion = 0; |
|
1863 |
- char *localFilename = NULL; |
|
1864 |
- char *remoteFilename = NULL; |
|
1865 |
- char *newLocalFilename = NULL; |
|
1861 |
+ uint32_t localTimestamp = 0; |
|
1862 |
+ uint32_t localVersion = 0; |
|
1863 |
+ uint32_t remoteVersion = 0; |
|
1864 |
+ char *localFilename = NULL; |
|
1865 |
+ char *remoteFilename = NULL; |
|
1866 |
+ char *newLocalFilename = NULL; |
|
1866 | 1867 |
|
1867 | 1868 |
char *tmpdir = NULL; |
1868 | 1869 |
char *tmpfile = NULL; |
... | ... |
@@ -1892,7 +1907,8 @@ fc_error_t updatedb( |
1892 | 1892 |
&localVersion, |
1893 | 1893 |
&remoteVersion, |
1894 | 1894 |
&localFilename, |
1895 |
- &remoteFilename))) { |
|
1895 |
+ &remoteFilename, |
|
1896 |
+ &localTimestamp))) { |
|
1896 | 1897 |
logg("*updatedb: %s database update failed.\n", database); |
1897 | 1898 |
status = ret; |
1898 | 1899 |
goto done; |
... | ... |
@@ -1914,8 +1930,15 @@ fc_error_t updatedb( |
1914 | 1914 |
/* |
1915 | 1915 |
* Download entire file. |
1916 | 1916 |
*/ |
1917 |
- ret = getcvd(remoteFilename, tmpfile, server, remoteVersion, logerr); |
|
1918 |
- if (FC_SUCCESS != ret) { |
|
1917 |
+ ret = getcvd(remoteFilename, tmpfile, server, localTimestamp, remoteVersion, logerr); |
|
1918 |
+ if (FC_UPTODATE == ret) { |
|
1919 |
+ logg("^Expected newer version of %s database but the server's copy is not newer than our local file (version %d).\n", database, localVersion); |
|
1920 |
+ if (NULL != localFilename) { |
|
1921 |
+ /* Received a 304 (not modified), must be up to date after all */ |
|
1922 |
+ *dbFilename = cli_strdup(localFilename); |
|
1923 |
+ } |
|
1924 |
+ goto up_to_date; |
|
1925 |
+ } else if (FC_SUCCESS != ret) { |
|
1919 | 1926 |
status = ret; |
1920 | 1927 |
goto done; |
1921 | 1928 |
} |
... | ... |
@@ -1980,7 +2003,7 @@ fc_error_t updatedb( |
1980 | 1980 |
logg("^Incremental update failed, trying to download %s\n", remoteFilename); |
1981 | 1981 |
} |
1982 | 1982 |
|
1983 |
- ret = getcvd(remoteFilename, tmpfile, server, remoteVersion, logerr); |
|
1983 |
+ ret = getcvd(remoteFilename, tmpfile, server, localTimestamp, remoteVersion, logerr); |
|
1984 | 1984 |
if (FC_SUCCESS != ret) { |
1985 | 1985 |
status = ret; |
1986 | 1986 |
goto done; |
... | ... |
@@ -496,7 +496,7 @@ const struct clam_option __clam_options[] = { |
496 | 496 |
{"DevPerformance", "dev-performance", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD | OPT_CLAMSCAN, "", ""}, |
497 | 497 |
{"DevLiblog", "dev-liblog", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD, "", ""}, |
498 | 498 |
|
499 |
- /* Freshclam-only entries */ |
|
499 |
+ /* FreshClam-only entries */ |
|
500 | 500 |
|
501 | 501 |
/* FIXME: drop this entry and use LogFile */ |
502 | 502 |
{"UpdateLogFile", "log", 'l', CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "Save all reports to a log file.", "/var/log/freshclam.log"}, |
... | ... |
@@ -505,7 +505,7 @@ const struct clam_option __clam_options[] = { |
505 | 505 |
|
506 | 506 |
{"Checks", "checks", 'c', CLOPT_TYPE_NUMBER, MATCH_NUMBER, 12, NULL, 0, OPT_FRESHCLAM, "This option defined how many times daily freshclam should check for\na database update.", "24"}, |
507 | 507 |
|
508 |
- {"DNSDatabaseInfo", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, "current.cvd.clamav.net", FLAG_REQUIRED, OPT_FRESHCLAM, "Use DNS to verify the virus database version. Freshclam uses DNS TXT records\nto verify the versions of the database and software itself. With this\ndirective you can change the database verification domain.\nWARNING: Please don't change it unless you're configuring freshclam to use\nyour own database verification domain.", "current.cvd.clamav.net"}, |
|
508 |
+ {"DNSDatabaseInfo", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, "current.cvd.clamav.net", FLAG_REQUIRED, OPT_FRESHCLAM, "Use DNS to verify the virus database version. FreshClam uses DNS TXT records\nto verify the versions of the database and software itself. With this\ndirective you can change the database verification domain.\nWARNING: Please don't change it unless you're configuring freshclam to use\nyour own database verification domain.", "current.cvd.clamav.net"}, |
|
509 | 509 |
|
510 | 510 |
{"DatabaseMirror", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_FRESHCLAM, "DatabaseMirror specifies to which mirror(s) freshclam should connect.\nYou should have at least one entry: database.clamav.net.", "database.clamav.net"}, |
511 | 511 |
|
... | ... |
@@ -55,7 +55,7 @@ Example |
55 | 55 |
# Default: clamav (may depend on installation options) |
56 | 56 |
#DatabaseOwner clamav |
57 | 57 |
|
58 |
-# Use DNS to verify virus database version. Freshclam uses DNS TXT records |
|
58 |
+# Use DNS to verify virus database version. FreshClam uses DNS TXT records |
|
59 | 59 |
# to verify database and software versions. With this directive you can change |
60 | 60 |
# the database verification domain. |
61 | 61 |
# WARNING: Do not touch it unless you're configuring freshclam to use your |