v1.1.0-dns-challenge #1

Merged
hatter merged 4 commits from v1.1.0-dns-challenge into master 2022-02-03 16:58:40 +08:00
3 changed files with 1089 additions and 108 deletions
Showing only changes of commit 2bb2c80768 - Show all commits

1149
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "acme-client" name = "acme-client"
version = "1.0.3" version = "1.1.0"
authors = ["Hatter Jiang <jht5945@gmail.com>"] authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018" edition = "2018"
description = "Acme auto challenge client, acme-client can issue certificates from Let's encrypt" description = "Acme auto challenge client, acme-client can issue certificates from Let's encrypt"
@@ -25,6 +25,7 @@ urlencoding = "1.0.0"
base64 = "0.11.0" base64 = "0.11.0"
hmac = "0.7.1" hmac = "0.7.1"
sha2 = "0.8.1" sha2 = "0.8.1"
aliyun-openapi-core-rust-sdk = "0.3.0"
[profile.release] [profile.release]
codegen-units = 1 codegen-units = 1

View File

@@ -31,6 +31,7 @@ use crate::config::{CertConfig, CERT_NAME, KEY_NAME};
use crate::x509::{X509PublicKeyAlgo, X509EcPublicKeyAlgo}; use crate::x509::{X509PublicKeyAlgo, X509EcPublicKeyAlgo};
use std::path::PathBuf; use std::path::PathBuf;
use rust_util::util_cmd::run_command_and_wait; use rust_util::util_cmd::run_command_and_wait;
use crate::AcmeChallenge::Http;
use crate::dingtalk::send_dingtalk_message; use crate::dingtalk::send_dingtalk_message;
use crate::network::{get_local_public_ip, get_resolver, resolve_first_ipv4}; use crate::network::{get_local_public_ip, get_resolver, resolve_first_ipv4};
use crate::statics::{AcmeStatics, AcmeStatus}; use crate::statics::{AcmeStatics, AcmeStatus};
@@ -44,8 +45,21 @@ lazy_static! {
static ref TOKEN_MAP: RwLock<BTreeMap<String, String>> = RwLock::new(BTreeMap::new()); static ref TOKEN_MAP: RwLock<BTreeMap<String, String>> = RwLock::new(BTreeMap::new());
} }
#[derive(Debug, Clone, Copy)]
enum AcmeChallenge {
Http,
Dns,
}
impl Default for AcmeChallenge {
fn default() -> Self {
Http
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct AcmeRequest<'a> { struct AcmeRequest<'a> {
challenge: AcmeChallenge,
contract_email: &'a str, contract_email: &'a str,
primary_name: &'a str, primary_name: &'a str,
alt_names: &'a [&'a str], alt_names: &'a [&'a str],
@@ -238,6 +252,7 @@ async fn main() -> tide::Result<()> {
}; };
let acme_request = AcmeRequest { let acme_request = AcmeRequest {
challenge: Http,
contract_email: &email, contract_email: &email,
primary_name, primary_name,
alt_names: &alt_names, alt_names: &alt_names,
@@ -273,6 +288,7 @@ async fn main() -> tide::Result<()> {
information!("Domains, main: {}, alt: {:?}", common_name, dns_names); information!("Domains, main: {}, alt: {:?}", common_name, dns_names);
let alt_names: Vec<&str> = dns_names.iter().map(|n| n.as_str()).collect(); let alt_names: Vec<&str> = dns_names.iter().map(|n| n.as_str()).collect();
let acme_request = AcmeRequest { let acme_request = AcmeRequest {
challenge: Http,
contract_email: &email, contract_email: &email,
primary_name: common_name, primary_name: common_name,
alt_names: &alt_names, alt_names: &alt_names,
@@ -435,6 +451,8 @@ fn request_acme_certificate(acme_request: AcmeRequest) -> XResult<()> {
debugging!("Start acme certificate http challenge"); debugging!("Start acme certificate http challenge");
let auths = opt_result!(ord_new.authorizations(), "Order auth failed: {}"); let auths = opt_result!(ord_new.authorizations(), "Order auth failed: {}");
for auth in &auths { for auth in &auths {
match acme_request.challenge {
Http => {
let chall = auth.http_challenge(); let chall = auth.http_challenge();
let token = chall.http_token(); let token = chall.http_token();
let proof = chall.http_proof(); let proof = chall.http_proof();
@@ -446,6 +464,17 @@ fn request_acme_certificate(acme_request: AcmeRequest) -> XResult<()> {
debugging!("Valid acme certificate http challenge"); debugging!("Valid acme certificate http challenge");
opt_result!(chall.validate(acme_request.timeout), "Validate http challenge failed: {}"); opt_result!(chall.validate(acme_request.timeout), "Validate http challenge failed: {}");
} }
Dns => {
let chall = auth.dns_challenge();
let record = format!("_acme-challenge.{}.", auth.domain_name());
let proof = chall.dns_proof();
information!("Add acme dns challenge: {} -> {}",record, proof);
debugging!("Valid acme certificate dns challenge");
opt_result!(chall.validate(acme_request.timeout), "Validate dns challenge failed: {}");
}
}
}
debugging!("Refresh acme certificate order"); debugging!("Refresh acme certificate order");
opt_result!(ord_new.refresh(), "Refresh order failed: {}"); opt_result!(ord_new.refresh(), "Refresh order failed: {}");