diff options
author | Corey Hulen <corey@hulen.com> | 2018-06-12 10:16:39 -0700 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2018-06-12 10:16:39 -0700 |
commit | 656c8a62d145fc565e9a98e060329239d2d59fbd (patch) | |
tree | b4922cbf8b14992c353742e9e4225d7736a2e3a3 /app | |
parent | 4ea7f6a2f7e61356996a3dfa85169f8db5d4d064 (diff) | |
download | chat-656c8a62d145fc565e9a98e060329239d2d59fbd.tar.gz chat-656c8a62d145fc565e9a98e060329239d2d59fbd.tar.bz2 chat-656c8a62d145fc565e9a98e060329239d2d59fbd.zip |
Prototype for CBA (#8475)
* Prototype for CBA
* Fixing gofmt issues
* Do not require password if logging in with certificate
* Fixing issues from feedback
* Adding unit tests
* Fixing feedback
Diffstat (limited to 'app')
-rw-r--r-- | app/login.go | 25 | ||||
-rw-r--r-- | app/login_test.go | 37 |
2 files changed, 62 insertions, 0 deletions
diff --git a/app/login.go b/app/login.go index 3001e1f4d..d3d2a423e 100644 --- a/app/login.go +++ b/app/login.go @@ -6,6 +6,7 @@ package app import ( "fmt" "net/http" + "strings" "time" "github.com/avct/uasurfer" @@ -13,6 +14,23 @@ import ( "github.com/mattermost/mattermost-server/store" ) +func (a *App) CheckForClienSideCert(r *http.Request) (string, string, string) { + pem := r.Header.Get("X-SSL-Client-Cert") // mapped to $ssl_client_cert from nginx + subject := r.Header.Get("X-SSL-Client-Cert-Subject-DN") // mapped to $ssl_client_s_dn from nginx + email := "" + + if len(subject) > 0 { + for _, v := range strings.Split(subject, "/") { + kv := strings.Split(v, "=") + if len(kv) == 2 && kv[0] == "emailAddress" { + email = kv[1] + } + } + } + + return pem, subject, email +} + func (a *App) AuthenticateUserForLogin(id, loginId, password, mfaToken string, ldapOnly bool) (user *model.User, err *model.AppError) { // Do statistics defer func() { @@ -35,6 +53,13 @@ func (a *App) AuthenticateUserForLogin(id, loginId, password, mfaToken string, l return nil, err } + // If client side cert is enable and it's checking as a primary source + // then trust the proxy and cert that the correct user is supplied and allow + // them access + if *a.Config().ExperimentalSettings.ClientSideCertEnable && *a.Config().ExperimentalSettings.ClientSideCertCheck == model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH { + return user, nil + } + // and then authenticate them if user, err = a.authenticateUser(user, password, mfaToken); err != nil { return nil, err diff --git a/app/login_test.go b/app/login_test.go new file mode 100644 index 000000000..db92f1d7d --- /dev/null +++ b/app/login_test.go @@ -0,0 +1,37 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package app + +import ( + "net/http" + "testing" +) + +func TestCheckForClienSideCert(t *testing.T) { + th := Setup() + defer th.TearDown() + + var tests = []struct { + pem string + subject string + expectedEmail string + }{ + {"blah", "blah", ""}, + {"blah", "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=test@test.com", "test@test.com"}, + {"blah", "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/EmailAddress=test@test.com", ""}, + {"blah", "CN=www.freesoft.org/EmailAddress=test@test.com, C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft", ""}, + } + + for _, tt := range tests { + r := &http.Request{Header: http.Header{}} + r.Header.Add("X-SSL-Client-Cert", tt.pem) + r.Header.Add("X-SSL-Client-Cert-Subject-DN", tt.subject) + + _, _, actualEmail := th.App.CheckForClienSideCert(r) + + if actualEmail != tt.expectedEmail { + t.Fatalf("CheckForClienSideCert(%v): expected %v, actual %v", tt.subject, tt.expectedEmail, actualEmail) + } + } +} |