[Libreoffice-commits] online.git: loolwsd/Auth.cpp
Pranav Kant
pranavk at collabora.com
Thu Mar 31 12:00:47 UTC 2016
loolwsd/Auth.cpp | 96 ++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 64 insertions(+), 32 deletions(-)
New commits:
commit 26dd4e0b4bde61ea486dd271dbf44c04512919eb
Author: Pranav Kant <pranavk at collabora.com>
Date: Thu Mar 31 13:10:22 2016 +0530
loolwsd: Verify JWT token's expiry time
Change-Id: I6e6913e7918ac4c36ab98457054e5660cce3a854
diff --git a/loolwsd/Auth.cpp b/loolwsd/Auth.cpp
index 5d079d4..71f2d2b 100644
--- a/loolwsd/Auth.cpp
+++ b/loolwsd/Auth.cpp
@@ -14,8 +14,11 @@
#include <Poco/Base64Decoder.h>
#include <Poco/Crypto/RSADigestEngine.h>
#include <Poco/Crypto/RSAKey.h>
+#include <Poco/Dynamic/Var.h>
#include <Poco/JSON/Object.h>
+#include <Poco/JSON/Parser.h>
#include <Poco/LineEndingConverter.h>
+#include <Poco/Net/NetException.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
@@ -26,9 +29,12 @@
#include "Auth.hpp"
#include "Util.hpp"
+using Poco::Base64Decoder;
+using Poco::Base64Encoder;
+using Poco::OutputLineEndingConverter;
//////////////
-// OAuth Impl
+// JWTAuth Impl
//////////////
const std::string JWTAuth::getAccessToken()
{
@@ -61,8 +67,8 @@ const std::string JWTAuth::getAccessToken()
// The signature generated contains CRLF line endings.
// Use a line ending converter to remove these CRLF
std::ostringstream ostr;
- Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
- Poco::Base64Encoder encoder(lineEndingConv);
+ OutputLineEndingConverter lineEndingConv(ostr, "");
+ Base64Encoder encoder(lineEndingConv);
encoder << std::string(digest.begin(), digest.end());
encoder.close();
std::string encodedSig = ostr.str();
@@ -87,34 +93,60 @@ bool JWTAuth::verify(const std::string& accessToken)
{
Poco::StringTokenizer tokens(accessToken, ".", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
- std::string encodedBody = tokens[0] + "." + tokens[1];
- _digestEngine.update(encodedBody.c_str(), static_cast<unsigned>(encodedBody.length()));
- Poco::Crypto::DigestEngine::Digest digest = _digestEngine.signature();
-
- std::ostringstream ostr;
- Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
- Poco::Base64Encoder encoder(lineEndingConv);
-
- encoder << std::string(digest.begin(), digest.end());
- encoder.close();
- std::string encodedSig = ostr.str();
-
- // trim '=' from end of encoded signature.
- encodedSig.erase(std::find_if(encodedSig.rbegin(), encodedSig.rend(),
- [](char& ch)->bool { return ch != '='; }).base(), encodedSig.end());
-
- // Make the encoded sig URL and filename safe
- std::replace(encodedSig.begin(), encodedSig.end(), '+', '-');
- std::replace(encodedSig.begin(), encodedSig.end(), '/', '_');
-
- if (encodedSig != tokens[2])
+ try
+ {
+ std::string encodedBody = tokens[0] + "." + tokens[1];
+ _digestEngine.update(encodedBody.c_str(), static_cast<unsigned>(encodedBody.length()));
+ Poco::Crypto::DigestEngine::Digest digest = _digestEngine.signature();
+
+ std::ostringstream ostr;
+ OutputLineEndingConverter lineEndingConv(ostr, "");
+ Base64Encoder encoder(lineEndingConv);
+
+ encoder << std::string(digest.begin(), digest.end());
+ encoder.close();
+ std::string encodedSig = ostr.str();
+
+ // trim '=' from end of encoded signature.
+ encodedSig.erase(std::find_if(encodedSig.rbegin(), encodedSig.rend(),
+ [](char& ch)->bool { return ch != '='; }).base(), encodedSig.end());
+
+ // Make the encoded sig URL and filename safe
+ std::replace(encodedSig.begin(), encodedSig.end(), '+', '-');
+ std::replace(encodedSig.begin(), encodedSig.end(), '/', '_');
+
+ if (encodedSig != tokens[2])
+ {
+ Log::info("JWTAuth: verification failed; Expected: " + encodedSig + ", Received: " + tokens[2]);
+ return false;
+ }
+
+ std::istringstream istr(tokens[1]);
+ std::string decodedPayload;
+ Base64Decoder decoder(istr);
+ decoder >> decodedPayload;
+
+ Log::info("JWTAuth:verify: decoded payload: " + decodedPayload);
+
+ // Verify if the token is not already expired
+ Poco::JSON::Parser parser;
+ Poco::Dynamic::Var result = parser.parse(decodedPayload);
+ Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
+ std::time_t decodedExptime = object->get("exp").convert<std::time_t>();
+
+ std::time_t curtime = Poco::Timestamp().epochTime();
+ if (curtime > decodedExptime)
+ {
+ Log::info("JWTAuth:verify: JWT expired; curtime:" + std::to_string(curtime) + ", exp:" + std::to_string(decodedExptime));
+ return false;
+ }
+ }
+ catch(Poco::Exception& exc)
{
- Log::info("JWTAuth::Token verification failed; Expected: " + encodedSig + ", Received: " + tokens[2]);
+ Log::warn("JWTAuth:verify: Exception: " + exc.displayText());
return false;
}
- // TODO: Check for expiry etc.
-
return true;
}
@@ -125,8 +157,8 @@ const std::string JWTAuth::createHeader()
Log::info("JWT Header: " + header);
std::ostringstream ostr;
- Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
- Poco::Base64Encoder encoder(lineEndingConv);
+ OutputLineEndingConverter lineEndingConv(ostr, "");
+ Base64Encoder encoder(lineEndingConv);
encoder << header;
encoder.close();
@@ -136,15 +168,15 @@ const std::string JWTAuth::createHeader()
const std::string JWTAuth::createPayload()
{
std::time_t curtime = Poco::Timestamp().epochTime();
- std::string exptime = std::to_string(curtime + 3600);
+ std::string exptime = std::to_string(curtime + 1800);
// TODO: Some sane code to represent JSON objects
std::string payload = "{\"iss\":\""+_iss+"\",\"sub\":\""+_sub+"\",\"aud\":\""+_aud+"\",\"nme\":\""+_name+"\",\"exp\":\""+exptime+"\"}";
Log::info("JWT Payload: " + payload);
std::ostringstream ostr;
- Poco::OutputLineEndingConverter lineEndingConv(ostr, "");
- Poco::Base64Encoder encoder(lineEndingConv);
+ OutputLineEndingConverter lineEndingConv(ostr, "");
+ Base64Encoder encoder(lineEndingConv);
encoder << payload;
encoder.close();
More information about the Libreoffice-commits
mailing list