diff --git a/src/helper/Site_Letsencrypt.php b/src/helper/Site_Letsencrypt.php index 2f99c218..6d4b64d4 100644 --- a/src/helper/Site_Letsencrypt.php +++ b/src/helper/Site_Letsencrypt.php @@ -77,18 +77,20 @@ public function revokeAuthorizationChallenge(AuthorizationChallenge $challenge) ]] ]; - $client = $this->getHttpClient(); - $resourceUrl = $this->getResourceUrl(ResourcesDirectory::NEW_ORDER); - $response = $client->request('POST', $resourceUrl, $client->signKidPayload($resourceUrl, $this->getResourceAccount(), $payload)); - if (!isset($response['authorizations']) || !$response['authorizations']) { - throw new ChallengeNotSupportedException(); + $client = $this->getHttpClient(); + $resourceUrl = $this->getResourceUrl( ResourcesDirectory::NEW_ORDER ); + $response = $client->request( 'POST', $resourceUrl, $client->signKidPayload( $resourceUrl, $this->getResourceAccount(), $payload ) ); + if ( ! isset( $response['authorizations'] ) || ! $response['authorizations'] ) { + \EE::warning( 'Challenge not supported for domain' ); + + return false; } $orderEndpoint = $client->getLastLocation(); foreach ($response['authorizations'] as $authorizationEndpoint) { $authorizationsResponse = $client->request('POST', $authorizationEndpoint, $client->signKidPayload($authorizationEndpoint, $this->getResourceAccount(), [ 'status' => 'deactivated' ])); } - return; + return true; } } @@ -207,9 +209,10 @@ public function authorize( Array $domains, $wildcard = false, $preferred_challen $order = $this->client->requestOrder( $domains ); } catch ( \Exception $e ) { \EE::warning( 'It seems you\'re in local environment or using non-public domain, please check logs. Skipping letsencrypt.' ); - throw $e; - } + \EE::log( 'You can fix the issue and re-run: ee site ssl-verify ' . $domains[0] ); + return false; + } $authorizationChallengesToSolve = []; foreach ( $order->getAuthorizationsChallenges() as $domainKey => $authorizationChallenges ) { $authorizationChallenge = null; @@ -223,12 +226,14 @@ public function authorize( Array $domains, $wildcard = false, $preferred_challen \EE::debug( 'Authorization challenge supported by solver. Solver: ' . $solverName . ' Challenge: ' . $candidate->getType() ); break; } - // Should not get here as we are handling it. \EE::debug( 'Authorization challenge not supported by solver. Solver: ' . $solverName . ' Challenge: ' . $candidate->getType() ); \EE::debug( print_r( $candidate, true ) ); } if ( null === $authorizationChallenge ) { - throw new ChallengeNotSupportedException(); + \EE::warning( 'Challenge not supported for domain ' . $domainKey ); + \EE::log( 'You can fix the issue and re-run: ee site ssl-verify ' . $domainKey ); + + return false; } \EE::debug( 'Storing authorization challenge. Domain: ' . $domainKey . ' Challenge: ' . print_r( $authorizationChallenge->toArray(), true ) ); @@ -367,7 +372,9 @@ public function check( Array $domains, $wildcard = false, $preferred_challenge = } } if ( null === $authorizationChallenge ) { - throw new ChallengeNotSupportedException(); + \EE::warning( 'Challenge not supported for domain' ); + + return false; } } else { if ( ! $this->repository->hasDomainAuthorizationChallenge( $domain ) ) { @@ -375,21 +382,27 @@ public function check( Array $domains, $wildcard = false, $preferred_challenge = } $authorizationChallenge = $this->repository->loadDomainAuthorizationChallenge( $domain ); if ( ! $solver->supports( $authorizationChallenge ) ) { - throw new ChallengeNotSupportedException(); + \EE::warning( 'Challenge not supported for domain' ); + + return false; } } \EE::debug( 'Challenge loaded.' ); $authorizationChallenge = $this->client->reloadAuthorization( $authorizationChallenge ); if ( ! $authorizationChallenge->isValid() ) { - \EE::debug( sprintf( 'Testing the challenge for domain %s', $domain ) ); - if ( ! $validator->isValid( $authorizationChallenge ) ) { - throw new \Exception( sprintf( 'Can not validate challenge for domain %s', $domain ) ); - } - - \EE::debug( sprintf( 'Requesting authorization check for domain %s', $domain ) ); try { + \EE::debug( sprintf( 'Testing the challenge for domain %s', $domain ) ); + if ( ! $validator->isValid( $authorizationChallenge ) ) { + \EE::warning( 'Can not validate challenge for domain ' . $domain ); + \EE::log( 'You can fix the issue and re-run: ee site ssl-verify ' . $domain ); + + return false; + } + + \EE::debug( sprintf( 'Requesting authorization check for domain %s', $domain ) ); $this->client->challengeAuthorization( $authorizationChallenge ); + $authorizationChallengeToCleanup[] = $authorizationChallenge; } catch ( \Exception $e ) { \EE::debug( $e->getMessage() ); \EE::warning( 'Challenge Authorization failed. Check logs and check if your domain is pointed correctly to this server.' ); @@ -398,9 +411,9 @@ public function check( Array $domains, $wildcard = false, $preferred_challenge = $site_name = str_replace( '*.', '', $site_name ); \EE::log( "Re-run `ee site ssl-verify $site_name` after fixing the issue." ); - throw $e; + + return false; } - $authorizationChallengeToCleanup[] = $authorizationChallenge; } } @@ -581,7 +594,7 @@ private function executeRenewal( $domain, array $alternativeNames, $force = fals ) ); - return; + return true; } \EE::log( @@ -627,12 +640,18 @@ private function executeRenewal( $domain, array $alternativeNames, $force = fals \EE::warning( 'A critical error occured during certificate renewal' ); \EE::debug( print_r( $e, true ) ); - throw $e; + \EE::warning( 'Challenge Authorization failed. Check logs and check if your domain is pointed correctly to this server.' ); + \EE::log( 'You can fix the issue and re-run: ee site ssl-verify ' . $domains[0] ); + + return false; } catch ( \Throwable $e ) { \EE::warning( 'A critical error occured during certificate renewal' ); \EE::debug( print_r( $e, true ) ); - throw $e; + \EE::warning( 'Challenge Authorization failed. Check logs and check if your domain is pointed correctly to this server.' ); + \EE::log( 'You can fix the issue and re-run: ee site ssl-verify ' . $domains[0] ); + + return false; } } diff --git a/src/helper/class-ee-site.php b/src/helper/class-ee-site.php index 627d619b..47320f65 100644 --- a/src/helper/class-ee-site.php +++ b/src/helper/class-ee-site.php @@ -1543,6 +1543,7 @@ protected function init_le( $site_url, $site_fs_path, $wildcard = false, $www_or \EE::get_runner()->ensure_present_in_config( 'le-mail', $this->le_mail ); if ( ! $client->register( $this->le_mail ) ) { $this->site_data['site_ssl'] = null; + \EE::warning( 'SSL registration failed.' ); return; } @@ -1553,6 +1554,9 @@ protected function init_le( $site_url, $site_fs_path, $wildcard = false, $www_or $client->revokeAuthorizationChallenges( $domains ); if ( ! $client->authorize( $domains, $wildcard, $preferred_challenge ) ) { + $this->site_data['site_ssl'] = null; + \EE::warning( 'SSL authorization failed. Site will be created without SSL. You can fix the issue and re-run: ee site ssl-verify ' . $site_url ); + return; } $api_key_absent = empty( get_config_value( 'cloudflare-api-key' ) ); @@ -1563,7 +1567,12 @@ protected function init_le( $site_url, $site_fs_path, $wildcard = false, $www_or EE::log( 'Waiting for DNS entry propagation.' ); sleep( 10 ); } - $this->ssl_verify( [], [ 'force' => $force ], $www_or_non_www ); + if ( ! $this->ssl_verify( [], [ 'force' => $force ], $www_or_non_www ) ) { + $this->site_data['site_ssl'] = null; + \EE::warning( 'SSL verification failed. You can fix the issue and re-run: ee site ssl-verify ' . $site_url ); + + return; + } } } @@ -1603,6 +1612,7 @@ private function get_cert_domains( string $site_url, $wildcard, $www_or_non_www * @param string Absolute path of site. * @param string $site_container_path * + * * @return bool */ protected function check_www_or_non_www_domain( $site_url, $site_path, $site_container_path ): bool { @@ -1679,29 +1689,24 @@ public function ssl_verify( $args = [], $assoc_args = [], $www_or_non_www = fals $preferred_challenge = get_preferred_ssl_challenge( $domains ); - try { - $client->check( $domains, $this->site_data['site_ssl_wildcard'], $preferred_challenge ); - } catch ( \Exception $e ) { - if ( $called_by_ee && $api_key_absent ) { - throw $e; - } + if ( ! $client->check( $domains, $this->site_data['site_ssl_wildcard'], $preferred_challenge ) ) { $is_solver_dns = ( $this->site_data['site_ssl_wildcard'] || 'dns' === $preferred_challenge ) ? true : false; $api_key_present = ! empty( get_config_value( 'cloudflare-api-key' ) ); - if ( $called_by_ee && ! $is_solver_dns && $api_key_present ) { - throw $e; - } - - $warning = ( $is_solver_dns && $api_key_present ) ? "The dns entries have not yet propogated. Manually check: \nhost -t TXT _acme-challenge." . $this->site_data['site_url'] . "\nBefore retrying `ee site ssl " . $this->site_data['site_url'] . "`" : 'Failed to verify SSL: ' . $e->getMessage(); + $warning = ( $is_solver_dns && $api_key_present ) + ? "The dns entries have not yet propogated. Manually check: \nhost -t TXT _acme-challenge." . $this->site_data['site_url'] . "\nBefore retrying `ee site ssl " . $this->site_data['site_url'] . "`" + : 'Failed to verify SSL.'; EE::warning( $warning ); EE::warning( sprintf( 'Check logs and retry `ee site ssl-verify %s` once the issue is resolved.', $this->site_data['site_url'] ) ); - return; + return false; } $san = array_values( array_diff( $domains, [ $this->site_data['site_url'] ] ) ); - $client->request( $this->site_data['site_url'], $san, $this->le_mail, $force ); + if ( ! $client->request( $this->site_data['site_url'], $san, $this->le_mail, $force ) ) { + return false; + } if ( ! $this->site_data['site_ssl_wildcard'] ) { $client->cleanup(); @@ -1710,6 +1715,8 @@ public function ssl_verify( $args = [], $assoc_args = [], $www_or_non_www = fals reload_global_nginx_proxy(); EE::success( 'SSL verification completed.' ); + + return true; } /** @@ -2284,7 +2291,7 @@ public function sync( $args, $assoc_args ) { * * [--list] * : List all available backups on remote. - * + * * ## EXAMPLES * * # Backup a site @@ -2296,7 +2303,7 @@ public function sync( $args, $assoc_args ) { public function backup( $args, $assoc_args ) { $args = auto_site_name( $args, 'site', __FUNCTION__ ); $this->site_data = get_site_info( $args, true, true, true ); - $backup_restore = new Site_Backup_Restore(); + $backup_restore = new Site_Backup_Restore(); $backup_restore->backup( $args, $assoc_args ); } @@ -2315,7 +2322,7 @@ public function backup( $args, $assoc_args ) { * * # Restore latest backup of site. * $ ee site restore example.com - * + * * # Restore specific backup of site. * $ ee site restore example.com --id=1737560626_2025-01-22-15-43-46 * @@ -2323,7 +2330,7 @@ public function backup( $args, $assoc_args ) { public function restore( $args, $assoc_args ) { $args = auto_site_name( $args, 'site', __FUNCTION__ ); $this->site_data = get_site_info( $args, true, true, true ); - $backup_restore = new Site_Backup_Restore(); + $backup_restore = new Site_Backup_Restore(); $backup_restore->restore( $args, $assoc_args ); }