Beispiel #1
0
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
    """
    Main domain change tool

    Keyword argument:
        new_domain
        old_domain

    """
    if not old_domain:
        with open('/etc/yunohost/current_host', 'r') as f:
            old_domain = f.readline().rstrip()

        if not new_domain:
            return {'current_main_domain': old_domain}

    if not new_domain:
        raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required'))
    if new_domain not in domain_list(auth)['domains']:
        domain_add(auth, new_domain)

    os.system('rm /etc/ssl/private/yunohost_key.pem')
    os.system('rm /etc/ssl/certs/yunohost_crt.pem')

    command_list = [
        'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem'
        % new_domain,
        'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem'
        % new_domain,
        'echo %s > /etc/yunohost/current_host' % new_domain,
    ]

    for command in command_list:
        if os.system(command) != 0:
            raise MoulinetteError(errno.EPERM,
                                  m18n.n('maindomain_change_failed'))

    if dyndns and len(new_domain.split('.')) >= 3:
        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except requests.ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain = '.'.join(new_domain.split('.')[1:])
            if dyndomain in dyndomains:
                dyndns_subscribe(domain=new_domain)

    try:
        with open('/etc/yunohost/installed', 'r') as f:
            service_regen_conf()
    except IOError:
        pass

    logger.success(m18n.n('maindomain_changed'))
Beispiel #2
0
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
    """
    Main domain change tool

    Keyword argument:
        new_domain
        old_domain

    """
    if not old_domain:
        with open('/etc/yunohost/current_host', 'r') as f:
            old_domain = f.readline().rstrip()

        if not new_domain:
            return { 'current_main_domain': old_domain }

    if not new_domain:
        raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required'))
    if new_domain not in domain_list(auth)['domains']:
        domain_add(auth, new_domain)

    os.system('rm /etc/ssl/private/yunohost_key.pem')
    os.system('rm /etc/ssl/certs/yunohost_crt.pem')

    command_list = [
        'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain,
        'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem'   % new_domain,
        'echo %s > /etc/yunohost/current_host' % new_domain,
    ]

    for command in command_list:
        if os.system(command) != 0:
            raise MoulinetteError(errno.EPERM,
                                  m18n.n('maindomain_change_failed'))

    if dyndns and len(new_domain.split('.')) >= 3:
        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except requests.ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain  = '.'.join(new_domain.split('.')[1:])
            if dyndomain in dyndomains:
                dyndns_subscribe(domain=new_domain)

    try:
        with open('/etc/yunohost/installed', 'r') as f:
            service_regen_conf()
    except IOError: pass

    logger.success(m18n.n('maindomain_changed'))
