#1542 A way to skip TLS verify for SMTP authentication
This commit is contained in:
parent
384fbeca80
commit
ea454c21f7
@ -794,6 +794,7 @@ auths.smtp_auth = SMTP Authorization Type
|
|||||||
auths.smtphost = SMTP Host
|
auths.smtphost = SMTP Host
|
||||||
auths.smtpport = SMTP Port
|
auths.smtpport = SMTP Port
|
||||||
auths.enable_tls = Enable TLS Encryption
|
auths.enable_tls = Enable TLS Encryption
|
||||||
|
auths.skip_tls_verify = Skip TLS Verify
|
||||||
auths.pam_service_name = PAM Service Name
|
auths.pam_service_name = PAM Service Name
|
||||||
auths.enable_auto_register = Enable Auto Registration
|
auths.enable_auto_register = Enable Auto Registration
|
||||||
auths.tips = Tips
|
auths.tips = Tips
|
||||||
|
@ -67,6 +67,7 @@ type SMTPConfig struct {
|
|||||||
Host string
|
Host string
|
||||||
Port int
|
Port int
|
||||||
TLS bool
|
TLS bool
|
||||||
|
SkipVerify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *SMTPConfig) FromDB(bs []byte) error {
|
func (cfg *SMTPConfig) FromDB(bs []byte) error {
|
||||||
@ -90,7 +91,7 @@ func (cfg *PAMConfig) ToDB() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LoginSource struct {
|
type LoginSource struct {
|
||||||
Id int64
|
ID int64 `xorm:"pk autoincr"`
|
||||||
Type LoginType
|
Type LoginType
|
||||||
Name string `xorm:"UNIQUE"`
|
Name string `xorm:"UNIQUE"`
|
||||||
IsActived bool `xorm:"NOT NULL DEFAULT false"`
|
IsActived bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
@ -100,6 +101,20 @@ type LoginSource struct {
|
|||||||
Updated time.Time `xorm:"UPDATED"`
|
Updated time.Time `xorm:"UPDATED"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
|
||||||
|
switch colName {
|
||||||
|
case "type":
|
||||||
|
switch LoginType((*val).(int64)) {
|
||||||
|
case LDAP:
|
||||||
|
source.Cfg = new(LDAPConfig)
|
||||||
|
case SMTP:
|
||||||
|
source.Cfg = new(SMTPConfig)
|
||||||
|
case PAM:
|
||||||
|
source.Cfg = new(PAMConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (source *LoginSource) TypeString() string {
|
func (source *LoginSource) TypeString() string {
|
||||||
return LoginTypes[source.Type]
|
return LoginTypes[source.Type]
|
||||||
}
|
}
|
||||||
@ -116,32 +131,17 @@ func (source *LoginSource) PAM() *PAMConfig {
|
|||||||
return source.Cfg.(*PAMConfig)
|
return source.Cfg.(*PAMConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
|
|
||||||
if colName == "type" {
|
|
||||||
ty := (*val).(int64)
|
|
||||||
switch LoginType(ty) {
|
|
||||||
case LDAP:
|
|
||||||
source.Cfg = new(LDAPConfig)
|
|
||||||
case SMTP:
|
|
||||||
source.Cfg = new(SMTPConfig)
|
|
||||||
case PAM:
|
|
||||||
source.Cfg = new(PAMConfig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateSource(source *LoginSource) error {
|
func CreateSource(source *LoginSource) error {
|
||||||
_, err := x.Insert(source)
|
_, err := x.Insert(source)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAuths() ([]*LoginSource, error) {
|
func GetAuths() ([]*LoginSource, error) {
|
||||||
var auths = make([]*LoginSource, 0, 5)
|
auths := make([]*LoginSource, 0, 5)
|
||||||
err := x.Find(&auths)
|
return auths, x.Find(&auths)
|
||||||
return auths, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLoginSourceById(id int64) (*LoginSource, error) {
|
func GetLoginSourceByID(id int64) (*LoginSource, error) {
|
||||||
source := new(LoginSource)
|
source := new(LoginSource)
|
||||||
has, err := x.Id(id).Get(source)
|
has, err := x.Id(id).Get(source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -153,19 +153,19 @@ func GetLoginSourceById(id int64) (*LoginSource, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSource(source *LoginSource) error {
|
func UpdateSource(source *LoginSource) error {
|
||||||
_, err := x.Id(source.Id).AllCols().Update(source)
|
_, err := x.Id(source.ID).AllCols().Update(source)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func DelLoginSource(source *LoginSource) error {
|
func DelLoginSource(source *LoginSource) error {
|
||||||
cnt, err := x.Count(&User{LoginSource: source.Id})
|
cnt, err := x.Count(&User{LoginSource: source.ID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cnt > 0 {
|
if cnt > 0 {
|
||||||
return ErrAuthenticationUserUsed
|
return ErrAuthenticationUserUsed
|
||||||
}
|
}
|
||||||
_, err = x.Id(source.Id).Delete(&LoginSource{})
|
_, err = x.Id(source.ID).Delete(&LoginSource{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,21 +206,21 @@ func UserSignIn(uname, passwd string) (*User, error) {
|
|||||||
for _, source := range sources {
|
for _, source := range sources {
|
||||||
if source.Type == LDAP {
|
if source.Type == LDAP {
|
||||||
u, err := LoginUserLdapSource(nil, uname, passwd,
|
u, err := LoginUserLdapSource(nil, uname, passwd,
|
||||||
source.Id, source.Cfg.(*LDAPConfig), true)
|
source.ID, source.Cfg.(*LDAPConfig), true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
|
log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
|
||||||
} else if source.Type == SMTP {
|
} else if source.Type == SMTP {
|
||||||
u, err := LoginUserSMTPSource(nil, uname, passwd,
|
u, err := LoginUserSMTPSource(nil, uname, passwd,
|
||||||
source.Id, source.Cfg.(*SMTPConfig), true)
|
source.ID, source.Cfg.(*SMTPConfig), true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
|
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
|
||||||
} else if source.Type == PAM {
|
} else if source.Type == PAM {
|
||||||
u, err := LoginUserPAMSource(nil, uname, passwd,
|
u, err := LoginUserPAMSource(nil, uname, passwd,
|
||||||
source.Id, source.Cfg.(*PAMConfig), true)
|
source.ID, source.Cfg.(*PAMConfig), true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
@ -243,11 +243,11 @@ func UserSignIn(uname, passwd string) (*User, error) {
|
|||||||
|
|
||||||
switch u.LoginType {
|
switch u.LoginType {
|
||||||
case LDAP:
|
case LDAP:
|
||||||
return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false)
|
return LoginUserLdapSource(u, u.LoginName, passwd, source.ID, source.Cfg.(*LDAPConfig), false)
|
||||||
case SMTP:
|
case SMTP:
|
||||||
return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false)
|
return LoginUserSMTPSource(u, u.LoginName, passwd, source.ID, source.Cfg.(*SMTPConfig), false)
|
||||||
case PAM:
|
case PAM:
|
||||||
return LoginUserPAMSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*PAMConfig), false)
|
return LoginUserPAMSource(u, u.LoginName, passwd, source.ID, source.Cfg.(*PAMConfig), false)
|
||||||
}
|
}
|
||||||
return nil, ErrUnsupportedLoginType
|
return nil, ErrUnsupportedLoginType
|
||||||
}
|
}
|
||||||
@ -311,14 +311,17 @@ func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
const (
|
||||||
SMTP_PLAIN = "PLAIN"
|
SMTP_PLAIN = "PLAIN"
|
||||||
SMTP_LOGIN = "LOGIN"
|
SMTP_LOGIN = "LOGIN"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
SMTPAuths = []string{SMTP_PLAIN, SMTP_LOGIN}
|
SMTPAuths = []string{SMTP_PLAIN, SMTP_LOGIN}
|
||||||
)
|
)
|
||||||
|
|
||||||
func SmtpAuth(host string, port int, a smtp.Auth, useTls bool) error {
|
func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error {
|
||||||
c, err := smtp.Dial(fmt.Sprintf("%s:%d", host, port))
|
c, err := smtp.Dial(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -328,10 +331,12 @@ func SmtpAuth(host string, port int, a smtp.Auth, useTls bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if useTls {
|
if cfg.TLS {
|
||||||
if ok, _ := c.Extension("STARTTLS"); ok {
|
if ok, _ := c.Extension("STARTTLS"); ok {
|
||||||
config := &tls.Config{ServerName: host}
|
if err = c.StartTLS(&tls.Config{
|
||||||
if err = c.StartTLS(config); err != nil {
|
InsecureSkipVerify: cfg.SkipVerify,
|
||||||
|
ServerName: cfg.Host,
|
||||||
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -361,7 +366,7 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP
|
|||||||
return nil, errors.New("Unsupported SMTP auth type")
|
return nil, errors.New("Unsupported SMTP auth type")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SmtpAuth(cfg.Host, cfg.Port, auth, cfg.TLS); err != nil {
|
if err := SMTPAuth(auth, cfg); err != nil {
|
||||||
if strings.Contains(err.Error(), "Username and Password not accepted") {
|
if strings.Contains(err.Error(), "Username and Password not accepted") {
|
||||||
return nil, ErrUserNotExist{u.Id, u.Name}
|
return nil, ErrUserNotExist{u.Id, u.Name}
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,6 @@ var (
|
|||||||
Gitignores, Licenses, Readmes []string
|
Gitignores, Licenses, Readmes []string
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
DescPattern = regexp.MustCompile(`https?://\S+`)
|
|
||||||
)
|
|
||||||
|
|
||||||
func LoadRepoConfig() {
|
func LoadRepoConfig() {
|
||||||
// Load .gitignore and license files and readme templates.
|
// Load .gitignore and license files and readme templates.
|
||||||
types := []string{"gitignore", "license", "readme"}
|
types := []string{"gitignore", "license", "readme"}
|
||||||
@ -266,6 +262,10 @@ func (repo *Repository) IsOwnedBy(userID int64) bool {
|
|||||||
return repo.OwnerID == userID
|
return repo.OwnerID == userID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
DescPattern = regexp.MustCompile(`https?://\S+`)
|
||||||
|
)
|
||||||
|
|
||||||
// DescriptionHtml does special handles to description and return HTML string.
|
// DescriptionHtml does special handles to description and return HTML string.
|
||||||
func (repo *Repository) DescriptionHtml() template.HTML {
|
func (repo *Repository) DescriptionHtml() template.HTML {
|
||||||
sanitize := func(s string) string {
|
sanitize := func(s string) string {
|
||||||
|
@ -29,6 +29,7 @@ type AuthenticationForm struct {
|
|||||||
SMTPHost string `form:"smtp_host"`
|
SMTPHost string `form:"smtp_host"`
|
||||||
SMTPPort int `form:"smtp_port"`
|
SMTPPort int `form:"smtp_port"`
|
||||||
TLS bool `form:"tls"`
|
TLS bool `form:"tls"`
|
||||||
|
SkipVerify bool
|
||||||
AllowAutoRegister bool `form:"allowautoregister"`
|
AllowAutoRegister bool `form:"allowautoregister"`
|
||||||
PAMServiceName string
|
PAMServiceName string
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -84,6 +84,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
|
|||||||
Host: form.SMTPHost,
|
Host: form.SMTPHost,
|
||||||
Port: form.SMTPPort,
|
Port: form.SMTPPort,
|
||||||
TLS: form.TLS,
|
TLS: form.TLS,
|
||||||
|
SkipVerify: form.SkipVerify,
|
||||||
}
|
}
|
||||||
case models.PAM:
|
case models.PAM:
|
||||||
u = &models.PAMConfig{
|
u = &models.PAMConfig{
|
||||||
@ -123,7 +124,7 @@ func EditAuthSource(ctx *middleware.Context) {
|
|||||||
ctx.Handle(404, "EditAuthSource", nil)
|
ctx.Handle(404, "EditAuthSource", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u, err := models.GetLoginSourceById(id)
|
u, err := models.GetLoginSourceByID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "GetLoginSourceById", err)
|
ctx.Handle(500, "GetLoginSourceById", err)
|
||||||
return
|
return
|
||||||
@ -171,6 +172,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
|
|||||||
Host: form.SMTPHost,
|
Host: form.SMTPHost,
|
||||||
Port: form.SMTPPort,
|
Port: form.SMTPPort,
|
||||||
TLS: form.TLS,
|
TLS: form.TLS,
|
||||||
|
SkipVerify: form.SkipVerify,
|
||||||
}
|
}
|
||||||
case models.PAM:
|
case models.PAM:
|
||||||
config = &models.PAMConfig{
|
config = &models.PAMConfig{
|
||||||
@ -182,7 +184,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u := models.LoginSource{
|
u := models.LoginSource{
|
||||||
Id: form.ID,
|
ID: form.ID,
|
||||||
Name: form.Name,
|
Name: form.Name,
|
||||||
IsActived: form.IsActived,
|
IsActived: form.IsActived,
|
||||||
Type: models.LoginType(form.Type),
|
Type: models.LoginType(form.Type),
|
||||||
@ -207,7 +209,7 @@ func DeleteAuthSource(ctx *middleware.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a, err := models.GetLoginSourceById(id)
|
a, err := models.GetLoginSourceByID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "GetLoginSourceById", err)
|
ctx.Handle(500, "GetLoginSourceById", err)
|
||||||
return
|
return
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<strong>{{.i18n.Tr "admin.auths.edit"}}</strong>
|
<strong>{{.i18n.Tr "admin.auths.edit"}}</strong>
|
||||||
</div>
|
</div>
|
||||||
<form class="form form-align panel-body" id="auth-setting-form" action="{{AppSubUrl}}/admin/auths/{{.Source.Id}}" data-delete-url="{{AppSubUrl}}/admin/auths/{{.Source.Id}}/delete" method="post">
|
<form class="form form-align panel-body" id="auth-setting-form" action="{{AppSubUrl}}/admin/auths/{{.Source.ID}}" data-delete-url="{{AppSubUrl}}/admin/auths/{{.Source.ID}}/delete" method="post">
|
||||||
{{.CsrfTokenHtml}}
|
{{.CsrfTokenHtml}}
|
||||||
<input type="hidden" value="{{.Source.Id}}" name="id"/>
|
<input type="hidden" value="{{.Source.ID}}" name="id"/>
|
||||||
{{$type := .Source.Type}}
|
{{$type := .Source.Type}}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{.i18n.Tr "admin.auths.auth_type"}}</label>
|
<label>{{.i18n.Tr "admin.auths.auth_type"}}</label>
|
||||||
@ -109,6 +109,10 @@
|
|||||||
<input name="tls" type="checkbox" {{if .Source.SMTP.TLS}}checked{{end}}>
|
<input name="tls" type="checkbox" {{if .Source.SMTP.TLS}}checked{{end}}>
|
||||||
<strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong>
|
<strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong>
|
||||||
<br>
|
<br>
|
||||||
|
<label></label>
|
||||||
|
<input name="skip_verify" type="checkbox" {{if .Source.SMTP.SkipVerify}}checked{{end}}>
|
||||||
|
<strong>{{.i18n.Tr "admin.auths.skip_tls_verify"}}</strong>
|
||||||
|
<br>
|
||||||
{{end}}
|
{{end}}
|
||||||
<label></label>
|
<label></label>
|
||||||
<input name="allowautoregister" type="checkbox" {{if .Source.AllowAutoRegister}}checked{{end}}>
|
<input name="allowautoregister" type="checkbox" {{if .Source.AllowAutoRegister}}checked{{end}}>
|
||||||
|
@ -30,13 +30,13 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{range .Sources}}
|
{{range .Sources}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.Id}}</td>
|
<td>{{.ID}}</td>
|
||||||
<td><a href="{{AppSubUrl}}/admin/auths/{{.Id}}">{{.Name}}</a></td>
|
<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td>
|
||||||
<td>{{.TypeString}}</td>
|
<td>{{.TypeString}}</td>
|
||||||
<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td>
|
<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td>
|
||||||
<td><span title="{{DateFmtLong .Updated}}">{{DateFmtShort .Updated}}</span></td>
|
<td><span title="{{DateFmtLong .Updated}}">{{DateFmtShort .Updated}}</span></td>
|
||||||
<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
|
<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
|
||||||
<td><a href="{{AppSubUrl}}/admin/auths/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td>
|
<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}"><i class="fa fa-pencil-square-o"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -102,6 +102,10 @@
|
|||||||
<input name="tls" type="checkbox" {{if .tls}}checked{{end}}>
|
<input name="tls" type="checkbox" {{if .tls}}checked{{end}}>
|
||||||
<strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong>
|
<strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong>
|
||||||
<br>
|
<br>
|
||||||
|
<label></label>
|
||||||
|
<input name="skip_verify" type="checkbox" {{if .skip_verify}}checked{{end}}>
|
||||||
|
<strong>{{.i18n.Tr "admin.auths.skip_tls_verify"}}</strong>
|
||||||
|
<br>
|
||||||
</div>
|
</div>
|
||||||
<label></label>
|
<label></label>
|
||||||
<input name="allowautoregister" type="checkbox" {{if .allowautoregister}}checked{{end}}>
|
<input name="allowautoregister" type="checkbox" {{if .allowautoregister}}checked{{end}}>
|
||||||
|
Loading…
Reference in New Issue
Block a user