begin to handle clientside payment, documentation added for configurator

This commit is contained in:
James Kasten 2012-11-07 14:35:51 -05:00
parent 8ef69f0c6b
commit 1692776be9
3 changed files with 37 additions and 22 deletions

View file

@ -13,6 +13,7 @@ import getopt
from trustify.protocol.chocolate_pb2 import chocolatemessage
from trustify.client.sni_challenge import SNI_Challenge
from trustify.client.payment_challenge import Payment_Challenge
from trustify.client import configurator
from trustify.client import logger
from trustify.client.CONFIG import difficulty, cert_file, chain_file
@ -26,7 +27,6 @@ allow_raw_ipv6_server = False
opts = getopt.getopt(sys.argv[1:], "", ["text", "privkey=", "csr=", "server="])
curses = True
shower = None
csr = None
privkey = None
server = None
@ -280,8 +280,17 @@ def challenge_factory(r, req_filepath, key_filepath, config):
dvsni_nonce, dvsni_y, dvsni_ext = chall.data
sni_todo.append( (chall.name, dvsni_y, dvsni_nonce, dvsni_ext) )
dn.append(chall.name)
# TODO: This domain name list is inelegant and the info should be
# gathered from the challenge itself
dn.append(chall.name)
if chall.type == r.Payment:
url, reason = chall.data
challenges.append(Payment_Challenge(url, reason))
if sni_todo:
# SNI_Challenge can satisfy many sni challenges at once so only
# one "challenge" is issued for all sni_challenges
challenges.append(SNI_Challenge(sni_todo, req_filepath, key_filepath, config))
logger.debug(sni_todo)
@ -408,7 +417,6 @@ def authenticate():
config = configurator.Configurator()
if not names:
#names = ["example.com", "www.example.com", "foo.example.com"]
names = config.get_all_names()
if curses:
@ -416,7 +424,6 @@ def authenticate():
choice_of_ca()
logger.setLogger(logger.NcursesLogger())
logger.setLogLevel(logger.INFO)
#shower = progress_shower()
else:
logger.setLogger(sys.stdout)
logger.setLogLevel(logger.INFO)

View file

