2012-10-23 17:28:35 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2013-07-06 09:42:26 +02:00
|
|
|
""" License
|
|
|
|
|
|
|
|
Copyright (C) 2013 YunoHost
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as published
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program; if not, see http://www.gnu.org/licenses
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
""" yunohost_tools.py
|
2013-07-06 10:17:16 +02:00
|
|
|
|
|
|
|
Specific tools
|
2013-07-06 09:42:26 +02:00
|
|
|
"""
|
2012-10-26 15:26:50 +02:00
|
|
|
import os
|
|
|
|
import sys
|
2012-10-23 17:28:35 +02:00
|
|
|
import yaml
|
2012-10-26 15:26:50 +02:00
|
|
|
import re
|
2012-10-27 17:06:43 +02:00
|
|
|
import getpass
|
2013-07-06 14:58:18 +02:00
|
|
|
import subprocess
|
2013-07-07 11:30:21 +02:00
|
|
|
import requests
|
2013-07-07 11:54:10 +02:00
|
|
|
import json
|
2014-02-05 02:01:03 +01:00
|
|
|
from domain import domain_add, domain_list
|
|
|
|
from dyndns import dyndns_subscribe
|
|
|
|
from backup import backup_init
|
|
|
|
from app import app_ssowatconf
|
|
|
|
|
2014-02-24 19:11:09 +01:00
|
|
|
from moulinette.core.helpers import YunoHostError, YunoHostLDAP, validate, colorize, get_required_args, win_msg
|
2012-10-27 17:06:43 +02:00
|
|
|
|
2013-10-10 12:52:21 +02:00
|
|
|
|
2013-07-07 09:38:18 +02:00
|
|
|
def tools_ldapinit(password=None):
|
2012-10-27 17:06:43 +02:00
|
|
|
"""
|
2013-07-06 10:17:16 +02:00
|
|
|
YunoHost LDAP initialization
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2012-10-27 17:06:43 +02:00
|
|
|
|
|
|
|
"""
|
2012-11-09 18:04:15 +01:00
|
|
|
with YunoHostLDAP() as yldap:
|
2012-10-26 15:26:50 +02:00
|
|
|
|
2013-02-26 20:36:37 +01:00
|
|
|
with open('ldap_scheme.yml') as f:
|
2012-11-09 18:04:15 +01:00
|
|
|
ldap_map = yaml.load(f)
|
2012-10-23 17:28:35 +02:00
|
|
|
|
2012-11-09 18:04:15 +01:00
|
|
|
for rdn, attr_dict in ldap_map['parents'].items():
|
2013-11-19 10:57:42 +01:00
|
|
|
try: yldap.add(rdn, attr_dict)
|
|
|
|
except: pass
|
2012-10-23 18:10:39 +02:00
|
|
|
|
2013-06-25 13:25:18 +02:00
|
|
|
for rdn, attr_dict in ldap_map['children'].items():
|
2013-11-19 10:57:42 +01:00
|
|
|
try: yldap.add(rdn, attr_dict)
|
|
|
|
except: pass
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2012-11-09 18:04:15 +01:00
|
|
|
admin_dict = {
|
|
|
|
'cn': 'admin',
|
|
|
|
'uid': 'admin',
|
|
|
|
'description': 'LDAP Administrator',
|
|
|
|
'gidNumber': '1007',
|
|
|
|
'uidNumber': '1007',
|
|
|
|
'homeDirectory': '/home/admin',
|
|
|
|
'loginShell': '/bin/bash',
|
2013-12-18 17:16:06 +01:00
|
|
|
'objectClass': ['organizationalRole', 'posixAccount', 'simpleSecurityObject'],
|
|
|
|
'userPassword': 'yunohost'
|
2012-11-09 18:04:15 +01:00
|
|
|
}
|
|
|
|
|
2013-07-06 17:27:24 +02:00
|
|
|
yldap.update('cn=admin', admin_dict)
|
|
|
|
|
2012-10-29 16:06:46 +01:00
|
|
|
win_msg(_("LDAP has been successfully initialized"))
|
2012-10-26 15:26:50 +02:00
|
|
|
|
2012-10-27 17:06:43 +02:00
|
|
|
|
2013-02-26 20:36:37 +01:00
|
|
|
def tools_adminpw(old_password, new_password):
|
2012-10-27 17:06:43 +02:00
|
|
|
"""
|
|
|
|
Change admin password
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2013-07-06 10:17:16 +02:00
|
|
|
Keyword argument:
|
2012-11-29 15:00:33 +01:00
|
|
|
new_password
|
2013-10-31 11:21:59 +01:00
|
|
|
old_password
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2012-10-27 17:06:43 +02:00
|
|
|
"""
|
2012-10-26 15:26:50 +02:00
|
|
|
# Validate password length
|
2012-11-29 15:00:33 +01:00
|
|
|
if len(new_password) < 4:
|
2012-10-26 15:26:50 +02:00
|
|
|
raise YunoHostError(22, _("Password is too short"))
|
|
|
|
|
2013-12-18 17:16:06 +01:00
|
|
|
old_password.replace('"', '\\"')
|
|
|
|
old_password.replace('&', '\\&')
|
|
|
|
new_password.replace('"', '\\"')
|
|
|
|
new_password.replace('&', '\\&')
|
|
|
|
result = os.system('ldappasswd -h localhost -D cn=admin,dc=yunohost,dc=org -w "'+ old_password +'" -a "'+ old_password +'" -s "' + new_password + '"')
|
2013-07-06 14:58:18 +02:00
|
|
|
|
2013-12-18 17:16:06 +01:00
|
|
|
if result == 0:
|
2012-10-29 16:06:46 +01:00
|
|
|
win_msg(_("Admin password has been changed"))
|
2012-10-25 21:17:26 +02:00
|
|
|
else:
|
|
|
|
raise YunoHostError(22, _("Invalid password"))
|
2012-10-27 17:06:43 +02:00
|
|
|
|
|
|
|
|
2013-07-07 11:13:21 +02:00
|
|
|
def tools_maindomain(old_domain, new_domain, dyndns=False):
|
2012-10-27 17:06:43 +02:00
|
|
|
"""
|
2013-07-06 10:17:16 +02:00
|
|
|
Main domain change tool
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2013-07-06 10:17:16 +02:00
|
|
|
Keyword argument:
|
2012-11-29 15:00:33 +01:00
|
|
|
new_domain
|
2013-10-31 11:21:59 +01:00
|
|
|
old_domain
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2012-10-27 17:06:43 +02:00
|
|
|
"""
|
2013-06-08 19:46:15 +02:00
|
|
|
|
2012-11-29 15:00:33 +01:00
|
|
|
if not old_domain:
|
2013-04-29 11:54:57 +02:00
|
|
|
with open('/etc/yunohost/current_host', 'r') as f:
|
2012-11-29 15:00:33 +01:00
|
|
|
old_domain = f.readline().rstrip()
|
2012-10-27 17:06:43 +02:00
|
|
|
|
2012-11-29 15:00:33 +01:00
|
|
|
validate(r'^([a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)(\.[a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)*(\.[a-zA-Z]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)$', old_domain)
|
2012-10-26 15:26:50 +02:00
|
|
|
|
|
|
|
config_files = [
|
2013-06-09 22:44:23 +02:00
|
|
|
'/etc/postfix/main.cf',
|
2013-06-10 22:06:02 +02:00
|
|
|
'/etc/metronome/metronome.cfg.lua',
|
2012-10-27 17:06:43 +02:00
|
|
|
'/etc/dovecot/dovecot.conf',
|
2013-05-03 12:10:39 +02:00
|
|
|
'/usr/share/yunohost/yunohost-config/others/startup',
|
2013-08-04 12:34:40 +02:00
|
|
|
'/home/yunohost.backup/tahoe/tahoe.cfg'
|
2014-02-11 10:30:27 +01:00
|
|
|
'/etc/amavis/conf.d/05-node_id'
|
2012-10-26 15:26:50 +02:00
|
|
|
]
|
|
|
|
|
2013-02-28 11:24:48 +01:00
|
|
|
config_dir = []
|
2012-10-26 15:26:50 +02:00
|
|
|
|
|
|
|
for dir in config_dir:
|
|
|
|
for file in os.listdir(dir):
|
|
|
|
config_files.append(dir + '/' + file)
|
|
|
|
|
|
|
|
for file in config_files:
|
|
|
|
with open(file, "r") as sources:
|
|
|
|
lines = sources.readlines()
|
|
|
|
with open(file, "w") as sources:
|
|
|
|
for line in lines:
|
2012-11-29 15:00:33 +01:00
|
|
|
sources.write(re.sub(r''+ old_domain +'', new_domain, line))
|
2012-10-26 15:26:50 +02:00
|
|
|
|
2013-10-17 11:45:02 +02:00
|
|
|
domain_add([new_domain], main=True)
|
2013-02-27 22:11:10 +01:00
|
|
|
|
2013-06-08 20:26:23 +02:00
|
|
|
os.system('rm /etc/ssl/private/yunohost_key.pem')
|
|
|
|
os.system('rm /etc/ssl/certs/yunohost_crt.pem')
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2013-02-28 12:03:51 +01:00
|
|
|
command_list = [
|
2013-06-08 19:46:15 +02:00
|
|
|
'ln -s /etc/yunohost/certs/'+ new_domain +'/key.pem /etc/ssl/private/yunohost_key.pem',
|
|
|
|
'ln -s /etc/yunohost/certs/'+ new_domain +'/crt.pem /etc/ssl/certs/yunohost_crt.pem',
|
2013-04-29 11:54:57 +02:00
|
|
|
'echo '+ new_domain +' > /etc/yunohost/current_host',
|
2013-10-17 11:38:55 +02:00
|
|
|
'service nginx restart',
|
2013-06-09 15:47:47 +02:00
|
|
|
'service metronome restart',
|
2013-07-06 19:36:19 +02:00
|
|
|
'service postfix restart',
|
2013-11-19 10:56:09 +01:00
|
|
|
'service dovecot restart'
|
2013-02-28 12:03:51 +01:00
|
|
|
]
|
|
|
|
|
2013-11-19 10:56:09 +01:00
|
|
|
try:
|
|
|
|
with open('/etc/yunohost/light') as f: pass
|
|
|
|
except IOError:
|
2013-11-19 11:18:13 +01:00
|
|
|
command_list.append('service amavis restart')
|
2013-11-21 19:08:53 +01:00
|
|
|
#command_list.append('service tahoe-lafs restart')
|
2013-11-19 10:56:09 +01:00
|
|
|
|
2013-02-28 12:03:51 +01:00
|
|
|
for command in command_list:
|
|
|
|
if os.system(command) != 0:
|
|
|
|
raise YunoHostError(17, _("There were a problem during domain changing"))
|
|
|
|
|
2013-07-07 11:13:21 +02:00
|
|
|
if dyndns: dyndns_subscribe(domain=new_domain)
|
|
|
|
elif len(new_domain.split('.')) >= 3:
|
|
|
|
r = requests.get('http://dyndns.yunohost.org/domains')
|
|
|
|
dyndomains = json.loads(r.text)
|
|
|
|
dyndomain = '.'.join(new_domain.split('.')[1:])
|
|
|
|
if dyndomain in dyndomains:
|
|
|
|
dyndns_subscribe(domain=new_domain)
|
|
|
|
|
2013-02-28 12:03:51 +01:00
|
|
|
win_msg(_("Main domain has been successfully changed"))
|
2012-10-27 17:06:43 +02:00
|
|
|
|
2012-10-26 15:26:50 +02:00
|
|
|
|
2013-06-16 14:41:29 +02:00
|
|
|
def tools_postinstall(domain, password, dyndns=False):
|
2012-10-27 17:06:43 +02:00
|
|
|
"""
|
2013-07-06 10:17:16 +02:00
|
|
|
YunoHost post-install
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2013-07-06 10:17:16 +02:00
|
|
|
Keyword argument:
|
|
|
|
domain -- YunoHost main domain
|
2013-10-31 11:21:59 +01:00
|
|
|
dyndns -- Subscribe domain to a DynDNS service
|
2013-07-06 12:59:06 +02:00
|
|
|
password -- YunoHost admin password
|
2012-10-27 17:06:43 +02:00
|
|
|
|
|
|
|
"""
|
2013-10-26 22:56:26 +02:00
|
|
|
try:
|
|
|
|
with open('/etc/yunohost/installed') as f: pass
|
|
|
|
except IOError:
|
|
|
|
print('Installing YunoHost')
|
|
|
|
else:
|
|
|
|
raise YunoHostError(17, _("YunoHost is already installed"))
|
2013-06-08 19:46:15 +02:00
|
|
|
|
2013-10-26 22:56:26 +02:00
|
|
|
if len(domain.split('.')) >= 3:
|
|
|
|
r = requests.get('http://dyndns.yunohost.org/domains')
|
|
|
|
dyndomains = json.loads(r.text)
|
|
|
|
dyndomain = '.'.join(domain.split('.')[1:])
|
|
|
|
if dyndomain in dyndomains:
|
|
|
|
if requests.get('http://dyndns.yunohost.org/test/'+ domain).status_code == 200:
|
|
|
|
dyndns=True
|
|
|
|
else:
|
|
|
|
raise YunoHostError(17, _("Domain is already taken"))
|
|
|
|
|
|
|
|
# Create required folders
|
|
|
|
folders_to_create = [
|
|
|
|
'/etc/yunohost/apps',
|
|
|
|
'/etc/yunohost/certs',
|
|
|
|
'/var/cache/yunohost/repo',
|
|
|
|
'/home/yunohost.backup',
|
|
|
|
'/home/yunohost.app'
|
|
|
|
]
|
2013-06-08 19:46:15 +02:00
|
|
|
|
2013-10-26 22:56:26 +02:00
|
|
|
for folder in folders_to_create:
|
|
|
|
try: os.listdir(folder)
|
|
|
|
except OSError: os.makedirs(folder)
|
|
|
|
|
|
|
|
# Set hostname to avoid amavis bug
|
|
|
|
if os.system('hostname -d') != 0:
|
|
|
|
os.system('hostname yunohost.yunohost.org')
|
2013-10-31 10:57:58 +01:00
|
|
|
|
2013-11-19 10:56:09 +01:00
|
|
|
# Activate "full" mode if RAM >= 512MB
|
|
|
|
for L in open("/proc/meminfo"):
|
|
|
|
if "MemTotal" in L:
|
2013-11-19 11:18:13 +01:00
|
|
|
if int(L.split(" ")[-2]) < 500000 or not requests.get('http://ip.yunohost.org/'):
|
2013-11-19 10:56:09 +01:00
|
|
|
os.system('touch /etc/yunohost/light')
|
|
|
|
else:
|
|
|
|
os.system('service dspam stop')
|
2014-01-06 16:25:01 +01:00
|
|
|
os.system('chmod -x /etc/cron.daily/dspam')
|
2013-11-29 12:39:47 +01:00
|
|
|
os.system('update-rc.d dspam remove')
|
|
|
|
os.system('sed -i "s/yes/no/g" /etc/default/dspam')
|
2013-12-25 12:03:05 +01:00
|
|
|
os.system('sed -i "s/dspam=no/dspam=yes/" /etc/yunohost/yunohost.conf')
|
2013-12-18 17:16:06 +01:00
|
|
|
os.system('apt-get install -y -qq yunohost-config-amavis')
|
2013-11-19 10:56:09 +01:00
|
|
|
os.system('service amavis start')
|
|
|
|
os.system('apt-get install --reinstall -y -qq yunohost-config-postfix yunohost-config-dovecot')
|
|
|
|
|
2013-10-26 22:56:26 +02:00
|
|
|
# Create SSL CA
|
|
|
|
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
|
|
|
|
command_list = [
|
|
|
|
'echo "01" > '+ ssl_dir +'/serial',
|
|
|
|
'rm '+ ssl_dir +'/index.txt',
|
|
|
|
'touch '+ ssl_dir +'/index.txt',
|
|
|
|
'cp '+ ssl_dir +'/openssl.cnf '+ ssl_dir +'/openssl.ca.cnf ',
|
|
|
|
'sed -i "s/yunohost.org/'+ domain +'/g" '+ ssl_dir +'/openssl.ca.cnf ',
|
|
|
|
'openssl req -x509 -new -config '+ ssl_dir +'/openssl.ca.cnf -days 3650 -out '+ ssl_dir +'/ca/cacert.pem -keyout '+ ssl_dir +'/ca/cakey.pem -nodes -batch',
|
|
|
|
'cp '+ ssl_dir +'/ca/cacert.pem /etc/ssl/certs/ca-yunohost_crt.pem',
|
|
|
|
'update-ca-certificates'
|
|
|
|
]
|
|
|
|
|
|
|
|
for command in command_list:
|
|
|
|
if os.system(command) != 0:
|
|
|
|
raise YunoHostError(17, _("There were a problem during CA creation"))
|
|
|
|
|
|
|
|
with YunoHostLDAP(password='yunohost') as yldap:
|
2013-06-08 19:46:15 +02:00
|
|
|
|
2012-11-09 18:04:15 +01:00
|
|
|
# Initialize YunoHost LDAP base
|
2013-07-07 09:38:18 +02:00
|
|
|
tools_ldapinit(password)
|
2012-10-26 15:26:50 +02:00
|
|
|
|
2013-08-05 09:53:11 +02:00
|
|
|
# Initialize backup system
|
|
|
|
backup_init()
|
|
|
|
|
2013-02-27 22:34:16 +01:00
|
|
|
# New domain config
|
2013-07-07 11:13:21 +02:00
|
|
|
tools_maindomain(old_domain='yunohost.org', new_domain=domain, dyndns=dyndns)
|
2013-02-27 22:34:16 +01:00
|
|
|
|
2013-10-17 17:11:58 +02:00
|
|
|
# Generate SSOwat configuration file
|
2013-10-28 10:39:15 +01:00
|
|
|
app_ssowatconf()
|
2013-10-17 17:11:58 +02:00
|
|
|
|
2012-11-09 18:04:15 +01:00
|
|
|
# Change LDAP admin password
|
2012-11-29 15:00:33 +01:00
|
|
|
tools_adminpw(old_password='yunohost', new_password=password)
|
2012-10-26 15:26:50 +02:00
|
|
|
|
2013-05-03 12:10:39 +02:00
|
|
|
os.system('touch /etc/yunohost/installed')
|
2013-11-21 15:41:10 +01:00
|
|
|
os.system('service yunohost-api restart &')
|
2013-02-26 20:36:37 +01:00
|
|
|
|
2012-10-29 16:06:46 +01:00
|
|
|
win_msg(_("YunoHost has been successfully configured"))
|
2013-10-17 12:57:52 +02:00
|
|
|
|
|
|
|
|