Commit a4199018 authored by Stefan Eissing's avatar Stefan Eissing
Browse files

On the trunk:

mod_md: new module for managing domains across VirtualHosts



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1804530 13f79535-47bb-0310-9956-ffa450edef68
parents cbaa7919 37edb2d0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.0

  *) mod_md: new module for managing domains across VirtualHosts with ACME protocol 
     implementation for automated certificate signup and renewal. Default CA is
     the test area of Let's Encrypt right now, so certificates root will not be valid.
     Will be switched to the real service endpoint rather soon. If you need it now,
     configure 'MDCertificateAuthority https://acme-v01.api.letsencrypt.org/directory'.
     Module standard xml documentation coming soonish. [Stefan Eissing] 
     
  *) mod_ssl, ab: Fix compatibility with LibreSSL.  PR 61184.
     [Bernard Spil <brnrd freebsd.org>, Yann Ylavic]

modules/md/Makefile

0 → 100644
+65 −0
Original line number Diff line number Diff line
top_srcdir   = /Users/sei/projects/httpd/trunk
top_builddir = /Users/sei/projects/httpd/trunk
srcdir       = /Users/sei/projects/httpd/trunk/modules/md
builddir     = /Users/sei/projects/httpd/trunk/modules/md
VPATH        = /Users/sei/projects/httpd/trunk/modules/md
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

#
#   standard stuff
#


LTLIBRARY_NAME    = libmd.la
LTLIBRARY_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


LTLIBRARY_DEPENDENCIES = md.h


a2md_OBJECTS = \
	md_cmd_main.c \
	md_cmd_acme.c \
	md_cmd_reg.c \
	md_cmd_store.c

a2md: $(a2md_OBJECTS) $(LTLIBRARY_NAME)
	$(LINK) $(a2md_LTFLAGS) $(a2md_OBJECTS) -lmd $(A2MD_LDADD) $(AP_LIBS)

# top be installed in bin dir
bin_PROGRAMS = a2md

TARGETS = $(bin_PROGRAMS)

local-shared-build: $(LTLIBRARY_NAME) $(SHARED_TARGETS) a2md

include $(top_srcdir)/build/library.mk
include $(top_srcdir)/build/special.mk

modules/md/Makefile.in

0 → 100644
+60 −0
Original line number Diff line number Diff line
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

#
#   standard stuff
#


LTLIBRARY_NAME    = libmd.la
LTLIBRARY_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


LTLIBRARY_DEPENDENCIES = md.h


a2md_OBJECTS = \
	md_cmd_main.c \
	md_cmd_acme.c \
	md_cmd_reg.c \
	md_cmd_store.c

a2md: $(a2md_OBJECTS) $(LTLIBRARY_NAME)
	$(LINK) $(a2md_LTFLAGS) $(a2md_OBJECTS) -lmd $(A2MD_LDADD) $(AP_LIBS)

# top be installed in bin dir
bin_PROGRAMS = a2md

TARGETS = $(bin_PROGRAMS)

local-shared-build: $(LTLIBRARY_NAME) $(SHARED_TARGETS) a2md

include $(top_srcdir)/build/library.mk
include $(top_srcdir)/build/special.mk

modules/md/config2.m4

0 → 100644
+283 −0
Original line number Diff line number Diff line
dnl Licensed to the Apache Software Foundation (ASF) under one or more
dnl contributor license agreements.  See the NOTICE file distributed with
dnl this work for additional information regarding copyright ownership.
dnl The ASF licenses this file to You under the Apache License, Version 2.0
dnl (the "License"); you may not use this file except in compliance with
dnl the License.  You may obtain a copy of the License at
dnl
dnl      http://www.apache.org/licenses/LICENSE-2.0
dnl
dnl Unless required by applicable law or agreed to in writing, software
dnl distributed under the License is distributed on an "AS IS" BASIS,
dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dnl See the License for the specific language governing permissions and
dnl limitations under the License.

