Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read access tokens from the backend server #4

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

moriyoshi
Copy link
Owner

@moriyoshi moriyoshi commented Apr 27, 2020

Heads up: this is an experimental feature and may still contain serious vulnerability, and the specification is also subject to change.

Summary

  • This patch implements a token conversation feature, which allows one to feed fresh access tokens for use in client authentication sessions provided by a background server process through a Unix domain or TCP socket.
  • The feature is turned on if those conditions are met:
    • SASL_XOAUTH2_CLIENT_TOKEN_CONV environment variable is set to the endpoint of the backend server.
    • Either the callback for SASL_CB_PASS or the interaction for SASL_CB_PASS yields an empty string or a single hyphen -.
  • The communication scheme between the client and server is detailed below:

SASL_XOAUTH2_CLIENT_TOKEN_CONV environment variable

It can take a string of the following form:

PROTOCOL:HOST
PROTOCOL:PATH
PROTOCOL:HOST:PORT

ex.
tcp:localhost
tcp:localhost:65321
tcp:[::1]
tcp:[::1]:65321
unix:/tmp/server.sock

Communication Protocol

The communication is done in the following phases:

  • Handshake phase. Client and Server send Signatures and their protocol versions each other.
  • Query phase. Client sends an authentication identifier (a.k.a. account name) to Server and Server responds to it with an access token.

Handshake Phase

  1. Client sends a Signature and its highest available protocol version, which are concatenated, to Server.

    The Signature is a 4 octet string, %x81 %x9d %x74 %x13. The version is a 32-bit big-endian unsigned integer.

    client_hello   = signature client_version
    signature      =  %x81 %x9d %x74 %x13
    client_version = <big-endian 32-bit unsigned integer>
    
    +----+----+----+----+----+----+----+----+
    |   0|   1|   2|   3|   4|   5|   6|   7|
    +----+----+----+----+----+----+----+----+
    |0x81|0x9d|0x74|0x13| CV3| CV2| CV1| CV0|
    +----+----+----+----+----+----+----+----+
    
  2. Server verifies the Signature and must terminate the session if it doesn't correspond to the string. Otherwise, it responds to Client with a Signature and the protocol version which will be used in further communication.

    The Signature is a 4 octet string, %x81 %x9d %x74 %x13 (same as the above). The version is a 32-bit big-endian unsigned integer. If Server has backward compatibility with Client's protocol, it is advised that it return the same protocol version as Client.

    server_hello   = signature server_version
    server_version = <32-bit big-endian unsigned integer>
    
  3. Upon reception of the response from Server, Client must terminate the session if the signature doesn't match, and may do so if the Server's protocol version doesn't meet its version.

  4. Client and Server step to Query Phase.

Query Phase

  1. Client sends a Packet with the following content:

    packet               = packet_length packet_content
    packet_length        = <32-bit big-endian unsigned integer>
    
    query_packet         = query_packet_length query_packet_content 
    query_packet_content = "authid" %x00 authid
    authid               = *%x00-ff
    

    A Packet starts with a 32-bit big-endian unsigned integer that stores the length of the packet content (length octets excluded) and is immediately followed by the packet content.

  2. Server receives the query Packet and responds with the access token that corresponds to the authentication ID contained in the query.

    resp_packet          = resp_packet_length resp_packet_content 
    resp_packet_content  = access_token
    
  3. Client may repeat queries.

@moriyoshi moriyoshi changed the title Read access token from uds Read access tokens from the backend server Apr 27, 2020
@moriyoshi moriyoshi marked this pull request as ready for review April 27, 2020 15:26
n -= iv->iov_len;
++iv;
}
*((unsigned char **)&iv->iov_base) += n;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong...

n -= iv->iov_len;
++iv;
}
*((unsigned char **)&iv->iov_base) += n;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong...

n -= p_wsiv->len;
++p_wsiv;
}
*((unsigned char **)&p_wsiv->buf) += n;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong...

++p_wsiv;
--nivs;
}
*((unsigned char **)&p_wsiv->buf) += n;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong...

if (AF_UNIX == info.af) {
#ifdef WIN32_UDS
tmp.ai_family = info.af;
tmp.ai_protocol = AF_INET;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct?

err = SASL_FAIL;
goto out;
}
/*{
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check out the reason for commenting this out.

{
const xoauth2_plugin_socket_iovec_t *p, *e = ivs + nivs;
for (p = ivs; p < e; p++) {
size_t new_total_len = total_len + p->iov_len;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant