# Find Boost
find_package(Boost 1.44 COMPONENTS iostreams unit_test_framework thread REQUIRED)
+# Find pcrecpp
+pkg_check_modules(PCRECPP REQUIRED libpcrecpp)
+INCLUDE_DIRECTORIES(${PCRECPP_INCLUDE_DIRS})
+LINK_DIRECTORIES(${PCRECPP_LIBRARY_DIRS})
+
# Find libxml++
if (BUILD_XMLLIB)
pkg_check_modules(XMLPP REQUIRED libxml++-2.6)
${Boost_IOSTREAMS_LIBRARIES}
${Boost_THREAD_LIBRARIES}
${ICONV_LIBRARIES}
- ${OPENSSL_LIBRARIES})
+ ${OPENSSL_LIBRARIES}
+ ${PCRECPP_LIBRARIES})
set_target_properties(i2ncommon PROPERTIES VERSION ${VERSION} SOVERSION 7)
set_target_properties(i2ncommon PROPERTIES OUTPUT_NAME i2ncommon CLEAN_DIRECT_OUTPUT 1)
#include <stringfunc.hxx>
#include <restricted_html.hpp>
+#include <pcrecpp.h>
+#include <fstream>
+#include "crypto.hxx"
+#include "filefunc.hxx"
using namespace std;
return out.str();
}
+
+/**
+* @brief Change the attribute Filename from which the SecretId is going
+* to be read.
+*
+* @param s custom_filename string new filename.
+*/
+void RedirectHash::set_custom_filename(string custom_filename)
+{
+ Filename = custom_filename;
+}
+
+/**
+* @brief Reads the file Filename and loads the data into SecretId.
+*/
+void RedirectHash::load_secret_id()
+{
+ SecretId = read_file(Filename);
+
+ if (SecretId.empty())
+ throw runtime_error("Inexistent file or empty");
+}
+
+/**
+* @brief Hashes the given url with the SecretId and returns a base64 hash.
+*
+* @param s &url string.
+*
+* @return base64 raw hash
+*/
+string RedirectHash::hash_url(const string &url)
+{
+ if (SecretId.empty())
+ load_secret_id();
+
+ return base64_encode(hash_data_raw(url + SecretId, MD5));
+}
+
+/**
+* @brief Reads a HTML file, removes all ##BEGIN_URL## and ##END_URL## tags and
+* adds urlauth param to the url in between these tags.
+*
+* @param s &html string.
+*
+* @return new html with the urls signed
+*/
+string RedirectHash::sign_urls(const string &html)
+{
+ string ret(html);
+ string url;
+ string re = "##BEGIN_URL##(.*?)##END_URL##";
+ pcrecpp::RE re_match(re);
+ while (re_match.PartialMatch(ret, &url))
+ {
+ string hashed_url = hash_url(url);
+
+ replace_all(ret,
+ "##BEGIN_URL##" + url + "##END_URL##",
+ encode_url(url) + "&urlauth=" + encode_url(hashed_url));
+ }
+ return ret;
+}
+
+/**
+* @brief Validates if the given url is the correspondent url to the given
+* authtag hash.
+*
+* @param s &url string;
+* &authtag string hash;
+*
+* @return bool true if the given url is the correspondent url to the
+* authtag hash, else returns false
+*/
+bool RedirectHash::validate_redirect_authtag(const string &url,
+ const string &authtag)
+{
+ return authtag == hash_url(url);
+}
+
} // eo namespace I2n
{
- std::string decode_url(std::string s);
+std::string decode_url(std::string s);
- std::string encode_url(std::string s);
+std::string encode_url(std::string s);
+
+
+class RedirectHash
+{
+ public:
+ RedirectHash() : Filename("/var/intranator/etc/redirect_secret_id"){}
+
+ void set_custom_filename(std::string custom_filename);
+
+ void load_secret_id();
+
+ std::string hash_url(const std::string &url);
+
+ std::string sign_urls(const std::string &html);
+
+ bool validate_redirect_authtag(const std::string &url,
+ const std::string &authtag);
+
+ private:
+ std::string Filename;
+
+ std::string SecretId;
+};
} // eo namespace I2n
{
protected:
- char* Filename;
+ string Filename;
tmpfstream Tempfile;
Tempfile << "Long Data and or Password";
Tempfile.close();
- Filename = (char*)Tempfile.get_tmp_filename().c_str();
+ Filename = Tempfile.get_tmp_filename();
}
public:
*/
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
+#include <tmpfstream.hpp>
#include <restricted_html.hpp>
output);
}
+BOOST_AUTO_TEST_CASE(RedirectHash1)
+{
+ tmpfstream TempFile;
+ string TempFilePattern = "/tmp/libi2ncommon_test_restricted_html_XXXXXX";
+ TempFile.open(TempFilePattern);
+ TempFile << "ABCDEF";
+ TempFile.close();
+
+ RedirectHash redirect_hash = RedirectHash();
+ redirect_hash.set_custom_filename(TempFile.get_tmp_filename());
+
+ string url1 = "http://www.domain.com/params?param=p";
+ string url2 = "http://www.google.com/search?q=test";
+
+ string url1_encoded = "http%3A%2F%2Fwww%2Edomain%2Ecom%2Fparams%3Fparam%3Dp";
+ string url2_encoded = "http%3A%2F%2Fwww%2Egoogle%2Ecom%2Fsearch%3Fq%3Dtest";
+
+ string hash1 = "a2Dlksjt5kBrt6Or4nKdxQ==";
+ string hash2 = "2BdwBA6vlqJS/3vWzUxa1w==";
+
+ string hash1_encoded = "a2Dlksjt5kBrt6Or4nKdxQ%3D%3D";
+ string hash2_encoded = "2BdwBA6vlqJS%2F3vWzUxa1w%3D%3D";
+
+ BOOST_CHECK_EQUAL(encode_url(url1) , url1_encoded);
+ BOOST_CHECK_EQUAL(encode_url(url2) , url2_encoded);
+
+ const string html = ("<html>"
+ "<a href=\"/arnie?form=redirect&url=##BEGIN_URL##" +
+ url1 +"##END_URL##\" target=\"_top\">Further information</a>"
+ "<a href=\"/arnie?form=redirect&url=##BEGIN_URL##" +
+ url2 +"##END_URL##\" target=\"_top\">Further information</a>"
+ "</html>");
+
+ const string result = ("<html>"
+ "<a href=\"/arnie?form=redirect&url=" + url1_encoded + "&urlauth=" +
+ hash1_encoded + "\" target=\"_top\">Further information</a>"
+ "<a href=\"/arnie?form=redirect&url=" + url2_encoded + "&urlauth=" +
+ hash2_encoded + "\" target=\"_top\">Further information</a>"
+ "</html>");
+
+
+ string new_html = redirect_hash.sign_urls(html);
+
+ BOOST_CHECK_EQUAL(result, new_html);
+
+ BOOST_CHECK(redirect_hash.validate_redirect_authtag(url1, hash1));
+ BOOST_CHECK(redirect_hash.validate_redirect_authtag(url2, hash2));
+
+ TempFile.unlink();
+}
+
BOOST_AUTO_TEST_SUITE_END()