TEST_F(EnrollTests, test_enroll_key_retrieval) { FLAGS_disable_enrollment = true; // Without enrollment, and with an empty nodeKey storage value, no node key // will be fetched or returned from cached. EXPECT_EQ(getNodeKey("test_simple"), ""); // Turn the enrollment features back on and expect a key. FLAGS_disable_enrollment = false; EXPECT_EQ(getNodeKey("test_simple"), "fetched_a_node_key"); }
Status TLSConfigPlugin::setUp() { if (FLAGS_enroll_always && !FLAGS_disable_enrollment) { // clear any cached node key clearNodeKey(); auto node_key = getNodeKey("tls"); if (node_key.size() == 0) { // Could not generate a node key, continue logging to stderr. return Status(1, "No node key, TLS config failed."); } } uri_ = TLSRequestHelper::makeURI(FLAGS_config_tls_endpoint); return Status(0, "OK"); }
TEST_F(EnrollTests, test_enroll_key_caching) { // Cause a fetch of the node key. auto node_key = getNodeKey("test_simple"); // Now fetch the time the node key was last cached from the database. std::string key_time; auto status = getDatabaseValue(kPersistentSettings, "nodeKeyTime", key_time); EXPECT_TRUE(status.ok()); // A subsequent call to getNodeKey will return the same node key. // But, our simple enroll plugin is not enforcing any secret check and is // always returning the same node key. auto node_key2 = getNodeKey("test_simple"); // In most scenarios subsequent calls to EnrollPlugin::enroll and the backing // enrollment service will generate and return different node keys. EXPECT_EQ(node_key2, node_key); // To work around our contrived example we make sure the node time was not // updated, meaning no call to EnrollPlugin::enroll occurred. std::string key_time2; getDatabaseValue(kPersistentSettings, "nodeKeyTime", key_time2); EXPECT_EQ(key_time2, key_time); }
Status TLSLoggerPlugin::init(const std::string& name, const std::vector<StatusLogLine>& log) { auto node_key = getNodeKey("tls"); if (node_key.size() == 0) { // Could not generate an enrollment key, continue logging to stderr. FLAGS_logtostderr = true; } else { // Start the log forwarding/flushing thread. Dispatcher::addService(std::make_shared<TLSLogForwarderRunner>(node_key)); } // Restart the glog facilities using the name init was provided. google::ShutdownGoogleLogging(); google::InitGoogleLogging(name.c_str()); return logStatus(log); }
Status TLSLogForwarder::send(std::vector<std::string>& log_data, const std::string& log_type) { pt::ptree params; params.put<std::string>("node_key", getNodeKey("tls")); params.put<std::string>("log_type", log_type); { // Read each logged line into JSON and populate a list of lines. // The result list will use the 'data' key. pt::ptree children; iterate(log_data, ([&children](std::string& item) { // Enforce a max log line size for TLS logging. if (item.size() > FLAGS_logger_tls_max) { LOG(WARNING) << "Line exceeds TLS logger max: " << item.size(); return; } pt::ptree child; try { std::stringstream input; input << item; std::string().swap(item); pt::read_json(input, child); } catch (const pt::json_parser::json_parser_error& /* e */) { // The log line entered was not valid JSON, skip it. return; } children.push_back(std::make_pair("", std::move(child))); })); params.add_child("data", std::move(children)); } // The response body is ignored (status is set appropriately by // TLSRequestHelper::go()) std::string response; if (FLAGS_logger_tls_compress) { params.put("_compress", true); } return TLSRequestHelper::go<JSONSerializer>(uri_, params, response); }
Status Carver::postCarve(const boost::filesystem::path& path) { auto startRequest = Request<TLSTransport, JSONSerializer>(startUri_); // Perform the start request to get the session id PlatformFile pFile(path.string(), PF_OPEN_EXISTING | PF_READ); auto blkCount = static_cast<size_t>(ceil(static_cast<double>(pFile.size()) / static_cast<double>(FLAGS_carver_block_size))); pt::ptree startParams; startParams.put<size_t>("block_count", blkCount); startParams.put<size_t>("block_size", FLAGS_carver_block_size); startParams.put<size_t>("carve_size", pFile.size()); startParams.put<std::string>("carve_id", carveGuid_); startParams.put<std::string>("request_id", requestId_); startParams.put<std::string>("node_key", getNodeKey("tls")); auto status = startRequest.call(startParams); if (!status.ok()) { return status; } // The call succeeded, store the session id for future posts boost::property_tree::ptree startRecv; status = startRequest.getResponse(startRecv); if (!status.ok()) { return status; } auto session_id = startRecv.get("session_id", ""); if (session_id.empty()) { return Status(1, "No session_id received from remote endpoint"); } auto contRequest = Request<TLSTransport, JSONSerializer>(contUri_); for (size_t i = 0; i < blkCount; i++) { std::vector<char> block(FLAGS_carver_block_size, 0); auto r = pFile.read(block.data(), FLAGS_carver_block_size); if (r != FLAGS_carver_block_size && r > 0) { // resize the buffer to size we read as last block is likely smaller block.resize(r); } pt::ptree params; params.put<size_t>("block_id", i); params.put<std::string>("session_id", session_id); params.put<std::string>("request_id", requestId_); params.put<std::string>( "data", base64Encode(std::string(block.begin(), block.end()))); // TODO: Error sending files. status = contRequest.call(params); if (!status.ok()) { VLOG(1) << "Post of carved block " << i << " failed: " << status.getMessage(); continue; } } updateCarveValue(carveGuid_, "status", "SUCCESS"); return Status(0, "Ok"); };