#!/bin/sh

#  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.

# Generate a minimal HTTPD SSL configuration
here=`readlink -f $0`; here=`dirname $here`
root=`readlink -f $1`

conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
host=`echo $conf | awk '{ print $6 }'`

sslpport=`$here/httpd-addr pport $2`
ssllisten=`$here/httpd-addr listen $2`
sslvhost=`$here/httpd-addr vhost $2`

htdocs=`echo $conf | awk '{ print $8 }'`
htdocs=`readlink -f $htdocs`

httpd_prefix=`cat $here/httpd.prefix`

# Extract organization name from our CA certificate
org=`openssl x509 -noout -subject -nameopt multiline -in $root/cert/ca.crt | grep organizationName | awk -F "= " '{ print $2 }'`

# Generate HTTPD configuration
cat >>$root/conf/httpd.conf <<EOF
# Generated by: httpd-ssl-conf $*
# Redirect all HTTP traffic to HTTPS
<Location />
RewriteEngine on
RewriteCond %{HTTPS} !^on$
RewriteRule .* https://%{SERVER_NAME}:$sslpport%{REQUEST_URI} [R,L]
</Location>

# Configure SSL support
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog  builtin
SSLSessionCache "shmcb:$root/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300
SSLMutex "file:$root/logs/ssl_mutex"
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin

# Listen on HTTPS port
Listen $ssllisten

# HTTPS virtual host
<VirtualHost $sslvhost>
ServerName https://$host:$sslpport

Include conf/svhost-ssl.conf

# Allow the server admin to view the server status
<Location /server-status>
SetHandler server-status
HostnameLookups on
Allow from all
Require user admin
</Location>

</VirtualHost>

# Report extended server status
ExtendedStatus On

EOF

# Generate HTTPS vhost configuration
cat >$root/conf/vhost-ssl.conf <<EOF
# Generated by: httpd-ssl-conf $*
# Virtual host configuration
UseCanonicalName Off

# Enable SSL
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
SSLOptions -StrictRequire +OptRenegotiate

# Verify client certificates
SSLVerifyClient optional
SSLVerifyDepth 1

# Log SSL requests
#CustomLog "$root/logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
LogFormat "%h %l %u %t %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" \"%{SSL_CLIENT_I_DN}x\" \"%{SSL_CLIENT_S_DN}x\"" sslcombined
CustomLog $root/logs/ssl_access_log sslcombined

EOF

# Generate HTTPS authentication requirement
cat >>$root/conf/vhost-ssl.conf <<EOF
<Location />
# Require clients to use SSL and authenticate
SSLRequireSSL

# Also accept other forms of authentication (e.g. HTTP basic
# authentication, or OpenID authentication)
Satisfy Any

EOF

proxyconf=`cat $root/conf/vhost.conf | grep "# Generated by: proxy-conf"`
if [ "$proxyconf" != "" ]; then
    cat >>$root/conf/vhost-ssl.conf <<EOF
# In an proxy, only require a 128+ cipher key
SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128

# Forward received SSL client certificate info in proxied requests
RewriteEngine on
RewriteRule .* - [E=SSL_PROTOCOL:%{SSL:SSL_PROTOCOL}]
RewriteRule .* - [E=SSL_CIPHER:%{SSL:SSL_CIPHER}]
RewriteCond %{SSL:SSL_CLIENT_I_DN} !="" 
RewriteRule .* - [E=SSL_I_DN:%{SSL:SSL_CLIENT_I_DN}] 
RewriteCond %{SSL:SSL_CLIENT_S_DN} !="" 
RewriteRule .* - [E=SSL_S_DN:%{SSL:SSL_CLIENT_S_DN}] 
RewriteCond %{SSL:SSL_CLIENT_I_DN_O} !="" 
RewriteRule .* - [E=SSL_I_DN_O:%{SSL:SSL_CLIENT_I_DN_O}] 
RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} !="" 
RewriteRule .* - [E=SSL_S_DN_OU:%{SSL:SSL_CLIENT_S_DN_OU}] 
RequestHeader unset X-Forwarded-SSL-Protocol
RequestHeader unset X-Forwarded-SSL-Cipher
RequestHeader unset X-Forwarded-SSL-Issuer-DN
RequestHeader unset X-Forwarded-SSL-Client-DN
RequestHeader unset X-Forwarded-SSL-Issuer-DN-O
RequestHeader unset X-Forwarded-SSL-Client-DN-OU
RequestHeader set X-Forwarded-SSL-Protocol %{SSL_PROTOCOL}e env=SSL_PROTOCOL
RequestHeader set X-Forwarded-SSL-Cipher %{SSL_CIPHER}e env=SSL_CIPHER
RequestHeader set X-Forwarded-SSL-Issuer-DN %{SSL_I_DN}e env=SSL_I_DN
RequestHeader set X-Forwarded-SSL-Client-DN %{SSL_S_DN}e env=SSL_S_DN
RequestHeader set X-Forwarded-SSL-Issuer-DN-O %{SSL_I_DN_O}e env=SSL_I_DN_O
RequestHeader set X-Forwarded-SSL-Client-DN-OU %{SSL_S_DN_OU}e env=SSL_S_DN_OU

