Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • fornari/ngx_http_voms_module
  • cnafsd/ngx_http_voms_module
2 results
Show changes
Showing
with 0 additions and 2118 deletions
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:CRYPTO_malloc
fun:SSL_SESSION_new
fun:ssl_get_new_session
fun:ssl23_connect
fun:ngx_ssl_handshake
fun:ngx_http_upstream_ssl_init_connection
fun:ngx_http_upstream_send_request_handler
fun:ngx_http_upstream_handler
fun:ngx_epoll_process_events
fun:ngx_process_events_and_timers
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:ngx_alloc
fun:ngx_set_environment
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Free
fun:free
fun:__libc_freeres
fun:_vgnU_freeres
fun:__run_exit_handlers
fun:exit
fun:ngx_master_process_exit
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Param
epoll_ctl(event)
fun:epoll_ctl
fun:ngx_epoll_test_rdhup
fun:ngx_epoll_init
fun:ngx_event_process_init
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Param
epoll_ctl(event)
fun:epoll_ctl
fun:ngx_epoll_test_rdhup
fun:ngx_epoll_init
fun:ngx_event_process_init
fun:ngx_single_process_cycle
fun:main
}
# Copyright 2018-2022 Istituto Nazionale di Fisica Nucleare
# SPDX-License-Identifier: EUPL-1.2
FROM centos:7
# Allow customization of nginx user ID and name
ARG USERNAME=nginx
ARG USER_UID=1000
ARG USER_GID=${USER_UID}
# install dependencies
COPY library-scripts/*.sh /tmp/library-scripts/
RUN yum update -y && \
sh /tmp/library-scripts/provide-deps.sh && \
sh /tmp/library-scripts/provide-user.sh ${USERNAME} ${USER_UID} ${USER_GID} && \
yum clean all && rm -rf /var/cache/yum
# install nginx with patch for HTTPG
COPY sources/nginx-httpg_no_delegation.patch /tmp/sources/
COPY sources/nginx.spec /tmp/sources/
RUN sh /tmp/library-scripts/provide-nginx-with-httpg.sh
# copy and install nginx_http_voms module
COPY ngx-http-voms-module /ngx-http-voms-module
COPY t /home/nginx/t
RUN sh /tmp/library-scripts/provide-ngx-http-voms-module.sh
#!/usr/bin/env bash
# Copyright 2018-2022 Istituto Nazionale di Fisica Nucleare
# SPDX-License-Identifier: EUPL-1.2
set -ex
ngxVersion=1.22.1
# set environment to build rpm
rpmdev-setuptree
cat <<EOF > ${HOME}/.rpmmacros
%_topdir %{getenv:HOME}/rpmbuild
EOF
# download nginx sources
cd ~/rpmbuild/SOURCES/
wget http://nginx.org/packages/centos/7/SRPMS/nginx-$ngxVersion-1.el7.ngx.src.rpm
rpm2cpio nginx-$ngxVersion-1.el7.ngx.src.rpm | cpio -idm
# use nginx spec file with the httpg patch
cp /tmp/sources/nginx-httpg_no_delegation.patch ${HOME}/rpmbuild/SOURCES/
cp /tmp/sources/nginx.spec ~/rpmbuild/SPECS
# build and install rpm
rpmlint ~/rpmbuild/SPECS/nginx.spec
rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec
sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/nginx-$ngxVersion-1.el7.ngx.x86_64.rpm
nginx -v
#!/usr/bin/env bash
# Copyright 2018-2022 Istituto Nazionale di Fisica Nucleare
# SPDX-License-Identifier: EUPL-1.2
set -ex
ngxVersion=1.22.1
wget -O /nginx-$ngxVersion.tar.gz https://nginx.org/download/nginx-$ngxVersion.tar.gz
wget -O /ngx-http-echo-module.tar.gz https://github.com/openresty/echo-nginx-module/archive/refs/tags/v0.63.tar.gz
cd /
tar -xzf /nginx-$ngxVersion.tar.gz
tar xzf /ngx-http-echo-module.tar.gz
cd /nginx-$ngxVersion
./configure --prefix=/etc/nginx --with-compat --with-http_ssl_module --add-dynamic-module=/ngx-http-voms-module --add-dynamic-module=/echo-nginx-module-0.63
make modules
make install -j 8
\ No newline at end of file
ngx_addon_name=ngx_http_voms_module
ngx_module_type=HTTP
ngx_module_name=ngx_http_voms_module
ngx_module_srcs="$ngx_addon_dir/src/ngx_http_voms_module.cpp"
ngx_module_libs="-lvomsapi -lstdc++"
. auto/module
echo "objs/addon/src/ngx_http_voms_module.o: CFLAGS += --std=c++1y -Werror" >> $NGX_MAKEFILE
// Copyright 2018-2022 Istituto Nazionale di Fisica Nucleare
// SPDX-License-Identifier: EUPL-1.2
extern "C" {
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
}
#include <voms/voms_api.h>
#include <cassert>
#include <chrono>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <string>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/optional.hpp>
using BioPtr = std::unique_ptr<BIO, decltype(&BIO_free)>;
using X509Ptr = std::unique_ptr<X509, decltype(&X509_free)>;
using VomsAc = voms;
using MaybeVomsAc = boost::optional<VomsAc>;
enum class EeDn { SUBJECT, ISSUER };
static ngx_int_t add_variables(ngx_conf_t* cf);
static ngx_int_t ngx_ssl_allow_proxy_certs(ngx_ssl_t* ssl);
static char* ngx_http_voms_merge_srv_conf(ngx_conf_t* cf, void*, void*);
static ngx_http_module_t ctx = {
add_variables, // preconfiguration
NULL, // postconfiguration
NULL, // create main configuration
NULL, // init main configuration
NULL, // create server configuration
ngx_http_voms_merge_srv_conf, // merge server configuration
NULL, // create location configuration
NULL // merge location configuration
};
ngx_module_t ngx_http_voms_module = {
NGX_MODULE_V1,
&ctx, // module context
NULL, // module directives
NGX_HTTP_MODULE, // module type
NULL, // init master
NULL, // init module
NULL, // init process
NULL, // init thread
NULL, // exit thread
NULL, // exit process
NULL, // exit master
NGX_MODULE_V1_PADDING //
};
static ngx_int_t generic_getter( //
ngx_http_request_t* r,
ngx_http_variable_value_t* v,
uintptr_t data);
static ngx_int_t get_ssl_client_ee_dn( //
ngx_http_request_t* r,
ngx_http_variable_value_t* v,
uintptr_t data);
static ngx_int_t get_ssl_client_ee_cert( //
ngx_http_request_t* r,
ngx_http_variable_value_t* v,
uintptr_t data);
using getter_t = std::string(VomsAc const& voms);
static getter_t get_voms_user;
static getter_t get_voms_user_ca;
static getter_t get_voms_fqans;
static getter_t get_voms_server;
static getter_t get_voms_server_ca;
static getter_t get_voms_vo;
static getter_t get_voms_server_uri;
static getter_t get_voms_not_before;
static getter_t get_voms_not_after;
static getter_t get_voms_generic_attributes;
static getter_t get_voms_serial;
static ngx_http_variable_t variables[] = {
{
ngx_string("voms_user"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_user),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_user_ca"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_user_ca),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_fqans"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_fqans),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_server"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_server),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_server_ca"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_server_ca),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_vo"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_vo),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_server_uri"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_server_uri),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_not_before"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_not_before),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_not_after"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_not_after),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_generic_attributes"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_generic_attributes),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("voms_serial"),
NULL,
generic_getter,
reinterpret_cast<uintptr_t>(&get_voms_serial),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("ssl_client_ee_s_dn"),
NULL,
get_ssl_client_ee_dn,
static_cast<uintptr_t>(EeDn::SUBJECT),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("ssl_client_ee_i_dn"),
NULL,
get_ssl_client_ee_dn,
static_cast<uintptr_t>(EeDn::ISSUER),
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
{
ngx_string("ssl_client_ee_cert"),
NULL,
get_ssl_client_ee_cert,
0,
NGX_HTTP_VAR_NOCACHEABLE,
0 //
},
ngx_http_null_variable //
};
static ngx_int_t add_variables(ngx_conf_t* cf)
{
for (ngx_http_variable_t* v = variables; v->name.len; ++v) {
ngx_http_variable_t* var = ngx_http_add_variable(cf, &v->name, v->flags);
if (var == NULL) {
return NGX_ERROR;
}
var->get_handler = v->get_handler;
var->data = v->data;
}
return NGX_OK;
}
static ngx_int_t ngx_ssl_allow_proxy_certs(ngx_ssl_t* ssl)
{
X509_STORE* store = SSL_CTX_get_cert_store(ssl->ctx);
if (store == NULL) {
ngx_ssl_error(NGX_LOG_EMERG,
ssl->log,
0,
const_cast<char*>("SSL_CTX_get_cert_store() failed"));
return NGX_ERROR;
}
X509_STORE_set_flags(store, X509_V_FLAG_ALLOW_PROXY_CERTS);
return NGX_OK;
}
static char* ngx_http_voms_merge_srv_conf(ngx_conf_t* cf, void*, void*)
{
auto conf = static_cast<ngx_http_ssl_srv_conf_t*>(
ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module));
if (conf->ssl.ctx != nullptr) {
if (ngx_ssl_allow_proxy_certs(&conf->ssl) != NGX_OK) {
return static_cast<char*>(NGX_CONF_ERROR);
}
}
return NGX_CONF_OK;
}
// return the first AC, if present
static MaybeVomsAc retrieve_voms_ac_from_proxy(ngx_http_request_t* r)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
if (!r->main->http_connection->ssl) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "SSL not enabled");
return boost::none;
}
if (!r->connection->ssl) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "plain HTTP request");
return boost::none;
}
auto client_cert = X509Ptr{
SSL_get_peer_certificate(r->connection->ssl->connection), X509_free};
if (!client_cert) {
ngx_log_error(NGX_LOG_ERR,
r->connection->log,
0,
"no SSL peer certificate available");
return boost::none;
}
auto client_chain = SSL_get_peer_cert_chain(r->connection->ssl->connection);
if (!client_chain) {
ngx_log_error(
NGX_LOG_ERR, r->connection->log, 0, "SSL_get_peer_cert_chain() failed");
return boost::none;
}
vomsdata vd;
auto ok = vd.Retrieve(client_cert.get(), client_chain, RECURSE_CHAIN);
if (!ok) {
auto msg = vd.ErrorMessage();
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", msg.c_str());
return boost::none;
}
if (vd.data.empty()) {
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "no ACs in proxy");
return boost::none;
}
return vd.data.front();
}
// note that an entry in the cache is always created if within a connection a
// request is made to one of the voms_* variables. If the presented
// credential is a normal certificate or a proxy without attribute certificates,
// the unique_ptr points to a MaybeVomsAc that is empty (in the sense of an
// std::optional)
static std::map<ngx_connection_t*, std::unique_ptr<MaybeVomsAc>> ac_cache;
static void clean_voms_ac(void* data)
{
auto c = static_cast<ngx_connection_t*>(data);
ngx_log_error(NGX_LOG_DEBUG, c->log, 0, "%s", __func__);
auto n = ac_cache.erase(c);
// we erase from the cache exactly once per connection
assert(n == 1);
}
static void cache_voms_ac(ngx_http_request_t* r,
std::unique_ptr<MaybeVomsAc> acp)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
auto c = r->connection;
auto cln = ngx_pool_cleanup_add(c->pool, 0);
if (cln) {
auto r = ac_cache.insert(std::make_pair(c, std::move(acp)));
// we insert into the cache exactly once per connection
assert(r.second);
cln->handler = clean_voms_ac;
cln->data = c;
} else {
ngx_log_error(
NGX_LOG_ERR, r->connection->log, 0, "ngx_pool_cleanup_add() failed");
}
}
static MaybeVomsAc* get_voms_ac_from_cache(ngx_http_request_t* r)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
auto it = ac_cache.find(r->connection);
return it != ac_cache.end() ? it->second.get() : nullptr;
}
static MaybeVomsAc const& get_voms_ac(ngx_http_request_t* r)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
MaybeVomsAc* acp = get_voms_ac_from_cache(r);
if (!acp) {
std::unique_ptr<MaybeVomsAc> p{new MaybeVomsAc(retrieve_voms_ac_from_proxy(r))};
acp = p.get();
cache_voms_ac(r, std::move(p));
}
return *acp;
}
static ngx_int_t generic_getter(ngx_http_request_t* r,
ngx_http_variable_value_t* v,
uintptr_t data)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
v->not_found = 1;
v->valid = 0;
auto& ac = get_voms_ac(r);
if (!ac) {
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "get_voms_ac() failed");
return NGX_OK;
}
using getter_p = std::string (*)(VomsAc const& voms);
auto getter = reinterpret_cast<getter_p>(data);
std::string const value = getter(*ac);
auto buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, value.size()));
if (!buffer) {
return NGX_OK;
}
ngx_memcpy(buffer, value.c_str(), value.size());
v->data = buffer;
v->len = value.size();
v->valid = 1;
v->not_found = 0;
v->no_cacheable = 0;
return NGX_OK;
}
std::string get_voms_user(VomsAc const& ac)
{
return ac.user;
}
std::string get_voms_user_ca(VomsAc const& ac)
{
return ac.userca;
}
std::string get_voms_fqans(VomsAc const& ac)
{
return boost::algorithm::join(ac.fqan, ",");
}
std::string get_voms_server(VomsAc const& ac)
{
return ac.server;
}
std::string get_voms_server_ca(VomsAc const& ac)
{
return ac.serverca;
}
std::string get_voms_vo(VomsAc const& ac)
{
return ac.voname;
}
std::string get_voms_server_uri(VomsAc const& ac)
{
return ac.uri;
}
std::string get_voms_not_before(VomsAc const& ac)
{
return ac.date1;
}
std::string get_voms_not_after(VomsAc const& ac)
{
return ac.date2;
}
static std::string escape_uri(std::string const& src)
{
std::string result = src;
// the following just counts the number of characters that need escaping
auto const n_escape =
ngx_escape_uri(nullptr, // <--
reinterpret_cast<u_char*>(const_cast<char*>(src.data())),
src.size(),
NGX_ESCAPE_URI_COMPONENT);
if (n_escape > 0) {
result.resize(src.size() + 2 * n_escape);
ngx_escape_uri(reinterpret_cast<u_char*>(const_cast<char*>(result.data())),
reinterpret_cast<u_char*>(const_cast<char*>(src.data())),
src.size(),
NGX_ESCAPE_URI_COMPONENT);
}
return result;
}
static std::string encode(attribute const& a)
{
return "n=" + a.name + " v=" + escape_uri(a.value) + " q=" + a.qualifier;
}
std::string get_voms_generic_attributes(VomsAc const& ac)
{
std::string result;
// the GetAttributes method is not declared const
auto const attributes = const_cast<VomsAc&>(ac).GetAttributes();
if (!attributes.empty()) {
auto& gas = attributes.front().attributes;
bool first = true;
for (auto& a : gas) {
if (first) {
first = false;
} else {
result += ',';
}
result += encode(a);
}
}
return result;
}
std::string get_voms_serial(VomsAc const& ac)
{
return ac.serial;
}
static std::string to_rfc2253(X509_NAME* name)
{
std::string result;
BioPtr bio(BIO_new(BIO_s_mem()), &BIO_free);
if (!bio) {
return result;
}
if (X509_NAME_print_ex(bio.get(), name, 0, XN_FLAG_RFC2253) < 0) {
return result;
}
auto len = BIO_pending(bio.get());
result.resize(len);
BIO_read(bio.get(), &result[0], result.size());
return result;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static uint32_t X509_get_extension_flags(X509* x)
{
return x->ex_flags;
}
#endif
static bool is_ca(X509* cert)
{
return X509_check_ca(cert) != 0;
}
static bool is_proxy(X509* cert)
{
return X509_get_extension_flags(cert) & EXFLAG_PROXY;
}
static X509* get_ee_cert(ngx_http_request_t* r)
{
auto chain = SSL_get_peer_cert_chain(r->connection->ssl->connection);
if (!chain) {
ngx_log_error(
NGX_LOG_ERR, r->connection->log, 0, "SSL_get_peer_cert_chain() failed");
return nullptr;
}
X509* ee_cert = nullptr;
if (sk_X509_num(chain) == 0) {
ee_cert = SSL_get_peer_certificate(r->connection->ssl->connection);
} else {
// find first non-proxy and non-ca cert
for (int i = 0; i != sk_X509_num(chain); ++i) {
auto cert = sk_X509_value(chain, i);
if (cert && is_ca(cert)) {
break;
}
if (cert && !is_proxy(cert)) {
ee_cert = cert;
break;
}
}
if (!ee_cert) {
ee_cert = SSL_get_peer_certificate(r->connection->ssl->connection);
}
}
return ee_cert;
}
static ngx_int_t get_ssl_client_ee_dn(ngx_http_request_t* r,
ngx_http_variable_value_t* v,
uintptr_t data)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
v->not_found = 1;
v->valid = 0;
auto ee_cert = get_ee_cert(r);
if (!ee_cert) {
ngx_log_error(NGX_LOG_DEBUG,
r->connection->log,
0,
"cannot identify end-entity certificate");
return NGX_OK;
}
X509_NAME* dn;
switch (static_cast<EeDn>(data)) {
case EeDn::SUBJECT:
dn = X509_get_subject_name(ee_cert);
break;
case EeDn::ISSUER:
dn = X509_get_issuer_name(ee_cert);
break;
default:
dn = nullptr;
}
if (!dn) {
ngx_log_error(
NGX_LOG_DEBUG, r->connection->log, 0, "cannot get DN from certificate");
return NGX_OK;
}
std::string value = to_rfc2253(dn);
auto buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, value.size()));
if (!buffer) {
return NGX_OK;
}
ngx_memcpy(buffer, value.c_str(), value.size());
v->data = buffer;
v->len = value.size();
v->valid = 1;
v->not_found = 0;
v->no_cacheable = 0;
return NGX_OK;
}
static ngx_int_t get_ssl_client_ee_cert_raw(ngx_http_request_t* r,
ngx_str_t* result)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
*result = {0, nullptr};
auto ee_cert = get_ee_cert(r);
if (!ee_cert) {
ngx_log_error(NGX_LOG_DEBUG,
r->connection->log,
0,
"cannot identify end-entity certificate");
return NGX_OK;
}
BioPtr bio(BIO_new(BIO_s_mem()), &BIO_free);
if (!bio) {
ngx_log_error(
NGX_LOG_ERR, r->connection->log, 0, "cannot create OpenSSL BIO");
return NGX_ERROR;
}
if (PEM_write_bio_X509(bio.get(), ee_cert) == 0) {
ngx_log_error(
NGX_LOG_ERR, r->connection->log, 0, "cannot write EEC to OpenSSL BIO");
return NGX_ERROR;
}
result->len = BIO_pending(bio.get());
result->data = static_cast<u_char*>(ngx_pnalloc(r->pool, result->len));
if (result->data == nullptr) {
return NGX_ERROR;
}
BIO_read(bio.get(), result->data, result->len);
return NGX_OK;
}
namespace boost {
template <typename IteratorT, typename IntegerT>
inline iterator_range<IteratorT> make_iterator_range_n(IteratorT first,
IntegerT n)
{
return iterator_range<IteratorT>(first, boost::next(first, n));
}
} // namespace boost
static ngx_int_t get_ssl_client_ee_cert(ngx_http_request_t* r,
ngx_http_variable_value_t* v,
uintptr_t data)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
v->not_found = 1;
v->valid = 0;
ngx_str_t cert{0, nullptr};
if (get_ssl_client_ee_cert_raw(r, &cert) != NGX_OK) {
return NGX_ERROR;
}
if (cert.len == 0) {
v->len = 0;
return NGX_OK;
}
// the first line is not prepended with a tab
auto const n_tabs = std::count(cert.data, cert.data + cert.len, '\n') - 1;
// cert is null-terminated
auto const len = cert.len - 1 + n_tabs;
auto const buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, len));
if (!buffer) {
return NGX_OK;
}
// the last newline is not to be followed by a tab
boost::algorithm::replace_all_copy(
buffer, boost::make_iterator_range_n(cert.data, len - 1), "\n", "\n\t");
v->data = buffer;
v->len = len;
v->valid = 1;
v->not_found = 0;
v->no_cacheable = 0;
return NGX_OK;
}
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index d9a1dbed..7438816e 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -149,7 +149,13 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
- if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') {
+ if (ch == '0') {
+ // httpg with no delegation
+ // eat the character and continue with the rest of the request
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "httpg request w/o delegation");
+ r->request_start++;
+ // httpg with a delegation request would fail for an unknown method
+ } else if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
#
%define nginx_home %{_localstatedir}/cache/nginx
%define nginx_user nginx
%define nginx_group nginx
%define nginx_loggroup adm
BuildRequires: systemd
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
%if 0%{?rhel}
%define _group System Environment/Daemons
%endif
%if (0%{?rhel} == 7) && (0%{?amzn} == 0)
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
Requires: openssl >= 1.0.2
BuildRequires: openssl-devel >= 1.0.2
%define dist .el7
%endif
%if (0%{?rhel} == 7) && (0%{?amzn} == 2)
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
Requires: openssl11 >= 1.1.1
BuildRequires: openssl11-devel >= 1.1.1
%endif
%if 0%{?rhel} == 8
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
BuildRequires: openssl-devel >= 1.1.1
%define _debugsource_template %{nil}
%endif
%if 0%{?rhel} == 9
%define epoch 1
Epoch: %{epoch}
Requires(pre): shadow-utils
BuildRequires: openssl-devel
%define _debugsource_template %{nil}
%endif
%if 0%{?suse_version} >= 1315
%define _group Productivity/Networking/Web/Servers
%define nginx_loggroup trusted
Requires(pre): shadow
BuildRequires: libopenssl-devel
%define _debugsource_template %{nil}
%endif
%if 0%{?fedora}
%define _debugsource_template %{nil}
%global _hardened_build 1
%define _group System Environment/Daemons
BuildRequires: openssl-devel
Requires(pre): shadow-utils
%endif
# end of distribution specific definitions
%define base_version 1.22.1
%define base_release 1%{?dist}.ngx
%define bdir %{_builddir}/%{name}-%{base_version}
%define WITH_CC_OPT $(echo %{optflags} $(pcre2-config --cflags)) -fPIC
%define WITH_LD_OPT -Wl,-z,relro -Wl,-z,now -pie
%define BASE_CONFIGURE_ARGS $(echo "--prefix=%{_sysconfdir}/nginx --sbin-path=%{_sbindir}/nginx --modules-path=%{_libdir}/nginx/modules --conf-path=%{_sysconfdir}/nginx/nginx.conf --error-log-path=%{_localstatedir}/log/nginx/error.log --http-log-path=%{_localstatedir}/log/nginx/access.log --pid-path=%{_localstatedir}/run/nginx.pid --lock-path=%{_localstatedir}/run/nginx.lock --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp --user=%{nginx_user} --group=%{nginx_group} --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module")
Summary: High performance web server
Name: nginx
Version: %{base_version}
Release: %{base_release}
Vendor: NGINX Packaging <nginx-packaging@f5.com>
URL: https://nginx.org/
Group: %{_group}
Source0: https://nginx.org/download/%{name}-%{version}.tar.gz
Source1: logrotate
Source2: nginx.conf
Source3: nginx.default.conf
Source4: nginx.service
Source5: nginx.upgrade.sh
Source6: nginx.suse.logrotate
Source7: nginx-debug.service
Source8: nginx.copyright
Source9: nginx.check-reload.sh
Patch0: nginx-httpg_no_delegation.patch
License: 2-clause BSD-like license
BuildRoot: %{_tmppath}/%{name}-%{base_version}-%{base_release}-root
BuildRequires: zlib-devel
BuildRequires: pcre2-devel
Provides: webserver
Provides: nginx-r%{base_version}
%description
nginx [engine x] is an HTTP and reverse proxy server, as well as
a mail proxy server.
%if 0%{?suse_version} >= 1315
%debug_package
%endif
%prep
%autosetup -p1
%patch0 -p1
%build
./configure %{BASE_CONFIGURE_ARGS} \
--with-cc-opt="%{WITH_CC_OPT}" \
--with-ld-opt="%{WITH_LD_OPT}" \
--with-debug
make %{?_smp_mflags}
%{__mv} %{bdir}/objs/nginx \
%{bdir}/objs/nginx-debug
./configure %{BASE_CONFIGURE_ARGS} \
--with-cc-opt="%{WITH_CC_OPT}" \
--with-ld-opt="%{WITH_LD_OPT}"
make %{?_smp_mflags}
%install
%{__rm} -rf $RPM_BUILD_ROOT
%{__make} DESTDIR=$RPM_BUILD_ROOT INSTALLDIRS=vendor install
%{__mkdir} -p $RPM_BUILD_ROOT%{_datadir}/nginx
%{__mv} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/html $RPM_BUILD_ROOT%{_datadir}/nginx/
%{__rm} -f $RPM_BUILD_ROOT%{_sysconfdir}/nginx/*.default
%{__rm} -f $RPM_BUILD_ROOT%{_sysconfdir}/nginx/fastcgi.conf
%{__mkdir} -p $RPM_BUILD_ROOT%{_localstatedir}/log/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_localstatedir}/run/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_localstatedir}/cache/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_libdir}/nginx/modules
cd $RPM_BUILD_ROOT%{_sysconfdir}/nginx && \
%{__ln_s} ../..%{_libdir}/nginx/modules modules && cd -
%{__mkdir} -p $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{base_version}
%{__install} -m 644 -p %{SOURCE8} \
$RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{base_version}/COPYRIGHT
%{__mkdir} -p $RPM_BUILD_ROOT%{_sysconfdir}/nginx/conf.d
%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/nginx.conf
%{__install} -m 644 -p %{SOURCE2} \
$RPM_BUILD_ROOT%{_sysconfdir}/nginx/nginx.conf
%{__install} -m 644 -p %{SOURCE3} \
$RPM_BUILD_ROOT%{_sysconfdir}/nginx/conf.d/default.conf
%{__install} -p -D -m 0644 %{bdir}/objs/nginx.8 \
$RPM_BUILD_ROOT%{_mandir}/man8/nginx.8
%{__mkdir} -p $RPM_BUILD_ROOT%{_unitdir}
%{__install} -m644 %SOURCE4 \
$RPM_BUILD_ROOT%{_unitdir}/nginx.service
%{__install} -m644 %SOURCE7 \
$RPM_BUILD_ROOT%{_unitdir}/nginx-debug.service
%{__mkdir} -p $RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/nginx
%{__install} -m755 %SOURCE5 \
$RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/nginx/upgrade
%{__install} -m755 %SOURCE9 \
$RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/nginx/check-reload
# install log rotation stuff
%{__mkdir} -p $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d
%if 0%{?suse_version}
%{__install} -m 644 -p %{SOURCE6} \
$RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/nginx
%else
%{__install} -m 644 -p %{SOURCE1} \
$RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/nginx
%endif
%{__install} -m755 %{bdir}/objs/nginx-debug \
$RPM_BUILD_ROOT%{_sbindir}/nginx-debug
%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/koi-utf
%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/koi-win
%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/win-utf
%check
%{__rm} -rf $RPM_BUILD_ROOT/usr/src
cd %{bdir}
grep -v 'usr/src' debugfiles.list > debugfiles.list.new && mv debugfiles.list.new debugfiles.list
cat /dev/null > debugsources.list
%if 0%{?suse_version} >= 1500
cat /dev/null > debugsourcefiles.list
%endif
%clean
%{__rm} -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{_sbindir}/nginx
%{_sbindir}/nginx-debug
%dir %{_sysconfdir}/nginx
%dir %{_sysconfdir}/nginx/conf.d
%{_sysconfdir}/nginx/modules
%config(noreplace) %{_sysconfdir}/nginx/nginx.conf
%config(noreplace) %{_sysconfdir}/nginx/conf.d/default.conf
%config(noreplace) %{_sysconfdir}/nginx/mime.types
%config(noreplace) %{_sysconfdir}/nginx/fastcgi_params
%config(noreplace) %{_sysconfdir}/nginx/scgi_params
%config(noreplace) %{_sysconfdir}/nginx/uwsgi_params
%config(noreplace) %{_sysconfdir}/logrotate.d/nginx
%{_unitdir}/nginx.service
%{_unitdir}/nginx-debug.service
%dir %{_libexecdir}/initscripts/legacy-actions/nginx
%{_libexecdir}/initscripts/legacy-actions/nginx/*
%attr(0755,root,root) %dir %{_libdir}/nginx
%attr(0755,root,root) %dir %{_libdir}/nginx/modules
%dir %{_datadir}/nginx
%dir %{_datadir}/nginx/html
%{_datadir}/nginx/html/*
%attr(0755,root,root) %dir %{_localstatedir}/cache/nginx
%attr(0755,root,root) %dir %{_localstatedir}/log/nginx
%dir %{_datadir}/doc/%{name}-%{base_version}
%doc %{_datadir}/doc/%{name}-%{base_version}/COPYRIGHT
%{_mandir}/man8/nginx.8*
%pre
# Add the "nginx" user
getent group %{nginx_group} >/dev/null || groupadd -r %{nginx_group}
getent passwd %{nginx_user} >/dev/null || \
useradd -r -g %{nginx_group} -s /sbin/nologin \
-d %{nginx_home} -c "nginx user" %{nginx_user}
exit 0
%post
# Register the nginx service
if [ $1 -eq 1 ]; then
/usr/bin/systemctl preset nginx.service >/dev/null 2>&1 ||:
/usr/bin/systemctl preset nginx-debug.service >/dev/null 2>&1 ||:
# print site info
cat <<BANNER
----------------------------------------------------------------------
Thanks for using nginx!
Please find the official documentation for nginx here:
* https://nginx.org/en/docs/
Please subscribe to nginx-announce mailing list to get
the most important news about nginx:
* https://nginx.org/en/support.html
Commercial subscriptions for nginx are available on:
* https://nginx.com/products/
----------------------------------------------------------------------
BANNER
# Touch and set permisions on default log files on installation
if [ -d %{_localstatedir}/log/nginx ]; then
if [ ! -e %{_localstatedir}/log/nginx/access.log ]; then
touch %{_localstatedir}/log/nginx/access.log
%{__chmod} 640 %{_localstatedir}/log/nginx/access.log
%{__chown} nginx:%{nginx_loggroup} %{_localstatedir}/log/nginx/access.log
fi
if [ ! -e %{_localstatedir}/log/nginx/error.log ]; then
touch %{_localstatedir}/log/nginx/error.log
%{__chmod} 640 %{_localstatedir}/log/nginx/error.log
%{__chown} nginx:%{nginx_loggroup} %{_localstatedir}/log/nginx/error.log
fi
fi
fi
%preun
if [ $1 -eq 0 ]; then
/usr/bin/systemctl --no-reload disable nginx.service >/dev/null 2>&1 ||:
/usr/bin/systemctl stop nginx.service >/dev/null 2>&1 ||:
fi
%postun
/usr/bin/systemctl daemon-reload >/dev/null 2>&1 ||:
if [ $1 -ge 1 ]; then
/sbin/service nginx status >/dev/null 2>&1 || exit 0
/sbin/service nginx upgrade >/dev/null 2>&1 || echo \
"Binary upgrade failed, please check nginx's error.log"
fi
%changelog
* Wed Oct 19 2022 Nginx Packaging <nginx-packaging@f5.com> - 1.22.1-1%{?dist}.ngx
- 1.22.1-1
* Tue May 24 2022 Konstantin Pavlov <thresh@nginx.com> - 1.22.0-1%{?dist}.ngx
- 1.22.0-1
* Tue Jan 25 2022 Mikhail Isachenkov <mikhail.isachenkov@nginx.com> - 1.21.6-1%{?dist}.ngx
- 1.21.6-1
* Tue Dec 28 2021 Konstantin Pavlov <thresh@nginx.com> - 1.21.5-1%{?dist}.ngx
- 1.21.5-1
- built with PCRE2
* Tue Nov 2 2021 Konstantin Pavlov <thresh@nginx.com> - 1.21.4-1%{?dist}.ngx
- 1.21.4-1
* Tue Sep 7 2021 Konstantin Pavlov <thresh@nginx.com> - 1.21.3-1%{?dist}.ngx
- 1.21.3-1
* Tue Aug 31 2021 Andrei Belov <defan@nginx.com> - 1.21.2-1%{?dist}.ngx
- 1.21.2-1
* Tue Jul 6 2021 Konstantin Pavlov <thresh@nginx.com> - 1.21.1-1%{?dist}.ngx
- 1.21.1-1
* Tue May 25 2021 Konstantin Pavlov <thresh@nginx.com> - 1.21.0-1%{?dist}.ngx
- 1.21.0-1
* Tue Apr 13 2021 Andrei Belov <defan@nginx.com> - 1.19.10-1%{?dist}.ngx
- 1.19.10-1
* Tue Mar 30 2021 Konstantin Pavlov <thresh@nginx.com> - 1.19.9-1%{?dist}.ngx
- 1.19.9-1
* Tue Mar 9 2021 Konstantin Pavlov <thresh@nginx.com> - 1.19.8-1%{?dist}.ngx
- 1.19.8-1
* Tue Feb 16 2021 Konstantin Pavlov <thresh@nginx.com> - 1.19.7-1%{?dist}.ngx
- 1.19.7-1
* Tue Dec 15 2020 Konstantin Pavlov <thresh@nginx.com> - 1.19.6-1%{?dist}.ngx
- 1.19.6-1
* Tue Nov 24 2020 Konstantin Pavlov <thresh@nginx.com> - 1.19.5-1%{?dist}.ngx
- 1.19.5-1
* Tue Oct 27 2020 Andrei Belov <defan@nginx.com> - 1.19.4-1%{?dist}.ngx
- 1.19.4-1
* Tue Sep 29 2020 Konstantin Pavlov <thresh@nginx.com> - 1.19.3-1%{?dist}.ngx
- 1.19.3
* Tue Aug 11 2020 Konstantin Pavlov <thresh@nginx.com> - 1.19.2-1%{?dist}.ngx
- 1.19.2
* Tue Jul 7 2020 Konstantin Pavlov <thresh@nginx.com> - 1.19.1-1%{?dist}.ngx
- 1.19.1
* Tue May 26 2020 Konstantin Pavlov <thresh@nginx.com> - 1.19.0-1%{?dist}.ngx
- 1.19.0
* Tue Apr 14 2020 Konstantin Pavlov <thresh@nginx.com> - 1.17.10-1%{?dist}.ngx
- 1.17.10
* Tue Mar 3 2020 Konstantin Pavlov <thresh@nginx.com> - 1.17.9-1%{?dist}.ngx
- 1.17.9
* Tue Jan 21 2020 Konstantin Pavlov <thresh@nginx.com> - 1.17.8-1%{?dist}.ngx
- 1.17.8
* Tue Dec 24 2019 Konstantin Pavlov <thresh@nginx.com> - 1.17.7-1%{?dist}.ngx
- 1.17.7
* Tue Nov 19 2019 Konstantin Pavlov <thresh@nginx.com> - 1.17.6-1%{?dist}.ngx
- 1.17.6
* Tue Oct 22 2019 Andrei Belov <defan@nginx.com> - 1.17.5-1%{?dist}.ngx
- 1.17.5
* Tue Sep 24 2019 Konstantin Pavlov <thresh@nginx.com> - 1.17.4-1%{?dist}.ngx
- 1.17.4
* Tue Aug 13 2019 Andrei Belov <defan@nginx.com> - 1.17.3-1%{?dist}.ngx
- 1.17.3
* Tue Jul 23 2019 Konstantin Pavlov <thresh@nginx.com> - 1.17.2-1%{?dist}.ngx
- 1.17.2
* Tue Jun 25 2019 Andrei Belov <defan@nginx.com> - 1.17.1-1%{?dist}.ngx
- 1.17.1
* Tue May 21 2019 Konstantin Pavlov <thresh@nginx.com> - 1.17.0-1%{?dist}.ngx
- 1.17.0
* Tue Apr 16 2019 Konstantin Pavlov <thresh@nginx.com> - 1.15.12-1%{?dist}.ngx
- 1.15.12
* Tue Apr 9 2019 Konstantin Pavlov <thresh@nginx.com> - 1.15.11-1%{?dist}.ngx
- 1.15.11
* Tue Mar 26 2019 Konstantin Pavlov <thresh@nginx.com> - 1.15.10-1%{?dist}.ngx
- 1.15.10
* Tue Feb 26 2019 Konstantin Pavlov <thresh@nginx.com> - 1.15.9-1%{?dist}.ngx
- 1.15.9
* Tue Dec 25 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.8-1%{?dist}.ngx
- 1.15.8
* Tue Nov 27 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.7-1%{?dist}.ngx
- 1.15.7
* Tue Nov 6 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.6-1%{?dist}.ngx
- 1.15.6
- Security: fixes CVE-2018-16843.
- Security: fixes CVE-2018-16844.
- Security: fixes CVE-2018-16845.
* Tue Oct 2 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.5-1%{?dist}.ngx
- 1.15.5
* Tue Sep 25 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.4-1%{?dist}.ngx
- 1.15.4
* Tue Aug 28 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.3-1%{?dist}.ngx
- 1.15.3
* Tue Jul 24 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.2-1%{?dist}.ngx
- 1.15.2
* Tue Jul 3 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.1-1%{?dist}.ngx
- 1.15.1
* Tue Jun 5 2018 Konstantin Pavlov <thresh@nginx.com> - 1.15.0-1%{?dist}.ngx
- 1.15.0
* Mon Apr 9 2018 Konstantin Pavlov <thresh@nginx.com> - 1.13.12-1%{?dist}.ngx
- 1.13.12
* Tue Apr 3 2018 Konstantin Pavlov <thresh@nginx.com> - 1.13.11-1%{?dist}.ngx
- 1.13.11
* Tue Mar 20 2018 Konstantin Pavlov <thresh@nginx.com> - 1.13.10-1%{?dist}.ngx
- 1.13.10
* Tue Feb 20 2018 Konstantin Pavlov <thresh@nginx.com> - 1.13.9-1%{?dist}.ngx
- 1.13.9
* Tue Dec 26 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.8-1%{?dist}.ngx
- 1.13.8
* Tue Nov 21 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.7-1%{?dist}.ngx
- 1.13.7
* Thu Sep 14 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.6-1%{?dist}.ngx
- 1.13.6
- Bugfix: in systemd service support
(https://trac.nginx.org/nginx/ticket/1380).
* Thu Sep 14 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.5-1%{?dist}.ngx
- 1.13.5
* Tue Aug 8 2017 Sergey Budnevitch <sb@nginx.com> - 1.13.4-1%{?dist}.ngx
- 1.13.4
* Tue Jul 11 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.3-1%{?dist}.ngx
- 1.13.3
- Security: fixes CVE-2017-7529.
* Tue Jun 27 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.2-1%{?dist}.ngx
- 1.13.2
* Tue May 30 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.1-1%{?dist}.ngx
- 1.13.1
* Tue Apr 25 2017 Konstantin Pavlov <thresh@nginx.com> - 1.13.0-1%{?dist}.ngx
- 1.13.0
* Tue Apr 4 2017 Konstantin Pavlov <thresh@nginx.com> - 1.11.13-1%{?dist}.ngx
- 1.11.13
- Made upgrade loops/timeouts configurable via /etc/defaults/nginx.
* Fri Mar 24 2017 Konstantin Pavlov <thresh@nginx.com> - 1.11.12-1%{?dist}.ngx
- 1.11.12
* Tue Mar 21 2017 Konstantin Pavlov <thresh@nginx.com> - 1.11.11-1%{?dist}.ngx
- 1.11.11
* Tue Feb 14 2017 Konstantin Pavlov <thresh@nginx.com> - 1.11.10-1%{?dist}.ngx
- 1.11.10
* Tue Jan 24 2017 Konstantin Pavlov <thresh@nginx.com> - 1.11.9-1%{?dist}.ngx
- 1.11.9
- Extended hardening build flags.
- Added check-reload target to init script / systemd service.
* Tue Dec 27 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.8-1%{?dist}.ngx
- 1.11.8
* Tue Dec 13 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.7-1%{?dist}.ngx
- 1.11.7
* Fri Nov 25 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.6-1%{?dist}.ngx
- 1.11.6
* Mon Oct 10 2016 Andrei Belov <defan@nginx.com> - 1.11.5-1%{?dist}.ngx
- 1.11.5
* Tue Sep 13 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.4-1%{?dist}.ngx
- 1.11.4
- njs updated to 0.1.2.
* Tue Jul 26 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.3-1%{?dist}.ngx
- 1.11.3
- njs updated to 0.1.0.
- njs stream dynamic module added to nginx-module-njs package.
- geoip stream dynamic module added to nginx-module-geoip package.
* Tue Jul 5 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.2-1%{?dist}.ngx
- 1.11.2
- njs updated to ef2b708510b1.
* Tue May 31 2016 Konstantin Pavlov <thresh@nginx.com> - 1.11.1-1%{?dist}.ngx
- 1.11.1
* Tue May 24 2016 Sergey Budnevitch <sb@nginx.com> - 1.11.0-1%{?dist}.ngx
- 1.11.0
- Bugfix: fixed logrotate error if nginx is not running.
* Tue Apr 19 2016 Konstantin Pavlov <thresh@nginx.com> - 1.9.15-1%{?dist}.ngx
- 1.9.15
- njs updated to 1c50334fbea6.
* Tue Apr 5 2016 Konstantin Pavlov <thresh@nginx.com> - 1.9.14-1%{?dist}.ngx
- 1.9.14
* Tue Mar 29 2016 Konstantin Pavlov <thresh@nginx.com> - 1.9.13-1%{?dist}.ngx
- 1.9.13
- Fixed modules path
- Added perl and njs dynamic modules subpackages
* Wed Feb 24 2016 Sergey Budnevitch <sb@nginx.com> - 1.9.12-1%{?dist}.ngx
- 1.9.12
- common configure args are now in variable
- xslt, image-filter and geoip dynamic modules added
* Tue Feb 9 2016 Sergey Budnevitch <sb@nginx.com> - 1.9.11-1%{?dist}.ngx
- 1.9.11
- dynamic modules path and symlink in /etc/nginx added
* Tue Jan 26 2016 Konstantin Pavlov <thresh@nginx.com> - 1.9.10-1%{?dist}.ngx
- 1.9.10
* Wed Dec 9 2015 Konstantin Pavlov <thresh@nginx.com> - 1.9.9-1%{?dist}.ngx
- 1.9.9
* Tue Dec 8 2015 Konstantin Pavlov <thresh@nginx.com> - 1.9.8-1%{?dist}.ngx
- 1.9.8
- http_slice module enabled
* Tue Nov 17 2015 Konstantin Pavlov <thresh@nginx.com> - 1.9.7-1%{?dist}.ngx
- 1.9.7
* Tue Oct 27 2015 Sergey Budnevitch <sb@nginx.com> - 1.9.6-1%{?dist}.ngx
- 1.9.6
* Tue Sep 22 2015 Andrei Belov <defan@nginx.com> - 1.9.5-1%{?dist}.ngx
- 1.9.5
- http_spdy module replaced with http_v2 module
* Tue Aug 18 2015 Konstantin Pavlov <thresh@nginx.com> - 1.9.4-1%{?dist}.ngx
- 1.9.4
* Tue Jul 14 2015 Sergey Budnevitch <sb@nginx.com> - 1.9.3-1%{?dist}.ngx
- 1.9.3
* Tue Jun 16 2015 Sergey Budnevitch <sb@nginx.com> - 1.9.2-1%{?dist}.ngx
- 1.9.2
* Tue May 26 2015 Sergey Budnevitch <sb@nginx.com> - 1.9.1-1%{?dist}.ngx
- 1.9.1
* Tue Apr 28 2015 Sergey Budnevitch <sb@nginx.com> - 1.9.0-1%{?dist}.ngx
- 1.9.0
- thread pool support added
- stream module added
- example_ssl.conf removed
* Tue Apr 7 2015 Sergey Budnevitch <sb@nginx.com> - 1.7.12-1%{?dist}.ngx
- 1.7.12
* Tue Mar 24 2015 Sergey Budnevitch <sb@nginx.com> - 1.7.11-1%{?dist}.ngx
- 1.7.11
* Tue Feb 10 2015 Sergey Budnevitch <sb@nginx.com> - 1.7.10-1%{?dist}.ngx
- 1.7.10
* Tue Dec 23 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.9-1%{?dist}.ngx
- 1.7.9
- init-script now sends signal only to the PID derived from pidfile
* Tue Dec 2 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.8-1%{?dist}.ngx
- 1.7.8
- package with debug symbols added
* Tue Oct 28 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.7-1%{?dist}.ngx
- 1.7.7
* Tue Sep 30 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.6-1%{?dist}.ngx
- 1.7.6
* Tue Sep 16 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.5-1%{?dist}.ngx
- 1.7.5
* Tue Aug 5 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.4-1%{?dist}.ngx
- 1.7.4
- init-script now returns 0 on stop command if nginx is not running
* Tue Jul 8 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.3-1%{?dist}.ngx
- 1.7.3
* Tue Jun 17 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.2-1%{?dist}.ngx
- 1.7.2
* Tue May 27 2014 Sergey Budnevitch <sb@nginx.com> - 1.7.1-1%{?dist}.ngx
- 1.7.1
* Thu Apr 24 2014 Konstantin Pavlov <thresh@nginx.com> - 1.7.0-1%{?dist}.ngx
- 1.7.0
* Tue Apr 8 2014 Sergey Budnevitch <sb@nginx.com> - 1.5.13-1%{?dist}.ngx
- 1.5.13
* Tue Mar 18 2014 Sergey Budnevitch <sb@nginx.com> - 1.5.12-1%{?dist}.ngx
- 1.5.12
- warning added when binary upgrade returns non-zero exit code
* Tue Mar 4 2014 Sergey Budnevitch <sb@nginx.com> - 1.5.11-1%{?dist}.ngx
- 1.5.11
* Tue Feb 4 2014 Sergey Budnevitch <sb@nginx.com> - 1.5.10-1%{?dist}.ngx
- 1.5.10
* Wed Jan 22 2014 Sergey Budnevitch <sb@nginx.com> - 1.5.9-1%{?dist}.ngx
- 1.5.9
* Tue Dec 17 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.8-1%{?dist}.ngx
- 1.5.8
* Fri Nov 29 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.7-1%{?dist}.ngx
- 1.5.7
- init script now honours additional options sourced from /etc/default/nginx
* Tue Oct 1 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.6-1%{?dist}.ngx
- 1.5.6
* Tue Sep 17 2013 Andrei Belov <defan@nginx.com> - 1.5.5-1%{?dist}.ngx
- 1.5.5
* Tue Aug 27 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.4-1%{?dist}.ngx
- 1.5.4
- auth request module added
* Tue Jul 30 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.3-1%{?dist}.ngx
- 1.5.3
* Tue Jul 2 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.2-1%{?dist}.ngx
- 1.5.2
* Tue Jun 4 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.1-1%{?dist}.ngx
- 1.5.1
- dpkg-buildflags options now passed by --with-{cc,ld}-opt
* Mon May 6 2013 Sergey Budnevitch <sb@nginx.com> - 1.5.0-1%{?dist}.ngx
- 1.5.0
- fixed openssl version detection with dash as /bin/sh
* Tue Apr 16 2013 Sergey Budnevitch <sb@nginx.com> - 1.3.16-1%{?dist}.ngx
- 1.3.16
* Tue Mar 26 2013 Sergey Budnevitch <sb@nginx.com> - 1.3.15-1%{?dist}.ngx
- 1.3.15
- gunzip module added
- spdy module added if openssl version >= 1.0.1
- set permissions on default log files at installation
# `ngx_http_voms_module` Testing
## Description
Setup and files to test the *ngx_http_voms_module* are contained in the `t` folder. The [Openresty data-driven testsuite](https://openresty.gitbooks.io/programming-openresty/content/testing/) has been adopted for testing.
### Test fixture setup
All the certificates and proxy certificates used in the tests are in the [`certs`](certs) folder (see that [README](certs/README.md) for further details), while trust-anchors (e.g. igi-test-ca.pem) are in the [`trust-anchors`](trust-anchors) folder.
`vomses` is the _vomses_ file needed for the generation of proxy certificates.
The LSC file `voms.example.lsc`, needed to perform correctly the VOMS AC validation, is in the [`vomsdir/test.vo`](vomsdir/test.vo) folder.
### Running Tests
To run the tests made available in `t` just type
```shell
$ prove -v
```
from `t`' s parent directory.
The `prove` command creates a directory called `servroot` in `t`, so if the `t` folder is accessible read-only, for
example in a docker container, just make a copy somewhere else and run the tests from there:
```
cp -r t /tmp
cd /tmp
prove -v
```
### Test coverage
To enable test coverage pass the `--coverage` option to both the compiler and the linker. For example:
```shell
$ ./configure ${RESTY_CONFIG_OPTIONS} --add-module=../ngx_http_voms_module --with-debug --with-cc-opt="-g -Og --coverage" --with-ld-opt="--coverage"
$ make && make install
```
The above command generates data files aside the source files for all Nginx. To enable coverage only for `ngx_http_voms_module` the `--coverage` option should be passed only when compiling `ngx_http_voms_module.cpp`, adding the option to `config.make`.
Running the tests will then create other data files with coverage information. To view that information, run `gcov <object file>`, e.g. `gcov .../objs/addon/src/ngx_http_voms_module.o`. This will produce files with the `.gcov` extension in the current directory.
### Testing directly the Nginx server
You can reuse the config file `t/servroot/conf/nginx.conf` produced by `test::Nginx`, which contains something like
```
server {
listen 8443 ssl;
server_name nginx-voms.example;
ssl_certificate ../../certs/nginx_voms_example.cert.pem;
ssl_certificate_key ./certs/nginx_voms_example.key.pem;
ssl_client_certificate ./trust-anchors/igi-test-ca.pem;
ssl_verify_depth 10;
ssl_verify_client on;
location = / {
echo user: $voms_user;
}
}
```
You may want to change the configuration so that the log goes to standard output instead of to a log file:
```
server {
error_log /dev/stdout debug;
...
```
Start nginx:
```shell
$ nginx -p t/servroot
```
Modify (as root) `/etc/hosts` so that `nginx-voms.example` is an alias for `localhost`:
```
127.0.0.1 localhost nginx-voms.example
```
Then run for example `curl`, calling directly the HTTPS endpoint:
```shell
$ curl https://nginx-voms.example:8443 --cert t/certs/3.pem --capath t/trust-anchors --cacert t/certs/3.cert.pem
```
-----BEGIN CERTIFICATE-----
MIICkjCCAXygAwIBAgIEaPuJvzALBgkqhkiG9w0BAQUwKzELMAkGA1UEBhMCSVQx
DDAKBgNVBAoTA0lHSTEOMAwGA1UEAxMFdGVzdDAwHhcNMTgwMzAyMTczNTU0WhcN
MjIwOTI0MTUzOTM0WjBAMQswCQYDVQQGEwJJVDEMMAoGA1UEChMDSUdJMQ4wDAYD
VQQDEwV0ZXN0MDETMBEGA1UEAxMKMTc2MTMxNTI2MzCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAgCtdYKINH/sClmYwxea8ydJbBTR7j8XdJmuZgA5c8YDLmN2E
Fo50XHtQXbpmNGvuOXC6n4hY193oEcXL7N+CTjlHEmx5imaNzFvcfEdjxx0Cytqi
xOt1tbhOvZUSMYqcIdJfPX21n7D1tObI3/+cZ16RHNWZF/wigdLoSr6qbZ0CAwEA
AaMxMC8wDgYDVR0PAQH/BAQDAgXgMB0GCCsGAQUFBwEOAQH/BA4wDDAKBggrBgEF
BQcVATALBgkqhkiG9w0BAQUDggEBACm+nPPqabJDsKb0BnihdPbIOls5Kla84nSo
p5WlRGrGtnBmWkL7WeZc2CYXzrrd4EhAQtjwnw1eYZ3+uTBNXbsQNSTiGqhfXcdH
p5O4AOUMdMda19kos67AIFCn5skWrKzn04TW8HEOYo6doJAkkAc7pFrQeXVU4IUM
ZlS6gNuXqLISelHZV2WGeueZ9oe8SL08ZKZCNI09BScUaqiIuuVdZhH48uNBQKXs
/KWjT8IBj4bTum+/nrSLGPRppSMC1bDfmn0C/ffk7g1Fo+ndyU9lB4ZF6eykGYe3
V1LswGAb9BQvbm2qYdmS4F/i2qLxkRyaA1IB8aaCv4tWqKtMH00=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCAK11gog0f+wKWZjDF5rzJ0lsFNHuPxd0ma5mADlzxgMuY3YQW
jnRce1BdumY0a+45cLqfiFjX3egRxcvs34JOOUcSbHmKZo3MW9x8R2PHHQLK2qLE
63W1uE69lRIxipwh0l89fbWfsPW05sjf/5xnXpEc1ZkX/CKB0uhKvqptnQIDAQAB
AoGAIEVK5IrIzTWRKDcgrqNzA0nQmxXkyoViMktDQefb5P6txJZ5rIg/qg1uZbsK
AsbuG05T3tkgrXF0/gyUVNbN4vKE1Po1HyCIz8ZO5ZoA+AB3W5swdkf/sP9/y5jG
qrh58CM+IqpyVIf0ZYSv3j/WEGgocBuzBlgzsu81ruR4ym0CQQDIAzAu1KigbKNs
kJvgjWGJK5fAF+eJgQ4waH1wnzlExgM8lBpQhNXiYnvcrTUBbBtc4onXbD1iiHkD
M52BJNhjAkEApAvuiv8TjIK9T5EyCf3Zbk5g8I9XUTNk2Qq9Dc9NfXnE9OwjNss/
hjvDCX89OA1DFRuud2a0qgvMSrVXnW+B/wJAJQzSJBqoke8N5tJyzYnjA3Hbzm2f
Kk2Jv1Xbxrz38tFrUBFvPnMc2666mwpKw1SvTOl59znJtTLql7k79+xHWQJAKcrA
YrjJCirkf7jFvrXlBq0BFUfvPsiREJojv7joTOcQvjTKY9Mzw8bF0U2REw6N4HrE
37ZSoF+RFBdO0tTtkQJAFs+jv0al71WnqEwoF0R8iSACcgTU5pG2c5upMUFbq+3V
Sc2mleRKf33pghtj1f/HP9+CXhUVG1rtLkcR6qW5Cg==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICkjCCAXygAwIBAgIEaPuJvzALBgkqhkiG9w0BAQUwKzELMAkGA1UEBhMCSVQx
DDAKBgNVBAoTA0lHSTEOMAwGA1UEAxMFdGVzdDAwHhcNMTgwMzAyMTczNTU0WhcN
MjIwOTI0MTUzOTM0WjBAMQswCQYDVQQGEwJJVDEMMAoGA1UEChMDSUdJMQ4wDAYD
VQQDEwV0ZXN0MDETMBEGA1UEAxMKMTc2MTMxNTI2MzCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAgCtdYKINH/sClmYwxea8ydJbBTR7j8XdJmuZgA5c8YDLmN2E
Fo50XHtQXbpmNGvuOXC6n4hY193oEcXL7N+CTjlHEmx5imaNzFvcfEdjxx0Cytqi
xOt1tbhOvZUSMYqcIdJfPX21n7D1tObI3/+cZ16RHNWZF/wigdLoSr6qbZ0CAwEA
AaMxMC8wDgYDVR0PAQH/BAQDAgXgMB0GCCsGAQUFBwEOAQH/BA4wDDAKBggrBgEF
BQcVATALBgkqhkiG9w0BAQUDggEBACm+nPPqabJDsKb0BnihdPbIOls5Kla84nSo
p5WlRGrGtnBmWkL7WeZc2CYXzrrd4EhAQtjwnw1eYZ3+uTBNXbsQNSTiGqhfXcdH
p5O4AOUMdMda19kos67AIFCn5skWrKzn04TW8HEOYo6doJAkkAc7pFrQeXVU4IUM
ZlS6gNuXqLISelHZV2WGeueZ9oe8SL08ZKZCNI09BScUaqiIuuVdZhH48uNBQKXs
/KWjT8IBj4bTum+/nrSLGPRppSMC1bDfmn0C/ffk7g1Fo+ndyU9lB4ZF6eykGYe3
V1LswGAb9BQvbm2qYdmS4F/i2qLxkRyaA1IB8aaCv4tWqKtMH00=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCAK11gog0f+wKWZjDF5rzJ0lsFNHuPxd0ma5mADlzxgMuY3YQW
jnRce1BdumY0a+45cLqfiFjX3egRxcvs34JOOUcSbHmKZo3MW9x8R2PHHQLK2qLE
63W1uE69lRIxipwh0l89fbWfsPW05sjf/5xnXpEc1ZkX/CKB0uhKvqptnQIDAQAB
AoGAIEVK5IrIzTWRKDcgrqNzA0nQmxXkyoViMktDQefb5P6txJZ5rIg/qg1uZbsK
AsbuG05T3tkgrXF0/gyUVNbN4vKE1Po1HyCIz8ZO5ZoA+AB3W5swdkf/sP9/y5jG
qrh58CM+IqpyVIf0ZYSv3j/WEGgocBuzBlgzsu81ruR4ym0CQQDIAzAu1KigbKNs
kJvgjWGJK5fAF+eJgQ4waH1wnzlExgM8lBpQhNXiYnvcrTUBbBtc4onXbD1iiHkD
M52BJNhjAkEApAvuiv8TjIK9T5EyCf3Zbk5g8I9XUTNk2Qq9Dc9NfXnE9OwjNss/
hjvDCX89OA1DFRuud2a0qgvMSrVXnW+B/wJAJQzSJBqoke8N5tJyzYnjA3Hbzm2f
Kk2Jv1Xbxrz38tFrUBFvPnMc2666mwpKw1SvTOl59znJtTLql7k79+xHWQJAKcrA
YrjJCirkf7jFvrXlBq0BFUfvPsiREJojv7joTOcQvjTKY9Mzw8bF0U2REw6N4HrE
37ZSoF+RFBdO0tTtkQJAFs+jv0al71WnqEwoF0R8iSACcgTU5pG2c5upMUFbq+3V
Sc2mleRKf33pghtj1f/HP9+CXhUVG1rtLkcR6qW5Cg==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
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
ZTAXFVmk
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCILRV6Kz/KYhWMixptl7fQghmCCDX8U5Ew7LV/Mjz14+ugzJ+U
G0KQ/nnPjskjM3rw+IZIuEAAinyOkihEQJWwp86I9ioAL/xaLdI3dVHQEPn2JMI+
gzRANPDa98ICIN9+uGQiJu94MqAN4SDfdZAaYqdLr/VqMY/PWk0b+z/eSwIDAQAB
AoGAJM8i9hIIvTkEIChdrXAMVMVGBdsYVKt2HKZvbQF0bvb780w8enlf5feTj6JG
BkjdG5PiIHgFfN/ySUuCrOhUTbNhAx5a9YExqtJoiNaVBcIvlwVEK6Md8iYc9Opv
RB7MOwVmzoQQzTbsKQMDj2Bn1IZmLXKlaW+OW/n/I5KnoYkCQQDsLIGpEdnDlK3e
FaRaBSL8dlE6PA3HKokTeEoy9/yWGcvvtBAfsL8GhFAXEzrCNbuy0dGUymksCSp5
NTRSe6pfAkEAk5uTf+6TlZaCNutG3H9ScLTvBef3qcrVx9CzsPH8NK6x6GGhpPzl
FBmLtsRxeOGTIFbnEcbfImbuSQ1rcPBrlQJBALiJbia1E/qGSfSl5G2SZevuZzmh
gwKEcecMrq10p6CBN6Bsicy5RgnJiOr+04K8iZUH7ULdhaAq6U0cDW4FwvECQDXm
Om8dtCCMbBIXybFcgMMNHrbeZI5ItdWX/PWg90JZhDdh5z+y5Qd46I6dnv3QCQRn
F0tjfjk2ss5UKyZ7dB0CQQDAGspYNiI7YQoJm7hIAwh332SGuVVqb6IL9rMfsVR6
ffsKgAQtwl5JYGEKEXtO/yylfaiYqOMHNRJPsiI7IHLq
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
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
ZTAXFVmk
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCILRV6Kz/KYhWMixptl7fQghmCCDX8U5Ew7LV/Mjz14+ugzJ+U
G0KQ/nnPjskjM3rw+IZIuEAAinyOkihEQJWwp86I9ioAL/xaLdI3dVHQEPn2JMI+
gzRANPDa98ICIN9+uGQiJu94MqAN4SDfdZAaYqdLr/VqMY/PWk0b+z/eSwIDAQAB
AoGAJM8i9hIIvTkEIChdrXAMVMVGBdsYVKt2HKZvbQF0bvb780w8enlf5feTj6JG
BkjdG5PiIHgFfN/ySUuCrOhUTbNhAx5a9YExqtJoiNaVBcIvlwVEK6Md8iYc9Opv
RB7MOwVmzoQQzTbsKQMDj2Bn1IZmLXKlaW+OW/n/I5KnoYkCQQDsLIGpEdnDlK3e
FaRaBSL8dlE6PA3HKokTeEoy9/yWGcvvtBAfsL8GhFAXEzrCNbuy0dGUymksCSp5
NTRSe6pfAkEAk5uTf+6TlZaCNutG3H9ScLTvBef3qcrVx9CzsPH8NK6x6GGhpPzl
FBmLtsRxeOGTIFbnEcbfImbuSQ1rcPBrlQJBALiJbia1E/qGSfSl5G2SZevuZzmh
gwKEcecMrq10p6CBN6Bsicy5RgnJiOr+04K8iZUH7ULdhaAq6U0cDW4FwvECQDXm
Om8dtCCMbBIXybFcgMMNHrbeZI5ItdWX/PWg90JZhDdh5z+y5Qd46I6dnv3QCQRn
F0tjfjk2ss5UKyZ7dB0CQQDAGspYNiI7YQoJm7hIAwh332SGuVVqb6IL9rMfsVR6
ffsKgAQtwl5JYGEKEXtO/yylfaiYqOMHNRJPsiI7IHLq
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
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
ggMdmoIl
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCffYJKroHe6Ss1in6zkuhSncjbiP3ghIjMwv6m1/bOcuyqzJpX
ZWoLEWvucG5haLZ05Ho1u19xzSlkqsSyc5YLwVhsHbUYF0/3IHBBtCdCShWAs9Bk
3q5/h3wBlciCY/sLanfiUIliUnsx0LovLMDTw5hN+Ez5iK9f5tAkpXX9owIDAQAB
AoGAbxTOQ0+JeoSxqIe+OTnvf2MPuv+Nuur0EJEbJX8zEZTviwIX2Rj0I6NNpfM+
na99rKpZB8Vp82vuEYPynUtty77UJ7o0iziWQoyb0OsY/U8C0DL0jInicEa7exGP
jWch1d9mFz5A4+mo8QFApo88Cx7ENHvWftro4CWPYkvEEikCQQD/28TpNbAAnJB7
99S5QaXqAxaPdQIwff5T2OncIsmzL/DHbkp21tPccZ+LVtZp3/2vNF11HT8FYEbW
bcsSZa2/AkEAn5QX82MXrcqEt0pdoU04UdNeSAXY8zaiRinPWlVAOjYl2kDcgInV
DVx0psaoUYbvg+hxzKKunuHChytTYcBxHQJBAPq2hJatWCDRSjdf22AJNyY/Dm1W
j+WqoHvTEx32LMVcVclmhqs6yXG7GUZ1ujcXGUQEwQuQs/91nxRhk9scLYsCQQCT
MSSOaR6UPTMBZeTLPdDvGMnkIRCl9gTkNvh92BiwGPX9RMqe/YO5GUi39JGY8Z/H
ygX9vSjYgGDQERSOG9W5AkAOhzoSyonBVeIvc7ky4F0KQSQupvyAQpTIZ/wkjbGo
W5z9Y3TbN0zJA7Qnx6oEV5ZHshplSdZXYJNvVe5qGvG1
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
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
ggMdmoIl
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCffYJKroHe6Ss1in6zkuhSncjbiP3ghIjMwv6m1/bOcuyqzJpX
ZWoLEWvucG5haLZ05Ho1u19xzSlkqsSyc5YLwVhsHbUYF0/3IHBBtCdCShWAs9Bk
3q5/h3wBlciCY/sLanfiUIliUnsx0LovLMDTw5hN+Ez5iK9f5tAkpXX9owIDAQAB
AoGAbxTOQ0+JeoSxqIe+OTnvf2MPuv+Nuur0EJEbJX8zEZTviwIX2Rj0I6NNpfM+
na99rKpZB8Vp82vuEYPynUtty77UJ7o0iziWQoyb0OsY/U8C0DL0jInicEa7exGP
jWch1d9mFz5A4+mo8QFApo88Cx7ENHvWftro4CWPYkvEEikCQQD/28TpNbAAnJB7
99S5QaXqAxaPdQIwff5T2OncIsmzL/DHbkp21tPccZ+LVtZp3/2vNF11HT8FYEbW
bcsSZa2/AkEAn5QX82MXrcqEt0pdoU04UdNeSAXY8zaiRinPWlVAOjYl2kDcgInV
DVx0psaoUYbvg+hxzKKunuHChytTYcBxHQJBAPq2hJatWCDRSjdf22AJNyY/Dm1W
j+WqoHvTEx32LMVcVclmhqs6yXG7GUZ1ujcXGUQEwQuQs/91nxRhk9scLYsCQQCT
MSSOaR6UPTMBZeTLPdDvGMnkIRCl9gTkNvh92BiwGPX9RMqe/YO5GUi39JGY8Z/H
ygX9vSjYgGDQERSOG9W5AkAOhzoSyonBVeIvc7ky4F0KQSQupvyAQpTIZ/wkjbGo
W5z9Y3TbN0zJA7Qnx6oEV5ZHshplSdZXYJNvVe5qGvG1
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBCTANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJJVDEM
MAoGA1UECgwDSUdJMRAwDgYDVQQDDAdUZXN0IENBMB4XDTEyMDkyNjE1MzkzNFoX
DTIyMDkyNDE1MzkzNFowKzELMAkGA1UEBhMCSVQxDDAKBgNVBAoTA0lHSTEOMAwG
A1UEAxMFdGVzdDAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxtrw
hoZ27SxxISjlRqWmBWB6U+N/xW2kS1uUfrQRav6auVtmtEW45J44VTi3WW6Y113R
BwmS6oW+3lzyBBZVPqnhV9/VkTxLp83gGVVvHATgGgkjeTxIsOE+TkPKAoZJ/QFc
CfPh3WdZ3ANI14WYkAM9VXsSbh2okCsWGa4o6pzt3Pt1zKkyO4PW0cBkletDImJK
2vufuDVNm7Iz/y3/8pY8p3MoiwbF/PdSba7XQAxBWUJMoaleh8xy8HSROn7tF2al
xoDLH4QWhp6UDn2rvOWseBqUMPXFjsUi1/rkw1oHAjMroTk5lL15GI0LGd5dTVop
kKXFbTTYxSkPz1MLAgMBAAGjgcowgccwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
fLdB5+jO9LyWN2/VCNYgMa0jvHEwDgYDVR0PAQH/BAQDAgXgMD4GA1UdJQQ3MDUG
CCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSRdzZ7LrRp8yfqt/YIi0ojohFJxjAnBgNVHREEIDAe
gRxhbmRyZWEuY2VjY2FudGlAY25hZi5pbmZuLml0MA0GCSqGSIb3DQEBBQUAA4IB
AQANYtWXetheSeVpCfnId9TkKyKTAp8RahNZl4XFrWWn2S9We7ACK/G7u1DebJYx
d8POo8ClscoXyTO2BzHHZLxauEKIzUv7g2GehI+SckfZdjFyRXjD0+wMGwzX7MDu
SL3CG2aWsYpkBnj6BMlr0P3kZEMqV5t2+2Tj0+aXppBPVwzJwRhnrSJiO5WIZAZf
49YhMn61sQIrepvhrKEUR4XVorH2Bj8ek1/iLlgcmFMBOds+PrehSRR8Gn0IjlEg
C68EY6KPE+FKySuS7Ur7lTAjNdddfdAgKV6hJyST6/dx8ymIkb8nxCPnxCcT2I2N
vDxcPMc/wmnMa+smNal0sJ6m
-----END CERTIFICATE-----