dnl
dnl APACHE_CHECK_CURL
dnl
dnl Configure for libcurl, giving preference to
dnl "--with-curl=<path>" if it was specified.
dnl
AC_DEFUN([APACHE_CHECK_CURL],[
  AC_CACHE_CHECK([for curl], [ac_cv_curl], [
    dnl initialise the variables we use
    ac_cv_curl=no
    ap_curl_found=""
    ap_curl_base=""
    ap_curl_libs=""

    dnl Determine the curl base directory, if any
    AC_MSG_CHECKING([for user-provided curl base directory])
    AC_ARG_WITH(curl, APACHE_HELP_STRING(--with-curl=PATH, curl installation directory), [
      dnl If --with-curl specifies a directory, we use that directory
      if test "x$withval" != "xyes" -a "x$withval" != "x"; then
        dnl This ensures $withval is actually a directory and that it is absolute
        ap_curl_base="`cd $withval ; pwd`"
      fi
    ])
    if test "x$ap_curl_base" = "x"; then
      AC_MSG_RESULT(none)
    else
      AC_MSG_RESULT($ap_curl_base)
    fi

    dnl Run header and version checks
    saved_CPPFLAGS="$CPPFLAGS"
    saved_LIBS="$LIBS"
    saved_LDFLAGS="$LDFLAGS"

    dnl Before doing anything else, load in pkg-config variables
    if test -n "$PKGCONFIG"; then
      saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
      AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
      if test "x$ap_curl_base" != "x" ; then
        if test -f "${ap_curl_base}/lib/pkgconfig/libcurl.pc"; then
          dnl Ensure that the given path is used by pkg-config too, otherwise
          dnl the system libcurl.pc might be picked up instead.
          PKG_CONFIG_PATH="${ap_curl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
          export PKG_CONFIG_PATH
        elif test -f "${ap_curl_base}/lib64/pkgconfig/libcurl.pc"; then
          dnl Ensure that the given path is used by pkg-config too, otherwise
          dnl the system libcurl.pc might be picked up instead.
          PKG_CONFIG_PATH="${ap_curl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
          export PKG_CONFIG_PATH
        fi
      fi
      AC_ARG_ENABLE(curl-staticlib-deps,APACHE_HELP_STRING(--enable-curl-staticlib-deps,[link mod_md with dependencies of libcurl's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-md.]), [
        if test "$enableval" = "yes"; then
          PKGCONFIG_LIBOPTS="--static"
        fi
      ])
      ap_curl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libcurl`"
      if test $? -eq 0; then
        ap_curl_found="yes"
        pkglookup="`$PKGCONFIG --cflags-only-I libcurl`"
        APR_ADDTO(CPPFLAGS, [$pkglookup])
        APR_ADDTO(MOD_CFLAGS, [$pkglookup])
        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libcurl`"
        APR_ADDTO(LDFLAGS, [$pkglookup])
        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libcurl`"
        APR_ADDTO(LDFLAGS, [$pkglookup])
        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
      fi
      PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
    fi

    dnl fall back to the user-supplied directory if not found via pkg-config
    if test "x$ap_curl_base" != "x" -a "x$ap_curl_found" = "x"; then
      APR_ADDTO(CPPFLAGS, [-I$ap_curl_base/include])
      APR_ADDTO(MOD_CFLAGS, [-I$ap_curl_base/include])
      APR_ADDTO(LDFLAGS, [-L$ap_curl_base/lib])
      APR_ADDTO(MOD_LDFLAGS, [-L$ap_curl_base/lib])
      if test "x$ap_platform_runtime_link_flag" != "x"; then
        APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_curl_base/lib])
        APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_curl_base/lib])
      fi
    fi

    AC_CHECK_HEADERS([curl/curl.h])

    AC_MSG_CHECKING([for curl version >= 7.50])
    AC_TRY_COMPILE([#include <curl/curlver.h>],[
#if !defined(LIBCURL_VERSION_MAJOR)
#error "Missing libcurl version"
#endif
#if LIBCURL_VERSION_MAJOR < 7
#error "Unsupported libcurl version " LIBCURL_VERSION
#endif
#if LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR < 50
#error "Unsupported libcurl version " LIBCURL_VERSION
#endif],
      [AC_MSG_RESULT(OK)
       ac_cv_curl=yes],
      [AC_MSG_RESULT(FAILED)])

    if test "x$ac_cv_curl" = "xyes"; then
      ap_curl_libs="${ap_curl_libs:--lcurl} `$apr_config --libs`"
      APR_ADDTO(MOD_LDFLAGS, [$ap_curl_libs])
      APR_ADDTO(LIBS, [$ap_curl_libs])
    fi

    dnl restore
    CPPFLAGS="$saved_CPPFLAGS"
    LIBS="$saved_LIBS"
    LDFLAGS="$saved_LDFLAGS"
  ])
  if test "x$ac_cv_curl" = "xyes"; then
    AC_DEFINE(HAVE_CURL, 1, [Define if curl is available])
  fi
])


dnl
dnl APACHE_CHECK_JANSSON
dnl
dnl Configure for libjansson, giving preference to
dnl "--with-jansson=<path>" if it was specified.
dnl
AC_DEFUN([APACHE_CHECK_JANSSON],[
  AC_CACHE_CHECK([for jansson], [ac_cv_jansson], [
    dnl initialise the variables we use
    ac_cv_jansson=no
    ap_jansson_found=""
    ap_jansson_base=""
    ap_jansson_libs=""

    dnl Determine the jansson base directory, if any
    AC_MSG_CHECKING([for user-provided jansson base directory])
    AC_ARG_WITH(jansson, APACHE_HELP_STRING(--with-jansson=PATH, jansson installation directory), [
      dnl If --with-jansson specifies a directory, we use that directory
      if test "x$withval" != "xyes" -a "x$withval" != "x"; then
        dnl This ensures $withval is actually a directory and that it is absolute
        ap_jansson_base="`cd $withval ; pwd`"
      fi
    ])
    if test "x$ap_jansson_base" = "x"; then
      AC_MSG_RESULT(none)
    else
      AC_MSG_RESULT($ap_jansson_base)
    fi

    dnl Run header and version checks
    saved_CPPFLAGS="$CPPFLAGS"
    saved_LIBS="$LIBS"
    saved_LDFLAGS="$LDFLAGS"

    dnl Before doing anything else, load in pkg-config variables
    if test -n "$PKGCONFIG"; then
      saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
      AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
      if test "x$ap_jansson_base" != "x" ; then
        if test -f "${ap_jansson_base}/lib/pkgconfig/libjansson.pc"; then
          dnl Ensure that the given path is used by pkg-config too, otherwise
          dnl the system libjansson.pc might be picked up instead.
          PKG_CONFIG_PATH="${ap_jansson_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
          export PKG_CONFIG_PATH
        elif test -f "${ap_jansson_base}/lib64/pkgconfig/libjansson.pc"; then
          dnl Ensure that the given path is used by pkg-config too, otherwise
          dnl the system libjansson.pc might be picked up instead.
          PKG_CONFIG_PATH="${ap_jansson_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
          export PKG_CONFIG_PATH
        fi
      fi
      AC_ARG_ENABLE(jansson-staticlib-deps,APACHE_HELP_STRING(--enable-jansson-staticlib-deps,[link mod_md with dependencies of libjansson's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-md.]), [
        if test "$enableval" = "yes"; then
          PKGCONFIG_LIBOPTS="--static"
        fi
      ])
      ap_jansson_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libjansson`"
      if test $? -eq 0; then
        ap_jansson_found="yes"
        pkglookup="`$PKGCONFIG --cflags-only-I libjansson`"
        APR_ADDTO(CPPFLAGS, [$pkglookup])
        APR_ADDTO(MOD_CFLAGS, [$pkglookup])
        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libjansson`"
        APR_ADDTO(LDFLAGS, [$pkglookup])
        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libjansson`"
        APR_ADDTO(LDFLAGS, [$pkglookup])
        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
      fi
      PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
    fi

    dnl fall back to the user-supplied directory if not found via pkg-config
    if test "x$ap_jansson_base" != "x" -a "x$ap_jansson_found" = "x"; then
      APR_ADDTO(CPPFLAGS, [-I$ap_jansson_base/include])
      APR_ADDTO(MOD_CFLAGS, [-I$ap_jansson_base/include])
      APR_ADDTO(LDFLAGS, [-L$ap_jansson_base/lib])
      APR_ADDTO(MOD_LDFLAGS, [-L$ap_jansson_base/lib])
      if test "x$ap_platform_runtime_link_flag" != "x"; then
        APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_jansson_base/lib])
        APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_jansson_base/lib])
      fi
    fi

    # attempts to include jansson.h fail me. So lets make sure we can at least
    # include its other header file
    AC_TRY_COMPILE([#include <jansson_config.h>],[],
      [AC_MSG_RESULT(OK) 
       ac_cv_jansson=yes], 
       [AC_MSG_RESULT(FAILED)])

    if test "x$ac_cv_jansson" = "xyes"; then
      ap_jansson_libs="${ap_jansson_libs:--ljansson} `$apr_config --libs`"
      APR_ADDTO(MOD_LDFLAGS, [$ap_jansson_libs])
      APR_ADDTO(LIBS, [$ap_jansson_libs])
    fi

    dnl restore
    CPPFLAGS="$saved_CPPFLAGS"
    LIBS="$saved_LIBS"
    LDFLAGS="$saved_LDFLAGS"
  ])
  if test "x$ac_cv_jansson" = "xyes"; then
    AC_DEFINE(HAVE_JANSSON, 1, [Define if jansson is available])
  fi
])


