module GS2:
Netmech_krb5_sasl.)
Create the final module like
module P = struct
let mechanism_name = "FOO"
let announce_channel_binding = false
let mechanism_oid = [| 1; ... |]
let mechanism_acceptable_oid_set = [ [| 1; ... |]; ... ]
...
end
module S = Netmech_gs2_sasl.GS2(P)(Netgss.System)
Remarks for clients:
The profile specifies how user name strings are mapped to GSSAPI
names. authz names are passed to the server as-is.
Remarks for servers:
The profile specifies how GSSAPI names are mapped to user name strings.
The lookup callback is then invoked with this user name, and the
unaltered authz name.
If lookup returns Some c for any c the user is accepted.
If it returns None the user is declined.
Parameters:
mutual is understood but ignored. Mutual authentication
is always requested from the GSSAPI mechanism.secure is understood but ignored
(GSSAPI is considered as secure method)The GSSAPI is stateful. Our SASL interface is stateless. We cannot hide the statefulness of the GSSAPI, and because of this old versions of sessions are invalidated. E.g. this does not work
let s1 = S.server_process_response s0 "some message"
let s2 = S.server_process_response s0 "another message"
and the second attempt to continue with the old session s0 will fail.
| Parameters: |
|
val mechanism_name : string
val client_first : [ `No | `Optional | `Required ]`Required: always`Optional: the client may choose to do so if the protocol
permits this`No: the server sends the first messageval server_sends_final_data : boolval supports_authz : boolval available : unit -> booltype credentials
val init_credentials : (string * string * (string * string) list) list ->
credentials(type,value,params). The mechanism may pick any element
of this list which are considered as equivalent.
Types are defined per mechanism. All mechanisms understand the "password" type, which is just the cleartext password, e.g.
[ "password", "ThE sEcReT", [] ]
Another common type is derived from the LDAP authPassword scheme (RFC 3112):
[ "authPassword-" ^ scheme, authValue, [ "info", authInfo ] ]
The "info" attribute is optional. For instance, if you want to provide MD5-hashed passwords:
[ "authPassword-MD5", hashed_password, [ "info", salt ] ]
Another common type is derived from the (older) LDAP userPassword scheme (RFC 2307):
[ "userPassword-" ^ scheme, value, [] ]
More information can be found here: Credentials for SASL
type server_session
val server_state : server_session ->
Netsys_sasl_types.server_state
val create_server_session : lookup:(string ->
string -> credentials option) ->
params:(string * string * bool) list ->
unit -> server_sessionlookup function is used to
get the credentials for a given user name and a given authorization
name (which is the empty string if not applicable). If the lookup
function returns None, the user can either not be found, or the
user does not have the privileges for the authorization name.
User name and authorization name are passed in UTF-8 encoding.
The parameters are given as list (name,value,critical).
Critical parameters must be interpreted by the mechanism, and
unknown critical parameters must be rejected by a Failure
exception. Non-critical parameters are ignored if they are unknown
to the mechanism.
val server_configure_channel_binding : server_session ->
(string * string) list -> server_session(type,data).val server_process_response : server_session ->
string -> server_session`Wait. As an exception,
however, this function may also be invoked with the initial client
response, even if the session state is `Emit, so far the mechanism
permits at least optionally that the client starts the protocol.val server_process_response_restart : server_session ->
string -> bool -> server_session * bool`Restart id after server_process_response, and in this case
the old session with id can be restarted. This function
should be called with the same message string as
server_process_repsonse was just called with.
If the bool arg is true, a stale response is created. This is a special restart which forces the client to run through the authentication process again, although everything else was successful. (If the protocol does not support the stale flag, it is silently ignored.)
Returns true if the restart is successful. If not, false is
returned. In this case, the server_session object can (and
should) still be used, but the caller must treat it as new
session. In particular, the session ID may change.
All in all, the idea of this function is best illustrated by this authentication snippet how to process responses (the session cache functions need to be written by the user of this module):
let update_cache() =
match server_session_id session with
| None -> ()
| Some id ->
replace_in_session_cache id (server_stash_session session) in
let rec check_state_after_response() =
match server_state session with
| `Restart id ->
let old_session_s, time = find_in_session_cache id in
let old_session = server_resume_session ~lookup old_session_s in
let set_stale = current_time - time > limit in
let session, cont =
server_process_response_restart session msg set_stale in
if not cont then
delete_in_session_cache id;
(* Now check server_state again, should be `Emit now *)
check_state_after_response()
| `Emit ->
let session, out_msg = server_emit_challenge session in
update_cache();
...
| ... ->
in
server_process_response session msg;
val server_emit_challenge : server_session ->
server_session * string`Emit.val server_stash_session : server_session -> stringval server_resume_session : lookup:(string ->
string -> credentials option) ->
string -> server_sessionlookup function.val server_session_id : server_session -> string optionval server_prop : server_session -> string -> stringval server_user_name : server_session -> stringNot_found)val server_authz_name : server_session -> stringNot_found)val server_channel_binding : server_session -> Netsys_sasl_types.cbval server_gssapi_props : server_session -> Netsys_gssapi.server_propstype client_session
val client_state : client_session ->
Netsys_sasl_types.client_state
val create_client_session : user:string ->
authz:string ->
creds:credentials ->
params:(string * string * bool) list ->
unit -> client_sessionuser and authorizes as
authz (empty string if not applicable). The credentials are
creds.
user and authz must be encoded in UTF-8.
The parameters are given as list (name,value,critical).
Critical parameters must be interpreted by the mechanism, and
unknown critical parameters must be rejected by a Failure
exception. Non-critical parameters are ignored if they are unknown
to the mechanism.
val client_configure_channel_binding : client_session ->
Netsys_sasl_types.cb -> client_sessionval client_restart : client_session ->
client_session`OK.val client_process_challenge : client_session ->
string -> client_session`Wait.
As an exception, this function can also be called for the initial
challenge from the server, even if the state is `Emit.val client_emit_response : client_session ->
client_session * string`Emit.val client_channel_binding : client_session -> Netsys_sasl_types.cbval client_user_name : client_session -> stringval client_authz_name : client_session -> stringval client_stash_session : client_session -> stringval client_resume_session : string -> client_sessionval client_session_id : client_session -> string optionval client_prop : client_session -> string -> stringval client_gssapi_props : client_session -> Netsys_gssapi.client_props