wamupd 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg
data/CHANGELOG.md ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Jonathan Walker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ Wamupd
2
+ ======
3
+
4
+ Introduction
5
+ ------------
6
+
7
+ Wamupd was originally created by roguelazer - for the original application,
8
+ see http://www.roguelazer.com/code/wamupd/. This version is primarily forked
9
+ to support the stable versions of Ruby (1.9), mDNSResponder (258.18),
10
+ Avahi (0.6.29), D-Bus (1.4.6), and FreeBSD (8.2) at the time of writing. It
11
+ also fixes some threading issues, adds logging, rc.d support, and FreeBSD
12
+ packaging.
13
+
14
+ Requirements
15
+ ------------
16
+
17
+ * ruby19
18
+ * ruby-dbus *(see my fork on [GitHub](https://github.com/johnnywalker/ruby-dbus))*
19
+ * algorithms
20
+ * rubygems
21
+ * dnsruby
22
+ * logger
23
+
24
+ ruby-dbus v0.6.0 does _not_ work properly on FreeBSD due to a problem with the
25
+ initial null byte sent to D-Bus for unix socket authentication. FreeBSD
26
+ supports the SCM\_CREDS socket option, so a simple patch is required.
27
+
28
+ Installing
29
+ ----------
30
+
31
+ After cloning this repository, use gmake to create the wamupd package and then
32
+ install the resulting file:
33
+
34
+ git clone https://github.com/johnnywalker/wamupd
35
+ cd wamupd
36
+ gmake
37
+ sudo pkg_add wamupd.tbz
38
+
39
+ Once installed, create the configuration file using the distribution template
40
+ and enable the wamupd service in your /etc/rc.conf:
41
+
42
+ cd /usr/local/etc/
43
+ sudo cp wamupd.yaml.dist wamupd.yaml
44
+ sudo vim wamupd.yaml (edit appropriately)
45
+ sudo echo wamupd_enable="YES" >>/etc/rc.conf
46
+ sudo service wamupd start
47
+
48
+ Specify custom arguments to wamupd as needed using the wamupd\_flags entry in
49
+ /etc/rc.conf. In order to get more information on the arguments available, try this:
50
+
51
+ sudo service wamupd stop
52
+ sudo /usr/local/sbin/wamupd run -- -h
53
+
54
+ The default flags used are:
55
+
56
+ wamupd_flags="-c /usr/local/etc/wamupd.yaml -A /usr/local/etc/avahi/services -a -i"
57
+
58
+ A log is created at /var/log/wamupd.log, but this only contains small amounts
59
+ of information. In order to debug your configuration, make sure the service
60
+ isn't running and then execute the /usr/local/sbin/wamupd program in the
61
+ foreground (note: the typical arguments used are "-A -a -i" - the "--" separates
62
+ the daemon command from the script arguments):
63
+
64
+ sudo service wamupd stop
65
+ sudo /usr/local/sbin/wamupd run -- -A -a -i
66
+
67
+ To uninstall, simply use pkg_delete:
68
+
69
+ sudo pkg_delete wamupd
70
+
71
+ Usage
72
+ -----
73
+
74
+ Usage: wamupd run -- [options] service-file
75
+ -c, --config FILE Get configuration data from FILE
76
+ If FILE is not provided, defaults to /usr/local/etc/wamupd.yaml
77
+ -A, --avahi-services [DIRECTORY] Load Avahi service definitions from DIRECTORY
78
+ If DIRECTORY is not provided, defaults to /usr/local/etc/avahi/services
79
+ If the -A flag is omitted altogether, static records will not be added.
80
+ -i, --[no-]ip-addresses Enable/Disable Publishing A and AAAA records
81
+ -a, --avahi Load Avahi services over D-BUS
82
+ -h, --help Show this message
83
+
84
+ Configuration
85
+ -------------
86
+
87
+ Make a wamupd.yaml file in /usr/local/etc/ in normal YAML style. Available
88
+ parameters include:
89
+ - hostname: the hostname of this machine
90
+ - zone: the zone to write to
91
+ - dns\_server: the dns server that controls the above zone
92
+ - dns\_port: the port to talk to
93
+ - dnssec\_key\_name: the key name for DNSSEC. Do not specify if you're
94
+ not using DNSSEC
95
+ - dnssec\_key\_hmac: the key value for DNSSEC.
96
+ - ttl: the standard TTL to use.
97
+ - transport: either "tcp" or "udp"
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ gemspec = eval(File.read(Dir["*.gemspec"].first))
2
+
3
+
4
+ desc "Validate the gemspec"
5
+ task :gemspec do
6
+ gemspec.validate
7
+ end
8
+
9
+ desc "Build gem locally"
10
+ task :build => :gemspec do
11
+ system "gem build #{gemspec.name}.gemspec"
12
+ FileUtils.mkdir_p "pkg"
13
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg"
14
+ end
15
+
16
+ desc "Install gem locally"
17
+ task :install => :build do
18
+ system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
19
+ end
20
+
21
+ desc "Clean automatically generated files"
22
+ task :clean do
23
+ FileUtils.rm_rf "pkg"
24
+ end
data/bin/wamupd ADDED
@@ -0,0 +1,314 @@
1
+ #!/usr/local/bin/ruby
2
+ # Copyright (C) 2009-2010 James Brown <roguelazer@roguelazer.com>.
3
+ #
4
+ # This file is part of wamupd.
5
+ #
6
+ # wamupd is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # wamupd is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with wamupd. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+ # == Synopsis
20
+ #
21
+ # wamupd: Read avahi service descriptions and current IP information, then
22
+ # use that information to generate Wide-Area mDNS Updates
23
+ #
24
+ # == Usage
25
+ #
26
+ # wamupd service-file
27
+ #
28
+ # -a, --avahi
29
+ # Load Avahi services over D-BUS
30
+ # -A DIRECTORY, --avahi-services DIRECTORY
31
+ # Load Avahi service definitions from DIRECTORY
32
+ # If DIRECTORY is not provided, defaults to /etc/avahi/services
33
+ # If the -A flag is omitted altogether, static records will not be added.
34
+ # -c FILE, --config FILE:
35
+ # Get configuration data from FILE
36
+ # -i, --ip-addreses (or --no-ip-addresses)
37
+ # Enable/Disable Publishing A and AAAA records
38
+ # -h, --help:
39
+ # Show this help
40
+
41
+ require 'rubygems'
42
+ require 'daemons'
43
+
44
+ options = {
45
+ :dir_mode => :system,
46
+ :multiple => false,
47
+ }
48
+
49
+ Daemons.run_proc('wamupd', options) do
50
+
51
+ require "wamupd"
52
+ require "getoptlong"
53
+ require "optparse"
54
+ require "singleton"
55
+ require "timeout"
56
+ require "logger"
57
+
58
+ # Wamupd is a module that is used to namespace all of the wamupd code.
59
+ module Wamupd
60
+ DEFAULT_CONFIG_FILE = "/usr/local/etc/wamupd.yaml"
61
+ DEFAULT_AVAHI_SERVICES_DIR = "/usr/local/etc/avahi/services"
62
+
63
+ app = Daemons.controller.group.applications.first
64
+
65
+ Options = Struct.new(:config, :ip_addresses, :avahi, :avahi_services_dir, :avahi_services)
66
+ $options = Options.new
67
+ $options.config = DEFAULT_CONFIG_FILE
68
+ $options.ip_addresses = false
69
+ $options.avahi = false
70
+ $options.avahi_services = false
71
+ $options.avahi_services_dir = DEFAULT_AVAHI_SERVICES_DIR
72
+
73
+ OptionParser.new do |opts|
74
+ opts.banner = "Usage: wamupd run -- [options] service-file"
75
+
76
+ opts.on("-c", "--config FILE",
77
+ "Get configuration data from FILE",
78
+ "If FILE is not provided, defaults to " + DEFAULT_CONFIG_FILE) do |cfg|
79
+ $options.config = cfg
80
+ end
81
+
82
+ opts.on("-A", "--avahi-services [DIRECTORY]",
83
+ "Load Avahi service definitions from DIRECTORY",
84
+ " If DIRECTORY is not provided, defaults to " + DEFAULT_AVAHI_SERVICES_DIR,
85
+ " If the -A flag is omitted altogether, static records will not be added.") do |services|
86
+ if services then
87
+ $options.avahi_services_dir = services
88
+ end
89
+ $options.avahi_services = true
90
+ end
91
+
92
+ opts.on("-i", "--[no-]ip-addresses", "Enable/Disable Publishing A and AAAA records") do |ips|
93
+ $options.ip_addresses = ips
94
+ end
95
+
96
+ opts.on("-a", "--avahi", "Load Avahi services over D-BUS") do |avahi|
97
+ $options.avahi = true
98
+ end
99
+
100
+ opts.on("-h", "--help", "Show this message") do
101
+ puts opts
102
+ exit
103
+ end
104
+ end.parse!(app.app_argv)
105
+
106
+ unless Daemons.controller.options[:ontop]
107
+ $logger = Logger.new(app.logfile, 'monthly')
108
+ $logger.level = Logger::INFO
109
+ else
110
+ $logger = Logger.new(STDOUT)
111
+ $logger.level = Logger::DEBUG
112
+ end
113
+
114
+ CurrentProcess.change_privilege('nobody', 'nogroup')
115
+
116
+
117
+ # Main wamupd object
118
+ class Main
119
+ include Singleton
120
+
121
+ # Process command-line objects
122
+ def process_args
123
+ @config_file = $options.config
124
+ @avahi_dir = $options.avahi_services_dir
125
+ @bools[:ip] = $options.ip_addresses
126
+ @bools[:avahi] = $options.avahi
127
+ @bools[:avahi_services] = $options.avahi_services
128
+ end
129
+
130
+ # Construct the object and process all command-line options
131
+ def initialize
132
+ @exiting = false
133
+
134
+ @bools = {
135
+ :publish=>false,
136
+ :unpublish=>false,
137
+ :avahi=>false,
138
+ :avahi_services=>false,
139
+ :ip=>false
140
+ }
141
+
142
+ $settings = MainSettings.instance()
143
+
144
+ process_args()
145
+
146
+ # Load settings
147
+ if (not File.exists?(@config_file))
148
+ $stderr.puts "Could not find configuration file #{@config_file}"
149
+ $stderr.puts "Try running with --help?"
150
+ exit
151
+ end
152
+ $settings.load_from_yaml(@config_file)
153
+
154
+ if (@bools[:ip])
155
+ @d = DNSIpController.new()
156
+ end
157
+
158
+ if (@bools[:avahi] or @bools[:avahi_services])
159
+ @a = Wamupd::DNSAvahiController.new()
160
+ end
161
+
162
+ if (@bools[:avahi_services])
163
+ @avahi_services = AvahiServiceFile.load_from_directory(@avahi_dir)
164
+ end
165
+ :w
166
+
167
+ if (@bools[:avahi])
168
+ @am = Wamupd::AvahiModel.new
169
+ end
170
+ end
171
+
172
+ # Actually run the program.
173
+ #
174
+ # This call doesn't return until SIGTERM is caught.
175
+ def run
176
+ $logger.debug "Starting main function"
177
+
178
+ update_queue = Queue.new
179
+ DNSUpdate.queue = update_queue
180
+
181
+ threads = []
182
+ if (@bools[:avahi] or @bools[:avahi_services])
183
+ # Handle the DNS controller
184
+ threads << Thread.new {
185
+ @a.on(:added) { |item,id|
186
+ $logger.debug('dns_controller') { "Added #{item.type_in_zone_with_name} (id=\"#{id}\")" }
187
+ }
188
+ @a.on(:deleted) { |item|
189
+ $logger.debug('dns_controller') { "Deleted #{item.type_in_zone_with_name}" }
190
+ }
191
+ @a.on(:renewed) { |item|
192
+ $logger.debug('dns_controller') { "Renewed #{item.type_in_zone_with_name}" }
193
+ }
194
+ @a.run
195
+ }
196
+
197
+ # Lease maintenance
198
+ threads << Thread.new {
199
+ @a.update_leases
200
+ }
201
+ end
202
+
203
+ publish_static
204
+
205
+ if (@bools[:avahi])
206
+ @am.on(:added) { |avahi_service|
207
+ @a.queue << Wamupd::Action.new(Wamupd::ActionType::ADD, avahi_service)
208
+ $logger.debug('avahi_listener') { "Found service: #{avahi_service}" }
209
+ }
210
+ # Handle listening to D-BUS
211
+ threads << Thread.new {
212
+ $logger.debug('dbus_listener') { "Starting" }
213
+ @am.run
214
+ }
215
+ end
216
+
217
+ if (@bools[:ip])
218
+ threads << Thread.new{
219
+ $logger.debug('ip_controller') { "Starting" }
220
+ @d.update_leases
221
+ }
222
+ end
223
+
224
+ threads << Thread.new {
225
+ while (1)
226
+ response_id, response, exception = update_queue.pop
227
+ $logger.debug('reporter') { "Got back response #{response_id}" }
228
+ if (not exception.nil?)
229
+ if (exception.kind_of?(Dnsruby::TsigNotSignedResponseError))
230
+ # Do nothing
231
+ else
232
+ $logger.warn('reporter') { "Error: #{exception}" }
233
+ $logger.warn('reporter') { response }
234
+ end
235
+ end
236
+ if (response.rcode != Dnsruby::RCode::NOERROR)
237
+ $logger.warn('reporter') { "Got an unexpected rcode (#{response.rcode})" }
238
+ $logger.warn('reporter') { response }
239
+ end
240
+ if DNSUpdate.outstanding.delete(response_id).nil?
241
+ $logger.warn('reporter') { "Got back an unexpected response ID" }
242
+ $logger.warn('reporter') { response }
243
+ end
244
+ end
245
+ }
246
+
247
+ stop_proc = proc { stop_threads(threads) }
248
+ trap(1, stop_proc)
249
+ trap(2, stop_proc)
250
+ trap(15, stop_proc)
251
+
252
+ $logger.info "Wamupd started"
253
+ while (!@exiting)
254
+ sleep(10)
255
+ end
256
+
257
+ threads.each { |t|
258
+ t.join
259
+ }
260
+
261
+ exit
262
+ end
263
+
264
+ def stop_threads(threads)
265
+ if (not @exiting) then
266
+ @exiting = true
267
+
268
+ $logger.info "Unregistering services..."
269
+ if (@bools[:avahi] or @bools[:avahi_services])
270
+ @a.exit
271
+ end
272
+ if (@bools[:avahi])
273
+ @am.exit
274
+ end
275
+ if (@bools[:ip])
276
+ @d.unpublish
277
+ end
278
+ sleep($settings.max_dns_response_time)
279
+ threads.each { |t|
280
+ t.exit
281
+ }
282
+ $logger.info "Wamupd stopped"
283
+ end
284
+ end
285
+
286
+ def publish_static
287
+ if (@d)
288
+ @d.on(:added) { |type,address|
289
+ $logger.debug('static_publisher') { "Added #{type} record for #{address}" }
290
+ }
291
+ @d.on(:removed) { |type,address|
292
+ $logger.debug('static_publisher') { "Removed #{type} record for #{address}" }
293
+ }
294
+ @d.publish
295
+ end
296
+
297
+ if (@avahi_services)
298
+ @avahi_services.each { |avahi_service_file|
299
+ avahi_service_file.each { |avahi_service|
300
+ @a.queue << Wamupd::Action.new(Wamupd::ActionType::ADD, avahi_service)
301
+ $logger.debug('static_publisher') { "Found static Avahi service: #{avahi_service}" }
302
+ }
303
+ }
304
+ end
305
+ end
306
+
307
+ private :process_args, :publish_static, :exit
308
+ end
309
+ end
310
+
311
+
312
+ w = Wamupd::Main.instance
313
+ w.run
314
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2010 James Brown <roguelazer@roguelazer.com>.
2
+ #
3
+ # This file is part of wamupd.
4
+ #
5
+ # wamupd is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # wamupd is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with wamupd. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module Wamupd
19
+ # Possible actions in the system. Essentially, an enum
20
+ class ActionType
21
+ ADD=1
22
+ DELETE=2
23
+ QUIT=4
24
+ end
25
+
26
+ # A command wrapper
27
+ class Action
28
+ # The action to be performed. A Wamupd::ActionType
29
+ attr_reader :action
30
+
31
+ # The associated record (might be an AvahiService, or whatever else
32
+ # is appropriate). Might be nil
33
+ attr_reader :record
34
+
35
+ def initialize(action, record=nil)
36
+ @action=action
37
+ @record=record
38
+ end
39
+ end
40
+ end