[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