]>
git.ipfire.org Git - ddns.git/blob - src/ddns/providers.py
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 DDNSProviderDHS(DDNSProvider
):
126 "handle" : "dhs.org",
127 "name" : "DHS International",
128 "website" : "http://dhs.org/",
129 "protocols" : ["ipv4",]
132 # No information about the used update api provided on webpage,
133 # grabed from source code of ez-ipudate.
134 url
= "http://members.dhs.org/nic/hosts"
138 "username" : self
.username
,
139 "password" : self
.password
,
143 "domain" : self
.hostname
,
144 "ip" : self
.get_address("ipv4"),
146 "hostcmdstage" : "2",
150 # Send update to the server.
151 response
= self
.send_request(url
, username
=self
.username
, password
=self
.password
,
154 # Handle success messages.
155 if response
.code
== 200:
158 # Handle error codes.
159 elif response
.code
== "401":
160 raise DDNSAuthenticationError
162 # If we got here, some other update error happened.
163 raise DDNSUpdateError
166 class DDNSProviderLightningWireLabs(DDNSProvider
):
168 "handle" : "dns.lightningwirelabs.com",
169 "name" : "Lightning Wire Labs",
170 "website" : "http://dns.lightningwirelabs.com/",
171 "protocols" : ["ipv6", "ipv4",]
174 # Information about the format of the HTTPS request is to be found
175 # https://dns.lightningwirelabs.com/knowledge-base/api/ddns
176 url
= "https://dns.lightningwirelabs.com/update"
181 Fast access to the token.
183 return self
.get("token")
187 "hostname" : self
.hostname
,
190 # Check if we update an IPv6 address.
191 address6
= self
.get_address("ipv6")
193 data
["address6"] = address6
195 # Check if we update an IPv4 address.
196 address4
= self
.get_address("ipv4")
198 data
["address4"] = address4
200 # Raise an error if none address is given.
201 if not data
.has_key("address6") and not data
.has_key("address4"):
202 raise DDNSConfigurationError
204 # Check if a token has been set.
206 data
["token"] = self
.token
208 # Check for username and password.
209 elif self
.username
and self
.password
:
211 "username" : self
.username
,
212 "password" : self
.password
,
215 # Raise an error if no auth details are given.
217 raise DDNSConfigurationError
219 # Send update to the server.
220 response
= self
.send_request(url
, data
=data
)
222 # Handle success messages.
223 if response
.code
== 200:
226 # Handle error codes.
227 if response
.code
== "403":
228 raise DDNSAuthenticationError
229 elif response
.code
== "400":
230 raise DDNSRequestError
232 # If we got here, some other update error happened.
233 raise DDNSUpdateError
236 class DDNSProviderNOIP(DDNSProvider
):
238 "handle" : "no-ip.com",
240 "website" : "http://www.no-ip.com/",
241 "protocols" : ["ipv4",]
244 # Information about the format of the HTTP request is to be found
245 # here: http://www.no-ip.com/integrate/request and
246 # here: http://www.no-ip.com/integrate/response
248 url
= "http://%(username)s:%(password)s@dynupdate.no-ip.com/nic/update"
252 "username" : self
.username
,
253 "password" : self
.password
,
257 "hostname" : self
.hostname
,
258 "address" : self
.get_address("ipv4"),
261 # Send update to the server.
262 response
= self
.send_request(url
, data
=data
)
264 # Get the full response message.
265 output
= response
.read()
267 # Handle success messages.
268 if output
.startswith("good") or output
.startswith("nochg"):
271 # Handle error codes.
272 if output
== "badauth":
273 raise DDNSAuthenticationError
274 elif output
== "aduse":
276 elif output
== "911":
277 raise DDNSInternalServerError
279 # If we got here, some other update error happened.
280 raise DDNSUpdateError
283 class DDNSProviderSelfhost(DDNSProvider
):
285 "handle" : "selfhost.de",
286 "name" : "Selfhost.de",
287 "website" : "http://www.selfhost.de/",
288 "protocols" : ["ipv4",],
291 url
= "https://carol.selfhost.de/update"
295 "username" : self
.username
,
296 "password" : self
.password
,
300 response
= self
.send_request(self
.url
, data
=data
)
302 match
= re
.search("status=20(0|4)", response
.read())
304 raise DDNSUpdateError