dnl #  start of module specific part
APACHE_MODPATH_INIT(md)

dnl #  list of module object files
md_objs="dnl
mod_md.lo dnl
mod_md_config.lo dnl
mod_md_os.lo dnl
"

dnl # hook module into the Autoconf mechanism (--enable-md)
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])
        enable_md=no
    fi
    
    APACHE_CHECK_JANSSON
    if test "x$ac_cv_jansson" != "xyes" ; then
        AC_MSG_WARN([libjansson not found])
        enable_md=no
    fi

    APACHE_CHECK_CURL
    if test "x$ac_cv_curl" != "xyes" ; then
        AC_MSG_WARN([libcurl not found])
        enable_md=no
    fi
    
    APR_ADDTO(MOD_MD_LDADD, [ "libmd.la" ])
    APR_ADDTO(A2MD_LDADD, [ "libmd.la" ])
])

# Ensure that other modules can pick up mod_md.h
APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])



dnl #  end of module specific part
APACHE_MODPATH_FINISH

modules/md/md.h

0 → 100644
+233 −0
Original line number Diff line number Diff line
/* 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 mod_md_md_h
#define mod_md_md_h

#include "md_version.h"

struct apr_array_header_t;
struct apr_hash_t;
struct md_json_t;
struct md_cert_t;
struct md_pkey_t;
struct md_store_t;

#define MD_TLSSNI01_DNS_SUFFIX     ".acme.invalid"

typedef enum {
    MD_S_UNKNOWN,                   /* MD has not been analysed yet */
    MD_S_INCOMPLETE,                /* MD is missing necessary information, cannot go live */
    MD_S_COMPLETE,                  /* MD has all necessary information, can go live */
    MD_S_EXPIRED,                   /* MD is complete, but credentials have expired */
    MD_S_ERROR,                     /* MD data is flawed, unable to be processed as is */ 
} md_state_t;

