memcached + SASL: Password verification failed

386 views
Skip to first unread message

Jiuming Shao

unread,
Mar 18, 2019, 7:06:53 PM3/18/19
to memcached
Hey all,

I am writing my own implementation of a memcachedClient within which I want to add authentication. I just started with PLAIN auth but failed.

My guess is that the binary message I am sending through the wire was wrong, thus it could never match with the secret I store in the db file.
After searching around, I found out the SASL_AUTH(0X21) is also a key-value like operation, where the key is the auth mechanism, and the value being auth data. The tricky part is how I put them in the outgoing request.

Please correct me if i am wrong, below is an example of PLAIN auth request
  1. The auth mechanism comes right after the header. in this case 'PLAIN'
  2. A NULL byte comes after the "key" -> "PLAIN". In this case byte # 29.
  3. Then comes the user@hostName
  4. A NULL bytes comes after user@hostname. In this case byte # 34
  5. The last part is the password
Byte/     0       |       1       |       2       |       3       |
     /              |               |               |               |
    |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
    +---------------+---------------+---------------+---------------+
   0| 0x80          | 0x21          | 0x00          | 0x05          |
    +---------------+---------------+---------------+---------------+
   4| 0x00          | 0x00          | 0x00          | 0x00          |
    +---------------+---------------+---------------+---------------+
   8| 0x00          | 0x00          | 0x00          | 0x11          |
    +---------------+---------------+---------------+---------------+
  12| 0x00          | 0x00          | 0x00          | 0x00          |
    +---------------+---------------+---------------+---------------+
  16| 0x00          | 0x00          | 0x00          | 0x00          |
    +---------------+---------------+---------------+---------------+
  20| 0x00          | 0x00          | 0x00          | 0x00          |
    +---------------+---------------+---------------+---------------+
  24| 0x50 ('P')    | 0x4c ('L')    | 0x41 ('A')    | 0x49 ('I')    |
    +---------------+---------------+---------------+---------------+
  28| 0x4e ('N')    | 0x00          | 0x75 ('u')    | 0x73 ('s')    |
    +---------------+---------------+---------------+---------------+
  32| 0x65 ('e')    | 0x72 ('r')    | 0x00          | 0x70 ('p')    |
    +---------------+---------------+---------------+---------------+
  36| 0x65 ('e')    | 0x6e ('n')    | 0x63 ('c')    | 0x69 ('i')    |
    +---------------+---------------+---------------+---------------+
  40| 0x6c ('l')    |
    +---------------+
    Total 41 bytes (24 bytes header, 5 bytes key and 12 value)
Field        (offset) (value)
Magic        (0)    : 0x80
Opcode       (1)    : 0x21
Key length   (2,3)  : 0x0005
Extra length (4)    : 0x00
Data type    (5)    : 0x00
Vbucket      (6,7)  : 0x0000
Total body   (8-11) : 0x00000011
Opaque       (12-15): 0x00000000
CAS          (16-23): 0x00000000

What could be wrong?
  • In my memcached-sasl-db, should I store userName:password or username@hostName:password?
  • Does the TotalLength of the message include the NULL bytes being added between authKey/authData and username/password?
  • In my authData should I use \0x00userName\0x00password or \0x00userName@hostNname\0x00password?
  • Any other suggestions?

Best regards,
Jiuming

Below are Logs and configurations for your references

memcached logs: Below you will find that I did a LIST_MECH(0x20) and then did a SASL_AUTH(0X21)
LRU crawler thread sleeping
<28 new binary client connection.
28: going from conn_new_cmd to conn_waiting
28: going from conn_waiting to conn_read
28: going from conn_read to conn_closing
<28 connection closed.
28: going from conn_closing to conn_closed
<28 new binary client connection.
28: going from conn_new_cmd to conn_waiting
28: going from conn_waiting to conn_read
28: going from conn_read to conn_parse_cmd
<28 Read binary protocol data:
<28    0x80 0x20 0x00 0x00
<28    0x00 0x00 0x00 0x00
<28    0x00 0x00 0x00 0x00
<28    0x00 0x00 0x00 0x01
<28    0x00 0x00 0x00 0x00
<28    0x00 0x00 0x00 0x00
authenticated() in cmd 0x20 is true
>28 Writing bin response:
>28   0x81 0x20 0x00 0x00
>28   0x00 0x00 0x00 0x00
>28   0x00 0x00 0x00 0x15
>28   0x00 0x00 0x00 0x01
>28   0x00 0x00 0x00 0x00
>28   0x00 0x00 0x00 0x00
28: going from conn_parse_cmd to conn_mwrite
28: going from conn_mwrite to conn_new_cmd
28: going from conn_new_cmd to conn_waiting
28: going from conn_waiting to conn_read
28: going from conn_read to conn_parse_cmd
<28 Read binary protocol data:
<28    0x80 0x21 0x00 0x05
<28    0x00 0x00 0x00 0x00
<28    0x00 0x00 0x00 0x14
<28    0x00 0x00 0x00 0x02
<28    0x00 0x00 0x00 0x00
<28    0x00 0x00 0x00 0x00
authenticated() in cmd 0x21 is true
28: going from conn_parse_cmd to conn_nread
mech:  ``PLAIN'' with 15 bytes of data
SASL (severity 2): Password verification failed
sasl result code:  -20
Unknown sasl response:  -20
>28 Writing an error: Auth failure.
>28 Writing bin response:
>28   0x81 0x21 0x00 0x00
>28   0x00 0x00 0x00 0x20
>28   0x00 0x00 0x00 0x0d
>28   0x00 0x00 0x00 0x02
>28   0x00 0x00 0x00 0x00
>28   0x00 0x00 0x00 0x00


