sheepsafe 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ === 0.1.0
2
+
3
+ - Initial release.
4
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Nick Sieger
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Sheepsafe
2
+ =========
3
+
4
+ http://github.com/nicksieger/sheepsafe
5
+
6
+ ## Description
7
+
8
+ Sheepsafe is a small utility to keep you safe from [FireSheep][]!
9
+
10
+ Sheepsafe was built to automate the task of switching your network
11
+ configuration to use a SOCKS proxy whenever you join an untrusted
12
+ network.
13
+
14
+ Sheepsafe works by keeping a configuration of known safe wireless
15
+ networks. When you join an untrusted network, Sheepsafe switches to a
16
+ network location that has a SOCKS proxy configured and starts a SOCKS
17
+ proxy by SSH'ing into a remote server, thus protecting your browsing
18
+ traffic from FireSheep and other snoopers on the local network. When
19
+ you switch back to a safe network, Sheepsafe switches back to the
20
+ default, trusted location and shuts down the SOCKS proxy.
21
+
22
+ You could probably use something like [Marco Polo][polo] for this too,
23
+ but this setup Works For Me.
24
+
25
+ ## Requirements
26
+
27
+ - Mac OS X. That's what I run. You'll have to cook something else up
28
+ for a different OS. Tested on 10.6.
29
+ - An SSH account on a remote server that can serve as a SOCKS proxy
30
+ through which to tunnel traffic. Typically this can be an EC2
31
+ server, a VPS, or some other cloud instance.
32
+ - Ruby 1.8.7 or greater. The Mac OS X system-installed Ruby is
33
+ preferred as the OS will be launching Sheepsafe in the background.
34
+
35
+ ## Install
36
+
37
+ - First install the gem: `sudo gem install sheepsafe`. It's
38
+ recommended to install using the system Ruby to minimize
39
+ difficulties informing launchd about an [RVM][] or some other
40
+ package manager.
41
+ - After installing the gem, run `sheepsafe install` and follow the
42
+ prompts for configuring Sheepsafe.
43
+
44
+ ### Setting up the "Untrusted" location
45
+
46
+ One manual step that you need to do during installation is to create
47
+ an "Untrusted" location for Sheepsafe to configure and use when you're
48
+ on an untrusted network. Sheepsafe will prompt you to do these steps
49
+ during installation.
50
+
51
+ ![Edit locations...](http://github.com/nicksieger/sheepsafe/raw/master/doc/edit-locations.jpg)
52
+
53
+ ![Add Untrusted and Apply...](http://github.com/nicksieger/sheepsafe/raw/master/doc/add-untrusted-apply.jpg)
54
+
55
+ ## Growl
56
+
57
+ If you wish to receive Growl notifications when Sheepsafe is switching
58
+ your location, be sure to install the `growlnotify` utility from the
59
+ "Extras" folder in the Growl .dmg.
60
+
61
+ ## Post-install
62
+
63
+ Be sure you configure your applications to use system-wide proxy
64
+ settings for making connections, where applicable.
65
+
66
+ ## Uninstall
67
+
68
+ - Run `sheepsafe uninstall` to unregister the Launchd task and remove
69
+ Sheepsafe vestiges from your system.
70
+
71
+ [FireSheep]: http://codebutler.com/firesheep
72
+ [RVM]: http://rvm.beginrescueend.com/
73
+ [polo]: http://www.symonds.id.au/marcopolo/
@@ -0,0 +1,104 @@
1
+ require 'date'
2
+ require 'rake/clean'
3
+
4
+ #############################################################################
5
+ #
6
+ # Helper functions
7
+ #
8
+ #############################################################################
9
+
10
+ def name
11
+ @name ||= Dir['*.gemspec'].first.split('.').first
12
+ end
13
+
14
+ def version
15
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
16
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
17
+ end
18
+
19
+ def date
20
+ Date.today.to_s
21
+ end
22
+
23
+ def rubyforge_project
24
+ "jruby-extras"
25
+ end
26
+
27
+ def gemspec_file
28
+ "#{name}.gemspec"
29
+ end
30
+
31
+ def gem_file
32
+ "#{name}-#{version}*.gem"
33
+ end
34
+
35
+ def replace_header(head, header_name)
36
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
37
+ end
38
+
39
+ #############################################################################
40
+ #
41
+ # Standard tasks
42
+ #
43
+ #############################################################################
44
+
45
+ task :default => :spec
46
+
47
+ require 'rspec/core/rake_task'
48
+ RSpec::Core::RakeTask.new do |t|
49
+ end
50
+
51
+ require 'rake/rdoctask'
52
+ Rake::RDocTask.new do |rdoc|
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "#{name} #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
58
+
59
+ task :release => :build do
60
+ unless `git branch` =~ /^\* master$/
61
+ puts "You must be on the master branch to release!"
62
+ exit!
63
+ end
64
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
65
+ sh "git tag v#{version}"
66
+ sh "git push origin master"
67
+ sh "git push origin v#{version}"
68
+ sh "gem push pkg/#{name}-#{version}.gem"
69
+ end
70
+
71
+ task :build => :gemspec do
72
+ sh "mkdir -p pkg"
73
+ sh "gem build #{gemspec_file}"
74
+ sh "mv #{gem_file} pkg"
75
+ end
76
+ CLEAN << 'pkg'
77
+
78
+ task :gemspec do
79
+ # read spec file and split out manifest section
80
+ spec = File.read(gemspec_file)
81
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
82
+
83
+ # replace name version and date
84
+ replace_header(head, :name)
85
+ replace_header(head, :version)
86
+ replace_header(head, :date)
87
+ #comment this out if your rubyforge_project has a different name
88
+ replace_header(head, :rubyforge_project)
89
+
90
+ # determine file list from git ls-files
91
+ files = `git ls-files`.
92
+ split("\n").
93
+ sort.
94
+ reject { |file| file =~ /^\./ }.
95
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
96
+ map { |file| " #{file}" }.
97
+ join("\n")
98
+
99
+ # piece file back together and write
100
+ manifest = " s.files = %w[\n#{files}\n ]\n"
101
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
102
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
103
+ puts "Updated #{gemspec_file}"
104
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ begin
5
+ require 'sheepsafe'
6
+ rescue LoadError
7
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
8
+ require 'sheepsafe'
9
+ end
10
+
11
+ if ARGV.length == 1 && ARGV.first =~ /^(un)?install$/
12
+ installer = Sheepsafe::Installer.new
13
+ ARGV.first == 'install' ? installer.run : installer.uninstall
14
+ else
15
+ # Allow network changes to sink in for a couple more seconds
16
+ sleep 2
17
+ Sheepsafe::Controller.new.run
18
+ end
Binary file
@@ -0,0 +1,9 @@
1
+ module Sheepsafe
2
+ VERSION = "0.1.0"
3
+ end
4
+
5
+ require 'sheepsafe/config'
6
+ require 'sheepsafe/controller'
7
+ require 'sheepsafe/installer'
8
+ require 'sheepsafe/network'
9
+ require 'sheepsafe/status'
@@ -0,0 +1,36 @@
1
+ require 'yaml'
2
+
3
+ module Sheepsafe
4
+ class Config
5
+ FILE = File.expand_path('~/.sheepsafe.yml')
6
+ DEFAULT_CONFIG = {"untrusted_location" => "Untrusted", "socks_port" => "9999"}
7
+ ATTRS = %w(trusted_location untrusted_location last_network ssh_host socks_port)
8
+ ARRAY_ATTRS = %w(trusted_names)
9
+
10
+ def self.load_config
11
+ File.open(FILE) {|f| YAML.load(f) }
12
+ rescue
13
+ raise "Unable to read ~/sheepsafe.yml; please run sheepsafe-install"
14
+ end
15
+
16
+ attr_reader :config
17
+
18
+ def initialize(hash = nil)
19
+ @config = DEFAULT_CONFIG.merge(hash || self.class.load_config)
20
+ end
21
+
22
+ ATTRS.each do |m|
23
+ define_method(m) { config[m] }
24
+ define_method("#{m}=") {|v| config[m] = v}
25
+ end
26
+
27
+ ARRAY_ATTRS.each do |m|
28
+ define_method(m) { config[m] ||= [] }
29
+ define_method("#{m}=") {|v| config[m] = [v].flatten}
30
+ end
31
+
32
+ def write
33
+ File.open(FILE, "w") {|f| f << YAML.dump(@config) }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,89 @@
1
+ require 'daemons'
2
+ require 'logger'
3
+ require 'growl'
4
+
5
+ module Sheepsafe
6
+ class Controller
7
+ LOG_FILE = Sheepsafe::Config::FILE.sub(/\.yml/, '.log')
8
+
9
+ def initialize(config = nil, status = nil, logger = nil)
10
+ @config = config || Sheepsafe::Config.new
11
+ @status = status || Sheepsafe::Status.new(@config)
12
+ @logger = logger || begin
13
+ STDOUT.reopen(File.open(LOG_FILE, (File::WRONLY | File::APPEND)))
14
+ Logger.new(STDOUT)
15
+ end
16
+ end
17
+
18
+ def run
19
+ log("Sheepsafe starting")
20
+ if network_up?
21
+ if network_changed?
22
+ if switch_to_trusted?
23
+ notify_ok "Switching to #{@config.trusted_location} location"
24
+ system "scselect #{@config.trusted_location}"
25
+ bring_socks_proxy 'down'
26
+ elsif switch_to_untrusted?
27
+ notify_warning "Switching to #{@config.untrusted_location} location"
28
+ bring_socks_proxy 'up'
29
+ system "scselect #{@config.untrusted_location}"
30
+ end
31
+ @config.last_network = @status.current_network
32
+ @config.write
33
+ end
34
+ else
35
+ log("AirPort is off")
36
+ end
37
+ log("Sheepsafe finished")
38
+ end
39
+
40
+ def network_up?
41
+ @status.network_up?
42
+ end
43
+
44
+ def network_changed?
45
+ @status.current_network != @config.last_network
46
+ end
47
+
48
+ def switch_to_trusted?
49
+ @status.current_network.trusted?
50
+ end
51
+
52
+ def switch_to_untrusted?
53
+ !@status.current_network.trusted?
54
+ end
55
+
56
+ def bring_socks_proxy(direction)
57
+ Daemons.run_proc '.sheepsafe.proxy', :ARGV => [direction == 'up' ? 'start' : 'stop'], :dir_mode => :normal, :dir => ENV['HOME'] do
58
+ log("Starting ssh -ND #{@config.socks_port} #{@config.ssh_host}")
59
+ exec("ssh -ND #{@config.socks_port} #{@config.ssh_host}")
60
+ end
61
+ end
62
+
63
+ def proxy_running?
64
+ File.exist?("#{ENV['HOME']}/.sheepsafe.proxy.pid")
65
+ end
66
+
67
+ def notify_ok(msg)
68
+ check_growl_installed
69
+ Growl.notify_ok(msg)
70
+ log(msg)
71
+ end
72
+
73
+ def notify_warning(msg)
74
+ check_growl_installed
75
+ Growl.notify_warning(msg)
76
+ log(msg)
77
+ end
78
+
79
+ def check_growl_installed
80
+ unless Growl.installed?
81
+ log("WARNING: Growl not installed (probably couldn't find growlnotify in PATH: #{ENV['PATH']})")
82
+ end
83
+ end
84
+
85
+ def log(msg)
86
+ @logger.info(msg)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,153 @@
1
+ module Sheepsafe
2
+ class Installer
3
+ PLIST_FILE = File.expand_path("~/Library/LaunchAgents/sheepsafe.plist")
4
+
5
+ attr_reader :config, :status, :controller
6
+
7
+ def initialize
8
+ require 'highline/import'
9
+ @config = File.readable?(Sheepsafe::Config::FILE) ? Sheepsafe::Config.new : Sheepsafe::Config.new({})
10
+ @status = Sheepsafe::Status.new(@config)
11
+ @controller = Sheepsafe::Controller.new @config, @status, Logger.new(Sheepsafe::Controller::LOG_FILE)
12
+ update_config_with_status
13
+ end
14
+
15
+ def run
16
+ intro_message
17
+ config_prompts
18
+ manual_network_location_prompt
19
+ setup_untrusted_location
20
+ write_config
21
+ write_launchd_plist
22
+ register_launchd_task
23
+ announce_done
24
+ end
25
+
26
+ def intro_message
27
+ say(<<-MSG)
28
+ Welcome to Sheepsafe!
29
+
30
+ So you want to protect yourself from FireSheep snoopers like me, eh?
31
+ Follow the prompts to get started.
32
+ MSG
33
+ end
34
+
35
+ def config_prompts
36
+ say "First thing we need is the name of a server you can reach via SSH."
37
+
38
+ config.ssh_host = ask "SSH connection (server name or user@server) >\n" do |q|
39
+ q.default = config.ssh_host
40
+ end
41
+
42
+ say "Testing connectivitity to #{config.ssh_host}..."
43
+ system "ssh #{config.ssh_host} true"
44
+ unless $?.success?
45
+ abort "Sorry! that ssh host was no good."
46
+ end
47
+
48
+ config.socks_port = ask "Ok, next we need to pick a port on localhost where the proxy runs >\n" do |q|
49
+ q.default = config.socks_port || 9999
50
+ end
51
+
52
+ config.trusted_location = ask "Next, a name for the \"trusted\" network location >\n" do |q|
53
+ q.default = config.trusted_location
54
+ end
55
+
56
+ config.trusted_names = ask "Next, one or more network names (blank line to stop, RET for #{@names.inspect}) >\n" do |q|
57
+ q.gather = ""
58
+ end
59
+ config.trusted_names = @names if config.trusted_names.empty?
60
+ end
61
+
62
+ def manual_network_location_prompt
63
+ say "Next, I need you to create and switch to the \"Untrusted\" location in Network preferences."
64
+ system "open /System/Library/PreferencePanes/Network.prefPane"
65
+ ask "Press ENTER when done."
66
+ end
67
+
68
+ def setup_untrusted_location
69
+ if agree "Next, I'll set up the SOCKS proxy in the \"Untrusted\" location for you. OK\? (yes/no)\n"
70
+ system "networksetup -setsocksfirewallproxy AirPort localhost #{config.socks_port}"
71
+ end
72
+ end
73
+
74
+ def write_config
75
+ say "Saving configuration to #{Sheepsafe::Config::FILE}..."
76
+ config.write
77
+ end
78
+
79
+ # Write a launchd plist file to .~/Library/LaunchAgents/sheepsafe.plist.
80
+ #
81
+ # For details see http://tech.inhelsinki.nl/locationchanger/
82
+ def write_launchd_plist
83
+ say "Setting up launchd configuration file #{PLIST_FILE}..."
84
+ plist = <<-PLIST
85
+ <?xml version="1.0" encoding="UTF-8"?>
86
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
87
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
88
+ <plist version="1.0">
89
+ <dict>
90
+ <key>Label</key>
91
+ <string>org.rubygems.sheepsafe</string>
92
+ <key>ProgramArguments</key>
93
+ <array>
94
+ <string>#{sheepsafe_bin_path}</string>
95
+ </array>
96
+ <key>WatchPaths</key>
97
+ <array>
98
+ <string>/Library/Preferences/SystemConfiguration</string>
99
+ </array>
100
+ <!-- We specify PATH here because /usr/local/bin, where grownotify -->
101
+ <!-- is usually installed, is not in the script path by default. -->
102
+ <key>EnvironmentVariables</key>
103
+ <dict>
104
+ <key>PATH</key><string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/bin</string>
105
+ </dict>
106
+ </dict>
107
+ </plist>
108
+ PLIST
109
+ File.open(PLIST_FILE, "w") {|f| f << plist }
110
+ end
111
+
112
+ # Register the task with launchd.
113
+ def register_launchd_task
114
+ say "Registering #{PLIST_FILE}"
115
+ system "launchctl load #{PLIST_FILE}"
116
+ end
117
+
118
+ def announce_done
119
+ controller.run # Choose the right network and get things going
120
+ say("Sheepsafe installation done!")
121
+ end
122
+
123
+ def uninstall
124
+ if controller.proxy_running?
125
+ say "Shutting down SOCKS proxy..."
126
+ controller.bring_socks_proxy 'down'
127
+ end
128
+ if File.exist?(PLIST_FILE)
129
+ say "Uninstalling Sheepsafe from launchd..."
130
+ system "launchctl unload #{PLIST_FILE}"
131
+ File.unlink PLIST_FILE rescue nil
132
+ end
133
+ Dir['~/.sheepsafe.*'].each {|f| File.unlink f rescue nil}
134
+ say "Uninstall finished."
135
+ end
136
+
137
+ private
138
+ def update_config_with_status
139
+ unless config.trusted_location
140
+ config.trusted_location = status.current_location
141
+ end
142
+ @names = [status.current_network.current_ssid, status.current_network.current_bssid]
143
+ end
144
+
145
+ def sheepsafe_bin_path
146
+ begin
147
+ Gem.bin_path('sheepsafe')
148
+ rescue Exception
149
+ File.expand_path('../../../bin/sheepsafe', __FILE__)
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,25 @@
1
+ module Sheepsafe
2
+ class Network
3
+ def initialize(config = nil)
4
+ @data = YAML.load(`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I`.gsub(/^\s*([^:]+)/, '"\1"'))
5
+ @config = config || Sheepsafe::Config.new({})
6
+ end
7
+
8
+ def trusted?
9
+ @config.trusted_names.include?(current_ssid) ||
10
+ @config.trusted_names.include?(current_bssid)
11
+ end
12
+
13
+ def up?
14
+ @data['AirPort'] != false
15
+ end
16
+
17
+ def current_ssid
18
+ @data['SSID']
19
+ end
20
+
21
+ def current_bssid
22
+ @data['BSSID']
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module Sheepsafe
2
+ class Status
3
+ attr_reader :current_location, :current_network
4
+
5
+ def initialize(config = nil)
6
+ @current_location = `networksetup -getcurrentlocation`.chomp
7
+ @current_network = Network.new config
8
+ end
9
+
10
+ def network_up?
11
+ @current_network.up?
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,67 @@
1
+ # -*- encoding: utf-8 ; mode: ruby -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'sheepsafe'
5
+ s.version = '0.1.0'
6
+ s.date = '2010-10-26'
7
+
8
+ s.rubyforge_project = %q{caldersphere}
9
+
10
+ s.summary = "Makes sure you're safe from FireSheep!"
11
+ s.description = "Automatically toggle network locations and start a SOCKS proxy on untrusted networks. Mac OS X only."
12
+
13
+ s.authors = ["Nick Sieger"]
14
+ s.email = 'nick@nicksieger.com'
15
+ s.homepage = 'http://github.com/nicksieger/sheepsafe'
16
+ s.require_paths = %w[lib]
17
+ s.rdoc_options = ["--charset=UTF-8"]
18
+ s.extra_rdoc_files = %w[README.md LICENSE]
19
+ s.executables = ["sheepsafe"]
20
+ s.default_executable = "sheepsafe"
21
+
22
+ s.post_install_message = %[
23
+ ===========================================================================
24
+ Welcome to Sheepsafe!
25
+
26
+ =8P <=== (That\'s a sheep emoji.)
27
+
28
+ If this is your first time using Sheepsafe, you probably want to set it up.
29
+
30
+ To do that, run \`sheepsafe install\' now.
31
+ ===========================================================================
32
+ ]
33
+
34
+ # = MANIFEST =
35
+ s.files = %w[
36
+ History.txt
37
+ LICENSE
38
+ README.md
39
+ Rakefile
40
+ bin/sheepsafe
41
+ doc/add-untrusted-apply.jpg
42
+ doc/edit-locations.jpg
43
+ lib/sheepsafe.rb
44
+ lib/sheepsafe/config.rb
45
+ lib/sheepsafe/controller.rb
46
+ lib/sheepsafe/installer.rb
47
+ lib/sheepsafe/network.rb
48
+ lib/sheepsafe/status.rb
49
+ sheepsafe.gemspec
50
+ spec/sheepsafe_spec.rb
51
+ ]
52
+ # = MANIFEST =
53
+
54
+ s.test_files = s.files.select { |path| path =~ /^spec\/.*spec.*\.rb/ }
55
+
56
+ s.add_dependency(%q<growl>, ["~> 1.0"])
57
+ s.add_dependency(%q<highline>, ["~> 1.6"])
58
+ s.add_dependency(%q<daemons>, ["~> 1.1"])
59
+ s.add_development_dependency(%q<rspec>, ["~> 2.0"])
60
+
61
+ s.rubygems_version = %q{1.3.7}
62
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
63
+ if s.respond_to? :specification_version then
64
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
65
+ s.specification_version = 3
66
+ end
67
+ end
@@ -0,0 +1,127 @@
1
+ require 'rspec'
2
+ require 'sheepsafe'
3
+
4
+ describe Sheepsafe::Controller do
5
+ let(:config) do
6
+ mock("config", :trusted_location => "trusted_location", :untrusted_location => "untrusted_location",
7
+ :last_network= => nil, :write => nil)
8
+ end
9
+
10
+ let (:status) do
11
+ mock("status", :current_network => "current_network", :network_up? => true)
12
+ end
13
+
14
+ let(:controller) do
15
+ # Stub out logging
16
+ Sheepsafe::Controller.new(config, status, mock("logger", :info => nil)).tap do |c|
17
+ c.stub!(:notify_ok)
18
+ c.stub!(:notify_warning)
19
+ end
20
+ end
21
+
22
+ context "#network_changed?" do
23
+ it "is when the current_network is different than the last_network" do
24
+ config.should_receive(:last_network).and_return "last_network"
25
+ status.should_receive(:current_network).and_return "current_network"
26
+ controller.network_changed?.should be_true
27
+ end
28
+ end
29
+
30
+ context "#switch_to_trusted?" do
31
+ it "is when the current network is trusted" do
32
+ status.stub_chain(:current_network, :trusted?).and_return true
33
+ controller.switch_to_trusted?.should be_true
34
+ end
35
+ end
36
+
37
+ context "#switch_to_untrusted?" do
38
+ it "is when the current network is trusted" do
39
+ status.stub_chain(:current_network, :trusted?).and_return false
40
+ controller.switch_to_untrusted?.should be_true
41
+ end
42
+ end
43
+
44
+ context "network didn't change" do
45
+ before :each do
46
+ config.should_receive(:last_network).and_return "last_network"
47
+ status.should_receive(:current_network).and_return "last_network"
48
+ end
49
+
50
+ it "does nothing" do
51
+ config.should_not_receive(:write)
52
+ controller.run
53
+ end
54
+ end
55
+
56
+ context "network is down" do
57
+ it "does nothing" do
58
+ status.should_receive(:network_up?).and_return false
59
+ config.should_not_receive(:write)
60
+ controller.run
61
+ end
62
+ end
63
+
64
+ context "network changed" do
65
+ before :each do
66
+ controller.stub!(:network_changed?).and_return true
67
+ controller.stub!(:switch_to_trusted?).and_return false
68
+ controller.stub!(:switch_to_untrusted?).and_return false
69
+ end
70
+
71
+ it "writes the last network to the configuration" do
72
+ status.should_receive(:current_network).and_return "current_network"
73
+ config.should_receive(:last_network=).with("current_network").ordered
74
+ config.should_receive(:write).ordered
75
+ controller.run
76
+ end
77
+
78
+ context "to trusted" do
79
+ it "changes to the trusted location" do
80
+ controller.should_receive(:switch_to_trusted?).and_return true
81
+ controller.should_receive(:system).with("scselect trusted_location")
82
+ controller.should_receive(:bring_socks_proxy).with('down')
83
+ controller.run
84
+ end
85
+ end
86
+
87
+ context "to untrusted" do
88
+ it "changes to the untrusted location" do
89
+ controller.should_receive(:switch_to_untrusted?).and_return true
90
+ controller.should_receive(:system).with("scselect untrusted_location")
91
+ controller.should_receive(:bring_socks_proxy).with('up')
92
+ controller.run
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ describe Sheepsafe::Status do
99
+ let(:status) { Sheepsafe::Status.new }
100
+
101
+ its(:current_location) { should_not be_nil }
102
+ its(:current_network) { should_not be_nil }
103
+ end
104
+
105
+ describe Sheepsafe::Network do
106
+ let(:current_network) { Sheepsafe::Network.new }
107
+
108
+ context "with trusted SSID" do
109
+ let(:config) { Sheepsafe::Config.new({"trusted_names" => [current_network.current_ssid]}) }
110
+ subject { Sheepsafe::Network.new(config) }
111
+
112
+ it { should be_trusted }
113
+ end
114
+
115
+ context "with trusted BSSID" do
116
+ let(:config) { Sheepsafe::Config.new({"trusted_names" => [current_network.current_bssid]}) }
117
+ subject { Sheepsafe::Network.new(config) }
118
+
119
+ it { should be_trusted }
120
+ end
121
+
122
+ context "with no trusted names" do
123
+ subject { Sheepsafe::Network.new }
124
+
125
+ it { should_not be_trusted }
126
+ end
127
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheepsafe
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Nick Sieger
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-26 00:00:00 -05:00
19
+ default_executable: sheepsafe
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: growl
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 1
32
+ - 0
33
+ version: "1.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: highline
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 1
47
+ - 6
48
+ version: "1.6"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: daemons
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 13
60
+ segments:
61
+ - 1
62
+ - 1
63
+ version: "1.1"
64
+ type: :runtime
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: rspec
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 2
77
+ - 0
78
+ version: "2.0"
79
+ type: :development
80
+ version_requirements: *id004
81
+ description: Automatically toggle network locations and start a SOCKS proxy on untrusted networks. Mac OS X only.
82
+ email: nick@nicksieger.com
83
+ executables:
84
+ - sheepsafe
85
+ extensions: []
86
+
87
+ extra_rdoc_files:
88
+ - README.md
89
+ - LICENSE
90
+ files:
91
+ - History.txt
92
+ - LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - bin/sheepsafe
96
+ - doc/add-untrusted-apply.jpg
97
+ - doc/edit-locations.jpg
98
+ - lib/sheepsafe.rb
99
+ - lib/sheepsafe/config.rb
100
+ - lib/sheepsafe/controller.rb
101
+ - lib/sheepsafe/installer.rb
102
+ - lib/sheepsafe/network.rb
103
+ - lib/sheepsafe/status.rb
104
+ - sheepsafe.gemspec
105
+ - spec/sheepsafe_spec.rb
106
+ has_rdoc: true
107
+ homepage: http://github.com/nicksieger/sheepsafe
108
+ licenses: []
109
+
110
+ post_install_message: "\n\
111
+ ===========================================================================\n\
112
+ Welcome to Sheepsafe!\n\n\
113
+ =8P <=== (That's a sheep emoji.)\n\n\
114
+ If this is your first time using Sheepsafe, you probably want to set it up.\n\n\
115
+ To do that, run `sheepsafe install' now.\n\
116
+ ===========================================================================\n "
117
+ rdoc_options:
118
+ - --charset=UTF-8
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ hash: 3
127
+ segments:
128
+ - 0
129
+ version: "0"
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">"
134
+ - !ruby/object:Gem::Version
135
+ hash: 25
136
+ segments:
137
+ - 1
138
+ - 3
139
+ - 1
140
+ version: 1.3.1
141
+ requirements: []
142
+
143
+ rubyforge_project: caldersphere
144
+ rubygems_version: 1.3.7
145
+ signing_key:
146
+ specification_version: 3
147
+ summary: Makes sure you're safe from FireSheep!
148
+ test_files:
149
+ - spec/sheepsafe_spec.rb