Beispiel #3
0
def domain_add(auth, domain, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domain -- Domain name to add
        dyndns -- Subscribe to DynDNS

    """
    from yunohost.hook import hook_callback

    attr_dict = {'objectClass': ['mailDomain', 'top']}

    now = datetime.datetime.now()
    timestamp = str(now.year) + str(now.month) + str(now.day)

    if domain in domain_list(auth)['domains']:
        raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

    # DynDNS domain
    if dyndns:
        if len(domain.split('.')) < 3:
            raise MoulinetteError(errno.EINVAL,
                                  m18n.n('domain_dyndns_invalid'))
        from yunohost.dyndns import dyndns_subscribe

        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except requests.ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain = '.'.join(domain.split('.')[1:])
            if dyndomain in dyndomains:
                if os.path.exists('/etc/cron.d/yunohost-dyndns'):
                    raise MoulinetteError(
                        errno.EPERM,
                        m18n.n('domain_dyndns_already_subscribed'))
                dyndns_subscribe(domain=domain)
            else:
                raise MoulinetteError(errno.EINVAL,
                                      m18n.n('domain_dyndns_root_unknown'))

    try:
        yunohost.certificate._certificate_install_selfsigned([domain], False)

        try:
            auth.validate_uniqueness({'virtualdomain': domain})
        except MoulinetteError:
            raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

        attr_dict['virtualdomain'] = domain

        if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
            raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))

        try:
            with open('/etc/yunohost/installed', 'r') as f:
                service_regen_conf(
                    names=['nginx', 'metronome', 'dnsmasq', 'rmilter'])
                os.system('yunohost app ssowatconf > /dev/null 2>&1')
        except IOError:
            pass
    except:
        # Force domain removal silently
        try:
            domain_remove(auth, domain, True)
        except:
            pass
        raise

    hook_callback('post_domain_add', args=[domain])

    logger.success(m18n.n('domain_created'))
Beispiel #4
0
def domain_add(operation_logger, domain, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domain -- Domain name to add
        dyndns -- Subscribe to DynDNS

    """
    from yunohost.hook import hook_callback
    from yunohost.app import app_ssowatconf
    from yunohost.utils.ldap import _get_ldap_interface

    if domain.startswith("xmpp-upload."):
        raise YunohostError("domain_cannot_add_xmpp_upload")

    ldap = _get_ldap_interface()

    try:
        ldap.validate_uniqueness({"virtualdomain": domain})
    except MoulinetteError:
        raise YunohostError("domain_exists")

    operation_logger.start()

    # Lower domain to avoid some edge cases issues
    # See: https://forum.yunohost.org/t/invalid-domain-causes-diagnosis-web-to-fail-fr-on-demand/11765
    domain = domain.lower()

    # DynDNS domain
    if dyndns:

        # Do not allow to subscribe to multiple dyndns domains...
        if os.path.exists("/etc/cron.d/yunohost-dyndns"):
            raise YunohostError("domain_dyndns_already_subscribed")

        from yunohost.dyndns import dyndns_subscribe, _dyndns_provides

        # Check that this domain can effectively be provided by
        # dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st)
        if not _dyndns_provides("dyndns.yunohost.org", domain):
            raise YunohostError("domain_dyndns_root_unknown")

        # Actually subscribe
        dyndns_subscribe(domain=domain)

    try:
        import yunohost.certificate

        yunohost.certificate._certificate_install_selfsigned([domain], False)

        attr_dict = {
            "objectClass": ["mailDomain", "top"],
            "virtualdomain": domain,
        }

        try:
            ldap.add("virtualdomain=%s,ou=domains" % domain, attr_dict)
        except Exception as e:
            raise YunohostError("domain_creation_failed",
                                domain=domain,
                                error=e)

        # Don't regen these conf if we're still in postinstall
        if os.path.exists("/etc/yunohost/installed"):
            # Sometime we have weird issues with the regenconf where some files
            # appears as manually modified even though they weren't touched ...
            # There are a few ideas why this happens (like backup/restore nginx
            # conf ... which we shouldnt do ...). This in turns creates funky
            # situation where the regenconf may refuse to re-create the conf
            # (when re-creating a domain..)
            # So here we force-clear the has out of the regenconf if it exists.
            # This is a pretty ad hoc solution and only applied to nginx
            # because it's one of the major service, but in the long term we
            # should identify the root of this bug...
            _force_clear_hashes(["/etc/nginx/conf.d/%s.conf" % domain])
            regen_conf(
                names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd"])
            app_ssowatconf()

    except Exception:
        # Force domain removal silently
        try:
            domain_remove(domain, force=True)
        except Exception:
            pass
        raise

    hook_callback("post_domain_add", args=[domain])

    logger.success(m18n.n("domain_created"))
Beispiel #5
0
def domain_add(auth, domain, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domain -- Domain name to add
        dyndns -- Subscribe to DynDNS

    """
    from yunohost.hook import hook_callback

    attr_dict = { 'objectClass' : ['mailDomain', 'top'] }

    now = datetime.datetime.now()
    timestamp = str(now.year) + str(now.month) + str(now.day)

    if domain in domain_list(auth)['domains']:
        raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

    # DynDNS domain
    if dyndns:
        if len(domain.split('.')) < 3:
            raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid'))
        from yunohost.dyndns import dyndns_subscribe

        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except requests.ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain  = '.'.join(domain.split('.')[1:])
            if dyndomain in dyndomains:
                if os.path.exists('/etc/cron.d/yunohost-dyndns'):
                    raise MoulinetteError(errno.EPERM,
                                          m18n.n('domain_dyndns_already_subscribed'))
                dyndns_subscribe(domain=domain)
            else:
                raise MoulinetteError(errno.EINVAL,
                                      m18n.n('domain_dyndns_root_unknown'))

    try:
        # Commands
        ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
        ssl_domain_path  = '/etc/yunohost/certs/%s' % domain
        with open('%s/serial' % ssl_dir, 'r') as f:
            serial = f.readline().rstrip()
        try: os.listdir(ssl_domain_path)
        except OSError: os.makedirs(ssl_domain_path)

        command_list = [
            'cp %s/openssl.cnf %s'                               % (ssl_dir, ssl_domain_path),
            'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf'        % (domain, ssl_domain_path),
            'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path,
            'cp %s/certs/yunohost_key.pem    %s/key.pem'         % (ssl_dir, ssl_domain_path),
            'cp %s/newcerts/%s.pem %s/crt.pem'                   % (ssl_dir, serial, ssl_domain_path),
            'chmod 755 %s'                                       % ssl_domain_path,
            'chmod 640 %s/key.pem'                               % ssl_domain_path,
            'chmod 640 %s/crt.pem'                               % ssl_domain_path,
            'chmod 600 %s/openssl.cnf'                           % ssl_domain_path,
            'chown root:metronome %s/key.pem'                    % ssl_domain_path,
            'chown root:metronome %s/crt.pem'                    % ssl_domain_path,
            'cat %s/ca.pem >> %s/crt.pem'                        % (ssl_domain_path, ssl_domain_path)
        ]

        for command in command_list:
            if os.system(command) != 0:
                raise MoulinetteError(errno.EIO,
                                      m18n.n('domain_cert_gen_failed'))

        try:
            auth.validate_uniqueness({ 'virtualdomain': domain })
        except MoulinetteError:
            raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))


        attr_dict['virtualdomain'] = domain

        if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
            raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))

        try:
            with open('/etc/yunohost/installed', 'r') as f:
                service_regen_conf(names=[
                    'nginx', 'metronome', 'dnsmasq', 'rmilter'])
                os.system('yunohost app ssowatconf > /dev/null 2>&1')
        except IOError: pass
    except:
        # Force domain removal silently
        try: domain_remove(auth, domain, True)
        except: pass
        raise

    hook_callback('post_domain_add', args=[domain])

    logger.success(m18n.n('domain_created'))
Beispiel #6
0
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
    """
    Main domain change tool

    Keyword argument:
        new_domain
        old_domain

    """
    from yunohost.domain import domain_add
    from yunohost.dyndns import dyndns_subscribe

    if not old_domain:
        with open('/etc/yunohost/current_host', 'r') as f:
            old_domain = f.readline().rstrip()

        if not new_domain:
            return { 'current_main_domain': old_domain }

    config_files = [
        '/etc/postfix/main.cf',
        '/etc/metronome/metronome.cfg.lua',
        '/etc/dovecot/dovecot.conf',
        '/usr/share/yunohost/yunohost-config/others/startup',
        '/home/yunohost.backup/tahoe/tahoe.cfg',
        '/etc/amavis/conf.d/05-node_id',
        '/etc/amavis/conf.d/50-user'
    ]

    config_dir = []

    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:
                sources.write(re.sub(r''+ old_domain +'', new_domain, line))

    domain_add(auth, [new_domain], main=True)

    os.system('rm /etc/ssl/private/yunohost_key.pem')
    os.system('rm /etc/ssl/certs/yunohost_crt.pem')

    command_list = [
        'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain,
        'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem'   % new_domain,
        'echo %s > /etc/yunohost/current_host' % new_domain,
        'service metronome restart',
        'service postfix restart',
        'service dovecot restart',
        'service amavis restart',
        'service nginx restart',
    ]

    for command in command_list:
        if os.system(command) != 0:
            raise MoulinetteError(errno.EPERM,
                                  m18n.n('maindomain_change_failed'))

    if dyndns: dyndns_subscribe(domain=new_domain)
    elif len(new_domain.split('.')) >= 3:
        try:
            r = requests.get('http://dyndns.yunohost.org/domains')
        except ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain  = '.'.join(new_domain.split('.')[1:])
            if dyndomain in dyndomains:
                dyndns_subscribe(domain=new_domain)

    msignals.display(m18n.n('maindomain_changed'), 'success')
Beispiel #7
0
def domain_add(auth, domain, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domain -- Domain name to add
        dyndns -- Subscribe to DynDNS

    """
    from yunohost.hook import hook_callback

    attr_dict = {'objectClass': ['mailDomain', 'top']}

    now = datetime.datetime.now()
    timestamp = str(now.year) + str(now.month) + str(now.day)

    if domain in domain_list(auth)['domains']:
        raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

    # DynDNS domain
    if dyndns:
        if len(domain.split('.')) < 3:
            raise MoulinetteError(errno.EINVAL,
                                  m18n.n('domain_dyndns_invalid'))
        from yunohost.dyndns import dyndns_subscribe

        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except requests.ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain = '.'.join(domain.split('.')[1:])
            if dyndomain in dyndomains:
                if os.path.exists('/etc/cron.d/yunohost-dyndns'):
                    raise MoulinetteError(
                        errno.EPERM,
                        m18n.n('domain_dyndns_already_subscribed'))
                dyndns_subscribe(domain=domain)
            else:
                raise MoulinetteError(errno.EINVAL,
                                      m18n.n('domain_dyndns_root_unknown'))

    try:
        # Commands
        ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
        ssl_domain_path = '/etc/yunohost/certs/%s' % domain
        with open('%s/serial' % ssl_dir, 'r') as f:
            serial = f.readline().rstrip()
        try:
            os.listdir(ssl_domain_path)
        except OSError:
            os.makedirs(ssl_domain_path)

        command_list = [
            'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path),
            'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' %
            (domain, ssl_domain_path),
            'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' %
            ssl_domain_path,
            'cp %s/certs/yunohost_key.pem    %s/key.pem' %
            (ssl_dir, ssl_domain_path),
            'cp %s/newcerts/%s.pem %s/crt.pem' %
            (ssl_dir, serial, ssl_domain_path),
            'chmod 755 %s' % ssl_domain_path,
            'chmod 640 %s/key.pem' % ssl_domain_path,
            'chmod 640 %s/crt.pem' % ssl_domain_path,
            'chmod 600 %s/openssl.cnf' % ssl_domain_path,
            'chown root:metronome %s/key.pem' % ssl_domain_path,
            'chown root:metronome %s/crt.pem' % ssl_domain_path,
            'cat %s/ca.pem >> %s/crt.pem' % (ssl_domain_path, ssl_domain_path)
        ]

        for command in command_list:
            if os.system(command) != 0:
                raise MoulinetteError(errno.EIO,
                                      m18n.n('domain_cert_gen_failed'))

        try:
            auth.validate_uniqueness({'virtualdomain': domain})
        except MoulinetteError:
            raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

        attr_dict['virtualdomain'] = domain

        if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
            raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))

        try:
            with open('/etc/yunohost/installed', 'r') as f:
                service_regen_conf(
                    names=['nginx', 'metronome', 'dnsmasq', 'rmilter'])
                os.system('yunohost app ssowatconf > /dev/null 2>&1')
        except IOError:
            pass
    except:
        # Force domain removal silently
        try:
            domain_remove(auth, domain, True)
        except:
            pass
        raise

    hook_callback('post_domain_add', args=[domain])

    logger.success(m18n.n('domain_created'))
Beispiel #8
0
def domain_add(auth, domain, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domain -- Domain name to add
        dyndns -- Subscribe to DynDNS

    """
    attr_dict = { 'objectClass' : ['mailDomain', 'top'] }
    try:
        ip = str(urlopen('http://ip.yunohost.org').read())
    except IOError:
        ip = "127.0.0.1"
    now = datetime.datetime.now()
    timestamp = str(now.year) + str(now.month) + str(now.day)

    if domain in domain_list(auth)['domains']:
        raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

    # DynDNS domain
    if dyndns:
        if len(domain.split('.')) < 3:
            raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid'))
        import requests
        from yunohost.dyndns import dyndns_subscribe

        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain  = '.'.join(domain.split('.')[1:])
            if dyndomain in dyndomains:
                if os.path.exists('/etc/cron.d/yunohost-dyndns'):
                    raise MoulinetteError(errno.EPERM,
                                          m18n.n('domain_dyndns_already_subscribed'))
                dyndns_subscribe(domain=domain)
            else:
                raise MoulinetteError(errno.EINVAL,
                                      m18n.n('domain_dyndns_root_unknown'))

    try:
        # Commands
        ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
        ssl_domain_path  = '/etc/yunohost/certs/%s' % domain
        with open('%s/serial' % ssl_dir, 'r') as f:
            serial = f.readline().rstrip()
        try: os.listdir(ssl_domain_path)
        except OSError: os.makedirs(ssl_domain_path)

        command_list = [
            'cp %s/openssl.cnf %s'                               % (ssl_dir, ssl_domain_path),
            'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf'        % (domain, ssl_domain_path),
            'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path,
            'cp %s/certs/yunohost_key.pem    %s/key.pem'         % (ssl_dir, ssl_domain_path),
            'cp %s/newcerts/%s.pem %s/crt.pem'                   % (ssl_dir, serial, ssl_domain_path),
            'chmod 755 %s'                                       % ssl_domain_path,
            'chmod 640 %s/key.pem'                               % ssl_domain_path,
            'chmod 640 %s/crt.pem'                               % ssl_domain_path,
            'chmod 600 %s/openssl.cnf'                           % ssl_domain_path,
            'chown root:metronome %s/key.pem'                    % ssl_domain_path,
            'chown root:metronome %s/crt.pem'                    % ssl_domain_path
        ]

        for command in command_list:
            if os.system(command) != 0:
                raise MoulinetteError(errno.EIO,
                                      m18n.n('domain_cert_gen_failed'))

        try:
            auth.validate_uniqueness({ 'virtualdomain': domain })
        except MoulinetteError:
            raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))


        attr_dict['virtualdomain'] = domain

        dnsmasq_config_path='/etc/dnsmasq.d'
        try:
            os.listdir(dnsmasq_config_path)
        except OSError:
            msignals.display(m18n.n('dnsmasq_isnt_installed'),
                                  'warning')
            os.makedirs(dnsmasq_config_path)

        try:
            with open('%s/%s' % (dnsmasq_config_path, domain)) as f: pass
        except IOError as e:
            zone_lines = [
             'address=/%s/%s' % (domain, ip),
             'txt-record=%s,"v=spf1 mx a -all"' % domain,
             'mx-host=%s,%s,5' % (domain, domain),
             'srv-host=_xmpp-client._tcp.%s,%s,5222,0,5' % (domain, domain),
             'srv-host=_xmpp-server._tcp.%s,%s,5269,0,5' % (domain, domain),
             'srv-host=_jabber._tcp.%s,%s,5269,0,5' % (domain, domain),
            ]
            with open('%s/%s' % (dnsmasq_config_path, domain), 'w') as zone:
                for line in zone_lines:
                    zone.write(line + '\n')
            os.system('service dnsmasq restart')

        else:
            msignals.display(m18n.n('domain_zone_exists'),
                                 'warning')

        # XMPP
        try:
            with open('/etc/metronome/conf.d/%s.cfg.lua' % domain) as f: pass
        except IOError as e:
            conf_lines = [
                'VirtualHost "%s"' % domain,
                '  ssl = {',
                '        key = "%s/key.pem";' % ssl_domain_path,
                '        certificate = "%s/crt.pem";' % ssl_domain_path,
                '  }',
                '  authentication = "ldap2"',
                '  ldap = {',
                '     hostname      = "localhost",',
                '     user = {',
                '       basedn        = "ou=users,dc=yunohost,dc=org",',
                '       filter        = "(&(objectClass=posixAccount)(mail=*@%s))",' % domain,
                '       usernamefield = "mail",',
                '       namefield     = "cn",',
                '       },',
                '  }',
            ]
            with open('/etc/metronome/conf.d/%s.cfg.lua' % domain, 'w') as conf:
                for line in conf_lines:
                    conf.write(line + '\n')

        os.system('mkdir -p /var/lib/metronome/%s/pep' % domain.replace('.', '%2e'))
        os.system('chown -R metronome: /var/lib/metronome/')
        os.system('chown -R metronome: /etc/metronome/conf.d/')
        os.system('service metronome restart')


        # Nginx
        os.system('cp /usr/share/yunohost/yunohost-config/nginx/template.conf /etc/nginx/conf.d/%s.conf' % domain)
        os.system('mkdir /etc/nginx/conf.d/%s.d/' % domain)
        os.system('sed -i s/yunohost.org/%s/g /etc/nginx/conf.d/%s.conf' % (domain, domain))
        os.system('service nginx reload')

        if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
            raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))

        os.system('yunohost app ssowatconf > /dev/null 2>&1')
    except:
        # Force domain removal silently
        try: domain_remove(auth, domain, True)
        except: pass
        raise

    msignals.display(m18n.n('domain_created'), 'success')
Beispiel #9
0
def domain_add(auth, domains, main=False, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domains -- Domain name to add
        main -- Is the main domain
        dyndns -- Subscribe to DynDNS

    """
    attr_dict = { 'objectClass' : ['mailDomain', 'top'] }
    try:
        ip = str(urlopen('http://ip.yunohost.org').read())
    except IOError:
        ip = "127.0.0.1"
    now = datetime.datetime.now()
    timestamp = str(now.year) + str(now.month) + str(now.day)
    result = []

    if not isinstance(domains, list):
        domains = [ domains ]

    for domain in domains:
        if domain in domain_list(auth)['domains']:
            continue

        # DynDNS domain
        if dyndns:
            if len(domain.split('.')) < 3:
                raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid'))
            import requests
            from yunohost.dyndns import dyndns_subscribe

            try:
                r = requests.get('http://dyndns.yunohost.org/domains')
            except ConnectionError:
                pass
            else:
                dyndomains = json.loads(r.text)
                dyndomain  = '.'.join(domain.split('.')[1:])
                if dyndomain in dyndomains:
                    if os.path.exists('/etc/cron.d/yunohost-dyndns'):
                        raise MoulinetteError(errno.EPERM,
                                              m18n.n('domain_dyndns_already_subscribed'))
                    dyndns_subscribe(domain=domain)
                else:
                    raise MoulinetteError(errno.EINVAL,
                                          m18n.n('domain_dyndns_root_unknown'))

        # Commands
        ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
        ssl_domain_path  = '/etc/yunohost/certs/%s' % domain
        with open('%s/serial' % ssl_dir, 'r') as f:
            serial = f.readline().rstrip()
        try: os.listdir(ssl_domain_path)
        except OSError: os.makedirs(ssl_domain_path)

        command_list = [
            'cp %s/openssl.cnf %s'                               % (ssl_dir, ssl_domain_path),
            'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf'        % (domain, ssl_domain_path),
            'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path,
            'cp %s/certs/yunohost_key.pem    %s/key.pem'         % (ssl_dir, ssl_domain_path),
            'cp %s/newcerts/%s.pem %s/crt.pem'                   % (ssl_dir, serial, ssl_domain_path),
            'chmod 755 %s'                                       % ssl_domain_path,
            'chmod 640 %s/key.pem'                               % ssl_domain_path,
            'chmod 640 %s/crt.pem'                               % ssl_domain_path,
            'chmod 600 %s/openssl.cnf'                           % ssl_domain_path,
            'chown root:metronome %s/key.pem'                    % ssl_domain_path,
            'chown root:metronome %s/crt.pem'                    % ssl_domain_path
        ]

        for command in command_list:
            if os.system(command) != 0:
                raise MoulinetteError(errno.EIO,
                                      m18n.n('domain_cert_gen_failed'))

        try:
            auth.validate_uniqueness({ 'virtualdomain': domain })
        except MoulinetteError:
            raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))


        attr_dict['virtualdomain'] = domain

        try:
            with open('/var/lib/bind/%s.zone' % domain) as f: pass
        except IOError as e:
            zone_lines = [
             '$TTL    38400',
             '%s.      IN   SOA   ns.%s. root.%s. %s 10800 3600 604800 38400' % (domain, domain, domain, timestamp),
             '%s.      IN   NS    ns.%s.'                         % (domain, domain),
             '%s.      IN   A     %s'                             % (domain, ip),
             '%s.      IN   MX    5 %s.'                          % (domain, domain),
             '%s.      IN   TXT   "v=spf1 mx a -all"'             % domain,
             'ns.%s.   IN   A     %s'                             % (domain, ip),
             '_xmpp-client._tcp.%s.  IN   SRV   0  5   5222  %s.' % (domain, domain),
             '_xmpp-server._tcp.%s.  IN   SRV   0  5   5269  %s.' % (domain, domain),
             '_jabber._tcp.%s.       IN   SRV   0  5   5269  %s.' % (domain, domain),
            ]
            if main:
                zone_lines.extend([
                    'pubsub.%s.   IN   A     %s' % (domain, ip),
                    'muc.%s.      IN   A     %s' % (domain, ip),
                    'vjud.%s.     IN   A     %s' % (domain, ip)
                ])
            with open('/var/lib/bind/%s.zone' % domain, 'w') as zone:
                for line in zone_lines:
                    zone.write(line + '\n')

            os.system('chown bind /var/lib/bind/%s.zone' % domain)

        else:
            raise MoulinetteError(errno.EEXIST,
                                  m18n.n('domain_zone_exists'))

        conf_lines = [
            'zone "%s" {' % domain,
            '    type master;',
            '    file "/var/lib/bind/%s.zone";' % domain,
            '    allow-transfer {',
            '        127.0.0.1;',
            '        localnets;',
            '    };',
            '};'
        ]
        with open('/etc/bind/named.conf.local', 'a') as conf:
            for line in conf_lines:
               conf.write(line + '\n')

        os.system('service bind9 reload')

        # XMPP
        try:
            with open('/etc/metronome/conf.d/%s.cfg.lua' % domain) as f: pass
        except IOError as e:
            conf_lines = [
                'VirtualHost "%s"' % domain,
                '  ssl = {',
                '        key = "%s/key.pem";' % ssl_domain_path,
                '        certificate = "%s/crt.pem";' % ssl_domain_path,
                '  }',
                '  authentication = "ldap2"',
                '  ldap = {',
                '     hostname      = "localhost",',
                '     user = {',
                '       basedn        = "ou=users,dc=yunohost,dc=org",',
                '       filter        = "(&(objectClass=posixAccount)(mail=*@%s))",' % domain,
                '       usernamefield = "mail",',
                '       namefield     = "cn",',
                '       },',
                '  }',
            ]
            with open('/etc/metronome/conf.d/%s.cfg.lua' % domain, 'w') as conf:
                for line in conf_lines:
                    conf.write(line + '\n')

        os.system('mkdir -p /var/lib/metronome/%s/pep' % domain.replace('.', '%2e'))
        os.system('chown -R metronome: /var/lib/metronome/')
        os.system('chown -R metronome: /etc/metronome/conf.d/')
        os.system('service metronome restart')


        # Nginx
        os.system('cp /usr/share/yunohost/yunohost-config/nginx/template.conf /etc/nginx/conf.d/%s.conf' % domain)
        os.system('mkdir /etc/nginx/conf.d/%s.d/' % domain)
        os.system('sed -i s/yunohost.org/%s/g /etc/nginx/conf.d/%s.conf' % (domain, domain))
        os.system('service nginx reload')

        if auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
            result.append(domain)
            continue
        else:
            raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))


    os.system('yunohost app ssowatconf > /dev/null 2>&1')

    msignals.display(m18n.n('domain_created'), 'success')
    return { 'domains': result }
