summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEd Tanous <ed.tanous@intel.com>2017-06-13 02:01:42 +0300
committerEd Tanous <ed.tanous@intel.com>2017-06-13 02:01:42 +0300
commitf3d847c9b91319220266695c726fdacbd1a860e8 (patch)
treeabdf28dcf03ebacb22c6948b153738aa17e5073e /src
parentc9b5521eb8505c55784f1bb2743e7d8addb6e42e (diff)
downloadbmcweb-f3d847c9b91319220266695c726fdacbd1a860e8.tar.xz
incremental
Diffstat (limited to 'src')
-rw-r--r--src/ast_video_puller_test.cpp2
-rw-r--r--src/getvideo_main.cpp2
-rw-r--r--src/security_headers_middleware.cpp39
-rw-r--r--src/token_authorization_middleware.cpp192
-rw-r--r--src/token_authorization_middleware_test.cpp13
-rw-r--r--src/webserver_main.cpp91
6 files changed, 54 insertions, 285 deletions
diff --git a/src/ast_video_puller_test.cpp b/src/ast_video_puller_test.cpp
index ef1cbe3b6d..b1f94e7579 100644
--- a/src/ast_video_puller_test.cpp
+++ b/src/ast_video_puller_test.cpp
@@ -14,7 +14,6 @@
#include <gtest/gtest.h>
TEST(AstvideoPuller, BasicRead) {
- std::cout << "Started\n";
AstVideo::RawVideoBuffer out;
bool have_hardware = false;
if (access("/dev/video", F_OK) != -1) {
@@ -43,7 +42,6 @@ TEST(AstvideoPuller, BasicRead) {
fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
AstVideo::AstJpegDecoder d;
- std::cout << "MODE " << static_cast<int>(out.mode);
d.decode(out.buffer, out.width, out.height, out.mode, out.y_selector,
out.uv_selector);
}
diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp
index 33885ee117..2ab0c0e0c9 100644
--- a/src/getvideo_main.cpp
+++ b/src/getvideo_main.cpp
@@ -20,7 +20,6 @@
#include <ast_video_puller.hpp>
int main() {
- std::cout << "Started\n";
AstVideo::RawVideoBuffer out;
bool have_hardware = false;
if (access("/dev/video", F_OK) != -1) {
@@ -49,7 +48,6 @@ int main() {
fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
AstVideo::AstJpegDecoder d;
- std::cout << "MODE " << static_cast<int>(out.mode);
d.decode(out.buffer, out.width, out.height, out.mode, out.y_selector,
out.uv_selector);
#ifdef BUILD_CIMG
diff --git a/src/security_headers_middleware.cpp b/src/security_headers_middleware.cpp
deleted file mode 100644
index 265cda72a7..0000000000
--- a/src/security_headers_middleware.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <security_headers_middleware.hpp>
-
-namespace crow {
-
-static const std::string strict_transport_security_key =
- "Strict-Transport-Security";
-static const std::string strict_transport_security_value =
- "max-age=31536000; includeSubdomains; preload";
-
-static const std::string ua_compatability_key = "X-UA-Compatible";
-static const std::string ua_compatability_value = "IE=11";
-
-static const std::string xframe_key = "X-Frame-Options";
-static const std::string xframe_value = "DENY";
-
-static const std::string xss_key = "X-XSS-Protection";
-static const std::string xss_value = "1; mode=block";
-
-static const std::string content_security_key = "X-Content-Security-Policy";
-static const std::string content_security_value = "default-src 'self'";
-
-void SecurityHeadersMiddleware::before_handle(crow::request& req, response& res,
- context& ctx) {}
-
-void SecurityHeadersMiddleware::after_handle(request& /*req*/, response& res,
- context& ctx) {
- /*
- TODO(ed) these should really check content types. for example,
- X-UA-Compatible header doesn't make sense when retrieving a JSON or
- javascript file. It doesn't hurt anything, it's just ugly.
- */
- res.add_header(strict_transport_security_key,
- strict_transport_security_value);
- res.add_header(ua_compatability_key, ua_compatability_value);
- res.add_header(xframe_key, xframe_value);
- res.add_header(xss_key, xss_value);
- res.add_header(content_security_key, content_security_value);
-}
-}
diff --git a/src/token_authorization_middleware.cpp b/src/token_authorization_middleware.cpp
deleted file mode 100644
index 508bfd982c..0000000000
--- a/src/token_authorization_middleware.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include <random>
-#include <unordered_map>
-#include <boost/algorithm/string/predicate.hpp>
-
-#include <security/pam_appl.h>
-#include <base64.hpp>
-#include <token_authorization_middleware.hpp>
-#include <crow/logging.h>
-
-namespace crow {
-
-using random_bytes_engine =
- std::independent_bits_engine<std::default_random_engine, CHAR_BIT,
- unsigned char>;
-
-// function used to get user input
-int pam_function_conversation(int num_msg, const struct pam_message** msg,
- struct pam_response** resp, void* appdata_ptr) {
- char* pass = (char*)malloc(strlen((char*)appdata_ptr) + 1);
- strcpy(pass, (char*)appdata_ptr);
-
- int i;
-
- *resp = (pam_response*)calloc(num_msg, sizeof(struct pam_response));
-
- for (i = 0; i < num_msg; ++i) {
- /* Ignore all PAM messages except prompting for hidden input */
- if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF) continue;
-
- /* Assume PAM is only prompting for the password as hidden input */
- resp[i]->resp = pass;
- }
-
- return PAM_SUCCESS;
-}
-
-bool authenticate_user_pam(const std::string& username,
- const std::string& password) {
- const struct pam_conv local_conversation = {pam_function_conversation,
- (char*)password.c_str()};
- pam_handle_t* local_auth_handle = NULL; // this gets set by pam_start
-
- int retval;
- retval = pam_start("su", username.c_str(), &local_conversation,
- &local_auth_handle);
-
- if (retval != PAM_SUCCESS) {
- printf("pam_start returned: %d\n ", retval);
- return false;
- }
-
- retval = pam_authenticate(local_auth_handle,
- PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
-
- if (retval != PAM_SUCCESS) {
- if (retval == PAM_AUTH_ERR) {
- printf("Authentication failure.\n");
- } else {
- printf("pam_authenticate returned %d\n", retval);
- }
- return false;
- }
-
- printf("Authenticated.\n");
- retval = pam_end(local_auth_handle, retval);
-
- if (retval != PAM_SUCCESS) {
- printf("pam_end returned\n");
- return false;
- }
-
- return true;
-}
-
-TokenAuthorizationMiddleware::TokenAuthorizationMiddleware(){
-};
-
-void TokenAuthorizationMiddleware::before_handle(crow::request& req,
- response& res, context& ctx) {
- auto return_unauthorized = [&req, &res]() {
- res.code = 401;
- res.end();
- };
-
- auto return_bad_request = [&req, &res]() {
- res.code = 400;
- res.end();
- };
-
- auto return_internal_error = [&req, &res]() {
- res.code = 500;
- res.end();
- };
-
- if (req.url == "/" || boost::starts_with(req.url, "/static/")) {
- // TODO this is total hackery to allow the login page to work before the
- // user is authenticated. Also, it will be quite slow for all pages instead
- // of a one time hit for the whitelist entries. Ideally, this should be
- // done in the url router handler, with tagged routes for the whitelist
- // entries. Another option would be to whitelist a minimal for based page
- // that didn't
- // load the full angular UI until after login
- return;
- }
-
- if (req.url == "/login") {
- if (req.method != HTTPMethod::POST) {
- return_unauthorized();
- return;
- } else {
- auto login_credentials = crow::json::load(req.body);
- if (!login_credentials) {
- return_bad_request();
- return;
- }
- if (!login_credentials.has("username") ||
- !login_credentials.has("password")) {
- return_bad_request();
- return;
- }
- auto username = login_credentials["username"].s();
- auto password = login_credentials["password"].s();
-
- // TODO(ed) pull real passwords from PAM
- if (authenticate_user_pam(username, password)) {
- crow::json::wvalue x;
-
- // TODO(ed) the RNG should be initialized at start, not every time we
- // want a token
- std::random_device rand;
- random_bytes_engine rbe;
- std::string token('a', 20);
- // TODO(ed) for some reason clang-tidy finds a divide by zero error in
- // cstdlibc here commented out for now. Needs investigation
- std::generate(begin(token), end(token), std::ref(rbe)); // NOLINT
- std::string encoded_token;
- base64::base64_encode(token, encoded_token);
- // ctx.auth_token = encoded_token;
- this->auth_token2.insert(encoded_token);
-
- x["token"] = encoded_token;
-
- res.write(json::dump(x));
- res.add_header("Content-Type", "application/json");
- res.end();
- } else {
- return_unauthorized();
- return;
- }
- }
-
- } else { // Normal, non login, non static file request
- // Check to make sure we're logged in
- if (this->auth_token2.empty()) {
- return_unauthorized();
- return;
- }
- // Check for an authorization header, reject if not present
- if (req.headers.count("Authorization") != 1) {
- return_unauthorized();
- return;
- }
-
- std::string auth_header = req.get_header_value("Authorization");
- // If the user is attempting any kind of auth other than token, reject
- if (!boost::starts_with(auth_header, "Token ")) {
- return_unauthorized();
- return;
- }
- std::string auth_key = auth_header.substr(6);
- // TODO(ed), use span here instead of constructing a new string
- if (this->auth_token2.find(auth_key) == this->auth_token2.end()) {
- return_unauthorized();
- return;
- }
-
- if (req.url == "/logout") {
- this->auth_token2.erase(auth_key);
- res.code = 200;
- res.end();
- return;
- }
-
- // else let the request continue unharmed
- }
-}
-
-void TokenAuthorizationMiddleware::after_handle(request& req, response& res,
- context& ctx) {
- // Do nothing
-}
-}
diff --git a/src/token_authorization_middleware_test.cpp b/src/token_authorization_middleware_test.cpp
index e82776533e..49933c9954 100644
--- a/src/token_authorization_middleware_test.cpp
+++ b/src/token_authorization_middleware_test.cpp
@@ -6,6 +6,14 @@
using namespace crow;
using namespace std;
+class KnownLoginAuthenticator {
+ public:
+ inline bool authenticate(const std::string& username,
+ const std::string& password) {
+ return (username == "dude") && (password == "foo");
+ }
+};
+
// Tests that static urls are correctly passed
TEST(TokenAuthentication, TestBasicReject) {
App<crow::TokenAuthorizationMiddleware> app;
@@ -177,9 +185,8 @@ TEST(TokenAuthentication, TestPostBadLoginUrl) {
app.stop();
}
-// Tests boundary conditions on login
TEST(TokenAuthentication, TestSuccessfulLogin) {
- App<crow::TokenAuthorizationMiddleware> app;
+ App<crow::TokenAuthorization<KnownLoginAuthenticator>> app;
app.bindaddr("127.0.0.1").port(45451);
CROW_ROUTE(app, "/")([]() { return 200; });
auto _ = async(launch::async, [&] { app.run(); });
@@ -215,7 +222,7 @@ TEST(TokenAuthentication, TestSuccessfulLogin) {
// Test correct login credentials
sendmsg =
"POST /login\r\nContent-Length:40\r\n\r\n{\"username\": \"dude\", "
- "\"password\": \"dude\"}\r\n";
+ "\"password\": \"foo\"}\r\n";
{
send_to_localhost(sendmsg);
std::string response(std::begin(buf), std::end(buf));
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 0c173dd947..3baf388a24 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -246,9 +246,20 @@ int main(int argc, char** argv) {
return j;
});
- CROW_ROUTE(app, "/ipmiws")
+ CROW_ROUTE(app, "/sensorws")
.websocket()
.onopen([&](crow::websocket::connection& conn) {
+ dbus::connection system_bus(conn.get_io_service(), dbus::bus::system);
+ dbus::match ma(system_bus,
+ "type='signal',sender='org.freedesktop.DBus', "
+ "interface='org.freedesktop.DBus.Properties',member="
+ "'PropertiesChanged'");
+ dbus::filter f(system_bus, [](dbus::message& m) { return true; });
+
+ f.async_dispatch([&](boost::system::error_code ec, dbus::message s) {
+ std::cout << "got event\n";
+ //f.async_dispatch(event_handler);
+ });
})
.onclose(
@@ -257,57 +268,43 @@ int main(int argc, char** argv) {
})
.onmessage([&](crow::websocket::connection& conn, const std::string& data,
bool is_binary) {
- boost::asio::io_service io_service;
- using boost::asio::ip::udp;
- udp::resolver resolver(io_service);
- udp::resolver::query query(udp::v4(), "10.243.48.31", "623");
- udp::endpoint receiver_endpoint = *resolver.resolve(query);
-
- udp::socket socket(io_service);
- socket.open(udp::v4());
-
- socket.send_to(boost::asio::buffer(data), receiver_endpoint);
-
- std::array<char, 255> recv_buf;
-
- udp::endpoint sender_endpoint;
- size_t len =
- socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);
- // TODO(ed) THis is ugly. Find a way to not make a copy (ie, use
- // std::string::data() to
- std::string str(std::begin(recv_buf), std::end(recv_buf));
- LOG(DEBUG) << "Got " << str << "back \n";
- conn.send_binary(str);
});
CROW_ROUTE(app, "/sensortest")
([](const crow::request& req, crow::response& res) {
- dbus::connection system_bus(*req.io_service, dbus::bus::system);
-
- dbus::endpoint test_daemon("org.freedesktop.DBus", "/",
- "org.freedesktop.DBus");
- dbus::message m = dbus::message::new_call(test_daemon, "ListNames");
- system_bus.async_send(m, [&](const boost::system::error_code ec,
- dbus::message r) {
- std::vector<std::string> services;
- //r.unpack(services);
- for (auto& service : services) {
- dbus::endpoint service_daemon(service, "/",
- "org.freedesktop.DBus.Introspectable");
- dbus::message m = dbus::message::new_call(service_daemon, "Introspect");
- system_bus.async_send(
- m, [&](const boost::system::error_code ec, dbus::message r) {
- std::string xml;
- r.unpack(xml);
- std::vector<std::string> dbus_objects;
- dbus::read_dbus_xml_names(xml, dbus_objects);
-
-
- });
- }
+ crow::json::wvalue j;
+ auto values = read_sensor_values();
- });
+ dbus::connection system_bus(*req.io_service, dbus::bus::system);
+ dbus::endpoint test_daemon("org.openbmc.Sensors",
+ "/org/openbmc/sensors/tach",
+ "org.freedesktop.DBus.Introspectable");
+ dbus::message m = dbus::message::new_call(test_daemon, "Introspect");
+ system_bus.async_send(
+ m,
+ [&j, &system_bus](const boost::system::error_code ec, dbus::message r) {
+ std::string xml;
+ r.unpack(xml);
+ std::vector<std::string> dbus_objects;
+ dbus::read_dbus_xml_names(xml, dbus_objects);
+
+ for (auto& object : dbus_objects) {
+ dbus::endpoint test_daemon("org.openbmc.Sensors",
+ "/org/openbmc/sensors/tach/" + object,
+ "org.openbmc.SensorValue");
+ dbus::message m2 = dbus::message::new_call(test_daemon, "getValue");
+
+ system_bus.async_send(
+ m2, [&](const boost::system::error_code ec, dbus::message r) {
+ int32_t value;
+ r.unpack(value);
+ // TODO(ed) if we ever go multithread, j needs a lock
+ j[object] = value;
+ });
+ }
+
+ });
});
@@ -337,6 +334,6 @@ int main(int argc, char** argv) {
auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file);
app.ssl(std::move(ssl_context));
}
- app.concurrency(4);
+ //app.concurrency(4);
app.run();
}