diff --git a/src/brod_gssapi.erl b/src/brod_gssapi.erl index a2e2112..5a9a17a 100644 --- a/src/brod_gssapi.erl +++ b/src/brod_gssapi.erl @@ -1,8 +1,4 @@ -%%%------------------------------------------------------------------- -%% @doc -%% SASL GSSAPI auth backend for brod -%% @end -%%%------------------------------------------------------------------- +%% @private -module(brod_gssapi). -export([auth/6, auth/7, new/7]). @@ -19,11 +15,14 @@ mechanism := binary(), sasl_context := binary(), sasl_conn := sasl_auth:state() | undefined, - handshake_vsn := non_neg_integer() + handshake_vsn := non_neg_integer() | undefined }. -export_type([state/0]). +-define(SASL_CONTEXT, <<"kafka">>). +-define(SASL_MECHANISM, <<"GSSAPI">>). + %% For backwards compat with version <= 0.2 -spec auth( Host :: string(), @@ -71,15 +70,11 @@ auth( dispatch(#{handshake_vsn := 1} = State) -> brod_gssapi_v1:auth(State); -dispatch(#{handshake_vsn := 0} = State) -> +dispatch(#{handshake_vsn := undefined} = State) -> brod_gssapi_v0:auth(State); dispatch(_State) -> {error, undefined_handshake_vsn}. -%% Backwards compat where handshake isn't given -%auth(Host, Sock, Mod, _ClientId, Timeout, _SaslOpts = {_Method = gssapi, Keytab, Principal}) -> -% - -spec new( Host :: string(), Sock :: gen_tcp:socket() | ssl:sslsocket(), @@ -97,10 +92,10 @@ new(Host, Sock, HandshakeVsn, Mod, ClientId, Timeout, {Method, KeyTab, Principal client_id => ClientId, timeout => Timeout, method => Method, - mechanism => <<"GSSAPI">>, + mechanism => ?SASL_MECHANISM, keytab => ensure_binary(KeyTab), principal => ensure_binary(Principal), - sasl_context => <<"kafka">>, + sasl_context => ?SASL_CONTEXT, handshake_vsn => HandshakeVsn, sasl_conn => undefined }. diff --git a/src/brod_gssapi_v0.erl b/src/brod_gssapi_v0.erl index cd97886..3bcac86 100644 --- a/src/brod_gssapi_v0.erl +++ b/src/brod_gssapi_v0.erl @@ -1,20 +1,10 @@ -%%%------------------------------------------------------------------- -%% @doc -%% SASL GSSAPI auth backend for brod -%% @end -%%%------------------------------------------------------------------- +%% @private -module(brod_gssapi_v0). -export([auth/6]). -define(HANDSHAKE_V0, 0). -%%%------------------------------------------------------------------- -%% @doc -%% Returns 'ok' if authentication successfully completed. See spec in behavior -%% @end -%%%------------------------------------------------------------------- - %% For backwards compat with version <= 0.2 -spec auth( Host :: string(), diff --git a/src/brod_gssapi_v1.erl b/src/brod_gssapi_v1.erl index 06effd9..b7ef5a9 100644 --- a/src/brod_gssapi_v1.erl +++ b/src/brod_gssapi_v1.erl @@ -1,14 +1,38 @@ -%%%------------------------------------------------------------------- -%% @doc -%% SASL GSSAPI auth backend for brod -%% @end -%%%------------------------------------------------------------------- +%% @private -module(brod_gssapi_v1). -export([auth/1, auth/6]). -define(HANDSHAKE_V1, 1). +%%% Flow +%%% ----------------------------------------------------------------- +%%% a) After initial series of sasl_auth calls, you get a kerberos token +%%% with a status if auth succeeded or failed or it should be continued. +%%% We got and Token (1 continue, 0 done, -1 Fail) +%%% +%%% b) On getting the token, we do handshake with Kafka using SaslHandshake +%%% call with GSSAPI mechanism. If Kafka supports GSSAPI mechanism, we +%%% are OK to move ahead + +%%% c) We send the token received in first step wrapped in Kafka Request using +%%% SaslAuthenticate, SaslAuthenticate returns a new token in its response, +%%% if successful. +%%% +%%% d) We then send this new Token to sasl_auth using method (sasl_client_step) +%%% to continue, this method returns {1 , []} i.e. continue with empty token +%%% e) We then send empty Token again to Kafka SaslAuthenticate wrapped in +%%% Kafka Request. We again get a Token in response, if successful. +%%% +%%% f) We then send this new Token to sasl_auth using method (sasl_client_step) +%%% to continue, this method returns {0 , Token} i.e. Successful Auth with a +%%% token. +%%% +%%% g) We sends this token to Kafka SaslAuthenticate wrapped in Kafka Request. +%%% Which if successful indicates a successful Handshake and authentication +%%% using Kerberos. +%%% ------------------------------------------------------------------- + %% For backwards compat with version <= 0.2 -spec auth( Host :: string(), @@ -28,6 +52,7 @@ auth( ) -> State = brod_gssapi:new(Host, Sock, Mod, ClientId, ?HANDSHAKE_V1, Timeout, Opts), auth(State). + %%%------------------------------------------------------------------- %% @doc %% Returns 'ok' if authentication successfully completed. See spec in behavior