# -*- coding: utf-8 -*- """ 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_dyndns.py Subscribe and Update DynDNS Hosts """ import os import sys import requests import json import glob import base64 from moulinette.core.helpers import YunoHostError, YunoHostLDAP, validate, colorize, win_msg def dyndns_subscribe(subscribe_host="dyndns.yunohost.org", domain=None, key=None): """ Subscribe to a DynDNS service Keyword argument: domain -- Full domain to subscribe with key -- Public DNS key subscribe_host -- Dynette HTTP API to subscribe to """ if domain is None: with open('/etc/yunohost/current_host', 'r') as f: domain = f.readline().rstrip() # Verify if domain is available if requests.get('http://'+ subscribe_host +'/test/'+ domain).status_code != 200: raise YunoHostError(17, _("DynDNS domain is already taken")) if key is None: if len(glob.glob('/etc/yunohost/dyndns/*.key')) == 0: os.makedirs('/etc/yunohost/dyndns') print(_("DNS key is being generated, it may take a while...")) os.system('cd /etc/yunohost/dyndns && dnssec-keygen -a hmac-md5 -b 128 -n USER '+ domain) os.system('chmod 600 /etc/yunohost/dyndns/*.key /etc/yunohost/dyndns/*.private') key_file = glob.glob('/etc/yunohost/dyndns/*.key')[0] with open(key_file) as f: key = f.readline().strip().split(' ')[-1] # Send subscription r = requests.post('http://'+ subscribe_host +'/key/'+ base64.b64encode(key), data={ 'subdomain': domain }) if r.status_code != 201: try: error = json.loads(r.text)['error'] except: error = "Server error" raise YunoHostError(1, _("An error occured during DynDNS registration: "+ error)) win_msg(_("Subscribed to DynDNS")) dyndns_installcron() def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=None): """ Update IP on DynDNS platform Keyword argument: domain -- Full domain to subscribe with dyn_host -- Dynette DNS server to inform key -- Public DNS key ip -- IP address to send """ if domain is None: with open('/etc/yunohost/current_host', 'r') as f: domain = f.readline().rstrip() if ip is None: new_ip = requests.get('http://ip.yunohost.org').text else: new_ip = ip try: with open('/etc/yunohost/dyndns/old_ip', 'r') as f: old_ip = f.readline().rstrip() except IOError: old_ip = '0.0.0.0' if old_ip != new_ip: host = domain.split('.')[1:] host = '.'.join(host) lines = [ 'server '+ dyn_host, 'zone '+ host, 'update delete '+ domain +'. A', 'update delete '+ domain +'. MX', 'update delete '+ domain +'. TXT', 'update delete pubsub.'+ domain +'. A', 'update delete muc.'+ domain +'. A', 'update delete vjud.'+ domain +'. A', 'update delete _xmpp-client._tcp.'+ domain +'. SRV', 'update delete _xmpp-server._tcp.'+ domain +'. SRV', 'update add '+ domain +'. 1800 A '+ new_ip, 'update add '+ domain +'. 14400 MX 5 '+ domain +'.', 'update add '+ domain +'. 14400 TXT "v=spf1 a mx -all"', 'update add pubsub.'+ domain +'. 1800 A '+ new_ip, 'update add muc.'+ domain +'. 1800 A '+ new_ip, 'update add vjud.'+ domain +'. 1800 A '+ new_ip, 'update add _xmpp-client._tcp.'+ domain +'. 14400 SRV 0 5 5222 '+ domain +'.', 'update add _xmpp-server._tcp.'+ domain +'. 14400 SRV 0 5 5269 '+ domain +'.', 'show', 'send' ] with open('/etc/yunohost/dyndns/zone', 'w') as zone: for line in lines: zone.write(line + '\n') if key is None: private_key_file = glob.glob('/etc/yunohost/dyndns/*.private')[0] else: private_key_file = key if os.system('/usr/bin/nsupdate -k '+ private_key_file +' /etc/yunohost/dyndns/zone') == 0: win_msg(_("IP successfully updated")) with open('/etc/yunohost/dyndns/old_ip', 'w') as f: f.write(new_ip) else: os.remove('/etc/yunohost/dyndns/old_ip') raise YunoHostError(1, _("An error occured during DynDNS update")) def dyndns_installcron(): """ Install IP update cron """ os.system("touch /etc/cron.d/yunohost-dyndns") os.system("echo '*/2 * * * * root yunohost dyndns update --no-ldap >> /dev/null' >/etc/cron.d/yunohost-dyndns") win_msg(_("DynDNS cron installed")) def dyndns_removecron(): """ Remove IP update cron """ try: os.remove("/etc/cron.d/yunohost-dyndns") except: raise YunoHostError(167,_("DynDNS cron was not installed!")) win_msg(_("DynDNS cron removed"))