diff --git a/integration/ssl/cacert.hurl b/integration/ssl/cacert.hurl index 1a3a8b26d..f17cef324 100644 --- a/integration/ssl/cacert.hurl +++ b/integration/ssl/cacert.hurl @@ -1,3 +1,5 @@ +# Access an SSL endpoint with a custom CA +# Remark: The option --ssl-no-revoke must be set for windows GET https://localhost:8002/hello HTTP 200 diff --git a/integration/ssl/cacert.options b/integration/ssl/cacert.options index e749c0097..9e685a0f8 100644 --- a/integration/ssl/cacert.options +++ b/integration/ssl/cacert.options @@ -1,2 +1,4 @@ --cacert ssl/ca/cert.pem +--ssl-no-revoke + diff --git a/packages/hurl/src/cli/options.rs b/packages/hurl/src/cli/options.rs index 0cdeed550..86f1401e2 100644 --- a/packages/hurl/src/cli/options.rs +++ b/packages/hurl/src/cli/options.rs @@ -61,6 +61,7 @@ pub struct CliOptions { pub retry: bool, pub retry_interval: Duration, pub retry_max_count: Option, + pub ssl_no_revoke: bool, pub test: bool, pub timeout: Duration, pub to_entry: Option, @@ -339,6 +340,12 @@ pub fn app(version: &str) -> Command { .value_parser(value_parser!(i32).range(-1..)) .num_args(1) ) + .arg( + clap::Arg::new("ssl_no_revoke") + .long("ssl-no-revoke") + .help("(Schannel) This option tells curl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask for exactly that.") + .action(ArgAction::SetTrue) + ) .arg( clap::Arg::new("test") .long("test") @@ -502,6 +509,7 @@ pub fn parse_options(matches: &ArgMatches) -> Result { r if r == -1 => None, r => Some(r as usize), }; + let ssl_no_revoke = has_flag(matches, "ssl_no_revoke"); let timeout = get::(matches, "max_time").unwrap(); let timeout = Duration::from_secs(timeout); let to_entry = get::(matches, "to_entry").map(|x| x as usize); @@ -540,6 +548,7 @@ pub fn parse_options(matches: &ArgMatches) -> Result { retry, retry_interval, retry_max_count, + ssl_no_revoke, test, timeout, to_entry, diff --git a/packages/hurl/src/http/client.rs b/packages/hurl/src/http/client.rs index bada4b82c..01aaafc6d 100644 --- a/packages/hurl/src/http/client.rs +++ b/packages/hurl/src/http/client.rs @@ -33,7 +33,7 @@ use crate::cli::Logger; use crate::http::ContextDir; use base64::engine::general_purpose; use base64::Engine; -use curl::easy::List; +use curl::easy::{List, SslOpt}; use std::str::FromStr; use url::Url; @@ -162,6 +162,8 @@ impl Client { .connect_timeout(options.connect_timeout) .unwrap(); + self.set_ssl_options(options.ssl_no_revoke); + let url = self.generate_url(&request_spec.url, &request_spec.querystring); self.handle.url(url.as_str()).unwrap(); let method = &request_spec.method; @@ -494,6 +496,13 @@ impl Client { } } + /// Sets SSL options + fn set_ssl_options(&mut self, no_revoke: bool) { + let mut ssl_opt = SslOpt::new(); + ssl_opt.no_revoke(no_revoke); + self.handle.ssl_options(&ssl_opt).unwrap(); + } + /// URL encodes parameters. fn url_encode_params(&mut self, params: &[Param]) -> String { params diff --git a/packages/hurl/src/http/options.rs b/packages/hurl/src/http/options.rs index 6e25eafe8..e5925c489 100644 --- a/packages/hurl/src/http/options.rs +++ b/packages/hurl/src/http/options.rs @@ -22,21 +22,22 @@ pub struct ClientOptions { pub cacert_file: Option, pub client_cert_file: Option, pub client_key_file: Option, + pub compressed: bool, + pub connect_timeout: Duration, pub connects_to: Vec, - pub follow_location: bool, - pub max_redirect: Option, pub cookie_input_file: Option, - pub proxy: Option, - pub no_proxy: Option, - pub verbosity: Option, + pub follow_location: bool, pub insecure: bool, + pub max_redirect: Option, + pub no_proxy: Option, + pub proxy: Option, pub resolves: Vec, pub retry_max_count: Option, + pub ssl_no_revoke: bool, pub timeout: Duration, - pub connect_timeout: Duration, pub user: Option, pub user_agent: Option, - pub compressed: bool, + pub verbosity: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -51,21 +52,22 @@ impl Default for ClientOptions { cacert_file: None, client_cert_file: None, client_key_file: None, + compressed: false, + connect_timeout: Duration::from_secs(300), connects_to: vec![], - follow_location: false, - max_redirect: Some(50), cookie_input_file: None, - proxy: None, - no_proxy: None, - verbosity: None, + follow_location: false, insecure: false, + max_redirect: Some(50), + no_proxy: None, + proxy: None, resolves: vec![], retry_max_count: Some(10), + ssl_no_revoke: false, timeout: Duration::from_secs(300), - connect_timeout: Duration::from_secs(300), user: None, user_agent: None, - compressed: false, + verbosity: None, } } } @@ -166,6 +168,7 @@ mod tests { "bar.com:443:127.0.0.1".to_string() ], retry_max_count: Some(10), + ssl_no_revoke: false, timeout: Duration::from_secs(10), connect_timeout: Duration::from_secs(20), user: Some("user:password".to_string()), diff --git a/packages/hurl/src/runner/entry.rs b/packages/hurl/src/runner/entry.rs index b436ac3c4..5e961311c 100644 --- a/packages/hurl/src/runner/entry.rs +++ b/packages/hurl/src/runner/entry.rs @@ -239,6 +239,7 @@ impl From<&RunnerOptions> for ClientOptions { insecure: runner_options.insecure, resolves: runner_options.resolves.clone(), retry_max_count: runner_options.retry_max_count, + ssl_no_revoke: runner_options.ssl_no_revoke, timeout: runner_options.timeout, connect_timeout: runner_options.connect_timeout, user: runner_options.user.clone(), diff --git a/packages/hurl/src/runner/runner_options.rs b/packages/hurl/src/runner/runner_options.rs index 4102a0af0..597c7b48d 100644 --- a/packages/hurl/src/runner/runner_options.rs +++ b/packages/hurl/src/runner/runner_options.rs @@ -299,6 +299,7 @@ impl RunnerOptionsBuilder { retry: self.retry, retry_interval: self.retry_interval, retry_max_count: self.retry_max_count, + ssl_no_revoke: false, timeout: self.timeout, to_entry: self.to_entry, user: self.user.clone(), @@ -331,6 +332,7 @@ pub struct RunnerOptions { pub(crate) retry: bool, pub(crate) retry_interval: Duration, pub(crate) retry_max_count: Option, + pub(crate) ssl_no_revoke: bool, pub(crate) timeout: Duration, pub(crate) to_entry: Option, pub(crate) user: Option, @@ -395,6 +397,7 @@ impl RunnerOptions { let retry_interval = cli_options.retry_interval; let retry_max_count = cli_options.retry_max_count; let ignore_asserts = cli_options.ignore_asserts; + let ssl_no_revoke = cli_options.ssl_no_revoke; RunnerOptions { cacert_file, @@ -418,6 +421,7 @@ impl RunnerOptions { retry, retry_interval, retry_max_count, + ssl_no_revoke, timeout, to_entry, user,