[rabbitmq-discuss] Creating an auth plugin (Kerberos)
Simon Lundström
simlu at su.se
Tue Dec 11 19:38:03 GMT 2012
On Tue, 2012-12-11 at 17:07:02 +0000, Tim Watson wrote:
> That's not saying check_user_login is undefined. In fact, check_user_login is not even part of the NIF infrastructure. It looks like it's saying 'connection.start_ok' is undefined. Hmn - doesn't make much sense to me I'm afraid. What happens if you move the NIF part out into another module, using the -on_load attribute there and then just call that utility module from your plugin?
>
> -module(kinit).
>
> -export([init/0, kinit/2]).
> -on_load(init/0).
>
> init() ->
> Kinit = code:priv_dir(?APPLICATION) ++ "/kinit.so",
> erlang:load_nif(Kinit, 0).
>
> kinit(User, Password) -> exit(nif_library_not_loaded).
I just did this <https://github.com/simmel/rabbitmq-auth-backend-kerberos/commit/e645d21439> (browse here <https://github.com/simmel/rabbitmq-auth-backend-kerberos/tree/e645d21439d1c7d13216a53766918d69c6e7c04a>) and now I get:
=INFO REPORT==== 11-Dec-2012::20:09:32 === Management agent started.
=ERROR REPORT==== 11-Dec-2012::20:09:32 ===
WAT: {error,upgrade,"Upgrade not supported by this NIF library."}
=ERROR REPORT==== 11-Dec-2012::20:09:32 ===
WAT: ok
=INFO REPORT==== 11-Dec-2012::20:09:32 ===
Management plugin started. Port: 443, path: /
=INFO REPORT==== 11-Dec-2012::20:09:32 ===
Statistics database started.
=INFO REPORT==== 11-Dec-2012::20:09:46 ===
accepting AMQP connection <0.287.0> (130.237.168.221:48918 -> 77.238.35.76:5671)
=ERROR REPORT==== 11-Dec-2012::20:09:46 ===
WAT: {error,upgrade,"Upgrade not supported by this NIF library."}
=ERROR REPORT==== 11-Dec-2012::20:09:49 ===
closing AMQP connection <0.287.0> (130.237.168.221:48918 -> 77.238.35.76:5671):
{channel0_error,starting,
{error,undef,'connection.start_ok',
[{kinit,kinit,[<<"simlu">>,<<"not_my_password">>]},
{rabbit_auth_backend_kerberos,check_user_login,2},
{rabbit_access_control,'-check_user_login/2-fun-0-',4},
{lists,foldl,3},
{rabbit_reader,auth_phase,2},
{rabbit_reader,handle_method0,3},
{rabbit_reader,handle_input,3},
{rabbit_reader,recvloop,2}]}}
when using AMQP login and this when I make an API call:
=CRASH REPORT==== 11-Dec-2012::20:10:27 === crasher:
initial call: mochiweb_acceptor:init/3
pid: <0.252.0>
registered_name: []
exception error: undefined function kinit:kinit/2
in function rabbit_auth_backend_kerberos:check_user_login/2
in call from rabbit_access_control:'-check_user_login/2-fun-0-'/4
in call from lists:foldl/3
in call from rabbit_mgmt_app:'-make_loop/0-fun-0-'/4
in call from mochiweb_http:headers/5
ancestors: [rabbit_mochiweb_web_mgmt,rabbit_mochiweb_sup,<0.131.0>]
messages: [] links: [<0.251.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 4181
stack_size: 24
reductions: 1488
neighbours:
How bad are those upgrade errors?
AFAIK, I could just add an empty function in kinit.c and use them as
load, reload, upgrade and unload when doing ERL_NIF_INIT since I don't
really need to keep any "state"(?).
> Anyway, if you put the NIF part into another module, you *should* be able to test it outside of rabbit my doing something like:
>
> $ erl -sname foo
> banner. .....
> % ok = application:start(rabbit_auth_backend_kerberos).
> ok
> % X = kinit:kinit("auser", "password").
> << a term >>
> % io:format("~p~n", [X]).
I couldn't get that to work = / I'm probably doing it wrong, but here's what I did:
kaka:~/scm/rabbitmq-public-umbrella/rabbitmq-auth-backend-kerberos$ LDFLAGS="-L/usr/heimdal/lib -undefined dynamic_lookup -dynamiclib" CFLAGS="-I/usr/heimdal/include -I/usr/local/Cellar/erlang/R15B02/lib/erlang/usr/include/" make dist
[elided] generate deps
[elided] fix test deps
sed -e 's|build/deps.mk|$(DEPS_FILE)|' build/deps.mk > build/deps.mk.tmp && mv build/deps.mk.tmp build/deps.mk
ERL_LIBS=./build/dep-apps erlc -Wall +debug_info -I ./include -pa ebin -o ebin src/kinit.erl
src/kinit.erl:14: Warning: variable 'Password' is unused
src/kinit.erl:14: Warning: variable 'User' is unused
escript ../generate_app src/rabbitmq_auth_backend_kerberos.app.src ebin/rabbitmq_auth_backend_kerberos.app ./src
sed -e 's|{vsn, *\"[^\"]*\"|{vsn,\"0.0.0\"|' <ebin/rabbitmq_auth_backend_kerberos.app >build/rabbitmq_auth_backend_kerberos.app.0.0.0
rm -rf build/app
mkdir -p ./build/app/rabbitmq_auth_backend_kerberos-0.0.0/ebin ./build/app/rabbitmq_auth_backend_kerberos-0.0.0/include
[elided] copy beams to ebin
cp -p ./build/rabbitmq_auth_backend_kerberos.app.0.0.0 ./build/app/rabbitmq_auth_backend_kerberos-0.0.0/ebin/rabbitmq_auth_backend_kerberos.app
mkdir -p ./build/app/rabbitmq_auth_backend_kerberos-0.0.0/priv
cp ./c_src/kinit.so ./build/app/rabbitmq_auth_backend_kerberos-0.0.0/priv
touch build/app/.done.0.0.0
rm -rf dist
mkdir -p dist
cd ./build/app/ && zip -q -r /Users/simlu/scm/rabbitmq-public-umbrella/rabbitmq-auth-backend-kerberos/dist/rabbitmq_auth_backend_kerberos-0.0.0.ez rabbitmq_auth_backend_kerberos-0.0.0
cp -r build/dep-ezs/amqp_client-0.0.0.ez build/dep-ezs/rabbit_common-0.0.0.ez ./dist
touch dist/.done.0.0.0
touch dist/.done
$ cd ebin
$ erl -sname `hostname -s`
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false] [dtrace]
Eshell V5.9.2 (abort with ^G)
(kaka at kaka)1> ok = application:start(rabbitmq_auth_backend_kerberos).
** exception error: no match of right hand side value {error,{not_started,inets}}
(kaka at kaka)2> kinit:kinit("auser", "password").
WAT: ok
true
This doesn't really test the whole thing since rabbitmq isn't really
involved or even loaded. Kind of feels like cheating = )
I have had this NIF-code to work outside of RabbitMQ, that's how I wrote
it originally.
(also, do get it working I changed the hardencoded path to match the
path on my Mac and I changed "rabbit_log:error" to "io:fwrite" since
RabbitMQ wasn't loaded correctly in my erl.
> Then if it *still* doesn't work when you're running it inside rabbit we might need to consider other things that could be going wrong (such as the NIF init magic).
I have no idea, but this seems more and more likely.
Thanks,
- Simon
More information about the rabbitmq-discuss
mailing list