aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/emersion/go-sasl/plain.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/emersion/go-sasl/plain.go')
-rw-r--r--vendor/github.com/emersion/go-sasl/plain.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/vendor/github.com/emersion/go-sasl/plain.go b/vendor/github.com/emersion/go-sasl/plain.go
new file mode 100644
index 0000000..344ed17
--- /dev/null
+++ b/vendor/github.com/emersion/go-sasl/plain.go
@@ -0,0 +1,77 @@
+package sasl
+
+import (
+ "bytes"
+ "errors"
+)
+
+// The PLAIN mechanism name.
+const Plain = "PLAIN"
+
+type plainClient struct {
+ Identity string
+ Username string
+ Password string
+}
+
+func (a *plainClient) Start() (mech string, ir []byte, err error) {
+ mech = "PLAIN"
+ ir = []byte(a.Identity + "\x00" + a.Username + "\x00" + a.Password)
+ return
+}
+
+func (a *plainClient) Next(challenge []byte) (response []byte, err error) {
+ return nil, ErrUnexpectedServerChallenge
+}
+
+// A client implementation of the PLAIN authentication mechanism, as described
+// in RFC 4616. Authorization identity may be left blank to indicate that it is
+// the same as the username.
+func NewPlainClient(identity, username, password string) Client {
+ return &plainClient{identity, username, password}
+}
+
+// Authenticates users with an identity, a username and a password. If the
+// identity is left blank, it indicates that it is the same as the username.
+// If identity is not empty and the server doesn't support it, an error must be
+// returned.
+type PlainAuthenticator func(identity, username, password string) error
+
+type plainServer struct {
+ done bool
+ authenticate PlainAuthenticator
+}
+
+func (a *plainServer) Next(response []byte) (challenge []byte, done bool, err error) {
+ if a.done {
+ err = ErrUnexpectedClientResponse
+ return
+ }
+
+ // No initial response, send an empty challenge
+ if response == nil {
+ return []byte{}, false, nil
+ }
+
+ a.done = true
+
+ parts := bytes.Split(response, []byte("\x00"))
+ if len(parts) != 3 {
+ err = errors.New("Invalid response")
+ return
+ }
+
+ identity := string(parts[0])
+ username := string(parts[1])
+ password := string(parts[2])
+
+ err = a.authenticate(identity, username, password)
+ done = true
+ return
+}
+
+// A server implementation of the PLAIN authentication mechanism, as described
+// in RFC 4616.
+func NewPlainServer(authenticator PlainAuthenticator) Server {
+ return &plainServer{authenticate: authenticator}
+}