First release of open-appsec source code

This commit is contained in:
roybarda
2022-10-26 19:33:19 +03:00
parent 3883109caf
commit a883352f79
1353 changed files with 276290 additions and 1 deletions

View File

@@ -0,0 +1,3 @@
add_library(time_proxy time_proxy.cc)
add_subdirectory(time_proxy_ut)

View File

@@ -0,0 +1,137 @@
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "time_proxy.h"
#include <chrono>
#include <string>
#include <time.h>
#include <sstream>
#include "debug.h"
#include "singleton.h"
#include "i_time_get.h"
#include "i_time_set.h"
using namespace std;
using std::chrono::microseconds;
using std::chrono::seconds;
using std::chrono::steady_clock;
using std::chrono::system_clock;
using std::chrono::time_point;
using std::chrono::duration_cast;
static const int no_of_ticks_in_a_second = 1000000;
static const int no_of_digits_after_the_dot_precision = 6;
class TimeProxyComponent::Impl
:
Singleton::Provide<I_TimeGet>::From<TimeProxyComponent>,
Singleton::Provide<I_TimeSet>::From<TimeProxyComponent>
{
public:
// Monotonic Time API
microseconds
getMonotonicTime() override
{
if (is_monotomic_set) return monotonic_now;
return duration_cast<microseconds>(steady_clock::now() - monotonic_start);
}
void
setMonotonicTime(microseconds new_time) override
{
if (is_monotomic_set) {
dbgAssert((new_time+monotonic_delta) >= monotonic_now) << "Monotonic time must not go back!";
} else {
// The first time that the monotonic time is been set, we take the current value to be the base line.
// This is in order to avoid the clock going backwards.
// So we calulate the delta from the current time to the vale we were given, and later on add it to
// any we get. That delta assures that setMonotonicTime can be used without concern as to what was the
// exact time when we started setting it.
auto curr = duration_cast<microseconds>(steady_clock::now() - monotonic_start);
monotonic_delta = curr - new_time;
is_monotomic_set = true;
}
monotonic_now = new_time + monotonic_delta;
}
// Wall Time API
microseconds
getWalltime() override
{
if (is_walltime_set) return walltime_now;
return duration_cast<microseconds>(system_clock::now().time_since_epoch());
}
void
setWalltime(microseconds new_time)
{
walltime_now = new_time;
is_walltime_set = true;
}
std::string getWalltimeStr() override { return getWalltimeStr(getWalltime()); }
std::string
getWalltimeStr(const microseconds &time_to_convert)
{
time_t ttime = duration_cast<seconds>(time_to_convert).count();
struct tm *gm_time = gmtime(&ttime);
return parseTime(time_to_convert, gm_time);
}
std::string
getLocalTimeStr()
{
microseconds time_in_microseconds = getWalltime();
time_t ttime = duration_cast<seconds>(time_in_microseconds).count();
struct tm *local_time = localtime(&ttime);
return parseTime(time_in_microseconds, local_time);
}
private:
bool is_monotomic_set = false;
bool is_walltime_set = false;
microseconds walltime_now;
microseconds monotonic_now;
microseconds monotonic_delta;
time_point<steady_clock> monotonic_start = steady_clock::now();
std::string
parseTime(const microseconds &time_in_microseconds, const struct tm *time_struct)
{
// Using ISO 8601 Format: YYYY-MM-DD'T'hh:mm:ss
char date[24];
size_t date_len = strftime(date, sizeof(date), "%FT%T", time_struct);
// Adding micro seconds too
stringstream str;
str.width(no_of_digits_after_the_dot_precision);
str.fill('0');
str << (time_in_microseconds.count() % no_of_ticks_in_a_second);
return string(date, date_len) + "." + str.str();
}
};
TimeProxyComponent::TimeProxyComponent()
:
Component("TimeProxyComponent"),
pimpl(make_unique<Impl>())
{
}
TimeProxyComponent::~TimeProxyComponent()
{
}

View File

