diff --git a/.rvmrc b/.rvmrc deleted file mode 100644 index 44a53e9..0000000 --- a/.rvmrc +++ /dev/null @@ -1 +0,0 @@ -rvm 1.9.3@SiriProxy --create diff --git a/Gemfile b/Gemfile index e6611e5..916f44a 100644 --- a/Gemfile +++ b/Gemfile @@ -3,26 +3,14 @@ source 'https://rubygems.org' gemspec # load plugins -require 'yaml' -require 'ostruct' -config_file = File.expand_path(File.join('~', '.siriproxy', 'config.yml')); - -unless File.exists?(config_file) - default_config = config_file - config_file = File.expand_path(File.join(File.dirname(__FILE__), 'config.example.yml')) - puts "[Notice - Configuration] ==================== Important Configuration Notice ==========================" - puts "[Notice - Configuration] '#{default_config}' not found. Using '#{config_file}'" - puts "[Notice - Configuration] " - puts "[Notice - Configuration] Remove this message by copying '#{config_file}' into '~/.siriproxy/'" - puts "[Notice - Configuration] ==============================================================================" -end +require 'siriproxy/configuration' gem 'cora', '0.0.4' -config = OpenStruct.new(YAML.load_file(File.expand_path(config_file))) -if config.plugins + +if SiriProxy.config.plugins puts "[Info - Configuration] Loading plugins -- If any fail to load, run `siriproxy bundle` (not `bundle install`) to resolve." - config.plugins.each do |plugin| + SiriProxy.config.plugins.each do |plugin| if plugin.is_a? String gem "siriproxy-#{plugin.downcase}" else diff --git a/lib/siriproxy.rb b/lib/siriproxy.rb index 87d00ed..3929c72 100644 --- a/lib/siriproxy.rb +++ b/lib/siriproxy.rb @@ -1,6 +1,7 @@ require 'eventmachine' require 'zlib' require 'pp' +require 'siriproxy/configuration' class String def to_hex(seperator=" ") @@ -12,10 +13,10 @@ class SiriProxy def initialize() # @todo shouldnt need this, make centralize logging instead - $LOG_LEVEL = $APP_CONFIG.log_level.to_i + $LOG_LEVEL = SiriProxy.config.log_level.to_i EventMachine.run do - if Process.uid == 0 && !$APP_CONFIG.user + if Process.uid == 0 && !SiriProxy.config.user puts "[Notice - Server] ======================= WARNING: Running as root =============================" puts "[Notice - Server] You should use -l or the config.yml to specify and non-root user to run under" puts "[Notice - Server] Running the server as root is dangerous." @@ -23,16 +24,16 @@ def initialize() end begin - listen_addr = $APP_CONFIG.listen || "0.0.0.0" - puts "[Info - Server] Starting SiriProxy on #{listen_addr}:#{$APP_CONFIG.port}..." - EventMachine::start_server(listen_addr, $APP_CONFIG.port, SiriProxy::Connection::Iphone, $APP_CONFIG.upstream_dns) { |conn| + listen_addr = SiriProxy.config.listen || "0.0.0.0" + puts "[Info - Server] Starting SiriProxy on #{listen_addr}:#{SiriProxy.config.port}..." + EventMachine::start_server(listen_addr, SiriProxy.config.port, SiriProxy::Connection::Iphone, SiriProxy.config.upstream_dns) { |conn| puts "[Info - Guzzoni] Starting conneciton #{conn.inspect}" if $LOG_LEVEL < 1 conn.plugin_manager = SiriProxy::PluginManager.new() conn.plugin_manager.iphone_conn = conn } retries = 0 - while $APP_CONFIG.server_ip && !$SP_DNS_STARTED && retries <= 5 + while SiriProxy.config.server_ip && !$SP_DNS_STARTED && retries <= 5 puts "[Info - Server] DNS server is not running yet, waiting #{2**retries} second#{'s' if retries > 1}..." sleep 2**retries retries += 1 @@ -43,16 +44,17 @@ def initialize() exit 1 end - EventMachine.set_effective_user($APP_CONFIG.user) if $APP_CONFIG.user + EventMachine.set_effective_user(SiriProxy.config.user) if SiriProxy.config.user puts "[Info - Server] SiriProxy up and running." rescue RuntimeError => err if err.message == "no acceptor" - raise "[Error - Server] Cannot start the server on port #{$APP_CONFIG.port} - are you root, or have another process on this port already?" + raise "[Error - Server] Cannot start the server on port #{SiriProxy.config.port} - are you root, or have another process on this port already?" else raise end end end end + end diff --git a/lib/siriproxy/command_line.rb b/lib/siriproxy/command_line.rb index e1e2aa8..f5973b6 100644 --- a/lib/siriproxy/command_line.rb +++ b/lib/siriproxy/command_line.rb @@ -1,12 +1,5 @@ require 'optparse' -require 'yaml' -require 'ostruct' - -# @todo want to make SiriProxy::Commandline without having to -# require 'siriproxy'. Im sure theres a better way. -class SiriProxy - -end +require 'siriproxy/configuration' class SiriProxy::CommandLine $LOG_LEVEL = 0 @@ -20,6 +13,7 @@ class SiriProxy::CommandLine Commands: server Start up the Siri proxy server +genconfig Generate the default configuration directory gencerts Generate a the certificates needed for SiriProxy bundle Install any dependancies needed by plugins console Launch the plugin test console @@ -32,12 +26,13 @@ class SiriProxy::CommandLine def initialize @branch = nil - parse_options + parse_options unless ARGV[0] == 'genconfig' command = ARGV.shift subcommand = ARGV.shift case command when 'server' then run_server(subcommand) when 'gencerts' then gen_certs + when 'genconfig' then gen_config when 'bundle' then run_bundle(subcommand) when 'console' then run_console when 'update' then update(subcommand) @@ -98,7 +93,7 @@ def run_server(subcommand='start') end def start_server - if $APP_CONFIG.server_ip + if SiriProxy.config.server_ip require 'siriproxy/dns' dns_server = SiriProxy::Dns.new dns_server.start() @@ -107,11 +102,15 @@ def start_server proxy.start() end + def gen_config + SiriProxy::Configuration.create_default + end + def gen_certs ca_name = @ca_name ||= "" command = File.join(File.dirname(__FILE__), '..', "..", "scripts", 'gen_certs.sh') sp_root = File.join(File.dirname(__FILE__), '..', "..") - puts `#{command} "#{sp_root}" "#{ca_name}"` + puts `#{command} "#{sp_root}" "#{ca_name}" "#{SiriProxy.config.config_path}"` end def update(directory=nil) @@ -145,7 +144,7 @@ def update(directory=nil) def dns require 'siriproxy/dns' - $APP_CONFIG.use_dns = true + SiriProxy.config.use_dns = true server = SiriProxy::Dns.new server.run(Logger::DEBUG) end @@ -157,37 +156,28 @@ def usage private def parse_options - config_file = File.expand_path(File.join('~', '.siriproxy', 'config.yml')); - - unless File.exists?(config_file) - default_config = config_file - config_file = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config.example.yml')) - end - - $APP_CONFIG = OpenStruct.new(YAML.load_file(config_file)) - # Google Public DNS servers - $APP_CONFIG.upstream_dns ||= %w[8.8.8.8 8.8.4.4] + SiriProxy.config.upstream_dns ||= %w[8.8.8.8 8.8.4.4] @branch = nil @option_parser = OptionParser.new do |opts| opts.on('-d', '--dns ADDRESS', '[server] Launch DNS server guzzoni.apple.com with ADDRESS (requires root)') do |ip| - $APP_CONFIG.server_ip = ip + SiriProxy.config.server_ip = ip end opts.on('-l', '--log LOG_LEVEL', '[server] The level of debug information displayed (higher is more)') do |log_level| - $APP_CONFIG.log_level = log_level + SiriProxy.config.log_level = log_level end opts.on('-L', '--listen ADDRESS', '[server] Address to listen on (central or node)') do |listen| - $APP_CONFIG.listen = listen + SiriProxy.config.listen = listen end opts.on('-D', '--upstream-dns SERVERS', Array, '[server] List of upstream DNS servers to use. Defaults to \'[8.8.8.8, 8.8.4.4]\'') do |servers| - $APP_CONFIG.upstream_dns = servers + SiriProxy.config.upstream_dns = servers end opts.on('-p', '--port PORT', '[server] Port number for server (central or node)') do |port_num| - $APP_CONFIG.port = port_num + SiriProxy.config.port = port_num end opts.on('-u', '--user USER', '[server] The user to run as after launch') do |user| - $APP_CONFIG.user = user + SiriProxy.config.user = user end opts.on('-b', '--branch BRANCH', '[update] Choose the branch to update from (default: master)') do |branch| @branch = branch @@ -230,7 +220,7 @@ def init_plugins pManager = SiriProxy::PluginManager.new pManager.plugins.each_with_index do |plugin, i| if plugin.respond_to?('plugin_init') - $APP_CONFIG.plugins[i]['init'] = plugin.plugin_init + SiriProxy.config.plugins[i]['init'] = plugin.plugin_init end end pManager = nil diff --git a/lib/siriproxy/configuration.rb b/lib/siriproxy/configuration.rb new file mode 100644 index 0000000..4dc2bfe --- /dev/null +++ b/lib/siriproxy/configuration.rb @@ -0,0 +1,122 @@ +require 'yaml' +require 'ostruct' + +class SiriProxy + def self.config=(configuration) + @@config = configuration + end + + def self.config + @@config + end +end + +class SiriProxy::Configuration + + attr_reader :config + + VALID_PATHS = [ + File.expand_path(File.join('~', '.siriproxy')), + File.join('/', 'etc', 'siriproxy.d') + ] + + + + + def initialize + @config_loaded = false + end + + def config_loaded? + !self.config.nil? + end + + def config_path + @config_path = find_config_path if @config_path.nil? + @config_path + end + + def find_config_path + # Check all possible configuration paths, higher priority first, + # returning the first valid path found + + SiriProxy::Configuration::VALID_PATHS.each do |path| + if File.exists?(path) + puts "Using configuration in #{path}" + return path + end + end + + puts "Configuration Error: No valid configuration could be found. Please run '#{$0} genconfig' to create one" + + raise "No config" + + exit 1 + end + + def config_file + File.join(config_path, 'config.yml') + end + + def certificate_file + File.join(config_path, 'server.passless.crt') + end + + def certificate_key_file + File.join(config_path, 'server.passless.key') + end + + def load_configuration + @config = OpenStruct.new(YAML.load_file(File.expand_path(config_file))) + end + + def method_missing(selector, *args) + load_configuration unless config_loaded? + @config.__send__(selector, *args) + end + + class << self + + def create_default + require 'readline' + require 'fileutils' + + puts "Generating default SiriProxy configuration\n" + path = get_preferred_path + + # Create a directory for the configuration and certificates to go in + puts "=> Creating #{path}" + FileUtils.mkdir(path) + + puts "=> Creating default config.yml" + default_config = File.join(File.dirname(__FILE__), '..', '..', 'config.example.yml') + FileUtils.cp(default_config, File.join(path, 'config.yml')) + + end + + def get_preferred_path + puts "New configuration location:" + + VALID_PATHS.each_with_index do |path, i| + puts "#{i+1}: #{path}" + end + + choice = nil + loop do + choice = Readline.readline("Location [1]: ") + break if choice=~/\d{1,}/ && choice.to_i > 0 && choice.to_i <= VALID_PATHS.length + + puts "Invalid choice. Please enter a choice between 1 and #{VALID_PATHS.length}" + end + + return VALID_PATHS[choice.to_i-1] + end + + + end + +end + + +# Prepare for lazy-loaded config here +SiriProxy.config = SiriProxy::Configuration.new diff --git a/lib/siriproxy/connection/iphone.rb b/lib/siriproxy/connection/iphone.rb index 837c112..0ec18ce 100644 --- a/lib/siriproxy/connection/iphone.rb +++ b/lib/siriproxy/connection/iphone.rb @@ -12,8 +12,8 @@ def initialize upstream_dns def post_init super - start_tls(:cert_chain_file => File.expand_path("~/.siriproxy/server.passless.crt"), - :private_key_file => File.expand_path("~/.siriproxy/server.passless.key"), + start_tls(:cert_chain_file => SiriProxy.config.certificate_file, + :private_key_file => SiriProxy.config.certificate_key_file, :verify_peer => false) end diff --git a/lib/siriproxy/dns.rb b/lib/siriproxy/dns.rb index 0518f54..c605dbf 100644 --- a/lib/siriproxy/dns.rb +++ b/lib/siriproxy/dns.rb @@ -11,7 +11,7 @@ def initialize servers = [] - $APP_CONFIG.upstream_dns.each { |dns_addr| + SiriProxy.config.upstream_dns.each { |dns_addr| servers << [:udp, dns_addr, 53] servers << [:tcp, dns_addr, 53] } @@ -45,7 +45,7 @@ def stop Thread.kill(@thread) end - def run(log_level=Logger::WARN,server_ip=$APP_CONFIG.server_ip) + def run(log_level=Logger::WARN,server_ip=SiriProxy.config.server_ip) if server_ip upstream = @upstream diff --git a/lib/siriproxy/plugin_manager.rb b/lib/siriproxy/plugin_manager.rb index 09b6578..6cba8f7 100644 --- a/lib/siriproxy/plugin_manager.rb +++ b/lib/siriproxy/plugin_manager.rb @@ -10,8 +10,8 @@ def initialize() def load_plugins() @plugins = [] - if $APP_CONFIG.plugins - $APP_CONFIG.plugins.each do |pluginConfig| + if SiriProxy.config.plugins + SiriProxy.config.plugins.each do |pluginConfig| begin if pluginConfig.is_a? String className = pluginConfig diff --git a/scripts/gen_certs.sh b/scripts/gen_certs.sh index eed3055..bd94d7f 100755 --- a/scripts/gen_certs.sh +++ b/scripts/gen_certs.sh @@ -1,10 +1,16 @@ #!/usr/bin/env bash commonName=$2 +SIRI_PROXY_SETTINGS=$3 if [ "${commonName}" == "" ] then commonName="SiriProxyCA" +else + if [ "${SIRI_PROXY_SETTINGS}" == ""] + then + SIRI_PROXY_SETTINGS=~/.siriproxy + fi fi # Feel free to change any of these defaults @@ -17,7 +23,6 @@ emailAddress="" #You probably don't need to modify these unless you know what you're doing. SIRI_PROXY_ROOT=$1 -SIRI_PROXY_SETTINGS=~/.siriproxy LOG_FILE=$SIRI_PROXY_SETTINGS/cert.log TMP_DIR=/tmp TMP_CA_DIR=/tmp/siriCA #THIS ($dir) ALSO MUST BE MODIFIED IN openssl.cnf IF YOU CHANGE IT!