@ -111,7 +111,8 @@ class Configurator(object):
returns: VH object
TODO: This should return list if no obvious answer is presented
"""
# TODO: TEST
# Allows for domain names to be associated with a virtual host
# Client isn't using create_dn_server_assoc(self, dn, vh) yet
for dn, vh in self.assoc:
if dn == name:
return vh
@ -126,6 +127,8 @@ class Configurator(object):
tup = a.partition(":")
if tup[0] == name and tup[2] == "443":
return v
# No matches, search for the default
for v in self.vhosts:
for a in v.addrs:
if a == "_default_:443":
@ -164,7 +167,7 @@ class Configurator(object):
Helper function for get_virtual_hosts()
"""
# This is case sensitive, but Apache is case insensitve
# Spent a bunch of time trying to get case insensitive search
# Spent 2 days trying to get case insensitive search to work
# it should be possible as of .7 with /i or 'append i' but I have been
# unsuccessful thus far
nameMatch = self.aug.match(host.path + "//*[self::directive=~regexp('[sS]erver[nN]ame')] | " + host.path + "//*[self::directive=~regexp('[sS]erver[aA]lias')]")
@ -174,7 +177,6 @@ class Configurator(object):
host.add_name(self.aug.get(arg))
# Test this new setup
def __create_vhost(self, path):
addrs = []
args = self.aug.match(path + "/arg")
@ -208,7 +210,7 @@ class Configurator(object):
"""
# search for NameVirtualHost directive for ip_addr
# check httpd.conf, ports.conf,
# note ip_addr can be FQDN
# note ip_addr can be FQDN although Apache does not recommend it
paths = self.find_directive("NameVirtualHost", None)
name_vh = []
for p in paths:
@ -235,7 +237,8 @@ class Configurator(object):
def add_name_vhost(self, addr):
"""
Adds NameVirtualHost directive for given address
Directive is added to ports.conf unless
Directive is added to ports.conf unless the file doesn't exist
It is added to httpd.conf as a backup
"""
aug_file_path = "/files" + SERVER_ROOT + "ports.conf"
self.add_dir_to_ifmodssl(aug_file_path, "NameVirtualHost", addr)
@ -371,6 +374,8 @@ class Configurator(object):
self.parse_file(arg)
# Argument represents an fnmatch regular expression, convert it
# Split up the path and convert each into an Augeas accepted regex
# then reassemble
if "*" in arg or "?" in arg:
postfix = ""
splitArg = arg.split("/")
@ -448,6 +453,7 @@ class Configurator(object):
self.add_dir(vh_p[0], "SSLCertificateFile", "/etc/ssl/certs/ssl-cert-snakeoil.pem")
self.add_dir(vh_p[0], "SSLCertificateKeyFile", "/etc/ssl/private/ssl-cert-snakeoil.key")
self.add_dir(vh_p[0], "Include", CONFIG_DIR + "options-ssl.conf")
# reload configurator vhosts
self.vhosts = self.get_virtual_hosts()
@ -546,22 +552,32 @@ LogLevel warn \n\
</VirtualHost>\n"
# Write out the file
# This is the default name
redirect_filename = "trustify-redirect.conf"
# See if a more appropriate name can be applied
if len(ssl_vhost.names) > 0:
# Sanity check...
# make sure servername doesn't exceed filename length restriction
if ssl_vhost.names[0] < (255-23):
redirect_filename = "trustify-redirect-" + ssl_vhost.names[0] + ".conf"
# Write out file
with open(SERVER_ROOT+"sites-available/"+redirect_filename, 'w') as f:
f.write(redirect_file)
logger.info("Created redirect file: " + redirect_filename)
# -- Now update data structures to reflect the change --
# Make sure that checkpoint data will
# remove the file if rollback is required
self.new_files.append(redirect_filename)
self.aug.load()
# Make a new vhost data structure and add it to the lists
new_fp = SERVER_ROOT + "sites-available/" + redirect_filename
new_vhost = self.__create_vhost("/files" + new_fp)
self.vhosts.add(new_vhost)
# Finally create documentation for the change
self.save_notes += 'Created a port 80 vhost, %s, for redirection to ssl vhost %s\n' % (new_vhost.file, ssl_vhost.file)
return True, new_vhost
@ -657,6 +673,10 @@ LogLevel warn \n\
return cert_key_pairs
def get_file_path(self, vhost_path):
"""
Takes in Augeas path and returns the file name
"""
# Strip off /files
avail_fp = vhost_path[6:]
# This can be optimized...
@ -745,6 +765,7 @@ LogLevel warn \n\
self.aug.load()
def save_apache_config(self):
# Not currently used
# Should be safe because it is a protected directory
shutil.copytree(SERVER_ROOT, BACKUP_DIR + "apache2-" + str(time.time()))

View file

@ -11,7 +11,6 @@ class Singleton(object):
cls, *args, **kwargs)
return cls._instance
# log levels
TRACE=5
DEBUG=4
@ -22,8 +21,6 @@ FATAL=0
NONE=-1
class Logger(Singleton):
debugLevelStr = {TRACE:'TRACE', DEBUG:'DEBUG', INFO:'INFO', \
WARN:'WARN', ERROR:'ERROR', FATAL:'FATAL'}
@ -42,8 +39,6 @@ class Logger(Singleton):
return time.strftime("%b %d %Y %H:%M:%S", time.localtime(t)) + ('%.03f' % (t - int(t)))[1:]
class FileLogger(Logger):
def __init__(self, outfile):
self.outfile = outfile
@ -53,8 +48,6 @@ class FileLogger(Logger):
msg = "%s [%s] %s\n" % (self.timefmt(), self.debugLevel(level), data)
self.outfile.write(msg)
import dialog
class NcursesLogger(Logger):
@ -75,11 +68,6 @@ class NcursesLogger(Logger):
def log(self, level, data):
self.add(data + "\n")
log_instance = None
def setLogger(log_inst):
@ -117,7 +105,6 @@ def none(data):
# Uh...what?
pass
if __name__ == "__main__":
# Unit test/example usage:
import logger