Beispiel #10
0
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
    """
    Main domain change tool

    Keyword argument:
        new_domain
        old_domain

    """
    from yunohost.domain import domain_add, domain_list
    from yunohost.dyndns import dyndns_subscribe

    if not old_domain:
        with open('/etc/yunohost/current_host', 'r') as f:
            old_domain = f.readline().rstrip()

        if not new_domain:
            return { 'current_main_domain': old_domain }

    if not new_domain:
        raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required'))
    if new_domain not in domain_list(auth)['domains']:
        domain_add(auth, new_domain)

    config_files = [
        '/etc/postfix/main.cf',
        '/etc/metronome/metronome.cfg.lua',
        '/etc/dovecot/dovecot.conf',
        '/usr/share/yunohost/yunohost-config/others/startup',
        '/etc/amavis/conf.d/05-node_id',
        '/etc/amavis/conf.d/50-user'
    ]

    config_dir = []

    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:
                sources.write(re.sub(r''+ old_domain +'', new_domain, line))

    ## Update DNS zone file for old and new domains
    main_subdomains = ['pubsub', 'muc', 'vjud']
    try:
        with open('/var/lib/bind/%s.zone' % old_domain, 'r') as f:
            old_zone = f.read()
    except IOError:
        pass
    else:
        # Remove unneeded subdomains entries
        for sub in main_subdomains:
            old_zone = re.sub(
                r'^({sub}.{domain}.|{sub})[\ \t]+(IN).*$[\n]?'.format(
                    sub=sub, domain=old_domain),
                '', old_zone, 1, re.MULTILINE)
        with open('/var/lib/bind/%s.zone' % old_domain, 'w') as f:
            f.write(old_zone)
    try:
        with open('/var/lib/bind/%s.zone' % new_domain, 'r') as f:
            new_zone = f.read()
    except IOError:
        msignals.display(m18n.n('domain_zone_not_found', new_domain), 'warning')
    else:
        # Add main subdomains entries
        for sub in main_subdomains:
            new_zone += '{sub}  IN  CNAME   {domain}.\n'.format(
                sub=sub, domain=new_domain)
        with open('/var/lib/bind/%s.zone' % new_domain, 'w') as f:
            f.write(new_zone)

    os.system('rm /etc/ssl/private/yunohost_key.pem')
    os.system('rm /etc/ssl/certs/yunohost_crt.pem')

    command_list = [
        'rm -f /etc/nginx/conf.d/%s.d/yunohost_local.conf' % old_domain,
        'cp /usr/share/yunohost/yunohost-config/nginx/yunohost_local.conf /etc/nginx/conf.d/%s.d/' % new_domain,
        'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain,
        'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem'   % new_domain,
        'echo %s > /etc/yunohost/current_host' % new_domain,
        'service metronome restart',
        'service postfix restart',
        'service dovecot restart',
        'service amavis restart',
        'service nginx restart',
    ]

    for command in command_list:
        if os.system(command) != 0:
            raise MoulinetteError(errno.EPERM,
                                  m18n.n('maindomain_change_failed'))

    if dyndns and len(new_domain.split('.')) >= 3:
        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain  = '.'.join(new_domain.split('.')[1:])
            if dyndomain in dyndomains:
                dyndns_subscribe(domain=new_domain)

    msignals.display(m18n.n('maindomain_changed'), 'success')
