dyndnsd 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83264e341913c7b4dfc4e79402a60b3284a5bb41
4
- data.tar.gz: 51af5408a701ca8829d3e73068c6bb198e3dc1b6
3
+ metadata.gz: 8f923d3f52ae7cb8b9249038aed58e3d4d0fde75
4
+ data.tar.gz: 168bb0ac5b60cd69f16fc6202a5d8955598ab1da
5
5
  SHA512:
6
- metadata.gz: 810aca8e4360ec88e959f116460841638824174d87b841adc7396c3fa3226106ed673aa678a24e33554d24252e7c704300bdb59ccdb266661fe10723c7dff842
7
- data.tar.gz: b056c351200e8ad50d120874ad77e466eb50bd27ee567722e5f9bf6bfe6c1481cf9c9f75de344d79c0855c102a45feb63566ddd7bda49581c5f72d4c338028ad
6
+ metadata.gz: 09d518eed62f45e7414a999c970e288fcf9ed98e7a9ade4c71b04300e401721054dda94405a8c13fd38e54bc00b24b72f8cb5e9838e73aa4012a430bee06a967
7
+ data.tar.gz: 5588b3488707a9d1c0934cc0f636e266a4286c53ef7ef05eeb2d5b62a4237f31a9a2dfdd9f17cf5fee0661a2b53a4a767c220bb71580c806c0568a0b4eca8862
data/.travis.yml CHANGED
@@ -6,3 +6,6 @@ rvm:
6
6
 
7
7
  gemfile:
8
8
  - Gemfile
9
+
10
+ before_install:
11
+ - gem install bundler
data/README.md CHANGED
@@ -120,6 +120,8 @@ The following rules apply:
120
120
  * use any IP address provided via the X-Real-IP header e.g. when used behind HTTP reverse proxy such as nginx, or
121
121
  * use any IP address used by the connecting HTTP client
122
122
 
123
+ If you want to provide an additional IPv6 address as myip6 parameter the myip parameter containing an IPv4 address has to be present, too! No automatism is applied then.
124
+
123
125
  ### SSL, multiple listen ports
124
126
 
125
127
  Use a webserver as a proxy to handle SSL and/or multiple listen addresses and ports. DynDNS.com provides HTTP on port 80 and 8245 and HTTPS on port 443.
data/lib/dyndnsd.rb CHANGED
@@ -78,24 +78,40 @@ module Dyndnsd
78
78
  return @responder.response_for_error(:host_forbidden) if not @users[user]['hosts'].include? hostname
79
79
  end
80
80
 
81
- # fallback value, always present
82
- myip = env["REMOTE_ADDR"]
81
+ myip = nil
83
82
 
84
- # check whether X-Real-IP header has valid IPAddr
85
- if env.has_key?("HTTP_X_REAL_IP")
83
+ if params.has_key?("myip6")
84
+ # require presence of myip parameter as valid IPAddr (v4) and valid myip6
85
+ return @responder.response_for_error(:host_forbidden) if not params["myip"]
86
86
  begin
87
- IPAddr.new(env["HTTP_X_REAL_IP"])
88
- myip = env["HTTP_X_REAL_IP"]
87
+ IPAddr.new(params["myip"], Socket::AF_INET)
88
+ IPAddr.new(params["myip6"], Socket::AF_INET6)
89
+
90
+ # myip will be an array
91
+ myip = [params["myip"], params["myip6"]]
89
92
  rescue ArgumentError
93
+ return @responder.response_for_error(:host_forbidden)
94
+ end
95
+ else
96
+ # fallback value, always present
97
+ myip = env["REMOTE_ADDR"]
98
+
99
+ # check whether X-Real-IP header has valid IPAddr
100
+ if env.has_key?("HTTP_X_REAL_IP")
101
+ begin
102
+ IPAddr.new(env["HTTP_X_REAL_IP"])
103
+ myip = env["HTTP_X_REAL_IP"]
104
+ rescue ArgumentError
105
+ end
90
106
  end
91
- end
92
107
 
93
- # check whether myip parameter has valid IPAddr
94
- if params.has_key?("myip")
95
- begin
96
- IPAddr.new(params["myip"])
97
- myip = params["myip"]
98
- rescue ArgumentError
108
+ # check whether myip parameter has valid IPAddr
109
+ if params.has_key?("myip")
110
+ begin
111
+ IPAddr.new(params["myip"])
112
+ myip = params["myip"]
113
+ rescue ArgumentError
114
+ end
99
115
  end
100
116
  end
101
117
 
@@ -18,11 +18,13 @@ module Dyndnsd
18
18
  out << "@ IN SOA #{@dns} #{@email_addr} ( #{zone['serial']} 3h 5m 1w 1h )"
