From 0c681d645f77f5d355c6ef2446e58bb95236fa0e Mon Sep 17 00:00:00 2001 From: Lazlo Westerhof <l.r.westerhof@uu.nl> Date: Fri, 28 Sep 2018 11:03:24 +0200 Subject: [PATCH] Escape URL's for ePIC JSON payload. --- CMakeLists.txt | 2 +- src/msiRegisterEpicPID.cc | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2251b12..320fb47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,7 +119,7 @@ set(CPACK_GENERATOR "RPM") set(CPACK_PACKAGE_NAME "irods-uu-microservices") set(CPACK_PACKAGE_VENDOR "Utrecht University <fbyoda@uu.nl>") set(CPACK_PACKAGE_CONTACT "Utrecht University <fbyoda@uu.nl>") -set(CPACK_PACKAGE_VERSION "4.2.4_0.7.8") +set(CPACK_PACKAGE_VERSION "4.2.4_0.7.9") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/package/description.txt") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Miscellaneous iRODS microservices developed or modified by Utrecht University.") diff --git a/src/msiRegisterEpicPID.cc b/src/msiRegisterEpicPID.cc index 44ea797..d96fd8e 100644 --- a/src/msiRegisterEpicPID.cc +++ b/src/msiRegisterEpicPID.cc @@ -2,6 +2,7 @@ * \file * \brief iRODS microservice to register a PID with EPIC. * \author Felix Croes + * \author Lazlo Westerhof * \copyright Copyright (c) 2018, Utrecht University * * This file is part of irods-uu-microservices. @@ -27,13 +28,37 @@ #include <string> #include <fstream> #include <streambuf> +#include <sstream> +#include <iomanip> #include <curl/curl.h> static CredentialsStore credentials; static size_t length; -extern "C" { +std::string escapeJson(const std::string &s) { + std::ostringstream o; + for (auto c = s.cbegin(); c != s.cend(); c++) { + switch (*c) { + case '"': o << "\\\""; break; + case '\\': o << "\\\\"; break; + case '\b': o << "\\b"; break; + case '\f': o << "\\f"; break; + case '\n': o << "\\n"; break; + case '\r': o << "\\r"; break; + case '\t': o << "\\t"; break; + default: + if ('\x00' <= *c && *c <= '\x1f') { + o << "\\u" + << std::hex << std::setw(4) << std::setfill('0') << (int)*c; + } else { + o << *c; + } + } + } + return o.str(); +} +extern "C" { /* Curl requires a static callback function to read the input of a PUT request from. * This callback simply copies the payload. */ static size_t readCallback(void *buffer, size_t size, size_t nmemb, void *userp) @@ -84,11 +109,6 @@ extern "C" { std::string value = parseMspForStr(valueIn); std::string uuid = parseMspForStr(idInOut); - /* Minimally verify that these will embed nicely in a payload. */ - if (value.find('"') != std::string::npos) { - return SYS_INVALID_INPUT_PARAM; - } - /* Retriece parameters from the credentials store. */ std::string url(credentials.get("epic_url")); std::string prefix(credentials.get("epic_handle_prefix")); @@ -118,7 +138,7 @@ extern "C" { /* Create payload. */ std::string payload = "{\"values\":[{\"index\":1,\"type\":\"URL\",\"data\":{\"format\":\"string\",\"value\":\"" + - value + + escapeJson(value) + "\"}},{\"index\":100,\"type\":\"HS_ADMIN\",\"data\":{\"format\":\"admin\",\"value\":{\"handle\":\"0.NA/" + prefix + "\",\"index\":200,\"permissions\":\"011111110011\"}}}]}"; @@ -127,7 +147,7 @@ extern "C" { length = payload.length(); curl_easy_setopt(curl, CURLOPT_INFILESIZE, (long) length); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, discard); - + /* Don't verify the server certificate. */ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); -- GitLab