@@ -2630,6 +2630,107 @@ func TestClient_auth(t *testing.T) {
26302630 t .Fatalf ("client should have failed to connect" )
26312631 }
26322632 })
2633+ // https://github.com/wneessen/go-mail/issues/428
2634+ t .Run ("auth with custom auth type should succeed" , func (t * testing.T ) {
2635+ ctx , cancel := context .WithCancel (context .Background ())
2636+ defer cancel ()
2637+ PortAdder .Add (1 )
2638+ serverPort := int (TestServerPortBase + PortAdder .Load ())
2639+ featureSet := "250-AUTH CUSTOM\r \n 250-8BITMIME\r \n 250-STARTTLS\r \n 250-DSN\r \n 250 SMTPUTF8"
2640+ go func () {
2641+ if err := simpleSMTPServer (ctx , t , & serverProps {
2642+ FeatureSet : featureSet ,
2643+ ListenPort : serverPort ,
2644+ }); err != nil {
2645+ t .Errorf ("failed to start test server: %s" , err )
2646+ return
2647+ }
2648+ }()
2649+ time .Sleep (time .Millisecond * 30 )
2650+
2651+ ctxDial , cancelDial := context .WithTimeout (ctx , time .Millisecond * 500 )
2652+ t .Cleanup (cancelDial )
2653+
2654+ message := testMessage (t )
2655+ client , err := NewClient (DefaultHost , WithPort (serverPort ),
2656+ WithTLSPolicy (TLSMandatory ), WithSMTPAuthCustom (newTestCustomAuth ()), WithTLSConfig (& tlsConfig ),
2657+ WithUsername ("test" ), WithPassword ("password" ))
2658+ if err != nil {
2659+ t .Fatalf ("failed to create new client: %s" , err )
2660+ }
2661+ if err = client .DialWithContext (ctxDial ); err != nil {
2662+ t .Fatalf ("failed to connect to test server: %s" , err )
2663+ }
2664+ if err = client .Send (message ); err != nil {
2665+ t .Errorf ("failed to send message: %s" , err )
2666+ }
2667+ })
2668+ // https://github.com/wneessen/go-mail/issues/428
2669+ t .Run ("auth with custom auth type should fail" , func (t * testing.T ) {
2670+ ctx , cancel := context .WithCancel (context .Background ())
2671+ defer cancel ()
2672+ PortAdder .Add (1 )
2673+ serverPort := int (TestServerPortBase + PortAdder .Load ())
2674+ featureSet := "250-AUTH UNKNOWN\r \n 250-8BITMIME\r \n 250-STARTTLS\r \n 250-DSN\r \n 250 SMTPUTF8"
2675+ go func () {
2676+ if err := simpleSMTPServer (ctx , t , & serverProps {
2677+ FeatureSet : featureSet ,
2678+ ListenPort : serverPort ,
2679+ }); err != nil {
2680+ t .Errorf ("failed to start test server: %s" , err )
2681+ return
2682+ }
2683+ }()
2684+ time .Sleep (time .Millisecond * 30 )
2685+
2686+ ctxDial , cancelDial := context .WithTimeout (ctx , time .Millisecond * 500 )
2687+ t .Cleanup (cancelDial )
2688+
2689+ client , err := NewClient (DefaultHost , WithPort (serverPort ),
2690+ WithTLSPolicy (TLSMandatory ), WithSMTPAuthCustom (newTestCustomAuth ()), WithTLSConfig (& tlsConfig ),
2691+ WithUsername ("test" ), WithPassword ("password" ))
2692+ if err != nil {
2693+ t .Fatalf ("failed to create new client: %s" , err )
2694+ }
2695+ if err = client .DialWithContext (ctxDial ); err == nil {
2696+ t .Fatalf ("client should have failed to connect" )
2697+ }
2698+ })
2699+ // https://github.com/wneessen/go-mail/issues/428
2700+ t .Run ("auth with custom auth type overridden by SetCustomAuth" , func (t * testing.T ) {
2701+ ctx , cancel := context .WithCancel (context .Background ())
2702+ defer cancel ()
2703+ PortAdder .Add (1 )
2704+ serverPort := int (TestServerPortBase + PortAdder .Load ())
2705+ featureSet := "250-AUTH CUSTOM\r \n 250-8BITMIME\r \n 250-STARTTLS\r \n 250-DSN\r \n 250 SMTPUTF8"
2706+ go func () {
2707+ if err := simpleSMTPServer (ctx , t , & serverProps {
2708+ FeatureSet : featureSet ,
2709+ ListenPort : serverPort ,
2710+ }); err != nil {
2711+ t .Errorf ("failed to start test server: %s" , err )
2712+ return
2713+ }
2714+ }()
2715+ time .Sleep (time .Millisecond * 30 )
2716+
2717+ ctxDial , cancelDial := context .WithTimeout (ctx , time .Millisecond * 500 )
2718+ t .Cleanup (cancelDial )
2719+
2720+ message := testMessage (t )
2721+ client , err := NewClient (DefaultHost , WithPort (serverPort ),
2722+ WithTLSPolicy (TLSMandatory ), WithSMTPAuth (SMTPAuthPlain ), WithTLSConfig (& tlsConfig ))
2723+ if err != nil {
2724+ t .Fatalf ("failed to create new client: %s" , err )
2725+ }
2726+ client .SetSMTPAuthCustom (newTestCustomAuth ())
2727+ if err = client .DialWithContext (ctxDial ); err != nil {
2728+ t .Fatalf ("failed to connect to test server: %s" , err )
2729+ }
2730+ if err = client .Send (message ); err != nil {
2731+ t .Errorf ("failed to send message: %s" , err )
2732+ }
2733+ })
26332734}
26342735
26352736func TestClient_authTypeAutoDiscover (t * testing.T ) {
@@ -3913,6 +4014,39 @@ func (t *testSender) Send(ctx context.Context, m *Msg) error {
39134014 return nil
39144015}
39154016
4017+ // testCustomAuth is a custom authentication mechanism implementation that satisfies the smtp.Auth
4018+ // interface. It is used to test the SMTPAuthCustom type.
4019+ type testCustomAuth struct {}
4020+
4021+ // newTestCustomAuth initializes and returns a new testCustomAuth instance for use in testing
4022+ // custom authentication.
4023+ func newTestCustomAuth () * testCustomAuth {
4024+ return & testCustomAuth {}
4025+ }
4026+
4027+ // Start begins the custom authentication process, verifying if the "CUSTOM" method is supported
4028+ // by the SMTP server.
4029+ func (a * testCustomAuth ) Start (info * smtp.ServerInfo ) (proto string , toServer []byte , err error ) {
4030+ if len (info .Auth ) > 0 {
4031+ supported := false
4032+ for _ , method := range info .Auth {
4033+ if method == "CUSTOM" {
4034+ supported = true
4035+ }
4036+ }
4037+ if ! supported {
4038+ return "" , nil , fmt .Errorf ("custom auth method not supported" )
4039+ }
4040+ }
4041+ return "CUSTOM" , nil , nil
4042+ }
4043+
4044+ // Next processes the next step in the authentication exchange, returning data to send to the server
4045+ // or an error.
4046+ func (a * testCustomAuth ) Next ([]byte , bool ) (toServer []byte , err error ) {
4047+ return nil , nil
4048+ }
4049+
39164050// parseJSONLog parses a JSON encoded log from the provided buffer and returns a slice of logLine structs.
39174051// In case of a decode error, it reports the error to the testing framework.
39184052func parseJSONLog (t * testing.T , buf * bytes.Buffer ) logData {
0 commit comments