diff --git a/openvpn/addr/ipv4.hpp b/openvpn/addr/ipv4.hpp index a31c32d1..b762d314 100644 --- a/openvpn/addr/ipv4.hpp +++ b/openvpn/addr/ipv4.hpp @@ -274,7 +274,7 @@ class Addr // NOTE: must be union-legal, so default constructor does not initial const int bl = parse_hex_char(s[idx + 1]); if (bh == -1 || bl == -1) throw ipv4_exception("parse hex error"); - ret.u.bytes[Endian::e4(di--)] = (bh << 4) + bl; + ret.u.bytes[Endian::e4(di--)] = static_cast((bh << 4) + bl); } return ret; } @@ -289,7 +289,7 @@ class Addr // NOTE: must be union-legal, so default constructor does not initial const unsigned char b = u.bytes[Endian::e4rev(i)]; if (b || firstnonzero || i == 3) { - const char bh = b >> 4; + const char bh = static_cast(b >> 4); if (bh || firstnonzero) ret += render_hex_char(bh); ret += render_hex_char(b & 0x0F); diff --git a/openvpn/addr/ipv6.hpp b/openvpn/addr/ipv6.hpp index bb6ce906..63c23fb1 100644 --- a/openvpn/addr/ipv6.hpp +++ b/openvpn/addr/ipv6.hpp @@ -176,7 +176,7 @@ class Addr // NOTE: must be union-legal, so default constructor does not initial const int bl = parse_hex_char(s[idx + 1]); if (bh == -1 || bl == -1) throw ipv6_exception("parse hex error"); - ret.u.bytes[Endian::e16(di--)] = (bh << 4) + bl; + ret.u.bytes[Endian::e16(di--)] = static_cast((bh << 4) + bl); } return ret; } @@ -191,7 +191,7 @@ class Addr // NOTE: must be union-legal, so default constructor does not initial const unsigned char b = u.bytes[Endian::e16rev(i)]; if (b || firstnonzero || i == 15) { - const char bh = b >> 4; + const char bh = static_cast(b >> 4); if (bh || firstnonzero) ret += render_hex_char(bh); ret += render_hex_char(b & 0x0F); diff --git a/openvpn/buffer/buffmt.hpp b/openvpn/buffer/buffmt.hpp index 011d1154..1aa806bc 100644 --- a/openvpn/buffer/buffmt.hpp +++ b/openvpn/buffer/buffmt.hpp @@ -68,7 +68,7 @@ class UnsignedDecimal T d = value_ / T(10); T r = value_ % T(10); value_ = d; - return '0' + r; + return static_cast('0' + r); } bool is_zero() const diff --git a/openvpn/buffer/lz4.hpp b/openvpn/buffer/lz4.hpp index b0adecee..d3f0f8d6 100644 --- a/openvpn/buffer/lz4.hpp +++ b/openvpn/buffer/lz4.hpp @@ -25,12 +25,15 @@ #include +#include #include #include // for ntohl/htonl #include -namespace openvpn { -namespace LZ4 { +using openvpn::numeric_util::clamp_to_typerange; + +namespace openvpn::LZ4 { + OPENVPN_EXCEPTION(lz4_error); inline BufferPtr compress(const ConstBuffer &src, @@ -47,7 +50,7 @@ inline BufferPtr compress(const ConstBuffer &src, // as a hint to receiver, write the decompressed size { - const std::uint32_t size = htonl(src.size()); + const std::uint32_t size = htonl(clamp_to_typerange(src.size())); dest->write(&size, sizeof(size)); } @@ -96,5 +99,4 @@ inline BufferPtr decompress(const ConstBuffer &source, return dest; } -} // namespace LZ4 -} // namespace openvpn +} // namespace openvpn::LZ4 diff --git a/openvpn/buffer/zlib.hpp b/openvpn/buffer/zlib.hpp index 502a03f4..f0e43238 100644 --- a/openvpn/buffer/zlib.hpp +++ b/openvpn/buffer/zlib.hpp @@ -28,11 +28,17 @@ #include +#include #include +#include #include #include + namespace openvpn { + +using namespace numeric_util; + namespace ZLib { OPENVPN_EXCEPTION(zlib_error); @@ -74,7 +80,7 @@ inline BufferPtr compress_gzip(BufferPtr src, int status; ZStream zs; zs.s.next_in = src->data(); - zs.s.avail_in = src->size(); + zs.s.avail_in = numeric_cast(src->size()); status = ::deflateInit2(&zs.s, level, Z_DEFLATED, @@ -87,7 +93,7 @@ inline BufferPtr compress_gzip(BufferPtr src, BufferPtr b = new BufferAllocated(outcap + headroom + tailroom, 0); b->init_headroom(headroom); zs.s.next_out = b->data(); - zs.s.avail_out = outcap; + zs.s.avail_out = numeric_cast(outcap); status = ::deflate(&zs.s, Z_FINISH); if (status != Z_STREAM_END) OPENVPN_THROW(zlib_error, "zlib deflate failed, error=" << status); @@ -120,7 +126,7 @@ inline BufferPtr decompress_gzip(BufferPtr src, int status; ZStream zs; zs.s.next_in = src->data(); - zs.s.avail_in = src->size(); + zs.s.avail_in = numeric_cast(src->size()); status = ::inflateInit2(&zs.s, GZIP_ENCODING + window_bits); if (status != Z_OK) OPENVPN_THROW(zlib_error, "zlib inflateinit2 failed, error=" << status); @@ -136,7 +142,7 @@ inline BufferPtr decompress_gzip(BufferPtr src, b->init_headroom(hr); const size_t avail = b->remaining(tr); zs.s.next_out = b->data(); - zs.s.avail_out = avail; + zs.s.avail_out = clamp_to_typerange(avail); status = ::inflate(&zs.s, Z_SYNC_FLUSH); if (status != Z_OK && status != Z_STREAM_END) OPENVPN_THROW(zlib_error, "zlib inflate failed, error=" << status); diff --git a/openvpn/client/cliproto.hpp b/openvpn/client/cliproto.hpp index 4d0c18f5..e7987cd0 100644 --- a/openvpn/client/cliproto.hpp +++ b/openvpn/client/cliproto.hpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -73,8 +74,9 @@ #define OPENVPN_LOG_CLIPROTO(x) #endif -namespace openvpn { -namespace ClientProto { +using openvpn::numeric_util::clamp_to_typerange; + +namespace openvpn::ClientProto { struct NotifyCallback { @@ -416,10 +418,12 @@ class Session : ProtoContext, const ProtoContext::Config &c = Base::conf(); // when calculating mss, we take IPv4 and TCP headers into account // here we need to add it back since we check the whole IP packet size, not just TCP payload - size_t mss_no_tcp_ip_encap = (size_t)c.mss_fix + (20 + 20); + constexpr size_t MinTcpHeader = 20; + constexpr size_t MinIpHeader = 20; + size_t mss_no_tcp_ip_encap = c.mss_fix + (MinTcpHeader + MinIpHeader); if (c.mss_fix > 0 && buf.size() > mss_no_tcp_ip_encap) { - Ptb::generate_icmp_ptb(buf, mss_no_tcp_ip_encap); + Ptb::generate_icmp_ptb(buf, clamp_to_typerange(mss_no_tcp_ip_encap)); tun->tun_send(buf); } else @@ -852,7 +856,7 @@ class Session : ProtoContext, { try { - timeout = std::stoul(timeout_str); + timeout = clamp_to_typerange(std::stoul(timeout_str)); // Cap the timeout to end well before renegotiation starts timeout = std::min(timeout, static_cast(conf().renegotiate.to_seconds() / 2)); } @@ -1374,7 +1378,6 @@ class Session : ProtoContext, std::ofstream packet_log; #endif }; -} // namespace ClientProto -} // namespace openvpn +} // namespace openvpn::ClientProto #endif diff --git a/openvpn/client/remotelist.hpp b/openvpn/client/remotelist.hpp index 80b9e5c5..c71e39a7 100644 --- a/openvpn/client/remotelist.hpp +++ b/openvpn/client/remotelist.hpp @@ -194,7 +194,7 @@ class RemoteList : public RC if (res_addr_list && index < res_addr_list->size()) { endpoint.address((*res_addr_list)[index]->addr.to_asio()); - endpoint.port(parse_number_throw(server_port, "remote_port")); + endpoint.port(parse_number_throw(server_port, "remote_port")); OPENVPN_LOG_REMOTELIST("*** RemoteList::Item endpoint GET[" << index << "] " << endpoint << ' ' << to_string()); return true; } diff --git a/openvpn/common/base64.hpp b/openvpn/common/base64.hpp index 20dac5b1..bf9f83c4 100644 --- a/openvpn/common/base64.hpp +++ b/openvpn/common/base64.hpp @@ -41,7 +41,10 @@ class Base64 class ConstUCharWrap { public: - ConstUCharWrap(const unsigned char *data, size_t size) + using value_type = unsigned char; + + public: + ConstUCharWrap(const value_type *data, size_t size) : data_(data), size_(size) { @@ -51,14 +54,14 @@ class Base64 { return size_; } - unsigned char operator[](const size_t i) const + value_type operator[](const size_t i) const { return data_[i]; } private: - const unsigned char *data_; + const value_type *data_; size_t size_; }; @@ -70,12 +73,15 @@ class Base64 class UCharWrap { public: - UCharWrap(unsigned char *data, size_t size) + using value_type = unsigned char; + + public: + UCharWrap(value_type *data, size_t size) : data(data), size(size), index(0) { } - void push_back(unsigned char c) + void push_back(value_type c) { if (index >= size) throw base64_decode_out_of_bound_error(); @@ -83,7 +89,7 @@ class Base64 data[index++] = c; } - unsigned char *data; + value_type *data; size_t size; size_t index; }; @@ -99,7 +105,7 @@ class Base64 // build encoding map { unsigned int i; - unsigned int j = 65; + unsigned char j = 65; for (i = 0; i < 62; ++i) { enc[i] = j++; @@ -209,13 +215,14 @@ class Base64 const char *endp = str.c_str() + str.length(); for (const char *p = str.c_str(); p < endp; p += 4) { + using vvalue_t = typename V::value_type; unsigned int marker; const unsigned int val = token_decode(p, std::min(endp - p, ptrdiff_t(4)), marker); - dest.push_back((val >> 16) & 0xff); + dest.push_back(static_cast((val >> 16) & 0xff)); if (marker < 2) - dest.push_back((val >> 8) & 0xff); + dest.push_back(static_cast((val >> 8) & 0xff)); if (marker < 1) - dest.push_back(val & 0xff); + dest.push_back(static_cast(val & 0xff)); } } diff --git a/openvpn/common/core.hpp b/openvpn/common/core.hpp index 2d12b66b..113ef4bd 100644 --- a/openvpn/common/core.hpp +++ b/openvpn/common/core.hpp @@ -56,7 +56,7 @@ inline int n_cores() long ret = ::sysconf(_SC_NPROCESSORS_ONLN); if (ret <= 0) ret = 1; - return ret; + return static_cast(ret); #elif defined(OPENVPN_PLATFORM_WIN) SYSTEM_INFO si; ::GetSystemInfo(&si); diff --git a/openvpn/common/environ.hpp b/openvpn/common/environ.hpp index 09622e3a..970e6f82 100644 --- a/openvpn/common/environ.hpp +++ b/openvpn/common/environ.hpp @@ -81,12 +81,12 @@ class Environ : public std::vector if (pos != std::string::npos) { if (name == s.substr(0, pos)) - return i; + return static_cast(i); // TODO: [OVPN3-928] Evaluate the safety of casting this down } else { if (name == s) - return i; + return static_cast(i); // Same as above } } return -1; diff --git a/openvpn/common/hexstr.hpp b/openvpn/common/hexstr.hpp index 43a3fc62..e732821e 100644 --- a/openvpn/common/hexstr.hpp +++ b/openvpn/common/hexstr.hpp @@ -27,10 +27,14 @@ #include #include #include +#include +#include #include #include +using namespace openvpn::numeric_util; + namespace openvpn { /** @@ -47,6 +51,8 @@ namespace openvpn { */ inline char render_hex_char(const int c, const bool caps = false) { + if (c < 0) + return '?'; if (c < 10) return '0' + c; else if (c < 16) @@ -55,7 +61,6 @@ inline char render_hex_char(const int c, const bool caps = false) return '?'; } - /** * Parses a character in the range {0..9,A-F,a-f} to an * integer value. Used to convert hexadecimal character to integer. @@ -284,7 +289,7 @@ inline std::string dump_hex(const unsigned char *data, size_t size) chars += '.'; } if (i) - os << string::spaces(2 + (((i - 1) & mask) ^ mask) * 3) << chars << std::endl; + os << string::spaces(clamp_to_typerange(2 + (((i - 1) & mask) ^ mask) * 3)) << chars << std::endl; return os.str(); } @@ -356,6 +361,7 @@ OPENVPN_SIMPLE_EXCEPTION(parse_hex_error); template inline void parse_hex(V &dest, const std::string &str) { + using vvalue_t = typename V::value_type; const int len = int(str.length()); int i; for (i = 0; i <= len - 2; i += 2) @@ -364,7 +370,7 @@ inline void parse_hex(V &dest, const std::string &str) const int low = parse_hex_char(str[i + 1]); if (high == -1 || low == -1) throw parse_hex_error(); - dest.push_back((high << 4) + low); + dest.push_back(static_cast((high << 4) + low)); } if (i != len) throw parse_hex_error(); // straggler char diff --git a/openvpn/common/hostport.hpp b/openvpn/common/hostport.hpp index 351fb50e..1173727c 100644 --- a/openvpn/common/hostport.hpp +++ b/openvpn/common/hostport.hpp @@ -59,7 +59,7 @@ inline unsigned short parse_port(const std::string &port, const std::string &tit { unsigned int ret = 0; validate_port(port, title, &ret); - return ret; + return static_cast(ret); } // An IP address is also considered to be a valid host diff --git a/openvpn/common/split.hpp b/openvpn/common/split.hpp index d40673d6..af25bf67 100644 --- a/openvpn/common/split.hpp +++ b/openvpn/common/split.hpp @@ -32,9 +32,13 @@ #include #include +#include + + +using namespace openvpn::numeric_util; + +namespace openvpn::Split { -namespace openvpn { -namespace Split { enum { TRIM_LEADING_SPACES = (1 << 0), @@ -122,7 +126,7 @@ inline void by_space_void(V &ret, const std::string &input, LIM *lim = nullptr) defined = true; if (lex.available()) { - const char tc = lex.get(); + const char tc = numeric_cast(lex.get()); if (!SPACE::is_space(tc) || lex.in_quote()) { defined = true; @@ -154,7 +158,6 @@ inline V by_space(const std::string &input, LIM *lim = nullptr) by_space_void(ret, input, lim); return ret; } -} // namespace Split -} // namespace openvpn +} // namespace openvpn::Split #endif // OPENVPN_COMMON_SPLIT_H diff --git a/openvpn/common/stop.hpp b/openvpn/common/stop.hpp index b593c8a6..065f2a17 100644 --- a/openvpn/common/stop.hpp +++ b/openvpn/common/stop.hpp @@ -27,7 +27,12 @@ #include #include +#include + +OPENVPN_EXCEPTION_INHERIT(std::range_error, openvpn_stop_limit); + namespace openvpn { + class Stop { public: @@ -41,6 +46,7 @@ class Stop method(std::move(method_arg)), index(-1) { + constexpr int stop_index_limit = 1000; if (stop) { std::lock_guard lock(stop->mutex); @@ -51,7 +57,10 @@ class Stop } else { - index = stop->scopes.size(); + if (index > stop_index_limit) + throw openvpn_stop_limit("Stop count limit exceeded"); + + index = static_cast(stop->scopes.size()); stop->scopes.push_back(this); } } @@ -104,10 +113,10 @@ class Stop return stop && stop->stop_called; } - private: Stop(const Stop &) = delete; Stop &operator=(const Stop &) = delete; + private: void prune() { while (scopes.size() && !scopes.back()) diff --git a/openvpn/common/string.hpp b/openvpn/common/string.hpp index 01e9cfe5..249d0120 100644 --- a/openvpn/common/string.hpp +++ b/openvpn/common/string.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include @@ -582,18 +582,20 @@ inline std::string trim_copy(const std::string &str) inline std::string to_upper_copy(const std::string &str) { std::string ret; + std::locale loc; ret.reserve(str.length()); for (const auto &c : str) - ret.push_back(std::toupper(static_cast(c))); + ret.push_back(std::toupper(c, loc)); return ret; } inline std::string to_lower_copy(const std::string &str) { std::string ret; + std::locale loc; ret.reserve(str.length()); for (const auto &c : str) - ret.push_back(std::tolower(static_cast(c))); + ret.push_back(std::tolower(c, loc)); return ret; } diff --git a/openvpn/common/tempfile.hpp b/openvpn/common/tempfile.hpp index 3a32e663..2390cc36 100644 --- a/openvpn/common/tempfile.hpp +++ b/openvpn/common/tempfile.hpp @@ -38,11 +38,14 @@ #include #include +#include #include #include #include #include +using openvpn::numeric_util::numeric_cast; + namespace openvpn { class TempFile { @@ -54,13 +57,17 @@ class TempFile : fn(new char[fn_template.length() + 1]), del(fn_delete) { + constexpr char pattern[] = "XXXXXX"; + constexpr size_t patternLen = sizeof(pattern) - 1; std::memcpy(fn.get(), fn_template.c_str(), fn_template.length() + 1); - const size_t pos = fn_template.find("XXXXXX"); + const size_t pos = fn_template.rfind(pattern); if (pos != std::string::npos) { - const int suffixlen = fn_template.length() - pos - 6; - if (suffixlen > 0) - fd.reset(::mkstemps(fn.get(), suffixlen)); + if (fn_template.length() > pos + patternLen) + { + const auto suffixlen = fn_template.length() - pos - patternLen; + fd.reset(::mkstemps(fn.get(), numeric_cast(suffixlen))); + } else fd.reset(::mkstemp(fn.get())); if (!fd.defined()) diff --git a/openvpn/common/unicode.hpp b/openvpn/common/unicode.hpp index 5edfa0e7..86c02577 100644 --- a/openvpn/common/unicode.hpp +++ b/openvpn/common/unicode.hpp @@ -236,8 +236,8 @@ inline BufferPtr string_to_utf16(const STRING &str) UTF8 *d = ret->data(); for (const UTF16 *s = utf16_dest.get(); s < dest; ++s) { - *d++ = *s & 0xFF; - *d++ = (*s >> 8) & 0xFF; + *d++ = static_cast(*s & 0xFF); + *d++ = static_cast((*s >> 8) & 0xFF); } return ret; } @@ -298,7 +298,7 @@ class UTF8Iterator private: const unsigned char *str; - unsigned int size; + size_t size; }; } // namespace Unicode } // namespace openvpn diff --git a/openvpn/compress/compress.hpp b/openvpn/compress/compress.hpp index 0353a04f..8a4df7ce 100644 --- a/openvpn/compress/compress.hpp +++ b/openvpn/compress/compress.hpp @@ -117,7 +117,7 @@ class Compress : public RC // Push a COMPRESS_V2 header byte (value). // Pass value == 0 to omit push. - void v2_push(Buffer &buf, int value) + void v2_push(Buffer &buf, unsigned char value) { unsigned char uc = buf[0]; if (value == 0 && uc != COMPRESS_V2_ESCAPE) diff --git a/openvpn/crypto/crypto_aead.hpp b/openvpn/crypto/crypto_aead.hpp index 87e0e75f..4aac156a 100644 --- a/openvpn/crypto/crypto_aead.hpp +++ b/openvpn/crypto/crypto_aead.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -41,8 +42,9 @@ // [4-byte // IV head] -namespace openvpn { -namespace AEAD { +using openvpn::numeric_util::numeric_cast; + +namespace openvpn::AEAD { OPENVPN_EXCEPTION(aead_error); @@ -252,8 +254,16 @@ class Crypto : public CryptoDCInstance void init_cipher(StaticKey &&encrypt_key, StaticKey &&decrypt_key) override { - e.impl.init(libctx, cipher, encrypt_key.data(), encrypt_key.size(), CRYPTO_API::CipherContextAEAD::ENCRYPT); - d.impl.init(libctx, cipher, decrypt_key.data(), decrypt_key.size(), CRYPTO_API::CipherContextAEAD::DECRYPT); + e.impl.init(libctx, + cipher, + encrypt_key.data(), + numeric_cast(encrypt_key.size()), + CRYPTO_API::CipherContextAEAD::ENCRYPT); + d.impl.init(libctx, + cipher, + decrypt_key.data(), + numeric_cast(decrypt_key.size()), + CRYPTO_API::CipherContextAEAD::DECRYPT); } void init_hmac(StaticKey &&encrypt_key, @@ -354,7 +364,6 @@ class CryptoContext : public CryptoDCContext SessionStats::Ptr stats; SSLLib::Ctx libctx; }; -} // namespace AEAD -} // namespace openvpn +} // namespace openvpn::AEAD #endif diff --git a/openvpn/crypto/packet_id.hpp b/openvpn/crypto/packet_id.hpp index 5af5e57d..5b86ced2 100644 --- a/openvpn/crypto/packet_id.hpp +++ b/openvpn/crypto/packet_id.hpp @@ -123,7 +123,9 @@ struct PacketID void write(Buffer &buf, const int form, const bool prepend) const { const id_t net_id = htonl(id); - const net_time_t net_time = htonl(time); + const net_time_t net_time = htonl(static_cast(time & 0x00000000FFFFFFFF)); + // TODO: [OVPN3-931] Make our code handle rollover of this value gracefully as possible + // since at the current time this will probably force a reconnect. if (prepend) { @@ -260,6 +262,7 @@ class PacketIDReceiveType OPENVPN_SIMPLE_EXCEPTION(packet_id_not_initialized); + // TODO: [OVPN3-933] Consider RAII'ifying this code PacketIDReceiveType() : initialized_(false) { @@ -350,7 +353,7 @@ class PacketIDReceiveType if (!mod) return Error::SUCCESS; base = REPLAY_INDEX(-1); - history[base / 8] |= (1 << (base % 8)); + history[base / 8] |= static_cast(1 << (base % 8)); if (extent < REPLAY_WINDOW_SIZE) ++extent; id_high = pin.id; @@ -364,14 +367,14 @@ class PacketIDReceiveType if (delta < REPLAY_WINDOW_SIZE) { base = REPLAY_INDEX(-delta); - history[base / 8] |= (1 << (base % 8)); + history[base / 8] |= static_cast(1 << (base % 8)); extent += delta; if (extent > REPLAY_WINDOW_SIZE) extent = REPLAY_WINDOW_SIZE; for (unsigned i = 1; i < delta; ++i) { const unsigned int newbase = REPLAY_INDEX(i); - history[newbase / 8] &= ~(1 << (newbase % 8)); + history[newbase / 8] &= static_cast(~(1 << (newbase % 8))); } } else @@ -395,7 +398,7 @@ class PacketIDReceiveType { const unsigned int ri = REPLAY_INDEX(delta); std::uint8_t *p = &history[ri / 8]; - const std::uint8_t mask = (1 << (ri % 8)); + const std::uint8_t mask = static_cast(1 << (ri % 8)); if (*p & mask) return Error::PKTID_REPLAY; if (!mod) diff --git a/openvpn/http/headredact.hpp b/openvpn/http/headredact.hpp index 9413f1d3..b4904c14 100644 --- a/openvpn/http/headredact.hpp +++ b/openvpn/http/headredact.hpp @@ -32,7 +32,7 @@ inline std::string headers_redact(const std::string &headers) #ifdef OPENVPN_HTTP_HEADERS_NO_REDACT return headers; #else - // C++14 only solution (not compatible with RHEL7/CentOS7) + // Alternative regex implementation: // static const std::regex re(R"((authorization[\s:=]+basic\s+)([^\s]+))", std::regex_constants::ECMAScript | std::regex_constants::icase); // return std::regex_replace(headers, re, "$1[REDACTED]"); std::stringstream result; @@ -41,20 +41,18 @@ inline std::string headers_redact(const std::string &headers) for (std::string line; std::getline(iss, line);) { - int authpos; - if ((authpos = line.find("Authorization: ")) != -1) + if (auto authpos = line.find("Authorization: "); authpos != std::string::npos) { auto auth = line.substr(authpos); auto argument = auth.substr(auth.find(' ') + 1); std::string authtype; - int arg1 = -1; - if ((arg1 = argument.find(' ')) != -1) + if (auto arg1 = argument.find(' '); arg1 != std::string::npos) { authtype = argument.substr(0, arg1); } result << line.substr(0, authpos) << "Authorization: " << authtype << " [REDACTED]\r" << std::endl; } - else if ((authpos = line.find("authorization=basic ")) != -1) + else if ((authpos = line.find("authorization=basic ")) != std::string::npos) { result << line.substr(0, authpos) << "authorization=basic [REDACTED]\r" << std::endl; } diff --git a/openvpn/ip/csum.hpp b/openvpn/ip/csum.hpp index a55ab855..9a3bd781 100644 --- a/openvpn/ip/csum.hpp +++ b/openvpn/ip/csum.hpp @@ -36,12 +36,12 @@ inline std::uint16_t fold(std::uint32_t sum) { sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); - return sum; + return static_cast(sum & 0x0000FFFF); } inline std::uint16_t cfold(const std::uint32_t sum) { - return ~fold(sum); + return static_cast(~fold(sum)); } inline std::uint32_t unfold(const std::uint16_t sum) diff --git a/openvpn/ip/ip4.hpp b/openvpn/ip/ip4.hpp index 3edd65e4..d77ef000 100644 --- a/openvpn/ip/ip4.hpp +++ b/openvpn/ip/ip4.hpp @@ -40,7 +40,7 @@ struct IPv4Header static std::uint8_t ver_len(const unsigned int version, const unsigned int len) { - return ((len >> 2) & 0x0F) | (version & 0x0F) << 4; + return static_cast(((len >> 2) & 0x0F) | (version & 0x0F) << 4); } std::uint8_t version_len; diff --git a/openvpn/ip/ping4.hpp b/openvpn/ip/ping4.hpp index b2824f4f..91ff7d55 100644 --- a/openvpn/ip/ping4.hpp +++ b/openvpn/ip/ping4.hpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -33,16 +34,17 @@ #include #include -namespace openvpn { -namespace Ping4 { +using openvpn::numeric_util::clamp_to_typerange; + +namespace openvpn::Ping4 { inline void generate_echo_request(Buffer &buf, const IPv4::Addr &src, const IPv4::Addr &dest, const void *extra_data, const size_t extra_data_size, - const unsigned int id, - const unsigned int seq_num, + const uint16_t id, + const uint16_t seq_num, const size_t total_size, std::string *log_info) { @@ -51,13 +53,14 @@ inline void generate_echo_request(Buffer &buf, if (log_info) *log_info = "PING4 " + src.to_string() + " -> " + dest.to_string() + " id=" + std::to_string(id) + " seq_num=" + std::to_string(seq_num) + " data_size=" + std::to_string(data_size); - std::uint8_t *b = buf.write_alloc(sizeof(ICMPv4) + data_size); + const auto total_length = clamp_to_typerange(sizeof(ICMPv4) + data_size); + std::uint8_t *b = buf.write_alloc(total_length); ICMPv4 *icmp = (ICMPv4 *)b; // IP Header - icmp->head.version_len = IPv4Header::ver_len(4, sizeof(IPv4Header)); + icmp->head.version_len = IPv4Header::ver_len(4, static_cast(sizeof(IPv4Header))); icmp->head.tos = 0; - icmp->head.tot_len = htons(sizeof(ICMPv4) + data_size); + icmp->head.tot_len = htons(total_length); icmp->head.id = 0; icmp->head.frag_off = 0; icmp->head.ttl = 64; @@ -109,5 +112,4 @@ inline void generate_echo_reply(Buffer &buf, if (log_info) *log_info = "ECHO4_REPLY size=" + std::to_string(buf.size()) + ' ' + IPv4::Addr::from_uint32_net(icmp->head.saddr).to_string() + " -> " + IPv4::Addr::from_uint32_net(icmp->head.daddr).to_string(); } -} // namespace Ping4 -} // namespace openvpn \ No newline at end of file +} // namespace openvpn::Ping4 \ No newline at end of file diff --git a/openvpn/ip/ping6.hpp b/openvpn/ip/ping6.hpp index f08e7034..e1baa6b3 100644 --- a/openvpn/ip/ping6.hpp +++ b/openvpn/ip/ping6.hpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -33,8 +34,9 @@ #include #include -namespace openvpn { -namespace Ping6 { +using namespace openvpn::numeric_util; + +namespace openvpn::Ping6 { inline static const std::uint16_t *get_addr16(const struct in6_addr *addr) { @@ -90,9 +92,13 @@ inline std::uint16_t csum_ipv6_pseudo(const struct in6_addr *saddr, // len must be >= sizeof(ICMPv6) inline std::uint16_t csum_icmp(const ICMPv6 *icmp, const size_t len) { + if (len < sizeof(IPv6Header)) + throw std::range_error("Argument 'len' too small"); + + auto lenArg = numeric_cast(len - sizeof(IPv6Header)); return csum_ipv6_pseudo(&icmp->head.saddr, &icmp->head.daddr, - len - sizeof(IPv6Header), + lenArg, IPCommon::ICMPv6, IPChecksum::compute((std::uint8_t *)icmp + sizeof(IPv6Header), len - sizeof(IPv6Header))); } @@ -102,8 +108,8 @@ inline void generate_echo_request(Buffer &buf, const IPv6::Addr &dest, const void *extra_data, const size_t extra_data_size, - const unsigned int id, - const unsigned int seq_num, + const uint16_t id, + const uint16_t seq_num, const size_t total_size, std::string *log_info) { @@ -120,7 +126,7 @@ inline void generate_echo_request(Buffer &buf, icmp->head.flow_lbl[0] = 0; icmp->head.flow_lbl[1] = 0; icmp->head.flow_lbl[2] = 0; - icmp->head.payload_len = htons(sizeof(ICMPv6) - sizeof(IPv6Header) + data_size); + icmp->head.payload_len = htons(numeric_cast(sizeof(ICMPv6) - sizeof(IPv6Header) + data_size)); icmp->head.nexthdr = IPCommon::ICMPv6; icmp->head.hop_limit = 64; icmp->head.saddr = src.to_in6_addr(); @@ -167,5 +173,4 @@ inline void generate_echo_reply(Buffer &buf, if (log_info) *log_info = "ECHO6_REPLY size=" + std::to_string(buf.size()) + ' ' + IPv6::Addr::from_in6_addr(&icmp->head.saddr).to_string() + " -> " + IPv6::Addr::from_in6_addr(&icmp->head.daddr).to_string(); } -} // namespace Ping6 -} // namespace openvpn \ No newline at end of file +} // namespace openvpn::Ping6 \ No newline at end of file diff --git a/openvpn/linux/usergroup_retain_cap.hpp b/openvpn/linux/usergroup_retain_cap.hpp index 76abe0a8..4a0df3b8 100644 --- a/openvpn/linux/usergroup_retain_cap.hpp +++ b/openvpn/linux/usergroup_retain_cap.hpp @@ -30,6 +30,7 @@ #include #include +#include #include #ifndef OPENVPN_PLATFORM_LINUX @@ -147,8 +148,8 @@ class SetUserGroupRetainCap : public SetUserGroup void set_flag(const std::vector &caps) { - if (::cap_set_flag(capabilities, CAP_PERMITTED, caps.size(), caps.data(), CAP_SET) - || ::cap_set_flag(capabilities, CAP_EFFECTIVE, caps.size(), caps.data(), CAP_SET)) + if (::cap_set_flag(capabilities, CAP_PERMITTED, numeric_cast(caps.size()), caps.data(), CAP_SET) + || ::cap_set_flag(capabilities, CAP_EFFECTIVE, numeric_cast(caps.size()), caps.data(), CAP_SET)) { const int eno = errno; OPENVPN_THROW(user_group_err, "SetUserGroupRetainCap::Capabilities: cap_set_flag " << title << " fail: " << strerror_str(eno)); diff --git a/openvpn/log/logperiod.hpp b/openvpn/log/logperiod.hpp index b3ed6ef0..317b17e8 100644 --- a/openvpn/log/logperiod.hpp +++ b/openvpn/log/logperiod.hpp @@ -81,7 +81,7 @@ class LogPeriod return period_ != UNDEF; } - unsigned int expires_in(const time_t now) + time_t expires_in(const time_t now) { const olong onow = olong(now); if (onow < end_) diff --git a/test/unittests/test_misc_unix.cpp b/test/unittests/test_misc_unix.cpp index 931c1ffb..ede040f0 100644 --- a/test/unittests/test_misc_unix.cpp +++ b/test/unittests/test_misc_unix.cpp @@ -27,4 +27,39 @@ TEST(misc, tempfile) tf.reset(); const std::string s2 = tf.read(); ASSERT_EQ(s2, content2); -} \ No newline at end of file +} + +TEST(misc, tempfile_name) +{ + TempFile tf(getTempDirPath("tempfile-XXXXXX"), true); + auto fn = tf.filename(); + ASSERT_NE(std::string::npos, fn.find("tempfile-")); + ASSERT_EQ(std::string::npos, fn.find("XXXXXX")); +} + +TEST(misc, tempfile_name_6Xs) +{ + TempFile tf(getTempDirPath("tempXXXXXXfile"), true); + auto fn = tf.filename(); + ASSERT_NE(std::string::npos, fn.find("temp")); + ASSERT_NE(std::string::npos, fn.find("file")); + ASSERT_EQ(std::string::npos, fn.find("XXXXXX")); +} + +TEST(misc, tempfile_name_7Xs) +{ + TempFile tf(getTempDirPath("tempXXXXXXXfile"), true); + auto fn = tf.filename(); + ASSERT_NE(std::string::npos, fn.find("temp")); + ASSERT_NE(std::string::npos, fn.find("file")); + ASSERT_EQ(std::string::npos, fn.find("XXXXXX")); +} + +TEST(misc, tempfile_name_6X6X) +{ + TempFile tf(getTempDirPath("tempXXXXXXfile-XXXXXX"), true); + auto fn = tf.filename(); + ASSERT_NE(std::string::npos, fn.find("temp")); + ASSERT_NE(std::string::npos, fn.find("file")); + ASSERT_EQ(fn.rfind("XXXXXX"), fn.find("XXXXXX")); +}