Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to use client authentication with certificate in freshclam #955

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@ ClamAV 1.2.0 includes the following improvements and changes:

### Major changes

- Added ability for Freshclam to use a client certificate PEM file and a
private key PEM file for authentication to a private mirror by setting the
following environment variables:
- `FRESHCLAM_CLIENT_CERT`: May be set to the path of a file (PEM) containing
the client certificate.
- `FRESHCLAM_CLIENT_KEY`: May be set to the path of a file (PEM) containing
the client private key.
- `FRESHCLAM_CLIENT_KEY_PASSWD`: May be set to a password for the client key
PEM file, if it is password protected.

Patch courtesy of jedrzej.

## Other improvements

### Bug fixes

### Acknowledgments

Special thanks to the following people for code contributions and bug reports:
- jedrzej

## 1.1.0

Expand Down
2 changes: 2 additions & 0 deletions clamsubmit/clamsubmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ int main(int argc, char *argv[])
logg(LOGG_ERROR, "ERROR: Failed to set SSL CTX function!\n");
}
#else
/* Use an alternate CA bundle, if specified by the CURL_CA_BUNDLE environment variable. */
set_tls_ca_bundle(clam_curl);
#endif

Expand Down Expand Up @@ -466,6 +467,7 @@ int main(int argc, char *argv[])
logg(LOGG_ERROR, "ERROR: Failed to set SSL CTX function!\n");
}
#else
/* Use an alternate CA bundle, if specified by the CURL_CA_BUNDLE environment variable. */
set_tls_ca_bundle(aws_curl);
#endif

Expand Down
32 changes: 32 additions & 0 deletions common/cert_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,3 +697,35 @@ CURLcode sslctx_function(CURL *curl, void *ssl_ctx, void *userptr)

return status;
}

void set_tls_client_certificate(CURL *curl)
{
char *client_certificate;
char *client_key;
char *client_key_passwd;

client_certificate = getenv("FRESHCLAM_CLIENT_CERT");
if (client_certificate == NULL) {
return;
}

client_key = getenv("FRESHCLAM_CLIENT_KEY");
if (client_key == NULL) {
return;
}

client_key_passwd = getenv("FRESHCLAM_CLIENT_KEY_PASSWD");

/* set the cert for client authentication */
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSLCERT, client_certificate);

/* set the private key type and path */
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSLKEY, client_key);

/* the private key may require a password */
if (client_key_passwd == NULL) {
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, client_key_passwd);
}
}
9 changes: 8 additions & 1 deletion common/cert_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,20 @@

#if !(defined(C_DARWIN) || defined(_WIN32))
/**
* @brief Set the tls ca bundle to a custom value using the CURL_CA_BUNDLE env var
* @brief Set the tls ca bundle to a custom value using the CURL_CA_BUNDLE environment variable.
*
* @param curl Pointer to the curl connection handle.
*/
void set_tls_ca_bundle(CURL *curl);
#endif

/**
* @brief Set the path for a client certificate PEM file and a private key PEM file using the FRESHCLAM_CLIENT_CERT, FRESHCLAM_CLIENT_KEY, and FRESHCLAM_CLIENT_KEY_PASSWD environment variables.
*
* @param curl Pointer to the curl connection handle.
*/
void set_tls_client_certificate(CURL *curl);

