Hey, I wanted to summarize the problem I have been having for the last few days from a [relatively] high-level perspective. Also, I thought I should share a conversation I had on IRC channel of cyrus.
Here is a current, and relatively high-level status of the problem I have been working on. There is this callback mechanism Cyrus SASL provides. Basically you can specify callback methods to initiate when SASL library needs to retrieve information from the application. If I do not set any callback methods, the sasl library of client and server initiates, the libraries accept each other as new connections(not after a negotiation but after each application providing manually typed info on the other party) and client receives a list of mechanisms from server it can choose from. Then, however the sasl library on client's side fails to start the authentication negotiation procedure with ANONYMOUS mechanism. If I do set the callback methods, though, this time the sasl library on client's end can not even initiate, saying that a bad parameter was passed in the structure that keeps the list of those callbacks. It is not really reasonable, because I specified the exact same callbacks sample-client does, only the functions were a little simpler as my code does not accept arguments from command-line to force some choices to SASL library. That said, below is my conversation with a developer on Cyrus IRC channel. The issue was not solved at the end of it, but I wanted to post the conversation here anyways, in case it ignites some ideas. To summarize the conversation: He suggested I should redo the configuration step, this time specifying the plugin directory parameter. I did what he suggested, it had no effect. the tool called pluginviewer showed that I only have EXTERNAL plugin available. So he thought the problem is not my code but the way I installed sasl. My only hesitation about that argument is, how sample-client and sample-server managed to authenticate via ANONYMOUS mechanism on my computer. If there was something wrong with enabling anonymous plugin, they could not have authenticated, either. dwhite ilim: does 'pluginviewer' list anonymous as an available plugin? dwhite as an available *mechanism*? ilim dwhite: no, actually. nice catch. but I though anonymous was enabled by default. dwhite ilim: well, EXTERNAL comes free with the glue library (libsasl2), but anonymous comes, typically, in its own shared library. dwhite ilim: did you install libsasl via a binary package? ilim I compiled the source, and installed using the "quick and dirty way", as described in cyrus sasl documentation. (i.e. make, make install) dwhite ilim: i suspect you need to specify a --with-plugindir in your ./configure command. dwhite an --with-confdir as well. dwhite and ilim I wonder why specifying SASL_CB_GETPATH is not enough. I thought that was the one used for getting the path to the plugin directory. dwhite the manpage for sasl_client_init says to use SASL_PATH dwhite although include/sasl.h seems to indicate SASL_CB_GETPATH ilim dwhite: I tried configuring with the options you thought I should specify. ilim I specified the default plugin directory(/usr/lib/sasl2) as the location for both the plugins and the conf files. ilim it still returned SASL_BADPARAM. ilim And the thing is, the sample-client and sample-server can successfully complere ANONYMOUS authentication ilim even on my ubuntu desktop with pluginviewer displaying only external as available. dwhite ilim: you might try the native ubuntu packages. there may be some shared library patch they are applying. dwhite or you might see if they include such a patch in the package source ilim well, without something in the sample-client & sample-server source, they couldn't have anonymously authenticated. ilim but grep gave no results in the source for case insensitive phrase "ubuntu". Thought they might have some ifdefs for handling such behavior. dwhite ilim: look for a debian/patches directory dwhite ilim: also check out /var/log/auth.log for possible errors. ilim dwhite: Probably as the issue is with sasl_client_init(), there is nothing on auth.log. Again, nothing turned out for debian orpatch(using grep). dwhite ilim: if pluginviewer is failing, then you have a fundamental problem with your sasl install. dwhite you could strace pluginview, to see where it's looking for shared libraries dwhite you may have a mix of cyrus sasl installed (native ubuntu packages and newly compiled packages). ldd on one of your binaries may confirm that. dwhite at this point i'd rule out your code being the primary issue. 2013/7/31 İlim Uğur <[email protected]> > Hey, > > I worked some more on this issue. Still no luck, but I think I can provide > a little more specific info on it. > > I did what Jan suggested about the sample-client and sample-server, and > was able to authenticate via ANONYMOUS mechanism when I specified the path > to the plugins. (i.e. although I had installed plugins at /usr/lib/sasl2, > which is the default location) > > Then, I utilized the callback structure Cyrus SASL provides, which helps > us feed the library data such as authname, realm, password, etc. One can > basically provide the callback code(e.g. SASL_CB_GETPATH) proc(i.e. > callback method) and a context data to have a callback mechanism. Then > Cyrus SASL uses that callback to gather information such as the plugin path > from one's application. > > After appropriately migrating over all the callbacks provided in > sample-client of Cyrus SASL to my AuthenticatorClient class, I still was > unable to authenticate. Not only that, but since I started using callbacks > and provided them as input to sasl_client_init(), I started getting > SASL_BADPARAM errors as its return value. > > I decided to dig deeper using GNU Debugger, and noticed something. In > Cyrus SASL source, definition of sasl_client_init() is included in > lib/client.c . I noticed I was getting the error while SASL tries to load > plugins via _sasl_load_plugins() function. In the beginning of the > definition of that function, in lib/dlopen.c, the parameters function takes > are checked in an if statement. What happens is, as long as I do not > specify SASL_CB_VERIFYFILE in my list of callbacks, WITH a callback > function (i.e. as opposed to providing NULL as a its proc) the last > check(i.e. !verifyfile_cb->proc) in this long if statement returns false > value, ending in that function, and sasl_client_init() returning > SASL_BADPARAM. > > Now, I do not know the required signature of thr proc method of > SASL_CB_VERIFYFILE callback, but I sill could try to code such a method. > Yet, what boggles my mind is, sample-client does not have a > SASL_CB_VERIFYFILE callback, either. Yet, a default callback provided for > SASL_CB_VERIFYFILE by _sasl_find_verifyfile_callback() to > _sasl_load_plugins() seems to work for sample-client, while it does not > work for my code, which has been almost the same. > > It probably is really hard to get this without having a look at the code, > but I wanted to be as specific as possible. I will be working on providing > a SASL_CB_VERIFYFILE callback, but not a bit sure if that attempt will > result in success. > > Any ideas/suggestions? > > - İlim > > > > > 2013/7/29 Jan Schaumann <[email protected]> > >> ?lim U?ur <[email protected]> wrote: >> >> > ./sample-server -m ANONYMOUS -i >> local=127.0.0.1;5555,remote=127.0.0.1;5555 >> > -s http >> > ./sample-client -m ANONYMOUS -i >> local=127.0.0.1;5555,remote=127.0.0.1;5555 >> > -s http >> >> You have a few semicolons in there, which is likely not what you want. >> (The shell will stop parsing your command at the semicolon and attempt >> to execute the remainder after the process terminates.) >> >> Have you tried specifying the path to the directory where the plugins >> are installed? >> >> I just build and installed cyrus-sasl-2.1.26 into a temporary location >> and can do the following: >> >> Server: >> $ ./sample-server -p ../../lib/sasl2 >> Generating client mechanism list... >> Sending list of 8 mechanism(s) >> S: >> U0NSQU0tU0hBLTEgR1NTLVNQTkVHTyBHU1NBUEkgRElHRVNULU1ENSBPVFAgQ1JBTS1NRDUgUExBSU4gQU5PTllNT1VT >> Waiting for client mechanism... >> C: QU5PTllNT1VTAGFub255bW91c0BndW1w >> got 'ANONYMOUS' >> lt-sample-server: SASL Info: ANONYMOUS login: "anonymous@gump" >> Negotiation complete >> Username: anonymous >> Realm: (NULL) >> SSF: 0 >> sending encrypted message 'srv message 1' >> S: c3J2IG1lc3NhZ2UgMQA= >> Waiting for encrypted message... >> C: Y2xpZW50IG1lc3NhZ2UgMQA= >> got 'client message 1' >> recieved decoded message 'client message 1' >> >> >> Client: >> $ ./sample-client -m ANONYMOUS >> Waiting for mechanism list from server... >> S: >> U0NSQU0tU0hBLTEgR1NTLVNQTkVHTyBHU1NBUEkgRElHRVNULU1ENSBPVFAgQ1JBTS1NRDUgUExBSU4gQU5PTllNT1VT >> recieved 69 byte message >> Forcing use of mechanism ANONYMOUS >> Choosing best mechanism from: ANONYMOUS >> Using mechanism ANONYMOUS >> Preparing initial. >> Sending initial response... >> C: QU5PTllNT1VTAGFub255bW91c0BndW1w >> Negotiation complete >> Username: anonymous >> SSF: 0 >> Waiting for encoded message... >> S: c3J2IG1lc3NhZ2UgMQA= >> recieved 14 byte message >> recieved decoded message 'srv message 1' >> sending encrypted message 'client message 1' >> C: Y2xpZW50IG1lc3NhZ2UgMQA= >> >> >> >> When I do not specify the pathname for the server, I do get the >> 'Starting SASL negotiation: no mechanism available (no mechanism >> available)' error. >> >> -Jan >> > >
