From ae2365e14a63c040d65cec70d1202bd7507652f5 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Fri, 20 Sep 2024 18:29:58 +0600 Subject: [PATCH 1/5] Update go mod Signed-off-by: Muhammad Raisul Islam Evan --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 1bf1615a..14b40946 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/bradfitz/gomemcache +module github.com/evanraisul/evan-gomemcache -go 1.18 +go 1.22.1 From 7e4b290361448a6af55fb97c3f0639e2b7f3d9dd Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Fri, 4 Apr 2025 11:16:13 +0600 Subject: [PATCH 2/5] Add Memcached Authentication Support Signed-off-by: Muhammad Raisul Islam Evan --- .idea/workspace.xml | 56 +++++++++++++++++++++++++++++++++++++++ memcache/memcache.go | 63 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 .idea/workspace.xml diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..53ff1ec3 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + { + "associatedIndex": 6 +} + + + + { + "keyToString": { + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.go.formatter.settings.were.checked": "true", + "RunOnceActivity.go.migrated.go.modules.settings": "true", + "RunOnceActivity.go.modules.automatic.dependencies.download": "true", + "RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true", + "git-widget-placeholder": "auth", + "go.import.settings.migrated": "true", + "go.sdk.automatically.set": "true", + "last_opened_file_path": "/home/evan/go/src/evanraisul/evan-gomemcache", + "node.js.detected.package.eslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "nodejs_package_manager_path": "npm" + } +} + + + + + + + + + + + true + + \ No newline at end of file diff --git a/memcache/memcache.go b/memcache/memcache.go index 6f48caac..def54d5f 100644 --- a/memcache/memcache.go +++ b/memcache/memcache.go @@ -62,6 +62,9 @@ var ( // ErrNoServers is returned when no servers are configured or available. ErrNoServers = errors.New("memcache: no servers configured or available") + + // ErrNotAuthenticated is returned when Client Authentication failed due to any reason. + ErrNotAuthenticated = errors.New("memcache: Client Authentication Failed") ) const ( @@ -114,6 +117,13 @@ var ( resultClientErrorPrefix = []byte("CLIENT_ERROR ") versionPrefix = []byte("VERSION") + + // Authentication Related Error + resultUnauthenticatedError = []byte("CLIENT_ERROR unauthenticated\r\n") + resultAuthenticationFailure = []byte("CLIENT_ERROR authentication failure\r\n") + resultBadCommandFormat = []byte("CLIENT_ERROR bad command line format\r\n") + resultBadCommandFormatTermination = []byte("CLIENT_ERROR bad command line format termination\r\n") + resultBadAuthenticationTokenFormat = []byte("CLIENT_ERROR bad authentication token format\r\n") ) // New returns a memcache client using the provided server(s) @@ -181,6 +191,12 @@ type Item struct { // It's populated by get requests and then the same value is // required for a CompareAndSwap request to succeed. CasID uint64 + + // Username for Authentication + User string + + // Password for Authentication + Pass string } // conn is a connection to a server. @@ -320,7 +336,7 @@ func (c *Client) onItem(item *Item, fn func(*Client, *bufio.ReadWriter, *Item) e return err } defer cn.condRelease(&err) - if err = fn(c, cn.rw, item); err != nil { + if err := fn(c, cn.rw, item); err != nil { return err } return nil @@ -847,3 +863,48 @@ func (c *Client) Close() error { c.freeconn = nil return ret } + +// Memcached Authentication Support + +func (c *Client) SetAuth(item *Item) error { + return c.onItem(item, (*Client).setAuth) +} + +func (c *Client) setAuth(rw *bufio.ReadWriter, item *Item) error { + return c.authFunc(rw, "set", item) +} + +func (c *Client) authFunc(rw *bufio.ReadWriter, verb string, item *Item) error { + if !legalKey(item.Key) { + return ErrMalformedKey + } + var err error + _, err = fmt.Fprintf(rw, "%s %s %d %d %d\r\n%s %s\r\n", + verb, item.Key, item.Flags, item.Expiration, len(item.User)+len(item.Pass)+1, item.User, item.Pass) + if err != nil { + return err + } + if err := rw.Flush(); err != nil { + return err + } + line, err := rw.ReadSlice('\n') + + if err != nil { + return err + } + switch { + case bytes.Equal(line, resultStored): + return nil + case bytes.Equal(line, resultUnauthenticatedError): + return ErrNotAuthenticated + case bytes.Equal(line, resultAuthenticationFailure): + return ErrNotAuthenticated + case bytes.Equal(line, resultBadCommandFormat): + return ErrNotAuthenticated + case bytes.Equal(line, resultBadCommandFormatTermination): + return ErrNotAuthenticated + case bytes.Equal(line, resultBadAuthenticationTokenFormat): + return ErrNotAuthenticated + } + return fmt.Errorf("memcache: unexpected response line from %q: %q", verb, string(line)) +} From 1443d709a89eeb0fa8d05a98e5c37124c4a26299 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Fri, 4 Apr 2025 13:01:44 +0600 Subject: [PATCH 3/5] Fix auth stuffs Signed-off-by: Muhammad Raisul Islam Evan --- memcache/memcache.go | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/memcache/memcache.go b/memcache/memcache.go index def54d5f..b6d3a31f 100644 --- a/memcache/memcache.go +++ b/memcache/memcache.go @@ -124,6 +124,13 @@ var ( resultBadCommandFormat = []byte("CLIENT_ERROR bad command line format\r\n") resultBadCommandFormatTermination = []byte("CLIENT_ERROR bad command line format termination\r\n") resultBadAuthenticationTokenFormat = []byte("CLIENT_ERROR bad authentication token format\r\n") + + // Authentication Error Stuffs + resultUnauthenticatedError = []byte("CLIENT_ERROR unauthenticated\r\n") + resultAuthenticationFailure = []byte("CLIENT_ERROR authentication failure\r\n") + resultBadCommandFormat = []byte("CLIENT_ERROR bad command line format\r\n") + resultBadCommandFormatTermination = []byte("CLIENT_ERROR bad command line format termination\r\n") + resultBadAuthenticationTokenFormat = []byte("CLIENT_ERROR bad authentication token format\r\n") ) // New returns a memcache client using the provided server(s) @@ -908,3 +915,47 @@ func (c *Client) authFunc(rw *bufio.ReadWriter, verb string, item *Item) error { } return fmt.Errorf("memcache: unexpected response line from %q: %q", verb, string(line)) } + +// Memcached Authentication Support +func (c *Client) SetAuth(item *Item) error { + return c.onItem(item, (*Client).setAuth) +} + +func (c *Client) setAuth(rw *bufio.ReadWriter, item *Item) error { + return c.authFunc(rw, "set", item) +} + +func (c *Client) authFunc(rw *bufio.ReadWriter, verb string, item *Item) error { + if !legalKey(item.Key) { + return ErrMalformedKey + } + var err error + _, err = fmt.Fprintf(rw, "%s %s %d %d %d\r\n%s %s\r\n", + verb, item.Key, item.Flags, item.Expiration, len(item.User)+len(item.Pass)+1, item.User, item.Pass) + if err != nil { + return err + } + if err := rw.Flush(); err != nil { + return err + } + line, err := rw.ReadSlice('\n') + + if err != nil { + return err + } + switch { + case bytes.Equal(line, resultStored): + return nil + case bytes.Equal(line, resultUnauthenticatedError): + return ErrNotAuthenticated + case bytes.Equal(line, resultAuthenticationFailure): + return ErrNotAuthenticated + case bytes.Equal(line, resultBadCommandFormat): + return ErrNotAuthenticated + case bytes.Equal(line, resultBadCommandFormatTermination): + return ErrNotAuthenticated + case bytes.Equal(line, resultBadAuthenticationTokenFormat): + return ErrNotAuthenticated + } + return fmt.Errorf("memcache: unexpected response line from %q: %q", verb, string(line)) +} \ No newline at end of file From 66cc7a66bfc7952d5b74a2963e6c2b0fd716fbec Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Sat, 5 Apr 2025 00:45:43 +0600 Subject: [PATCH 4/5] Update go mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 14b40946..8ee417c9 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/evanraisul/evan-gomemcache +module github.com/bradfitz/gomemcache go 1.22.1 From 119788e9ba59cb73ac731c4585ed929c31b2a642 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Sat, 5 Apr 2025 00:47:30 +0600 Subject: [PATCH 5/5] Remove .idea file --- .idea/workspace.xml | 56 --------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 .idea/workspace.xml diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 53ff1ec3..00000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - { - "associatedIndex": 6 -} - - - - { - "keyToString": { - "RunOnceActivity.ShowReadmeOnStart": "true", - "RunOnceActivity.go.formatter.settings.were.checked": "true", - "RunOnceActivity.go.migrated.go.modules.settings": "true", - "RunOnceActivity.go.modules.automatic.dependencies.download": "true", - "RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true", - "git-widget-placeholder": "auth", - "go.import.settings.migrated": "true", - "go.sdk.automatically.set": "true", - "last_opened_file_path": "/home/evan/go/src/evanraisul/evan-gomemcache", - "node.js.detected.package.eslint": "true", - "node.js.selected.package.eslint": "(autodetect)", - "nodejs_package_manager_path": "npm" - } -} - - - - - - - - - - - true - - \ No newline at end of file