From f26f8d5afa8d84e4cf3fde6c956dcf907d7883b5 Mon Sep 17 00:00:00 2001 From: Linquize Date: Sat, 28 Mar 2015 22:30:05 +0800 Subject: [PATCH 01/14] Set Content-Type to text/plain for http status 401 This is because git command line shows the failure reason only if Content-Type is text/plain. --- modules/middleware/context.go | 7 +++++++ routers/repo/http.go | 14 +++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/middleware/context.go b/modules/middleware/context.go index b580de5038..200a74cb3a 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -139,6 +139,13 @@ func (ctx *Context) Handle(status int, title string, err error) { ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) } +func (ctx *Context) HandleText(status int, title string) { + if (status / 100 == 4) || (status / 100 == 5) { + log.Error(4, "%s", title) + } + ctx.RenderData(status, []byte(title)) +} + func (ctx *Context) HandleAPI(status int, obj interface{}) { var message string if err, ok := obj.(error); ok { diff --git a/routers/repo/http.go b/routers/repo/http.go index 9165128a36..8395d1c041 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -96,12 +96,12 @@ func Http(ctx *middleware.Context) { // FIXME: middlewares/context.go did basic auth check already, // maybe could use that one. if len(auths) != 2 || auths[0] != "Basic" { - ctx.Handle(401, "no basic auth and digit auth", nil) + ctx.HandleText(401, "no basic auth and digit auth") return } authUsername, authPasswd, err = base.BasicAuthDecode(auths[1]) if err != nil { - ctx.Handle(401, "no basic auth and digit auth", nil) + ctx.HandleText(401, "no basic auth and digit auth") return } @@ -116,7 +116,7 @@ func Http(ctx *middleware.Context) { token, err := models.GetAccessTokenBySha(authUsername) if err != nil { if err == models.ErrAccessTokenNotExist { - ctx.Handle(401, "invalid token", nil) + ctx.HandleText(401, "invalid token") } else { ctx.Handle(500, "GetAccessTokenBySha", err) } @@ -138,23 +138,23 @@ func Http(ctx *middleware.Context) { has, err := models.HasAccess(authUser, repo, tp) if err != nil { - ctx.Handle(401, "no basic auth and digit auth", nil) + ctx.HandleText(401, "no basic auth and digit auth") return } else if !has { if tp == models.ACCESS_MODE_READ { has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE) if err != nil || !has { - ctx.Handle(401, "no basic auth and digit auth", nil) + ctx.HandleText(401, "no basic auth and digit auth") return } } else { - ctx.Handle(401, "no basic auth and digit auth", nil) + ctx.HandleText(401, "no basic auth and digit auth") return } } if !isPull && repo.IsMirror { - ctx.Handle(401, "can't push to mirror", nil) + ctx.HandleText(401, "can't push to mirror") return } } From 7e5063a93d15945150339c30beb6d09ba7b42939 Mon Sep 17 00:00:00 2001 From: Robert Rauch Date: Wed, 1 Apr 2015 00:45:00 +0200 Subject: [PATCH 02/14] fix typo in centos init script We should be *sourcing* `/etc/sysconfig/gogs`, not *executing* it, don't we? --- scripts/init/centos/gogs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/init/centos/gogs b/scripts/init/centos/gogs index 1a92ff2070..5ff6de537f 100644 --- a/scripts/init/centos/gogs +++ b/scripts/init/centos/gogs @@ -33,7 +33,7 @@ LOGFILE=${GOGS_HOME}/log/gogs.log RETVAL=0 # Read configuration from /etc/sysconfig/gogs to override defaults -[ -r /etc/sysconfig/$NAME ] && ./etc/sysconfig/$NAME +[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME # Don't do anything if nothing is installed [ -x ${GOGS_PATH} ] || exit 0 From 1988c0993d1f2d535766e03695b4cdb0fe74e4d6 Mon Sep 17 00:00:00 2001 From: Luka Dornhecker Date: Thu, 2 Apr 2015 22:22:58 +0200 Subject: [PATCH 03/14] remove extra space in ssh authentication message --- cmd/serve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/serve.go b/cmd/serve.go index 484060c4c3..c291c5e341 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -102,7 +102,7 @@ func runServ(c *cli.Context) { cmd := os.Getenv("SSH_ORIGINAL_COMMAND") if cmd == "" { - println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.") + fmt.Printf("Hi, %s! You've successfully authenticated, but Gogs does not provide shell access.\n", user.Name) if user.IsAdmin { println("If this is unexpected, please log in with password and setup Gogs under another user.") } From 072c67e457e9a91b63bba1442726c71b93045e08 Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Wed, 15 Apr 2015 21:39:13 -0400 Subject: [PATCH 04/14] Wrap remember text+checkbox in label; close #1209 --- templates/user/auth/signin.tmpl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/user/auth/signin.tmpl b/templates/user/auth/signin.tmpl index 455df63ac8..8cca3aca2a 100644 --- a/templates/user/auth/signin.tmpl +++ b/templates/user/auth/signin.tmpl @@ -17,8 +17,9 @@ {{if not .IsSocialLogin}}
- -     {{.i18n.Tr "auth.remember_me"}} +
{{end}}
@@ -41,4 +42,4 @@
-{{template "ng/base/footer" .}} \ No newline at end of file +{{template "ng/base/footer" .}} From b579800e50c73b648dbbbcb54942d12a96ae926a Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Wed, 15 Apr 2015 21:49:10 -0400 Subject: [PATCH 05/14] :lipstick: Style checkbox label in sign in form --- public/ng/less/gogs/sign.less | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/public/ng/less/gogs/sign.less b/public/ng/less/gogs/sign.less index 55a9ffbbd9..3950be032a 100644 --- a/public/ng/less/gogs/sign.less +++ b/public/ng/less/gogs/sign.less @@ -25,6 +25,11 @@ The register and sign-in page style .form-label { width: 160px; } + .chk-label { + width: auto; + text-align: left; + margin-left: 176px; + } .alert{ margin:0 30px 24px 30px; } @@ -60,4 +65,4 @@ The register and sign-in page style background-color: #FFF; margin-left: -15px; } -} \ No newline at end of file +} From 3a3e1b90e7c1c293a60d74ecf3a08cb2c07743dc Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Wed, 15 Apr 2015 21:53:27 -0400 Subject: [PATCH 06/14] =?UTF-8?q?Match=20naming=20convention=20on=20page?= =?UTF-8?q?=20(checkbox=E2=86=92chk)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/user/auth/signin.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/user/auth/signin.tmpl b/templates/user/auth/signin.tmpl index 8cca3aca2a..bc0b0f2d31 100644 --- a/templates/user/auth/signin.tmpl +++ b/templates/user/auth/signin.tmpl @@ -17,7 +17,7 @@ {{if not .IsSocialLogin}}
-
From f78046fc3be8db80f8ac44512237c92825540e5d Mon Sep 17 00:00:00 2001 From: Dustin Willis Webber Date: Thu, 16 Apr 2015 14:36:32 -0400 Subject: [PATCH 07/14] typo fix --- models/login.go | 2 +- models/user.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/models/login.go b/models/login.go index 916e27310c..73d112568b 100644 --- a/models/login.go +++ b/models/login.go @@ -169,7 +169,7 @@ func UserSignIn(uname, passwd string) (*User, error) { // For plain login, user must exist to reach this line. // Now verify password. if u.LoginType == PLAIN { - if !u.ValidtePassword(passwd) { + if !u.ValidatePassword(passwd) { return nil, ErrUserNotExist } return u, nil diff --git a/models/user.go b/models/user.go index dcfd0dc5ec..8651464e7b 100644 --- a/models/user.go +++ b/models/user.go @@ -146,7 +146,7 @@ func (u *User) EncodePasswd() { } // ValidtePassword checks if given password matches the one belongs to the user. -func (u *User) ValidtePassword(passwd string) bool { +func (u *User) ValidatePassword(passwd string) bool { newUser := &User{Passwd: passwd, Salt: u.Salt} newUser.EncodePasswd() return u.Passwd == newUser.Passwd From e57594dc31fc42c1bb7ba0df77d1d4f249f8f079 Mon Sep 17 00:00:00 2001 From: Dustin Willis Webber Date: Thu, 16 Apr 2015 14:40:39 -0400 Subject: [PATCH 08/14] typo fix for comment --- models/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/user.go b/models/user.go index 8651464e7b..e0ba4be3c1 100644 --- a/models/user.go +++ b/models/user.go @@ -145,7 +145,7 @@ func (u *User) EncodePasswd() { u.Passwd = fmt.Sprintf("%x", newPasswd) } -// ValidtePassword checks if given password matches the one belongs to the user. +// ValidatePassword checks if given password matches the one belongs to the user. func (u *User) ValidatePassword(passwd string) bool { newUser := &User{Passwd: passwd, Salt: u.Salt} newUser.EncodePasswd() From 5a4f314cf7465425bb2802bf9d2995c258af6697 Mon Sep 17 00:00:00 2001 From: Dustin Willis Webber Date: Thu, 16 Apr 2015 14:42:24 -0400 Subject: [PATCH 09/14] fix calls that go rename missed --- routers/api/v1/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo.go b/routers/api/v1/repo.go index d7cc5955ab..4ec524b401 100644 --- a/routers/api/v1/repo.go +++ b/routers/api/v1/repo.go @@ -163,7 +163,7 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) { } return } - if !u.ValidtePassword(ctx.Query("password")) { + if !u.ValidatePassword(ctx.Query("password")) { ctx.HandleAPI(422, "Username or password is not correct.") return } From 6a0fec77eaacbce05486fea76b67db3f5f880e88 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 18 Apr 2015 05:21:07 -0500 Subject: [PATCH 10/14] Allow an SSHDomain configuration option. Defaults to Domain, preserves legacy behavior --- models/repo.go | 5 +++-- modules/setting/setting.go | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/models/repo.go b/models/repo.go index 7b47c20b1e..cc4b53b0f2 100644 --- a/models/repo.go +++ b/models/repo.go @@ -242,10 +242,11 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) { if err = repo.GetOwner(); err != nil { return cl, err } + if setting.SSHPort != 22 { - cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName) + cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName) } else { - cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName) + cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.LowerName, repo.LowerName) } cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName) return cl, nil diff --git a/modules/setting/setting.go b/modules/setting/setting.go index aefc3520f9..3ce27b2e3b 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -53,6 +53,7 @@ var ( HttpAddr, HttpPort string DisableSSH bool SSHPort int + SSHDomain string OfflineMode bool DisableRouterLog bool CertFile, KeyFile string @@ -232,6 +233,7 @@ func NewConfigContext() { HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0") HttpPort = sec.Key("HTTP_PORT").MustString("3000") DisableSSH = sec.Key("DISABLE_SSH").MustBool() + SSHDomain = sec.Key("SSH_DOMAIN").MustString(Domain) SSHPort = sec.Key("SSH_PORT").MustInt(22) OfflineMode = sec.Key("OFFLINE_MODE").MustBool() DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool() From 51aef347ee8b315426b81d97e5dc82fe11cea3bf Mon Sep 17 00:00:00 2001 From: Dhuan Date: Sat, 4 Apr 2015 17:53:21 +0000 Subject: [PATCH 11/14] Display author's name on explore page --- templates/explore/repos.tmpl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/explore/repos.tmpl b/templates/explore/repos.tmpl index 954d0b06ec..3718803172 100644 --- a/templates/explore/repos.tmpl +++ b/templates/explore/repos.tmpl @@ -12,7 +12,9 @@
  • {{.NumStars}}
  • {{.NumForks}}
  • -

    {{.Name}}

    +

    + {{.Owner.Name}} / {{.Name}} +

    {{.Description}}

    {{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}

    @@ -22,4 +24,4 @@ -{{template "ng/base/footer" .}} \ No newline at end of file +{{template "ng/base/footer" .}} From 80e640f082e55d1661f94f6e5d744a6edc8cc43e Mon Sep 17 00:00:00 2001 From: Dhuan Date: Sat, 18 Apr 2015 16:22:27 +0000 Subject: [PATCH 12/14] Fix HTML indentation --- templates/explore/repos.tmpl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/templates/explore/repos.tmpl b/templates/explore/repos.tmpl index 3718803172..1e0143f56a 100644 --- a/templates/explore/repos.tmpl +++ b/templates/explore/repos.tmpl @@ -2,25 +2,25 @@ {{template "ng/base/header" .}}
    - {{template "explore/nav" .}} + {{template "explore/nav" .}}
    -
    - {{range .Repos}} -
    -
      -
    • {{.NumStars}}
    • -
    • {{.NumForks}}
    • -
    -

    - {{.Owner.Name}} / {{.Name}} -

    -

    {{.Description}}

    -

    {{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}

    -
    - {{end}} -
    -
    +
    + {{range .Repos}} +
    +
      +
    • {{.NumStars}}
    • +
    • {{.NumForks}}
    • +
    +

    + {{.Owner.Name}} / {{.Name}} +

    +

    {{.Description}}

    +

    {{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}

    +
    + {{end}} +
    +
    From 8363c9dd0f2161d4ca34f4b1e3eb5e02cf738a31 Mon Sep 17 00:00:00 2001 From: William Roush Date: Mon, 20 Apr 2015 01:28:19 -0400 Subject: [PATCH 13/14] Fixes issue with LDAP inserting users with blank names. --- models/repo.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/models/repo.go b/models/repo.go index cc4b53b0f2..f144be5a3f 100644 --- a/models/repo.go +++ b/models/repo.go @@ -40,6 +40,7 @@ var ( ErrRepoFileNotLoaded = errors.New("Repository file not loaded") ErrMirrorNotExist = errors.New("Mirror does not exist") ErrInvalidReference = errors.New("Invalid reference specified") + ErrNameEmpty = errors.New("Name is empty") ) var ( @@ -259,7 +260,11 @@ var ( // IsUsableName checks if name is reserved or pattern of name is not allowed. func IsUsableName(name string) error { - name = strings.ToLower(name) + name = strings.TrimSpace(strings.ToLower(name)) + if utf8.RuneCountInString(name) == 0 { + return ErrNameEmpty + } + for i := range reservedNames { if name == reservedNames[i] { return ErrNameReserved{name} From 182003aa417ba67661c6743e0fabe6e1f67efd1c Mon Sep 17 00:00:00 2001 From: Paolo Borelli Date: Thu, 23 Apr 2015 13:58:57 +0200 Subject: [PATCH 14/14] Add PAM authentication --- .travis.yml | 6 ++-- conf/locale/locale_en-US.ini | 1 + models/login.go | 61 ++++++++++++++++++++++++++++++++++ modules/auth/auth_form.go | 1 + modules/auth/pam/pam.go | 35 +++++++++++++++++++ modules/auth/pam/pam_stub.go | 15 +++++++++ public/ng/js/gogs.js | 7 ++++ routers/admin/auths.go | 8 +++++ templates/admin/auth/edit.tmpl | 6 ++++ templates/admin/auth/new.tmpl | 6 ++++ 10 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 modules/auth/pam/pam.go create mode 100644 modules/auth/pam/pam_stub.go diff --git a/.travis.yml b/.travis.yml index 4149e17316..113773d697 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,13 @@ go: - 1.4 - tip -sudo: false +before_install: + - sudo apt-get update -qq + - sudo apt-get install -y libpam-dev script: go build -v notifications: email: - u@gogs.io - slack: gophercn:o5pSanyTeNhnfYc3QnG0X7Wx \ No newline at end of file + slack: gophercn:o5pSanyTeNhnfYc3QnG0X7Wx diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini index 3fbc71cb14..8e768ae6ec 100644 --- a/conf/locale/locale_en-US.ini +++ b/conf/locale/locale_en-US.ini @@ -619,6 +619,7 @@ auths.smtp_auth = SMTP Authorization Type auths.smtphost = SMTP Host auths.smtpport = SMTP Port auths.enable_tls = Enable TLS Encryption +auths.pam_service_name = PAM Service Name auths.enable_auto_register = Enable Auto Registration auths.tips = Tips auths.edit = Edit Authorization Setting diff --git a/models/login.go b/models/login.go index 916e27310c..8b773c1397 100644 --- a/models/login.go +++ b/models/login.go @@ -17,6 +17,7 @@ import ( "github.com/go-xorm/xorm" "github.com/gogits/gogs/modules/auth/ldap" + "github.com/gogits/gogs/modules/auth/pam" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/uuid" ) @@ -28,6 +29,7 @@ const ( PLAIN LDAP SMTP + PAM ) var ( @@ -39,12 +41,14 @@ var ( var LoginTypes = map[LoginType]string{ LDAP: "LDAP", SMTP: "SMTP", + PAM: "PAM", } // Ensure structs implemented interface. var ( _ core.Conversion = &LDAPConfig{} _ core.Conversion = &SMTPConfig{} + _ core.Conversion = &PAMConfig{} ) type LDAPConfig struct { @@ -74,6 +78,18 @@ func (cfg *SMTPConfig) ToDB() ([]byte, error) { return json.Marshal(cfg) } +type PAMConfig struct { + ServiceName string // pam service (e.g. system-auth) +} + +func (cfg *PAMConfig) FromDB(bs []byte) error { + return json.Unmarshal(bs, &cfg) +} + +func (cfg *PAMConfig) ToDB() ([]byte, error) { + return json.Marshal(cfg) +} + type LoginSource struct { Id int64 Type LoginType @@ -97,6 +113,10 @@ func (source *LoginSource) SMTP() *SMTPConfig { return source.Cfg.(*SMTPConfig) } +func (source *LoginSource) PAM() *PAMConfig { + return source.Cfg.(*PAMConfig) +} + func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { if colName == "type" { ty := (*val).(int64) @@ -105,6 +125,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { source.Cfg = new(LDAPConfig) case SMTP: source.Cfg = new(SMTPConfig) + case PAM: + source.Cfg = new(PAMConfig) } } } @@ -197,6 +219,13 @@ func UserSignIn(uname, passwd string) (*User, error) { return u, nil } log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err) + } else if source.Type == PAM { + u, err := LoginUserPAMSource(nil, uname, passwd, + source.Id, source.Cfg.(*PAMConfig), true) + if err == nil { + return u, nil + } + log.Warn("Fail to login(%s) by PAM(%s): %v", uname, source.Name, err) } } @@ -218,6 +247,8 @@ func UserSignIn(uname, passwd string) (*User, error) { return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false) case SMTP: return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false) + case PAM: + return LoginUserPAMSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*PAMConfig), false) } return nil, ErrUnsupportedLoginType } @@ -359,3 +390,33 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP err := CreateUser(u) return u, err } + +// Query if name/passwd can login against PAM +// Create a local user if success +// Return the same LoginUserPlain semantic +func LoginUserPAMSource(u *User, name, passwd string, sourceId int64, cfg *PAMConfig, autoRegister bool) (*User, error) { + if err := pam.PAMAuth(cfg.ServiceName, name, passwd); err != nil { + if strings.Contains(err.Error(), "Authentication failure") { + return nil, ErrUserNotExist + } + return nil, err + } + + if !autoRegister { + return u, nil + } + + // fake a local user creation + u = &User{ + LowerName: strings.ToLower(name), + Name: strings.ToLower(name), + LoginType: PAM, + LoginSource: sourceId, + LoginName: name, + IsActive: true, + Passwd: passwd, + Email: name, + } + err := CreateUser(u) + return u, err +} diff --git a/modules/auth/auth_form.go b/modules/auth/auth_form.go index 7d45999914..1102dc3492 100644 --- a/modules/auth/auth_form.go +++ b/modules/auth/auth_form.go @@ -30,6 +30,7 @@ type AuthenticationForm struct { SMTPPort int `form:"smtp_port"` TLS bool `form:"tls"` AllowAutoRegister bool `form:"allowautoregister"` + PAMServiceName string } func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { diff --git a/modules/auth/pam/pam.go b/modules/auth/pam/pam.go new file mode 100644 index 0000000000..7d150b1c0b --- /dev/null +++ b/modules/auth/pam/pam.go @@ -0,0 +1,35 @@ +// +build !windows + +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package pam + +import ( + "errors" + + "github.com/msteinert/pam" +) + +func PAMAuth(serviceName, userName, passwd string) error { + t, err := pam.StartFunc(serviceName, userName, func(s pam.Style, msg string) (string, error) { + switch s { + case pam.PromptEchoOff: + return passwd, nil + case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo: + return "", nil + } + return "", errors.New("Unrecognized PAM message style") + }) + + if err != nil { + return err + } + + if err = t.Authenticate(0); err != nil { + return err + } + + return nil +} diff --git a/modules/auth/pam/pam_stub.go b/modules/auth/pam/pam_stub.go new file mode 100644 index 0000000000..2f210bf6e7 --- /dev/null +++ b/modules/auth/pam/pam_stub.go @@ -0,0 +1,15 @@ +// +build windows + +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package pam + +import ( + "errors" +) + +func PAMAuth(serviceName, userName, passwd string) error { + return errors.New("PAM not supported") +} diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js index c5fd719c32..7ffef8af8b 100644 --- a/public/ng/js/gogs.js +++ b/public/ng/js/gogs.js @@ -753,10 +753,17 @@ function initAdmin() { if (v == 2) { $('.ldap').toggleShow(); $('.smtp').toggleHide(); + $('.pam').toggleHide(); } if (v == 3) { $('.smtp').toggleShow(); $('.ldap').toggleHide(); + $('.pam').toggleHide(); + } + if (v == 4) { + $('.pam').toggleShow(); + $('.smtp').toggleHide(); + $('.ldap').toggleHide(); } }); diff --git a/routers/admin/auths.go b/routers/admin/auths.go index b13b0bd134..2bec7da46c 100644 --- a/routers/admin/auths.go +++ b/routers/admin/auths.go @@ -84,6 +84,10 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { Port: form.SMTPPort, TLS: form.TLS, } + case models.PAM: + u = &models.PAMConfig{ + ServiceName: form.PAMServiceName, + } default: ctx.Error(400) return @@ -166,6 +170,10 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { Port: form.SMTPPort, TLS: form.TLS, } + case models.PAM: + config = &models.PAMConfig{ + ServiceName: form.PAMServiceName, + } default: ctx.Error(400) return diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl index a178b71756..12d1d1f8f2 100644 --- a/templates/admin/auth/edit.tmpl +++ b/templates/admin/auth/edit.tmpl @@ -91,6 +91,12 @@ + + {{else if eq $type 4}} +
    + + +
    {{end}}
    diff --git a/templates/admin/auth/new.tmpl b/templates/admin/auth/new.tmpl index 0d1f2ab417..36b90cfb48 100644 --- a/templates/admin/auth/new.tmpl +++ b/templates/admin/auth/new.tmpl @@ -86,6 +86,12 @@
    +