Skip to content

Commit

Permalink
Merge pull request opnsense#3749 from fraenki/acme_321
Browse files Browse the repository at this point in the history
security/acme-client: release 3.21
  • Loading branch information
fraenki authored Jan 8, 2024
2 parents 89c9255 + e6742e3 commit 5f3092d
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 150 deletions.
3 changes: 3 additions & 0 deletions security/acme-client/pkg-descr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ WWW: https://github.com/acmesh-official/acme.sh
Plugin Changelog
================

Fixed:
* fix sporadic command failure with gcloud DNS API (#3745)

3.20

Added:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* Copyright (C) 2020-2021 Frank Wall
* Copyright (C) 2020-2024 Frank Wall
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -29,6 +29,7 @@
namespace OPNsense\AcmeClient;

use OPNsense\Core\Config;
use OPNsense\AcmeClient\LeUtils;

/**
* Manage ACME CA accounts with acme.sh
Expand Down Expand Up @@ -104,40 +105,23 @@ public function generateKey()
return true;
} else {
LeUtils::log_debug('generating a new account key for ' . (string)$this->config->name, $this->debug);

// Preparation to run acme client
$proc_env = $this->acme_env; // env variables for proc_open()
$proc_env = $this->acme_env; // add env variables
$proc_env['PATH'] = $this::ACME_ENV_PATH;
$proc_desc = array( // descriptor array for proc_open()
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$proc_pipes = array();

// Run acme client to generate a account key

// Prepare acme.sh command to generate a account key
$acmecmd = '/usr/local/sbin/acme.sh '
. '--createAccountKey '
. implode(' ', $this->acme_args) . ' '
. LeUtils::execSafe('--accountkeylength %s', self::ACME_ACCOUNT_KEY_LENGTH) . ' '
. LeUtils::execSafe('--accountconf %s', $account_conf_file);
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
fclose($proc_pipes[0]);
fclose($proc_pipes[1]);
fclose($proc_pipes[2]);
// Get exit code
$result = proc_close($proc);
} else {
LeUtils::log_error('unable to start acme client process');
$this->setStatus(500);
return false;
}

// Check exit code
// Run acme.sh command
$result = LeUtils::run_shell_command($acmecmd, $proc_env);

// Check acme.sh result
if ($result) {
LeUtils::log_error('failed to create a new account key for ' . (string)$this->config->name);
$this->setStatus(300);
Expand Down Expand Up @@ -220,38 +204,20 @@ public function register()
}

// Preparation to run acme client
$proc_env = $this->acme_env; // env variables for proc_open()
$proc_env = $this->acme_env; // add env variables
$proc_env['PATH'] = $this::ACME_ENV_PATH;
$proc_desc = array( // descriptor array for proc_open()
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$proc_pipes = array();

// Run acme client

// Prepare acme.sh command to register an account
$acmecmd = '/usr/local/sbin/acme.sh '
. '--registeraccount '
. implode(' ', $this->acme_args) . ' '
. LeUtils::execSafe('--accountconf %s', $this->account_conf_file);
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
fclose($proc_pipes[0]);
fclose($proc_pipes[1]);
fclose($proc_pipes[2]);
// Get exit code
$result = proc_close($proc);
} else {
LeUtils::log_error('unable to start acme client process');
$this->setStatus(500);
return false;
}

// Check validation result
// Run acme.sh command
$result = LeUtils::run_shell_command($acmecmd, $proc_env);

// Check acme.sh result
if ($result) {
LeUtils::log_error('account registration failed for ' . $this->config->name);
$this->setStatus(400);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* Copyright (C) 2020-2021 Frank Wall
* Copyright (C) 2020-2024 Frank Wall
* Copyright (C) 2018 Deciso B.V.
* Copyright (C) 2018 Franco Fichtner <[email protected]>
* All rights reserved.
Expand Down Expand Up @@ -120,35 +120,19 @@ public function runAcme()
LeUtils::log('running automation (acme.sh): ' . $this->config->name);

// Preparation to run acme client
$proc_env = $this->acme_env; // env variables for proc_open()
$proc_env = $this->acme_env; // add env variables
$proc_env['PATH'] = $this::ACME_ENV_PATH;
$proc_desc = array( // descriptor array for proc_open()
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$proc_pipes = array();

// Run acme client

// Prepare acme.sh command to run a deploy hook
$acmecmd = self::ACME_CMD
. ' '
. '--deploy '
. implode(' ', $this->acme_args);
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
fclose($proc_pipes[0]);
fclose($proc_pipes[1]);
fclose($proc_pipes[2]);
// Get exit code
$result = proc_close($proc);
} else {
LeUtils::log_error('unable to start acme client process');
return false;
}
// Run acme.sh command
$result = LeUtils::run_shell_command($acmecmd, $proc_env);

// acme.sh records the last used deploy hook and would automatically
// use it on the next run. This information must be removed from the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* Copyright (C) 2020-2021 Frank Wall
* Copyright (C) 2020-2024 Frank Wall
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -35,6 +35,7 @@
use OPNsense\AcmeClient\LeAccount;
use OPNsense\AcmeClient\LeAutomationFactory;
use OPNsense\AcmeClient\LeValidationFactory;
use OPNsense\AcmeClient\LeUtils;

/**
* Manage ACME certificates with acme.sh
Expand Down Expand Up @@ -474,37 +475,20 @@ public function remove()
LeUtils::log('wiping certificate config: ' . (string)$this->config->name);

// Preparation to run acme client
$proc_env = $this->acme_env; // env variables for proc_open()
$proc_env = $this->acme_env; // add env variables
$proc_env['PATH'] = $this::ACME_ENV_PATH;
$proc_desc = array( // descriptor array for proc_open()
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$proc_pipes = array();

// Run acme client to remove certificate and related config

// Prepare acme.sh command to remove certificate and related config
$acmecmd = '/usr/local/sbin/acme.sh '
. '--remove '
. implode(' ', $this->acme_args) . ' '
. LeUtils::execSafe('--domain %s', (string)$this->config->name);
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
fclose($proc_pipes[0]);
fclose($proc_pipes[1]);
fclose($proc_pipes[2]);
// Get exit code
$result = proc_close($proc);
} else {
LeUtils::log_error('unable to start acme client process');
return false;
}

// Check exit code
// Run acme.sh command
$result = LeUtils::run_shell_command($acmecmd, $proc_env);

// Check acme.sh result
if ($result) {
LeUtils::log_error('error removing certificate ' . (string)$this->config->name);
return false;
Expand Down Expand Up @@ -565,36 +549,19 @@ public function revoke()
$account_conf_file = $account_conf_dir . '/account.conf';

// Preparation to run acme client
$proc_env = $this->acme_env; // env variables for proc_open()
$proc_env = $this->acme_env; // add env variables
$proc_env['PATH'] = $this::ACME_ENV_PATH;
$proc_desc = array( // descriptor array for proc_open()
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$proc_pipes = array();

// Run acme client to revoke certificate

// Prepare acme.sh command to revoke certificate
$acmecmd = '/usr/local/sbin/acme.sh '
. '--revoke '
. implode(' ', $this->acme_args) . ' '
. LeUtils::execSafe('--domain %s', (string)$this->config->name) . ' '
. LeUtils::execSafe('--accountconf %s', $account_conf_file);
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
fclose($proc_pipes[0]);
fclose($proc_pipes[1]);
fclose($proc_pipes[2]);
// Get exit code
$result = proc_close($proc);
} else {
LeUtils::log_error('unable to start acme client process');
return false;
}

// Run acme.sh command
$result = LeUtils::run_shell_command($acmecmd, $proc_env);

// Check exit code
if ($result) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* Copyright (C) 2017-2020 Frank Wall
* Copyright (C) 2017-2024 Frank Wall
* Copyright (C) 2015 Deciso B.V.
* Copyright (C) 2010 Jim Pingle <[email protected]>
* Copyright (C) 2008 Shrew Soft Inc. <[email protected]>
Expand Down Expand Up @@ -194,17 +194,26 @@ public static function run_shell_command($proc_cmd, $proc_env = array())

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
// This workaround ensures that the accurate return code
// is reliably returned.
fclose($proc_pipes[0]);
$output = array();
while (!feof($proc_pipes[1])) {
$output[] = rtrim(fgets($proc_pipes[1], 1024), "\n");
}
fclose($proc_pipes[1]);
while (!feof($proc_pipes[2])) {
$output[] = rtrim(fgets($proc_pipes[2], 1024), "\n");
}
fclose($proc_pipes[2]);

// Get exit code
$result = proc_close($proc);
log_error(sprintf("AcmeClient: The shell command '%s' returned exit code '%d'", $proc_cmd, $result));
log_error(sprintf("AcmeClient: The shell command returned exit code '%d': '%s'", $result, $proc_cmd));
return($result);
} else {
log_error(sprintf("AcmeClient: Unable to prepare shell command '%s'", $proc_cmd));
return false;
return(-999);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* Copyright (C) 2020-2021 Frank Wall
* Copyright (C) 2020-2024 Frank Wall
* Copyright (C) 2018 Deciso B.V.
* Copyright (C) 2018 Franco Fichtner <[email protected]>
* All rights reserved.
Expand Down Expand Up @@ -154,16 +154,10 @@ public function run(bool $renew = false)
$account_conf_file = $account_conf_dir . '/account.conf';

// Preparation to run acme client
$proc_env = $this->acme_env; // env variables for proc_open()
$proc_env = $this->acme_env; // add env variables
$proc_env['PATH'] = $this::ACME_ENV_PATH;
$proc_desc = array( // descriptor array for proc_open()
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$proc_pipes = array();

// Run acme client

// Prepare acme.sh command
// NOTE: We "export" certificates to our own directory, so we don't have to deal
// with domain names in filesystem, but instead can use the ID of our certObj, which
// will never change.
Expand All @@ -173,25 +167,14 @@ public function run(bool $renew = false)
. implode(' ', $this->acme_args) . ' '
. LeUtils::execSafe('--accountconf %s', $account_conf_file);
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);

// Make sure the resource could be setup properly
if (is_resource($proc)) {
// Close all pipes
fclose($proc_pipes[0]);
fclose($proc_pipes[1]);
fclose($proc_pipes[2]);
// Get exit code
$result = proc_close($proc);
} else {
LeUtils::log_error('unable to start acme client process');
return false;
}

// Run acme.sh command
$result = LeUtils::run_shell_command($acmecmd, $proc_env);

// Run optional cleanup tasks.
$this->cleanup();

// Check validation result
// Check acme.sh result
if ($result) {
LeUtils::log_error('domain validation failed (' . $this->getMethod() . ')');
return false;
Expand Down

0 comments on commit 5f3092d

Please sign in to comment.