summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kopete/protocols/jabber/libiris/iris/xmpp-core/simplesasl.cpp207
1 files changed, 128 insertions, 79 deletions
diff --git a/kopete/protocols/jabber/libiris/iris/xmpp-core/simplesasl.cpp b/kopete/protocols/jabber/libiris/iris/xmpp-core/simplesasl.cpp
index 92091f63..371f6092 100644
--- a/kopete/protocols/jabber/libiris/iris/xmpp-core/simplesasl.cpp
+++ b/kopete/protocols/jabber/libiris/iris/xmpp-core/simplesasl.cpp
@@ -155,6 +155,7 @@ public:
TQString out_mech;
TQByteArray out_buf;
bool capable;
+ bool allow_plain;
int err;
TQCA_SASLNeedParams need;
@@ -207,12 +208,13 @@ public:
host = _host;
}
- void setSecurityProps(bool, bool, bool, bool, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int, const TQString &, int)
+ void setSecurityProps(bool noPlain, bool, bool, bool, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int, const TQString &, int)
{
if(reqForward || reqCreds || reqMutual || ssfMin > 0)
capable = false;
else
capable = true;
+ allow_plain = !noPlain;
}
int security() const
@@ -228,8 +230,17 @@ public:
bool clientStart(const TQStringList &mechlist)
{
bool haveMech = false;
+ resetState();
+ step = 0;
+
for(TQStringList::ConstIterator it = mechlist.begin(); it != mechlist.end(); ++it) {
+ if((*it) == "PLAIN" && allow_plain) {
+ out_mech = "PLAIN";
+ haveMech = true;
+ break;
+ }
if((*it) == "DIGEST-MD5") {
+ out_mech = "DIGEST-MD5";
haveMech = true;
break;
}
@@ -238,9 +249,6 @@ public:
err = TQCA::SASL::NoMech;
return false;
}
-
- resetState();
- step = 0;
return true;
}
@@ -316,7 +324,7 @@ public:
const TQByteArray *clientInit() const
{
- return 0;
+ return out_mech == "PLAIN" ? &out_buf : 0;
}
TQByteArray result() const
@@ -326,85 +334,126 @@ public:
int clientTryAgain()
{
- if(step == 0) {
- out_mech = "DIGEST-MD5";
- ++step;
- return Continue;
+ if( out_mech == "PLAIN" ) {
+ if(step == 0) {
+ // First, check if we have everything
+ if(need.user || need.pass) {
+ err = -1;
+ return Error;
+ }
+ if(!have.user) {
+ need.user = true;
+ }
+ if(!have.pass) {
+ need.pass = true;
+ }
+ if(need.user || need.pass) {
+ return NeedParams;
+ }
+
+ TQCString authz_ = authz.utf8();
+ TQCString user_ = user.utf8();
+ TQCString pass_ = pass.utf8();
+ int l = 0;
+
+ out_buf.resize(authz_.length() + 1 + user_.length() + 1 + pass_.length());
+ memcpy(&out_buf[l], authz_.data(), authz_.length());
+ l += authz_.length();
+ out_buf[l] = '\0';
+ l += 1;
+ memcpy(&out_buf[l], user_.data(), user_.length());
+ l += user_.length();
+ out_buf[l] = '\0';
+ l += 1;
+
+ memcpy(&out_buf[l], pass_.data(), pass_.length());
+ ++step;
+ return Continue;
+ }
+
+ out_buf.resize(0);
+ return Success;
}
- else if(step == 1) {
- // if we still need params, then the app has failed us!
- if(need.user || need.authzid || need.pass || need.realm) {
- err = -1;
- return Error;
+
+ if( out_mech == "DIGEST-MD5" ) {
+ if(step == 0) {
+ ++step;
+ return Continue;
}
+ else if(step == 1) {
+ // if we still need params, then the app has failed us!
+ if(need.user || need.authzid || need.pass || need.realm) {
+ err = -1;
+ return Error;
+ }
- // see if some params are needed
- if(!have.user)
- need.user = true;
- if(!have.authzid)
- need.authzid = true;
- if(!have.pass)
- need.pass = true;
- if(need.user || need.authzid || need.pass)
- return NeedParams;
-
- // get props
- TQCString cs(in_buf.data(), in_buf.size()+1);
- PropList in;
- if(!in.fromString(cs)) {
- err = TQCA::SASL::BadProto;
- return Error;
+ // see if some params are needed
+ if(!have.user)
+ need.user = true;
+ if(!have.authzid)
+ need.authzid = true;
+ if(!have.pass)
+ need.pass = true;
+ if(need.user || need.authzid || need.pass)
+ return NeedParams;
+
+ // get props
+ TQCString cs(in_buf.data(), in_buf.size()+1);
+ PropList in;
+ if(!in.fromString(cs)) {
+ err = TQCA::SASL::BadProto;
+ return Error;
+ }
+
+ // make a cnonce
+ TQByteArray a(32);
+ for(int n = 0; n < (int)a.size(); ++n)
+ a[n] = (char)(256.0*rand()/(RAND_MAX+1.0));
+ TQCString cnonce = Base64::arrayToString(a).latin1();
+
+ // make other variables
+ realm = host;
+ TQCString nonce = in.get("nonce");
+ TQCString nc = "00000001";
+ TQCString uri = service.utf8() + '/' + host.utf8();
+ TQCString qop = "auth";
+
+ // build 'response'
+ TQCString X = user.utf8() + ':' + realm.utf8() + ':' + pass.utf8();
+ TQByteArray Y = TQCA::MD5::hash(X);
+ TQCString tmp = TQCString(":") + nonce + ':' + cnonce + ':' + authz.utf8();
+ TQByteArray A1(Y.size() + tmp.length());
+ memcpy(A1.data(), Y.data(), Y.size());
+ memcpy(A1.data() + Y.size(), tmp.data(), tmp.length());
+ TQCString A2 = "AUTHENTICATE:" + uri;
+ TQCString HA1 = TQCA::MD5::hashToString(A1).latin1();
+ TQCString HA2 = TQCA::MD5::hashToString(A2).latin1();
+ TQCString KD = HA1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + HA2;
+ TQCString Z = TQCA::MD5::hashToString(KD).latin1();
+
+ // build output
+ PropList out;
+ out.set("username", user.utf8());
+ out.set("realm", host.utf8());
+ out.set("nonce", nonce);
+ out.set("cnonce", cnonce);
+ out.set("nc", nc);
+ out.set("serv-type", service.utf8());
+ out.set("host", host.utf8());
+ out.set("digest-uri", uri);
+ out.set("qop", qop);
+ out.set("response", Z);
+ out.set("charset", "utf-8");
+ out.set("authzid", authz.utf8());
+ TQCString s = out.toString();
+
+ // done
+ out_buf.resize(s.length());
+ memcpy(out_buf.data(), s.data(), out_buf.size());
+ ++step;
+ return Continue;
}
- // make a cnonce
- TQByteArray a(32);
- for(int n = 0; n < (int)a.size(); ++n)
- a[n] = (char)(256.0*rand()/(RAND_MAX+1.0));
- TQCString cnonce = Base64::arrayToString(a).latin1();
-
- // make other variables
- realm = host;
- TQCString nonce = in.get("nonce");
- TQCString nc = "00000001";
- TQCString uri = service.utf8() + '/' + host.utf8();
- TQCString qop = "auth";
-
- // build 'response'
- TQCString X = user.utf8() + ':' + realm.utf8() + ':' + pass.utf8();
- TQByteArray Y = TQCA::MD5::hash(X);
- TQCString tmp = TQCString(":") + nonce + ':' + cnonce + ':' + authz.utf8();
- TQByteArray A1(Y.size() + tmp.length());
- memcpy(A1.data(), Y.data(), Y.size());
- memcpy(A1.data() + Y.size(), tmp.data(), tmp.length());
- TQCString A2 = "AUTHENTICATE:" + uri;
- TQCString HA1 = TQCA::MD5::hashToString(A1).latin1();
- TQCString HA2 = TQCA::MD5::hashToString(A2).latin1();
- TQCString KD = HA1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + HA2;
- TQCString Z = TQCA::MD5::hashToString(KD).latin1();
-
- // build output
- PropList out;
- out.set("username", user.utf8());
- out.set("realm", host.utf8());
- out.set("nonce", nonce);
- out.set("cnonce", cnonce);
- out.set("nc", nc);
- out.set("serv-type", service.utf8());
- out.set("host", host.utf8());
- out.set("digest-uri", uri);
- out.set("qop", qop);
- out.set("response", Z);
- out.set("charset", "utf-8");
- out.set("authzid", authz.utf8());
- TQCString s = out.toString();
-
- // done
- out_buf.resize(s.length());
- memcpy(out_buf.data(), s.data(), out_buf.size());
- ++step;
- return Continue;
- }
- else {
out_buf.resize(0);
return Success;
}