19
19
  out << "@ IN NS #{@dns}"
20
20
  out << ""
21
- zone['hosts'].each do |hostname,ip|
22
- ip = IPAddr.new(ip).native
23
- type = ip.ipv6? ? "AAAA" : "A"
24
- name = hostname.chomp('.' + @domain)
25
- out << "#{name} IN #{type} #{ip}"
21
+ zone['hosts'].each do |hostname,ips|
22
+ (ips.is_a?(Array) ? ips : [ips]).each do |ip|
23
+ ip = IPAddr.new(ip).native
24
+ type = ip.ipv6? ? "AAAA" : "A"
25
+ name = hostname.chomp('.' + @domain)
26
+ out << "#{name} IN #{type} #{ip}"
27
+ end
26
28
  end
27
29
  out << ""
28
30
  out << @additional_zone_content
@@ -11,9 +11,9 @@ module Dyndnsd
11
11
  return [200, {"Content-Type" => "text/plain"}, ["nohost"]] if state == :host_forbidden
12
12
  return [200, {"Content-Type" => "text/plain"}, ["notfqdn"]] if state == :hostname_malformed
13
13
  end
14
-
14
+
15
15
  def response_for_changes(states, ip)
16
- body = states.map { |state| "#{state} #{ip}" }.join("\n")
16
+ body = states.map { |state| "#{state} #{ip.is_a?(Array) ? ip.join(' ') : ip}" }.join("\n")
17
17
  return [200, {"Content-Type" => "text/plain"}, [body]]
18
18
  end
19
19
  end
@@ -11,9 +11,9 @@ module Dyndnsd
11
11
  return [403, {"Content-Type" => "text/plain"}, ["Forbidden"]] if state == :host_forbidden
12
12
  return [422, {"Content-Type" => "text/plain"}, ["Hostname malformed"]] if state == :hostname_malformed
13
13
  end
14
-
14
+
15
15
  def response_for_changes(states, ip)
16
- body = states.map { |state| state == :good ? "Changed to #{ip}" : "No change needed for #{ip}" }.join("\n")
16
+ body = states.map { |state| state == :good ? "Changed to #{ip.is_a?(Array) ? ip.join(' ') : ip}" : "No change needed for #{ip.is_a?(Array) ? ip.join(' ') : ip}" }.join("\n")
17
17
  return [200, {"Content-Type" => "text/plain"}, [body]]
18
18
  end
19
19
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Dyndnsd
3
- VERSION = "1.5.0"
3
+ VERSION = "1.6.0"
4
4
  end
data/spec/daemon_spec.rb CHANGED
@@ -170,8 +170,37 @@ describe Dyndnsd::Daemon do
170
170
 
171
171
  it 'uses clients remote IP address from X-Real-IP header if behind proxy' do
172
172
  authorize 'test', 'secret'
173
+
173
174
  get '/nic/update?hostname=foo.example.org', '', 'HTTP_X_REAL_IP' => '10.0.0.1'
174
175
  expect(last_response).to be_ok
175
176
  expect(last_response.body).to eq('good 10.0.0.1')
177
+
178
+ get '/nic/update?hostname=foo.example.org', '', 'HTTP_X_REAL_IP' => '2001:db8::1'
179
+ expect(last_response).to be_ok
180
+ expect(last_response.body).to eq('good 2001:db8::1')
181
+ end
182
+
183
+ it 'supports an IPv4 and an IPv6 address in one request' do
184
+ authorize 'test', 'secret'
185
+
186
+ get '/nic/update?hostname=foo.example.org&myip=1.2.3.4&myip6=2001:db8::1'
187
+ expect(last_response).to be_ok
188
+ expect(last_response.body).to eq("good 1.2.3.4 2001:db8::1")
189
+
190
+ get '/nic/update?hostname=foo.example.org&myip=BROKENIP&myip6=2001:db8::1'
191
+ expect(last_response).to be_ok
192
+ expect(last_response.body).to eq('nohost')
193
+
194
+ get '/nic/update?hostname=foo.example.org&myip=1.2.3.4&myip6=BROKENIP'
195
+ expect(last_response).to be_ok
196
+ expect(last_response.body).to eq('nohost')
197
+
198
+ get '/nic/update?hostname=foo.example.org&myip6=2001:db8::10'
199
+ expect(last_response).to be_ok
200
+ expect(last_response.body).to eq('nohost')
201
+
202
+ get '/nic/update?hostname=foo.example.org&myip=1.2.3.40'
203
+ expect(last_response).to be_ok
204
+ expect(last_response.body).to eq('good 1.2.3.40')
176
205
  end
177
206
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyndnsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Nicolai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-30 00:00:00.000000000 Z
11
+ date: 2016-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack