From e2787c3299965cf54f26f1557820dbb92ed1399a Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Wed, 24 Apr 2019 11:16:39 +0200 Subject: [PATCH] Require the explicit terms of service agreement As stated in the RFC 8555, the client should explicitly ask the user for the terms of service agreement. In the case of ACMEd, the retained method is to ask for a `tos_agreed` field to be set to true or false in the configuration. This field has been set in the endpoint object rather than in the account one because the same account can be used on multiple endpoints. --- acmed/src/acme_proto/account.rs | 2 +- acmed/src/acme_proto/structs/account.rs | 8 ++++---- acmed/src/certificate.rs | 1 + acmed/src/config.rs | 17 ++++++++++++++--- acmed/src/main_event_loop.rs | 1 + 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/acmed/src/acme_proto/account.rs b/acmed/src/acme_proto/account.rs index 5860172..a6792da 100644 --- a/acmed/src/acme_proto/account.rs +++ b/acmed/src/acme_proto/account.rs @@ -37,7 +37,7 @@ impl AccountManager { storage::set_account_pub_key(cert, &pub_key)?; (priv_key, pub_key) }; - let account = Account::new(&cert.account); + let account = Account::new(cert); let account = serde_json::to_string(&account)?; let data = encode_jwk(&priv_key, account.as_bytes(), &directory.new_account, nonce)?; let (acc_rep, account_url, nonce) = diff --git a/acmed/src/acme_proto/structs/account.rs b/acmed/src/acme_proto/structs/account.rs index 222507d..09d490c 100644 --- a/acmed/src/acme_proto/structs/account.rs +++ b/acmed/src/acme_proto/structs/account.rs @@ -1,4 +1,4 @@ -use crate::config; +use crate::certificate::Certificate; use crate::error::Error; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -12,10 +12,10 @@ pub struct Account { } impl Account { - pub fn new(cnf_account: &config::Account) -> Self { + pub fn new(cert: &Certificate) -> Self { Account { - contact: vec![format!("mailto:{}", cnf_account.email)], - terms_of_service_agreed: true, + contact: vec![format!("mailto:{}", cert.account.email)], + terms_of_service_agreed: cert.tos_agreed, only_return_existing: false, } } diff --git a/acmed/src/certificate.rs b/acmed/src/certificate.rs index d17b9fa..055d0d6 100644 --- a/acmed/src/certificate.rs +++ b/acmed/src/certificate.rs @@ -46,6 +46,7 @@ pub struct Certificate { pub algo: Algorithm, pub kp_reuse: bool, pub remote_url: String, + pub tos_agreed: bool, pub challenge: Challenge, pub challenge_hooks: Vec, pub post_operation_hooks: Vec, diff --git a/acmed/src/config.rs b/acmed/src/config.rs index a42c73c..6e3e095 100644 --- a/acmed/src/config.rs +++ b/acmed/src/config.rs @@ -118,10 +118,11 @@ pub struct GlobalOptions { pub pk_file_group: Option, } -#[derive(Deserialize)] +#[derive(Clone, Deserialize)] pub struct Endpoint { pub name: String, pub url: String, + pub tos_agreed: bool, } #[derive(Deserialize)] @@ -223,15 +224,25 @@ impl Certificate { crt_directory.to_string() } - pub fn get_remote_url(&self, cnf: &Config) -> Result { + fn get_endpoint(&self, cnf: &Config) -> Result { for endpoint in cnf.endpoint.iter() { if endpoint.name == self.endpoint { - return Ok(endpoint.url.to_owned()); + return Ok(endpoint.clone()); } } Err(format!("{}: unknown endpoint.", self.endpoint).into()) } + pub fn get_remote_url(&self, cnf: &Config) -> Result { + let ep = self.get_endpoint(cnf)?; + Ok(ep.url) + } + + pub fn get_tos_agreement(&self, cnf: &Config) -> Result { + let ep = self.get_endpoint(cnf)?; + Ok(ep.tos_agreed) + } + pub fn get_challenge_hooks(&self, cnf: &Config) -> Result, Error> { get_hooks(&self.challenge_hooks, cnf) } diff --git a/acmed/src/main_event_loop.rs b/acmed/src/main_event_loop.rs index 3bdee55..7ddd01a 100644 --- a/acmed/src/main_event_loop.rs +++ b/acmed/src/main_event_loop.rs @@ -22,6 +22,7 @@ impl MainEventLoop { algo: crt.get_algorithm()?, kp_reuse: crt.get_kp_reuse(), remote_url: crt.get_remote_url(&cnf)?, + tos_agreed: crt.get_tos_agreement(&cnf)?, challenge: crt.get_challenge()?, challenge_hooks: crt.get_challenge_hooks(&cnf)?, post_operation_hooks: crt.get_post_operation_hooks(&cnf)?,