mirror of
https://github.com/certbot/certbot.git
synced 2026-07-25 23:29:26 +02:00
Added base challenge class, converted sni_challenge to class, client uses challenge factory and generic perform, cleanup functions
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
from trustify.client import logger
|
||||
|
||||
class Challenge(object):
|
||||
def __init__(self, configurator):
|
||||
self.config = configurator
|
||||
def perform(self):
|
||||
logger.error("Error - base class challenge.perform()")
|
||||
def clean(self):
|
||||
logger.error("Error - base class challenge.clean()")
|
||||
|
||||
+30
-20
@@ -8,12 +8,12 @@ import os, grp, pwd, sys, time, random, sys
|
||||
import hashlib
|
||||
import subprocess
|
||||
import getopt
|
||||
import logger
|
||||
# TODO: support a mode where use of interactive prompting is forbidden
|
||||
|
||||
from trustify.protocol.chocolate_pb2 import chocolatemessage
|
||||
from trustify.client import sni_challenge
|
||||
from trustify.client import configurator
|
||||
from trustify.client import logger
|
||||
from trustify.client.CONFIG import difficulty, cert_file, chain_file
|
||||
from trustify.client.CONFIG import KEY_DIR, CERT_DIR
|
||||
|
||||
@@ -261,6 +261,26 @@ def gen_https_names(domains):
|
||||
result = result + "https://" + domains[len(domains)-1]
|
||||
return result
|
||||
|
||||
def challenge_factory(r, req_filepath, key_filepath, config):
|
||||
sni_todo = []
|
||||
dn = []
|
||||
challenges = []
|
||||
logger.info("Received %s challenges from server." % len(r.challenge))
|
||||
for chall in r.challenge:
|
||||
logger.debug(chall)
|
||||
if chall.type == r.DomainValidateSNI:
|
||||
logger.info("\tDomainValidateSNI challenge for name %s." % chall.name)
|
||||
dvsni_nonce, dvsni_y, dvsni_ext = chall.data
|
||||
sni_todo.append( (chall.name, dvsni_y, dvsni_nonce, dvsni_ext) )
|
||||
|
||||
dn.append(chall.name)
|
||||
if sni_todo:
|
||||
challenges.append(sni_todo, req_filepath, key_filepath, config)
|
||||
logger.debug(sni_todo)
|
||||
|
||||
return challenges, dn
|
||||
|
||||
|
||||
def send_request(key_pem, csr_pem, quiet=curses):
|
||||
global server
|
||||
upstream = "https://%s/chocolate.py" % server
|
||||
@@ -291,9 +311,9 @@ def send_request(key_pem, csr_pem, quiet=curses):
|
||||
return r, k
|
||||
|
||||
|
||||
def handle_verification_response(r, dn, sni_todo, vhost, key_file, config):
|
||||
def handle_verification_response(r, dn, challenge, vhost, key_file, config):
|
||||
if r.success.IsInitialized():
|
||||
sni_challenge.cleanup(sni_todo, config)
|
||||
challenge.cleanup()
|
||||
cert_chain_abspath = None
|
||||
with open(cert_file, "w") as f:
|
||||
f.write(r.success.certificate)
|
||||
@@ -401,19 +421,8 @@ def authenticate():
|
||||
|
||||
r, k = send_request(key_pem, csr_pem)
|
||||
|
||||
sni_todo = []
|
||||
dn = []
|
||||
logger.info("Received %s challenges from server." % len(r.challenge))
|
||||
for chall in r.challenge:
|
||||
logger.debug(chall)
|
||||
if chall.type == r.DomainValidateSNI:
|
||||
logger.info("\tDomainValidateSNI challenge for name %s." % chall.name)
|
||||
dvsni_nonce, dvsni_y, dvsni_ext = chall.data
|
||||
sni_todo.append( (chall.name, dvsni_y, dvsni_nonce, dvsni_ext) )
|
||||
dn.append(chall.name)
|
||||
|
||||
|
||||
logger.debug(sni_todo)
|
||||
challenges, dn = challenge_factory(r, os.path.abspath(req_file), os.path.abspath(key_file), config)
|
||||
|
||||
# Find virtual hosts to deploy certificates too
|
||||
vhost = set()
|
||||
@@ -422,9 +431,10 @@ def authenticate():
|
||||
if host is not None:
|
||||
vhost.add(host)
|
||||
|
||||
if not sni_challenge.perform_sni_cert_challenge(sni_todo, os.path.abspath(req_file), os.path.abspath(key_file), config, quiet=curses):
|
||||
logger.fatal("sni_challenge failed")
|
||||
sys.exit(1)
|
||||
for challenge in challenges:
|
||||
if not challenge.perform(quiet=curses):
|
||||
logger.fatal("challenge failed")
|
||||
sys.exit(1)
|
||||
logger.info("Configured Apache for challenge; waiting for verification...")
|
||||
|
||||
logger.debug("waiting 3")
|
||||
@@ -438,8 +448,8 @@ def authenticate():
|
||||
k.session = r.session
|
||||
r = decode(do(upstream, k))
|
||||
logger.debug(r)
|
||||
|
||||
handle_verification_response(r, dn, sni_todo, vhost, key_file, config)
|
||||
# TODO: This needs to be rewritten to handle multiple challenges
|
||||
handle_verification_response(r, dn, challenges[0], vhost, key_file, config)
|
||||
|
||||
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4
|
||||
|
||||
@@ -6,11 +6,11 @@ import sys
|
||||
import socket
|
||||
import time
|
||||
import shutil
|
||||
import logger
|
||||
|
||||
from trustify.client.CONFIG import SERVER_ROOT, BACKUP_DIR, MODIFIED_FILES
|
||||
#from CONFIG import SERVER_ROOT, BACKUP_DIR, MODIFIED_FILES, REWRITE_HTTPS_ARGS
|
||||
from trustify.client.CONFIG import REWRITE_HTTPS_ARGS
|
||||
from trustify.client import logger
|
||||
|
||||
#TODO - Need an initialization routine... make sure directories exist..ect
|
||||
|
||||
@@ -545,8 +545,16 @@ LogLevel warn \n\
|
||||
return True, new_vhost
|
||||
|
||||
def __conflicting_host(self, ssl_vhost):
|
||||
'''
|
||||
Checks for a conflicting host, such that a new port 80 host could not
|
||||
be created without ruining the apache config
|
||||
Used with redirection
|
||||
|
||||
returns: conflict, hostOrAddrs - boolean
|
||||
if conflict: returns conflicting vhost
|
||||
if not conflict: returns space separated list of new host addrs
|
||||
'''
|
||||
# Consider changing this to a dictionary check
|
||||
# Make sure adding the vhost will be safe
|
||||
redirect_addrs = ""
|
||||
for ssl_a in ssl_vhost.addrs:
|
||||
# Add space on each new addr, combine "VirtualHost"+redirect_addrs
|
||||
|
||||
+198
-181
@@ -16,42 +16,58 @@ from trustify.client import configurator
|
||||
from trustify.client.CONFIG import CONFIG_DIR, WORK_DIR, SERVER_ROOT
|
||||
from trustify.client.CONFIG import CHOC_CERT_CONF, OPTIONS_SSL_CONF, APACHE_CHALLENGE_CONF
|
||||
from trustify.client.CONFIG import S_SIZE, NONCE_SIZE
|
||||
from trustify.client import logger
|
||||
from trustify.client.challenge import Challenge
|
||||
|
||||
def getChocCertFile(nonce):
|
||||
"""
|
||||
Returns standardized name for challenge certificate
|
||||
class SNI_Challenge(Challenge):
|
||||
def __init__(self, sni_todos, req_filepath, key_filepath, config):
|
||||
'''
|
||||
sni_todos: List of tuples with form (addr, y, nonce, ext_oid)
|
||||
addr (string), y (byte array), nonce (hex string),
|
||||
ext_oid (string)
|
||||
csr: string - File path to chocolate csr
|
||||
key: string - File path to key
|
||||
configurator: Configurator obj
|
||||
'''
|
||||
self.listSNITuple = sni_todos
|
||||
self.csr = req_filepath
|
||||
self.key = key_filepath
|
||||
self.configurator = config
|
||||
|
||||
|
||||
nonce: string - hex
|
||||
|
||||
result: returns certificate file name
|
||||
"""
|
||||
def getChocCertFile(self, nonce):
|
||||
"""
|
||||
Returns standardized name for challenge certificate
|
||||
|
||||
return WORK_DIR + nonce + ".crt"
|
||||
nonce: string - hex
|
||||
|
||||
def findApacheConfigFile():
|
||||
"""
|
||||
Locates the file path to the user's main apache config
|
||||
result: returns certificate file name
|
||||
"""
|
||||
|
||||
TODO: This needs to use true server_root
|
||||
|
||||
result: returns file path if present
|
||||
"""
|
||||
if path.isfile(SERVER_ROOT + "httpd.conf"):
|
||||
return SERVER_ROOT + "httpd.conf"
|
||||
print "Unable to find httpd.conf, file does not exist in Apache ServerRoot"
|
||||
return None
|
||||
return WORK_DIR + nonce + ".crt"
|
||||
|
||||
def getConfigText(nonce, ip_addrs, key):
|
||||
"""
|
||||
Chocolate virtual server configuration text
|
||||
def findApacheConfigFile(self):
|
||||
"""
|
||||
Locates the file path to the user's main apache config
|
||||
|
||||
nonce: string - hex
|
||||
ip_addr: string - address of challenged domain
|
||||
key: string - file path to key
|
||||
result: returns file path if present
|
||||
"""
|
||||
if path.isfile(SERVER_ROOT + "httpd.conf"):
|
||||
return SERVER_ROOT + "httpd.conf"
|
||||
logger.error("Unable to find httpd.conf, file does not exist in Apache ServerRoot")
|
||||
return None
|
||||
|
||||
result: returns virtual host configuration text
|
||||
"""
|
||||
configText = "<VirtualHost " + " ".join(ip_addrs) + "> \n \
|
||||
def __getConfigText(self, nonce, ip_addrs, key):
|
||||
"""
|
||||
Chocolate virtual server configuration text
|
||||
|
||||
nonce: string - hex
|
||||
ip_addr: string - address of challenged domain
|
||||
key: string - file path to key
|
||||
|
||||
result: returns virtual host configuration text
|
||||
"""
|
||||
configText = "<VirtualHost " + " ".join(ip_addrs) + "> \n \
|
||||
ServerName " + nonce + ".chocolate \n \
|
||||
UseCanonicalName on \n \
|
||||
SSLStrictSNIVHostCheck on \n \
|
||||
@@ -65,190 +81,191 @@ SSLCertificateKeyFile " + key + " \n \
|
||||
DocumentRoot " + CONFIG_DIR + "challenge_page/ \n \
|
||||
</VirtualHost> \n\n "
|
||||
|
||||
return configText
|
||||
return configText
|
||||
|
||||
def modifyApacheConfig(mainConfig, listSNITuple, listlistAddrs, key, configurator):
|
||||
"""
|
||||
Modifies Apache config files to include the challenge virtual servers
|
||||
|
||||
mainConfig: string - file path to Apache user config file
|
||||
listSNITuple: list of tuples with form (addr, y, nonce, ext_oid)
|
||||
addr (string), y (byte array), nonce (hex string), ext_oid (string)
|
||||
key: string - file path to key
|
||||
def modifyApacheConfig(self, mainConfig, listlistAddrs):
|
||||
"""
|
||||
Modifies Apache config files to include the challenge virtual servers
|
||||
|
||||
result: Apache config includes virtual servers for issued challenges
|
||||
"""
|
||||
mainConfig: string - file path to Apache user config file
|
||||
listSNITuple: list of tuples with form (addr, y, nonce, ext_oid)
|
||||
addr (string), y (byte array), nonce (hex string), ext_oid (string)
|
||||
key: string - file path to key
|
||||
|
||||
# TODO: Use ip address of existing vhost instead of relying on FQDN
|
||||
configText = "<IfModule mod_ssl.c> \n"
|
||||
for idx, lis in enumerate(listlistAddrs):
|
||||
configText += getConfigText(listSNITuple[idx][2], lis, key)
|
||||
configText += "</IfModule> \n"
|
||||
result: Apache config includes virtual servers for issued challenges
|
||||
"""
|
||||
|
||||
checkForApacheConfInclude(mainConfig, configurator)
|
||||
newConf = open(APACHE_CHALLENGE_CONF, 'w')
|
||||
newConf.write(configText)
|
||||
newConf.close()
|
||||
# TODO: Use ip address of existing vhost instead of relying on FQDN
|
||||
configText = "<IfModule mod_ssl.c> \n"
|
||||
for idx, lis in enumerate(listlistAddrs):
|
||||
configText += self.__getConfigText(self.listSNITuple[idx][2], lis, self.key)
|
||||
configText += "</IfModule> \n"
|
||||
|
||||
# Need to add NameVirtualHost IP_ADDR or does the chocolate install do this?
|
||||
def checkForApacheConfInclude(mainConfig, configurator):
|
||||
"""
|
||||
Adds chocolate challenge include file if it does not already exist
|
||||
within mainConfig
|
||||
|
||||
mainConfig: string - file path to main user apache config file
|
||||
self.checkForApacheConfInclude(mainConfig)
|
||||
newConf = open(APACHE_CHALLENGE_CONF, 'w')
|
||||
newConf.write(configText)
|
||||
newConf.close()
|
||||
|
||||
result: User Apache configuration includes chocolate sni challenge file
|
||||
"""
|
||||
if len(configurator.find_directive("Include", APACHE_CHALLENGE_CONF)) == 0:
|
||||
#print "Including challenge virtual host(s)"
|
||||
configurator.add_dir("/files" + mainConfig, "Include", APACHE_CHALLENGE_CONF)
|
||||
def checkForApacheConfInclude(self, mainConfig):
|
||||
"""
|
||||
Adds chocolate challenge include file if it does not already exist
|
||||
within mainConfig
|
||||
|
||||
def createChallengeCert(oid, ext, nonce, csr, key):
|
||||
"""
|
||||
Modifies challenge certificate configuration and calls openssl binary to create a certificate
|
||||
mainConfig: string - file path to main user apache config file
|
||||
|
||||
oid: string
|
||||
ext: string - hex z value
|
||||
nonce: string - hex
|
||||
csr: string - file path to csr
|
||||
key: string - file path to key
|
||||
result: User Apache configuration includes chocolate sni challenge file
|
||||
"""
|
||||
if len(self.configurator.find_directive("Include", APACHE_CHALLENGE_CONF)) == 0:
|
||||
#print "Including challenge virtual host(s)"
|
||||
self.configurator.add_dir("/files" + mainConfig, "Include", APACHE_CHALLENGE_CONF)
|
||||
|
||||
result: certificate created at getChocCertFile(nonce)
|
||||
"""
|
||||
def createChallengeCert(self, oid, ext, nonce, csr, key):
|
||||
"""
|
||||
Modifies challenge certificate configuration and calls openssl binary to create a certificate
|
||||
|
||||
updateCertConf(oid, ext)
|
||||
subprocess.call(["openssl", "x509", "-req", "-days", "21", "-extfile", CHOC_CERT_CONF, "-extensions", "v3_ca", "-signkey", key, "-out", getChocCertFile(nonce), "-in", csr], stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
|
||||
|
||||
oid: string
|
||||
ext: string - hex z value
|
||||
nonce: string - hex
|
||||
csr: string - file path to csr
|
||||
key: string - file path to key
|
||||
|
||||
def generateExtension(key, y):
|
||||
"""
|
||||
Generates z to be placed in certificate extension
|
||||
result: certificate created at getChocCertFile(nonce)
|
||||
"""
|
||||
|
||||
key: string - File path to key
|
||||
y: byte array
|
||||
updateCertConf(oid, ext)
|
||||
subprocess.call(["openssl", "x509", "-req", "-days", "21", "-extfile", CHOC_CERT_CONF, "-extensions", "v3_ca", "-signkey", key, "-out", getChocCertFile(nonce), "-in", csr], stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
|
||||
|
||||
result: returns z value
|
||||
"""
|
||||
|
||||
rsaPrivKey = M2Crypto.RSA.load_key(key)
|
||||
r = rsaPrivKey.private_decrypt(y, M2Crypto.RSA.pkcs1_oaep_padding)
|
||||
def generateExtension(self, key, y):
|
||||
"""
|
||||
Generates z to be placed in certificate extension
|
||||
|
||||
s = Random.get_random_bytes(S_SIZE)
|
||||
extHMAC = hmac.new(r, str(s), hashlib.sha256)
|
||||
return byteToHex(s) + extHMAC.hexdigest()
|
||||
key: string - File path to key
|
||||
y: byte array
|
||||
|
||||
def byteToHex(byteStr):
|
||||
"""
|
||||
Converts binary array to hex string
|
||||
|
||||
byteStr: byte array
|
||||
|
||||
result: returns hex representation of byteStr
|
||||
"""
|
||||
result: returns z value
|
||||
"""
|
||||
|
||||
return ''.join(["%02X" % ord(x) for x in byteStr]).strip()
|
||||
rsaPrivKey = M2Crypto.RSA.load_key(key)
|
||||
r = rsaPrivKey.private_decrypt(y, M2Crypto.RSA.pkcs1_oaep_padding)
|
||||
|
||||
#Searches for the first extension specified in binary
|
||||
def updateCertConf(oid, value):
|
||||
"""
|
||||
Updates the sni_challenge openssl certificate config file
|
||||
s = Random.get_random_bytes(S_SIZE)
|
||||
extHMAC = hmac.new(r, str(s), hashlib.sha256)
|
||||
return self.byteToHex(s) + extHMAC.hexdigest()
|
||||
|
||||
oid: string - ex. 1.3.3.7
|
||||
value string hex - value of OID
|
||||
def byteToHex(self, byteStr):
|
||||
"""
|
||||
Converts binary array to hex string
|
||||
|
||||
result: updated certificate config file
|
||||
"""
|
||||
byteStr: byte array
|
||||
|
||||
confOld = open(CHOC_CERT_CONF)
|
||||
confNew = open(CHOC_CERT_CONF + ".tmp", 'w')
|
||||
flag = False
|
||||
for line in confOld:
|
||||
if "=critical, DER:" in line:
|
||||
confNew.write(oid + "=critical, DER:" + value + "\n")
|
||||
flag = True
|
||||
else:
|
||||
confNew.write(line)
|
||||
if flag is False:
|
||||
print "Error: Could not find extension in CHOC_CERT_CONF"
|
||||
exit()
|
||||
confNew.close()
|
||||
confOld.close()
|
||||
remove(CHOC_CERT_CONF)
|
||||
move(CHOC_CERT_CONF + ".tmp", CHOC_CERT_CONF)
|
||||
result: returns hex representation of byteStr
|
||||
"""
|
||||
|
||||
def cleanup(listSNITuple, configurator):
|
||||
"""
|
||||
Remove all temporary changes necessary to perform the challenge
|
||||
|
||||
configurator: Configurator object
|
||||
listSNITuple: The initial challenge tuple
|
||||
return ''.join(["%02X" % ord(x) for x in byteStr]).strip()
|
||||
|
||||
result: Apache server is restored to the pre-challenge state
|
||||
"""
|
||||
configurator.revert_config()
|
||||
configurator.restart(True)
|
||||
remove_files(listSNITuple)
|
||||
|
||||
#Searches for the first extension specified in binary
|
||||
def updateCertConf(self, oid, value):
|
||||
"""
|
||||
Updates the sni_challenge openssl certificate config file
|
||||
|
||||
def remove_files(listSNITuple):
|
||||
"""
|
||||
Removes all of the temporary SNI files
|
||||
"""
|
||||
for tup in listSNITuple:
|
||||
remove(getChocCertFile(tup[2]))
|
||||
remove(APACHE_CHALLENGE_CONF)
|
||||
oid: string - ex. 1.3.3.7
|
||||
value string hex - value of OID
|
||||
|
||||
#main call
|
||||
def perform_sni_cert_challenge(listSNITuple, csr, key, configurator, quiet=False):
|
||||
"""
|
||||
Sets up and reloads Apache server to handle SNI challenges
|
||||
result: updated certificate config file
|
||||
"""
|
||||
|
||||
listSNITuple: List of tuples with form (addr, y, nonce, ext_oid)
|
||||
addr (string), y (byte array), nonce (hex string),
|
||||
ext_oid (string)
|
||||
csr: string - File path to chocolate csr
|
||||
key: string - File path to key
|
||||
configurator: Configurator obj
|
||||
"""
|
||||
# Save any changes to the configuration as a precaution
|
||||
# About to make temporary changes to the config
|
||||
configurator.save("Before performing sni_challenge")
|
||||
confOld = open(CHOC_CERT_CONF)
|
||||
confNew = open(CHOC_CERT_CONF + ".tmp", 'w')
|
||||
flag = False
|
||||
for line in confOld:
|
||||
if "=critical, DER:" in line:
|
||||
confNew.write(oid + "=critical, DER:" + value + "\n")
|
||||
flag = True
|
||||
else:
|
||||
confNew.write(line)
|
||||
if flag is False:
|
||||
print "Error: Could not find extension in CHOC_CERT_CONF"
|
||||
exit()
|
||||
confNew.close()
|
||||
confOld.close()
|
||||
remove(CHOC_CERT_CONF)
|
||||
move(CHOC_CERT_CONF + ".tmp", CHOC_CERT_CONF)
|
||||
|
||||
addresses = []
|
||||
default_addr = "*:443"
|
||||
for tup in listSNITuple:
|
||||
vhost = configurator.choose_virtual_host(tup[0])
|
||||
if vhost is None:
|
||||
print "No vhost exists with servername or alias of:", tup[0]
|
||||
print "No _default_:443 vhost exists"
|
||||
print "Please specify servernames in the Apache config"
|
||||
return False
|
||||
|
||||
if not configurator.make_server_sni_ready(vhost, default_addr):
|
||||
return False
|
||||
def cleanup(self):
|
||||
"""
|
||||
Remove all temporary changes necessary to perform the challenge
|
||||
|
||||
for a in vhost.addrs:
|
||||
if "_default_" in a:
|
||||
addresses.append([default_addr])
|
||||
break
|
||||
else:
|
||||
addresses.append(vhost.addrs)
|
||||
configurator: Configurator object
|
||||
listSNITuple: The initial challenge tuple
|
||||
|
||||
for tup in listSNITuple:
|
||||
ext = generateExtension(key, tup[1])
|
||||
createChallengeCert(tup[3], ext, tup[2], csr, key)
|
||||
|
||||
modifyApacheConfig(findApacheConfigFile(), listSNITuple, addresses, key, configurator)
|
||||
# Save reversible changes and restart the server
|
||||
configurator.save("SNI Challenge", True)
|
||||
configurator.restart(quiet)
|
||||
return True
|
||||
result: Apache server is restored to the pre-challenge state
|
||||
"""
|
||||
self.configurator.revert_config()
|
||||
self.configurator.restart(True)
|
||||
self.__remove_files()
|
||||
|
||||
|
||||
def __remove_files(self):
|
||||
"""
|
||||
Removes all of the temporary SNI files
|
||||
"""
|
||||
for tup in self.listSNITuple:
|
||||
remove(getChocCertFile(tup[2]))
|
||||
remove(APACHE_CHALLENGE_CONF)
|
||||
|
||||
#main call
|
||||
def perform(self, quiet=False):
|
||||
"""
|
||||
Sets up and reloads Apache server to handle SNI challenges
|
||||
|
||||
listSNITuple: List of tuples with form (addr, y, nonce, ext_oid)
|
||||
addr (string), y (byte array), nonce (hex string),
|
||||
ext_oid (string)
|
||||
csr: string - File path to chocolate csr
|
||||
key: string - File path to key
|
||||
configurator: Configurator obj
|
||||
"""
|
||||
# Save any changes to the configuration as a precaution
|
||||
# About to make temporary changes to the config
|
||||
self.configurator.save("Before performing sni_challenge")
|
||||
|
||||
addresses = []
|
||||
default_addr = "*:443"
|
||||
for tup in self.listSNITuple:
|
||||
vhost = self.configurator.choose_virtual_host(tup[0])
|
||||
if vhost is None:
|
||||
print "No vhost exists with servername or alias of:", tup[0]
|
||||
print "No _default_:443 vhost exists"
|
||||
print "Please specify servernames in the Apache config"
|
||||
return False
|
||||
|
||||
if not self.configurator.make_server_sni_ready(vhost, default_addr):
|
||||
return False
|
||||
|
||||
for a in vhost.addrs:
|
||||
if "_default_" in a:
|
||||
addresses.append([default_addr])
|
||||
break
|
||||
else:
|
||||
addresses.append(vhost.addrs)
|
||||
|
||||
for tup in self.listSNITuple:
|
||||
ext = self.generateExtension(self.key, tup[1])
|
||||
self.createChallengeCert(tup[3], ext, tup[2], self.csr, self.key)
|
||||
|
||||
self.modifyApacheConfig(self.findApacheConfigFile(), addresses, self.key)
|
||||
# Save reversible changes and restart the server
|
||||
self.configurator.save("SNI Challenge", True)
|
||||
self.configurator.restart(quiet)
|
||||
return True
|
||||
|
||||
# This main function is just used for testing
|
||||
def main():
|
||||
key = path.abspath("key.pem")
|
||||
csr = path.abspath("req.pem")
|
||||
logger.setLogger(sys.stdout)
|
||||
logger.setLogLevel(logger.INFO)
|
||||
|
||||
testkey = M2Crypto.RSA.load_key(key)
|
||||
|
||||
@@ -274,15 +291,15 @@ def main():
|
||||
|
||||
challenges = [("example.com", y, nonce, "1.3.3.7"), ("www.example.com",y2, nonce2, "1.3.3.7")]
|
||||
#challenges = [("127.0.0.1", y, nonce, "1.3.3.7"), ("localhost", y2, nonce2, "1.3.3.7")]
|
||||
if perform_sni_cert_challenge(challenges, csr, key, config):
|
||||
|
||||
sni_chall = SNI_Challenge(challenges, csr, key, config)
|
||||
if sni_chall.perform():
|
||||
# Waste some time without importing time module... just for testing
|
||||
for i in range(0, 12000):
|
||||
if i % 2000 == 0:
|
||||
print "Waiting:", i
|
||||
|
||||
print "Cleaning up"
|
||||
cleanup(challenges, config)
|
||||
sni_chall.cleanup()
|
||||
else:
|
||||
print "Failed SNI challenge..."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user