From 0de3cf93b1c0a7fea7bcb024994bcf2e36b65fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 07:25:35 -0400 Subject: [PATCH 01/19] bin: [+] split large files in several packets Up to 2MiB of storage is split among packets of size 56KiB each. Exceeding data is not read from standard input and is thus ingnored. The changes are summarized in the following bullet points: * The Bin class: * New public constants for better controling the parameters regarding the size of every packets and maximal allowed file size: DPASTE_NPACKETS_LEN, DPASTE_PIN_LEN, DPASTE_MAX_SIZE. * Bin::paste's main implementation is now using std::stringstream instead of std::vector. This allows to avoid unnecessary copies when creating individual packets. * New helper functions such as parse_code_info, code_from_pin and hexStrFromInt contain previously sparsely written code. * The Bin::Packet structure has a new EXTRA_SERIALIZATION_BYTES constant specifying the extra space needed for serialization of packets. * Bin::Random structure encapsulates the random number generator for Bin. * The AES class: * Removal of the unused CODE_PASS_OFFSET constant. * Increasing of the PIN_WITH_PASS_LEN constant specifying the length of the PIN. * The HttpClient class: * new isAvailable function; * GET request: make sure every values are recovered from the REST server. * Documentation related to changed function signatures or new ones have been handled appropriately. --- src/aescrypto.h | 11 +-- src/bin.cpp | 214 ++++++++++++++++++++++++++++++-------------- src/bin.h | 122 ++++++++++++++++++++++--- src/http_client.cpp | 17 ++-- src/http_client.h | 24 ++++- tests/bin.cpp | 6 +- 6 files changed, 298 insertions(+), 96 deletions(-) diff --git a/src/aescrypto.h b/src/aescrypto.h index 0a09e5f..d260ca6 100644 --- a/src/aescrypto.h +++ b/src/aescrypto.h @@ -33,15 +33,10 @@ class AES : public Cipher { public: /** * Length of the PIN if it contains the password for encrypted pasted data. - * It consists of 16 hexadecimal characters: 16*4 = 64 bits. Last 32 bits - * encode the password. Otherwise, PIN should be 32 bits. + * It consists of 18 hexadecimal characters: 18*4 = 72 bits. Last 32 bits + * encode the password. Otherwise, PIN should be 40 bits. */ - static const constexpr size_t PIN_WITH_PASS_LEN {16}; - /** - * Number of bytes offsetting the password in the binary representation of - * the hexadecimal password. - */ - static const constexpr size_t CODE_PASS_OFFSET {4}; + static const constexpr size_t PIN_WITH_PASS_LEN {18}; AES() {} virtual ~AES () {} diff --git a/src/bin.cpp b/src/bin.cpp index 7a0a92f..076916d 100644 --- a/src/bin.cpp +++ b/src/bin.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -38,7 +40,7 @@ const constexpr uint8_t Bin::PROTO_VERSION; Bin::Bin() { /* load dpaste config */ - auto config_file = conf::ConfigurationFile(); + conf::ConfigurationFile config_file {}; config_file.load(); conf_ = config_file.getConfiguration(); @@ -58,29 +60,31 @@ std::string Bin::code_from_dpaste_uri(const std::string& uri) { return uri.substr(p != std::string::npos ? p+DUP.length() : 0); } -std::pair Bin::get(std::string&& code, bool no_decrypt) { - code = code_from_dpaste_uri(code); - const auto offset = crypto::AES::CODE_PASS_OFFSET*2; - const auto lcode = code.substr(0, offset); - const auto pwd = code.substr(offset); - - /* first try http server */ - auto data_str = http_client_->get(lcode); - std::vector data {data_str.begin(), data_str.end()}; - - /* if fail, then perform request from local node */ - if (data.empty()) { - /* get a pasted blob */ - auto values = node.get(lcode); - if (not values.empty()) - data = values.front(); - } +std::tuple +Bin::parse_code_info(const std::string& code) { + std::stringstream ns(code.substr(Bin::DPASTE_PIN_LEN, Bin::DPASTE_NPACKETS_LEN)); + uint32_t npackets; + ns >> std::hex >> npackets; + return { + code.substr(0, Bin::DPASTE_PIN_LEN), + npackets, + code.substr(Bin::DPASTE_PIN_LEN+Bin::DPASTE_NPACKETS_LEN) + }; +} - if (not data.empty()) { - Packet p; +std::vector +Bin::parse_data(const std::string& code, + std::vector>&& values, + std::string pwd, + bool no_decrypt) const +{ + for (const auto& v : values) { try { - p.deserialize(data); + Packet p; + p.deserialize(v); + std::vector data; auto cipher = crypto::Cipher::get(p.data, code); + if (cipher and not no_decrypt) { std::shared_ptr params; if (auto aes = std::dynamic_pointer_cast(cipher)) { @@ -90,6 +94,7 @@ std::pair Bin::get(std::string&& code, bool no_decrypt) { data = cipher->processCipherText(p.data, std::move(params)); } else data = std::move(p.data); + if (not (cipher or p.signature.empty())) { auto gc = std::dynamic_pointer_cast(crypto::Cipher::get(crypto::Cipher::Scheme::GPG, {})); DPASTE_MSG("Data is GPG signed. Verifying..."); @@ -97,45 +102,89 @@ std::pair Bin::get(std::string&& code, bool no_decrypt) { if (res.numSignatures() > 0) gc->comment_on_signature(res.signature(0)); } + + return data; } catch (const GpgME::Exception& e) { DPASTE_MSG("%s", e.what()); - return {false, ""}; + return {}; } catch (const dht::crypto::DecryptError& e) { DPASTE_MSG("%s", e.what()); - return {false, ""}; + return {}; } catch (msgpack::type_error& e) { } /* backward compatibility with <=0.3.3 */ + } + + return {}; +} +std::pair Bin::get(std::string&& code, bool no_decrypt) { + code = code_from_dpaste_uri(code); + const auto parsed_code = parse_code_info(code); + const auto& lcode = std::get<0>(parsed_code); + const auto& npackets = std::get<1>(parsed_code); + const auto& pwd = std::get<2>(parsed_code); + + std::vector packets(npackets); + + auto available = http_client_->isAvailable(); + auto get_method = [this,&available](const auto& c) { + /* if available, try http server */ + if (available) { + auto datas = http_client_->get(c); + std::vector> data; + std::transform(datas.begin(), datas.end(), std::back_inserter(data), [](const auto& s) { + std::vector blob; + std::move(s.begin(), s.end(), std::back_inserter(blob)); + return blob; + }); + return data; + /* if fail, then perform request from local node */ + } else return node.get(c); + }; + + std::vector whole_data; + uint32_t licode; + { + std::stringstream css(lcode); + css >> std::hex >> licode; } - return {true, {data.begin(), data.end()}}; + for (uint8_t s = 0; s < npackets; ++s) { + std::string target = code_from_pin(licode + s); + auto values = get_method(target); + auto data = parse_data(code, std::move(values), pwd, no_decrypt); + if (data.empty()) + return {false, {}}; + std::move(data.begin(), data.end(), std::back_inserter(whole_data)); + } + + std::string ret; + std::move(whole_data.begin(), whole_data.end(), std::back_inserter(ret)); + return {true, std::move(ret)}; } -std::vector Bin::data_from_stream(std::stringstream&& input_stream) { +std::vector Bin::data_from_stream(std::stringstream& input_stream, const size_t& count) { std::vector buffer; - buffer.resize(dht::MAX_VALUE_SIZE); - input_stream.read(reinterpret_cast(buffer.data()), dht::MAX_VALUE_SIZE); + buffer.resize(count); + input_stream.read(reinterpret_cast(buffer.data()), count); buffer.resize(input_stream.gcount()); return buffer; } -std::string Bin::random_pin() { - static std::uniform_int_distribution dist; - static std::mt19937_64 rand_; - static dht::crypto::random_device rdev; - static std::seed_seq seed {rdev(), rdev()}; - static bool initialized = false; - if (not initialized) - rand_.seed(seed); - - auto pin = dist(rand_); - std::stringstream ss; - ss << std::setfill('0') << std::setw(Bin::DPASTE_PIN_LEN) << std::hex << pin; - auto pin_s = ss.str(); +std::string Bin::code_from_pin(uint32_t pin) { + auto pin_s = hexStrFromInt(pin, Bin::DPASTE_PIN_LEN); std::transform(pin_s.begin(), pin_s.end(), pin_s.begin(), ::toupper); return pin_s; } -std::pair Bin::prepare_data(std::vector&& data, std::unique_ptr&& params) { - Packet p; +std::string Bin::hexStrFromInt(uint32_t i, size_t len) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(len) << std::hex << i; + return ss.str(); +} + +std::pair, std::string> +Bin::prepare_data(std::stringstream&& input_stream, + std::unique_ptr&& params) +{ std::string pwd = ""; std::shared_ptr sparams(std::move(params)); std::shared_ptr init_params; @@ -144,48 +193,75 @@ std::pair Bin::prepare_data(std::vector&& dat bool to_sign {false}; if (auto gp = std::get_if(sparams.get())) { auto& keyid = conf_.at("pgp_key_id"); - to_sign = gp->sign and not keyid.empty(); - scheme = gp->scheme; + to_sign = gp->sign and not keyid.empty(); + scheme = gp->scheme; init_params = std::make_shared(); init_params->emplace(keyid); } else if (auto aesp = std::get_if(sparams.get())) { - scheme = aesp->scheme; - pwd = random_pin(); + scheme = aesp->scheme; + pwd = random_pin(); aesp->password = pwd; } auto cipher = crypto::Cipher::get(scheme, std::move(init_params)); - if (cipher) { - auto cipher_text = cipher->processPlainText(data, std::move(sparams)); - if (cipher_text.empty()) { - p.data.insert(p.data.end(), data.begin(), data.end()); - if (to_sign) { - DPASTE_MSG("Signing data..."); - auto res = std::dynamic_pointer_cast(cipher)->sign(p.data); - p.signature = res.first; - } + uint32_t rsiz = 0; + const size_t SIZE_PER_PACKET = dht::MAX_VALUE_SIZE - Packet::EXTRA_SERIALIZATION_BYTES; + std::vector packets; + packets.reserve(std::ceil(((double)Bin::DPASTE_MAX_SIZE) / SIZE_PER_PACKET)); + std::vector data; + while (rsiz < Bin::DPASTE_MAX_SIZE + and (data = data_from_stream(input_stream, SIZE_PER_PACKET)).size() > 0) + { + rsiz += data.size(); + + Packet p; + if (cipher) { + auto cipher_text = cipher->processPlainText(data, std::move(sparams)); + if (cipher_text.empty()) { + p.data.insert(p.data.end(), data.begin(), data.end()); + if (to_sign) { + DPASTE_MSG("Signing data..."); + auto res = std::dynamic_pointer_cast(cipher)->sign(p.data); + p.signature = std::move(res.first); + } + } else + p.data = std::move(cipher_text); } else - p.data = cipher_text; - } else - p.data.insert(p.data.end(), data.begin(), data.end()); - return {p, pwd}; + p.data = std::move(data); + + packets.push_back(std::move(p)); + } + + packets.shrink_to_fit(); + return {packets, std::move(pwd)}; } -std::string Bin::paste(std::vector&& data, std::unique_ptr&& params) { - auto code = random_pin(); +std::string +Bin::paste(std::stringstream&& input_stream, std::unique_ptr&& params) { + auto pin = random_.integer(); + auto available = http_client_->isAvailable(); + auto paste_method = [this,&available](const auto& c, auto&& d) { + if (available) return http_client_->put(c, {d.begin(), d.end()}); + else return node.paste(c, std::forward>(d)); + }; - auto pp = prepare_data(std::forward>(data), std::forward>(params)); - auto& p = pp.first; - auto& pwd = pp.second; + auto pp = prepare_data(std::forward(input_stream), + std::forward>(params)); + auto& packets = pp.first; + auto& pwd = pp.second; DPASTE_MSG("Pasting data..."); - auto bin_packet = p.serialize(); - auto success = http_client_->put(code, {bin_packet.begin(), bin_packet.end()}); - if (not success) - success = node.paste(code, std::move(bin_packet)); + size_t shift = 0; + for (const auto& p : packets) { + auto code = code_from_pin(pin + shift++); + auto bin_packet = p.serialize(); + bool success = paste_method(code, std::move(bin_packet)); + if (not success) + return {}; + } - return success ? DPASTE_URI_PREFIX+code+pwd : ""; + return DPASTE_URI_PREFIX+code_from_pin(pin)+hexStrFromInt(shift, Bin::DPASTE_NPACKETS_LEN)+pwd; } msgpack::object* diff --git a/src/bin.h b/src/bin.h index 50acf0d..6414e42 100644 --- a/src/bin.h +++ b/src/bin.h @@ -46,7 +46,19 @@ class Bin { #endif public: + /** + * Number of bytes in a dpaste code accounting for the number of packets the + * file was split into + */ + static const constexpr unsigned int DPASTE_NPACKETS_LEN {2}; + /** + * Number of bytes in a dpaste code accounting for the location PIN. */ static const constexpr unsigned int DPASTE_PIN_LEN {8}; + /** + * Maximal size to be read from the input stream and pasted on the DHT + * (possibly split in several packets). + */ + static const constexpr size_t DPASTE_MAX_SIZE {2 * 1024 * 1024}; Bin(); virtual ~Bin () {} @@ -69,11 +81,13 @@ class Bin { * * @return the code (key) to the pasted data. If empty, then process failed. */ - std::string paste(std::vector&& data, std::unique_ptr&& params); - std::string paste(std::stringstream&& input_stream, std::unique_ptr&& params) { - return paste(data_from_stream(std::move(input_stream)), - std::forward>(params)); + std::string paste(std::vector&& data, std::unique_ptr&& params) { + std::string is; + std::move(data.begin(), data.end(), std::back_inserter(is)); + std::stringstream ss(std::move(is)); + return paste(std::move(ss), std::forward>(params)); } + std::string paste(std::stringstream&& input_stream, std::unique_ptr&& params); private: /* constants */ @@ -81,6 +95,13 @@ class Bin { static const constexpr uint8_t PROTO_VERSION = 0; struct Packet { + /** + * Bytes needed for the two layers of serialization. This accounts for + * dpaste's usage of msgpack as well as OpenDHT's and GPG + * encryption/signature. + */ + static const constexpr size_t EXTRA_SERIALIZATION_BYTES {12 * 1024}; + std::vector data {}; std::vector signature {}; @@ -88,25 +109,67 @@ class Bin { void deserialize(const std::vector& pbuffer); }; + /*! + * @class Random + * @brief Random number generator state encapsulator. + * @details + * The structure contains the the state of the random number generator used + * by the Bin class to perform its random code generation. The structure + * is embeded inside the Bin class as a private member. + */ + struct Random { + Random() { + dht::crypto::random_device rdev; + std::seed_seq seed {rdev(), rdev()}; + gen.seed(seed); + } + + inline uint32_t integer() { return dist(gen); } + + std::uniform_int_distribution dist; + std::mt19937_64 gen; + }; + /** * Create a Packet from input data and crypto parameters. * - * @param data input data in bytes. - * @param params cryptographic parameters (either GPGParameters or - * AESParameters). + * @param input_stream input data stream of bytes. + * @param params cryptographic parameters (either GPGParameters or + * AESParameters). * * @return an ordered pair of a Packet and associated password. */ - std::pair prepare_data(std::vector&& data, std::unique_ptr&& params); + std::pair, std::string> + prepare_data(std::stringstream&& input_stream, std::unique_ptr&& params); + + /** + * Parses the DHT values recovered from the DHT get operation and returns + * the first value found the the given code identifier. + * + * @param code String of bytes consisting in the location code + * information. + * @param values The values to parse. + * @param pwd The password used to decrypt the AES encrypted data + * (if it was present in the input code). + * @param no_decrypt A bool indicating if the data should be decrypted + * before being returned. + * + * @return The value (or part of the value) recovered from the DHT. + */ + std::vector parse_data(const std::string& code, + std::vector>&& values, + std::string pwd, + bool no_decrypt) const; /** * Get data from input stream. * * @param input_stream The stream to read to get the data. + * @param count Number of bytes to be read from the stream. * * @return the data */ - static std::vector data_from_stream(std::stringstream&& input_stream); + static std::vector data_from_stream(std::stringstream& input_stream, const size_t& count); /** * Parse dpaste uri for code. @@ -117,13 +180,52 @@ class Bin { */ static std::string code_from_dpaste_uri(const std::string& uri); - static std::string random_pin(); + /** + * Parses the input code into three separate parts consisting respectivly in + * the location code information, the number of packets the file is split + * into and the password used to decrypt AES encrypted data. + * + * @param code The input code. + * + * @return The tuple described above. + */ + static std::tuple parse_code_info(const std::string& code); + + /** + * Converts a number into its hexadecimal `len` bytes long string value + * with zeroes padding in prefix when necessary. + * + * @param i The integer. + * @param len The length of the resulting string. + * + * @return the resulting hexadecimal string representation of the integer. + */ + static std::string hexStrFromInt(uint32_t i, size_t len); + /** + * Converts a PIN number into a string code, i.e. an hexadecimal string + * representation of the PIN in upper case. + * + * @param i The integer. + * + * @return the resulting hexadecimal string representation of the integer. + */ + static std::string code_from_pin(uint32_t i); + + /** + * Generates a random PIN using a 32-bit random number generator. The + * resulting string describes a 32-bit value. + */ + inline std::string random_pin() { return code_from_pin(random_.integer()); } + + /* A map containing the configuration read from the config file on disk. */ std::map conf_; /* transport */ std::unique_ptr http_client_ {}; Node node {}; + + Random random_ {}; }; } /* dpaste */ diff --git a/src/http_client.cpp b/src/http_client.cpp index 1864ded..59828d9 100644 --- a/src/http_client.cpp +++ b/src/http_client.cpp @@ -37,12 +37,17 @@ using json = nlohmann::json; static std::ofstream null("/dev/null"); -std::string HttpClient::get(const std::string& code) const { +bool HttpClient::isAvailable() const { + return put(dht::InfoHash::getRandom().toString(), "hello world"); +} + +std::vector HttpClient::get(const std::string& code) const { try { curlpp::Cleanup mycleanup; curlpp::Easy req; req.setOpt(port); - std::stringstream response, oss; + std::stringstream response; + std::vector data; req.setOpt(HTTP_PROTO+ host+"/"+dht::InfoHash::get(code).toString() +"?user_type="+dpaste::Node::DPASTE_USER_TYPE @@ -54,15 +59,17 @@ std::string HttpClient::get(const std::string& code) const { /* server gives code 200 when everything is fine. */ if (curlpp::Infos::ResponseCode::get(req) == 200) { auto pr = json::parse(response.str()); - if (not pr.empty()) { - std::istringstream iss((*pr.begin())["base64"].dump()); + for (const auto& entry : pr) { + std::istringstream iss(entry["base64"].dump()); + std::stringstream oss; base64::decoder d; d.decode(iss, oss); + data.emplace_back(oss.str()); } } } catch (curlpp::RuntimeError & e) { } - return oss.str(); + return data; } catch (curlpp::LogicError & e) { return {}; } } diff --git a/src/http_client.h b/src/http_client.h index 1c11465..028cec5 100644 --- a/src/http_client.h +++ b/src/http_client.h @@ -20,6 +20,7 @@ #pragma once +#include #include namespace dpaste { @@ -29,7 +30,28 @@ class HttpClient { HttpClient (std::string host, long port) : host(host), port(port) {} virtual ~HttpClient () {} - std::string get(const std::string& code) const; + /** + * Tells if the server responds to requests. + */ + bool isAvailable() const; + + /** + * Send a GET request to the REST server. + * + * @param code The location code. + * + * @return A vector of the values recovered from the DHT by the REST server. + */ + std::vector get(const std::string& code) const; + + /** + * Send a PUT request to the REST server. + * + * @param code The location code. + * @param data The data to publish. + * + * @return True if the server accepted and completed the request, false otherwise. + */ bool put(const std::string& code, const std::string& data) const; private: diff --git a/tests/bin.cpp b/tests/bin.cpp index 07d78b9..885d61a 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -41,8 +41,8 @@ class PirateBinTester { return Bin::code_from_dpaste_uri(uri); } - std::vector data_from_stream(std::stringstream&& input_stream) const { - return Bin::data_from_stream(std::forward(input_stream)); + std::vector data_from_stream(std::stringstream& input_stream, size_t count) const { + return Bin::data_from_stream(input_stream, count); } }; @@ -117,7 +117,7 @@ TEST_CASE("Bin conversion of stringstream to vector", "[Bin][data_from_stream]") const std::string DATA = "SOME DATA"; std::stringstream ss(DATA); std::vector d {DATA.begin(), DATA.end()}; - REQUIRE ( pt.data_from_stream(std::move(ss)) == d ); + REQUIRE ( pt.data_from_stream(ss, DATA.size()) == d ); } } /* tests */ From 398a6a62bd794b3fee9cb8d8478bed417e4e2da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 07:32:47 -0400 Subject: [PATCH 02/19] bin: [/] parse_code_info, read only 32bits pwd --- src/bin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin.cpp b/src/bin.cpp index 076916d..6c5c068 100644 --- a/src/bin.cpp +++ b/src/bin.cpp @@ -63,12 +63,13 @@ std::string Bin::code_from_dpaste_uri(const std::string& uri) { std::tuple Bin::parse_code_info(const std::string& code) { std::stringstream ns(code.substr(Bin::DPASTE_PIN_LEN, Bin::DPASTE_NPACKETS_LEN)); + const auto PWD_LEN = crypto::AES::PIN_WITH_PASS_LEN - Bin::DPASTE_PIN_LEN - Bin::DPASTE_NPACKETS_LEN; uint32_t npackets; ns >> std::hex >> npackets; return { code.substr(0, Bin::DPASTE_PIN_LEN), npackets, - code.substr(Bin::DPASTE_PIN_LEN+Bin::DPASTE_NPACKETS_LEN) + code.substr(Bin::DPASTE_PIN_LEN+Bin::DPASTE_NPACKETS_LEN, PWD_LEN) }; } From 327d809e5ee2b68fd69598e5c5c79c80fd60d7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 08:06:41 -0400 Subject: [PATCH 03/19] bin: [/] ensure code is no more than 18 chars 18 Hexadecimal characters is 32 + 2 + 32 bits. --- src/bin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin.cpp b/src/bin.cpp index 6c5c068..a768cf2 100644 --- a/src/bin.cpp +++ b/src/bin.cpp @@ -57,7 +57,7 @@ Bin::Bin() { std::string Bin::code_from_dpaste_uri(const std::string& uri) { static const std::string DUP {DPASTE_URI_PREFIX}; const auto p = uri.find(DUP); - return uri.substr(p != std::string::npos ? p+DUP.length() : 0); + return uri.substr(p != std::string::npos ? p+DUP.length() : 0, crypto::AES::PIN_WITH_PASS_LEN); } std::tuple From bc9cc42c42e6c5d467683a5dfba8b080c35007e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 08:22:55 -0400 Subject: [PATCH 04/19] tests: [/] replace PIN by CODE where appropriate A PIN is number while a code is a string possibly encoding more than one number. --- tests/bin.cpp | 20 ++++++++++---------- tests/node.cpp | 2 +- tests/tests.cpp | 2 +- tests/tests.h | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/bin.cpp b/tests/bin.cpp index 885d61a..5132509 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -77,15 +77,15 @@ TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { PirateBinTester pt; - const std::string PIN = random_pin(); - std::string pin_upper {PIN.begin(), PIN.end()}; + const std::string CODE = random_code(); + std::string pin_upper {CODE.begin(), CODE.end()}; std::transform(pin_upper.begin(), pin_upper.end(), pin_upper.begin(), ::toupper); SECTION ( "good pins" ) { - auto gc1 = "dpaste:"+PIN; - auto gc2 = PIN; - REQUIRE ( pt.code_from_dpaste_uri(gc1) == PIN ); - REQUIRE ( pt.code_from_dpaste_uri(gc2) == PIN ); + auto gc1 = "dpaste:"+CODE; + auto gc2 = CODE; + REQUIRE ( pt.code_from_dpaste_uri(gc1) == CODE ); + REQUIRE ( pt.code_from_dpaste_uri(gc2) == CODE ); SECTION ( "good pin (upper case)" ) { auto gc3 = "dpaste:"+pin_upper; @@ -96,10 +96,10 @@ TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste } } SECTION ( "bad pins" ) { - std::string bc1 = "DPASTE:"+PIN; - std::string bc2 = "DPaste:"+PIN; - REQUIRE ( pt.code_from_dpaste_uri(bc1) != PIN ); - REQUIRE ( pt.code_from_dpaste_uri(bc2) != PIN ); + std::string bc1 = "DPASTE:"+CODE; + std::string bc2 = "DPaste:"+CODE; + REQUIRE ( pt.code_from_dpaste_uri(bc1) != CODE ); + REQUIRE ( pt.code_from_dpaste_uri(bc2) != CODE ); SECTION ( "bad pins (upper case)" ) { auto bc3 = "DPASTE:"+pin_upper; diff --git a/tests/node.cpp b/tests/node.cpp index 633da39..fd7ea94 100644 --- a/tests/node.cpp +++ b/tests/node.cpp @@ -38,7 +38,7 @@ class PirateNodeTester { TEST_CASE("Node get/paste on DHT", "[Node][get][paste]") { PirateNodeTester pt; - const std::string PIN = random_pin(); + const std::string PIN = random_code(); std::vector data = {0, 1, 2, 3, 4}; dpaste::Node node {}; node.run(); diff --git a/tests/tests.cpp b/tests/tests.cpp index 4b8e451..40632bd 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -44,7 +44,7 @@ int random_number() { return dist(rand_); } -std::string random_pin() { +std::string random_code() { const auto i = random_number(); std::stringstream ss; ss << std::hex << i; diff --git a/tests/tests.h b/tests/tests.h index 025cd69..c78e974 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -22,7 +22,7 @@ namespace dpaste { namespace tests { int random_number(); -std::string random_pin(); +std::string random_code(); } /* tests */ } /* dpaste */ From 62b9a3431c3b9a2b4f8c396cd7fcd3c9a6122f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 21:14:46 -0400 Subject: [PATCH 05/19] code: [+] moving code constants to code.h --- src/aescrypto.h | 7 ------- src/bin.cpp | 15 +++++++------- src/bin.h | 8 -------- src/cipher.cpp | 4 +++- src/code.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 src/code.h diff --git a/src/aescrypto.h b/src/aescrypto.h index d260ca6..58930bd 100644 --- a/src/aescrypto.h +++ b/src/aescrypto.h @@ -31,13 +31,6 @@ namespace crypto { class AES : public Cipher { public: - /** - * Length of the PIN if it contains the password for encrypted pasted data. - * It consists of 18 hexadecimal characters: 18*4 = 72 bits. Last 32 bits - * encode the password. Otherwise, PIN should be 40 bits. - */ - static const constexpr size_t PIN_WITH_PASS_LEN {18}; - AES() {} virtual ~AES () {} diff --git a/src/bin.cpp b/src/bin.cpp index a768cf2..2e48ec2 100644 --- a/src/bin.cpp +++ b/src/bin.cpp @@ -29,6 +29,8 @@ #include #include "bin.h" + +#include "code.h" #include "conf.h" #include "log.h" #include "gpgcrypto.h" @@ -57,19 +59,18 @@ Bin::Bin() { std::string Bin::code_from_dpaste_uri(const std::string& uri) { static const std::string DUP {DPASTE_URI_PREFIX}; const auto p = uri.find(DUP); - return uri.substr(p != std::string::npos ? p+DUP.length() : 0, crypto::AES::PIN_WITH_PASS_LEN); + return uri.substr(p != std::string::npos ? p+DUP.length() : 0, code::PIN_WITH_PASS_LEN); } std::tuple Bin::parse_code_info(const std::string& code) { - std::stringstream ns(code.substr(Bin::DPASTE_PIN_LEN, Bin::DPASTE_NPACKETS_LEN)); - const auto PWD_LEN = crypto::AES::PIN_WITH_PASS_LEN - Bin::DPASTE_PIN_LEN - Bin::DPASTE_NPACKETS_LEN; + std::stringstream ns(code.substr(code::DPASTE_PIN_LEN, code::DPASTE_NPACKETS_LEN)); uint32_t npackets; ns >> std::hex >> npackets; return { - code.substr(0, Bin::DPASTE_PIN_LEN), + code.substr(0, code::DPASTE_PIN_LEN), npackets, - code.substr(Bin::DPASTE_PIN_LEN+Bin::DPASTE_NPACKETS_LEN, PWD_LEN) + code.substr(code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN, code::PASSWORD_LEN) }; } @@ -171,7 +172,7 @@ std::vector Bin::data_from_stream(std::stringstream& input_stream, cons } std::string Bin::code_from_pin(uint32_t pin) { - auto pin_s = hexStrFromInt(pin, Bin::DPASTE_PIN_LEN); + auto pin_s = hexStrFromInt(pin, code::DPASTE_PIN_LEN); std::transform(pin_s.begin(), pin_s.end(), pin_s.begin(), ::toupper); return pin_s; } @@ -262,7 +263,7 @@ Bin::paste(std::stringstream&& input_stream, std::unique_ptr return {}; } - return DPASTE_URI_PREFIX+code_from_pin(pin)+hexStrFromInt(shift, Bin::DPASTE_NPACKETS_LEN)+pwd; + return DPASTE_URI_PREFIX+code_from_pin(pin)+hexStrFromInt(shift, code::DPASTE_NPACKETS_LEN)+pwd; } msgpack::object* diff --git a/src/bin.h b/src/bin.h index 6414e42..5f8429a 100644 --- a/src/bin.h +++ b/src/bin.h @@ -46,14 +46,6 @@ class Bin { #endif public: - /** - * Number of bytes in a dpaste code accounting for the number of packets the - * file was split into - */ - static const constexpr unsigned int DPASTE_NPACKETS_LEN {2}; - /** - * Number of bytes in a dpaste code accounting for the location PIN. */ - static const constexpr unsigned int DPASTE_PIN_LEN {8}; /** * Maximal size to be read from the input stream and pasted on the DHT * (possibly split in several packets). diff --git a/src/cipher.cpp b/src/cipher.cpp index 9c1c52c..0205483 100644 --- a/src/cipher.cpp +++ b/src/cipher.cpp @@ -19,6 +19,8 @@ */ #include "cipher.h" + +#include "code.h" #include "gpgcrypto.h" #include "aescrypto.h" @@ -37,7 +39,7 @@ void Cipher::init() { std::shared_ptr Cipher::get(const std::vector& cipher_text, const std::string& pin="") { if (GPG::isGPGencrypted(cipher_text)) return std::make_shared(); - else if (pin.size() == AES::PIN_WITH_PASS_LEN) + else if (pin.size() == code::PIN_WITH_PASS_LEN) return std::make_shared(); return {}; } diff --git a/src/code.h b/src/code.h new file mode 100644 index 0000000..2a5ac5a --- /dev/null +++ b/src/code.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2020 Simon Désaulniers + * Author: Simon Désaulniers + * + * This file is part of dpaste. + * + * dpaste is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * dpaste is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dpaste. If not, see . + */ + +#pragma once + +#include + +namespace dpaste { +namespace code { + +/** + * Number of bytes in a dpaste code accounting for the number of packets the + * file was split into + */ +static const constexpr unsigned int DPASTE_NPACKETS_LEN {2}; +/** + * Number of bytes in a dpaste code accounting for the location PIN. */ +static const constexpr unsigned int DPASTE_PIN_LEN {8}; + +/** + * Number of bytes used to encode the AES password. + */ +static const constexpr size_t PASSWORD_LEN {8}; + +/** + * Length of the PIN if it contains the password for encrypted pasted data. + * It consists of 18 hexadecimal characters: 18*4 = 72 bits. Last 32 bits + * encode the password. Otherwise, PIN should be 40 bits. + */ +static const constexpr size_t PIN_WITH_PASS_LEN {DPASTE_PIN_LEN + DPASTE_NPACKETS_LEN + PASSWORD_LEN}; + +} +} /* dpaste */ + +/* vim: set sts=4 ts=4 sw=4 tw=120 et :*/ + From d4f19a6d4de59264a6cbc2e2a59fa8386fec8bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 21:58:50 -0400 Subject: [PATCH 06/19] tests/bin: [/] (encrypted) paste test functions These verification tests will be applied multiple times, so it is better to put them in functions. --- tests/bin.cpp | 52 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/tests/bin.cpp b/tests/bin.cpp index 5132509..88aba68 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -22,6 +22,7 @@ #include +#include "code.h" #include "tests.h" #include "bin.h" @@ -31,12 +32,12 @@ namespace tests { class PirateBinTester { #define YARRRRR public: - static const constexpr unsigned int LOCATION_CODE_LEN = 8; - static const constexpr char* DPASTE_URI_PREFIX = "dpaste:"; PirateBinTester () {} virtual ~PirateBinTester () {} + static std::string dpaste_uri_prefix() { return Bin::DPASTE_URI_PREFIX; } + std::string code_from_dpaste_uri(const std::string& uri) const { return Bin::code_from_dpaste_uri(uri); } @@ -46,32 +47,41 @@ class PirateBinTester { } }; -TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { +void test_paste(Bin& bin, const std::vector& data) { + using pbt = PirateBinTester; + auto code = bin.paste(std::vector {data}, {}); + REQUIRE ( code.size() == pbt::dpaste_uri_prefix().size()+code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN ); + + SECTION ( "getting pasted blob back from the DHT" ) { + auto rd = bin.get(std::move(code)).second; + std::vector rdv {rd.begin(), rd.end()}; + REQUIRE ( data == rdv ); + } +} + +void test_paste_encrypted(Bin& bin, const std::vector& data) { using pbt = PirateBinTester; + auto p = std::make_unique(); + p->emplace(); + auto code = bin.paste(std::vector {data}, std::move(p)); + REQUIRE ( code.size() == pbt::dpaste_uri_prefix().size()+code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN+code::PASSWORD_LEN ); + + SECTION ( "getting pasted AES encrypted blob back from the DHT" ) { + auto rd = bin.get(std::move(code)).second; + std::vector rdv {rd.begin(), rd.end()}; + REQUIRE ( data == rdv ); + } +} + +TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { std::vector data = {0, 1, 2, 3, 4}; Bin bin {}; crypto::Cipher::init(); SECTION ( "pasting data {0,1,2,3,4}" ) { - auto code = bin.paste(std::vector {data}, {}); - REQUIRE ( code.size() == pbt::LOCATION_CODE_LEN+sizeof(pbt::DPASTE_URI_PREFIX)-1 ); - - SECTION ( "getting pasted blob back from the DHT" ) { - auto rd = bin.get(std::move(code)).second; - std::vector rdv {rd.begin(), rd.end()}; - REQUIRE ( data == rdv ); - } + test_paste(bin, data); } SECTION ( "pasting AES encrypted {0,1,2,3,4}" ) { - auto p = std::make_unique(); - p->emplace(); - auto code = bin.paste(std::vector {data}, std::move(p)); - REQUIRE ( code.size() == 2*pbt::LOCATION_CODE_LEN+sizeof(pbt::DPASTE_URI_PREFIX)-1 ); - - SECTION ( "getting pasted AES encrypted blob back from the DHT" ) { - auto rd = bin.get(std::move(code)).second; - std::vector rdv {rd.begin(), rd.end()}; - REQUIRE ( data == rdv ); - } + test_paste_encrypted(bin, data); } } From ffbf13e9086f5f379bb1348c669e310c3ddb6400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 22:01:06 -0400 Subject: [PATCH 07/19] tests/bin: [+] paste data of size > 64 KiB --- tests/bin.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/bin.cpp b/tests/bin.cpp index 88aba68..9ea7345 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -83,6 +83,22 @@ TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { SECTION ( "pasting AES encrypted {0,1,2,3,4}" ) { test_paste_encrypted(bin, data); } + SECTION ( "pasting data (size over 64KB)" ) { + std::array sizes = {32 * 1024, 64 * 1024, 512 * 1024}; + for (const auto& s : sizes) { + std::stringstream ss; + ss << s; + SECTION ( "trying for size of " + ss.str() + "B" ) { + std::vector buffer(s); + SECTION ( "plain data" ) { + test_paste(bin, buffer); + } + SECTION ( "AES encrypted data" ) { + test_paste_encrypted(bin, buffer); + } + } + } + } } TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { From e3bb53285df25706a71cb9965304b95a3a487580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 22:31:14 -0400 Subject: [PATCH 08/19] tests: [/] use CATCH_ prefix for all macros This prevents conflict with OpenDHT where the word WARN from enable_log.h would be substituted by the brutal usage of macros by Catch2. The usage of the special macro definition CATCH_CONFIG_PREFIX_ALL helps going around this issue. --- tests/aes.cpp | 10 ++++----- tests/bin.cpp | 61 +++++++++++++++++++++++++------------------------- tests/catch.h | 28 +++++++++++++++++++++++ tests/conf.cpp | 26 ++++++++++----------- tests/node.cpp | 14 ++++++------ 5 files changed, 84 insertions(+), 55 deletions(-) create mode 100644 tests/catch.h diff --git a/tests/aes.cpp b/tests/aes.cpp index 244e33b..3ca95da 100644 --- a/tests/aes.cpp +++ b/tests/aes.cpp @@ -20,15 +20,15 @@ #include -#include - #include "cipher.h" #include "aescrypto.h" +#include "catch.h" + namespace dpaste { namespace tests { -TEST_CASE("AES process plain/cipher text", "[AES][processPlainText][processCipherText]") { +CATCH_TEST_CASE("AES process plain/cipher text", "[AES][processPlainText][processCipherText]") { crypto::AES aes {}; std::vector data {0,1,2,3,4}; auto pwd = "this_is_a_really_good_pwd"; @@ -37,10 +37,10 @@ TEST_CASE("AES process plain/cipher text", "[AES][processPlainText][processCiphe p->emplace(pwd); auto ct = aes.processPlainText(data, std::move(p)); - REQUIRE ( not ct.empty() ); + CATCH_REQUIRE ( not ct.empty() ); auto pt = aes.processCipherText(ct, std::move(pp)); - REQUIRE ( pt == data ); + CATCH_REQUIRE ( pt == data ); } } /* tests */ diff --git a/tests/bin.cpp b/tests/bin.cpp index 9ea7345..4e511c8 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -20,12 +20,12 @@ #include -#include - #include "code.h" #include "tests.h" #include "bin.h" +#include "catch.h" + namespace dpaste { namespace tests { @@ -50,12 +50,12 @@ class PirateBinTester { void test_paste(Bin& bin, const std::vector& data) { using pbt = PirateBinTester; auto code = bin.paste(std::vector {data}, {}); - REQUIRE ( code.size() == pbt::dpaste_uri_prefix().size()+code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN ); + CATCH_REQUIRE ( code.size() == pbt::dpaste_uri_prefix().size()+code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN ); - SECTION ( "getting pasted blob back from the DHT" ) { + CATCH_SECTION ( "getting pasted blob back from the DHT" ) { auto rd = bin.get(std::move(code)).second; std::vector rdv {rd.begin(), rd.end()}; - REQUIRE ( data == rdv ); + CATCH_REQUIRE ( data == rdv ); } } @@ -64,36 +64,36 @@ void test_paste_encrypted(Bin& bin, const std::vector& data) { auto p = std::make_unique(); p->emplace(); auto code = bin.paste(std::vector {data}, std::move(p)); - REQUIRE ( code.size() == pbt::dpaste_uri_prefix().size()+code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN+code::PASSWORD_LEN ); + CATCH_REQUIRE ( code.size() == pbt::dpaste_uri_prefix().size()+code::DPASTE_PIN_LEN+code::DPASTE_NPACKETS_LEN+code::PASSWORD_LEN ); - SECTION ( "getting pasted AES encrypted blob back from the DHT" ) { + CATCH_SECTION ( "getting pasted AES encrypted blob back from the DHT" ) { auto rd = bin.get(std::move(code)).second; std::vector rdv {rd.begin(), rd.end()}; - REQUIRE ( data == rdv ); + CATCH_REQUIRE ( data == rdv ); } } -TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { +CATCH_TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { std::vector data = {0, 1, 2, 3, 4}; Bin bin {}; crypto::Cipher::init(); - SECTION ( "pasting data {0,1,2,3,4}" ) { + CATCH_SECTION ( "pasting data {0,1,2,3,4}" ) { test_paste(bin, data); } - SECTION ( "pasting AES encrypted {0,1,2,3,4}" ) { + CATCH_SECTION ( "pasting AES encrypted {0,1,2,3,4}" ) { test_paste_encrypted(bin, data); } - SECTION ( "pasting data (size over 64KB)" ) { + CATCH_SECTION ( "pasting data (size over 64KB)" ) { std::array sizes = {32 * 1024, 64 * 1024, 512 * 1024}; for (const auto& s : sizes) { std::stringstream ss; ss << s; - SECTION ( "trying for size of " + ss.str() + "B" ) { + CATCH_SECTION ( "trying for size of " + ss.str() + "B" ) { std::vector buffer(s); - SECTION ( "plain data" ) { + CATCH_SECTION ( "plain data" ) { test_paste(bin, buffer); } - SECTION ( "AES encrypted data" ) { + CATCH_SECTION ( "AES encrypted data" ) { test_paste_encrypted(bin, buffer); } } @@ -101,49 +101,50 @@ TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { } } -TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { +CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { PirateBinTester pt; const std::string CODE = random_code(); std::string pin_upper {CODE.begin(), CODE.end()}; std::transform(pin_upper.begin(), pin_upper.end(), pin_upper.begin(), ::toupper); - SECTION ( "good pins" ) { + CATCH_SECTION ( "good pins" ) { auto gc1 = "dpaste:"+CODE; auto gc2 = CODE; - REQUIRE ( pt.code_from_dpaste_uri(gc1) == CODE ); - REQUIRE ( pt.code_from_dpaste_uri(gc2) == CODE ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc1) == CODE ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc2) == CODE ); - SECTION ( "good pin (upper case)" ) { + CATCH_SECTION ( "good pin (upper case)" ) { auto gc3 = "dpaste:"+pin_upper; auto gc4 = pin_upper; - REQUIRE ( pt.code_from_dpaste_uri(gc3) == pin_upper ); - REQUIRE ( pt.code_from_dpaste_uri(gc4) == pin_upper ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc3) == pin_upper ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc4) == pin_upper ); } } - SECTION ( "bad pins" ) { + CATCH_SECTION ( "bad pins" ) { std::string bc1 = "DPASTE:"+CODE; std::string bc2 = "DPaste:"+CODE; - REQUIRE ( pt.code_from_dpaste_uri(bc1) != CODE ); - REQUIRE ( pt.code_from_dpaste_uri(bc2) != CODE ); + std::string gc3 = "dpaste:" + CODE + std::string {10}; + CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc1) != CODE ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc2) != CODE ); - SECTION ( "bad pins (upper case)" ) { + CATCH_SECTION ( "bad pins (upper case)" ) { auto bc3 = "DPASTE:"+pin_upper; auto bc4 = "DPaste:"+pin_upper; - REQUIRE ( pt.code_from_dpaste_uri(bc3) != pin_upper ); - REQUIRE ( pt.code_from_dpaste_uri(bc4) != pin_upper ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc3) != pin_upper ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc4) != pin_upper ); } } } -TEST_CASE("Bin conversion of stringstream to vector", "[Bin][data_from_stream]") { +CATCH_TEST_CASE("Bin conversion of stringstream to vector", "[Bin][data_from_stream]") { PirateBinTester pt; const std::string DATA = "SOME DATA"; std::stringstream ss(DATA); std::vector d {DATA.begin(), DATA.end()}; - REQUIRE ( pt.data_from_stream(ss, DATA.size()) == d ); + CATCH_REQUIRE ( pt.data_from_stream(ss, DATA.size()) == d ); } } /* tests */ diff --git a/tests/catch.h b/tests/catch.h new file mode 100644 index 0000000..45c0ccc --- /dev/null +++ b/tests/catch.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2020 Simon Désaulniers + * Author: Simon Désaulniers + * + * This file is part of dpaste. + * + * dpaste is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * dpaste is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dpaste. If not, see . + */ + +#pragma once + +#define CATCH_CONFIG_PREFIX_ALL 0 + +#include + +/* vim: set sts=4 ts=4 sw=4 tw=120 et :*/ + diff --git a/tests/conf.cpp b/tests/conf.cpp index 20ab1ef..943ecab 100644 --- a/tests/conf.cpp +++ b/tests/conf.cpp @@ -18,37 +18,37 @@ * along with dpaste. If not, see . */ -#include - #include "conf.h" +#include "catch.h" + namespace dpaste { namespace tests { const std::string CONFIG_FILE_PATH_PREFIX = "./tests/misc/dpaste.conf"; -TEST_CASE("ConfigurationFile loading/parsing (./misc/dpaste.conf)", "[ConfigurationFile][get][load]") { - SECTION ( "Well-formed file" ) { +CATCH_TEST_CASE("ConfigurationFile loading/parsing (./misc/dpaste.conf)", "[ConfigurationFile][get][load]") { + CATCH_SECTION ( "Well-formed file" ) { conf::ConfigurationFile f(CONFIG_FILE_PATH_PREFIX+".1"); - REQUIRE ( f.load() == 0 ); + CATCH_REQUIRE ( f.load() == 0 ); auto c = f.getConfiguration(); - REQUIRE ( c.at("host") == "192.168.1.100" ); - REQUIRE ( c.at("port") == "6500" ); + CATCH_REQUIRE ( c.at("host") == "192.168.1.100" ); + CATCH_REQUIRE ( c.at("port") == "6500" ); } - SECTION ( "Malformed file (bad host)" ) { + CATCH_SECTION ( "Malformed file (bad host)" ) { conf::ConfigurationFile f(CONFIG_FILE_PATH_PREFIX+".2"); - REQUIRE ( f.load() == 0 ); + CATCH_REQUIRE ( f.load() == 0 ); auto c = f.getConfiguration(); - REQUIRE ( c.at("host") == "127.0.0.1" ); /* the default */ - REQUIRE ( c.at("port") == "6500" ); /* recovered from file */ + CATCH_REQUIRE ( c.at("host") == "127.0.0.1" ); /* the default */ + CATCH_REQUIRE ( c.at("port") == "6500" ); /* recovered from file */ } - SECTION ( "File not found" ) { + CATCH_SECTION ( "File not found" ) { conf::ConfigurationFile f("/dpaste.conf"); /* This should not work on any computer owned by a sane person */ - REQUIRE ( f.load() == 1 ); + CATCH_REQUIRE ( f.load() == 1 ); } } diff --git a/tests/node.cpp b/tests/node.cpp index fd7ea94..67a69c3 100644 --- a/tests/node.cpp +++ b/tests/node.cpp @@ -18,7 +18,7 @@ * along with dpaste. If not, see . */ -#include +#include "catch.h" #include "tests.h" #include "node.h" @@ -35,7 +35,7 @@ class PirateNodeTester { bool is_running(const dpaste::Node& n) const { return n.running_; } }; -TEST_CASE("Node get/paste on DHT", "[Node][get][paste]") { +CATCH_TEST_CASE("Node get/paste on DHT", "[Node][get][paste]") { PirateNodeTester pt; const std::string PIN = random_code(); @@ -43,17 +43,17 @@ TEST_CASE("Node get/paste on DHT", "[Node][get][paste]") { dpaste::Node node {}; node.run(); - SECTION ( "pasting data {0,1,2,3,4}" ) { - REQUIRE ( node.paste(PIN, std::vector {data}) ); + CATCH_SECTION ( "pasting data {0,1,2,3,4}" ) { + CATCH_REQUIRE ( node.paste(PIN, std::vector {data}) ); - SECTION ( "getting pasted blob back from the DHT" ) { + CATCH_SECTION ( "getting pasted blob back from the DHT" ) { auto rd = node.get(PIN); - REQUIRE ( data == rd.front() ); + CATCH_REQUIRE ( data == rd.front() ); } } node.stop(); - REQUIRE ( not pt.is_running(node) ); + CATCH_REQUIRE ( not pt.is_running(node) ); } } /* tests */ From 48363bbcd0ee57d0ad217390b52aeceab2aa3e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 1 Apr 2020 22:31:30 -0400 Subject: [PATCH 09/19] gitignore: [+] static *.a libraries --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c8dea6c..e9b416e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ Makefile.in *.l[ao] *~ *.pc +*.a # CMake dir build From ad5d9cd442a3dc3033187cb57248da187d3a7261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 20:35:33 -0400 Subject: [PATCH 10/19] tests/tests.h: [+] missing include --- tests/tests.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/tests.h b/tests/tests.h index c78e974..50e73d4 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -18,6 +18,8 @@ * along with dpaste. If not, see . */ +#include + namespace dpaste { namespace tests { From c9ce6b42e6f00574a34da9b6ec02ba422e88fa42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 21:54:11 -0400 Subject: [PATCH 11/19] tests/bin: [-] unused var in code_from_dpaste_uri --- tests/bin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/bin.cpp b/tests/bin.cpp index 4e511c8..dae284b 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -124,7 +124,6 @@ CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_ CATCH_SECTION ( "bad pins" ) { std::string bc1 = "DPASTE:"+CODE; std::string bc2 = "DPaste:"+CODE; - std::string gc3 = "dpaste:" + CODE + std::string {10}; CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc1) != CODE ); CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc2) != CODE ); From a4c1428dbde10fae8953087ff865959a97a58fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 21:56:48 -0400 Subject: [PATCH 12/19] tests/bin: code_from_dpaste_uri, also test with pwd --- tests/bin.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/bin.cpp b/tests/bin.cpp index dae284b..ebbc628 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -104,21 +104,26 @@ CATCH_TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { PirateBinTester pt; const std::string CODE = random_code(); + const std::string PWD = random_code(); std::string pin_upper {CODE.begin(), CODE.end()}; std::transform(pin_upper.begin(), pin_upper.end(), pin_upper.begin(), ::toupper); CATCH_SECTION ( "good pins" ) { auto gc1 = "dpaste:"+CODE; auto gc2 = CODE; + auto gc3 = "dpaste:"+CODE+PWD; CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc1) == CODE ); CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc2) == CODE ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc3) == CODE+PWD ); CATCH_SECTION ( "good pin (upper case)" ) { auto gc3 = "dpaste:"+pin_upper; auto gc4 = pin_upper; + auto gc6 = "dpaste:"+pin_upper+PWD; CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc3) == pin_upper ); CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc4) == pin_upper ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc6) == pin_upper+PWD ); } } CATCH_SECTION ( "bad pins" ) { From 72228d987f97893cb6e070bbf14d06e07b5b6f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 22:01:34 -0400 Subject: [PATCH 13/19] tests/bin: code_from_dpaste_uri, nb of packets Include the number of packets in the code when testing the code as per the new code format. --- tests/bin.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/bin.cpp b/tests/bin.cpp index ebbc628..159179e 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -38,6 +38,10 @@ class PirateBinTester { static std::string dpaste_uri_prefix() { return Bin::DPASTE_URI_PREFIX; } + static std::string hexStrFromInt(uint32_t i, size_t len) { + return Bin::hexStrFromInt(i, len); + } + std::string code_from_dpaste_uri(const std::string& uri) const { return Bin::code_from_dpaste_uri(uri); } @@ -103,7 +107,10 @@ CATCH_TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { PirateBinTester pt; - const std::string CODE = random_code(); + const uint32_t NPACKETS = (uint32_t)random_number() % 256; + const std::string NPACKETSS = pbt::hexStrFromInt(NPACKETS, 2); + const std::string LCODE = random_code(); + const std::string CODE = LCODE + NPACKETSS; const std::string PWD = random_code(); std::string pin_upper {CODE.begin(), CODE.end()}; std::transform(pin_upper.begin(), pin_upper.end(), pin_upper.begin(), ::toupper); From 461446113517aec1689664d260f8ab02dd97a76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 22:05:25 -0400 Subject: [PATCH 14/19] tests/bin: [+] test for parse_code_info Combine fields in a final code for Bin::parse_code_info to seperate and test if result is valid. --- tests/bin.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/bin.cpp b/tests/bin.cpp index 159179e..b2e17af 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -42,6 +42,10 @@ class PirateBinTester { return Bin::hexStrFromInt(i, len); } + static std::tuple parse_code_info(const std::string& uri) { + return Bin::parse_code_info(uri); + } + std::string code_from_dpaste_uri(const std::string& uri) const { return Bin::code_from_dpaste_uri(uri); } @@ -105,7 +109,8 @@ CATCH_TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { } } -CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri]") { +CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri][parse_code_info]") { + using pbt = PirateBinTester; PirateBinTester pt; const uint32_t NPACKETS = (uint32_t)random_number() % 256; const std::string NPACKETSS = pbt::hexStrFromInt(NPACKETS, 2); @@ -115,6 +120,14 @@ CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_ std::string pin_upper {CODE.begin(), CODE.end()}; std::transform(pin_upper.begin(), pin_upper.end(), pin_upper.begin(), ::toupper); + auto test_code_parsing = [&LCODE,&NPACKETS](const std::string& unparsed_code, const std::string& pwd) { + const auto code_tuple1 = pbt::parse_code_info(unparsed_code); + + CATCH_REQUIRE ( std::get<0>(code_tuple1) == LCODE ); + CATCH_REQUIRE ( std::get<1>(code_tuple1) == NPACKETS ); + CATCH_REQUIRE ( std::get<2>(code_tuple1) == pwd ); + }; + CATCH_SECTION ( "good pins" ) { auto gc1 = "dpaste:"+CODE; auto gc2 = CODE; @@ -124,14 +137,20 @@ CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_ CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc3) == CODE+PWD ); CATCH_SECTION ( "good pin (upper case)" ) { - auto gc3 = "dpaste:"+pin_upper; - auto gc4 = pin_upper; + auto gc4 = "dpaste:"+pin_upper; + auto gc5 = pin_upper; auto gc6 = "dpaste:"+pin_upper+PWD; - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc3) == pin_upper ); CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc4) == pin_upper ); + CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc5) == pin_upper ); CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc6) == pin_upper+PWD ); } + CATCH_SECTION ( "testing Bin::parse_code_info" ) { + test_code_parsing(CODE, ""); + } + CATCH_SECTION ( "testing Bin::parse_code_info with password" ) { + test_code_parsing(CODE+PWD, PWD); + } } CATCH_SECTION ( "bad pins" ) { std::string bc1 = "DPASTE:"+CODE; From c1ef304229a85867bd44a62d230712a4c8fd3603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 22:10:13 -0400 Subject: [PATCH 15/19] tests/bin: [/] static code_from_dpaste_uri wrapper Bin::code_from_dpaste_uri has always been static. So should PirateBinTester::code_from_dpaste_uri. --- tests/bin.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/bin.cpp b/tests/bin.cpp index b2e17af..fdaf10e 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -46,7 +46,7 @@ class PirateBinTester { return Bin::parse_code_info(uri); } - std::string code_from_dpaste_uri(const std::string& uri) const { + static std::string code_from_dpaste_uri(const std::string& uri) { return Bin::code_from_dpaste_uri(uri); } @@ -111,7 +111,6 @@ CATCH_TEST_CASE("Bin get/paste on DHT", "[Bin][get][paste]") { CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_dpaste_uri][parse_code_info]") { using pbt = PirateBinTester; - PirateBinTester pt; const uint32_t NPACKETS = (uint32_t)random_number() % 256; const std::string NPACKETSS = pbt::hexStrFromInt(NPACKETS, 2); const std::string LCODE = random_code(); @@ -132,18 +131,18 @@ CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_ auto gc1 = "dpaste:"+CODE; auto gc2 = CODE; auto gc3 = "dpaste:"+CODE+PWD; - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc1) == CODE ); - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc2) == CODE ); - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc3) == CODE+PWD ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(gc1) == CODE ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(gc2) == CODE ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(gc3) == CODE+PWD ); CATCH_SECTION ( "good pin (upper case)" ) { auto gc4 = "dpaste:"+pin_upper; auto gc5 = pin_upper; auto gc6 = "dpaste:"+pin_upper+PWD; - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc4) == pin_upper ); - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc5) == pin_upper ); - CATCH_REQUIRE ( pt.code_from_dpaste_uri(gc6) == pin_upper+PWD ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(gc4) == pin_upper ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(gc5) == pin_upper ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(gc6) == pin_upper+PWD ); } CATCH_SECTION ( "testing Bin::parse_code_info" ) { test_code_parsing(CODE, ""); @@ -155,15 +154,15 @@ CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_ CATCH_SECTION ( "bad pins" ) { std::string bc1 = "DPASTE:"+CODE; std::string bc2 = "DPaste:"+CODE; - CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc1) != CODE ); - CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc2) != CODE ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(bc1) != CODE ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(bc2) != CODE ); CATCH_SECTION ( "bad pins (upper case)" ) { auto bc3 = "DPASTE:"+pin_upper; auto bc4 = "DPaste:"+pin_upper; - CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc3) != pin_upper ); - CATCH_REQUIRE ( pt.code_from_dpaste_uri(bc4) != pin_upper ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(bc3) != pin_upper ); + CATCH_REQUIRE ( pbt::code_from_dpaste_uri(bc4) != pin_upper ); } } } From 565944e364c859b995387e2f2c2ecbd06f0d6602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 10 May 2020 22:58:07 -0400 Subject: [PATCH 16/19] tests/bin: [+] hexStrFromInt --- tests/bin.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/bin.cpp b/tests/bin.cpp index fdaf10e..6a0ddb5 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -167,6 +167,14 @@ CATCH_TEST_CASE("Bin parsing of uri code ([dpaste:]XXXXXXXX)", "[Bin][code_from_ } } +CATCH_TEST_CASE("Bin conversion to hex string from int", "[Bin][hexStrFromInt]") { + using pbt = PirateBinTester; + CATCH_REQUIRE ( pbt::hexStrFromInt(255, 2) == "ff" ); + CATCH_REQUIRE ( pbt::hexStrFromInt(121, 2) == "79" ); + CATCH_REQUIRE ( pbt::hexStrFromInt(0, 2) == "00" ); +} + + CATCH_TEST_CASE("Bin conversion of stringstream to vector", "[Bin][data_from_stream]") { PirateBinTester pt; From 9d7b2e8a2a9f1c199472a362cc8f64f620efd76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Mon, 11 May 2020 01:08:51 -0400 Subject: [PATCH 17/19] main: [/] specify max size of 2MB in help string --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 32a3552..192f42e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -102,7 +102,7 @@ ParsedArgs parseArgs(int argc, char *argv[]) { } void print_help() { - std::cout << PACKAGE_NAME << " -- A simple pastebin for light values (max 64KB)" + std::cout << PACKAGE_NAME << " -- A simple pastebin (for values of size up to 2MB)" << " using OpenDHT distributed hash table." << std::endl << std::endl; std::cout << "SYNOPSIS" << std::endl From 4127478294c0d8fe652b96ed94c4d87e26d9fdee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Mon, 11 May 2020 01:16:10 -0400 Subject: [PATCH 18/19] src, tests: update copyright 201[78]-2020 --- src/aescrypto.cpp | 2 +- src/aescrypto.h | 2 +- src/bin.cpp | 2 +- src/bin.h | 2 +- src/cipher.cpp | 2 +- src/cipher.h | 2 +- src/conf.cpp | 2 +- src/conf.h | 2 +- src/gpgcrypto.cpp | 2 +- src/gpgcrypto.h | 2 +- src/http_client.cpp | 2 +- src/http_client.h | 2 +- src/log.cpp | 2 +- src/log.h | 2 +- src/main.cpp | 2 +- src/node.cpp | 2 +- src/node.h | 2 +- tests/aes.cpp | 2 +- tests/bin.cpp | 2 +- tests/conf.cpp | 2 +- tests/node.cpp | 2 +- tests/tests.cpp | 2 +- tests/tests.h | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/aescrypto.cpp b/src/aescrypto.cpp index c859be9..24bf187 100644 --- a/src/aescrypto.cpp +++ b/src/aescrypto.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/aescrypto.h b/src/aescrypto.h index 58930bd..065618e 100644 --- a/src/aescrypto.h +++ b/src/aescrypto.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/bin.cpp b/src/bin.cpp index 2e48ec2..d80a8b2 100644 --- a/src/bin.cpp +++ b/src/bin.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/bin.h b/src/bin.h index 5f8429a..44ab827 100644 --- a/src/bin.h +++ b/src/bin.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/cipher.cpp b/src/cipher.cpp index 0205483..99d125c 100644 --- a/src/cipher.cpp +++ b/src/cipher.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/cipher.h b/src/cipher.h index 1ee0fe6..e6f6905 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/conf.cpp b/src/conf.cpp index 1a31f90..6a22b75 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/conf.h b/src/conf.h index 68edde7..d92144a 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/gpgcrypto.cpp b/src/gpgcrypto.cpp index 23bfd9d..ed54472 100644 --- a/src/gpgcrypto.cpp +++ b/src/gpgcrypto.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/gpgcrypto.h b/src/gpgcrypto.h index 99865d5..45cfbf4 100644 --- a/src/gpgcrypto.h +++ b/src/gpgcrypto.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/http_client.cpp b/src/http_client.cpp index 59828d9..16bfbfe 100644 --- a/src/http_client.cpp +++ b/src/http_client.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/http_client.h b/src/http_client.h index 028cec5..ac9e69d 100644 --- a/src/http_client.h +++ b/src/http_client.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/log.cpp b/src/log.cpp index ce93ebd..b8259e8 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/log.h b/src/log.h index b78042b..4c7f943 100644 --- a/src/log.h +++ b/src/log.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/main.cpp b/src/main.cpp index 192f42e..acdebe0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/node.cpp b/src/node.cpp index d6b084b..41950c3 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/src/node.h b/src/node.h index bce8a53..c803a36 100644 --- a/src/node.h +++ b/src/node.h @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Simon Désaulniers + * Copyright © 2017-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/tests/aes.cpp b/tests/aes.cpp index 3ca95da..343d649 100644 --- a/tests/aes.cpp +++ b/tests/aes.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Simon Désaulniers + * Copyright © 2018-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/tests/bin.cpp b/tests/bin.cpp index 6a0ddb5..dd382e7 100644 --- a/tests/bin.cpp +++ b/tests/bin.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Simon Désaulniers + * Copyright © 2018-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/tests/conf.cpp b/tests/conf.cpp index 943ecab..6731cb7 100644 --- a/tests/conf.cpp +++ b/tests/conf.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Simon Désaulniers + * Copyright © 2018-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/tests/node.cpp b/tests/node.cpp index 67a69c3..fb9982f 100644 --- a/tests/node.cpp +++ b/tests/node.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Simon Désaulniers + * Copyright © 2018-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/tests/tests.cpp b/tests/tests.cpp index 40632bd..ddb800c 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Simon Désaulniers + * Copyright © 2018-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. diff --git a/tests/tests.h b/tests/tests.h index 50e73d4..1052a91 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Simon Désaulniers + * Copyright © 2018-2020 Simon Désaulniers * Author: Simon Désaulniers * * This file is part of dpaste. From 2ab7cf095ac733017459e1592685641d0b776b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Sun, 3 Nov 2024 14:39:56 -0500 Subject: [PATCH 19/19] main: max size for value in MiB --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index acdebe0..786ad39 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -102,7 +102,7 @@ ParsedArgs parseArgs(int argc, char *argv[]) { } void print_help() { - std::cout << PACKAGE_NAME << " -- A simple pastebin (for values of size up to 2MB)" + std::cout << PACKAGE_NAME << " -- A simple pastebin (for values of size up to 2MiB)" << " using OpenDHT distributed hash table." << std::endl << std::endl; std::cout << "SYNOPSIS" << std::endl