Skip to content

Commit

Permalink
Merge pull request #100 from wneessen/feature/97_fork-the-netsmtp-pac…
Browse files Browse the repository at this point in the history
…kage-from-stdlib-into-go-mail

Fork the net/smtp package from Go's stdlib into go-mail
  • Loading branch information
wneessen committed Jan 13, 2023
2 parents a7126b4 + 2950f22 commit 813020f
Show file tree
Hide file tree
Showing 16 changed files with 2,187 additions and 125 deletions.
27 changes: 27 additions & 0 deletions LICENSES/BSD-3-Clause.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 changes: 13 additions & 4 deletions LICENSES/MIT.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
MIT License

Copyright (c) <year> <copyright holders>
Copyright (c) 2022-2023 The go-mail Authors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without
limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
104 changes: 0 additions & 104 deletions auth/auth_test.go

This file was deleted.

5 changes: 2 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import (
"errors"
"fmt"
"net"
"net/smtp"
"os"
"strings"
"time"

"github.com/wneessen/go-mail/auth"
"github.com/wneessen/go-mail/smtp"
)

// Defaults
Expand Down Expand Up @@ -593,7 +592,7 @@ func (c *Client) auth() error {
if !strings.Contains(sat, string(SMTPAuthLogin)) {
return ErrLoginAuthNotSupported
}
c.sa = auth.LoginAuth(c.user, c.pass, c.host)
c.sa = smtp.LoginAuth(c.user, c.pass, c.host)
case SMTPAuthCramMD5:
if !strings.Contains(sat, string(SMTPAuthCramMD5)) {
return ErrCramMD5AuthNotSupported
Expand Down
7 changes: 3 additions & 4 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import (
"crypto/tls"
"errors"
"fmt"
"net/smtp"
"os"
"strconv"
"strings"
"testing"
"time"

"github.com/wneessen/go-mail/auth"
"github.com/wneessen/go-mail/smtp"
)

// DefaultHost is used as default hostname for the Client
Expand Down Expand Up @@ -496,7 +495,7 @@ func TestSetSMTPAuthCustom(t *testing.T) {
}{
{"SMTPAuth: PLAIN", smtp.PlainAuth("", "", "", ""), "PLAIN", false},
{"SMTPAuth: CRAM-MD5", smtp.CRAMMD5Auth("", ""), "CRAM-MD5", false},
{"SMTPAuth: LOGIN", auth.LoginAuth("", "", ""), "LOGIN", false},
{"SMTPAuth: LOGIN", smtp.LoginAuth("", "", ""), "LOGIN", false},
}
si := smtp.ServerInfo{TLS: true}
for _, tt := range tests {
Expand Down Expand Up @@ -584,7 +583,7 @@ func TestClient_DialWithContextInvalidAuth(t *testing.T) {
}
c.user = "invalid"
c.pass = "invalid"
c.SetSMTPAuthCustom(auth.LoginAuth("invalid", "invalid", "invalid"))
c.SetSMTPAuthCustom(smtp.LoginAuth("invalid", "invalid", "invalid"))
ctx := context.Background()
if err := c.DialWithContext(ctx); err == nil {
t.Errorf("dial succeeded but was supposed to fail")
Expand Down
27 changes: 27 additions & 0 deletions smtp/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 changes: 44 additions & 0 deletions smtp/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Copyright 2010 The Go Authors. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2022-2023 The go-mail Authors
//
// Original net/smtp code from the Go stdlib by the Go Authors.
// Use of this source code is governed by a BSD-style
// LICENSE file that can be found in this directory.
//
// go-mail specific modifications by the go-mail Authors.
// Licensed under the MIT License.
// See [PROJECT ROOT]/LICENSES directory for more information.
//
// SPDX-License-Identifier: BSD-3-Clause AND MIT

package smtp

// Auth is implemented by an SMTP authentication mechanism.
type Auth interface {
// Start begins an authentication with a server.
// It returns the name of the authentication protocol
// and optionally data to include in the initial AUTH message
// sent to the server.
// If it returns a non-nil error, the SMTP client aborts
// the authentication attempt and closes the connection.
Start(server *ServerInfo) (proto string, toServer []byte, err error)

// Next continues the authentication. The server has just sent
// the fromServer data. If more is true, the server expects a
// response, which Next should return as toServer; otherwise
// Next should return toServer == nil.
// If Next returns a non-nil error, the SMTP client aborts
// the authentication attempt and closes the connection.
Next(fromServer []byte, more bool) (toServer []byte, err error)
}

// ServerInfo records information about an SMTP server.
type ServerInfo struct {
Name string // SMTP server name
TLS bool // using TLS, with valid certificate for Name
Auth []string // advertised authentication mechanisms
}

func isLocalhost(name string) bool {
return name == "localhost" || name == "127.0.0.1" || name == "::1"
}
50 changes: 50 additions & 0 deletions smtp/auth_cram_md5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: Copyright 2010 The Go Authors. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2022-2023 The go-mail Authors
//
// Original net/smtp code from the Go stdlib by the Go Authors.
// Use of this source code is governed by a BSD-style
// LICENSE file that can be found in this directory.
//
// go-mail specific modifications by the go-mail Authors.
// Licensed under the MIT License.
// See [PROJECT ROOT]/LICENSES directory for more information.
//
// SPDX-License-Identifier: BSD-3-Clause AND MIT

//go:build go1.19
// +build go1.19

package smtp

import (
"crypto/hmac"
"crypto/md5"
"fmt"
)

// cramMD5Auth is the type that satisfies the Auth interface for the "SMTP CRAM_MD5" auth
type cramMD5Auth struct {
username, secret string
}

// CRAMMD5Auth returns an Auth that implements the CRAM-MD5 authentication
// mechanism as defined in RFC 2195.
// The returned Auth uses the given username and secret to authenticate
// to the server using the challenge-response mechanism.
func CRAMMD5Auth(username, secret string) Auth {
return &cramMD5Auth{username, secret}
}

func (a *cramMD5Auth) Start(_ *ServerInfo) (string, []byte, error) {
return "CRAM-MD5", nil, nil
}

func (a *cramMD5Auth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
d := hmac.New(md5.New, []byte(a.secret))
d.Write(fromServer)
s := make([]byte, 0, d.Size())
return fmt.Appendf(nil, "%s %x", a.username, d.Sum(s)), nil
}
return nil, nil
}
52 changes: 52 additions & 0 deletions smtp/auth_cram_md5_118.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-FileCopyrightText: Copyright 2010 The Go Authors. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2022-2023 The go-mail Authors
//
// Original net/smtp code from the Go stdlib by the Go Authors.
// Use of this source code is governed by a BSD-style
// LICENSE file that can be found in this directory.
//
// go-mail specific modifications by the go-mail Authors.
// Licensed under the MIT License.
// See [PROJECT ROOT]/LICENSES directory for more information.
//
// SPDX-License-Identifier: BSD-3-Clause AND MIT

//go:build !go1.19
// +build !go1.19

package smtp

import (
"crypto/hmac"
"crypto/md5"
"fmt"
)

// cramMD5Auth is the type that satisfies the Auth interface for the "SMTP CRAM_MD5" auth
type cramMD5Auth struct {
username, secret string
}

// CRAMMD5Auth returns an Auth that implements the CRAM-MD5 authentication
// mechanism as defined in RFC 2195.
// The returned Auth uses the given username and secret to authenticate
// to the server using the challenge-response mechanism.
func CRAMMD5Auth(username, secret string) Auth {
return &cramMD5Auth{username, secret}
}

func (a *cramMD5Auth) Start(_ *ServerInfo) (string, []byte, error) {
return "CRAM-MD5", nil, nil
}

// Backport of: https://github.com/golang/go/commit/58158e990f272774e615c9abd8662bf0198c29aa#diff-772fc9f5d0c86f26e35158fb3e7a71a4967d18b4ec23a5dbb60781ab0babf426
// to guarantee backwards compatiblity with Go 1.16-1.18
func (a *cramMD5Auth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
d := hmac.New(md5.New, []byte(a.secret))
d.Write(fromServer)
s := make([]byte, 0, d.Size())
return []byte(fmt.Sprintf("%s %x", a.username, d.Sum(s))), nil
}
return nil, nil
}
Loading

0 comments on commit 813020f

Please sign in to comment.