diff --git a/frontend/components/forms/admin/AppConfigForm/AppConfigForm.jsx b/frontend/components/forms/admin/AppConfigForm/AppConfigForm.jsx index 82ee968e8c..4776fbd108 100644 --- a/frontend/components/forms/admin/AppConfigForm/AppConfigForm.jsx +++ b/frontend/components/forms/admin/AppConfigForm/AppConfigForm.jsx @@ -15,6 +15,7 @@ import validate from 'components/forms/admin/AppConfigForm/validate'; const authMethodOptions = [ { label: 'Plain', value: 'authmethod_plain' }, { label: 'Cram MD5', value: 'authmethod_cram_md5' }, + { label: 'Login', value: 'authmethod_login' }, ]; const authTypeOptions = [ { label: 'Username and Password', value: 'authtype_username_password' }, diff --git a/server/kolide/app.go b/server/kolide/app.go index bb4e9c0ddc..2ccd7e5717 100644 --- a/server/kolide/app.go +++ b/server/kolide/app.go @@ -30,6 +30,7 @@ type AppConfigService interface { // SMTPAuthMethod const ( AuthMethodNameCramMD5 = "authmethod_cram_md5" + AuthMethodNameLogin = "authmethod_login" AuthMethodNamePlain = "authmethod_plain" AuthTypeNameUserNamePassword = "authtype_username_password" AuthTypeNameNone = "authtype_none" @@ -58,6 +59,7 @@ type SMTPAuthMethod int const ( AuthMethodPlain SMTPAuthMethod = iota AuthMethodCramMD5 + AuthMethodLogin ) func (m SMTPAuthMethod) String() string { @@ -66,6 +68,8 @@ func (m SMTPAuthMethod) String() string { return AuthMethodNamePlain case AuthMethodCramMD5: return AuthMethodNameCramMD5 + case AuthMethodLogin: + return AuthMethodNameLogin default: return "" } diff --git a/server/mail/mail.go b/server/mail/mail.go index 345b51ab83..e9aa926c57 100644 --- a/server/mail/mail.go +++ b/server/mail/mail.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/smtp" + "strings" "time" "github.com/kolide/fleet/server/kolide" @@ -70,6 +71,35 @@ func (m mailService) SendEmail(e kolide.Email) error { return m.sendMail(e, msg) } +type loginauth struct { + username string + password string +} + +func LoginAuth(username, password string) smtp.Auth { + return &loginauth{username: username, password: password} +} + +func (l *loginauth) Start(serverInfo *smtp.ServerInfo) (proto string, toServer []byte, err error) { + return "LOGIN", nil, nil +} + +func (l *loginauth) Next(fromServer []byte, more bool) (toServer []byte, err error) { + if !more { + return nil, nil + } + + prompt := strings.TrimSpace(string(fromServer)) + switch prompt { + case "Username:": + return []byte(l.username), nil + case "Password:": + return []byte(l.password), nil + default: + return nil, errors.New("unexpected LOGIN prompt from server") + } +} + func smtpAuth(e kolide.Email) (smtp.Auth, error) { if e.Config.SMTPAuthenticationType != kolide.AuthTypeUserNamePassword { return nil, nil @@ -80,6 +110,8 @@ func smtpAuth(e kolide.Email) (smtp.Auth, error) { auth = smtp.CRAMMD5Auth(e.Config.SMTPUserName, e.Config.SMTPPassword) case kolide.AuthMethodPlain: auth = smtp.PlainAuth("", e.Config.SMTPUserName, e.Config.SMTPPassword, e.Config.SMTPServer) + case kolide.AuthMethodLogin: + auth = LoginAuth(e.Config.SMTPUserName, e.Config.SMTPPassword) default: return nil, fmt.Errorf("unknown SMTP auth type '%d'", e.Config.SMTPAuthenticationMethod) } diff --git a/server/service/service_appconfig.go b/server/service/service_appconfig.go index f922861915..f2d2ec8e6e 100644 --- a/server/service/service_appconfig.go +++ b/server/service/service_appconfig.go @@ -150,6 +150,8 @@ func appConfigFromAppConfigPayload(p kolide.AppConfigPayload, config kolide.AppC config.SMTPAuthenticationMethod = kolide.AuthMethodCramMD5 case kolide.AuthMethodNamePlain: config.SMTPAuthenticationMethod = kolide.AuthMethodPlain + case kolide.AuthMethodNameLogin: + config.SMTPAuthenticationMethod = kolide.AuthMethodLogin default: panic("unknown SMTP AuthMethod: " + *p.SMTPAuthenticationMethod) }