My memcached.conf 
% cat memcached.conf
mech_list: plain
log_level: 5
sasldb_path: /tmp/memcached-sasl-db

My /tmp/memcached-sasl-db
% cat memcached-sasl-db
myname@myHostName:mypass

My exports:
export MEMCACHED_SASL_PWDB=/tmp/memcached-sasl-db
export SASL_CONF_PATH=`pwd`/memcached.conf

dormando

unread,
Mar 18, 2019, 7:10:23 PM3/18/19
to memcached
Hey,

Can look more closely later, but a few quick things that might help:

1) stick to memcached/memcached on github - that's an old couchbase fork
you linked to. If you're using couchbase you need to talk to them instead.

2) in the t/ dir there're some unit tests for SASL which might help you
understand the workflow better.

On Mon, 18 Mar 2019, Jiuming Shao wrote:

> Hey all,
> I am writing my own implementation of a memcachedClient within which I want to add authentication. I just started with PLAIN auth but
> failed.
>
> My main reference is this one https://github.com/couchbase/memcached/blob/master/docs/sasl.md 
> My guess is that the binary message I am sending through the wire was wrong, thus it could never match with the secret I store in the db
> file.
> After searching around, I found out the SASL_AUTH(0X21) is also a key-value like operation, where the key is the auth mechanism, and the
> value being auth data. The tricky part is how I put them in the outgoing request.
>
> Please correct me if i am wrong, below is an example of PLAIN auth request
> 1. The auth mechanism comes right after the header. in this case 'PLAIN'
> 2. A NULL byte comes after the "key" -> "PLAIN". In this case byte # 29.
> 3. Then comes the user@hostName
> 4. A NULL bytes comes after user@hostname. In this case byte # 34
> 5. The last part is the password
> * In my memcached-sasl-db, should I store userName:password or username@hostName:password?
> * Does the TotalLength of the message include the NULL bytes being added between authKey/authData and username/password?
> * In my authData should I use \0x00userName\0x00password or \0x00userName@hostNname\0x00password?
> * Any other suggestions?
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "memcached" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to memcached+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>

Jiuming Shao

unread,
Mar 19, 2019, 1:15:19 PM3/19/19
to memc...@googlegroups.com
Thanks for getting back to me! I referred to that because memcached/memcached does not tell me how the binary protocol packets for SASL AUTH looks like. For all the server configuration and db setup, I followed https://github.com/memcached/memcached/wiki/SASLHowto and https://github.com/memcached/memcached/wiki/SASLAuthProtocol 
Please let me know when you have time to take a closer look.

Cheers!
Jiuming

dormando <dorm...@rydia.net> 于2019年3月18日周一 下午4:10写道:

dormando

unread,
Mar 19, 2019, 1:49:38 PM3/19/19
to memc...@googlegroups.com
t/binary-sasl.t under memcached/memcached should show you examples of how
to authenticate. You should be able to just hack up the test to get more
information about what the password files look like/etc. it writes it out
to tmp.

seems some systems require the @hostname and some don't (mine doesn't, I
haven't looked into why)

Jiuming Shao

unread,
Mar 22, 2019, 5:40:39 PM3/22/19
to memc...@googlegroups.com
Thanks! I figured it out by postfixing `@memcached.realm` after my key. 

dormando <dorm...@rydia.net> 于2019年3月19日周二 上午10:49写道:

Om Kale

unread,
Mar 22, 2019, 6:17:06 PM3/22/19
to memc...@googlegroups.com
Hi Jiuming,
Were you able to make it work with DIGEST-MD5 instead of just PLAIN auth?

Regards,
Om Kale
Master of Science in Electrical and Computer Engineering
Georgia Institute of Technology

Jiuming Shao

unread,
Mar 22, 2019, 6:23:45 PM3/22/19
to memc...@googlegroups.com
Hi Om, 

No. I just started with PLAIN as a PoC.

Cheers!

Om Kale <omka...@gmail.com> 于2019年3月22日周五 下午3:17写道:

Om Kale

unread,
Mar 22, 2019, 6:31:29 PM3/22/19
to memc...@googlegroups.com
Alright...cool.
Let me know if you ever successfully get DIGEST-MD5 working.
Have a great weekend!

Thanks and Regards,
Om Kale
Master of Science in Electrical and Computer Engineering
Georgia Institute of Technology
Reply all
Reply to author
Forward
0 new messages