Beispiel #11
0
def domain_add(auth, domain, dyndns=False):
    """
    Create a custom domain

    Keyword argument:
        domain -- Domain name to add
        dyndns -- Subscribe to DynDNS

    """
    attr_dict = {'objectClass': ['mailDomain', 'top']}
    try:
        ip = str(urlopen('http://ip.yunohost.org').read())
    except IOError:
        ip = "127.0.0.1"
    now = datetime.datetime.now()
    timestamp = str(now.year) + str(now.month) + str(now.day)

    if domain in domain_list(auth)['domains']:
        raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

    # DynDNS domain
    if dyndns:
        if len(domain.split('.')) < 3:
            raise MoulinetteError(errno.EINVAL,
                                  m18n.n('domain_dyndns_invalid'))
        import requests
        from yunohost.dyndns import dyndns_subscribe

        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain = '.'.join(domain.split('.')[1:])
            if dyndomain in dyndomains:
                if os.path.exists('/etc/cron.d/yunohost-dyndns'):
                    raise MoulinetteError(
                        errno.EPERM,
                        m18n.n('domain_dyndns_already_subscribed'))
                dyndns_subscribe(domain=domain)
            else:
                raise MoulinetteError(errno.EINVAL,
                                      m18n.n('domain_dyndns_root_unknown'))

    try:
        # Commands
        ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
        ssl_domain_path = '/etc/yunohost/certs/%s' % domain
        with open('%s/serial' % ssl_dir, 'r') as f:
            serial = f.readline().rstrip()
        try:
            os.listdir(ssl_domain_path)
        except OSError:
            os.makedirs(ssl_domain_path)

        command_list = [
            'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path),
            'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' %
            (domain, ssl_domain_path),
            'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch'
            % (ssl_domain_path, ssl_dir, ssl_dir),
            'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' %
            ssl_domain_path,
            'cp %s/certs/yunohost_key.pem    %s/key.pem' %
            (ssl_dir, ssl_domain_path),
            'cp %s/newcerts/%s.pem %s/crt.pem' %
            (ssl_dir, serial, ssl_domain_path),
            'chmod 755 %s' % ssl_domain_path,
            'chmod 640 %s/key.pem' % ssl_domain_path,
            'chmod 640 %s/crt.pem' % ssl_domain_path,
            'chmod 600 %s/openssl.cnf' % ssl_domain_path,
            'chown root:metronome %s/key.pem' % ssl_domain_path,
            'chown root:metronome %s/crt.pem' % ssl_domain_path
        ]

        for command in command_list:
            if os.system(command) != 0:
                raise MoulinetteError(errno.EIO,
                                      m18n.n('domain_cert_gen_failed'))

        try:
            auth.validate_uniqueness({'virtualdomain': domain})
        except MoulinetteError:
            raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))

        attr_dict['virtualdomain'] = domain

        dnsmasq_config_path = '/etc/dnsmasq.d'
        try:
            os.listdir(dnsmasq_config_path)
        except OSError:
            msignals.display(m18n.n('dnsmasq_isnt_installed'), 'warning')
            os.makedirs(dnsmasq_config_path)

        try:
            with open('%s/%s' % (dnsmasq_config_path, domain)) as f:
                pass
        except IOError as e:
            zone_lines = [
                'address=/%s/%s' % (domain, ip),
                'txt-record=%s,"v=spf1 mx a -all"' % domain,
                'mx-host=%s,%s,5' % (domain, domain),
                'srv-host=_xmpp-client._tcp.%s,%s,5222,0,5' % (domain, domain),
                'srv-host=_xmpp-server._tcp.%s,%s,5269,0,5' % (domain, domain),
                'srv-host=_jabber._tcp.%s,%s,5269,0,5' % (domain, domain),
            ]
            with open('%s/%s' % (dnsmasq_config_path, domain), 'w') as zone:
                for line in zone_lines:
                    zone.write(line + '\n')
            os.system('service dnsmasq restart')

        else:
            msignals.display(m18n.n('domain_zone_exists'), 'warning')

        # XMPP
        try:
            with open('/etc/metronome/conf.d/%s.cfg.lua' % domain) as f:
                pass
        except IOError as e:
            conf_lines = [
                'VirtualHost "%s"' % domain,
                '  ssl = {',
                '        key = "%s/key.pem";' % ssl_domain_path,
                '        certificate = "%s/crt.pem";' % ssl_domain_path,
                '  }',
                '  authentication = "ldap2"',
                '  ldap = {',
                '     hostname      = "localhost",',
                '     user = {',
                '       basedn        = "ou=users,dc=yunohost,dc=org",',
                '       filter        = "(&(objectClass=posixAccount)(mail=*@%s))",'
                % domain,
                '       usernamefield = "mail",',
                '       namefield     = "cn",',
                '       },',
                '  }',
            ]
            with open('/etc/metronome/conf.d/%s.cfg.lua' % domain,
                      'w') as conf:
                for line in conf_lines:
                    conf.write(line + '\n')

        os.system('mkdir -p /var/lib/metronome/%s/pep' %
                  domain.replace('.', '%2e'))
        os.system('chown -R metronome: /var/lib/metronome/')
        os.system('chown -R metronome: /etc/metronome/conf.d/')
        os.system('service metronome restart')

        # Nginx
        os.system(
            'cp /usr/share/yunohost/yunohost-config/nginx/template.conf /etc/nginx/conf.d/%s.conf'
            % domain)
        os.system('mkdir /etc/nginx/conf.d/%s.d/' % domain)
        os.system('sed -i s/yunohost.org/%s/g /etc/nginx/conf.d/%s.conf' %
                  (domain, domain))
        os.system('service nginx reload')

        if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
            raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))

        os.system('yunohost app ssowatconf > /dev/null 2>&1')
    except:
        # Force domain removal silently
        try:
            domain_remove(auth, domain, True)
        except:
            pass
        raise

    msignals.display(m18n.n('domain_created'), 'success')
