-
Notifications
You must be signed in to change notification settings - Fork 4
/
options.rb
327 lines (296 loc) · 11 KB
/
options.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# RubIRCd - An IRC server written in Ruby
# Copyright (C) 2013 Lloyd Dilley (see authors.txt for details)
# http://www.rubircd.rocks/
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
require 'yaml'
require_relative 'user'
require_relative 'utility'
# Handles parameters from options.yml
class Options
@admin_name = nil
@admin_nick = nil
@admin_email = nil
@network_name = nil
@server_name = nil
@server_description = nil
@listen_port = nil
@ssl_port = nil
@enable_starttls = nil
@max_clones = nil
@auto_join = nil
@cloak_host = nil
@debug_mode = nil
# If called_from_rehash is true, we make this method more resilient so it will not bring down the server while it is up
def self.parse(called_from_rehash)
begin
options_file = YAML.load_file('cfg/options.yml')
rescue => e
return e if called_from_rehash
puts 'failed. Unable to open options.yml file!'
exit!
end
@admin_name = options_file['admin_name']
@admin_nick = options_file['admin_nick']
@admin_email = options_file['admin_email']
@network_name = options_file['network_name']
@server_name = options_file['server_name']
@server_description = options_file['server_description']
unless called_from_rehash # changing these options while the server is already up is currently not supported
@listen_host = options_file['listen_host']
@listen_port = options_file['listen_port']
@ssl_port = options_file['ssl_port']
@io_type = options_file['io_type']
@debug_mode = options_file['debug_mode']
end
@enable_starttls = options_file['enable_starttls']
@max_connections = options_file['max_connections']
@max_clones = options_file['max_clones']
@cloak_host = options_file['cloak_host']
@auto_cloak = options_file['auto_cloak']
@auto_invisible = options_file['auto_invisible']
@auto_join = options_file['auto_join']
@control_hash = options_file['control_hash']
@server_hash = options_file['server_hash']
if @admin_name.nil?
error_text = '\nUnable to read admin_name option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @admin_nick.nil?
error_text = '\nUnable to read admin_nick option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @admin_email.nil?
error_text = '\nUnable to read admin_email option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @network_name.nil?
error_text = '\nUnable to read network_name option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @server_name.nil?
error_text = '\nUnable to read server_name option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @server_description.nil?
error_text = '\nUnable to read server_description option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @listen_port.nil?
error_text = '\nUnable to read listen_port option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @max_connections.nil?
error_text = '\nUnable to read max_connections option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @io_type.nil?
error_text = '\nUnable to read io_type option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @debug_mode.nil?
error_text = '\nUnable to read debug_mode option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @control_hash.nil?
error_text = '\nUnable to read control_hash option from options.yml file!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @listen_port <= 0 || @listen_port >= 65_536
error_text = '\nlisten_port value is out of range!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
unless @ssl_port.nil?
begin
if @ssl_port <= 0 || @ssl_port >= 65_536
error_text = '\nssl_port value is out of range!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
rescue
error_text = '\nInvalid ssl_port value!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
end
if @listen_port == @ssl_port
error_text = '\nlisten_port and ssl_port values cannot match!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @enable_starttls.to_s != 'true' && @enable_starttls.to_s != 'false'
error_text = '\nenable_starttls value should be set to either true or false.'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @max_connections < 10
error_text = '\nmax_connections value is set too low!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
unless @max_clones.nil?
if @max_clones < 1
error_text = '\nmax_clones value is set too low!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
end
unless @cloak_host.nil?
unless Utility.valid_hostname?(@cloak_host) || Utility.valid_address?(@cloak_host)
error_text = '\ncloak_host value is not a valid hostname or address!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
end
if @auto_cloak.to_s != 'true' && @auto_cloak.to_s != 'false'
error_text = '\nauto_cloak value should be set to either true or false.'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @auto_cloak.to_s == 'true' && @cloak_host.nil?
error_text = '\nauto_cloak value is set to true when cloak_host is not defined!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @auto_invisible.to_s != 'true' && @auto_invisible.to_s != 'false'
error_text = '\nauto_invisible value should be set to either true or false.'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if !@auto_join.nil? && !Channel.valid_channel_name?(@auto_join)
error_text = '\nauto_join value is not a valid channel name.'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @io_type.to_s == 'em'
error_text = '\nio_type \"em\" is not fully implemented yet!'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @io_type.to_s != 'em' && @io_type.to_s != 'cell' && @io_type.to_s != 'event' && @io_type.to_s != 'thread'
error_text = '\nio_type value should be set to either em, cell, event, or thread.'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
if @debug_mode.to_s != 'true' && @debug_mode.to_s != 'false'
error_text = '\ndebug_mode value should be set to either true or false.'
return Exception.new(error_text.lstrip) if called_from_rehash
puts error_text
exit!
end
end
class << self
attr_reader :admin_name, :admin_nick, :admin_email, :network_name, :server_name, :server_description,
:listen_host, :listen_port, :ssl_port, :enable_starttls, :max_connections, :max_clones,
:cloak_host, :auto_cloak, :auto_invisible, :auto_join, :io_type, :debug_mode, :control_hash,
:server_hash
end
end
# Handles data from modules.yml
class Modules
# If called_from_rehash is true, we do not want to exit the server process while it is up during a rescue
def self.parse(called_from_rehash)
begin
modules_file = YAML.load_file('cfg/modules.yml')
rescue => e
return e if called_from_rehash
Log.write(3, 'Unable to open modules.yml file!')
return
end
modules_file.each_value do |values|
values.each { |module_name| Command.handle_modload(nil, module_name) }
end
end
end
# Handles data from opers.yml
class Opers
# If called_from_rehash is true, we do not want to exit the server process while it is up during a rescue
def self.parse(called_from_rehash)
admin_count = 0
oper_count = 0
begin
opers_file = YAML.load_file('cfg/opers.yml')
rescue => e
return e if called_from_rehash
Log.write(3, 'Unable to open opers.yml file!')
return
end
opers_file.each do |key, value|
next unless key.to_s == 'admins' && !value.nil?
admin_count = value.length
value.each do |subkey|
if subkey['nick'].nil? || subkey['nick'] == ''
Log.write(3, 'Invalid nick in opers.yml file!')
end
if subkey['hash'].nil? || subkey['hash'] == '' || subkey['hash'].length < 32
Log.write(3, 'Invalid hash in opers.yml file!')
end
admin = Oper.new(subkey['nick'], subkey['hash'], subkey['host'])
Server.add_admin(admin)
end
next unless key.to_s == 'opers' && !value.nil?
oper_count = value.length
value.each do |subkey|
if subkey['nick'].nil? || subkey['nick'] == ''
Log.write(3, 'Invalid nick in opers.yml file!')
end
if subkey['hash'].nil? || subkey['hash'] == '' || subkey['hash'].length < 32
Log.write(3, 'Invalid hash in opers.yml file!')
end
oper = Oper.new(subkey['nick'], subkey['hash'], subkey['host'])
Server.add_oper(oper)
end
end
Log.write(2, "#{admin_count} admin entries loaded.")
Log.write(2, "#{oper_count} oper entries loaded.")
end
end