]>
git.ipfire.org Git - ddns.git/blob - src/ddns/providers.py
0a20e3ae29f97d82cae2a11cc7340f6e2c4736cf
2 ###############################################################################
4 # ddns - A dynamic DNS client for IPFire #
5 # Copyright (C) 2012 IPFire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
22 # Import all possible exception types.
25 class DDNSProvider(object):
27 # A short string that uniquely identifies
31 # The full name of the provider.
34 # A weburl to the homepage of the provider.
35 # (Where to register a new account?)
38 # A list of supported protocols.
39 "protocols" : ["ipv6", "ipv4"],
44 def __init__(self
, core
, **settings
):
47 # Copy a set of default settings and
48 # update them by those from the configuration file.
49 self
.settings
= self
.DEFAULT_SETTINGS
.copy()
50 self
.settings
.update(settings
)
53 return "<DDNS Provider %s (%s)>" % (self
.name
, self
.handle
)
55 def __cmp__(self
, other
):
56 return cmp(self
.hostname
, other
.hostname
)
61 Returns the name of the provider.
63 return self
.INFO
.get("name")
68 Returns the website URL of the provider
69 or None if that is not available.
71 return self
.INFO
.get("website", None)
76 Returns the handle of this provider.
78 return self
.INFO
.get("handle")
80 def get(self
, key
, default
=None):
82 Get a setting from the settings dictionary.
84 return self
.settings
.get(key
, default
)
89 Fast access to the hostname.
91 return self
.get("hostname")
96 Fast access to the username.
98 return self
.get("username")
103 Fast access to the password.
105 return self
.get("password")
108 raise NotImplementedError
110 def send_request(self
, *args
, **kwargs
):
112 Proxy connection to the send request
115 return self
.core
.system
.send_request(*args
, **kwargs
)
117 def get_address(self
, proto
):
119 Proxy method to get the current IP address.
121 return self
.core
.system
.get_address(proto
)
124 class DDNSProviderLightningWireLabs(DDNSProvider
):
126 "handle" : "dns.lightningwirelabs.com",
127 "name" : "Lightning Wire Labs",
128 "website" : "http://dns.lightningwirelabs.com/",
129 "protocols" : ["ipv6", "ipv4",]
132 # Information about the format of the HTTPS request is to be found
133 # https://dns.lightningwirelabs.com/knowledge-base/api/ddns
134 url
= "https://dns.lightningwirelabs.com/update"
139 Fast access to the token.
141 return self
.get("token")
145 "hostname" : self
.hostname
,
148 # Check if we update an IPv6 address.
149 address6
= self
.get_address("ipv6")
151 data
["address6"] = address6
153 # Check if we update an IPv4 address.
154 address4
= self
.get_address("ipv4")
156 data
["address4"] = address4
158 # Raise an error if none address is given.
159 if not data
.has_key("address6") and not data
.has_key("address4"):
160 raise DDNSConfigurationError
162 # Check if a token has been set.
164 data
["token"] = self
.token
166 # Check for username and password.
167 elif self
.username
and self
.password
:
169 "username" : self
.username
,
170 "password" : self
.password
,
173 # Raise an error if no auth details are given.
175 raise DDNSConfigurationError
177 # Send update to the server.
178 response
= self
.send_request(url
, data
=data
)
180 # Handle success messages.
181 if response
.code
== 200:
184 # Handle error codes.
185 if response
.code
== "403":
186 raise DDNSAuthenticationError
187 elif response
.code
== "400":
188 raise DDNSRequestError
190 # If we got here, some other update error happened.
191 raise DDNSUpdateError
194 class DDNSProviderNOIP(DDNSProvider
):
196 "handle" : "no-ip.com",
198 "website" : "http://www.no-ip.com/",
199 "protocols" : ["ipv4",]
202 # Information about the format of the HTTP request is to be found
203 # here: http://www.no-ip.com/integrate/request and
204 # here: http://www.no-ip.com/integrate/response
206 url
= "http://%(username)s:%(password)s@dynupdate.no-ip.com/nic/update"
210 "username" : self
.username
,
211 "password" : self
.password
,
215 "hostname" : self
.hostname
,
216 "address" : self
.get_address("ipv4"),
219 # Send update to the server.
220 response
= self
.send_request(url
, data
=data
)
222 # Get the full response message.
223 output
= response
.read()
225 # Handle success messages.
226 if output
.startswith("good") or output
.startswith("nochg"):
229 # Handle error codes.
230 if output
== "badauth":
231 raise DDNSAuthenticationError
232 elif output
== "aduse":
234 elif output
== "911":
235 raise DDNSInternalServerError
237 # If we got here, some other update error happened.
238 raise DDNSUpdateError
241 class DDNSProviderSelfhost(DDNSProvider
):
243 "handle" : "selfhost.de",
244 "name" : "Selfhost.de",
245 "website" : "http://www.selfhost.de/",
246 "protocols" : ["ipv4",],
249 url
= "https://carol.selfhost.de/update"
253 "username" : self
.username
,
254 "password" : self
.password
,
258 response
= self
.send_request(self
.url
, data
=data
)
260 match
= re
.search("status=20(0|4)", response
.read())
262 raise DDNSUpdateError