Browse Source

Use account objects instead of an email field

Defining an account solely by an email address is not the best strategy
since the ACME protocol does not require it and also allows for more
contacts information. Although this commit does not change the "one
email" policy, it sets the bases so it could evolve in the future.
pull/5/head
Rodolphe Breard 6 years ago
parent
commit
e66b5a5254
  1. 4
      CHANGELOG.md
  2. 2
      acmed/src/acme_proto/account.rs
  3. 5
      acmed/src/acme_proto/structs/account.rs
  4. 7
      acmed/src/certificate.rs
  5. 18
      acmed/src/config.rs
  6. 2
      acmed/src/main_event_loop.rs
  7. 4
      acmed/src/storage.rs

4
CHANGELOG.md

@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added
- An account object has been added in the configuration.
### Changed ### Changed
- In the configuration, the `email` certificate field has been replaced by the `account` field which matches an account object.
- The `token` challenge hook variable has been renamed `file_name`. - The `token` challenge hook variable has been renamed `file_name`.
- The logs has been purged from many useless debug and trace entries. - The logs has been purged from many useless debug and trace entries.

2
acmed/src/acme_proto/account.rs

@ -37,7 +37,7 @@ impl AccountManager {
storage::set_account_pub_key(cert, &pub_key)?; storage::set_account_pub_key(cert, &pub_key)?;
(priv_key, pub_key) (priv_key, pub_key)
}; };
let account = Account::new(&[cert.email.to_owned()]);
let account = Account::new(&cert.account);
let account = serde_json::to_string(&account)?; let account = serde_json::to_string(&account)?;
let data = encode_jwk(&priv_key, account.as_bytes(), &directory.new_account, nonce)?; let data = encode_jwk(&priv_key, account.as_bytes(), &directory.new_account, nonce)?;
let (acc_rep, account_url, nonce) = let (acc_rep, account_url, nonce) =

5
acmed/src/acme_proto/structs/account.rs

@ -1,3 +1,4 @@
use crate::config;
use crate::error::Error; use crate::error::Error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::str::FromStr; use std::str::FromStr;
@ -11,9 +12,9 @@ pub struct Account {
} }
impl Account { impl Account {
pub fn new(contact: &[String]) -> Self {
pub fn new(cnf_account: &config::Account) -> Self {
Account { Account {
contact: contact.iter().map(|v| format!("mailto:{}", v)).collect(),
contact: vec![format!("mailto:{}", cnf_account.email)],
terms_of_service_agreed: true, terms_of_service_agreed: true,
only_return_existing: false, only_return_existing: false,
} }

7
acmed/src/certificate.rs

@ -1,4 +1,5 @@
use crate::acme_proto::Challenge; use crate::acme_proto::Challenge;
use crate::config::Account;
use crate::error::Error; use crate::error::Error;
use crate::hooks::{self, ChallengeHookData, Hook, PostOperationHookData}; use crate::hooks::{self, ChallengeHookData, Hook, PostOperationHookData};
use crate::storage::{certificate_files_exists, get_certificate}; use crate::storage::{certificate_files_exists, get_certificate};
@ -40,10 +41,10 @@ impl fmt::Display for Algorithm {
#[derive(Debug)] #[derive(Debug)]
pub struct Certificate { pub struct Certificate {
pub account: Account,
pub domains: Vec<String>, pub domains: Vec<String>,
pub algo: Algorithm, pub algo: Algorithm,
pub kp_reuse: bool, pub kp_reuse: bool,
pub email: String,
pub remote_url: String, pub remote_url: String,
pub challenge: Challenge, pub challenge: Challenge,
pub challenge_hooks: Vec<Hook>, pub challenge_hooks: Vec<Hook>,
@ -83,14 +84,14 @@ impl fmt::Display for Certificate {
"Certificate information: "Certificate information:
Domains: {domains} Domains: {domains}
Algorithm: {algo} Algorithm: {algo}
Contact: {email}
Account: {account}
Private key reuse: {kp_reuse} Private key reuse: {kp_reuse}
Challenge: {challenge} Challenge: {challenge}
Challenge hooks: {challenge_hooks} Challenge hooks: {challenge_hooks}
Post operation hooks: {post_operation_hooks}", Post operation hooks: {post_operation_hooks}",
domains = self.domains.join(", "), domains = self.domains.join(", "),
algo = self.algo, algo = self.algo,
email = self.email,
account = self.account.name,
kp_reuse = self.kp_reuse, kp_reuse = self.kp_reuse,
challenge = self.challenge, challenge = self.challenge,
challenge_hooks = challenge_hooks, challenge_hooks = challenge_hooks,

18
acmed/src/config.rs

@ -14,6 +14,7 @@ pub struct Config {
pub endpoint: Vec<Endpoint>, pub endpoint: Vec<Endpoint>,
pub hook: Vec<Hook>, pub hook: Vec<Hook>,
pub group: Vec<Group>, pub group: Vec<Group>,
pub account: Vec<Account>,
pub certificate: Vec<Certificate>, pub certificate: Vec<Certificate>,
} }
@ -139,9 +140,15 @@ pub struct Group {
pub hooks: Vec<String>, pub hooks: Vec<String>,
} }
#[derive(Clone, Debug, Deserialize)]
pub struct Account {
pub name: String,
pub email: String,
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct Certificate { pub struct Certificate {
pub email: String,
pub account: String,
pub endpoint: String, pub endpoint: String,
pub domains: Vec<String>, pub domains: Vec<String>,
pub challenge: String, pub challenge: String,
@ -160,6 +167,15 @@ pub struct Certificate {
} }
impl Certificate { impl Certificate {
pub fn get_account(&self, cnf: &Config) -> Result<Account, Error> {
for account in cnf.account.iter() {
if account.name == self.account {
return Ok(account.clone());
}
}
Err(format!("{}: account not found", self.account).into())
}
pub fn get_algorithm(&self) -> Result<Algorithm, Error> { pub fn get_algorithm(&self) -> Result<Algorithm, Error> {
let algo = match &self.algorithm { let algo = match &self.algorithm {
Some(a) => &a, Some(a) => &a,

2
acmed/src/main_event_loop.rs

@ -17,10 +17,10 @@ impl MainEventLoop {
let mut certs = Vec::new(); let mut certs = Vec::new();
for crt in cnf.certificate.iter() { for crt in cnf.certificate.iter() {
let cert = Certificate { let cert = Certificate {
account: crt.get_account(&cnf)?,
domains: crt.domains.to_owned(), domains: crt.domains.to_owned(),
algo: crt.get_algorithm()?, algo: crt.get_algorithm()?,
kp_reuse: crt.get_kp_reuse(), kp_reuse: crt.get_kp_reuse(),
email: crt.email.to_owned(),
remote_url: crt.get_remote_url(&cnf)?, remote_url: crt.get_remote_url(&cnf)?,
challenge: crt.get_challenge()?, challenge: crt.get_challenge()?,
challenge_hooks: crt.get_challenge_hooks(&cnf)?, challenge_hooks: crt.get_challenge_hooks(&cnf)?,

4
acmed/src/storage.rs

@ -43,8 +43,8 @@ fn get_file_full_path(
}; };
let file_name = match file_type { let file_name = match file_type {
FileType::AccountPrivateKey | FileType::AccountPublicKey => format!( FileType::AccountPrivateKey | FileType::AccountPublicKey => format!(
"{email}.{file_type}.{ext}",
email = cert.email,
"{account}.{file_type}.{ext}",
account = cert.account.name,
file_type = file_type.to_string(), file_type = file_type.to_string(),
ext = "pem" ext = "pem"
), ),

Loading…
Cancel
Save