@@ -0,0 +1 @@
add_unit_test(time_proxy_ut "time_proxy_ut.cc;time_print_ut.cc" "time_proxy;singleton;rest")

View File

@@ -0,0 +1,45 @@
#include "time_print.h"
#include "cptest.h"
using namespace std;
using namespace testing;
TEST(time_printTest, time_print_operator_for_microseconds)
{
chrono::microseconds usec(1000);
stringstream buf;
buf << usec;
EXPECT_EQ(buf.str(), "1000usec");
}
TEST(time_printTest, time_print_operator_for_milliseconds)
{
chrono::milliseconds ms(1000);
stringstream buf;
buf << ms;
EXPECT_EQ(buf.str(), "1000ms");
}
TEST(time_printTest, time_print_operator_for_seconds)
{
chrono::seconds sec(1000);
stringstream buf;
buf << sec;
EXPECT_EQ(buf.str(), "1000s");
}
TEST(time_printTest, time_print_operator_for_minutes)
{
chrono::minutes m(1000);
stringstream buf;
buf << m;
EXPECT_EQ(buf.str(), "1000m");
}
TEST(time_printTest, time_print_operator_for_hours)
{
chrono::hours hours_val(1000);
stringstream buf;
buf << hours_val;
EXPECT_EQ(buf.str(), "1000h");
}

View File

@@ -0,0 +1,67 @@
#include <string>
#include "cptest.h"
#include "time_proxy.h"
#include "singleton.h"
using namespace std;
using namespace testing;
using namespace std::chrono;
class TimeProxyTest : public Test
{
public:
TimeProxyComponent proxy;
I_TimeGet *i_time_get = Singleton::Consume<I_TimeGet>::from(proxy);
I_TimeSet *i_time_set = Singleton::Consume<I_TimeSet>::from(proxy);
};
TEST_F(TimeProxyTest, get_without_set)
{
auto mono1 = i_time_get->getMonotonicTime(); // Check that it doesn't crash - but we can't verify the value.
usleep(1000);
auto mono2 = i_time_get->getMonotonicTime();
EXPECT_LT(mono1, mono2);
i_time_get->getWalltime(); // Check that it doesn't crash - but we can't verify the value.
// Checking that ISO-8601 time format is used, e.g.: 2016-11-11T15:33:01.034
EXPECT_THAT(
i_time_get->getWalltimeStr(),
MatchesRegex("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}")
);
EXPECT_THAT(
i_time_get->getLocalTimeStr(),
MatchesRegex("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}")
);
}
TEST_F(TimeProxyTest, set)
{
auto marty_mcfly_time = microseconds((1445455680L)*1000000); // 21 Oct 2015, 19:28
std::string marty_mcfly_time_str = "2015-10-21T19:28:00.000000";
i_time_set->setWalltime(marty_mcfly_time);
EXPECT_EQ(i_time_get->getWalltime(), marty_mcfly_time);
EXPECT_EQ(i_time_get->getWalltimeStr(), marty_mcfly_time_str);
i_time_set->setMonotonicTime(microseconds(0));
auto time = i_time_get->getMonotonicTime();
i_time_set->setMonotonicTime(microseconds(1337000));
EXPECT_EQ(i_time_get->getMonotonicTime(), time + microseconds(1337000));
usleep(1000);
EXPECT_EQ(i_time_get->getMonotonicTime(), time + microseconds(1337000));
// No problem reseting walltime to whatever
i_time_set->setWalltime(microseconds(1000000));
i_time_set->setWalltime(microseconds(2001000));
EXPECT_EQ(i_time_get->getWalltime(), microseconds(2001000));
EXPECT_EQ(i_time_get->getWalltimeStr(), "1970-01-01T00:00:02.001000");
// You can move monotonic time forwards
i_time_set->setMonotonicTime(microseconds(2000000));
EXPECT_EQ(i_time_get->getMonotonicTime(), time + microseconds(2000000));
// But not backwards
cptestPrepareToDie();
EXPECT_DEATH(i_time_set->setMonotonicTime(microseconds(1000)), "Monotonic time must not go back!");
}