#!/usr/bin/python # -*- coding: utf-8 -*- import urllib, json, subprocess, argparse, re, sys import [...] from M2Crypto import BIO, Rand, SMIME from [...] [...] ssl_key = '/etc/ssl/private/mailcert-vpn.charite.de.key' ssl_cert = '/etc/ssl/certs/mailcert-vpn.charite.de.crt' def send_mail_ssl(sender, to, subject, text, files=[], attachments={}, bcc=[]): """ Sends SSL signed mail [...] """ if isinstance(to, str): to = [to] # create multipart message msg = MIMEMultipart() # attach message text as first attachment msg.attach( MIMEText(text, "plain", "utf-8") ) # attach files to be read from file system for file in files: part = MIMEBase('application', "octet-stream") part.set_payload( open(file,"rb").read() ) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file)) msg.attach(part) # attach files read from dictionary for name in attachments: part = MIMEBase('application', "octet-stream") part.set_payload(attachments[name]) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % name) msg.attach(part) # put message with attachments into SSL' I/O buffer msg_str = msg.as_string() buf = BIO.MemoryBuffer(msg_str) # load seed file for PRNG Rand.load_file('/tmp/randpool.dat', -1) smime = SMIME.SMIME() # load certificate smime.load_key(ssl_key, ssl_cert) # sign whole message p7 = smime.sign(buf, SMIME.PKCS7_DETACHED) # create buffer for final mail and write header out = BIO.MemoryBuffer() out.write('From: %s\n' % sender) out.write('To: %s\n' % COMMASPACE.join(to)) out.write('Date: %s\n' % formatdate(localtime=True)) out.write('Subject: %s\n' % subject) out.write('Auto-Submitted: %s\n' % 'auto-generated') out.write('X-Auto-Response-Suppress: %s\n' % 'OOF') # convert message back into string buf = BIO.MemoryBuffer(msg_str) # append signed message and original message to mail header smime.write(out, p7, buf) # load save seed file for PRNG Rand.save_file('/tmp/randpool.dat') # extend list of recipients with bcc addresses to.extend(bcc) # finally send mail p = Popen(["/usr/sbin/sendmail", "-fvpn@charite.de", "-oi", COMMASPACE.join(to)], stdin=PIPE, universal_newlines=True) p.communicate(out.read()) # BEGINNING OF SCRIPT if not os.geteuid() == 0: sys.exit('Script must be run as root') # Parse command-line arguments parser = argparse.ArgumentParser(description='Sends VPN configuration file to users') parser.add_argument('userinput', help='') parser.add_argument('mailaddress', nargs='?', help='') args = parser.parse_args() [...] is_mail = re.compile('^.+?\@.+') if is_mail.match(args.userinput): #print args.userinput + " is an email address" url = "http://vpnapi.charite.de/vpn/user/detailsbyemail/" + args.userinput else: #print args.userinput + " is a username" url = "http://vpnapi.charite.de/vpn/user/details/" + args.userinput #response = urllib.urlopen(url); response = urllib.urlopen(url, proxies={}); data = json.loads(response.read()) username = data.get('username') active = data.get('vpnActive') if args.mailaddress: if is_mail.match(args.mailaddress): #print args.mailaddress + " is an email address" email = args.mailaddress else: print args.mailaddress + " is an email address!" sys.exit(1) else: email = data.get('mail') if not username: print "Username does not exist" sys.exit(1) if not active: print "User is not active" sys.exit(1) if not email: print "Email is blank" sys.exit(1) # Encode email address if not blank! email = email.encode('ascii','ignore') #print username, email if os.path.isfile( "/opt/openvpn/ca/keys/" + username + ".crt"): #print "Cert for " + username + " exists" # Read in the text portion of the mail with open('/opt/openvpn/etc/sendcertagain-mailbody.txt', 'r') as myfile: text=myfile.read() # Set filenames for the attachment configfilename="charite-" + username + ".ovpn" # Define key material paths keyfilename="/opt/openvpn/ca/keys/" + username + ".key"; crtfilename="/opt/openvpn/ca/keys/" + username + ".crt"; cafilename="/opt/openvpn/ca/keys/ca.crt"; # Open key material with open('/opt/openvpn/etc/charite.ovpn.template', 'r') as myfile: configtemplatefile = myfile.read() with open(cafilename, 'r') as myfile: cafile = myfile.read() with open(keyfilename, 'r') as myfile: keyfile = myfile.read() with open(crtfilename, 'r') as myfile: crtfile = myfile.read() sender = str(Header("CharitÈ VPN administrator", "utf8")) + " " subject = Header("Configuration file to your CharitÈ VPN access","utf8") configfile = configtemplatefile + "\n" + cafile + "\n\n" + keyfile + "\n\n" + crtfile + "\n" send_mail_ssl(sender, email, subject, text, files=[], attachments={configfilename: configfile} ) print "Configuration file was sent to " + email + "." else: print "User " + username + " has no certificate" sys.exit(1) if os.path.isfile( "/opt/openvpn/ca/keys/" + username + ".crt"): #print "Cert for " + username + " exists" # Read in the text part of the mail with open('/opt/openvpn/etc/sendcertagain-mailbody.txt', 'r') as myfile: text=myfile.read() # Set attachment filenames configfilename="charite-" + username + ".ovpn" # Define key material paths keyfilename="/opt/openvpn/ca/keys/" + username + ".key"; crtfilename="/opt/openvpn/ca/keys/" + username + ".crt"; cafilename="/opt/openvpn/ca/keys/ca.crt"; # Open key material with open('/opt/openvpn/etc/charite.ovpn.template', 'r') as myfile: configtemplatefile = myfile.read() with open(cafilename, 'r') as myfile: cafile = myfile.read() with open(keyfilename, 'r') as myfile: keyfile = myfile.read() with open(crtfilename, 'r') as myfile: crtfile = myfile.read() sender = str(Header("CharitÈ VPN Administrator", "utf8")) + " " subject = Header("Configuration file to your CharitÈ VPN access","utf8") configfile = configtemplatefile + "\n" + cafile + "\n\n" + keyfile + "\n\n" + crtfile + "\n" send_mail_ssl(sender, email, subject, text, files=[], attachments={configfilename: configfile} ) print "Configuration file was sent to " + email + "." else: print "User " + username + " has no Certificate" sys.exit(1)