shibboleths_lil_helper 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Gemfile +16 -0
  2. data/Gemfile.lock +36 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.markdown +199 -0
  5. data/Rakefile +54 -0
  6. data/TODOS.txt +15 -0
  7. data/VERSION +1 -0
  8. data/bin/slh +9 -0
  9. data/doc/debugging_shibboleth.markdown +8 -0
  10. data/doc/deprecated_code_that_could_be_useful.rb +32 -0
  11. data/doc/for_slh_developers.markdown +38 -0
  12. data/doc/nuances.markdown +13 -0
  13. data/doc/technical_question_and_answer.markdown +85 -0
  14. data/lib/shibboleths_lil_helper.rb +9 -0
  15. data/lib/slh.rb +17 -0
  16. data/lib/slh/class_methods.rb +83 -0
  17. data/lib/slh/cli.rb +140 -0
  18. data/lib/slh/cli/command_base.rb +32 -0
  19. data/lib/slh/cli/compare_metadata.rb +53 -0
  20. data/lib/slh/cli/copy_templates_to_override.rb +12 -0
  21. data/lib/slh/cli/describe_config.rb +75 -0
  22. data/lib/slh/cli/fetch_metadata.rb +27 -0
  23. data/lib/slh/cli/generate.rb +20 -0
  24. data/lib/slh/cli/generate_capistrano_deploy.rb +35 -0
  25. data/lib/slh/cli/generate_metadata.rb +53 -0
  26. data/lib/slh/cli/host_filterable_base.rb +16 -0
  27. data/lib/slh/cli/initialize.rb +30 -0
  28. data/lib/slh/cli/verify_metadata_encryption.rb +25 -0
  29. data/lib/slh/models/base.rb +23 -0
  30. data/lib/slh/models/host.rb +55 -0
  31. data/lib/slh/models/site.rb +139 -0
  32. data/lib/slh/models/site_path.rb +17 -0
  33. data/lib/slh/models/strategy.rb +131 -0
  34. data/lib/slh/models/version.rb +4 -0
  35. data/lib/slh/templates/_application_details.erb +33 -0
  36. data/lib/slh/templates/config.rb.erb +33 -0
  37. data/lib/slh/templates/deploy.rb.erb +42 -0
  38. data/lib/slh/templates/shib_apache.conf.erb +24 -0
  39. data/lib/slh/templates/shibboleth2.xml.erb +44 -0
  40. data/lib/slh/templates/sp_metadata_for_entity_id_to_give_to_idp.xml.erb +40 -0
  41. data/lib/slh/templates/sp_metadata_for_host_to_give_to_idp.xml.erb +33 -0
  42. data/shibboleths_lil_helper.gemspec +111 -0
  43. data/test/fixtures/dummy1.rb +15 -0
  44. data/test/fixtures/dummy1_output/attribute-map.xml +5 -0
  45. data/test/fixtures/dummy1_output/shib_for_vhost.conf +15 -0
  46. data/test/fixtures/dummy1_output/shibboleth2.xml +27 -0
  47. data/test/helper.rb +18 -0
  48. data/test/test_shibboleths_lil_helper.rb +105 -0
  49. metadata +211 -0
@@ -0,0 +1,13 @@
1
+ Nuances
2
+ =======
3
+
4
+ Order matters with "for_site" (sort of)
5
+ ---------------------------
6
+ * When running 'slh metadata', the first site declared under "for_host"
7
+ (in shibboleths_lil_helper/config.rb), is used when as the remote target to hit /Shibboleth.sso/Metadata.
8
+ This true anywhere a remote request is needed to be made for one of
9
+ your hosts
10
+
11
+ Therefore, if the first site is broken but others are not--switching the order so the first one works will
12
+ make the metadata comparing work.
13
+
@@ -0,0 +1,85 @@
1
+ This document is both for Shibboleth's Lil Helper developers and folks
2
+ setting up the Shibboleth SP. It was created to simply catelog the many
3
+ different gotchas that were solved while building this tool
4
+
5
+ ---
6
+ QUESTION
7
+ How can I learn how Shibboleth actually works from end to end in
8
+ less than an hour?
9
+
10
+ ANSWER
11
+ http://www.switch.ch/aai/demo/index.html
12
+
13
+ ---
14
+ QUESTION
15
+ If you are at
16
+ https://shib-php-test.asr.umn.edu/secure
17
+ and goto
18
+ https://shib-php-test.asr.umn.edu/Shibboleth.sso/Login
19
+ it redirects to
20
+ https://shib-php-test.asr.umn.edu
21
+ How to make it redirect to /secure?
22
+
23
+ ANSWER
24
+ See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSessionCreationParameters
25
+ Goto
26
+ https://shib-php-test.asr.umn.edu/Shibboleth.sso/Login?target=https%3A%2F%2Fshib-php-test.asr.umn.edu%2Fsecure
27
+
28
+ ---
29
+ QUESTION
30
+ How do I logout and redirect to the current page
31
+ If you are on
32
+ https://shib-php-test.asr.umn.edu/secure
33
+ and want to log out and redirect back to this same apge
34
+
35
+ ANSWER
36
+ See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPLogoutInitiator
37
+ You go to this page:
38
+ https://shib-rails2-test.asr.umn.edu/Shibboleth.sso/Logout?return=https%3A%2F%2Fshib-php-test.asr.umn.edu%2Fsecure
39
+
40
+
41
+ ---
42
+ QUESTION
43
+ Where is the specs and examples on how to do setup the RequestMap correctly?
44
+ https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo
45
+ https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapPath
46
+ https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapPathRegex
47
+
48
+
49
+ QUESTION:
50
+ Where is the XML specs for what constitutes valid Metadata?
51
+ ANSWER
52
+ http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf
53
+ You can also find specification details at schemacentral.com (e.g.
54
+ http://www.schemacentral.com/sc/ulex20/e-md_SPSSODescriptor.html)
55
+
56
+ QUESTION
57
+
58
+ If HTTP headers are an issue in Apache, why aren't they in IIS?
59
+
60
+ ANSWER
61
+
62
+ It seems like the ONLY way to use the Native SP with IIS is HTTP headers.
63
+
64
+ TODO.
65
+
66
+
67
+ ---
68
+ Question
69
+ I've have apache and shib installed and configured for a particular IDP and out on a target server, and when I go to Shibboleth.sso/Login, I get "shibsp::ConfigurationException", whats wrong?
70
+
71
+ Answer:
72
+ One likely issue is that one of the files referenced from shibboleth2.xml (i.e. attribute-map.xml), does not exist OR is not referenced as an absolute path in the case where shibboleth is not installed at the default location of /etc/shibboleth.
73
+
74
+
75
+ QUESTION:
76
+ When I hit something.com/Shibboleth.sso/Metadata on IIS I get:
77
+ Shibboleth Error
78
+ Shibboleth Extension not configured for web site (check ISAPI mappings in SP configuration).
79
+
80
+ how do I fix this?
81
+ ANSWER:
82
+
83
+ You probably just need to restart IIS and shibd.
84
+ but you should also check this out:
85
+ https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPWindowsIIS7Installer
@@ -0,0 +1,9 @@
1
+ require 'active_support/all'
2
+ require 'securerandom' # part of the Ruby standard library
3
+ require 'erb'
4
+ require 'net/http'
5
+ require 'net/https'
6
+ require 'nokogiri' # XML Parser Gem sudo gem install nokogiri
7
+ require 'fileutils'
8
+ require 'optparse'
9
+ require 'slh'
data/lib/slh.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Slh
2
+ # PROJECT_URL = 'https://github.com/joegoggins/shibboleths_lil_helper'
3
+ extend ActiveSupport::Autoload
4
+ autoload :ClassMethods
5
+ extend Slh::ClassMethods
6
+
7
+ autoload :Cli
8
+ module Models
9
+ extend ActiveSupport::Autoload
10
+ autoload :Base
11
+ autoload :Strategy
12
+ autoload :Host
13
+ autoload :Site
14
+ autoload :SitePath
15
+ autoload :Version
16
+ end
17
+ end
@@ -0,0 +1,83 @@
1
+ module Slh::ClassMethods
2
+ @@strategies = []
3
+ def strategies; @@strategies; end
4
+
5
+
6
+ ##########################
7
+ # CORE API METHODS BEGIN #
8
+ ##########################
9
+ def for_strategy(strategy_sym, &block)
10
+ @@strategies << Slh::Models::Strategy.new(strategy_sym, &block)
11
+ end
12
+
13
+ def clone_strategy_for_new_idp(existing_s, new_s, new_idp_url)
14
+ existing_strategy = self.strategies.detect {|x| x.name == existing_s}
15
+ raise "The specified strategy, #{existing_s}, does not exist" if existing_strategy.nil?
16
+ raise "The new strategy,#{new_s}, already exists" if self.strategies.detect {|x| x.name == new_s}
17
+ new_strategy = existing_strategy.clone
18
+ new_strategy.idp_metadata_url = new_idp_url
19
+ new_strategy.instance_variable_set(:@name, new_s)
20
+ @@strategies << new_strategy
21
+ end
22
+ ########################
23
+ # CORE API METHODS END #
24
+ ########################
25
+
26
+ def config_dir
27
+ 'shibboleths_lil_helper'
28
+ end
29
+
30
+ def config_file
31
+ File.join self.config_dir,'config.rb'
32
+ end
33
+
34
+ @@is_loaded = false
35
+ def load_config
36
+ unless @@is_loaded
37
+ Slh.command_line_output "Loading #{Slh.config_file}"
38
+ begin
39
+ require Slh.config_file
40
+ rescue LoadError
41
+ Slh.command_line_output "No #{Slh.config_file} found, exiting...Are you sure you are running this command from the right working directory?",
42
+ :highlight => :red,
43
+ :exit => true
44
+ end
45
+ if Slh.strategies.empty?
46
+ Slh.command_line_output "No strategies found in #{Slh.config_file}, you should add some, exiting...",
47
+ :highlight => :red,
48
+ :exit => true
49
+ end
50
+ Slh.strategies.each do |strategy|
51
+ begin
52
+ strategy.key_originator_site
53
+ rescue Slh::Models::Strategy::KeyOriginatorNotSpecified => e
54
+ Slh.command_line_output "Strategy: #{strategy.name} DOES NOT specify 'set :is_key_originator, true' on any site--all strategies must.",
55
+ :highlight => :red,
56
+ :exit => true
57
+ end
58
+ end
59
+ @@is_loaded = true
60
+ end
61
+ end
62
+ def command_line_output(msg,*args)
63
+ options = args.extract_options!
64
+ s=msg
65
+ unless options[:highlight].blank?
66
+ case options[:highlight]
67
+ when :green
68
+ s="\e[1;32m#{s}\e[0m"
69
+ when :red
70
+ s="\e[1;31m#{s}\e[0m"
71
+ else
72
+ s="\e[1;31m#{s}\e[0m"
73
+ end
74
+ end
75
+ unless options[:exception].blank?
76
+ s << "Exception = #{options[:exception].class.to_s}, message=#{options[:exception].message}"
77
+ end
78
+ puts s
79
+ if options[:exit]
80
+ exit
81
+ end
82
+ end
83
+ end
data/lib/slh/cli.rb ADDED
@@ -0,0 +1,140 @@
1
+ module Slh
2
+ class Cli # Command Line Interface
3
+ extend ActiveSupport::Autoload
4
+ autoload :CommandBase # abstract class
5
+ autoload :HostFilterableBase # abstract class
6
+ autoload :Initialize
7
+ autoload :Generate
8
+ autoload :FetchMetadata
9
+ autoload :CompareMetadata
10
+ autoload :VerifyMetadataEncryption
11
+ autoload :GenerateMetadata
12
+ autoload :GenerateCapistranoDeploy
13
+ autoload :CopyTemplatesToOverride
14
+ autoload :DescribeConfig
15
+
16
+ attr_reader :args,:action
17
+
18
+ def output(msg,*args)
19
+ Slh.command_line_output(msg,*args)
20
+ end
21
+
22
+ def parse_options_and_delegate(args)
23
+ if args.nil?
24
+ @args = []
25
+ else
26
+ @args = args.dup
27
+ end
28
+ $stdout.sync = true # no output buffering
29
+ case @args.first
30
+ when nil
31
+ puts <<-'EOS'
32
+
33
+ This is Shibboleth's Lil Helper.
34
+ He'll help you create consistent
35
+ ___,@ config XML for your Shibboleth-Native
36
+ / < Service-Provider servers (Apache or IIS)
37
+ ,_ / \ _, without pulling your hair out in frustration.
38
+ ? \`/______\`/
39
+ ,_(_). |; (e e) ;| He knows several commands listed below
40
+ \___ \ \/\ 7 /\/ _\8/_ invoked like: "slh initialize".
41
+ \/\ \'=='/ | /| /|
42
+ \ \___)--(_______|//|//| Append "--help" like "slh initialize --help"
43
+ \___ () _____/|/_|/_| to learn about the options each command can
44
+ / () \ `----' take
45
+ / () \
46
+ '-.______.-' It is STRONLY RECOMMENDED to keep generated files
47
+ _ |_||_| _ produced by this tool under source control--this sneaky
48
+ (@____) || (____@) little elf does not prompt before overwriting files.
49
+ \______||______/
50
+ MAIN COMMANDS (in usage order)
51
+ initialize
52
+ Creates a shibboleths_lil_helper/config.rb.
53
+ This is where you put ALL OF YOUR shibboleth SP config info for your organization.
54
+ Shibboleth's Lil Helper operates on this structure to provide all of the funcionality below.
55
+
56
+ generate
57
+ Generates shibboleth2.xml (and others) for deployment to each of your target hosts.
58
+ Don't forget to restart shibd and httpd on each host after you've updated these files.
59
+
60
+ verify_metadata
61
+ Makes sure all sites expose a URL like site.com/Shibboleth.sso/Metadata.
62
+ Detects differences in locally generated config with deployed config.
63
+ Detects encryption key inconsistency issues.
64
+
65
+ generate_metadata
66
+ Assembles your SP metadata for each strategy to give to your IDP
67
+
68
+ OPTIONAL COMMANDS
69
+ generate_capistrano
70
+ Creates a Capistrano config/deploy.rb for automating deployment. (see Capistrano website)
71
+ To install and prep for use with capistrano
72
+ Install: gem install capistrano
73
+ Capify dir: capify .
74
+ Edit config/deploy.rb
75
+ cap deploy HOST=somehost.com
76
+
77
+ copy_templates_to_override
78
+ Copies config templates into your local directory should you need to customize things beyond what the tool
79
+ provides.
80
+ This feature is designed to be used with the 'set_custom :var, "somevalue"' syntax in the config.rb
81
+ After running this command, you could add the following to one of the shibboleths_lil_helper/templates files:
82
+ <% if @strategy.respond_to? :dogz %>
83
+ <%= @strategy.dogz %>
84
+ <% end %>
85
+ then in the shibboleths_lil_helper/config.rb
86
+ set_custom :dogz, "YEA DOGZ"
87
+ it would result in "YEA DOGZ" appearing in rendered template
88
+
89
+ This feature is like a gun in church: You probably don't need it, but if you do, its good to have.
90
+ (read: don't use this unless you really need it.)
91
+
92
+ describe
93
+ Summarizes the configuration described in shibboleths_lil_helper/config.rb
94
+
95
+ OTHER DOCUMENTATION SOURCES (not just this tool)
96
+ https://wiki.shibboleth.net/
97
+ The official Shibboleth Wiki
98
+ (within this project--the doc folder)
99
+ There are lots of short little developer oriented tips we used while creating this tool.
100
+
101
+ EOS
102
+ exit
103
+ when 'initialize'
104
+ klass = Slh::Cli::Initialize
105
+ when 'generate'
106
+ klass = Slh::Cli::Generate
107
+ when 'verify_metadata'
108
+ klass = [Slh::Cli::FetchMetadata, Slh::Cli::CompareMetadata, Slh::Cli::VerifyMetadataEncryption]
109
+ when 'generate_metadata'
110
+ klass = [Slh::Cli::FetchMetadata, Slh::Cli::CompareMetadata,Slh::Cli::VerifyMetadataEncryption, Slh::Cli::GenerateMetadata]
111
+ when "generate_capistrano"
112
+ klass = Slh::Cli::GenerateCapistranoDeploy
113
+ when "copy_templates_to_override"
114
+ klass = Slh::Cli::CopyTemplatesToOverride
115
+ when "describe"
116
+ klass = Slh::Cli::DescribeConfig
117
+ else
118
+ raise "Invalid slh action"
119
+ end
120
+ if klass.kind_of? Array
121
+ klass.each do |k|
122
+ @action = k.new(@args[1..-1]) # everything except "slh" aka "initialize -f"
123
+ @action.execute
124
+ end
125
+ else
126
+ @action = klass.new(@args[1..-1]) # everything except "slh" aka "initialize -f"
127
+ @action.execute
128
+ end
129
+ end
130
+ def self.execute
131
+ @@instance = self.new
132
+ @@instance.parse_options_and_delegate(ARGV)
133
+ end
134
+ @@instance = nil
135
+ def self.instance
136
+ raise "must hit execute to get this piece rolling" if @@instance.nil?
137
+ @@instance
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,32 @@
1
+ # Children should define .default_options and option_parser
2
+ class Slh::Cli::CommandBase
3
+ attr_reader :args,:option_parser,:options
4
+ def default_options
5
+ { } # CHILD SHOULD DEFINE
6
+ end
7
+ def option_parser
8
+ OptionParser.new # CHILD SHOULD DEFINE
9
+ end
10
+
11
+ def initialize(args)
12
+ @options = self.default_options
13
+ if args.nil?
14
+ @args = []
15
+ else
16
+ @args = args.dup
17
+ end
18
+ end
19
+ def output_header
20
+ Slh::Cli.instance.output "\n<<<< BEGIN #{self.class.to_s} >>>>\n"
21
+ end
22
+ def output_footer
23
+ Slh::Cli.instance.output "\n<<<< END #{self.class.to_s} >>>>\n"
24
+ end
25
+ def execute
26
+ Slh.load_config unless self.class == Slh::Cli::Initialize
27
+ self.option_parser.parse!(self.args)
28
+ self.output_header
29
+ self.perform_action
30
+ self.output_footer
31
+ end
32
+ end
@@ -0,0 +1,53 @@
1
+ class Slh::Cli::CompareMetadata < Slh::Cli::HostFilterableBase
2
+ def perform_action
3
+ # DEV_WISH_LIST: Clean up this mess... this stuff belongs somewhere else
4
+ mismatch_found = false
5
+
6
+ Slh.strategies.each do |strategy|
7
+ Slh::Cli.instance.output "Iterating hosts for strategy #{strategy.name}"
8
+ strategy.hosts.each do |host|
9
+ next if @options[:filter].kind_of?(String) && !host.name.match(@options[:filter])
10
+
11
+ raise "Can't find the generated shibboleth2.xml for #{host.name}" unless File.exists?(host.shibboleth2_path)
12
+
13
+ local = Nokogiri::XML(File.read(host.shibboleth2_path)) #Nokogiri::XML(shib2)
14
+ remote_first_site = host.sites.first
15
+
16
+ begin
17
+ remote = Nokogiri::XML(remote_first_site.metadata)
18
+ rescue Slh::Models::Site::CouldNotGetMetadata => e
19
+ Slh::Cli.instance.output " NOT FOUND #{host.name}", :highlight => :red
20
+ Slh::Cli.instance.output " Remote metadata not available at #{remote_first_site.metadata_url}, exception message: #{e.message}"
21
+ mismatch_found = true
22
+ next # skip this host
23
+ rescue Timeout::Error => e
24
+ Slh::Cli.instance.output " TIMEOUT #{host.name}", :highlight => :red
25
+ Slh::Cli.instance.output " Remote metadata not available at #{remote_first_site.metadata_url}, exception message: #{e.message}"
26
+ mismatch_found = true
27
+ next # skip this host
28
+ end
29
+ local.remove_namespaces!
30
+ remote.remove_namespaces!
31
+ local_version_node = local.at('ApplicationDefaults/CredentialResolver/Key/Name')
32
+ remote_version_node = remote.at('KeyInfo/KeyName') # remote.at('md:KeyDescriptor/ds:Name')
33
+ raise "No version nodes found in #{shib2.path}!" if local_version_node.blank?
34
+ raise "No version nodes found in remote metadata for #{host.name}" if remote_version_node.blank?
35
+ local_version = local_version_node.inner_text.sub(Slh::Models::Version::PREFIX, '')
36
+ remote_version = remote_version_node.inner_text.sub(Slh::Models::Version::PREFIX, '')
37
+ if local_version == remote_version
38
+ Slh::Cli.instance.output " OK #{host.name}", :highlight => :green
39
+ else
40
+ Slh::Cli.instance.output " MISMATCH #{host.name}", :highlight => :red
41
+ Slh::Cli.instance.output " From metadata gathered at #{remote_first_site.metadata_url}"
42
+ mismatch_found = true
43
+ end
44
+ end
45
+ end
46
+
47
+ if mismatch_found
48
+ Slh::Cli.instance.output "\nThe newest copy of shibboleth2.xml is not deployed to all of your hosts! This may or may not result in a broken installation, depending on what has changed since the last time you ran this command.", :highlight => true
49
+ else
50
+ Slh::Cli.instance.output "\nShibboleth2.xml is up-to-date on all of your hosts!"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,12 @@
1
+ class Slh::Cli::CopyTemplatesToOverride < Slh::Cli::CommandBase
2
+ def default_options
3
+ { }
4
+ end
5
+
6
+ def perform_action
7
+ Slh::Cli.instance.output "Copying all of the erb templates from Shibboleth's Lil Helper to your local directory"
8
+ FileUtils.cp_r(File.join(File.dirname(__FILE__), '..', 'templates'),Slh.config_dir)
9
+ Slh::Cli.instance.output "These templates will be used instead of the defaults in the Shibboleth's Lil Helper Rubygem"
10
+ end
11
+ end
12
+