/**
* @brief Load system and trusted root certificates into memory. Any errors
* while loading trusted certificates will be ignored. If error checking
Expand Down
3 changes: 2 additions & 1 deletion common/linux/cert_util_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ void set_tls_ca_bundle(CURL *curl)
char *ca_bundle;

ca_bundle = getenv("CURL_CA_BUNDLE");
if (ca_bundle == NULL)
if (ca_bundle == NULL) {
return;
}

if (curl_easy_setopt(curl, CURLOPT_CAINFO, ca_bundle) != CURLE_OK) {
fprintf(stderr, "Failed to set CURLOPT_CAINFO!\n");
Expand Down
4 changes: 3 additions & 1 deletion docs/man/clamsubmit.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ The name of the virus detected as false positive. This option is required for fa
.LP
clamsubmit uses the following environment variables:
.TP
CURL_CA_BUNDLE - May be set to the path of a file (bundle) containing one or more CA certificates. This will override the default openssl certificate path.
\fBCURL_CA_BUNDLE\fR
(Linux/Unix only, excluding macOS) May be set to the path of a file (bundle) containing one or more CA certificates. This will override the default openssl certificate path.

.TP
Note that the CURL_CA_BUNDLE environment variable is also used by the curl command line tool for the same purpose.

.SH "AUTHOR"
Expand Down
13 changes: 12 additions & 1 deletion docs/man/freshclam.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,19 @@ With this option you can limit updates to a subset of database files. The DBNAME
.LP
freshclam uses the following environment variables:
.TP
CURL_CA_BUNDLE - May be set to the path of a file (bundle) containing one or more CA certificates. This will override the default openssl certificate path.
\fBCURL_CA_BUNDLE\fR
(Linux/Unix only, excluding macOS) May be set to the path of a file (bundle) containing one or more CA certificates. This will override the default openssl certificate path.
.TP
\fBFRESHCLAM_CLIENT_CERT\fR
May be set to the path of a file (PEM) containing the client certificate. This may be used for client authentication.
.TP
\fBFRESHCLAM_CLIENT_KEY\fR
May be set to the path of a file (PEM) containing the client private key. This is required if FRESHCLAM_CLIENT_CERT is set.
.TP
\fBFRESHCLAM_CLIENT_KEY_PASSWD\fR
May be set to a password for the client key PEM file. This is required if FRESHCLAM_CLIENT_KEY is set and the PEM file is password protected.

.TP
Note that the CURL_CA_BUNDLE environment variable is also used by the curl command line tool for the same purpose.

.SH "EXAMPLES"
Expand Down
23 changes: 22 additions & 1 deletion freshclam/freshclam.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ static void help(void)
printf(" --debug Enable debug messages\n");
printf(" --quiet Only output error messages\n");
printf(" --no-warnings Don't print and log warnings\n");
printf(" --stdout Write to stdout instead of stderr. Does not affect 'debug' messages.\n");
printf(" --stdout Write to stdout instead of stderr.\n");
printf(" Does not affect 'debug' messages.\n");
printf(" --show-progress Show download progress percentage\n");
printf("\n");
printf(" --config-file=FILE Read configuration from FILE.\n");
Expand All @@ -198,6 +199,26 @@ static void help(void)
printf(" --on-outdated-execute=COMMAND Execute COMMAND when software is outdated\n");
printf(" --update-db=DBNAME Only update database DBNAME\n");
printf("\n");
printf("Environment Variables:\n");
printf("\n");
#if !defined(C_DARWIN) && !defined(_WIN32)
printf(" CURL_CA_BUNDLE May be set to the path of a file (bundle)\n");
printf(" containing one or more CA certificates.\n");
printf(" This will override the default openssl\n");
printf(" certificate path.\n");
printf("\n");
#endif
printf(" FRESHCLAM_CLIENT_CERT May be set to the path of a file (PEM)\n");
printf(" containing the client certificate.\n");
printf(" This may be used for client authentication\n");
printf(" to a private mirror.\n");
printf(" FRESHCLAM_CLIENT_KEY May be set to the path of a file (PEM)\n");
printf(" containing the client private key.\n");
printf(" This is required if FRESHCLAM_CLIENT_CERT is set.\n");
printf(" FRESHCLAM_CLIENT_KEY_PASSWD May be set to a password for the client key PEM file.\n");
printf(" This is required if FRESHCLAM_CLIENT_KEY is\n");
printf(" set and the PEM file is password protected.\n");
printf("\n");
}

static void libclamav_msg_callback(enum cl_msg severity, const char *fullmsg, const char *msg, void *ctx)
Expand Down
4 changes: 4 additions & 0 deletions libfreshclam/libfreshclam_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,9 +727,13 @@ static fc_error_t create_curl_handle(
logg(LOGG_DEBUG, "create_curl_handle: Failed to set SSL CTX function. Your libcurl may use an SSL backend that does not support CURLOPT_SSL_CTX_FUNCTION.\n");
}
#else
/* Use an alternate CA bundle, if specified by the CURL_CA_BUNDLE environment variable. */
set_tls_ca_bundle(curl);
#endif

/* Authenticate using a client certificate and private key, if specified by the FRESHCLAM_CLIENT_CERT, FRESHCLAM_CLIENT_KEY, and FRESHCLAM_CLIENT_KEY_PASSWD environment variables. */
set_tls_client_certificate(curl);

*curlHandle = curl;
status = FC_SUCCESS;

Expand Down
Loading