@@ -26,6 +26,7 @@ import (
26
26
"code.gitea.io/gitea/modules/setting"
27
27
"code.gitea.io/gitea/modules/templates"
28
28
29
+ ntlmssp "github.com/Azure/go-ntlmssp"
29
30
"github.com/jaytaylor/html2text"
30
31
"gopkg.in/gomail.v2"
31
32
)
@@ -145,6 +146,35 @@ func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
145
146
return nil , nil
146
147
}
147
148
149
+ type ntlmAuth struct {
150
+ username , password , domain string
151
+ domainNeeded bool
152
+ }
153
+
154
+ // NtlmAuth SMTP AUTH NTLM Auth Handler
155
+ func NtlmAuth (username , password string ) smtp.Auth {
156
+ user , domain , domainNeeded := ntlmssp .GetDomain (username )
157
+ return & ntlmAuth {user , password , domain , domainNeeded }
158
+ }
159
+
160
+ // Start starts SMTP NTLM Auth
161
+ func (a * ntlmAuth ) Start (server * smtp.ServerInfo ) (string , []byte , error ) {
162
+ negotiateMessage , err := ntlmssp .NewNegotiateMessage (a .domain , "" )
163
+ return "NTLM" , negotiateMessage , err
164
+ }
165
+
166
+ // Next next step of SMTP ntlm auth
167
+ func (a * ntlmAuth ) Next (fromServer []byte , more bool ) ([]byte , error ) {
168
+ if more {
169
+ if len (fromServer ) == 0 {
170
+ return nil , fmt .Errorf ("ntlm ChallengeMessage is empty" )
171
+ }
172
+ authenticateMessage , err := ntlmssp .ProcessChallenge (fromServer , a .username , a .password , a .domainNeeded )
173
+ return authenticateMessage , err
174
+ }
175
+ return nil , nil
176
+ }
177
+
148
178
// Sender SMTP mail sender
149
179
type smtpSender struct {}
150
180
@@ -237,6 +267,8 @@ func (s *smtpSender) Send(from string, to []string, msg io.WriterTo) error {
237
267
} else if strings .Contains (options , "LOGIN" ) {
238
268
// Patch for AUTH LOGIN
239
269
auth = LoginAuth (opts .User , opts .Passwd )
270
+ } else if strings .Contains (options , "NTLM" ) {
271
+ auth = NtlmAuth (opts .User , opts .Passwd )
240
272
}
241
273
242
274
if auth != nil {
0 commit comments