EOF
else
    cat >>$root/conf/vhost-ssl.conf <<EOF
# In a server, require a 128+ cipher key and one of the following
# - another server's certificate issued by our certificate authority
# - a proxy certificate + forwarded info on the client request certificate,
#   both signed by our certificate authority
# - OpenID authentication (set by mod_auth_openid in the auth_type)
# - another valid form of authentication as per the Satisfy directive
SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 and ( \
( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "server" ) or \
( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "tunnel" ) or \
( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "proxy" and \
  %{HTTP:X-Forwarded-SSL-Issuer-DN-O} == "$org" and %{HTTP:X-Forwarded-SSL-Client-DN-OU} == "server" ) or \
%{REQUEST_URI} =~ m/^.(login|logout|openid|unprotected).*$/ )

# Record received SSL client certificate info in environment vars
RewriteEngine on
RewriteRule .* - [E=SSL_PROTOCOL:%{SSL:SSL_PROTOCOL}]
RewriteRule .* - [E=SSL_CIPHER:%{SSL:SSL_CIPHER}]
RewriteCond %{SSL:SSL_CLIENT_I_DN} !="" 
RewriteRule .* - [E=SSL_I_DN:%{SSL:SSL_CLIENT_I_DN}] 
RewriteCond %{SSL:SSL_CLIENT_S_DN} !="" 
RewriteRule .* - [E=SSL_S_DN:%{SSL:SSL_CLIENT_S_DN}] 

# Store the client certificate DN in the SSL_REMOTE_USER var,
# that's similar to the SSLUserName directive but more flexible as
# it can pick a client certificate DN forwarded by a proxy
RewriteCond %{SSL:SSL_CLIENT_I_DN_O} "$org"
RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} "server"
RewriteRule .* - [E=SSL_REMOTE_USER:%{SSL:SSL_CLIENT_S_DN}] 

RewriteCond %{SSL:SSL_CLIENT_I_DN_O} "$org"
RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} "tunnel"
RewriteRule .* - [E=SSL_REMOTE_USER:%{SSL:SSL_CLIENT_S_DN}] 

RewriteCond %{SSL:SSL_CLIENT_I_DN_O} "$org"
RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} "proxy"
RewriteCond %{HTTP:X-Forwarded-SSL-Issuer-DN-O} "$org"
RewriteCond %{HTTP:X-Forwarded-SSL-Client-DN-OU} "server"
RewriteRule .* - [E=SSL_REMOTE_USER:%{HTTP:X-Forwarded-SSL-Client-DN}] 

EOF
fi

cat >>$root/conf/vhost-ssl.conf <<EOF
</Location>

EOF

cat >$root/conf/svhost-ssl.conf <<EOF
# Generated by: httpd-ssl-conf $*
# Static virtual host configuration
Include conf/vhost-ssl.conf

# Declare SSL certificates used in this virtual host
SSLCACertificateFile "$root/cert/ca.crt"
SSLCertificateChainFile "$root/cert/ca.crt"
SSLCertificateFile "$root/cert/server.crt"
SSLCertificateKeyFile "$root/cert/server.key"

EOF

cat >$root/conf/dvhost-ssl.conf <<EOF
# Mass dynamic virtual host configuration
# Generated by: httpd-ssl-conf $*
Include conf/vhost-ssl.conf

# Declare wildcard SSL certificates used in this virtual host
SSLCACertificateFile "$root/cert/ca.crt"
SSLCertificateChainFile "$root/cert/ca.crt"
SSLCertificateFile "$root/cert/vhost.crt"
SSLCertificateKeyFile "$root/cert/vhost.key"

EOF

