diff options
| -rw-r--r-- | Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp | 3 | ||||
| -rw-r--r-- | Swiften/SASL/SConscript | 12 | ||||
| -rw-r--r-- | Swiften/SConscript | 5 |
3 files changed, 15 insertions, 5 deletions
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp index 15c8ab6..b0a9f96 100644 --- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp +++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp @@ -1,106 +1,107 @@ #include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h" #include <cassert> #include <map> #include <boost/lexical_cast.hpp> #include "Swiften/StringCodecs/SHA1.h" #include "Swiften/StringCodecs/Base64.h" #include "Swiften/StringCodecs/HMACSHA1.h" #include "Swiften/StringCodecs/PBKDF2.h" +#include "Swiften/StringPrep/StringPrep.h" namespace Swift { SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const String& nonce) : ClientAuthenticator("SCRAM-SHA-1"), step(Initial), clientnonce(nonce) { // TODO: Normalize authentication id // TODO: Normalize getPassword() } ByteArray SCRAMSHA1ClientAuthenticator::getResponse() { if (step == Initial) { return "n,," + getInitialBareClientMessage(); } else { ByteArray saltedPassword = PBKDF2::encode(getPassword(), salt, iterations); ByteArray clientKey = HMACSHA1::getResult(saltedPassword, "Client Key"); ByteArray storedKey = SHA1::getBinaryHash(clientKey); ByteArray serverKey = HMACSHA1::getResult(saltedPassword, "Server Key"); ByteArray authMessage = getInitialBareClientMessage() + "," + initialServerMessage + "," + "c=biwsCg==," + "r=" + clientnonce + serverNonce; ByteArray clientSignature = HMACSHA1::getResult(storedKey, authMessage); serverSignature = HMACSHA1::getResult(serverKey, authMessage); ByteArray clientProof = clientKey; for (unsigned int i = 0; i < clientProof.getSize(); ++i) { clientProof[i] ^= clientSignature[i]; } ByteArray result = ByteArray("c=biwsCg==,r=") + clientnonce + serverNonce + ",p=" + Base64::encode(clientProof); return result; } } bool SCRAMSHA1ClientAuthenticator::setChallenge(const ByteArray& challenge) { if (step == Initial) { initialServerMessage = challenge; // TODO: Check if these values are correct std::map<char, String> keys = parseMap(String(initialServerMessage.getData(), initialServerMessage.getSize())); salt = Base64::decode(keys['s']); String clientServerNonce = keys['r']; serverNonce = clientServerNonce.getSubstring(clientnonce.getUTF8Size(), clientServerNonce.npos()); iterations = boost::lexical_cast<int>(keys['i'].getUTF8String()); step = Proof; return true; } else { return challenge == Base64::encode(ByteArray("v=") + Base64::encode(serverSignature)); } } std::map<char, String> SCRAMSHA1ClientAuthenticator::parseMap(const String& s) { // TODO: Do some proper checking here std::map<char, String> result; if (s.getUTF8Size() > 0) { char key; String value; size_t i = 0; bool expectKey = true; while (i < s.getUTF8Size()) { if (expectKey) { key = s[i]; expectKey = false; i++; } else if (s[i] == ',') { result[key] = value; value = ""; expectKey = true; } else { value += s[i]; } i++; } result[key] = value; } return result; } ByteArray SCRAMSHA1ClientAuthenticator::getInitialBareClientMessage() const { - String authenticationID = getAuthenticationID(); + String authenticationID = StringPrep::getPrepared(getAuthenticationID(), StringPrep::SASLPrep); String escapedAuthenticationID; for (size_t i = 0; i < authenticationID.getUTF8Size(); ++i) { if (authenticationID[i] == ',') { escapedAuthenticationID += "=2C"; } else if (authenticationID[i] == '=') { escapedAuthenticationID += "=3D"; } else { escapedAuthenticationID += authenticationID[i]; } } return ByteArray(String("n=" + escapedAuthenticationID + ",r=" + clientnonce)); } } diff --git a/Swiften/SASL/SConscript b/Swiften/SASL/SConscript new file mode 100644 index 0000000..22b242e --- /dev/null +++ b/Swiften/SASL/SConscript @@ -0,0 +1,12 @@ +Import("swiften_env") + +myenv = swiften_env.Clone() +myenv.MergeFlags(swiften_env["LIBIDN_FLAGS"]) + +objects = myenv.StaticObject([ + "ClientAuthenticator.cpp", + "PLAINClientAuthenticator.cpp", + "PLAINMessage.cpp", + "SCRAMSHA1ClientAuthenticator.cpp", + ]) +swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/SConscript b/Swiften/SConscript index af3ac97..6189b2e 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -1,145 +1,142 @@ Import("env") env["SWIFTEN_FLAGS"] = { "LIBPATH": [Dir(".")], "LIBS": ["Swiften"] } swiften_env = env.Clone() swiften_env.MergeFlags(swiften_env["BOOST_FLAGS"]) Export("swiften_env") # TODO: Move all this to a submodule SConscript myenv = swiften_env.Clone() myenv.MergeFlags(myenv["ZLIB_FLAGS"]) myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) sources = [ "Avatars/AvatarFileStorage.cpp", "Avatars/AvatarManager.cpp", "Avatars/AvatarStorage.cpp", "Client/Client.cpp", "Client/ClientSession.cpp", "Compress/ZLibCodecompressor.cpp", "Disco/CapsInfoGenerator.cpp", "Elements/DiscoInfo.cpp", "Elements/Element.cpp", "Elements/IQ.cpp", "Elements/MUCPayload.cpp", "Elements/Payload.cpp", "Elements/RosterPayload.cpp", "Elements/Stanza.cpp", "MUC/MUC.cpp", "MUC/MUCOccupant.cpp", "MUC/MUCRegistry.cpp", "Notifier/Notifier.cpp", "Presence/PresenceOracle.cpp", "Queries/IQChannel.cpp", "Queries/IQHandler.cpp", "Queries/IQRouter.cpp", "Queries/Request.cpp", "Queries/Responders/DiscoInfoResponder.cpp", "Queries/Responders/SoftwareVersionResponder.cpp", "Roster/ContactRosterItem.cpp", "Roster/Roster.cpp", "Roster/XMPPRoster.cpp", - "SASL/ClientAuthenticator.cpp", - "SASL/PLAINClientAuthenticator.cpp", - "SASL/PLAINMessage.cpp", - "SASL/SCRAMSHA1ClientAuthenticator.cpp", "Serializer/AuthRequestSerializer.cpp", "Serializer/AuthChallengeSerializer.cpp", "Serializer/AuthResponseSerializer.cpp", "Serializer/CompressRequestSerializer.cpp", "Serializer/ElementSerializer.cpp", "Serializer/MessageSerializer.cpp", "Serializer/PayloadSerializer.cpp", "Serializer/PayloadSerializerCollection.cpp", "Serializer/PayloadSerializers/CapsInfoSerializer.cpp", "Serializer/PayloadSerializers/DiscoInfoSerializer.cpp", "Serializer/PayloadSerializers/ErrorSerializer.cpp", "Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp", "Serializer/PayloadSerializers/MUCPayloadSerializer.cpp", "Serializer/PayloadSerializers/ResourceBindSerializer.cpp", "Serializer/PayloadSerializers/RosterSerializer.cpp", "Serializer/PayloadSerializers/SecurityLabelSerializer.cpp", "Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp", "Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp", "Serializer/PayloadSerializers/VCardSerializer.cpp", "Serializer/PayloadSerializers/VCardUpdateSerializer.cpp", "Serializer/PayloadSerializers/StorageSerializer.cpp", "Serializer/PayloadSerializers/PrivateStorageSerializer.cpp", "Serializer/PresenceSerializer.cpp", "Serializer/StanzaSerializer.cpp", "Serializer/StreamFeaturesSerializer.cpp", "Serializer/XML/XMLElement.cpp", "Serializer/XML/XMLNode.cpp", "Serializer/XMPPSerializer.cpp", "Server/ServerFromClientSession.cpp", "Server/ServerSession.cpp", "Server/ServerStanzaRouter.cpp", "Server/SimpleUserRegistry.cpp", "Server/UserRegistry.cpp", "Session/Session.cpp", "Session/SessionStream.cpp", "Session/BasicSessionStream.cpp", "StringCodecs/Base64.cpp", "StringCodecs/SHA1.cpp", "StringCodecs/HMACSHA1.cpp", "StringCodecs/PBKDF2.cpp", ] # "Notifier/GrowlNotifier.cpp", if myenv.get("HAVE_OPENSSL", 0) : sources += ["TLS/OpenSSL/OpenSSLContext.cpp"] SConscript(dirs = [ "Base", "StringPrep", + "SASL", "Application", "EventLoop", "Parser", "JID", "Network", "History", "StreamStack", "LinkLocal", "QA", ]) myenv.StaticLibrary("Swiften", sources + swiften_env["SWIFTEN_OBJECTS"]) env.Append(UNITTEST_SOURCES = [ File("Application/UnitTest/ApplicationTest.cpp"), File("Base/UnitTest/IDGeneratorTest.cpp"), File("Base/UnitTest/StringTest.cpp"), File("Base/UnitTest/ByteArrayTest.cpp"), File("Client/UnitTest/ClientSessionTest.cpp"), File("Compress/UnitTest/ZLibCompressorTest.cpp"), File("Compress/UnitTest/ZLibDecompressorTest.cpp"), File("Disco/UnitTest/CapsInfoGeneratorTest.cpp"), File("Elements/UnitTest/IQTest.cpp"), File("Elements/UnitTest/StanzaTest.cpp"), File("Elements/UnitTest/StanzasTest.cpp"), File("EventLoop/UnitTest/EventLoopTest.cpp"), File("EventLoop/UnitTest/SimpleEventLoopTest.cpp"), File("History/UnitTest/SQLiteHistoryManagerTest.cpp"), File("JID/UnitTest/JIDTest.cpp"), File("LinkLocal/UnitTest/LinkLocalConnectorTest.cpp"), File("LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp"), File("LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp"), File("LinkLocal/UnitTest/LinkLocalServiceTest.cpp"), File("Network/UnitTest/HostAddressTest.cpp"), File("Network/UnitTest/ConnectorTest.cpp"), File("Parser/PayloadParsers/UnitTest/BodyParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/PriorityParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/RawXMLPayloadParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/ResourceBindParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/RosterParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/SecurityLabelParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/SoftwareVersionParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/StatusParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/StatusShowParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/VCardParserTest.cpp"), |
Swift