You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1033 lines
42 KiB
1033 lines
42 KiB
|
13 years ago
|
# -*- coding:utf-8 -*-
|
||
|
|
#
|
||
|
|
# vim:syntax=python:sw=4:ts=4:expandtab
|
||
|
|
|
||
|
|
#
|
||
|
|
# Copyright (C) Adelux - 2009
|
||
|
|
#
|
||
|
|
|
||
|
|
from django.db import models
|
||
|
|
from ovpnmanager.ovpnconsole import *
|
||
|
|
from django.forms import ModelForm
|
||
|
|
from django import forms
|
||
|
|
from django.utils.encoding import force_unicode, smart_str, smart_unicode
|
||
|
|
from django.conf import settings
|
||
|
|
from django.contrib.admin import widgets
|
||
|
|
from django.core.mail import send_mail
|
||
|
|
from django.contrib.auth.models import *
|
||
|
|
from django.utils.translation import ugettext as _
|
||
|
|
|
||
|
|
from ovpntools.ovpntools import *
|
||
|
|
from synctools.synctools import *
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import datetime
|
||
|
|
import tempfile
|
||
|
|
import re
|
||
|
|
import shutil
|
||
|
|
|
||
|
|
class OVPNSettings(models.Model):
|
||
|
|
work_dir = models.CharField(max_length=255, default="/tmp/ovpnmanager")
|
||
|
|
smtp_server = models.CharField(max_length=255, default="smtp.mydomain.com")
|
||
|
|
|
||
|
|
class OVPNSite(models.Model):
|
||
|
|
name = models.CharField(max_length=30,unique=True, verbose_name=_("name"))
|
||
|
|
locality = models.CharField(max_length=30, verbose_name=_("locality"))
|
||
|
|
|
||
|
|
# Private methods
|
||
|
|
def __unicode__(self):
|
||
|
|
return self.name
|
||
|
|
|
||
|
|
def _name_in_utf8(self):
|
||
|
|
""" Public method used to convert the name into utf8 string """
|
||
|
|
return smart_str(self.name)
|
||
|
|
|
||
|
|
# Public methods
|
||
|
|
def save(self):
|
||
|
|
""" Overload of public method used to save object in database """
|
||
|
|
super(OVPNSite, self).save()
|
||
|
|
|
||
|
|
def delete(self):
|
||
|
|
# Delete each authority from database
|
||
|
|
for ovpnauthority in self.ovpnauthority_set.all():
|
||
|
|
ovpnauthority.delete()
|
||
|
|
# Delete each server configuration files and dir
|
||
|
|
for ovpnserver in ovpnauthority.ovpnserver_set.all():
|
||
|
|
ovpnserver.delete()
|
||
|
|
# Remove tmp directory if exist
|
||
|
|
if os.path.isdir(settings.OUTPUT_DIR + "/" + self.name):
|
||
|
|
try:
|
||
|
|
os.rmdir(settings.OUTPUT_DIR + "/" + self.ovpnsite.name)
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
super(OVPNSite, self).delete()
|
||
|
|
|
||
|
|
class OVPNSiteForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNSite
|
||
|
|
|
||
|
|
class OVPNAuthority(models.Model):
|
||
|
|
|
||
|
|
RSA_SIZE_LIST = (
|
||
|
|
('1024','1024'),
|
||
|
|
)
|
||
|
|
|
||
|
|
name = models.CharField(max_length=30,verbose_name=_("Name"))
|
||
|
|
country = models.CharField(max_length=2, verbose_name=_("Country Code"))
|
||
|
|
state = models.CharField(max_length=30,verbose_name=_("State"))
|
||
|
|
city = models.CharField(max_length=30, verbose_name=_("City"))
|
||
|
|
organization = models.CharField(max_length=40, verbose_name=_("Organization"))
|
||
|
|
expiration_date = models.DateField(editable=False,blank=True)
|
||
|
|
creation_date = models.DateField(editable=False,auto_now=True)
|
||
|
|
valid_for = models.SmallIntegerField(verbose_name=_("Validity Period"), default=3650)
|
||
|
|
email = models.CharField(max_length=50, verbose_name=_("email"))
|
||
|
|
rsa_size = models.IntegerField(choices=RSA_SIZE_LIST, verbose_name=_("RSA Key Size"), default="1024")
|
||
|
|
is_valid = models.BooleanField(default=True, editable=False, blank=True)
|
||
|
|
ovpnsite = models.ForeignKey(OVPNSite, verbose_name=_("Site"))
|
||
|
|
|
||
|
|
# Certificates properties
|
||
|
|
work_dir = models.CharField(max_length=255,editable=False, blank=True, verbose_name=_("Workdir"))
|
||
|
|
key_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
crt_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
crl_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
dh_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
interkey_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
intercsr_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
intercrt_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
ossl_config_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
ca_index_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
ca_index_old_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
ca_index_attr_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
ca_serial_file = models.FilePathField(editable=False, blank=True)
|
||
|
|
ossl_config_content = models.TextField(editable=False, blank=True)
|
||
|
|
ca_content = models.TextField(editable=False, blank=True)
|
||
|
|
certificate_content = models.TextField(editable=False, blank=True)
|
||
|
|
inter_csr_content = models.TextField(editable=False, blank=True)
|
||
|
|
server_key_content = models.TextField(editable=False, blank=True)
|
||
|
|
ca_key_content = models.TextField(editable=False, blank=True)
|
||
|
|
crl_content = models.TextField(editable=False, blank=True)
|
||
|
|
dh_content = models.TextField(editable=False, blank=True)
|
||
|
|
ca_index = models.TextField(editable=False, blank=True)
|
||
|
|
ca_index_attr = models.TextField(editable=False, blank=True)
|
||
|
|
ca_index_old = models.TextField(editable=False, blank=True)
|
||
|
|
ca_serial = models.TextField(editable=False, blank=True)
|
||
|
|
ca_index_num = models.CharField(max_length=4,editable=False, blank=True)
|
||
|
|
|
||
|
|
## Methods
|
||
|
|
|
||
|
|
def __unicode__(self):
|
||
|
|
return self.name
|
||
|
|
|
||
|
|
# private methods
|
||
|
|
def create_authority_dir(self):
|
||
|
|
""" Private method used to create authority (sub)directory """
|
||
|
|
if not os.path.isdir(settings.OUTPUT_DIR):
|
||
|
|
os.mkdir(settings.OUTPUT_DIR)
|
||
|
|
if not os.path.isdir(settings.OUTPUT_DIR + "/" + self.ovpnsite.name):
|
||
|
|
os.mkdir(settings.OUTPUT_DIR + "/" + self.ovpnsite.name)
|
||
|
|
if not os.path.isdir(self.work_dir):
|
||
|
|
os.mkdir(self.work_dir)
|
||
|
|
|
||
|
|
# public methods
|
||
|
|
def create_ovpntools_object(self):
|
||
|
|
# create ovpntools object
|
||
|
|
ovpnca = OVPNCA()
|
||
|
|
ovpnca.commonName = self.name
|
||
|
|
ovpnca.country = self.country
|
||
|
|
ovpnca.city = self.city
|
||
|
|
ovpnca.organization = self.organization
|
||
|
|
ovpnca.validity_in_days = self.valid_for
|
||
|
|
ovpnca.email = self.email
|
||
|
|
ovpnca.keysize = self.rsa_size
|
||
|
|
ovpnca.certs_dir = self.work_dir
|
||
|
|
ovpnca.crtfile = self.crt_file
|
||
|
|
ovpnca.crlfile = self.crl_file
|
||
|
|
ovpnca.keyfile = self.key_file
|
||
|
|
ovpnca.interkeyfile = self.interkey_file
|
||
|
|
ovpnca.intercsrfile = self.intercsr_file
|
||
|
|
ovpnca.intercrtfile = self.intercrt_file
|
||
|
|
ovpnca.dhfile = self.dh_file
|
||
|
|
ovpnca.config_file = self.ossl_config_file
|
||
|
|
return ovpnca
|
||
|
|
|
||
|
|
def generate_authority(self):
|
||
|
|
""" private method used to create authority certificate"""
|
||
|
|
self.ovpnca = self.create_ovpntools_object()
|
||
|
|
# generate openssl config
|
||
|
|
self.ovpnca.generate_ossl_config()
|
||
|
|
self.ossl_config_content = self.ovpnca.read_ossl_config()
|
||
|
|
|
||
|
|
# generates and reads all CA certs, remove temporary files
|
||
|
|
self.ca_index_num = '00'
|
||
|
|
self.ovpnca.create_CA_certs()
|
||
|
|
self.ca_content = self.ovpnca.read_ca().rstrip('\n')
|
||
|
|
self.certificate_content = self.ovpnca.read_certificate().rstrip('\n')
|
||
|
|
self.server_key_content = self.ovpnca.read_key().rstrip('\n')
|
||
|
|
self.inter_csr_content = self.ovpnca.read_inter_csr().rstrip('\n')
|
||
|
|
self.ca_key_content = self.ovpnca.read_ca_key().rstrip('\n')
|
||
|
|
self.dh_content = self.ovpnca.read_dh().rstrip('\n')
|
||
|
|
self.crl_content = self.ovpnca.read_crl_verify().rstrip('\n')
|
||
|
|
self.ca_index = self.ovpnca.read_index().rstrip('\n')
|
||
|
|
self.ca_index_attr = self.ovpnca.read_index_attr().rstrip('\n')
|
||
|
|
self.ca_index_old = self.ovpnca.read_index_old().rstrip('\n')
|
||
|
|
self.ca_serial = self.ovpnca.read_serial().rstrip('\n')
|
||
|
|
# clean temporary files
|
||
|
|
self.ovpnca.clean_all()
|
||
|
|
self.clean_work_dir()
|
||
|
|
|
||
|
|
def write_authority_files(self):
|
||
|
|
# generate temporary authority files
|
||
|
|
self.create_authority_dir()
|
||
|
|
f = open(self.ossl_config_file,'w')
|
||
|
|
print >> f, self.ossl_config_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.crt_file,'w')
|
||
|
|
print >> f, self.ca_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.crl_file,'w')
|
||
|
|
print >> f, self.crl_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.intercrt_file,'w')
|
||
|
|
print >> f, self.certificate_content
|
||
|
|
f.close()
|
||
|
|
## converts ca_index in int
|
||
|
|
ca_index_num = int(self.ca_index_num)
|
||
|
|
f = open(self.work_dir + '/' + '%.2d.pem' % ca_index_num,'w')
|
||
|
|
print >> f, self.certificate_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.intercsr_file,'w')
|
||
|
|
print >> f, self.inter_csr_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.key_file,'w')
|
||
|
|
print >> f, self.ca_key_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.interkey_file,'w')
|
||
|
|
print >> f, self.server_key_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.dh_file,'w')
|
||
|
|
print >> f, self.dh_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.ca_index_file,'w')
|
||
|
|
print >> f, self.ca_index
|
||
|
|
f.close()
|
||
|
|
f = open(self.ca_index_old_file,'w')
|
||
|
|
print >> f, self.ca_index_old
|
||
|
|
f.close()
|
||
|
|
f = open(self.ca_index_attr_file,'w')
|
||
|
|
print >> f, self.ca_index_attr
|
||
|
|
f.close()
|
||
|
|
f = open(self.ca_serial_file,'w')
|
||
|
|
print >> f, self.ca_serial
|
||
|
|
f.close()
|
||
|
|
|
||
|
|
def save(self,force_insert=False,force_update=False):
|
||
|
|
""" Overload of public method used to save object in database """
|
||
|
|
|
||
|
|
if force_update is False:
|
||
|
|
# Calculates the expiration_date
|
||
|
|
self.expiration_date = datetime.datetime.today() + datetime.timedelta(days=self.valid_for)
|
||
|
|
|
||
|
|
# set country in upper-case
|
||
|
|
self.country = self.country.upper()
|
||
|
|
|
||
|
|
# sets non editable properties
|
||
|
|
self.isvalid = self.set_validity()
|
||
|
|
self.work_dir = settings.OUTPUT_DIR + "/" + self.ovpnsite.name + "/" + self.name
|
||
|
|
self.ossl_config_file = self.work_dir + '/openssl.cnf'
|
||
|
|
self.key_file = self.work_dir + '/' + self.name + '.key'
|
||
|
|
self.crt_file = self.work_dir + '/' + self.name + '.crt'
|
||
|
|
self.crl_file = self.work_dir + '/' + self.name + '.pem'
|
||
|
|
self.dh_file = self.work_dir + '/' + self.name + '_' + '%d.dh' % self.rsa_size
|
||
|
|
self.interkey_file = self.work_dir + '/' + self.name + '_inter.key'
|
||
|
|
self.intercsr_file = self.work_dir + '/' + self.name + '_inter.csr'
|
||
|
|
self.intercrt_file = self.work_dir + '/' + self.name + '_inter.crt'
|
||
|
|
self.ossl_config_file = self.work_dir + '/' + self.name + '_ssl.cnf'
|
||
|
|
self.ca_index_file = self.work_dir + '/' + 'index.txt'
|
||
|
|
self.ca_index_old_file = self.work_dir + '/' + 'index.txt.old'
|
||
|
|
self.ca_index_attr_file = self.work_dir + '/' + 'index.txt.attr'
|
||
|
|
self.ca_serial_file = self.work_dir + '/' + 'serial'
|
||
|
|
|
||
|
|
# creates directory for this authority
|
||
|
|
self.create_authority_dir()
|
||
|
|
# generate certificate of authority
|
||
|
|
self.generate_authority()
|
||
|
|
|
||
|
|
else:
|
||
|
|
force_insert = False
|
||
|
|
|
||
|
|
super(OVPNAuthority, self).save(force_insert,force_update)
|
||
|
|
|
||
|
|
def delete(self):
|
||
|
|
# Remove work dir if exist
|
||
|
|
if os.path.isdir(self.work_dir):
|
||
|
|
try:
|
||
|
|
shutil.rmtree(self.work_dir)
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
super(OVPNAuthority, self).delete()
|
||
|
|
|
||
|
|
def set_validity(self,isvalid=True):
|
||
|
|
self.is_valid = isvalid
|
||
|
|
|
||
|
|
def clean_work_dir(self):
|
||
|
|
if os.path.isdir(self.work_dir):
|
||
|
|
try:
|
||
|
|
shutil.rmtree(self.work_dir)
|
||
|
|
self.create_authority_dir()
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
|
||
|
|
class Meta:
|
||
|
|
unique_together = ("ovpnsite", "name")
|
||
|
|
|
||
|
|
class OVPNAuthorityForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNAuthority
|
||
|
|
|
||
|
|
class OVPNServer(models.Model):
|
||
|
|
PROTO_LIST = (
|
||
|
|
('tcp', 'tcp'),
|
||
|
|
('udp','udp')
|
||
|
|
)
|
||
|
|
|
||
|
|
DEVICE_LIST = (
|
||
|
|
('tun', 'tun'),
|
||
|
|
('tap', 'tap')
|
||
|
|
)
|
||
|
|
|
||
|
|
SERVER_MODE_LIST = (
|
||
|
|
('p2p', 'p2p'),
|
||
|
|
('srv', 'server')
|
||
|
|
)
|
||
|
|
|
||
|
|
STATUS_VERSION_LIST = (
|
||
|
|
('1', '1'),
|
||
|
|
('2', '2')
|
||
|
|
)
|
||
|
|
|
||
|
|
# Server configuration
|
||
|
|
ovpnauthority = models.ForeignKey(OVPNAuthority, verbose_name=_("OVPNAuthority"))
|
||
|
|
name = models.CharField(max_length=30, verbose_name=_("Server Name"))
|
||
|
|
openvpn_base_dir = models.CharField(max_length=255, verbose_name=_("OpenVPN Base Dir"))
|
||
|
|
server_config_dir = models.CharField(max_length=255, editable=False, blank=True)
|
||
|
|
client_config_dir = models.CharField(max_length=255, editable=False, blank=True)
|
||
|
|
is_configured = models.BooleanField(default=False, editable=False)
|
||
|
|
is_up_to_date = models.BooleanField(default=False, editable=False)
|
||
|
|
# OpenVPN Configuration
|
||
|
|
certs_dir = models.CharField(max_length=255, editable=False, blank=True)
|
||
|
|
server_config_content = models.TextField(editable=False, blank=True)
|
||
|
|
local_ip_address = models.IPAddressField(verbose_name=_("Local IP Address"))
|
||
|
|
public_ip_address = models.IPAddressField(verbose_name=_("Public IP Address"))
|
||
|
|
port = models.SmallIntegerField(default=1194, verbose_name=_("Port"))
|
||
|
|
protocol = models.CharField(max_length=3, choices=PROTO_LIST, default="TCP",verbose_name=_("Protocol"))
|
||
|
|
device = models.CharField(max_length=3, choices=DEVICE_LIST, default="TUN", verbose_name=_("Device"))
|
||
|
|
server_mode = models.CharField(max_length=3, choices=SERVER_MODE_LIST, default="srv", verbose_name=_("Server Mode"))
|
||
|
|
client_to_client = models.BooleanField(default=True, verbose_name=_("Client-to-CLient"))
|
||
|
|
vpn_network = models.IPAddressField()
|
||
|
|
vpn_mask = models.IPAddressField()
|
||
|
|
dns_list = models.TextField(blank="True", verbose_name=_("DNS List"))
|
||
|
|
suffix_dns = models.CharField(max_length=255, blank="True", verbose_name=_("DNS Suffix"))
|
||
|
|
wins_list = models.TextField(blank="True", verbose_name=_("WINS Server"))
|
||
|
|
routes_list = models.TextField(blank="True", verbose_name=_("Routes List"))
|
||
|
|
compress_data = models.BooleanField(default="True", verbose_name=_("CompressData"))
|
||
|
|
floating_server = models.BooleanField(default="True", verbose_name=_("FloatingServer"))
|
||
|
|
redirect_gw = models.BooleanField(default="True", verbose_name=_("RedirectGateway"))
|
||
|
|
log_file = models.CharField(max_length=100, verbose_name=("LogFile"))
|
||
|
|
log_verbosity = models.SmallIntegerField(default=3, verbose_name=_("Log Level"))
|
||
|
|
status_file = models.CharField(max_length=100, verbose_name=_("Status file"))
|
||
|
|
status_version = models.CharField(max_length="1", choices=STATUS_VERSION_LIST, default="2", verbose_name=_("Status Version"))
|
||
|
|
mute = models.SmallIntegerField(default=5, verbose_name=_("Mute"))
|
||
|
|
daemon_user = models.CharField(max_length=30, default="nobody", verbose_name=_("Daemon User"))
|
||
|
|
daemon_group = models.CharField(max_length=30, default="nogroup", verbose_name=_("Daemon Group"))
|
||
|
|
dns_name = models.CharField(max_length=50, blank=True, verbose_name=_("DNS Name"))
|
||
|
|
keep_alive = models.SmallIntegerField(default=10, verbose_name=_("Keep Alive"))
|
||
|
|
keep_alive_retry = models.SmallIntegerField(default=120, verbose_name=_("Keep Alive retry"))
|
||
|
|
mtu_test = models.BooleanField(default="True", verbose_name=_("Mtu Test"))
|
||
|
|
tls_server = models.BooleanField(default="True", verbose_name=_("TLS Server"))
|
||
|
|
max_clients = models.SmallIntegerField(default=100, verbose_name=_("Max Clients"))
|
||
|
|
persist_key = models.BooleanField(default="True", verbose_name=_("PersistKey"))
|
||
|
|
persist_tun = models.BooleanField(default="True", verbose_name=_("Persist Tun"))
|
||
|
|
management_address = models.IPAddressField(default="0.0.0.0", verbose_name=_("Management Addr"))
|
||
|
|
management_port = models.SmallIntegerField(default="5555", verbose_name=_("Management Port"))
|
||
|
|
|
||
|
|
def __unicode__(self):
|
||
|
|
return self.name
|
||
|
|
|
||
|
|
# private methods
|
||
|
|
|
||
|
|
# public methods
|
||
|
|
def save(self,force_insert=False,force_update=False):
|
||
|
|
""" Overload of public method used to save object in database """
|
||
|
|
|
||
|
|
# Generates config dir name
|
||
|
|
self.server_config_dir = self.openvpn_base_dir + '/' + self.name
|
||
|
|
|
||
|
|
## Creates OVPNConfig Object
|
||
|
|
ovpnserver_config = OVPNConfig()
|
||
|
|
ovpnserver_config.server_config_dir = self.server_config_dir
|
||
|
|
ovpnserver_config.client_config_dir = self.server_config_dir + '/' + 'ccd'
|
||
|
|
ovpnserver_config.ca_cert_file = self.certs_dir + '/' + self.ovpnauthority.name + '.crt'
|
||
|
|
ovpnserver_config.inter_cert_file = self.certs_dir + '/' + self.ovpnauthority.name + '_inter.crt'
|
||
|
|
ovpnserver_config.inter_key_file = self.certs_dir + '/' + self.ovpnauthority.name + '_inter.key'
|
||
|
|
ovpnserver_config.crl_verify_file = self.certs_dir + '/' + self.ovpnauthority.name + '.pem'
|
||
|
|
ovpnserver_config.dh_key_file = self.certs_dir + '/' + self.ovpnauthority.name + '_' + '%d.dh' % self.ovpnauthority.rsa_size
|
||
|
|
ovpnserver_config.server_mode = self.get_server_mode_display()
|
||
|
|
ovpnserver_config.client_to_client = self.client_to_client
|
||
|
|
ovpnserver_config.ip_address = self.local_ip_address
|
||
|
|
ovpnserver_config.port = self.port
|
||
|
|
ovpnserver_config.protocol = self.protocol
|
||
|
|
ovpnserver_config.device = self.device
|
||
|
|
ovpnserver_config.vpn_network = self.vpn_network
|
||
|
|
ovpnserver_config.vpn_mask = self.vpn_mask
|
||
|
|
ovpnserver_config.dns_list = self.dns_list
|
||
|
|
if len(self.suffix_dns) != 0:
|
||
|
|
ovpnserver_config.suffix_dns = self.suffix_dns
|
||
|
|
ovpnserver_config.wins_list = self.wins_list
|
||
|
|
ovpnserver_config.routes_list = self.routes_list
|
||
|
|
ovpnserver_config.compress_data = self.compress_data
|
||
|
|
ovpnserver_config.floating_server = self.floating_server
|
||
|
|
ovpnserver_config.redirect_gw = self.redirect_gw
|
||
|
|
ovpnserver_config.log_file = self.log_file
|
||
|
|
ovpnserver_config.log_verbosity = self.log_verbosity
|
||
|
|
ovpnserver_config.status_file = self.status_file
|
||
|
|
ovpnserver_config.status_version = self.status_version
|
||
|
|
ovpnserver_config.mute = self.mute
|
||
|
|
ovpnserver_config.daemon_user = self.daemon_user
|
||
|
|
ovpnserver_config.daemon_group = self.daemon_group
|
||
|
|
ovpnserver_config.dns_name = self.dns_name
|
||
|
|
ovpnserver_config.keep_alive = self.keep_alive
|
||
|
|
ovpnserver_config.keep_alive_retry = self.keep_alive_retry
|
||
|
|
ovpnserver_config.mtu_test = self.mtu_test
|
||
|
|
ovpnserver_config.tls_server = self.tls_server
|
||
|
|
ovpnserver_config.max_clients = self.max_clients
|
||
|
|
ovpnserver_config.persist_key = self.persist_key
|
||
|
|
ovpnserver_config.persist_tun = self.persist_tun
|
||
|
|
ovpnserver_config.management_address = self.management_address
|
||
|
|
ovpnserver_config.management_port = self.management_port
|
||
|
|
## generates server configuration
|
||
|
|
self.server_config_content = ovpnserver_config.generate_server_config()
|
||
|
|
|
||
|
|
## Sets non-editable values
|
||
|
|
self.client_config_dir = 'ccd'
|
||
|
|
self.certs_dir = 'certs'
|
||
|
|
|
||
|
|
self.is_up_to_date = False
|
||
|
|
super(OVPNServer, self).save(force_insert,force_update)
|
||
|
|
|
||
|
|
# generate all users' config
|
||
|
|
for current_user in self.ovpnuser_set.all():
|
||
|
|
current_user.generate_user_config()
|
||
|
|
super(OVPNUser, current_user).save(force_update=False, force_insert=False)
|
||
|
|
|
||
|
|
def write_ovpnserver_files(self,basedir):
|
||
|
|
## server configuration
|
||
|
|
f = open(basedir + '/' + self.name + '.conf', 'w')
|
||
|
|
print >> f, self.server_config_content
|
||
|
|
f.close()
|
||
|
|
## server certificates
|
||
|
|
# openssl config
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '_ssl.cnf', 'w')
|
||
|
|
print >> f, self.ovpnauthority.ossl_config_content
|
||
|
|
f.close()
|
||
|
|
# crt
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '.crt', 'w')
|
||
|
|
print >> f, self.ovpnauthority.ca_content
|
||
|
|
f.close()
|
||
|
|
# crl
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '.crl', 'w')
|
||
|
|
print >> f, self.ovpnauthority.crl_content
|
||
|
|
f.close()
|
||
|
|
# inter_crt
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '_inter.crt', 'w')
|
||
|
|
print >> f, self.ovpnauthority.certificate_content
|
||
|
|
f.close()
|
||
|
|
# pem
|
||
|
|
ca_index_num = int(self.ovpnauthority.ca_index_num)
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.ca_index_num + '.pem', 'w')
|
||
|
|
print >> f, self.ovpnauthority.certificate_content
|
||
|
|
f.close()
|
||
|
|
# inter key
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '_inter.key', 'w')
|
||
|
|
print >> f, self.ovpnauthority.server_key_content
|
||
|
|
f.close()
|
||
|
|
# authority pem
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '.pem', 'w')
|
||
|
|
print >> f, self.ovpnauthority.crl_content
|
||
|
|
f.close()
|
||
|
|
# rsa
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + self.ovpnauthority.name + '_' + '%d.dh' % self.ovpnauthority.rsa_size, 'w')
|
||
|
|
print >> f, self.ovpnauthority.dh_content
|
||
|
|
f.close()
|
||
|
|
# index
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + 'index.txt' , 'w')
|
||
|
|
print >> f, self.ovpnauthority.ca_index
|
||
|
|
f.close()
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + 'index.old' , 'w')
|
||
|
|
print >> f, self.ovpnauthority.ca_index_old
|
||
|
|
f.close()
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + 'index.attr' , 'w')
|
||
|
|
print >> f, self.ovpnauthority.ca_index_attr
|
||
|
|
f.close()
|
||
|
|
|
||
|
|
## create config and certificates for each user
|
||
|
|
for current_user in self.ovpnuser_set.all():
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + current_user.name + '.key', 'w')
|
||
|
|
print >> f, current_user.user_key_content
|
||
|
|
f.close()
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + current_user.name + '.csr', 'w')
|
||
|
|
print >> f, current_user.user_csr_content
|
||
|
|
f.close()
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + current_user.name + '.crt', 'w')
|
||
|
|
print >> f, current_user.user_crt_content
|
||
|
|
f.close()
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.certs_dir + '/' + current_user.name + '.crl', 'w')
|
||
|
|
print >> f, current_user.user_crl_content
|
||
|
|
f.close()
|
||
|
|
# generate user pkcs
|
||
|
|
ovpntools = self.ovpnauthority.create_ovpntools_object()
|
||
|
|
ovpntools.commonName = current_user.name
|
||
|
|
ovpntools.email = current_user.email
|
||
|
|
#ovpntools.certs_dir = basedir + '/' + self.name + '/' + self.certs_dir
|
||
|
|
ovpntools.generate_user_pkcs(current_user.name,current_user.password,basedir + '/' + self.name + '/' + self.certs_dir)
|
||
|
|
|
||
|
|
if current_user.extra_config:
|
||
|
|
f = open(basedir + '/' + self.name + '/' + self.client_config_dir + '/' + current_user.name, 'w')
|
||
|
|
print >> f, current_user.extra_config
|
||
|
|
f.close()
|
||
|
|
|
||
|
|
def submit_server_config(self):
|
||
|
|
''' submit all config files and certs '''
|
||
|
|
ovpnserversettings = self.ovpnserversettings
|
||
|
|
|
||
|
|
if ovpnserversettings.ovpnserver_type == "loc":
|
||
|
|
## empty dir, or create if don't exist
|
||
|
|
self.empty_dirs(self.openvpn_base_dir)
|
||
|
|
self.create_dirs(self.openvpn_base_dir)
|
||
|
|
## create server configuration file
|
||
|
|
self.write_ovpnserver_files(self.openvpn_base_dir)
|
||
|
|
## creates log and status path if not exist
|
||
|
|
|
||
|
|
## Remove temporary configuration
|
||
|
|
self.ovpnauthority.clean_work_dir()
|
||
|
|
output = 'Fichiers copies dans ' + self.openvpn_base_dir
|
||
|
|
|
||
|
|
elif ovpnserversettings.ovpnserver_type == "ssh":
|
||
|
|
## empty dir, or create if don't exist
|
||
|
|
self.empty_dirs(self.ovpnauthority.work_dir + '/' + self.name)
|
||
|
|
self.create_dirs(self.ovpnauthority.work_dir + '/' + self.name)
|
||
|
|
## Copy all configuration to temporary dir
|
||
|
|
self.write_ovpnserver_files(self.ovpnauthority.work_dir + '/' + self.name)
|
||
|
|
|
||
|
|
## Try to connect and copy file to server
|
||
|
|
# create synctools object
|
||
|
|
syncserver = OVPNServerSync(ovpnserversettings.connection_address, ovpnserversettings.connection_login, ovpnserversettings.connection_password)
|
||
|
|
syncserver.source_dir = self.ovpnauthority.work_dir + '/' + self.name
|
||
|
|
syncserver.dst_dir = self.openvpn_base_dir
|
||
|
|
syncserver.copy_method = 'ssh'
|
||
|
|
|
||
|
|
# sync temporary directory content with distant server
|
||
|
|
output = syncserver.sync()
|
||
|
|
|
||
|
|
## Remove temporary configuration
|
||
|
|
self.ovpnauthority.clean_work_dir()
|
||
|
|
|
||
|
|
self.is_up_to_date = True
|
||
|
|
super(OVPNServer, self).save(False, False)
|
||
|
|
return 'OK',output
|
||
|
|
|
||
|
|
def create_dirs(self, basedir):
|
||
|
|
if not os.path.isdir(basedir + '/' + self.name):
|
||
|
|
os.makedirs(basedir + '/' + self.name)
|
||
|
|
if not os.path.isdir(basedir + '/' + self.name + '/' + self.client_config_dir):
|
||
|
|
os.mkdir(basedir + '/' + self.name + '/' + self.client_config_dir)
|
||
|
|
if not os.path.isdir(basedir + '/' + self.name + '/' + self.certs_dir):
|
||
|
|
os.mkdir(basedir + '/' + self.name + '/' + self.certs_dir)
|
||
|
|
|
||
|
|
def empty_dirs(self, basedir):
|
||
|
|
# Clean certs dir
|
||
|
|
if os.path.exists(basedir + '/' + self.name + '/' + self.certs_dir):
|
||
|
|
for file in os.listdir(basedir + '/' + self.name + '/' + self.certs_dir):
|
||
|
|
os.remove(basedir + '/' + self.name + '/' + self.certs_dir + '/' + file)
|
||
|
|
os.rmdir(basedir + '/' + self.name + '/' + self.certs_dir)
|
||
|
|
# Clean clients config dir
|
||
|
|
if os.path.exists(basedir + '/' + self.name + self.client_config_dir):
|
||
|
|
for file in os.listdir(basedir + '/' + self.name + '/' + self.client_config_dir):
|
||
|
|
os.remove(basedir + '/' + self.name + '/' + self.client_config_dir + '/' + file)
|
||
|
|
os.rmdir(basedir + '/' + self.name + '/' + self.client_config_dir)
|
||
|
|
# Clean server_configuration dir
|
||
|
|
if os.path.exists(basedir + '/' + self.name + '.conf'):
|
||
|
|
os.remove(basedir + '/' + self.name + '.conf')
|
||
|
|
|
||
|
|
def delete(self):
|
||
|
|
# Empty dirs
|
||
|
|
self.empty_dirs(self.openvpn_base_dir)
|
||
|
|
# Remove each user from database
|
||
|
|
for ovpnuser in self.ovpnuser_set.all():
|
||
|
|
ovpnuser.delete()
|
||
|
|
super(OVPNServer, self).delete()
|
||
|
|
|
||
|
|
def get_server_status(self):
|
||
|
|
#ovpnserversettings = self.ovpnserversettings_set.all()[0]
|
||
|
|
ovpnserversettings = self.ovpnserversettings
|
||
|
|
ovpnserver_admin = OVPNServerAdmin()
|
||
|
|
ovpnserver_admin.server_type = ovpnserversettings.ovpnserver_type
|
||
|
|
ovpnserver_admin.init_script = ovpnserversettings.daemon_init_script
|
||
|
|
ovpnserver_admin.hostname = ovpnserversettings.connection_address
|
||
|
|
ovpnserver_admin.login = ovpnserversettings.connection_login
|
||
|
|
ovpnserver_admin.password = ovpnserversettings.connection_password
|
||
|
|
|
||
|
|
def get_connected_users(self):
|
||
|
|
#ovpnserversettings = self.ovpnserversettings_set.all()[0]
|
||
|
|
ovpnserversettings = self.ovpnserversettings
|
||
|
|
ovpnserver_admin = OVPNServerAdmin()
|
||
|
|
if ovpnserversettings.ovpnserver_type == 'ssh':
|
||
|
|
ovpnserver_admin.server_type = 'ssh'
|
||
|
|
ovpnserver_admin.init_script = ovpnserversettings.daemon_init_script
|
||
|
|
ovpnserver_admin.hostname = ovpnserversettings.connection_address
|
||
|
|
ovpnserver_admin.login = ovpnserversettings.connection_login
|
||
|
|
ovpnserver_admin.password = ovpnserversettings.connection_password
|
||
|
|
(ret, connected_users, error) = ovpnserver_admin.get_connected_users(self.status_file)
|
||
|
|
return connected_users
|
||
|
|
|
||
|
|
def get_connected_users_num(self):
|
||
|
|
return len(self.get_connected_users())
|
||
|
|
|
||
|
|
|
||
|
|
def restart_server(self):
|
||
|
|
#ovpnserversettings = self.ovpnserversettings_set.all()[0]
|
||
|
|
ovpnserversettings = self.ovpnserversettings
|
||
|
|
ovpnserver_admin = OVPNServerAdmin()
|
||
|
|
if ovpnserversettings.ovpnserver_type == 'ssh':
|
||
|
|
ovpnserver_admin.server_type = 'ssh'
|
||
|
|
ovpnserver_admin.init_script = ovpnserversettings.daemon_init_script
|
||
|
|
ovpnserver_admin.hostname = ovpnserversettings.connection_address
|
||
|
|
ovpnserver_admin.login = ovpnserversettings.connection_login
|
||
|
|
ovpnserver_admin.password = ovpnserversettings.connection_password
|
||
|
|
ovpnserver_admin.cmd_prefix = ovpnserversettings.prefix_command
|
||
|
|
(ret, stdout, stderr) = ovpnserver_admin.restart_server(self.name)
|
||
|
|
output = []
|
||
|
|
output.append(ret)
|
||
|
|
output.append(stdout)
|
||
|
|
output.append(stderr)
|
||
|
|
return output
|
||
|
|
|
||
|
|
def ovpnusers_sorted_by_name(self):
|
||
|
|
return self.ovpnuser_set.all().order_by('name')
|
||
|
|
|
||
|
|
def get_last_five_connhist(self):
|
||
|
|
return self.ovpnserverconnhist_set.all().order_by('-conn_date', '-date')[:5]
|
||
|
|
|
||
|
|
def get_connhist(self):
|
||
|
|
return self.ovpnserverconnhist_set.all().order_by('-date')
|
||
|
|
|
||
|
|
|
||
|
|
class OVPNServerForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNServer
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super(OVPNServerForm, self).__init__(*args, **kwargs)
|
||
|
|
self.fields['dns_list'].widget = forms.Textarea(attrs={'cols':'40', 'rows':'2'})
|
||
|
|
self.fields['wins_list'].widget = forms.Textarea(attrs={'cols':'40', 'rows':'2'})
|
||
|
|
self.fields['routes_list'].widget = forms.Textarea(attrs={'cols':'40', 'rows':'2'})
|
||
|
|
|
||
|
|
def clean_dns_list(self):
|
||
|
|
if self.cleaned_data:
|
||
|
|
data = self.cleaned_data.get('dns_list')
|
||
|
|
if data:
|
||
|
|
dns_list = data.split(',')
|
||
|
|
for dns_address in dns_list:
|
||
|
|
dns_address = dns_address.replace(" ","")
|
||
|
|
if not re.search("^\d+\.\d+\.\d+\.\d+$", dns_address):
|
||
|
|
raise forms.ValidationError("Value %s is not a valid address definition" % dns_address)
|
||
|
|
return data
|
||
|
|
|
||
|
|
def clean_wins_list(self):
|
||
|
|
if self.cleaned_data:
|
||
|
|
data = self.cleaned_data.get('wins_list')
|
||
|
|
if data:
|
||
|
|
wins_list = data.split(',')
|
||
|
|
for wins_address in wins_list:
|
||
|
|
wins_address = wins_address.replace(" ","")
|
||
|
|
if not re.search("^\d+\.\d+\.\d+\.\d+$", wins_address):
|
||
|
|
raise forms.ValidationError("Value %s is not a valid address definition" % wins_address)
|
||
|
|
return data
|
||
|
|
|
||
|
|
def clean_routes_list(self):
|
||
|
|
if self.cleaned_data:
|
||
|
|
data = self.cleaned_data.get('routes_list')
|
||
|
|
if data:
|
||
|
|
route_list = data.split(',')
|
||
|
|
for route in route_list:
|
||
|
|
route = route.replace(" ","")
|
||
|
|
if not re.search("^\d+\.\d+\.\d+\.\d+\/\d+\.\d+\.\d+\.\d+$", route):
|
||
|
|
raise forms.ValidationError("Value %s is not a valid network definition" % route)
|
||
|
|
return data
|
||
|
|
|
||
|
|
class OVPNServerConnHist(models.Model):
|
||
|
|
''' OVPNServer Connections history class '''
|
||
|
|
|
||
|
|
STATE_LIST = (
|
||
|
|
('c', 'connected'),
|
||
|
|
('d', 'disconnected'),
|
||
|
|
)
|
||
|
|
|
||
|
|
date = models.DateTimeField(auto_now=True, verbose_name=_("Date"))
|
||
|
|
conn_date = models.DateTimeField(auto_now=False, verbose_name=_("Connection"))
|
||
|
|
disc_date = models.DateTimeField(auto_now=False,blank=True, verbose_name=_("Disonnection"))
|
||
|
|
recv_from = models.CharField(max_length=128, verbose_name=_("Received from"))
|
||
|
|
user_name = models.CharField(max_length=255, verbose_name=_("User Name"))
|
||
|
|
real_ip = models.IPAddressField(verbose_name=_("Real IP"))
|
||
|
|
virt_ip = models.IPAddressField(verbose_name=_("VPN IP"))
|
||
|
|
brecv = models.CharField(max_length=255, verbose_name=_("Brecv"))
|
||
|
|
bsent = models.CharField(max_length=255, verbose_name=_("Bsent"))
|
||
|
|
connected_since = models.DateTimeField(verbose_name=_("Connected Since"))
|
||
|
|
state = models.CharField(max_length=50,choices=STATE_LIST, verbose_name=_("State"))
|
||
|
|
ovpnserver = models.ForeignKey(OVPNServer, verbose_name=_("OVPNServer"))
|
||
|
|
|
||
|
|
|
||
|
|
class OVPNServerSettings(models.Model):
|
||
|
|
''' OvpnServer Settings, used to configure server type, connections settings... '''
|
||
|
|
|
||
|
|
SERVER_TYPE_LIST = (
|
||
|
|
('loc', 'local'),
|
||
|
|
('ssh', 'Distant (ssh)')
|
||
|
|
)
|
||
|
|
|
||
|
|
default_email_message = """
|
||
|
|
Veuillez trouver ci-joint les fichiers de configuration de votre connexion VPN.
|
||
|
|
Ces fichiers sont à copier dans le répertoire de configuration du client.
|
||
|
|
* Client Windows :
|
||
|
|
Le client OpenVPN est à télécharger ici :
|
||
|
|
http://www.openvpn.net/release/openvpn-2.1_rc18-install.exe
|
||
|
|
Copier les fichiers ci-joints dans le répertoire c:\program files\openvpn\config\
|
||
|
|
* Client Linux :
|
||
|
|
Installer le client OpenVpn de votre distribution :
|
||
|
|
par exemple : apt-get install openvpn
|
||
|
|
copirer les fichiers ci-joint dans le répertoire /etc/openvpn/, en prenant soin de renommer le fichier .ovpn en .conf
|
||
|
|
|
||
|
|
Pour plus d'informations : http://openvpn.se/install.txt
|
||
|
|
"""
|
||
|
|
ovpnserver_type = models.CharField(max_length=3, choices=SERVER_TYPE_LIST, default="LOC", verbose_name=_("Server Type"))
|
||
|
|
connection_address = models.IPAddressField(blank=True,verbose_name=_("IP Address"))
|
||
|
|
connection_login = models.CharField(max_length=30, blank=True, verbose_name=_("Login"))
|
||
|
|
connection_password = models.CharField(max_length=30, blank=True, verbose_name=_("Password"))
|
||
|
|
daemon_init_script = models.CharField(max_length=255, default='/etc/init.d/openvpn', verbose_name=_("Init Script"))
|
||
|
|
prefix_command = models.CharField(max_length=255, blank=True, verbose_name=_("Prefix Cmd"))
|
||
|
|
email_subject = models.CharField(max_length=255,blank=False, default='Compte OpenVPN', verbose_name=_("Email Subject"))
|
||
|
|
email_message = models.TextField(blank=True, default=default_email_message, verbose_name=_("Email Message"))
|
||
|
|
ovpnserver = models.OneToOneField(OVPNServer, verbose_name=_("OVPNServer"))
|
||
|
|
ovpnagent_key = models.CharField(max_length=24, verbose_name=_("OVPNAgentKey"))
|
||
|
|
|
||
|
|
def save(self,force_insert=False,force_update=False):
|
||
|
|
if force_update is False:
|
||
|
|
self.ovpnserver.is_configured = True
|
||
|
|
super(OVPNServer, self.ovpnserver).save(force_update)
|
||
|
|
super(OVPNServerSettings, self).save(force_insert,force_update)
|
||
|
|
|
||
|
|
class OVPNServerSettingsForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNServerSettings
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super(OVPNServerSettingsForm, self).__init__(*args, **kwargs)
|
||
|
|
self.fields['email_message'].widget.attrs['cols'] = 100
|
||
|
|
|
||
|
|
class OVPNUser(models.Model):
|
||
|
|
name = models.CharField(max_length=30, verbose_name=_("Name"))
|
||
|
|
email = models.EmailField(verbose_name=_("Email"))
|
||
|
|
is_valid = models.BooleanField(editable=False,blank=True)
|
||
|
|
type = models.CharField(max_length=20, blank=True, verbose_name=_("Type"))
|
||
|
|
_country = models.CharField(max_length=2,editable=False,blank=True)
|
||
|
|
_state = models.CharField(max_length=30,editable=False,blank=True)
|
||
|
|
_city = models.CharField(max_length=30,editable=False,blank=True)
|
||
|
|
_organization = models.CharField(max_length=40,editable=False,blank=True)
|
||
|
|
_validity = models.DateField(editable=False,blank=True)
|
||
|
|
password = models.CharField(max_length=30, verbose_name=_("Password"))
|
||
|
|
password_validation = models.CharField(max_length=30, verbose_name=_("Confirm Password"))
|
||
|
|
extra_config = models.TextField(blank=True)
|
||
|
|
user_key_content = models.TextField(editable=False, blank=True)
|
||
|
|
user_csr_content = models.TextField(editable=False, blank=True)
|
||
|
|
user_crt_content = models.TextField(editable=False, blank=True)
|
||
|
|
user_crl_content = models.TextField(editable=False, blank=True)
|
||
|
|
user_cert_index = models.TextField(max_length=4,editable=False, blank=True)
|
||
|
|
config_content = models.TextField(editable=False, blank=True)
|
||
|
|
ovpnserver = models.ForeignKey(OVPNServer, verbose_name=_("OVPNServer"))
|
||
|
|
|
||
|
|
def __unicode__(self):
|
||
|
|
return self.name
|
||
|
|
|
||
|
|
# private methods
|
||
|
|
|
||
|
|
# public methods
|
||
|
|
|
||
|
|
def save(self,force_insert=False,force_update=False):
|
||
|
|
""" Overload of public method used to save object in database """
|
||
|
|
|
||
|
|
self.set_validity()
|
||
|
|
# set certificate values as of authority
|
||
|
|
self._country = self.ovpnserver.ovpnauthority.country
|
||
|
|
self._state = self.ovpnserver.ovpnauthority.state
|
||
|
|
self._city = self.ovpnserver.ovpnauthority.city
|
||
|
|
self._organization = self.ovpnserver.ovpnauthority.organization
|
||
|
|
self._validity = self.ovpnserver.ovpnauthority.expiration_date
|
||
|
|
# generate user certificates
|
||
|
|
self.generate_user_certificate()
|
||
|
|
|
||
|
|
self.generate_user_config()
|
||
|
|
|
||
|
|
self.ovpnserver.is_up_to_date = False
|
||
|
|
super(OVPNServer, self.ovpnserver).save()
|
||
|
|
|
||
|
|
super(OVPNUser, self).save(force_insert,force_update)
|
||
|
|
|
||
|
|
def set_validity(self,isvalid=True):
|
||
|
|
self.is_valid = isvalid
|
||
|
|
|
||
|
|
def generate_user_config(self):
|
||
|
|
# create ovpnconfig object
|
||
|
|
ovpnclient_config = OVPNConfig()
|
||
|
|
ovpnclient_config.ip_address = self.ovpnserver.public_ip_address
|
||
|
|
if len(self.ovpnserver.dns_name) != 0:
|
||
|
|
ovpnclient_config.dns_name = self.ovpnserver.dns_name
|
||
|
|
ovpnclient_config.port = self.ovpnserver.port
|
||
|
|
ovpnclient_config.protocol = self.ovpnserver.protocol
|
||
|
|
ovpnclient_config.device = self.ovpnserver.device
|
||
|
|
ovpnclient_config.keep_alive = self.ovpnserver.keep_alive
|
||
|
|
ovpnclient_config.compress_data = self.ovpnserver.compress_data
|
||
|
|
ovpnclient_config.tls_server = self.ovpnserver.tls_server
|
||
|
|
ovpnclient_config.client_pkcs_file = self.name + '-' + self.ovpnserver.ovpnauthority.ovpnsite.name + '-' + self.ovpnserver.ovpnauthority.name + '-' + self.ovpnserver.name + '.p12'
|
||
|
|
ovpnclient_config.log_verbosity = self.ovpnserver.log_verbosity
|
||
|
|
|
||
|
|
# generate client config file
|
||
|
|
self.config_content = ovpnclient_config.generate_client_config()
|
||
|
|
|
||
|
|
def generate_user_certificate(self):
|
||
|
|
# creates ovpntools object
|
||
|
|
ovpntools = self.ovpnserver.ovpnauthority.create_ovpntools_object()
|
||
|
|
ovpntools.commonName = self.name
|
||
|
|
ovpntools.email = self.email
|
||
|
|
|
||
|
|
# generate temporary authority files
|
||
|
|
self.ovpnserver.ovpnauthority.write_authority_files()
|
||
|
|
ovpntools.generate_ossl_config()
|
||
|
|
|
||
|
|
# generate user csr key
|
||
|
|
ovpntools.generate_user_csr_key(self.name)
|
||
|
|
self.user_csr_content = ovpntools.read_user_csr(self.name).rstrip('\n')
|
||
|
|
self.user_key_content = ovpntools.read_user_key(self.name).rstrip('\n')
|
||
|
|
|
||
|
|
# generate user crt
|
||
|
|
ovpntools.generate_user_crt(self.name)
|
||
|
|
self.user_crt_content = ovpntools.read_user_certificate(self.name).rstrip('\n')
|
||
|
|
|
||
|
|
# generate user crl
|
||
|
|
ovpntools.generate_user_crl(self.name)
|
||
|
|
self.user_crl_content = ovpntools.read_user_crl(self.name).rstrip('\n')
|
||
|
|
|
||
|
|
# read user certificate index
|
||
|
|
self.user_cert_index = ovpntools.read_user_cert_index()
|
||
|
|
|
||
|
|
# generate user pkcs
|
||
|
|
#ovpntools.generate_user_pkcs(self.name,self.password)
|
||
|
|
|
||
|
|
# update authority index and serial
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index = ovpntools.read_index().rstrip('\n')
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index_attr = ovpntools.read_index_attr().rstrip('\n')
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index_old = ovpntools.read_index_old().rstrip('\n')
|
||
|
|
self.ovpnserver.ovpnauthority.ca_serial = ovpntools.read_serial().rstrip('\n')
|
||
|
|
#self.ovpnserver.ovpnauthority.save(force_update=True)
|
||
|
|
super(OVPNAuthority,self.ovpnserver.ovpnauthority).save()
|
||
|
|
|
||
|
|
def revoke_user(self):
|
||
|
|
# generate temporary certs files
|
||
|
|
self.ovpnserver.ovpnauthority.write_authority_files()
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + self.name + '.key', 'w')
|
||
|
|
print >> f, self.user_key_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + self.name + '.csr', 'w')
|
||
|
|
print >> f, self.user_csr_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + self.name + '.crt', 'w')
|
||
|
|
print >> f, self.user_crt_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + self.user_cert_index + '.pem', 'w')
|
||
|
|
print >> f, self.user_crt_content
|
||
|
|
f.close()
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + self.name + '.crl', 'w')
|
||
|
|
print >> f, self.user_crl_content
|
||
|
|
f.close()
|
||
|
|
# creates ovpntools object
|
||
|
|
ovpntools = self.ovpnserver.ovpnauthority.create_ovpntools_object()
|
||
|
|
ovpntools.commonName = self.name
|
||
|
|
ovpntools.email = self.email
|
||
|
|
|
||
|
|
ovpntools.revoke_user(self.name)
|
||
|
|
self.is_valid = False;
|
||
|
|
|
||
|
|
# update authority index and serial
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index = ovpntools.read_index().rstrip('\n')
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index_attr = ovpntools.read_index_attr().rstrip('\n')
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index_old = ovpntools.read_index_old().rstrip('\n')
|
||
|
|
self.ovpnserver.ovpnauthority.ca_serial = ovpntools.read_serial().rstrip('\n')
|
||
|
|
super(OVPNAuthority, self.ovpnserver.ovpnauthority).save()
|
||
|
|
|
||
|
|
self.ovpnserver.is_up_to_date = False
|
||
|
|
super(OVPNServer, self.ovpnserver).save()
|
||
|
|
|
||
|
|
# save ovpnuser object
|
||
|
|
super(OVPNUser, self).save()
|
||
|
|
|
||
|
|
def notify_user(self, subject, message, copyto=None):
|
||
|
|
""" function used to send user, connexion parameters and certificate by email """
|
||
|
|
if copyto is not None:
|
||
|
|
self.email.append(copyto)
|
||
|
|
send_mail(subject, message, sender, self.email)
|
||
|
|
|
||
|
|
def delete(self):
|
||
|
|
# generate temporary certs files
|
||
|
|
self.ovpnserver.ovpnauthority.write_authority_files()
|
||
|
|
# delete the user's line
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + 'index.txt', 'r')
|
||
|
|
newlines = ''
|
||
|
|
# converts user_cert_index into hexa
|
||
|
|
user_cert_index_hex = '%.2X' % int(self.user_cert_index)
|
||
|
|
for line in f:
|
||
|
|
(flag, serial, serial2, id, type, cn) = line.split("\t")
|
||
|
|
#if user_cert_index_hex in line:
|
||
|
|
if id == user_cert_index_hex:
|
||
|
|
print "removed line %s" % line
|
||
|
|
else:
|
||
|
|
newlines += line
|
||
|
|
f.close()
|
||
|
|
f = open(self.ovpnserver.ovpnauthority.work_dir + '/' + 'index.txt', 'w')
|
||
|
|
print >> f, newlines
|
||
|
|
f.close()
|
||
|
|
|
||
|
|
# update authority index
|
||
|
|
# creates ovpntools object
|
||
|
|
ovpntools = self.ovpnserver.ovpnauthority.create_ovpntools_object()
|
||
|
|
ovpntools.commonName = self.name
|
||
|
|
ovpntools.email = self.email
|
||
|
|
|
||
|
|
self.ovpnserver.ovpnauthority.ca_index = ovpntools.read_index().rstrip('\n')
|
||
|
|
# save the ovpnathority
|
||
|
|
super(OVPNAuthority, self.ovpnserver.ovpnauthority).save()
|
||
|
|
|
||
|
|
self.ovpnserver.is_up_to_date = False
|
||
|
|
super(OVPNServer, self.ovpnserver).save()
|
||
|
|
|
||
|
|
# delete object
|
||
|
|
super(OVPNUser,self).delete()
|
||
|
|
|
||
|
|
class Meta:
|
||
|
|
unique_together = ("ovpnserver", "name")
|
||
|
|
|
||
|
|
|
||
|
|
class OVPNUserParamForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNUser
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super(OVPNUserParamForm, self).__init__(*args, **kwargs)
|
||
|
|
if self.instance:
|
||
|
|
#self.fields['password'].initial = OVPNUser.objects.get(id = self.instance.id).password
|
||
|
|
#self.fields['password_validation'].initial = OVPNUser.objects.get(id = self.instance.id).password
|
||
|
|
self.fields['password'].required = False
|
||
|
|
self.fields['password_validation'].required = False
|
||
|
|
self.fields['extra_config'].widget = forms.Textarea(attrs={'cols':'40', 'rows':'2'})
|
||
|
|
self.fields['password'].widget = forms.PasswordInput()
|
||
|
|
self.fields['password_validation'].widget = forms.PasswordInput()
|
||
|
|
|
||
|
|
def clean_password_validation(self):
|
||
|
|
if self.cleaned_data.get('password') != self.cleaned_data.get('password_validation'):
|
||
|
|
raise forms.ValidationError('Passwords must match.')
|
||
|
|
else:
|
||
|
|
return self.cleaned_data.get('password')
|
||
|
|
|
||
|
|
class OVPNUserForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNUser
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super(OVPNUserForm, self).__init__(*args, **kwargs)
|
||
|
|
self.fields['extra_config'].widget = forms.Textarea(attrs={'cols':'40', 'rows':'2'})
|
||
|
|
self.fields['password'].widget = forms.PasswordInput()
|
||
|
|
self.fields['password_validation'].widget = forms.PasswordInput()
|
||
|
|
|
||
|
|
def clean_password_validation(self):
|
||
|
|
if self.cleaned_data.get('password') != self.cleaned_data.get('password_validation'):
|
||
|
|
raise forms.ValidationError('Passwords must match.')
|
||
|
|
else:
|
||
|
|
return self.cleaned_data.get('password')
|
||
|
|
|
||
|
|
class OVPNUserPasswdForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = OVPNUser
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super(OVPNUserPasswdForm, self).__init__(*args, **kwargs)
|
||
|
|
self.fields['name'].widget = forms.TextInput(attrs={'readonly':''})
|
||
|
|
self.fields['email'].widget = forms.TextInput(attrs={'readonly':''})
|
||
|
|
self.fields['type'].widget = forms.TextInput(attrs={'readonly':''})
|
||
|
|
self.fields['extra_config'].widget = forms.Textarea(attrs={'cols':'40', 'rows':'2', 'readonly':''})
|
||
|
|
self.fields['password'].widget = forms.PasswordInput()
|
||
|
|
self.fields['password_validation'].widget = forms.PasswordInput()
|
||
|
|
|
||
|
|
def clean_password_validation(self):
|
||
|
|
if self.cleaned_data.get('password') != self.cleaned_data.get('password_validation'):
|
||
|
|
raise forms.ValidationError('Passwords must match.')
|
||
|
|
else:
|
||
|
|
return self.cleaned_data.get('password')
|
||
|
|
|
||
|
|
class OVPNLogs(models.Model):
|
||
|
|
""" Class used to manage log events in database """
|
||
|
|
date = models.DateTimeField(auto_now=True)
|
||
|
|
title = models.CharField(max_length=255)
|
||
|
|
message = models.TextField()
|
||
|
|
user = models.CharField(max_length=255)
|
||
|
|
related_object = models.CharField(max_length=255, default='Global')
|
||
|
|
related_object_id = models.PositiveIntegerField()
|
||
|
|
|
||
|
|
# overload of init function to auto save Logs when created
|
||
|
|
def __init__(self,*args,**kwargs):
|
||
|
|
super(OVPNLogs,self).__init__(*args,**kwargs)
|
||
|
|
self.save(force_insert=True)
|
||
|
|
|
||
|
|
class UserForm_temp(forms.Form):
|
||
|
|
first_name = forms.CharField()
|
||
|
|
last_name = forms.CharField()
|
||
|
|
email = forms.EmailField()
|
||
|
|
username = forms.CharField()
|
||
|
|
password = forms.CharField(widget=forms.PasswordInput(render_value=False))
|
||
|
|
|
||
|
|
def save(self):
|
||
|
|
new_user = User.objects.create_user(username=self.cleaned_data['username'],
|
||
|
|
email=self.cleaned_data['email'],
|
||
|
|
password=self.cleaned_data['password'])
|
||
|
|
new_user.first_name = self.cleaned_data['first_name']
|
||
|
|
new_user.last_name = self.cleaned_data['last_name']
|
||
|
|
new_user.is_active = False
|
||
|
|
new_user.save()
|
||
|
|
return new_user
|
||
|
|
|
||
|
|
class UserForm(forms.ModelForm):
|
||
|
|
class Meta:
|
||
|
|
model = User
|
||
|
|
|
||
|
|
password = forms.CharField(_('password'))
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super(UserForm, self).__init__(*args, **kwargs)
|
||
|
|
self.fields['password'].widget = forms.PasswordInput()
|
||
|
|
|
||
|
|
def clean_password(self):
|
||
|
|
import random
|
||
|
|
algo = 'sha1'
|
||
|
|
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
|
||
|
|
hsh = get_hexdigest(algo, salt, self.cleaned_data.get('password'))
|
||
|
|
hash_passwd = '%s$%s$%s' % (algo, salt, hsh)
|
||
|
|
return hash_passwd
|
||
|
|
|