Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The outcome of the authentication process at both server and client sides is indicated by a transport event. In the case of authentication failure it will be a PN_TRANSPORT_ERROR event, and the case of success it will a PN_TRANSPORT_AUTHENTICATED event. Once the authentication event has been received the server can discover who it is talking to by using the pn_transport_get_user() API. If required the mechanism used can be recovered using pn_sasl_get_mech().

Note that on the server you can also use the PN_CONNECTION_REMOTE_OPEN event to signal that authentication has succeeded if you don't need to deal with authentication by itself.

SASL

The biggest functional changes happen in the SASL layer code where the API has largely changed, very little backwards compatibility has been kept, because it is fairly clear that very few (if any) people have been using the current API to implement their own SASL mechanisms.

If this turns out to be untrue, then we could add some further measure of backwards compatibility as required.

Functions Removed

  • void

    pn_sasl_client(pn_sasl_t

    *sasl)

  • void

    pn_sasl_server(pn_sasl_t

    *sasl)

These functions were used to specify the SASL layer as either a client or server, they have been deprecated since functionality went into the transport code to specify whether it is an authentication client or server. Currently, on creation,  the SASL layer will determine from the transport whether it should be a server or a client. As there is a good deal of SASL churn in these current changes this is a good opportunity to remove these deprecated APIs.

  • pn_sasl_state_t

    pn_sasl_state(pn_sasl_t

    *sasl)

  • size_t

    pn_sasl_pending(pn_sasl_t

    *sasl)

  • ssize_t

    pn_sasl_recv(pn_sasl_t

    *sasl,

    char

    *bytes,

    size_t

    size)

  • ssize_t

    pn_sasl_send(pn_sasl_t

    *sasl,

    const

    char

    *bytes,

    size_t

    size)

These functions are the ones which support the client directly reading and writing the SASL protocol frames. They are not needed as this functionality has been removed and superseded by internal functionality.

  • void

    pn_sasl_mechanisms(pn_sasl_t

    *sasl,

    const

    char

    *mechanisms)

  • const

    char

    *pn_sasl_remote_mechanisms(pn_sasl_t

    *sasl)

These functions

...

functionality here has been replaced by pn_sasl_exclude_

...

mechs() and pn_sasl_get_mech().

  • void pn_sasl_plain(pn_sasl_t *sasl, const char

    _t *sasl, const char

    *username,

    const

    char

    *password)

This

Functions Added

/** Retrieve the authenticated user
 *
 * This is usually used at the the server end to find the name of the authenticated user.
 * On the client it will merely return whatever user was passed in to the

...

function is a helper function that constructs and sends a SASL PLAIN mechanism frame. As directly sending the frames is no longer the responsibility of the application it is not needed, however it is broadly replaced with pn_transport_set_user_password()

...

 *

which allows the client to set the authentication username and password.

Functions Added

  • const char *

...

  • pn_sasl_get_

...

  • user(pn_sasl_t *sasl)

    This is usually used at the the server end to find the name of the authenticated user. On the client it will merely return whatever user was passed in to pn_transport_set_user_password(). The returned value is only reliable after the

  • PN_TRANSPORT_AUTHENTICATED

...

  • event

...

  • has

...

  • been

...

 *
 * @param[in] sasl the sasl layer
 *
 * @return
 * If the SASL layer was not negotiated then 0 is returned
 * If the ANONYMOUS mechanism is used then the user will be "anonymous"
 * Otherwise a string containing the user is returned.
 */

...

  • received. If the SASL layer was not negotiated then 0 is returned If the ANONYMOUS mechanism is used then the user will be "anonymous" Otherwise a string containing the authenticated user is returned.

  • const char *pn_sasl_get_

...

  • mech(pn_sasl_t

...

  • *sasl)

...

 

...

  • Return

...

  • the

...

  • selected

...

  • SASL

...

 *

...

  • mechanism: The returned value is only reliable after the PN_TRANSPORT_AUTHENTICATED

...

  • event

...

  • has

...

  • been

...

  • received.

 *
 * @param[in] sasl the SASL layer
 *
 * @return The authentication mechanism selected by the SASL layer
 */

...

  • void pn_sasl_exclude_mechs(pn_sasl_t *sasl, const char *mechs)

    Specify SASL mechanisms that are not to be considered for authentication. This can be used on either the client or the server to restrict the SASL mechanisms that may be used. Multiple  mechanisms to exclude are space separated in the string that is passed into this function.

  • void pn_sasl_force_anonymous(pn_sasl_t

...

  • *sasl)