typedef enum {
    MD_SV_TEXT,
    MD_SV_JSON,
    MD_SV_CERT,
    MD_SV_PKEY,
    MD_SV_CHAIN,
} md_store_vtype_t;

typedef enum {
    MD_SG_NONE,
    MD_SG_ACCOUNTS,
    MD_SG_CHALLENGES,
    MD_SG_DOMAINS,
    MD_SG_STAGING,
    MD_SG_ARCHIVE,
    MD_SG_TMP,
    MD_SG_COUNT,
} md_store_group_t;

typedef enum {
    MD_DRIVE_DEFAULT = -1,          /* default value */
    MD_DRIVE_MANUAL,                /* manually triggered transmission of credentials */
    MD_DRIVE_AUTO,                  /* automatic process performed by httpd */
    MD_DRIVE_ALWAYS,                /* always driven by httpd, even if not used in any vhost */
} md_drive_mode_t;

typedef struct md_t md_t;
struct md_t {
    const char *name;               /* unique name of this MD */
    md_state_t state;               /* state of this MD */
    apr_time_t expires;             /* When the credentials for this domain expire. 0 if unknown */
    apr_interval_time_t renew_window;/* time before expiration that starts renewal */
    
    struct apr_array_header_t *domains; /* all DNS names this MD includes */
    int transitive;                 /* != 0 iff VirtualHost names/aliases are auto-added */
    md_drive_mode_t drive_mode;     /* mode of obtaining credentials */
    int must_staple;                /* certificates should set the OCSP Must Staple extension */
    
    const char *ca_url;             /* url of CA certificate service */
    const char *ca_proto;           /* protocol used vs CA (e.g. ACME) */
    const char *ca_account;         /* account used at CA */
    const char *ca_agreement;       /* accepted agreement uri between CA and user */ 
    struct apr_array_header_t *ca_challenges; /* challenge types configured for this MD */
    struct apr_array_header_t *contacts;   /* list of contact uris, e.g. mailto:xxx */

    const char *cert_url;           /* url where cert has been created, remember during drive */ 

    const char *defn_name;          /* config file this MD was defined */
    unsigned defn_line_number;      /* line number of definition */
};

