From 8a7993194ea832ecee99502a514c0894acc4d547 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Fri, 12 Dec 2014 19:32:15 +0200 Subject: [PATCH 1/5] Kerberos support --- Gemfile | 1 + Gemfile.lock | 7 ++++ app/assets/images/authbuttons/kerberos_32.png | Bin 0 -> 2085 bytes app/assets/images/authbuttons/kerberos_64.png | Bin 0 -> 6029 bytes .../omniauth_callbacks_controller.rb | 1 + app/helpers/oauth_helper.rb | 14 ++++++- .../devise/sessions/_new_kerberos.html.haml | 5 +++ app/views/devise/sessions/new.html.haml | 22 +++++++---- lib/gitlab/auth.rb | 5 +++ lib/gitlab/kerberos/authentication.rb | 36 ++++++++++++++++++ 10 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 app/assets/images/authbuttons/kerberos_32.png create mode 100644 app/assets/images/authbuttons/kerberos_64.png create mode 100644 app/views/devise/sessions/_new_kerberos.html.haml create mode 100644 lib/gitlab/kerberos/authentication.rb diff --git a/Gemfile b/Gemfile index 773484a8a0..62f8870cff 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,7 @@ gem 'omniauth-google-oauth2' gem 'omniauth-twitter' gem 'omniauth-github' gem 'omniauth-shibboleth' +gem 'omniauth-kerberos' # Extracting information from a git repository # Provide access to Gitlab::Git library diff --git a/Gemfile.lock b/Gemfile.lock index 8222fe7f9e..80076150c7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -323,6 +323,11 @@ GEM omniauth-google-oauth2 (0.2.5) omniauth (> 1.0) omniauth-oauth2 (~> 1.1) + omniauth-kerberos (0.2.0) + omniauth-multipassword + timfel-krb5-auth (~> 0.8) + omniauth-multipassword (0.4.1) + omniauth (~> 1.0) omniauth-oauth (1.0.1) oauth omniauth (~> 1.0) @@ -536,6 +541,7 @@ GEM thread_safe (0.3.4) tilt (1.4.1) timers (1.1.0) + timfel-krb5-auth (0.8) tinder (1.9.3) eventmachine (~> 1.0) faraday (~> 0.8) @@ -661,6 +667,7 @@ DEPENDENCIES omniauth (~> 1.1.3) omniauth-github omniauth-google-oauth2 + omniauth-kerberos omniauth-shibboleth omniauth-twitter org-ruby (= 0.9.9) diff --git a/app/assets/images/authbuttons/kerberos_32.png b/app/assets/images/authbuttons/kerberos_32.png new file mode 100644 index 0000000000000000000000000000000000000000..66b6f91d863449ecae27c29a5af58d3fb2d7c971 GIT binary patch literal 2085 zcmV+=2-^3FP)Vl&|000Nh8D^KOU=fW+Yyw)HRHz}EX&R$4MyoTHL9C9)bS7zSGfBtHv}R)4u^LSa8WbfM zZJMB5MOpCz1Y7|R)M#2kkpKcKEUX;M-UqwveLa1@4_LFJ(RA9$Kl9H2@9h77&-*>^ z^B!Li0N;0IK_d@Oyu3c|uz6f?4E4cb8Gw&|JBIq*$5LEXHVKH{XL(V<;&iCJgyIdAn4eii%mq69}8FXEz zp=!$^u!H2pZZy@Gp}1fN2-P9GKO&;c}S1J@_zn9-_4$n$BWqJ4LkM z5g2;TLH<<+`s)8ej$}h6$;XW=Wsu%2gRCx%ocV~}%cXbrK;3qPJ8DwZ!{hZl)`hV^6sa^Kn@JO)iA4Wa@~9*xYMqOp|2Whiknt?lH!|9UVAC_E`A^N zo;~-=dqoq3=;m`7;v_zmuzt0 z3Ky47R>CQByKQh2y<)LA0Gv6Ko0o&EtSro&J^|6=!x0n|#O;msGf-1?7D@_*w!54& zz(mM2<0b)*0cSC^8ap`MM)?)=-TtdztsajDsi~=OI2?X(i)9F#H*dy<4ePOf?F)Wj zW?^AMOnPP_Vu^{Alw_2h%z~`pATfG@G}H13aEi6=eg!lg$Dkyt4LxH23k*DccPg}6 zEeB`2zFJ+4g|Sm{^w?29Xw>(|Vbi9!F=gshgocK4dv4mZcyUfVemFe_Rpm#Bi8EZR zqnqI14vQT6`;|m@83vm6@l@lXAgTuk2a&Qe33>VXT;ZKvok;(~uW)*)0F@-RQSily z3vu}HXQ-^KKt*LaDk{oxyZ$D+x;n7!Pg`*NdJzw)+wBYlw=jj1vK1|#z^rKiW5P|! zZE9}9x{bd>Xk;{EV`EWs@d8qJ??UGGjnLOGz+1oFh>(yFOrAU$+dudKZEbg9G8BU@B>`s9&BovDh6S3mwNtiWjCT`ujO5cfaq2>?{WPObC@^ZA2 zLr$la3RV$?^e`2lQ-R>d-t$Cz1q@_XqZBfk3~_OBoX!y812HXIwhRY%CLv{MBBCQh zM+6oIp-_mI7AHZjRC0}sHki>YV$ZBf8s(RvXgw4NZs@y=(vl*Sl%7J}weuKIG$JEo z7gAQy?t(){oDg8ilGpKK!jCX}Tv&j@naz743h!;*Nm*eFXez!DaJ3{Cy>(l8cmu)Z zH;|OH9PuwDKzwTdh}RyfSWbwFvhm~i7%YA@9NYf9fT)ii1I%pZ4}uXl`*}#E9ghUp zQPGm$*+oUCBoLhSJCGP<`Sf*la`GtQIrH{~q*;xmfs0G&a4P><9bxS^?f# zHxUAXfGh-2QBepF4@2d-a{7Na4VHQEu}$WZU$bS8;>{NTt`a& zB{ptYgYwKRsLPp;+QTam85zNW1%e=CrV6m*eIfRwFG9w?y|{k;8bqRFXl=a-yTk5x zfEi0+1&LXI|19k0-av3x_SDpgG}1GWHsqmO)(we7g6-S3;+5DifLgkGP6r>M;cs|ywPQj}A&tp0jq}=>m(v6YkfdVL+vuO7Y#Jswu8)!%N}ojKyL zsz_v|e8^;T0b9#XQ|`l)Z2&m?)8({4#dx$M2-RX(?`{9aNr9*ChKVm z(Nbknv>c$pumHVxK1Nsl0lq_)9c*&dQCyX6pF>ISGpbEAx4CF68%{&-(}6#HSa4Vr z#6lG*_U{CgNh11mxbHXa;l}1Xll&SFm5vXc#l%Fbe`4hZ-?u+Be7!b1D3%soGd~d6 zO!p~uF474`%m)NEGMhE^6fTXwt3Bz!@YLXA%{yYg#~c0!;Q!C-I|cs_rqJWX(lA2A P00000NkvXXu0mjf)6nI9 literal 0 HcmV?d00001 diff --git a/app/assets/images/authbuttons/kerberos_64.png b/app/assets/images/authbuttons/kerberos_64.png new file mode 100644 index 0000000000000000000000000000000000000000..f22fbc57da3ea7414fcbcbe1935d92b4000288aa GIT binary patch literal 6029 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 'tab' + - if ldap_enabled? + - @ldap_servers.each_with_index do |server, i| + %li{class: (:active if i.zero?)} + = link_to server['label'], "#tab-#{server['provider_name']}", 'data-toggle' => 'tab' + - if kerberos_enabled? + %li{class: (:active unless ldap_enabled?)} + = link_to "Kerberos", "#tab-kerberos", 'data-toggle' => 'tab' - if gitlab_config.signin_enabled %li = link_to 'Standard', '#tab-signin', 'data-toggle' => 'tab' .tab-content - - @ldap_servers.each_with_index do |server, i| - %div.tab-pane{id: "tab-#{server['provider_name']}", class: (:active if i.zero?)} - = render 'devise/sessions/new_ldap', provider: server['provider_name'] + - if ldap_enabled? + - @ldap_servers.each_with_index do |server, i| + %div.tab-pane{id: "tab-#{server['provider_name']}", class: (:active if i.zero?)} + = render 'devise/sessions/new_ldap', provider: server['provider_name'] + - if kerberos_enabled? + %div#tab-kerberos.tab-pane{class: (:active unless ldap_enabled?)} + = render 'devise/sessions/new_kerberos', provider: :kerberos - if gitlab_config.signin_enabled %div#tab-signin.tab-pane = render 'devise/sessions/new_base' diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 30509528b8..6520b82e2a 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -2,6 +2,11 @@ module Gitlab class Auth def find(login, password) user = User.by_login(login) + + if Devise.omniauth_providers.include?(:kerberos) + kerberos_user = Gitlab::Kerberos::Authentication.login(login, password) + return kerberos_user if kerberos_user + end # If no user is found, or it's an LDAP server, try LDAP. # LDAP users are only authenticated via LDAP diff --git a/lib/gitlab/kerberos/authentication.rb b/lib/gitlab/kerberos/authentication.rb new file mode 100644 index 0000000000..ad99ebf204 --- /dev/null +++ b/lib/gitlab/kerberos/authentication.rb @@ -0,0 +1,36 @@ +require "krb5_auth" +# This calls helps to authenticate to Kerberos by providing username and password + +module Gitlab + module Kerberos + class Authentication + def self.login(login, password) + return unless Devise.omniauth_providers.include?(:kerberos) + return unless login.present? && password.present? + + auth = new(login, password) + auth.login + end + + def initialize(login, password) + @login = login + @password = password + @krb5 = ::Krb5Auth::Krb5.new + end + + def valid? + @krb5.get_init_creds_password(@login, @password) + rescue ::Krb5Auth::Krb5::Exception + false + end + + def login + valid? && User.find_by(email: email) + end + + def email + @login + "@" + @krb5.get_default_realm.downcase + end + end + end +end From e3a419aa64d5ac878358d2783baf2481d099c735 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Fri, 12 Dec 2014 20:44:05 +0200 Subject: [PATCH 2/5] Kerberos: specs --- spec/helpers/oauth_helper_spec.rb | 12 ++++++ spec/lib/gitlab/auth_spec.rb | 11 +++++ .../gitlab/kerberos/authentication_spec.rb | 41 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 spec/lib/gitlab/kerberos/authentication_spec.rb diff --git a/spec/helpers/oauth_helper_spec.rb b/spec/helpers/oauth_helper_spec.rb index 453699136e..a4bc1a18c0 100644 --- a/spec/helpers/oauth_helper_spec.rb +++ b/spec/helpers/oauth_helper_spec.rb @@ -17,4 +17,16 @@ describe OauthHelper do helper.additional_providers.should == [] end end + + describe "kerberos_enabled?" do + it 'returns true' do + allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :github, :kerberos] } + helper.kerberos_enabled?.should be_true + end + + it 'returns false' do + allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :ldapmain] } + helper.kerberos_enabled?.should be_false + end + end end \ No newline at end of file diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 95fc7e16a1..fe85819396 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -35,6 +35,17 @@ describe Gitlab::Auth do expect( gl_auth.find(username, password) ).to_not eql user end + context "with kerberos" do + before { Devise.stub(omniauth_providers: [:kerberos]) } + + it "finds user" do + Gitlab::Kerberos::Authentication.stub(valid?: true) + Gitlab::Kerberos::Authentication.stub(email: user.email) + + expect( gl_auth.find(username, password) ).to eql user + end + end + context "with ldap enabled" do before { Gitlab::LDAP::Config.stub(enabled?: true) } diff --git a/spec/lib/gitlab/kerberos/authentication_spec.rb b/spec/lib/gitlab/kerberos/authentication_spec.rb new file mode 100644 index 0000000000..0e20d11062 --- /dev/null +++ b/spec/lib/gitlab/kerberos/authentication_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe Gitlab::Kerberos::Authentication do + let(:klass) { Gitlab::Kerberos::Authentication } + let(:user) { create(:user) } + let(:login) { 'john' } + let(:password) { 'password' } + + describe :login do + before do + Devise.stub(omniauth_providers: [:kerberos]) + end + + it "finds the user if authentication is successful" do + kerberos_login = user.email.sub(/@.*/, '') + kerberos_realm = user.email.sub(/.*@/, '') + ::Krb5Auth::Krb5.any_instance.stub(get_init_creds_password: true) + ::Krb5Auth::Krb5.any_instance.stub(get_default_realm: kerberos_realm) + + expect(klass.login(kerberos_login, password)).to be_true + end + + it "returns false if there is no such user in kerberos" do + kerberos_login = "some-login" + kerberos_realm = user.email.sub(/.*@/, '') + ::Krb5Auth::Krb5.any_instance.stub(get_init_creds_password: true) + ::Krb5Auth::Krb5.any_instance.stub(get_default_realm: kerberos_realm) + + expect(klass.login(kerberos_login, password)).to be_false + end + + it "returns false if kerberos user is valid but system has wrong realm" do + kerberos_login = user.email.sub(/@.*/, '') + kerberos_realm = "some-realm.com" + ::Krb5Auth::Krb5.any_instance.stub(get_init_creds_password: true) + ::Krb5Auth::Krb5.any_instance.stub(get_default_realm: kerberos_realm) + + expect(klass.login(kerberos_login, password)).to be_false + end + end +end \ No newline at end of file From 451a078a9bcddabe3f3391726970302ed66417cd Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Fri, 12 Dec 2014 20:50:03 +0200 Subject: [PATCH 3/5] EE changelog --- CHANGELOG-EE | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG-EE b/CHANGELOG-EE index 7b84bb7067..4d57fb8d74 100644 --- a/CHANGELOG-EE +++ b/CHANGELOG-EE @@ -4,6 +4,7 @@ v 7.6.0 - Dont show LDAP groups settings if LDAP disabled - Rebase on merge request. Introduced merge request option to rebase before merging - Better message for failed pushes because of git hooks + - Kerberos support for web interface and git HTTP v 7.5.3 - Only set up Sidetiq from a Sidekiq server process (fixes Redis::InheritedError) From cbabc0b2f3fc029aeea6cc58992f3a32e2e9bee5 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Mon, 15 Dec 2014 12:47:27 +0200 Subject: [PATCH 4/5] Kerberos: update docs --- db/schema.rb | 4 ++-- doc/integration/README.md | 1 + doc/integration/kerberos.md | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 doc/integration/kerberos.md diff --git a/db/schema.rb b/db/schema.rb index 95bab864c0..5acf6f8ee9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -262,9 +262,9 @@ ActiveRecord::Schema.define(version: 20141205134006) do t.datetime "updated_at" t.string "type" t.string "description", default: "", null: false + t.string "avatar" t.string "ldap_cn" t.integer "ldap_access" - t.string "avatar" end add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree @@ -325,8 +325,8 @@ ActiveRecord::Schema.define(version: 20141205134006) do t.boolean "archived", default: false, null: false t.string "import_status" t.float "repository_size", default: 0.0 - t.text "merge_requests_template" t.integer "star_count", default: 0, null: false + t.text "merge_requests_template" t.boolean "merge_requests_rebase_enabled", default: false end diff --git a/doc/integration/README.md b/doc/integration/README.md index b5b88159f3..ccf3911bf5 100644 --- a/doc/integration/README.md +++ b/doc/integration/README.md @@ -10,6 +10,7 @@ See the documentation below for details on how to configure these services. - [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth. - [Jenkins](jenkins.md) Integrate with the Jenkins CI - [Slack](slack.md) Integrate with the Slack chat service +- [Kerberos](kerberos.md) Integrate with the Slack chat service ## Project services diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md new file mode 100644 index 0000000000..e0bcc972df --- /dev/null +++ b/doc/integration/kerberos.md @@ -0,0 +1,16 @@ +# Kerberos integration + +GitLab can be configured to allow your users to sign with their Kerberos credentials. +Kerberos integration can be enabled as a regular omniauth provider, edit [gitlab.rb (omnibus-gitlab)`](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#omniauth-google-twitter-github-login) or [gitlab.yml (source installations)](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/gitlab.yml.example) on your GitLab server and restart GitLab. You only need to specify the provider name. For example: + +``` +{ name: 'kerberos'} +``` + +You still need to configure your system for Kerberos usage, such as specifying realms. GitLab will make use of the system's Kerberos settings. + +The first time a user signs in with Kerberos credentials, GitLab will create a new GitLab user associated with the email, which is built from the kerberos username and realm. This also means that the system realm you want to use and the email addresses of existing GitLab users should match, meaning the domain part of the email addresses and the realm should match. Existing GitLab users can go to profile > account and attach a Kerberos account. If the email and realm match, the Kerberos account will be linked to the user. + +## HTTP git access + +A linked Kerberos account enables you to `git pull` and `git push` using your Kerberos account, as well as your standard GitLab credentials. \ No newline at end of file From 73c0dfd265e7d0fd0f8df16fa63eecd6ecf202b4 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Mon, 15 Dec 2014 17:44:06 +0200 Subject: [PATCH 5/5] Kerberos: username as identifier --- doc/integration/README.md | 2 +- doc/integration/kerberos.md | 2 +- lib/gitlab/kerberos/authentication.rb | 11 ++++++++--- spec/lib/gitlab/kerberos/authentication_spec.rb | 14 ++------------ 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/doc/integration/README.md b/doc/integration/README.md index ccf3911bf5..00131a8d50 100644 --- a/doc/integration/README.md +++ b/doc/integration/README.md @@ -10,7 +10,7 @@ See the documentation below for details on how to configure these services. - [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth. - [Jenkins](jenkins.md) Integrate with the Jenkins CI - [Slack](slack.md) Integrate with the Slack chat service -- [Kerberos](kerberos.md) Integrate with the Slack chat service +- [Kerberos](kerberos.md) Integrate with Kerberos ## Project services diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md index e0bcc972df..42252f64e4 100644 --- a/doc/integration/kerberos.md +++ b/doc/integration/kerberos.md @@ -9,7 +9,7 @@ Kerberos integration can be enabled as a regular omniauth provider, edit [gitlab You still need to configure your system for Kerberos usage, such as specifying realms. GitLab will make use of the system's Kerberos settings. -The first time a user signs in with Kerberos credentials, GitLab will create a new GitLab user associated with the email, which is built from the kerberos username and realm. This also means that the system realm you want to use and the email addresses of existing GitLab users should match, meaning the domain part of the email addresses and the realm should match. Existing GitLab users can go to profile > account and attach a Kerberos account. If the email and realm match, the Kerberos account will be linked to the user. +The first time a user signs in with Kerberos credentials, GitLab will create a new GitLab user associated with the email, which is built from the kerberos username and realm. Existing GitLab users can go to profile > account and attach a Kerberos account. ## HTTP git access diff --git a/lib/gitlab/kerberos/authentication.rb b/lib/gitlab/kerberos/authentication.rb index ad99ebf204..6e9a2e6216 100644 --- a/lib/gitlab/kerberos/authentication.rb +++ b/lib/gitlab/kerberos/authentication.rb @@ -25,11 +25,16 @@ module Gitlab end def login - valid? && User.find_by(email: email) + valid? && find_by_login(@login) end - def email - @login + "@" + @krb5.get_default_realm.downcase + private + + def find_by_login(login) + identity = ::Identity. + where(provider: :kerberos). + where('lower(extern_uid) = ?', login).last + identity && identity.user end end end diff --git a/spec/lib/gitlab/kerberos/authentication_spec.rb b/spec/lib/gitlab/kerberos/authentication_spec.rb index 0e20d11062..f75c4d0b23 100644 --- a/spec/lib/gitlab/kerberos/authentication_spec.rb +++ b/spec/lib/gitlab/kerberos/authentication_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::Kerberos::Authentication do let(:klass) { Gitlab::Kerberos::Authentication } - let(:user) { create(:user) } + let(:user) { create(:omniauth_user, provider: :kerberos, extern_uid: 'gitlab') } let(:login) { 'john' } let(:password) { 'password' } @@ -12,12 +12,11 @@ describe Gitlab::Kerberos::Authentication do end it "finds the user if authentication is successful" do - kerberos_login = user.email.sub(/@.*/, '') kerberos_realm = user.email.sub(/.*@/, '') ::Krb5Auth::Krb5.any_instance.stub(get_init_creds_password: true) ::Krb5Auth::Krb5.any_instance.stub(get_default_realm: kerberos_realm) - expect(klass.login(kerberos_login, password)).to be_true + expect(klass.login('gitlab', password)).to be_true end it "returns false if there is no such user in kerberos" do @@ -28,14 +27,5 @@ describe Gitlab::Kerberos::Authentication do expect(klass.login(kerberos_login, password)).to be_false end - - it "returns false if kerberos user is valid but system has wrong realm" do - kerberos_login = user.email.sub(/@.*/, '') - kerberos_realm = "some-realm.com" - ::Krb5Auth::Krb5.any_instance.stub(get_init_creds_password: true) - ::Krb5Auth::Krb5.any_instance.stub(get_default_realm: kerberos_realm) - - expect(klass.login(kerberos_login, password)).to be_false - end end end \ No newline at end of file