...


 
/** SASL mechanism that are not to be considered for authentication
 *
 * This can be used on either the client or the server to restrict the SASL mechanisms that may be used.
 *
 * @param[in] sasl the SASL layer
 * @param[in] mechs space separated list of mechanisms that are not to be allowed for authentication
 */

...

  • This is used on either server or client to setup the SASL layer so that it will pre-emptively

  • void pn_sasl_config_name(pn_sasl_t *sasl, const char *name)

  • void pn_sasl_config_path(pn_sasl_t

...

  • *sasl,

...

  • const

...

  • char

...

  • *

...

  • path)

...



/**

 *

Set

the

sasl

configuration

name

 *

 *

This

is

used

to

construct

the

SASL

configuration

filename.

In

the

current

implementation

 *

it

".conf"

is

added

to

the

name

and

the

file

is

looked

for

in

the

configuration

directory.

 *

 *

If

not

set

it

will

default

to

"proton-server"

for

a

sasl

server

and

"proton-client"

 *

for

a

client.

 *

 *

@param[in]

sasl

the

SASL

layer

 *

@param[in]

name

the

configuration

name

 */

PN_EXTERN

void

pn_sasl_config_name(pn_sasl_t

*sasl,

const

char

*name);

 

/**

 *

Set

the

sasl

configuration

path

 *

 *

This

is

used

to

tell

SASL

where

to

look

for

the

configuration

file.

 *

In

the

current

implementation

it

can

be

a

colon

separated

list

of

directories.

 *

 *

The

environment

variable

PN_SASL_CONFIG_PATH

can

also

be

used

to

set

this

path,

 *

but

if

both

methods

are

used

then

this

pn_sasl_config_path()

will

take

precedence.

 *

 *

If

not

set

the

underlying

implementation

default

will

be

used.

 *

for

a

client.

 *

 *

@param[in]

sasl

the

SASL

layer

 *

@param[in]

path

the

configuration

path

 */

PN_EXTERN

void

pn_sasl_config_path(pn_sasl_t

*sasl,

const

char

*path);

Transport

Functions Added

/**

 * Set the authentication username and password for a client transport

 *

 * If not set then no authentication will be negotiated unless the client

 * sasl layer is explicitly created (this would be for sometting like Kerberos

 * where the credentials are implicit in the environment, or to explicitly use

 * the ANONYMOUS SASL mechanism)

 *

 * @param[in] transport the transport

 * @param[in] user the username

 * @param[in] password the password corresponding to the username - this will be copied and zeroed out after use

 */

PN_EXTERN void pn_transport_set_user_password(pn_transport_t *transport, const char *user, const char* password);

/** Retrieve the authenticated user

 *

 * This is usually used at the the server end to find the name of the authenticated user.

 * On the client it will merely return whatever user was passed in to the

 * pn_transport_set_user_password() API.

 *

 * The returned value is only reliable after the PN_TRANSPORT_AUTHENTICATED event has been received.

 *

 * @param[in] transport the transport

 *

 * @return

 * If a the user is anonymous (either no SASL layer is negotiated or the SASL ANONYMOUS mechanism is used)

 * then the user will be "anonymous"

 * Otherwise a string containing the user is returned.

 */

PN_EXTERN const char *pn_transport_get_user(pn_transport_t *transport);

/**

 * Set the remote FQDN

 *

 * @param[in] transport the transport

 * @param[in] fqdn the remotes Fully qualified domain name

 */

PN_EXTERN void pn_transport_set_remote_hostname(pn_transport_t *transport, const char* fqdn);

/**

 * Set whether a non authenticated transport connection is allowed

 *

 * There are several ways within the AMQP protocol suite to get unauthenticated connections:

 * - Use no SASL layer (with either no TLS or TLS without client certificates)

 * - Use an SASL layer but the ANONYMOUS mechanism

 *

 * The default if this option is not set is to allow unauthenticated connections.

 *

 * @param[in] transport the transport

 * @param[in] required boolean is true when authenticated connections are required

 */

PN_EXTERN void pn_transport_require_auth(pn_transport_t *transport, bool required);

/**

 * Set whether a non encrypted transport connection is allowed

 *

 * There are several ways within the AMQP protocol suite to get encrypted connections:

 * - Use TLS/SSL

 * - Use an SASL with a mechanism that supports saecurity layers

 *

 * The default if this option is not set is to allow unencrypted connections.

 *

 * @param[in] transport the transport

 * @param[in] required boolean is true when encrypted connections are required

 */

PN_EXTERN void pn_transport_require_encryption(pn_transport_t *transport, bool required);

...