#define MD_KEY_ACCOUNT          "account"
#define MD_KEY_AGREEMENT        "agreement"
#define MD_KEY_CA               "ca"
#define MD_KEY_CA_URL           "ca-url"
#define MD_KEY_CERT             "cert"
#define MD_KEY_CHALLENGES       "challenges"
#define MD_KEY_CONTACT          "contact"
#define MD_KEY_CONTACTS         "contacts"
#define MD_KEY_CSR              "csr"
#define MD_KEY_DISABLED         "disabled"
#define MD_KEY_DIR              "dir"
#define MD_KEY_DOMAIN           "domain"
#define MD_KEY_DOMAINS          "domains"
#define MD_KEY_DRIVE_MODE       "drive-mode"
#define MD_KEY_EXPIRES          "expires"
#define MD_KEY_HTTP             "http"
#define MD_KEY_HTTPS            "https"
#define MD_KEY_ID               "id"
#define MD_KEY_IDENTIFIER       "identifier"
#define MD_KEY_KEY              "key"
#define MD_KEY_KEYAUTHZ         "keyAuthorization"
#define MD_KEY_LOCATION         "location"
#define MD_KEY_NAME             "name"
#define MD_KEY_PROTO            "proto"
#define MD_KEY_REGISTRATION     "registration"
#define MD_KEY_RENEW_WINDOW     "renew-window"
#define MD_KEY_RESOURCE         "resource"
#define MD_KEY_STATE            "state"
#define MD_KEY_STATUS           "status"
#define MD_KEY_STORE            "store"
#define MD_KEY_TOKEN            "token"
#define MD_KEY_TRANSITIVE       "transitive"
#define MD_KEY_TYPE             "type"
#define MD_KEY_URL              "url"
#define MD_KEY_URI              "uri"
#define MD_KEY_VALUE            "value"
#define MD_KEY_VERSION          "version"

#define MD_FN_MD                "md.json"
#define MD_FN_PKEY              "pkey.pem"
#define MD_FN_CERT              "cert.pem"
#define MD_FN_CHAIN             "chain.pem"
#define MD_FN_HTTPD_JSON        "httpd.json"

/* Check if a string member of a new MD (n) has 
 * a value and if it differs from the old MD o
 */
#define MD_VAL_UPDATE(n,o,s)    ((n)->s != (o)->s)
#define MD_SVAL_UPDATE(n,o,s)   ((n)->s && (!(o)->s || strcmp((n)->s, (o)->s)))

#define MD_SECS_PER_HOUR      (60*60)
#define MD_SECS_PER_DAY       (24*MD_SECS_PER_HOUR)

/**
 * Determine if the Managed Domain contains a specific domain name.
 */
int md_contains(const md_t *md, const char *domain, int case_sensitive);

/**
 * Determine if the names of the two managed domains overlap.
 */
int md_domains_overlap(const md_t *md1, const md_t *md2);

/**
 * Determine if the domain names are equal.
 */
int md_equal_domains(const md_t *md1, const md_t *md2, int case_sensitive);

/**
 * Determine if the domains in md1 contain all domains of md2.
 */
int md_contains_domains(const md_t *md1, const md_t *md2);

/**
 * Get one common domain name of the two managed domains or NULL.
 */
const char *md_common_name(const md_t *md1, const md_t *md2);

/**
 * Get the number of common domains.
 */
apr_size_t md_common_name_count(const md_t *md1, const md_t *md2);

/**
 * Look up a managed domain by its name.
 */
md_t *md_get_by_name(struct apr_array_header_t *mds, const char *name);

/**
 * Look up a managed domain by a DNS name it contains.
 */
md_t *md_get_by_domain(struct apr_array_header_t *mds, const char *domain);

/**
 * Find a managed domain, different from the given one, that has overlaps
 * in the domain list.
 */
md_t *md_get_by_dns_overlap(struct apr_array_header_t *mds, const md_t *md);

/**
 * Find the managed domain in the list that, for the given md, 
 * has the same name, or the most number of overlaps in domains
 */
md_t *md_find_closest_match(apr_array_header_t *mds, const md_t *md);

/**
 * Create and empty md record, structures initialized.
 */
md_t *md_create_empty(apr_pool_t *p);

/**
 * Create a managed domain, given a list of domain names.
 */
const char *md_create(md_t **pmd, apr_pool_t *p, struct apr_array_header_t *domains);

/**
 * Deep copy an md record into another pool.
 */
md_t *md_clone(apr_pool_t *p, const md_t *src);

/**
 * Shallow copy an md record into another pool.
 */
md_t *md_copy(apr_pool_t *p, const md_t *src);

/** 
 * Convert the managed domain into a JSON representation and vice versa. 
 *
 * This reads and writes the following information: name, domains, ca_url, ca_proto and state.
 */
struct md_json_t *md_to_json (const md_t *md, apr_pool_t *p);
md_t *md_from_json(struct md_json_t *json, apr_pool_t *p);

/**************************************************************************************************/
/* domain credentials */

typedef struct md_creds_t md_creds_t;
struct md_creds_t {
    struct md_cert_t *cert;
    struct md_pkey_t *pkey;
    struct apr_array_header_t *chain;      /* list of md_cert* */
    int expired;
};

#endif /* mod_md_md_h */
Loading