Beispiel #12
0
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
    """
    Main domain change tool

    Keyword argument:
        new_domain
        old_domain

    """
    from yunohost.domain import domain_add, domain_list
    from yunohost.dyndns import dyndns_subscribe

    if not old_domain:
        with open('/etc/yunohost/current_host', 'r') as f:
            old_domain = f.readline().rstrip()

        if not new_domain:
            return { 'current_main_domain': old_domain }

    if not new_domain:
        raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required'))
    if new_domain not in domain_list(auth)['domains']:
        domain_add(auth, new_domain)

    config_files = [
        '/etc/postfix/main.cf',
        '/etc/metronome/metronome.cfg.lua',
        '/etc/dovecot/dovecot.conf',
        '/usr/share/yunohost/yunohost-config/others/startup',
        '/etc/amavis/conf.d/05-node_id',
        '/etc/amavis/conf.d/50-user'
    ]

    config_dir = []

    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:
                sources.write(re.sub(r''+ old_domain +'', new_domain, line))

    ## Update DNS zone file for old and new domains
    main_subdomains = ['pubsub', 'muc', 'vjud']
    try:
        with open('/var/lib/bind/%s.zone' % old_domain, 'r') as f:
            old_zone = f.read()
    except IOError:
        pass
    else:
        # Remove unneeded subdomains entries
        for sub in main_subdomains:
            old_zone = re.sub(
                r'^({sub}.{domain}.|{sub})[\ \t]+(IN).*$[\n]?'.format(
                    sub=sub, domain=old_domain),
                '', old_zone, 1, re.MULTILINE)
        with open('/var/lib/bind/%s.zone' % old_domain, 'w') as f:
            f.write(old_zone)
    try:
        with open('/var/lib/bind/%s.zone' % new_domain, 'r') as f:
            new_zone = f.read()
    except IOError:
        msignals.display(m18n.n('domain_zone_not_found', new_domain), 'warning')
    else:
        # Add main subdomains entries
        for sub in main_subdomains:
            new_zone += '{sub}  IN  CNAME   {domain}.\n'.format(
                sub=sub, domain=new_domain)
        with open('/var/lib/bind/%s.zone' % new_domain, 'w') as f:
            f.write(new_zone)

    os.system('rm /etc/ssl/private/yunohost_key.pem')
    os.system('rm /etc/ssl/certs/yunohost_crt.pem')

    command_list = [
        'rm -f /etc/nginx/conf.d/%s.d/yunohost_local.conf' % old_domain,
        'cp /usr/share/yunohost/yunohost-config/nginx/yunohost_local.conf /etc/nginx/conf.d/%s.d/' % new_domain,
        'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain,
        'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem'   % new_domain,
        'echo %s > /etc/yunohost/current_host' % new_domain,
        'service metronome restart',
        'service postfix restart',
        'service dovecot restart',
        'service amavis restart',
        'service nginx restart',
    ]

    for command in command_list:
        if os.system(command) != 0:
            raise MoulinetteError(errno.EPERM,
                                  m18n.n('maindomain_change_failed'))

    if dyndns and len(new_domain.split('.')) >= 3:
        try:
            r = requests.get('https://dyndns.yunohost.org/domains')
        except ConnectionError:
            pass
        else:
            dyndomains = json.loads(r.text)
            dyndomain  = '.'.join(new_domain.split('.')[1:])
            if dyndomain in dyndomains:
                dyndns_subscribe(domain=new_domain)

    msignals.display(m18n.n('maindomain_changed'), 'success')