mirror of
https://github.com/QuasarApp/qca.git
synced 2025-05-11 02:09:33 +00:00
reorganized cyrus sasl plugin
svn path=/trunk/kdesupport/qca/; revision=245831
This commit is contained in:
parent
72be06386a
commit
1a0cf2b8e5
7
TODO
7
TODO
@ -1,14 +1,11 @@
|
|||||||
* cipher: option to specify size for genkey
|
* cipher: option to specify size for genkey
|
||||||
* cert: properly check hostnames with wildcards
|
* cert: properly check hostnames with wildcards
|
||||||
* ssl: error signal
|
* ssl: error signal
|
||||||
* sasl: option to not support client-send-first
|
* sasl: bring API up to speed with the plugin
|
||||||
* sasl: other security options
|
|
||||||
* sasl: server auth callback
|
|
||||||
* sasl: security layer
|
|
||||||
|
|
||||||
* openssl plugin: fixmes and todos
|
* openssl plugin: fixmes and todos
|
||||||
|
* cyrussasl plugin: serverstepthread
|
||||||
|
|
||||||
* sasl: external auth
|
|
||||||
* dsa
|
* dsa
|
||||||
* diffie-hellman
|
* diffie-hellman
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ extern "C"
|
|||||||
#include<qstringlist.h>
|
#include<qstringlist.h>
|
||||||
#include<qptrlist.h>
|
#include<qptrlist.h>
|
||||||
#include<qfile.h>
|
#include<qfile.h>
|
||||||
|
#include<qthread.h>
|
||||||
|
|
||||||
#define SASL_BUFSIZE 8192
|
#define SASL_BUFSIZE 8192
|
||||||
|
|
||||||
@ -185,10 +186,25 @@ static QString methodsToString(const QStringList &methods)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// needed to give interactive behavior to a callback-based function
|
||||||
|
class ServerStepThread : public QThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ServerStepThread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
//int r = sasl_server_start(con, in_mech.latin1(), clientin, clientinlen, &serverout, &serveroutlen);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class SASLContext : public QCA_SASLContext
|
class SASLContext : public QCA_SASLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QCACyrusSASL *g;
|
QCACyrusSASL *g;
|
||||||
|
ServerStepThread *sst;
|
||||||
|
|
||||||
// core props
|
// core props
|
||||||
QString service, host;
|
QString service, host;
|
||||||
@ -197,25 +213,37 @@ public:
|
|||||||
// security props
|
// security props
|
||||||
int secflags;
|
int secflags;
|
||||||
int ssf_min, ssf_max;
|
int ssf_min, ssf_max;
|
||||||
|
QString ext_authid;
|
||||||
// params
|
int ext_ssf;
|
||||||
SASLParams params;
|
|
||||||
int ssf, maxoutbuf;
|
|
||||||
|
|
||||||
sasl_conn_t *con;
|
sasl_conn_t *con;
|
||||||
sasl_interact_t *need;
|
sasl_interact_t *need;
|
||||||
|
int ssf, maxoutbuf;
|
||||||
QStringList mechlist;
|
QStringList mechlist;
|
||||||
bool servermode;
|
|
||||||
sasl_callback_t *callbacks;
|
sasl_callback_t *callbacks;
|
||||||
bool (*authCallback)(const QString &authname, const QString &username, QCA_SASLContext *c);
|
|
||||||
|
// state
|
||||||
|
bool servermode;
|
||||||
|
int step;
|
||||||
|
bool in_sendFirst;
|
||||||
|
QByteArray in_buf;
|
||||||
|
QString in_mech;
|
||||||
|
bool in_useClientInit;
|
||||||
|
QByteArray in_clientInit;
|
||||||
|
QString out_mech;
|
||||||
|
bool out_useClientInit;
|
||||||
|
QByteArray out_clientInit;
|
||||||
|
QByteArray out_buf;
|
||||||
|
|
||||||
|
SASLParams params;
|
||||||
|
QString sc_authname, sc_username;
|
||||||
|
|
||||||
SASLContext(QCACyrusSASL *_g)
|
SASLContext(QCACyrusSASL *_g)
|
||||||
{
|
{
|
||||||
g = _g;
|
g = _g;
|
||||||
con = 0;
|
con = 0;
|
||||||
need = 0;
|
|
||||||
callbacks = 0;
|
callbacks = 0;
|
||||||
authCallback = 0;
|
sst = 0;
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@ -233,6 +261,10 @@ public:
|
|||||||
|
|
||||||
void resetState()
|
void resetState()
|
||||||
{
|
{
|
||||||
|
if(sst) {
|
||||||
|
// only would happen if the user forgot to call setAuth, so let's do it now
|
||||||
|
setAuth(false);
|
||||||
|
}
|
||||||
if(con) {
|
if(con) {
|
||||||
sasl_dispose(&con);
|
sasl_dispose(&con);
|
||||||
con = 0;
|
con = 0;
|
||||||
@ -248,6 +280,8 @@ public:
|
|||||||
mechlist.clear();
|
mechlist.clear();
|
||||||
ssf = 0;
|
ssf = 0;
|
||||||
maxoutbuf = 0;
|
maxoutbuf = 0;
|
||||||
|
sc_authname = "";
|
||||||
|
sc_username = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetParams()
|
void resetParams()
|
||||||
@ -256,6 +290,8 @@ public:
|
|||||||
secflags = 0;
|
secflags = 0;
|
||||||
ssf_min = 0;
|
ssf_min = 0;
|
||||||
ssf_max = 0;
|
ssf_max = 0;
|
||||||
|
ext_authid = "";
|
||||||
|
ext_ssf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCoreProps(const QString &_service, const QString &_host, QCA_SASLHostPort *la, QCA_SASLHostPort *ra)
|
void setCoreProps(const QString &_service, const QString &_host, QCA_SASLHostPort *la, QCA_SASLHostPort *ra)
|
||||||
@ -266,7 +302,7 @@ public:
|
|||||||
remoteAddr = ra ? addrString(*ra) : "";
|
remoteAddr = ra ? addrString(*ra) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax)
|
void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax, const QString &_ext_authid, int _ext_ssf)
|
||||||
{
|
{
|
||||||
int sf = 0;
|
int sf = 0;
|
||||||
if(noPlain)
|
if(noPlain)
|
||||||
@ -286,11 +322,8 @@ public:
|
|||||||
secflags = sf;
|
secflags = sf;
|
||||||
ssf_min = ssfMin;
|
ssf_min = ssfMin;
|
||||||
ssf_max = ssfMax;
|
ssf_max = ssfMax;
|
||||||
}
|
ext_authid = _ext_authid;
|
||||||
|
ext_ssf = _ext_ssf;
|
||||||
void setAuthCallback(bool (*auth)(const QString &authname, const QString &username, QCA_SASLContext *c))
|
|
||||||
{
|
|
||||||
authCallback = auth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scb_checkauth(sasl_conn_t *, void *context, const char *requested_user, unsigned, const char *auth_identity, unsigned, const char *, unsigned, struct propctx *)
|
static int scb_checkauth(sasl_conn_t *, void *context, const char *requested_user, unsigned, const char *auth_identity, unsigned, const char *, unsigned, struct propctx *)
|
||||||
@ -298,17 +331,17 @@ public:
|
|||||||
SASLContext *that = (SASLContext *)context;
|
SASLContext *that = (SASLContext *)context;
|
||||||
QString authname = auth_identity;
|
QString authname = auth_identity;
|
||||||
QString username = requested_user;
|
QString username = requested_user;
|
||||||
if(that->authCallback) {
|
/*if(that->authCallback) {
|
||||||
if(that->authCallback(authname, username, that))
|
if(that->authCallback(authname, username, that))
|
||||||
return SASL_OK;
|
return SASL_OK;
|
||||||
else
|
else
|
||||||
return SASL_NOAUTHZ;
|
return SASL_NOAUTHZ;
|
||||||
}
|
}
|
||||||
else
|
else*/
|
||||||
return SASL_OK;
|
return SASL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setsecprops()
|
bool setsecprops()
|
||||||
{
|
{
|
||||||
sasl_security_properties_t secprops;
|
sasl_security_properties_t secprops;
|
||||||
secprops.min_ssf = ssf_min;
|
secprops.min_ssf = ssf_min;
|
||||||
@ -317,7 +350,22 @@ public:
|
|||||||
secprops.property_names = NULL;
|
secprops.property_names = NULL;
|
||||||
secprops.property_values = NULL;
|
secprops.property_values = NULL;
|
||||||
secprops.security_flags = secflags;
|
secprops.security_flags = secflags;
|
||||||
sasl_setprop(con, SASL_SEC_PROPS, &secprops);
|
int r = sasl_setprop(con, SASL_SEC_PROPS, &secprops);
|
||||||
|
if(r != SASL_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!ext_authid.isEmpty()) {
|
||||||
|
const char *authid = ext_authid.latin1();
|
||||||
|
sasl_ssf_t ssf = ext_ssf;
|
||||||
|
r = sasl_setprop(con, SASL_SSF_EXTERNAL, &ssf);
|
||||||
|
if(r != SASL_OK)
|
||||||
|
return false;
|
||||||
|
r = sasl_setprop(con, SASL_AUTH_EXTERNAL, &authid);
|
||||||
|
if(r != SASL_OK)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getssfparams()
|
void getssfparams()
|
||||||
@ -369,13 +417,21 @@ public:
|
|||||||
if(r != SASL_OK)
|
if(r != SASL_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
setsecprops();
|
if(!setsecprops())
|
||||||
|
return false;
|
||||||
|
|
||||||
mechlist = _mechlist;
|
mechlist = _mechlist;
|
||||||
servermode = false;
|
servermode = false;
|
||||||
|
step = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int clientFirstStep(bool allowClientSendFirst)
|
||||||
|
{
|
||||||
|
in_sendFirst = allowClientSendFirst;
|
||||||
|
return clientTryAgain();
|
||||||
|
}
|
||||||
|
|
||||||
bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)
|
bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)
|
||||||
{
|
{
|
||||||
resetState();
|
resetState();
|
||||||
@ -400,7 +456,8 @@ public:
|
|||||||
if(r != SASL_OK)
|
if(r != SASL_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
setsecprops();
|
if(!setsecprops())
|
||||||
|
return false;
|
||||||
|
|
||||||
const char *ml;
|
const char *ml;
|
||||||
r = sasl_listmech(con, 0, NULL, " ", NULL, &ml, 0, 0);
|
r = sasl_listmech(con, 0, NULL, " ", NULL, &ml, 0, 0);
|
||||||
@ -408,138 +465,201 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
*mechlist = QStringList::split(' ', ml);
|
*mechlist = QStringList::split(' ', ml);
|
||||||
servermode = true;
|
servermode = true;
|
||||||
|
step = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clientFirstStep(QString *mech, QByteArray **out, QCA_SASLNeedParams *np)
|
int serverFirstStep(const QString &mech, const QByteArray *in)
|
||||||
{
|
{
|
||||||
bool supportClientSendFirst = out ? true: false;
|
in_mech = mech;
|
||||||
|
|
||||||
const char *clientout, *m;
|
|
||||||
unsigned int clientoutlen;
|
|
||||||
|
|
||||||
need = 0;
|
|
||||||
QString list = methodsToString(mechlist);
|
|
||||||
int r;
|
|
||||||
while(1) {
|
|
||||||
if(need)
|
|
||||||
params.extractHave(need);
|
|
||||||
if(supportClientSendFirst)
|
|
||||||
r = sasl_client_start(con, list.latin1(), &need, &clientout, &clientoutlen, &m);
|
|
||||||
else
|
|
||||||
r = sasl_client_start(con, list.latin1(), &need, NULL, NULL, &m);
|
|
||||||
if(r != SASL_INTERACT)
|
|
||||||
break;
|
|
||||||
|
|
||||||
params.applyInteract(need);
|
|
||||||
if(params.missingAny()) {
|
|
||||||
*np = params.need;
|
|
||||||
return NeedParams;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(r != SASL_OK && r != SASL_CONTINUE)
|
|
||||||
return Error;
|
|
||||||
|
|
||||||
*mech = m;
|
|
||||||
if(supportClientSendFirst && clientout)
|
|
||||||
*out = new QByteArray(makeByteArray(clientout, clientoutlen));
|
|
||||||
else
|
|
||||||
*out = 0;
|
|
||||||
|
|
||||||
if(r == SASL_OK) {
|
|
||||||
getssfparams();
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int serverFirstStep(const QString &mech, const QByteArray *in, QByteArray *out)
|
|
||||||
{
|
|
||||||
const char *clientin = 0;
|
|
||||||
unsigned int clientinlen = 0;
|
|
||||||
if(in) {
|
if(in) {
|
||||||
clientin = in->data();
|
in_useClientInit = true;
|
||||||
clientinlen = in->size();
|
in_clientInit = in->copy();
|
||||||
}
|
|
||||||
const char *serverout;
|
|
||||||
unsigned int serveroutlen;
|
|
||||||
int r = sasl_server_start(con, mech.latin1(), clientin, clientinlen, &serverout, &serveroutlen);
|
|
||||||
if(r != SASL_OK && r != SASL_CONTINUE)
|
|
||||||
return Error;
|
|
||||||
*out = makeByteArray(serverout, serveroutlen);
|
|
||||||
if(r == SASL_OK) {
|
|
||||||
getssfparams();
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return Continue;
|
in_useClientInit = false;
|
||||||
|
return serverTryAgain();
|
||||||
}
|
}
|
||||||
|
|
||||||
int clientNextStep(const QByteArray &in, QByteArray *out, QCA_SASLNeedParams *np)
|
QCA_SASLNeedParams clientParamsNeeded() const
|
||||||
{
|
{
|
||||||
//clearNeedParams(np);
|
return params.need;
|
||||||
const char *clientout;
|
}
|
||||||
unsigned int clientoutlen;
|
|
||||||
int r;
|
|
||||||
while(1) {
|
|
||||||
if(need)
|
|
||||||
params.extractHave(need);
|
|
||||||
r = sasl_client_step(con, in.data(), in.size(), &need, &clientout, &clientoutlen);
|
|
||||||
if(r != SASL_INTERACT)
|
|
||||||
break;
|
|
||||||
|
|
||||||
params.applyInteract(need);
|
void setClientParams(const QString *auth, const QString *user, const QString *pass, const QString *realm)
|
||||||
if(params.missingAny()) {
|
{
|
||||||
*np = params.need;
|
if(auth)
|
||||||
return NeedParams;
|
params.setAuthname(*auth);
|
||||||
|
if(user)
|
||||||
|
params.setUsername(*user);
|
||||||
|
if(pass)
|
||||||
|
params.setPassword(*pass);
|
||||||
|
if(realm)
|
||||||
|
params.setRealm(*realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString authname() const
|
||||||
|
{
|
||||||
|
return sc_authname;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString username() const
|
||||||
|
{
|
||||||
|
return sc_username;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAuth(bool)
|
||||||
|
{
|
||||||
|
if(!sst)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: send the decision to the thread
|
||||||
|
sst->wait();
|
||||||
|
delete sst;
|
||||||
|
sst = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextStep(const QByteArray &in)
|
||||||
|
{
|
||||||
|
in_buf = in.copy();
|
||||||
|
return tryAgain();
|
||||||
|
}
|
||||||
|
|
||||||
|
int tryAgain()
|
||||||
|
{
|
||||||
|
if(servermode)
|
||||||
|
return serverTryAgain();
|
||||||
|
else
|
||||||
|
return clientTryAgain();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString mech() const
|
||||||
|
{
|
||||||
|
return out_mech;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray *clientInit() const
|
||||||
|
{
|
||||||
|
if(out_useClientInit)
|
||||||
|
return &out_clientInit;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray result() const
|
||||||
|
{
|
||||||
|
return out_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clientTryAgain()
|
||||||
|
{
|
||||||
|
if(step == 0) {
|
||||||
|
const char *clientout, *m;
|
||||||
|
unsigned int clientoutlen;
|
||||||
|
|
||||||
|
need = 0;
|
||||||
|
QString list = methodsToString(mechlist);
|
||||||
|
int r;
|
||||||
|
while(1) {
|
||||||
|
if(need)
|
||||||
|
params.extractHave(need);
|
||||||
|
if(in_sendFirst)
|
||||||
|
r = sasl_client_start(con, list.latin1(), &need, &clientout, &clientoutlen, &m);
|
||||||
|
else
|
||||||
|
r = sasl_client_start(con, list.latin1(), &need, NULL, NULL, &m);
|
||||||
|
if(r != SASL_INTERACT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
params.applyInteract(need);
|
||||||
|
if(params.missingAny())
|
||||||
|
return NeedParams;
|
||||||
}
|
}
|
||||||
|
if(r != SASL_OK && r != SASL_CONTINUE)
|
||||||
|
return Error;
|
||||||
|
|
||||||
|
out_mech = m;
|
||||||
|
if(in_sendFirst && clientout) {
|
||||||
|
out_clientInit = makeByteArray(clientout, clientoutlen);
|
||||||
|
out_useClientInit = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out_useClientInit = false;
|
||||||
|
|
||||||
|
++step;
|
||||||
|
|
||||||
|
if(r == SASL_OK) {
|
||||||
|
getssfparams();
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return Continue;
|
||||||
}
|
}
|
||||||
if(r != SASL_OK && r != SASL_CONTINUE)
|
else {
|
||||||
return Error;
|
const char *clientout;
|
||||||
*out = makeByteArray(clientout, clientoutlen);
|
unsigned int clientoutlen;
|
||||||
if(r == SASL_OK) {
|
int r;
|
||||||
getssfparams();
|
while(1) {
|
||||||
return Success;
|
if(need)
|
||||||
|
params.extractHave(need);
|
||||||
|
r = sasl_client_step(con, in_buf.data(), in_buf.size(), &need, &clientout, &clientoutlen);
|
||||||
|
if(r != SASL_INTERACT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
params.applyInteract(need);
|
||||||
|
if(params.missingAny())
|
||||||
|
return NeedParams;
|
||||||
|
}
|
||||||
|
if(r != SASL_OK && r != SASL_CONTINUE)
|
||||||
|
return Error;
|
||||||
|
out_buf = makeByteArray(clientout, clientoutlen);
|
||||||
|
if(r == SASL_OK) {
|
||||||
|
getssfparams();
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return Continue;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
int serverTryAgain()
|
||||||
|
{
|
||||||
|
if(step == 0) {
|
||||||
|
const char *clientin = 0;
|
||||||
|
unsigned int clientinlen = 0;
|
||||||
|
if(in_useClientInit) {
|
||||||
|
clientin = in_clientInit.data();
|
||||||
|
clientinlen = in_clientInit.size();
|
||||||
|
}
|
||||||
|
const char *serverout;
|
||||||
|
unsigned int serveroutlen;
|
||||||
|
int r = sasl_server_start(con, in_mech.latin1(), clientin, clientinlen, &serverout, &serveroutlen);
|
||||||
|
if(r != SASL_OK && r != SASL_CONTINUE)
|
||||||
|
return Error;
|
||||||
|
out_buf = makeByteArray(serverout, serveroutlen);
|
||||||
|
|
||||||
|
++step;
|
||||||
|
|
||||||
|
if(r == SASL_OK) {
|
||||||
|
getssfparams();
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return Continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *serverout;
|
||||||
|
unsigned int serveroutlen;
|
||||||
|
int r = sasl_server_step(con, in_buf.data(), in_buf.size(), &serverout, &serveroutlen);
|
||||||
|
if(r != SASL_OK && r != SASL_CONTINUE)
|
||||||
|
return Error;
|
||||||
|
if(r == SASL_OK) {
|
||||||
|
out_buf.resize(0);
|
||||||
|
getssfparams();
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
out_buf = makeByteArray(serverout, serveroutlen);
|
||||||
return Continue;
|
return Continue;
|
||||||
}
|
|
||||||
|
|
||||||
int serverNextStep(const QByteArray &in, QByteArray *out)
|
|
||||||
{
|
|
||||||
const char *serverout;
|
|
||||||
unsigned int serveroutlen;
|
|
||||||
int r = sasl_server_step(con, in.data(), in.size(), &serverout, &serveroutlen);
|
|
||||||
if(r != SASL_OK && r != SASL_CONTINUE)
|
|
||||||
return Error;
|
|
||||||
if(r == SASL_OK) {
|
|
||||||
out->resize(0);
|
|
||||||
getssfparams();
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
*out = makeByteArray(serverout, serveroutlen);
|
|
||||||
return Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAuthname(const QString &s)
|
|
||||||
{
|
|
||||||
params.setAuthname(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setUsername(const QString &s)
|
|
||||||
{
|
|
||||||
params.setUsername(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPassword(const QString &s)
|
|
||||||
{
|
|
||||||
params.setPassword(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRealm(const QString &s)
|
|
||||||
{
|
|
||||||
params.setRealm(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool encode(const QByteArray &in, QByteArray *out)
|
bool encode(const QByteArray &in, QByteArray *out)
|
||||||
|
73
src/qca.cpp
73
src/qca.cpp
@ -837,6 +837,7 @@ public:
|
|||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tried;
|
||||||
QCA_SASLContext *c;
|
QCA_SASLContext *c;
|
||||||
bool allowPlain;
|
bool allowPlain;
|
||||||
QHostAddress localAddr, remoteAddr;
|
QHostAddress localAddr, remoteAddr;
|
||||||
@ -897,11 +898,12 @@ bool SASL::startClient(const QString &service, const QString &host, const QStrin
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
|
d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
|
||||||
d->c->setSecurityProps(!d->allowPlain, false, false, false, false, false, false, 0, 256);
|
d->c->setSecurityProps(!d->allowPlain, false, false, false, false, false, false, 0, 256, "", 0);
|
||||||
if(!d->c->clientStart(mechlist))
|
if(!d->c->clientStart(mechlist))
|
||||||
return false;
|
return false;
|
||||||
d->first = true;
|
d->first = true;
|
||||||
d->server = false;
|
d->server = false;
|
||||||
|
d->tried = false;
|
||||||
QTimer::singleShot(0, this, SLOT(tryAgain()));
|
QTimer::singleShot(0, this, SLOT(tryAgain()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -919,34 +921,33 @@ bool SASL::startServer(const QString &service, const QString &host, const QStrin
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
|
d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
|
||||||
d->c->setSecurityProps(!d->allowPlain, false, false, false, false, false, false, 0, 256);
|
d->c->setSecurityProps(!d->allowPlain, false, false, false, false, false, false, 0, 256, "", 0);
|
||||||
if(!d->c->serverStart(realm, mechlist, saslappname))
|
if(!d->c->serverStart(realm, mechlist, saslappname))
|
||||||
return false;
|
return false;
|
||||||
d->first = true;
|
d->first = true;
|
||||||
d->server = true;
|
d->server = true;
|
||||||
|
d->tried = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::putServerFirstStep(const QString &mech)
|
void SASL::putServerFirstStep(const QString &mech)
|
||||||
{
|
{
|
||||||
QByteArray buf;
|
int r = d->c->serverFirstStep(mech, 0);
|
||||||
int r = d->c->serverFirstStep(mech, 0, &buf);
|
handleServerFirstStep(r);
|
||||||
handleServerFirstStep(r, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit)
|
void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit)
|
||||||
{
|
{
|
||||||
QByteArray buf;
|
int r = d->c->serverFirstStep(mech, &clientInit);
|
||||||
int r = d->c->serverFirstStep(mech, &clientInit, &buf);
|
handleServerFirstStep(r);
|
||||||
handleServerFirstStep(r, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::handleServerFirstStep(int r, const QByteArray &buf)
|
void SASL::handleServerFirstStep(int r)
|
||||||
{
|
{
|
||||||
if(r == QCA_SASLContext::Success)
|
if(r == QCA_SASLContext::Success)
|
||||||
authenticated(true);
|
authenticated(true);
|
||||||
else if(r == QCA_SASLContext::Continue)
|
else if(r == QCA_SASLContext::Continue)
|
||||||
nextStep(buf);
|
nextStep(d->c->result());
|
||||||
else
|
else
|
||||||
authenticated(false);
|
authenticated(false);
|
||||||
}
|
}
|
||||||
@ -959,22 +960,22 @@ void SASL::putStep(const QByteArray &stepData)
|
|||||||
|
|
||||||
void SASL::setAuthname(const QString &auth)
|
void SASL::setAuthname(const QString &auth)
|
||||||
{
|
{
|
||||||
d->c->setAuthname(auth);
|
d->c->setClientParams(&auth, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::setUsername(const QString &user)
|
void SASL::setUsername(const QString &user)
|
||||||
{
|
{
|
||||||
d->c->setUsername(user);
|
d->c->setClientParams(0, &user, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::setPassword(const QString &pass)
|
void SASL::setPassword(const QString &pass)
|
||||||
{
|
{
|
||||||
d->c->setPassword(pass);
|
d->c->setClientParams(0, 0, &pass, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::setRealm(const QString &realm)
|
void SASL::setRealm(const QString &realm)
|
||||||
{
|
{
|
||||||
d->c->setRealm(realm);
|
d->c->setClientParams(0, 0, 0, &realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SASL::continueAfterParams()
|
void SASL::continueAfterParams()
|
||||||
@ -987,50 +988,70 @@ void SASL::tryAgain()
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(d->server) {
|
if(d->server) {
|
||||||
QByteArray out;
|
if(!d->tried) {
|
||||||
r = d->c->serverNextStep(d->stepData, &out);
|
r = d->c->nextStep(d->stepData);
|
||||||
|
d->tried = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
r = d->c->tryAgain();
|
||||||
|
|
||||||
if(r == QCA_SASLContext::Error) {
|
if(r == QCA_SASLContext::Error) {
|
||||||
authenticated(false);
|
authenticated(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(r == QCA_SASLContext::Continue) {
|
else if(r == QCA_SASLContext::Continue) {
|
||||||
nextStep(out);
|
d->tried = false;
|
||||||
|
nextStep(d->c->result());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(d->first) {
|
if(d->first) {
|
||||||
QString mech;
|
if(!d->tried) {
|
||||||
QByteArray *clientInit;
|
r = d->c->clientFirstStep(true);
|
||||||
QCA_SASLNeedParams np;
|
d->tried = true;
|
||||||
r = d->c->clientFirstStep(&mech, &clientInit, &np);
|
}
|
||||||
|
else
|
||||||
|
r = d->c->tryAgain();
|
||||||
|
|
||||||
if(r == QCA_SASLContext::Error) {
|
if(r == QCA_SASLContext::Error) {
|
||||||
authenticated(false);
|
authenticated(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(r == QCA_SASLContext::NeedParams) {
|
else if(r == QCA_SASLContext::NeedParams) {
|
||||||
|
d->tried = false;
|
||||||
|
QCA_SASLNeedParams np = d->c->clientParamsNeeded();
|
||||||
needParams(np.auth, np.user, np.pass, np.realm);
|
needParams(np.auth, np.user, np.pass, np.realm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString mech = d->c->mech();
|
||||||
|
const QByteArray *clientInit = d->c->clientInit();
|
||||||
|
|
||||||
d->first = false;
|
d->first = false;
|
||||||
|
d->tried = false;
|
||||||
clientFirstStep(mech, clientInit);
|
clientFirstStep(mech, clientInit);
|
||||||
delete clientInit;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QByteArray out;
|
if(!d->tried) {
|
||||||
QCA_SASLNeedParams np;
|
r = d->c->nextStep(d->stepData);
|
||||||
r = d->c->clientNextStep(d->stepData, &out, &np);
|
d->tried = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
r = d->c->tryAgain();
|
||||||
|
|
||||||
if(r == QCA_SASLContext::Error) {
|
if(r == QCA_SASLContext::Error) {
|
||||||
authenticated(false);
|
authenticated(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(r == QCA_SASLContext::NeedParams) {
|
else if(r == QCA_SASLContext::NeedParams) {
|
||||||
|
d->tried = false;
|
||||||
|
QCA_SASLNeedParams np = d->c->clientParamsNeeded();
|
||||||
needParams(np.auth, np.user, np.pass, np.realm);
|
needParams(np.auth, np.user, np.pass, np.realm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//else if(r == QCA_SASLContext::Continue) {
|
//else if(r == QCA_SASLContext::Continue) {
|
||||||
nextStep(out);
|
nextStep(d->c->result());
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ namespace QCA
|
|||||||
class Private;
|
class Private;
|
||||||
Private *d;
|
Private *d;
|
||||||
|
|
||||||
void handleServerFirstStep(int r, const QByteArray &buf);
|
void handleServerFirstStep(int r);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,31 +134,36 @@ struct QCA_SASLNeedParams
|
|||||||
class QCA_SASLContext
|
class QCA_SASLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { Success, Error, NeedParams, Continue };
|
enum { Success, Error, NeedParams, AuthCheck, Continue };
|
||||||
virtual ~QCA_SASLContext() {}
|
virtual ~QCA_SASLContext() {}
|
||||||
|
|
||||||
// common
|
// common
|
||||||
virtual void reset()=0;
|
virtual void reset()=0;
|
||||||
virtual void setCoreProps(const QString &service, const QString &host, QCA_SASLHostPort *local, QCA_SASLHostPort *remote)=0;
|
virtual void setCoreProps(const QString &service, const QString &host, QCA_SASLHostPort *local, QCA_SASLHostPort *remote)=0;
|
||||||
virtual void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax)=0;
|
virtual void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax, const QString &_ext_authid, int _ext_ssf)=0;
|
||||||
virtual int security() const=0;
|
virtual int security() const=0;
|
||||||
|
|
||||||
// client
|
// init / first step
|
||||||
virtual bool clientStart(const QStringList &mechlist)=0;
|
virtual bool clientStart(const QStringList &mechlist)=0;
|
||||||
virtual int clientFirstStep(QString *mech, QByteArray **out, QCA_SASLNeedParams *np)=0;
|
virtual int clientFirstStep(bool allowClientSendFirst)=0;
|
||||||
virtual int clientNextStep(const QByteArray &in, QByteArray *out, QCA_SASLNeedParams *np)=0;
|
|
||||||
|
|
||||||
// server
|
|
||||||
virtual bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)=0;
|
virtual bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)=0;
|
||||||
virtual int serverFirstStep(const QString &mech, const QByteArray *in, QByteArray *out)=0;
|
virtual int serverFirstStep(const QString &mech, const QByteArray *in)=0;
|
||||||
virtual int serverNextStep(const QByteArray &in, QByteArray *out)=0;
|
|
||||||
virtual void setAuthCallback(bool (*auth)(const QString &authname, const QString &username, QCA_SASLContext *c))=0;
|
|
||||||
|
|
||||||
// client params
|
// get / set params
|
||||||
virtual void setAuthname(const QString &)=0;
|
virtual QCA_SASLNeedParams clientParamsNeeded() const=0;
|
||||||
virtual void setUsername(const QString &)=0;
|
virtual void setClientParams(const QString *auth, const QString *user, const QString *pass, const QString *realm)=0;
|
||||||
virtual void setPassword(const QString &)=0;
|
virtual QString authname() const=0;
|
||||||
virtual void setRealm(const QString &)=0;
|
virtual QString username() const=0;
|
||||||
|
virtual void setAuth(bool)=0;
|
||||||
|
|
||||||
|
// continue steps
|
||||||
|
virtual int nextStep(const QByteArray &in)=0;
|
||||||
|
virtual int tryAgain()=0;
|
||||||
|
|
||||||
|
// results
|
||||||
|
virtual QString mech() const=0;
|
||||||
|
virtual const QByteArray *clientInit() const=0;
|
||||||
|
virtual QByteArray result() const=0;
|
||||||
|
|
||||||
// security layer
|
// security layer
|
||||||
virtual bool encode(const QByteArray &in, QByteArray *out)=0;
|
virtual bool encode(const QByteArray &in, QByteArray *out)=0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user