-*- coding: utf-8 -*-
Changes with Apache 2.5.1
+ *) mod_md: v1.0.4, removed the 'a2md' utility command from build. Only used in github
+ testing. Avoid problems with our build system that had problems after the latest
+ changes to make a clean initial build. Remove the windows a2md.dsp therefore also.
+ [Stefan Eissing]
+
*) mod_ssl: Fail with 403 if the username for FakeBasicAuth mode
includes a colon character. PR 52644. [Joe Orton]
# See the License for the specific language governing permissions and
# limitations under the License.
-COMMON_SOURCES = \
- md_acme.c \
- md_acme_acct.c \
- md_acme_authz.c \
- md_acme_drive.c \
- md_core.c \
- md_curl.c \
- md_crypt.c \
- md_http.c \
- md_json.c \
- md_jws.c \
- md_log.c \
- md_reg.c \
- md_store.c \
- md_store_fs.c \
- md_util.c
-
-COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
-COMMON_SHOBJECTS = $(COMMON_SOURCES:.c=.slo)
-
-a2md_CFLAGS = $(EXTRA_CPPFLAGS) $(EXTRA_INCLUDES)
-
-a2md_SOURCES = \
- md_cmd_main.c \
- md_cmd_acme.c \
- md_cmd_reg.c \
- md_cmd_store.c
-
-a2md_OBJECTS = $(a2md_SOURCES:.c=.o)
-a2md_SHOBJECTS = $(a2md_SOURCES:.c=.slo)
-
-a2md: $(a2md_OBJECTS) $(COMMON_OBJECTS) $(COMMON_SHOBJECTS) md.h
- $(LINK) $(a2md_CFLAGS) $(a2md_LTFLAGS) $(a2md_OBJECTS) $(COMMON_OBJECTS) $(A2MD_LDADD) $(AP_LIBS)
-
-# top be installed in bin dir
-bin_PROGRAMS = a2md
-
-TARGETS = $(bin_PROGRAMS)
-
-local-shared-build: $(LTLIBRARY_NAME) $(SHARED_TARGETS) a2md
+#
+# standard stuff
+#
-include $(top_srcdir)/build/library.mk
include $(top_srcdir)/build/special.mk
+++ /dev/null
-# Microsoft Developer Studio Project File - Name="a2md" - Package Owner=<4>\r
-# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
-# ** DO NOT EDIT **\r
-\r
-# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
-\r
-CFG=a2md - Win32 Debug\r
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "a2md.mak".\r
-!MESSAGE \r
-!MESSAGE You can specify a configuration when running NMAKE\r
-!MESSAGE by defining the macro CFG on the command line. For example:\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "a2md.mak" CFG="a2md - Win32 Debug"\r
-!MESSAGE \r
-!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
-!MESSAGE "a2md - Win32 Release" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "a2md - Win32 Debug" (based on "Win32 (x86) Console Application")\r
-!MESSAGE \r
-\r
-# Begin Project\r
-# PROP AllowPerConfigDependencies 0\r
-# PROP Scc_ProjName ""\r
-# PROP Scc_LocalPath ""\r
-CPP=cl.exe\r
-RSC=rc.exe\r
-\r
-!IF "$(CFG)" == "a2md - Win32 Release"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 0\r
-# PROP BASE Output_Dir "Release"\r
-# PROP BASE Intermediate_Dir "Release"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 0\r
-# PROP Output_Dir "Release"\r
-# PROP Intermediate_Dir "Release"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c\r
-# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../server/mpm/winnt" /I "../../srclib/openssl/inc32" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/jansson/include" /I "../../srclib/curl/include" /I "../core" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Release\a2md_src" /FD /c\r
-# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
-# ADD RSC /l 0x409 /fo"Release/a2md.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d "BIN_NAME=a2md.exe" /d "LONG_NAME=a2md command line utility"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 kernel32.lib user32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console\r
-# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib libeay32.lib ssleay32.lib jansson.lib libcurl.lib /libpath:"../../Release/" /libpath:"../../srclib/apr/Release" /libpath:"../../srclib/apr-util/Release" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/curl/lib" /libpath:"../../srclib/jansson/lib" /nologo /subsystem:console /debug /opt:ref\r
-# Begin Special Build Tool\r
-TargetPath=.\Release\a2md.exe\r
-SOURCE="$(InputPath)"\r
-PostBuild_Desc=Embed .manifest\r
-PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1\r
-# End Special Build Tool\r
-\r
-!ELSEIF "$(CFG)" == "a2md - Win32 Debug"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "Debug"\r
-# PROP BASE Intermediate_Dir "Debug"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "Debug"\r
-# PROP Intermediate_Dir "Debug"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c\r
-# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/a2md_src" /FD /c\r
-# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
-# ADD RSC /l 0x409 /fo"Debug/a2md.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d "BIN_NAME=a2md.exe" /d "LONG_NAME=a2md command line utility"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug\r
-# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib libeay32.lib ssleay32.lib jansson_d.lib libcurl.lib /libpath:"../../Debug/" /libpath:"../../srclib/apr/Debug" /libpath:"../../srclib/apr-util/Debug" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/curl/lib" /libpath:"../../srclib/jansson/lib" /nologo /subsystem:console /debug /opt:ref\r
-# Begin Special Build Tool\r
-TargetPath=.\Debug\a2md.exe\r
-SOURCE="$(InputPath)"\r
-PostBuild_Desc=Embed .manifest\r
-PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1\r
-# End Special Build Tool\r
-\r
-!ENDIF \r
-\r
-# Begin Target\r
-\r
-# Name "a2md - Win32 Release"\r
-# Name "a2md - Win32 Debug"\r
-# Begin Source File\r
-\r
-SOURCE=./md_cmd_main.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_cmd_acme.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_cmd_reg.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_cmd_store.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_core.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_crypt.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_curl.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_http.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_json.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_jws.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_log.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_reg.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_store.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_store_fs.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_util.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_acme.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_acme_acct.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_acme_authz.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=./md_acme_drive.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-\r
-SOURCE=..\..\build\win32\httpd.rc\r
-# End Source File\r
-# End Target\r
-# End Project\r
dnl # start of module specific part
APACHE_MODPATH_INIT(md)
-dnl # list of common object files
-md_common_objs="dnl
+dnl # list of module object files
+md_objs="dnl
md_acme.lo dnl
md_acme_acct.lo dnl
md_acme_authz.lo dnl
md_store.lo dnl
md_store_fs.lo dnl
md_util.lo dnl
-"
-
-dnl # list of module object files
-md_objs="dnl
mod_md.lo dnl
mod_md_config.lo dnl
mod_md_os.lo dnl
APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
dnl # hook module into the Autoconf mechanism (--enable-md)
-APACHE_MODULE(md, [Managed Domain handling], $md_objs $md_common_objs, , most, [
+APACHE_MODULE(md, [Managed Domain handling], $md_objs, , most, [
APACHE_CHECK_OPENSSL
if test "x$ac_cv_openssl" = "xno" ; then
AC_MSG_WARN([libssl (or compatible) not found])
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef md_cmd_h
-#define md_cmd_h
-
-struct apr_getopt_option_t;
-struct apr_table_t;
-struct md_json_t;
-struct md_store_t;
-struct md_ref_t;
-struct md_acme_t;
-
-typedef struct md_opts md_opts;
-typedef struct md_cmd_ctx md_cmd_ctx;
-typedef struct md_cmd_t md_cmd_t;
-
-typedef apr_status_t md_cmd_opt_fn(md_cmd_ctx *ctx, int option, const char *optarg);
-typedef apr_status_t md_cmd_do_fn(md_cmd_ctx *ctx, const md_cmd_t *cmd);
-
-struct md_cmd_ctx {
- apr_pool_t *p;
-
- const char *base_dir;
- const char *ca_url;
-
- struct md_store_t *store;
- struct md_reg_t *reg;
- struct md_acme_t *acme;
-
- struct apr_table_t *options;
-
- const char *tos;
-
- struct md_json_t *json_out;
-
- int argc;
- const char *const *argv;
-};
-
-#define MD_CMD_OPT_PROXY_URL "proxy-url"
-
-int md_cmd_ctx_has_option(md_cmd_ctx *ctx, const char *key);
-const char *md_cmd_ctx_get_option(md_cmd_ctx *ctx, const char *key);
-
-void md_cmd_ctx_set_option(md_cmd_ctx *ctx, const char *key, const char *value);
-
-
-/* needs */
-#define MD_CTX_NONE 0x0000
-#define MD_CTX_STORE 0x0001
-#define MD_CTX_REG 0x0002
-#define MD_CTX_ACME 0x0004
-
-struct md_cmd_t {
- const char *name; /* command name */
- int needs; /* command needs: store, reg, acme etc. */
-
- md_cmd_opt_fn *opt_fn; /* callback for options handling */
- md_cmd_do_fn *do_fn; /* callback for executing the command */
-
- const struct apr_getopt_option_t *opts; /* options definitions */
- const md_cmd_t **sub_cmds; /* sub commands of this command or NULL */
-
- const char *synopsis; /* command line synopsis for this command */
- const char *description; /* textual description of this command */
-};
-
-extern apr_getopt_option_t MD_NoOptions[];
-
-apr_status_t usage(const md_cmd_t *cmd, const char *msg);
-
-apr_array_header_t *md_cmd_gather_args(md_cmd_ctx *ctx, int index);
-
-void md_cmd_print_md(md_cmd_ctx *ctx, const md_t *md);
-
-#endif /* md_cmd_h */
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <apr_lib.h>
-#include <apr_buckets.h>
-#include <apr_getopt.h>
-#include <apr_hash.h>
-#include <apr_strings.h>
-
-#include "md.h"
-#include "md_acme.h"
-#include "md_acme_acct.h"
-#include "md_acme_authz.h"
-#include "md_json.h"
-#include "md_http.h"
-#include "md_log.h"
-#include "md_reg.h"
-#include "md_store.h"
-#include "md_util.h"
-#include "md_version.h"
-#include "md_cmd.h"
-#include "md_cmd_acme.h"
-
-/**************************************************************************************************/
-/* command: acme newreg */
-
-static apr_status_t cmd_acme_newreg(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_status_t rv = APR_SUCCESS;
- int i;
-
- apr_array_header_t *contacts = apr_array_make(ctx->p, 5, sizeof(const char *));
- for (i = 0; i < ctx->argc; ++i) {
- APR_ARRAY_PUSH(contacts, const char *) = md_util_schemify(ctx->p, ctx->argv[i], "mailto");
- }
- if (apr_is_empty_array(contacts)) {
- return usage(cmd, "newreg needs at least one contact email as argument");
- }
-
- if (APR_SUCCESS == (rv = md_acme_create_acct(ctx->acme, ctx->p, contacts, ctx->tos))) {
- md_acme_save(ctx->acme, ctx->store, ctx->p);
- fprintf(stdout, "registered: %s\n", md_acme_get_acct_id(ctx->acme));
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ctx->p, "register new account");
- }
-
- return rv;
-}
-
-static md_cmd_t AcmeNewregCmd = {
- "newreg", MD_CTX_ACME,
- NULL, cmd_acme_newreg, MD_NoOptions, NULL,
- "newreg contact-uri [contact-uri...]",
- "register a new account at ACME server with given contact uri (email)",
-};
-
-/**************************************************************************************************/
-/* command: acme agree */
-
-static apr_status_t acct_agree_tos(md_cmd_ctx *ctx, const char *name,
- const char *tos, apr_pool_t *p)
-{
- apr_status_t rv;
-
- if (APR_SUCCESS == (rv = md_acme_use_acct(ctx->acme, ctx->store, ctx->p, name))) {
- if (!tos) {
- tos = ctx->acme->acct->agreement;
- if (!tos) {
- return APR_BADARG;
- }
- }
- rv = md_acme_agree(ctx->acme, ctx->p, tos);
- if (rv == APR_SUCCESS) {
- rv = md_acme_save(ctx->acme, ctx->store, ctx->p);
- fprintf(stdout, "agreed terms-of-service: %s\n", ctx->acme->acct->url);
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "agree to terms-of-service %s", tos);
- }
- }
- else if (APR_ENOENT == rv) {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "unknown account: %s", name);
- }
-
- return rv;
-}
-
-static apr_status_t cmd_acme_agree(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_status_t rv = APR_SUCCESS;
- int i;
-
- (void)cmd;
- for (i = 0; i < ctx->argc; ++i) {
- rv = acct_agree_tos(ctx, ctx->argv[i], ctx->tos, ctx->p);
- if (rv != APR_SUCCESS) {
- break;
- }
- }
- return rv;
-}
-
-static md_cmd_t AcmeAgreeCmd = {
- "agree", MD_CTX_STORE|MD_CTX_ACME,
- NULL, cmd_acme_agree, MD_NoOptions, NULL,
- "agree account",
- "agree to ACME terms of service",
-};
-
-/**************************************************************************************************/
-/* command: acme validate */
-
-static apr_status_t acct_validate(md_cmd_ctx *ctx, const char *name, apr_pool_t *p)
-{
- apr_status_t rv;
-
- if (APR_SUCCESS == (rv = md_acme_use_acct(ctx->acme, ctx->store, ctx->p, name))) {
- fprintf(stdout, "account valid: %s\n", name);
- }
- else if (APR_ENOENT == rv) {
- fprintf(stderr, "unknown account: %s", name);
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "validating account: %s", name);
- }
- return rv;
-}
-
-static apr_status_t cmd_acme_validate(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_status_t rv = APR_SUCCESS;
- int i;
-
- (void)cmd;
- for (i = 0; i < ctx->argc; ++i) {
- rv = acct_validate(ctx, ctx->argv[i], ctx->p);
- if (rv != APR_SUCCESS) {
- break;
- }
- }
- return rv;
-}
-
-static md_cmd_t AcmeValidateCmd = {
- "validate", MD_CTX_STORE|MD_CTX_ACME,
- NULL, cmd_acme_validate, MD_NoOptions, NULL,
- "validate account",
- "validate account existence",
-};
-
-/**************************************************************************************************/
-/* command: acme delreg */
-
-static apr_status_t acme_delreg(md_cmd_ctx *ctx, const char *name, apr_pool_t *p)
-{
- apr_status_t rv;
-
- if (ctx->acme) {
- if (APR_SUCCESS == (rv = md_acme_use_acct(ctx->acme, ctx->store, ctx->p, name))) {
- rv = md_acme_delete_acct(ctx->acme, ctx->store, ctx->p);
- if (rv == APR_SUCCESS) {
- fprintf(stdout, "deleted: %s\n", name);
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "delete account");
- }
- }
- else if (APR_ENOENT == rv) {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "unknown account: %s", name);
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "loading account: %s", name);
- }
- }
- else if (ctx->store) {
- rv = md_acme_unstore_acct(ctx->store, ctx->p, name);
- }
- else {
- rv = APR_EGENERAL;
- }
- return rv;
-}
-
-static apr_status_t cmd_acme_delreg(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_status_t rv = APR_SUCCESS;
- int i;
-
- (void)cmd;
- for (i = 0; i < ctx->argc; ++i) {
- rv = acme_delreg(ctx, ctx->argv[i], ctx->p);
- if (rv != APR_SUCCESS) {
- break;
- }
- }
- return rv;
-}
-
-static md_cmd_t AcmeDelregCmd = {
- "delreg", MD_CTX_STORE,
- NULL, cmd_acme_delreg, MD_NoOptions, NULL,
- "delreg account",
- "delete an existing ACME account",
-};
-
-/**************************************************************************************************/
-/* command: acme authz */
-
-static apr_status_t acme_newauthz(md_cmd_ctx *ctx, md_acme_acct_t *acct, const char *domain)
-{
- apr_status_t rv;
- md_acme_authz_t *authz;
-
- (void)acct;
- rv = md_acme_authz_register(&authz, ctx->acme, ctx->store, domain, ctx->p);
-
- if (rv == APR_SUCCESS) {
- fprintf(stdout, "authz: %s %s\n", domain, authz->location);
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ctx->p, "register new authz");
- }
- return rv;
-}
-
-static apr_status_t cmd_acme_authz(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- const char *s;
- apr_status_t rv;
- int i;
-
- if (ctx->argc <= 0) {
- return usage(cmd, NULL);
- }
- s = ctx->argv[0];
- if (APR_SUCCESS == (rv = md_acme_use_acct(ctx->acme, ctx->store, ctx->p, s))) {
- for (i = 1; i < ctx->argc; ++i) {
- rv = acme_newauthz(ctx, ctx->acme->acct, ctx->argv[i]);
- if (rv != APR_SUCCESS) {
- break;
- }
- }
- }
- else if (APR_ENOENT == rv) {
- fprintf(stderr, "unknown account: %s\n", s);
- return APR_EGENERAL;
- }
-
- return rv;
-}
-
-static md_cmd_t AcmeAuthzCmd = {
- "authz", MD_CTX_STORE|MD_CTX_ACME,
- NULL, cmd_acme_authz, MD_NoOptions, NULL,
- "authz account domain",
- "request a new authorization for an account and domain",
-};
-
-/**************************************************************************************************/
-/* command: acme */
-
-static const md_cmd_t *AcmeSubCmds[] = {
- &AcmeNewregCmd,
- &AcmeDelregCmd,
- &AcmeAgreeCmd,
- &AcmeAuthzCmd,
- &AcmeValidateCmd,
- NULL
-};
-
-md_cmd_t MD_AcmeCmd = {
- "acme", MD_CTX_STORE,
- NULL, NULL, MD_NoOptions, AcmeSubCmds,
- "acme cmd [opts] [args]",
- "play with the ACME server",
-};
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef md_cmd_acme_h
-#define md_cmd_acme_h
-
-extern md_cmd_t MD_AcmeCmd;
-
-#endif /* md_cmd_acme_h */
+++ /dev/null
-/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <apr_lib.h>
-#include <apr_buckets.h>
-#include <apr_getopt.h>
-#include <apr_hash.h>
-#include <apr_strings.h>
-
-#include "md.h"
-#include "md_acme.h"
-#include "md_json.h"
-#include "md_http.h"
-#include "md_log.h"
-#include "md_reg.h"
-#include "md_store.h"
-#include "md_store_fs.h"
-#include "md_util.h"
-#include "md_version.h"
-
-#include "md_cmd.h"
-#include "md_cmd_acme.h"
-#include "md_cmd_reg.h"
-#include "md_cmd_store.h"
-#include "md_curl.h"
-
-
-/**************************************************************************************************/
-/* command infrastructure */
-
-apr_getopt_option_t MD_NoOptions [] = {
- { NULL, 0, 0, NULL }
-};
-
-apr_status_t usage(const md_cmd_t *cmd, const char *msg)
-{
- const apr_getopt_option_t *opt;
- int i;
-
- if (msg) {
- fprintf(stderr, "%s\n", msg);
- }
- fprintf(stderr, "usage: %s\n", cmd->synopsis);
- if (cmd->description) {
- fprintf(stderr, "\t%s\n", cmd->description);
- }
- if (cmd->opts[0].name) {
- fprintf(stderr, " with the following options:\n");
-
- opt = NULL;
- for (i = 0; !opt || opt->optch; ++i) {
- opt = cmd->opts + i;
- if (opt->optch) {
- fprintf(stderr, " -%c | --%s %s\t%s\n",
- opt->optch, opt->name, opt->has_arg? "arg" : "", opt->description);
-
- }
- }
- }
- if (cmd->sub_cmds && cmd->sub_cmds[0]) {
- fprintf(stderr, " using one of the following commands:\n");
- for (i = 0; cmd->sub_cmds[i]; ++i) {
- fprintf(stderr, " \t%s\n", cmd->sub_cmds[i]->synopsis);
- fprintf(stderr, " \t\t%s\n", cmd->sub_cmds[i]->description);
- }
- }
-
- exit(msg? 1 : 2);
-}
-
-static apr_status_t md_cmd_ctx_init(md_cmd_ctx *ctx, apr_pool_t *p,
- int argc, const char *const *argv)
-{
- ctx->p = p;
- ctx->argc = argc;
- ctx->argv = argv;
- ctx->options = apr_table_make(p, 5);
-
- return ctx->options? APR_SUCCESS : APR_ENOMEM;
-}
-
-void md_cmd_ctx_set_option(md_cmd_ctx *ctx, const char *key, const char *value)
-{
- apr_table_setn(ctx->options, key, value);
-}
-
-int md_cmd_ctx_has_option(md_cmd_ctx *ctx, const char *option)
-{
- return NULL != apr_table_get(ctx->options, option);
-}
-
-const char *md_cmd_ctx_get_option(md_cmd_ctx *ctx, const char *key)
-{
- return apr_table_get(ctx->options, key);
-}
-
-static const md_cmd_t *find_cmd(const md_cmd_t **cmds, const char *name)
-{
- int i;
- if (cmds) {
- for (i = 0; cmds[i]; ++i) {
- if (!strcmp(name, cmds[i]->name)) {
- return cmds[i];
- }
- }
- }
- return NULL;
-}
-
-static apr_status_t cmd_process(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_getopt_t *os;
- const char *optarg;
- int opt;
- apr_status_t rv = APR_SUCCESS;
-
- md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ctx->p,
- "start processing cmd %s", cmd->name);
-
- apr_getopt_init(&os, ctx->p, ctx->argc, ctx->argv);
- while ((rv = apr_getopt_long(os, cmd->opts, &opt, &optarg)) == APR_SUCCESS) {
- if (!cmd->opt_fn) {
- return usage(cmd, NULL);
- }
- else if (APR_SUCCESS != (rv = cmd->opt_fn(ctx, opt, optarg))) {
- return usage(cmd, NULL);
- }
- }
- if (rv != APR_EOF) {
- return usage(cmd, NULL);
- }
-
- if (md_cmd_ctx_has_option(ctx, "help")) {
- return usage(cmd, NULL);
- }
- if (md_cmd_ctx_has_option(ctx, "version")) {
- fprintf(stdout, "version: %s\n", MOD_MD_VERSION);
- exit(0);
- }
-
- ctx->argv = os->argv + os->ind;
- ctx->argc -= os->ind;
-
- md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ctx->p, "args remaining: %d", ctx->argc);
-
- if (cmd->needs & (MD_CTX_STORE|MD_CTX_REG|MD_CTX_ACME) && !ctx->store) {
- if (!ctx->base_dir) {
- fprintf(stderr, "need store directory for command: %s\n", cmd->name);
- return APR_EINVAL;
- }
- if (APR_SUCCESS != (rv = md_store_fs_init(&ctx->store, ctx->p, ctx->base_dir))) {
- fprintf(stderr, "error %d creating store for: %s\n", rv, ctx->base_dir);
- return APR_EINVAL;
- }
- }
- if (cmd->needs & MD_CTX_REG && !ctx->reg) {
- if (!ctx->store) {
- fprintf(stderr, "need store for registry: %s\n", cmd->name);
- return APR_EINVAL;
- }
- if (APR_SUCCESS != (rv = md_reg_init(&ctx->reg, ctx->p, ctx->store,
- md_cmd_ctx_get_option(ctx, MD_CMD_OPT_PROXY_URL)))) {
- fprintf(stderr, "error %d creating registry from store: %s\n", rv, ctx->base_dir);
- return APR_EINVAL;
- }
- }
- if (cmd->needs & MD_CTX_ACME && !ctx->acme) {
- if (!ctx->store) {
- fprintf(stderr, "need store for ACME: %s\n", cmd->name);
- return APR_EINVAL;
- }
- rv = md_acme_create(&ctx->acme, ctx->p, ctx->ca_url,
- md_cmd_ctx_get_option(ctx, MD_CMD_OPT_PROXY_URL));
- if (APR_SUCCESS != rv) {
- fprintf(stderr, "error creating acme instance %s (%s)\n",
- ctx->ca_url, ctx->base_dir);
- return rv;
- }
- rv = md_acme_setup(ctx->acme);
- if (rv != APR_SUCCESS) {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ctx->p, "contacting %s", ctx->ca_url);
- return rv;
- }
- }
-
- if (cmd->sub_cmds && cmd->sub_cmds[0]) {
- const md_cmd_t *sub_cmd;
-
- if (!ctx->argc) {
- return usage(cmd, "sub command is missing");
- }
-
- md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ctx->p, "sub command %s", ctx->argv[0]);
-
- sub_cmd = find_cmd(cmd->sub_cmds, ctx->argv[0]);
- if (sub_cmd) {
- return cmd_process(ctx, sub_cmd);
- }
- else if (!cmd->do_fn) {
- fprintf(stderr, "unknown cmd: %s\n", ctx->argv[0]);
- return APR_EINVAL;
- }
- }
-
- if (cmd->do_fn) {
- md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ctx->p, "%s->do_fn", cmd->name);
- return cmd->do_fn(ctx, cmd);
- }
- return APR_EINVAL;
-}
-
-/**************************************************************************************************/
-/* logging setup */
-
-static md_log_level_t active_level = MD_LOG_INFO;
-
-static int log_is_level(void *baton, apr_pool_t *p, md_log_level_t level)
-{
- (void)baton;
- (void)p;
- return level <= active_level;
-}
-
-#define LOG_BUF_LEN 16*1024
-
-static void log_print(const char *file, int line, md_log_level_t level,
- apr_status_t rv, void *baton, apr_pool_t *p, const char *fmt, va_list ap)
-{
- if (log_is_level(baton, p, level)) {
- char buffer[LOG_BUF_LEN];
- char errbuff[32];
-
- apr_vsnprintf(buffer, LOG_BUF_LEN-1, fmt, ap);
- buffer[LOG_BUF_LEN-1] = '\0';
-
- if (rv) {
- fprintf(stderr, "[%s:%d %s][%d(%s)] %s\n", file, line,
- md_log_level_name(level), rv,
- apr_strerror(rv, errbuff, sizeof(errbuff)/sizeof(errbuff[0])),
- buffer);
- }
- else if (active_level == MD_LOG_INFO) {
- fprintf(stderr, "%s\n", buffer);
- }
- else {
- fprintf(stderr, "[%s:%d %s][ok] %s\n", file, line,
- md_log_level_name(level), buffer);
- }
- }
-}
-
-/**************************************************************************************************/
-/* utils */
-
-void md_cmd_print_md(md_cmd_ctx *ctx, const md_t *md)
-{
- assert(md);
- if (ctx->json_out) {
- md_json_t *json = md_to_json(md, ctx->p);
- md_json_addj(json, ctx->json_out, "output", NULL);
- }
- else {
- int i;
- fprintf(stdout, "md: %s [", md->name);
- for (i = 0; i < md->domains->nelts; ++i) {
- const char *domain = APR_ARRAY_IDX(md->domains, i, const char*);
- fprintf(stdout, "%s%s", (i? ", " : ""), domain);
- }
- fprintf(stdout, "]\n");
- }
-}
-
-static int pool_abort(int rv)
-{
- (void)rv;
- abort();
-}
-
-apr_array_header_t *md_cmd_gather_args(md_cmd_ctx *ctx, int index)
-{
- int i;
-
- apr_array_header_t *args = apr_array_make(ctx->p, 5, sizeof(const char *));
- for (i = index; i < ctx->argc; ++i) {
- APR_ARRAY_PUSH(args, const char *) = ctx->argv[i];
- }
- return args;
-}
-
-/**************************************************************************************************/
-/* command: main() */
-
-static void init_json_out(md_cmd_ctx *ctx)
-{
- apr_array_header_t *empty = apr_array_make(ctx->p, 1, sizeof(char*));
-
- ctx->json_out = md_json_create(ctx->p);
-
- md_json_setsa(empty, ctx->json_out, "output", NULL);
- md_json_setl(0, ctx->json_out, "status", NULL);
-}
-
-static apr_status_t main_opts(md_cmd_ctx *ctx, int option, const char *optarg)
-{
- switch (option) {
- case 'a':
- ctx->ca_url = optarg;
- break;
- case 'd':
- ctx->base_dir = optarg;
- break;
- case 'h':
- md_cmd_ctx_set_option(ctx, "help", "1");
- break;
- case 'j':
- init_json_out(ctx);
- break;
- case 'p':
- md_cmd_ctx_set_option(ctx, MD_CMD_OPT_PROXY_URL, optarg);
- break;
- case 'q':
- if (active_level > 0) {
- --active_level;
- }
- break;
- case 'v':
- if (active_level < MD_LOG_TRACE8) {
- ++active_level;
- }
- break;
- case 'V':
- md_cmd_ctx_set_option(ctx, "version", "1");
- break;
- case 't':
- ctx->tos = optarg;
- break;
- default:
- return APR_EINVAL;
- }
- return APR_SUCCESS;
-}
-
-static const md_cmd_t *MainSubCmds[] = {
- &MD_AcmeCmd,
- &MD_RegAddCmd,
- &MD_RegUpdateCmd,
- &MD_RegDriveCmd,
- &MD_RegListCmd,
- &MD_StoreCmd,
- NULL
-};
-
-static apr_getopt_option_t MainOptions [] = {
- { "acme", 'a', 1, "the url of the ACME server directory"},
- { "dir", 'd', 1, "directory for file data"},
- { "help", 'h', 0, "print usage information"},
- { "json", 'j', 0, "produce json output"},
- { "proxy", 'p', 1, "use the HTTP proxy url"},
- { "quiet", 'q', 0, "produce less output"},
- { "terms", 't', 1, "you agree to the terms of services (url)" },
- { "verbose", 'v', 0, "produce more output" },
- { "version", 'V', 0, "print version" },
- { NULL, 0, 0, NULL }
-};
-
-static md_cmd_t MainCmd = {
- "a2md", MD_CTX_NONE,
- main_opts, NULL,
- MainOptions, MainSubCmds,
- "a2md [options] cmd [cmd options] [args]",
- "Show and manipulate Apache Managed Domains",
-};
-
-#define BASE_VERSION "apachemd/" MOD_MD_VERSION
-
-int main(int argc, const char *const *argv)
-{
- apr_allocator_t *allocator;
- apr_status_t rv;
- apr_pool_t *p;
- md_cmd_ctx ctx;
-
- rv = apr_app_initialize(&argc, &argv, NULL);
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "error initializing APR (error code %d)\n", (int) rv);
- return 1;
- }
-
- if (atexit(apr_terminate)) {
- perror("error registering atexit");
- return 1;
- }
-
- memset(&ctx, 0, sizeof(ctx));
- md_log_set(log_is_level, log_print, NULL);
-
- apr_allocator_create(&allocator);
- rv = apr_pool_create_ex(&p, NULL, pool_abort, allocator);
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "error initializing pool\n");
- return 1;
- }
-
- md_http_use_implementation(md_curl_get_impl(p));
- md_acme_init(p, BASE_VERSION);
- md_cmd_ctx_init(&ctx, p, argc, argv);
-
- rv = cmd_process(&ctx, &MainCmd);
-
- if (ctx.json_out) {
- const char *out;
-
- md_json_setl(rv, ctx.json_out, "status", NULL);
- if (APR_SUCCESS != rv) {
- char errbuff[32];
-
- apr_strerror(rv, errbuff, sizeof(errbuff)/sizeof(errbuff[0]));
- md_json_sets(apr_pstrdup(p, errbuff), ctx.json_out, "description", NULL);
- }
-
- out = md_json_writep(ctx.json_out, p, MD_JSON_FMT_INDENT);
- if (!out) {
- rv = APR_EINVAL;
- }
-
- fprintf(stdout, "%s\n", out ? out : "<failed to serialize!>");
- }
-
- return (rv == APR_SUCCESS)? 0 : 1;
-}
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <apr_lib.h>
-#include <apr_buckets.h>
-#include <apr_getopt.h>
-#include <apr_hash.h>
-#include <apr_strings.h>
-
-#include "md.h"
-#include "md_json.h"
-#include "md_http.h"
-#include "md_log.h"
-#include "md_reg.h"
-#include "md_store.h"
-#include "md_util.h"
-#include "md_version.h"
-#include "md_cmd.h"
-#include "md_cmd_reg.h"
-
-/**************************************************************************************************/
-/* command: add */
-
-static apr_status_t cmd_reg_add(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- md_t *md;
- apr_status_t rv;
-
- (void)cmd;
- md = md_create(ctx->p, md_cmd_gather_args(ctx, 0));
- if (md->domains->nelts == 0) {
- return APR_EINVAL;
- }
-
- md->ca_url = ctx->ca_url;
- md->ca_proto = "ACME";
-
- rv = md_reg_add(ctx->reg, md, ctx->p);
- if (APR_SUCCESS == rv) {
- md_cmd_print_md(ctx, md_reg_get(ctx->reg, md->name, ctx->p));
- }
- return rv;
-}
-
-md_cmd_t MD_RegAddCmd = {
- "add", MD_CTX_REG,
- NULL, cmd_reg_add, MD_NoOptions, NULL,
- "add [opts] domain [domain...]",
- "Adds a new managed domain. Must not overlap with existing domains.",
-};
-
-/**************************************************************************************************/
-/* command: list */
-
-static int list_add_md(void *baton, md_reg_t *reg, md_t *md)
-{
- apr_array_header_t *mdlist = baton;
-
- (void)reg;
- APR_ARRAY_PUSH(mdlist, const md_t *) = md;
- return 1;
-}
-
-static int md_name_cmp(const void *v1, const void *v2)
-{
- return strcmp((*(const md_t**)v1)->name, (*(const md_t**)v2)->name);
-}
-
-static apr_status_t cmd_reg_list(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_array_header_t *mdlist = apr_array_make(ctx->p, 5, sizeof(md_t *));
- const char *name;
- const md_t *md;
- int i;
-
- (void)cmd;
- if (ctx->argc > 0) {
- for (i = 0; i < ctx->argc; ++i) {
- name = ctx->argv[i];
- md = md_reg_get(ctx->reg, name, ctx->p);
- if (!md) {
- md = md_reg_find(ctx->reg, name, ctx->p);
- }
- if (!md) {
- fprintf(stderr, "managed domain not found: %s\n", name);
- return APR_ENOENT;
- }
- md_cmd_print_md(ctx, md);
- }
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ctx->p, "list do");
- md_reg_do(list_add_md, mdlist, ctx->reg, ctx->p);
- qsort(mdlist->elts, (size_t)mdlist->nelts, sizeof(md_t *), md_name_cmp);
-
- for (i = 0; i < mdlist->nelts; ++i) {
- md = APR_ARRAY_IDX(mdlist, i, const md_t*);
- md_cmd_print_md(ctx, md);
- }
- }
-
- return APR_SUCCESS;
-}
-
-md_cmd_t MD_RegListCmd = {
- "list", MD_CTX_REG,
- NULL, cmd_reg_list, MD_NoOptions, NULL,
- "list",
- "list all managed domains"
-};
-
-/**************************************************************************************************/
-/* command: update */
-
-static apr_status_t cmd_reg_update(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- const char *name;
- const md_t *md;
- md_t *nmd;
- apr_status_t rv = APR_SUCCESS;
- int i, fields;
-
- if (ctx->argc <= 0) {
- return usage(cmd, "needs md name");
- }
- name = ctx->argv[0];
-
- md = md_reg_get(ctx->reg, name, ctx->p);
- if (NULL == md) {
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, ctx->p, "%s: not found", name);
- return APR_ENOENT;
- }
-
- /* update what */
- fields = 0;
- nmd = md_copy(ctx->p, md);
- if (NULL == md) {
- return APR_ENOMEM;
- }
-
- if (ctx->ca_url && (nmd->ca_url == NULL || strcmp(ctx->ca_url, nmd->ca_url))) {
- nmd->ca_url = ctx->ca_url;
- fields |= MD_UPD_CA_URL;
- }
-
- if (ctx->argc > 1) {
- const char *aspect = ctx->argv[1];
-
- if (!strcmp("domains", aspect)) {
- nmd->domains = md_cmd_gather_args(ctx, 2);
-
- if (apr_is_empty_array(nmd->domains)) {
- fprintf(stderr, "update domains needs at least 1 domain name as parameter\n");
- return APR_EGENERAL;
- }
- fields |= MD_UPD_DOMAINS;
- }
- else if (!strcmp("account", aspect)) {
- if (ctx->argc <= 1) {
- usage(cmd, "update name account <id>");
- return APR_EINVAL;
- }
- fields |= MD_UPD_CA_ACCOUNT;
- nmd->ca_account = ctx->argv[2];
- }
- else if (!strcmp("ca", aspect)) {
- if (ctx->argc <= 2) {
- usage(cmd, "update name ca <url> [proto]");
- return APR_EINVAL;
- }
- nmd->ca_url = ctx->argv[2];
- fields |= MD_UPD_CA_URL;
- if (ctx->argc > 3) {
- nmd->ca_proto = ctx->argv[3];
- fields |= MD_UPD_CA_PROTO;
- }
- }
- else if (!strcmp("contacts", aspect)) {
- apr_array_header_t *contacts = apr_array_make(ctx->p, 5, sizeof(const char *));
- for (i = 2; i < ctx->argc; ++i) {
- APR_ARRAY_PUSH(contacts, const char *) =
- md_util_schemify(ctx->p, ctx->argv[i], "mailto");
- }
- nmd->contacts = contacts;
-
- if (apr_is_empty_array(nmd->contacts)) {
- fprintf(stderr, "update contacts needs at least 1 contact email\n");
- return APR_EINVAL;
- }
- fields |= MD_UPD_CONTACTS;
- }
- else if (!strcmp("agreement", aspect)) {
- if (ctx->argc <= 1) {
- usage(cmd, "update name tos <url>");
- return APR_EINVAL;
- }
- nmd->ca_agreement = ctx->argv[2];
- fields |= MD_UPD_AGREEMENT;
- }
- else {
- fprintf(stderr, "unknown update aspect: %s\n", aspect);
- return APR_ENOTIMPL;
- }
- }
-
- if (fields) {
- if (APR_SUCCESS == (rv = md_reg_update(ctx->reg, ctx->p, md->name, nmd, fields))) {
- md = md_reg_get(ctx->reg, md->name, ctx->p);
- }
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, ctx->p, "no changes necessary");
- }
-
- if (APR_SUCCESS == rv) {
- md_cmd_print_md(ctx, md);
- }
- return rv;
-}
-
-md_cmd_t MD_RegUpdateCmd = {
- "update", MD_CTX_REG,
- NULL, cmd_reg_update, MD_NoOptions, NULL,
- "update name [ 'aspect' args ]",
- "update a managed domain's properties, where 'aspect' is one of: 'domains', 'ca', 'account', "
- "'contacts' or 'agreement'"
-};
-
-/**************************************************************************************************/
-/* command: drive */
-
-static apr_status_t assess_and_drive(md_cmd_ctx *ctx, md_t *md)
-{
- int errored, force, renew, reset;
- const char *challenge, *msg;
- apr_status_t rv;
-
- reset = md_cmd_ctx_has_option(ctx, "reset");
- force = md_cmd_ctx_has_option(ctx, "force");
- challenge = md_cmd_ctx_get_option(ctx, "challenge");
-
- if (APR_SUCCESS != (rv = md_reg_assess(ctx->reg, md, &errored, &renew, ctx->p))) {
- msg = "error assessing the current state of the "
- "Managed Domain. Please check the server "
- "logs or run this command in very verbose form and check the output.";
- goto out;
- }
-
- if (errored) {
- rv = APR_EGENERAL;
- msg = "is in error state. Please check the server "
- "logs or run this command in very verbose form and check the output.";
- goto out;
- }
-
- if (renew || force) {
-
- msg = "incomplete, sign up";
- if (md->state == MD_S_COMPLETE) {
- msg = force? "forcing renewal" : "for renewal";
- }
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, ctx->p, "%s: %s", md->name, msg);
-
- if (APR_SUCCESS == (rv = md_reg_stage(ctx->reg, md, challenge, reset, NULL, ctx->p))) {
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, ctx->p, "%s: loading", md->name);
-
- rv = md_reg_load(ctx->reg, md->name, ctx->p);
-
- if (APR_SUCCESS == rv) {
- msg = "new credentials active on next server restart";
- }
- else {
- msg = "error activating new credentials";
- }
- }
- else {
- msg = "error obtaining new credentials";
- }
- }
- else {
- msg = "up-to-date";
- }
-out:
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, ctx->p, "%s: %s", md->name, msg);
- return rv;
-}
-
-static apr_status_t cmd_reg_drive(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- apr_array_header_t *mdlist = apr_array_make(ctx->p, 5, sizeof(md_t *));
- md_t *md;
- apr_status_t rv;
- int i;
-
- (void)cmd;
- md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ctx->p, "drive do");
- if (ctx->argc > 0) {
- for (i = 0; i < ctx->argc; ++i) {
- md = md_reg_get(ctx->reg, ctx->argv[i], ctx->p);
- if (!md) {
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, ctx->p, "%s: not found", ctx->argv[i]);
- return APR_ENOENT;
- }
- APR_ARRAY_PUSH(mdlist, const md_t *) = md;
- }
- }
- else {
- md_reg_do(list_add_md, mdlist, ctx->reg, ctx->p);
- qsort(mdlist->elts, (size_t)mdlist->nelts, sizeof(md_t *), md_name_cmp);
- }
-
- rv = APR_SUCCESS;
- for (i = 0; i < mdlist->nelts; ++i) {
- md = APR_ARRAY_IDX(mdlist, i, md_t*);
- if (APR_SUCCESS != (rv = assess_and_drive(ctx, md))) {
- break;
- }
- }
-
- return rv;
-}
-
-static apr_status_t cmd_reg_drive_opts(md_cmd_ctx *ctx, int option, const char *optarg)
-{
- switch (option) {
- case 'c':
- md_cmd_ctx_set_option(ctx, "challenge", optarg);
- break;
- case 'f':
- md_cmd_ctx_set_option(ctx, "force", "1");
- break;
- case 'r':
- md_cmd_ctx_set_option(ctx, "reset", "1");
- break;
- default:
- return APR_EINVAL;
- }
- return APR_SUCCESS;
-}
-
-static apr_getopt_option_t DriveOptions [] = {
- { "challenge",'c', 1, "which challenge type to use"},
- { "force", 'f', 0, "force driving the managed domain, even when it seems valid"},
- { "reset", 'r', 0, "reset any staging data for the managed domain"},
- { NULL , 0, 0, NULL }
-};
-
-md_cmd_t MD_RegDriveCmd = {
- "drive", MD_CTX_REG,
- cmd_reg_drive_opts, cmd_reg_drive, DriveOptions, NULL,
- "drive [md...]",
- "drive all or the mentioned managed domains toward completeness"
-};
-
-
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef md_cmd_reg_h
-#define md_cmd_reg_h
-
-extern md_cmd_t MD_RegAddCmd;
-extern md_cmd_t MD_RegUpdateCmd;
-extern md_cmd_t MD_RegDriveCmd;
-extern md_cmd_t MD_RegListCmd;
-
-#endif /* md_cmd_reg_h */
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <apr_lib.h>
-#include <apr_buckets.h>
-#include <apr_getopt.h>
-#include <apr_hash.h>
-#include <apr_strings.h>
-
-#include "md.h"
-#include "md_json.h"
-#include "md_http.h"
-#include "md_log.h"
-#include "md_reg.h"
-#include "md_store.h"
-#include "md_util.h"
-#include "md_version.h"
-#include "md_cmd.h"
-#include "md_cmd_store.h"
-
-/**************************************************************************************************/
-/* command: store add */
-
-static apr_status_t cmd_add(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- md_t *md, *nmd;
- apr_status_t rv;
-
- (void)cmd;
- md = md_create(ctx->p, md_cmd_gather_args(ctx, 0));
- if (md->domains->nelts == 0) {
- return APR_EINVAL;
- }
-
- md->ca_url = ctx->ca_url;
- md->ca_proto = "ACME";
-
- rv = md_save(ctx->store, ctx->p, MD_SG_DOMAINS, md, 1);
- if (APR_SUCCESS == rv) {
- md_load(ctx->store, MD_SG_DOMAINS, md->name, &nmd, ctx->p);
- md_cmd_print_md(ctx, nmd);
- }
- return rv;
-}
-
-static md_cmd_t AddCmd = {
- "add", MD_CTX_STORE,
- NULL, cmd_add, MD_NoOptions, NULL,
- "add dns [dns2...]",
- "add a new managed domain 'dns' with all the additional domain names",
-};
-
-/**************************************************************************************************/
-/* command: store remove */
-
-static apr_status_t cmd_remove(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- const char *name;
- apr_status_t rv;
- int i;
-
- if (ctx->argc <= 0) {
- return usage(cmd, "needs at least one name");
- }
-
- for (i = 0; i < ctx->argc; ++i) {
- name = ctx->argv[i];
- rv = md_remove(ctx->store, ctx->p,
- MD_SG_DOMAINS, name, md_cmd_ctx_has_option(ctx, "force"));
- if (APR_SUCCESS != rv) {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ctx->p, "removing md %s", name);
- break;
- }
- }
-
- return rv;
-}
-
-static apr_status_t opts_remove(md_cmd_ctx *ctx, int option, const char *optarg)
-{
- (void)optarg;
- switch (option) {
- case 'f':
- md_cmd_ctx_set_option(ctx, "force", "1");
- break;
- default:
- return APR_EINVAL;
- }
- return APR_SUCCESS;
-}
-
-static apr_getopt_option_t RemoveOptions [] = {
- { "force", 'f', 0, "force removal, be silent about missing domains"},
- { NULL , 0, 0, NULL }
-};
-
-static md_cmd_t RemoveCmd = {
- "remove", MD_CTX_STORE,
- opts_remove, cmd_remove,
- RemoveOptions, NULL,
- "remove [options] name [name...]",
- "remove the managed domains <name> from the store",
-};
-
-/**************************************************************************************************/
-/* command: store list */
-
-static int list_md(void *baton, md_store_t *store, md_t *md, apr_pool_t *ptemp)
-{
- (void)store;
- (void)ptemp;
- md_cmd_print_md(baton, md);
- return 1;
-}
-
-static apr_status_t cmd_list(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- (void)cmd;
- return md_store_md_iter(list_md, ctx, ctx->store, ctx->p, MD_SG_DOMAINS, "*");
-}
-
-static md_cmd_t ListCmd = {
- "list", MD_CTX_STORE,
- NULL, cmd_list, MD_NoOptions, NULL,
- "list",
- "list all managed domains in the store"
-};
-
-/**************************************************************************************************/
-/* command: store update */
-
-static apr_status_t cmd_update(md_cmd_ctx *ctx, const md_cmd_t *cmd)
-{
- const char *name;
- md_t *md;
- apr_status_t rv;
- int changed;
-
- if (ctx->argc <= 0) {
- return usage(cmd, "needs md name");
- }
- name = ctx->argv[0];
-
- rv = md_load(ctx->store, MD_SG_DOMAINS, name, &md, ctx->p);
- if (APR_ENOENT == rv) {
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, ctx->p, "%s: not found", name);
- return rv;
- }
- else if (APR_SUCCESS != rv) {
- md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ctx->p, "loading store");
- return rv;
- }
-
- /* update what */
- changed = 0;
-
- if (ctx->argc > 1) {
- const char *aspect = ctx->argv[1];
-
- if (!strcmp("domains", aspect)) {
- md->domains = md_cmd_gather_args(ctx, 2);
-
- if (apr_is_empty_array(md->domains)) {
- fprintf(stderr, "update domains needs at least 1 domain name as parameter\n");
- return APR_EGENERAL;
- }
- changed = 1;
- }
- else {
- fprintf(stderr, "unknown update aspect: %s\n", aspect);
- return APR_ENOTIMPL;
- }
- }
-
- if (ctx->ca_url && (md->ca_url == NULL || strcmp(ctx->ca_url, md->ca_url))) {
- md->ca_url = ctx->ca_url;
- changed = 1;
- }
-
- if (changed) {
- rv = md_save(ctx->store, ctx->p, MD_SG_DOMAINS, md, 0);
- }
- else {
- md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, ctx->p, "no changes necessary");
- }
-
- if (APR_SUCCESS == rv) {
- rv = md_load(ctx->store, MD_SG_DOMAINS, name, &md, ctx->p);
- md_cmd_print_md(ctx, md);
- }
- return rv;
-}
-
-static md_cmd_t UpdateCmd = {
- "update", MD_CTX_STORE,
- NULL, cmd_update, MD_NoOptions, NULL,
- "update <name>",
- "update the managed domain <name> in the store"
-};
-
-/**************************************************************************************************/
-/* command: store */
-
-static const md_cmd_t *StoreSubCmds[] = {
- &AddCmd,
- &RemoveCmd,
- &ListCmd,
- &UpdateCmd,
- NULL
-};
-
-md_cmd_t MD_StoreCmd = {
- "store", MD_CTX_STORE,
- NULL, NULL, MD_NoOptions, StoreSubCmds,
- "store cmd [opts] [args]",
- "manipulate the MD store",
-};
-
+++ /dev/null
-/* Copyright 2017 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef md_cmd_store_h
-#define md_cmd_store_h
-
-extern md_cmd_t MD_StoreCmd;
-
-#endif /* md_cmd_store_h */
break;
case MD_S_ERROR:
md_log_perror( MD_LOG_MARK, MD_LOG_ERR, 0, p,
- "md(%s): in error state, unable to drive forward. It could "
- "be that files have gotten corrupted. You may check with "
- "a2md the status of this managed domain to diagnose the "
- " problem. As a last resort, you may delete the files for "
- " this md and start all over.", md->name);
+ "md(%s): in error state, unable to drive forward. If unable to "
+ " detect the cause, you may remove the staging or even domain "
+ " sub-directory for this MD and start all over.", md->name);
errored = 1;
break;
case MD_S_COMPLETE:
* @macro
* Version number of the md module as c string
*/
-#define MOD_MD_VERSION "1.0.3-git"
+#define MOD_MD_VERSION "1.0.4"
/**
* @macro
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
-#define MOD_MD_VERSION_NUM 0x010003
+#define MOD_MD_VERSION_NUM 0x010004
#define MD_EXPERIMENTAL 0
#define MD_ACME_DEF_URL "https://acme-v01.api.letsencrypt.org/directory"