* @brief This file contains test of CAPI for Privacy Privilege Manager
*/
+#include <functional>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
+#include <random>
#include <glib.h>
#include <unistd.h>
printf("Options:\n");
printf("-s run as a server\n");
printf("-c run as a client (uses CAPI)\n");
+ printf("-a run client or server in auto mode (stress testing)");
+ printf(" The client will send randomly generated requests at random intervals of time.");
+ printf(" The server will respond with 'deny once' to all pending requests at random intervals of time.");
printf("-h display this help end exit\n");
}
printPrompt(Mode::SERVER);
}
+std::function<int(void)> createRandomGenerator() {
+ std::uniform_int_distribution<int> distribution(0, 1000);
+ std::mt19937 engine(time(0));
+ return std::bind(distribution, engine);
+}
+
struct ServerSimulator : public IServerCallbacks {
ServerSimulator()
}
}
+ void respondToAllRequests() {
+ for (const auto &reqSet : m_requests) {
+ for (const auto &req : reqSet.second) {
+ m_channel->popupResponse(reqSet.first, req.m_id, PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE);
+ }
+ }
+
+ m_requests.clear();
+ }
+
void showPrivilegeRequests() {
printf("fd requestId privilege\n");
for (const auto &con : m_requests) {
throw std::logic_error("AppContext::initialize called with argc < 1");
}
+ bool autoMode = false;
int c;
opterr = 0;
- while ((c = getopt (argc, argv, "sch")) != -1) {
+ while ((c = getopt (argc, argv, "cash")) != -1) {
switch (c) {
case 's':
m_mode = Mode::SERVER;
case 'c':
m_mode = Mode::CLIENT;
break;
+ case 'a':
+ autoMode = true;
+ break;
case 'h':
default:
break;
GIOChannel *gio_channel = g_io_channel_unix_new(0);
g_io_add_watch(gio_channel, static_cast<GIOCondition>(G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
&AppContext::mainLoopCallback, this);
+
+ if (autoMode) {
+ m_randomGenerator = createRandomGenerator();
+ g_timeout_add(0, &AppContext::timerCallback, this);
+ }
}
void run() {
return TRUE;
}
+ static gboolean timerCallback(gpointer user_data) {
+ AppContext *ctx = static_cast<AppContext *>(user_data);
+
+ switch (ctx->m_mode) {
+ case Mode::CLIENT:
+ ctx->handleAutoClient();
+ break;
+ case Mode::SERVER:
+ ctx->handleAutoServer();
+ break;
+ case Mode::UNKNOWN:
+ default:
+ printf("Mode not set, exiting.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ g_timeout_add(ctx->m_randomGenerator(), timerCallback, ctx);
+
+ return FALSE;
+ }
+
+ void handleAutoClient() {
+ int requests = m_randomGenerator() % 10;
+ static RequestId clientRequestId;
+
+ for (int ri = 0; ri < requests; ri++) {
+ std::string privilege = generateRandomString(1 + m_randomGenerator() % 128);
+
+ printf("sending localId: %d privilege: \"%s\"\n", clientRequestId, privilege.c_str());
+
+ ClientRequest *request = new ClientRequest{ clientRequestId++, m_mainloop, false };
+ ppm_error_e err = static_cast<ppm_error_e>(ppm_request_permission(privilege.c_str(),
+ &AppContext::requestResponseCallback, request));
+ if (err != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
+ delete request;
+ }
+ }
+ }
+
+ void handleAutoServer() {
+ m_serverSimulator->respondToAllRequests();
+ }
+
+ std::string generateRandomString(int len) {
+ if (len > 1024)
+ throw std::logic_error("String too long " + std::to_string(len));
+
+ char tab[len + 1];
+
+ for (int i = 0; i < len; i++) {
+ tab[i] = 'a' + m_randomGenerator() % ('z' - 'a' + 1);
+ }
+ tab[len] = '\0';
+
+ return std::string(tab);
+ }
+
GMainLoop *m_mainloop;
ServerSimulator *m_serverSimulator;
ServerChannel *m_channel;
Mode m_mode;
+ std::function<int(void)> m_randomGenerator;
};
int main(int argc, char **argv)