${SERVER2_PATH}/main/dbus-manager.cpp
${SERVER2_PATH}/client/usb-access-client.cpp
${SERVER2_PATH}/client/client-common.cpp
+ ${SERVER2_PATH}/service/usb-ask-user-service.cpp
+ ${SERVER2_PATH}/service/add-permission.cpp
)
SET_SOURCE_FILES_PROPERTIES(
SET(USD_CLIENT_SOURCES
${SERVER2_PATH}/client/client-common.cpp
${SERVER2_PATH}/client/usb-access-client.cpp
+ ${SERVER2_PATH}/client/usb-ask-user-client.cpp
)
ADD_LIBRARY(${TARGET_USD_CLIENT} SHARED ${USD_CLIENT_SOURCES})
*/
namespace {
-const int POLL_TIMEOUT = 2000;
+const int POLL_TIMEOUT = 60000;
void securityClientEnableLogSystem(void) {
USD::Singleton<USD::Log::LogSystem>::Instance().SetTag("USD_CLIENT");
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Karol Lewandowski <k.lewandowsk@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with 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
+ */
+/*
+ * @file usb-ask-user-client.cpp
+ * @author Jan Cybulski <j.cybulski@samsung.com>
+ * @version 1.0
+ * @brief This file is implementation of client side functions for service
+ * which manages popups to user.
+ */
+
+#include <stdio.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <message-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+
+#include <usb-security-daemon.h>
+
+_USD_API_
+int usd_ask_user_to_grant_permission(const char *path) {
+ using namespace USD;
+
+ return try_catch([&] {
+ if (NULL == path){
+ LogDebug("path is NULL");
+ return USD_API_ERROR_INPUT_PARAM;
+ }
+
+ MessageBuffer send, recv;
+ Serialization::Serialize(send, std::string(path));
+
+ int retCode = sendToServer(
+ SERVICE_SOCKET_ASK_USER,
+ send.Pop(),
+ recv);
+
+ if (retCode == USD_API_SUCCESS) {
+ Deserialization::Deserialize(recv, retCode);
+ }
+
+ return retCode;
+
+ });
+}
+
char const * const SERVICE_SOCKET_USB_ACCESS =
SOCKET_PATH_PREFIX_USD "usd-api-usb-access.socket";
+char const * const SERVICE_SOCKET_ASK_USER =
+ SOCKET_PATH_PREFIX_USD "usd-api-ask-user.socket";
+
} // namespace USD
/*
- * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Bumjin Im <bj.im@samsung.com>
*
namespace USD {
extern char const *const SERVICE_SOCKET_USB_ACCESS;
+extern char const *const SERVICE_SOCKET_ASK_USER;
enum class USBAccessCall
{
/*! \brief indicating file read error */
#define USD_API_ERROR_FILE_READ_FAILED -28
+/*! \brief indicating that there is yet policy set for device*/
+#define USD_API_ERROR_POLICY_UNKNOWN -29
+
/*! \brief indicating the error with unknown reason */
#define USD_API_ERROR_UNKNOWN -255
/** @}*/
int usd_setup_usb_device_access(const char *topology, const char *smack,
bool allow);
+int usd_ask_user_to_grant_permission(const char *path);
+
#ifdef __cplusplus
}
#endif
#include <thread>
#include <string>
#include <dpl/log/log.h>
+#include <add-permission.h>
namespace USD {
bool DbusManager::handlePopup(pid_t pid, int popupResult) {
std::lock_guard<std::mutex> lock(m_popupHandleMutex);
- //PopupData *popupData;
+ USBAddPermission addPerm;
auto it = m_popupMap.find(pid);
if (it != m_popupMap.end()) {
- //popupData = &*it;
const char *device = getPopupDevice(pid);
const char *application = getPopupApp(pid);
bool allow = (popupResult == USB_DEVICE_CONFIRM_OK);
LogDebug("Got popup answer notify from pid" << pid);
this->m_popupMap.erase(pid);
- usd_setup_usb_device_access(device, application, allow);
+ addPerm.writePermission(device, application, allow);
return true;
}
LogWarning("Someone tries to fake popup answer data... ");
#include <usb-access.h>
+#include <usb-ask-user-service.h>
IMPLEMENT_SAFE_SINGLETON(USD::Log::LogSystem);
LogInfo("Start!");
USD::SocketManager manager;
-
REGISTER_SOCKET_SERVICE(manager, USD::USBAccessService);
+ REGISTER_SOCKET_SERVICE(manager, USD::UsbAskUserService);
dbusmanager.Create();
manager.MainLoop();
dbusmanager.Join();
namespace {
-const time_t SOCKET_TIMEOUT = 20;
+const time_t SOCKET_TIMEOUT = 60;
} // namespace anonymous
--- /dev/null
+/*-*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-*/
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Stanislaw Wadas <s.wadas@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with 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
+ */
+/*
+ * @file add-permission.cpp
+ * @author Stanislaw Wadas <s.wadas@samsung.com>
+ * @version 1.0
+ */
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <protocols.h>
+#include <usb-security-daemon.h>
+#include <usd-util.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <add-permission.h>
+#include <usb-access.h>
+#include <usb-access-map.h>
+#include <dbus-manager.h>
+#include <cstdint>
+
+namespace USD {
+
+USBAccessMap m_accessMap;
+
+int USBAddPermission::writePermission(const char *path, const char *smack, bool policy)
+{
+ using namespace USD;
+
+ LogDebug("Processing writePermission");
+
+ int retCode = USD_API_ERROR_SERVER_ERROR;
+
+ try {
+ std::string smack1, path1;
+ bool valid;
+ path1 = std::string(path);
+ smack1 = std::string(smack);
+
+ USBAccessMapKey mk(smack1,
+ USBDeviceId(path1, USBDevicePath::PATH_TYPE_SYSFS));
+
+ LogDebug("policy: " << policy
+ << ", smack: " << smack << ", path: " << path1);
+
+ valid = mk.validate();
+ LogDebug("Validation" << (valid ? "ok" : "failed")
+ <<" on: " << mk << ", policy: " << policy);
+
+ if (valid) {
+ std::lock_guard<std::mutex> lock(m_eventWriteDBMutex);
+ m_accessMap[mk] = policy;
+ retCode = USD_API_SUCCESS;
+ } else {
+ retCode = USD_API_ERROR_ACCESS_DENIED;
+ LogDebug("SD_API_ERROR_ACCESS_DENIED");
+ }
+ } catch(int e) {
+ LogDebug("Error occured on processing: " << e);
+ retCode = e;
+ }
+
+ return retCode;
+}
+
+} // namespace USD
--- /dev/null
+/*-*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-*/
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Stanislaw Wadas <s.wadas@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with 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
+ */
+/*
+ * @file add-permission.h
+ * @author Stanislaw Wadas <s.wadas@samsung.com>
+ * @version 1.0
+ */
+
+#ifndef USD_ADD_PERMISSION_H_
+#define USD_ADD_PERMISSION_H_
+
+#include <usb-access-map.h>
+#include <usb-access.h>
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <dpl/serialization.h>
+#include <message-buffer.h>
+#include <usb-access-map.h>
+#include <mutex>
+
+
+namespace USD {
+
+extern USBAccessMap m_accessMap;
+
+
+class USBAddPermission
+
+{
+public:
+ int writePermission(const char *topology, const char *smack, bool allow);
+
+private:
+ std::mutex m_eventWriteDBMutex;
+};
+
+} /* namespace USD */
+
+#endif /* USD_USB_ACCESS_H_ */
#include <usb-access.h>
#include <usb-access-map.h>
+#include <dbus-manager.h>
+#include <add-permission.h>
namespace {
// Service may open more than one socket.
} // namespace anonymous
-
+extern USD::DbusManager dbusmanager;
namespace USD {
m_serviceManager->Close(event.connectionID);
}
-bool USBAccessService::checkAccessEntry(PolicySubjectId subjectId,
+int USBAccessService::checkAccessEntry(PolicySubjectId subjectId,
const USBDeviceId &devId)
{
USBAccessMapKey key(subjectId, devId);
auto it = m_accessMap.find(key);
if (it == m_accessMap.end()) {
- LogDebug("There is no entry in the database. Return deny.");
- return false;
+ LogDebug("There is no entry in the database.");
+ return USD_API_ERROR_POLICY_UNKNOWN;
}
LogDebug("There is an entry in a database. "
- "Return value of policy: " << it->second);
+ "Value of policy: " << it->second);
- return it->second;
+ return it->second ? USD_API_SUCCESS : USD_API_ERROR_ACCESS_DENIED;
}
static inline int openFileForClient(const char *path, int &fd)
try {
std::string path;
- bool accessGranted;
PolicySubjectId peerId(conn.sock);
Deserialization::Deserialize(buffer, path);
USBDeviceId devId(path, USBDevicePath::PATH_TYPE_DEV);
- accessGranted = checkAccessEntry(peerId, devId);
- if (accessGranted || true) {
+ retCode = checkAccessEntry(peerId, devId);
+ if (retCode == USD_API_ERROR_POLICY_UNKNOWN) {
+ USBAccessMapKey mapkey(peerId, devId);
+ pid_t pid = dbusmanager.addPopupRequest(mapkey);
+ if (dbusmanager.waitForPopupHandled(pid))
+ retCode = checkAccessEntry(peerId, devId);
+ else
+ retCode = USD_API_ERROR_POLICY_UNKNOWN;
+ }
+
+ if (retCode == USD_API_SUCCESS) {
LogDebug("Access granted for opening: "
<< path << " which belongs to: " << devId
<< " by: " << peerId);
retCode = openFileForClient(path.c_str(), fd);
- } else {
- retCode = USD_API_ERROR_ACCESS_DENIED;
+ }
+ else {
+ LogDebug("Access denied for opening: "
+ << path << " which belongs to: " << devId
+ << " by: " << peerId << " Error code: " << retCode);
}
} catch(int e) {
retCode = e;
LogDebug("Validation" << (valid ? "ok" : "failed")
<<" on: " << mk << ", policy: " << policy);
if (valid) {
+ std::lock_guard<std::mutex> lock(m_eventWriteDBMutex);
m_accessMap[mk] = policy;
retCode = USD_API_SUCCESS;
} else {
bool processOne(const ConnectionID &conn, MessageBuffer &buffer);
bool processOpen(const ConnectionID &conn, MessageBuffer &buffer);
bool processSetupPolicy(const ConnectionID &conn, MessageBuffer &buffer);
- bool checkAccessEntry(PolicySubjectId subjectId, const USBDeviceId &devId);
+ int checkAccessEntry(PolicySubjectId subjectId, const USBDeviceId &devId);
+ std::mutex m_eventWriteDBMutex;
MessageBufferMap m_messageBufferMap;
- USBAccessMap m_accessMap;
};
} /* namespace USD */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Karol Lewandowski <k.lewandowsk@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with 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
+ */
+/*
+ * @file usb-ask-user-service.cpp
+ * @author Jan Cybulski <j.cybulski@samsung.com>
+ * @version 1.0
+ * @brief Implementation of service asking users for access.
+ */
+
+#include <sys/smack.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <dpl/exception.h>
+
+
+#include <protocols.h>
+#include <usb-ask-user-service.h>
+
+#include <usb-security-daemon.h>
+#include <usd-util.h>
+#include <smack-check.h>
+
+#include <usb-access-map.h>
+#include <dbus-manager.h>
+
+
+extern USD::DbusManager dbusmanager;
+
+
+namespace USD {
+
+
+
+UsbAskUserService::ServiceDescriptionVector UsbAskUserService::GetServiceDescription() {
+ return ServiceDescriptionVector
+ {{SERVICE_SOCKET_ASK_USER, "usd::api-ask-user" }};
+}
+
+void UsbAskUserService::accept(const AcceptEvent &event) {
+ LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+ << " ConnectionID.counter: " << event.connectionID.counter
+ << " ServiceID: " << event.interfaceID);
+}
+
+void UsbAskUserService::write(const WriteEvent &event) {
+ LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+ " Size: " << event.size << " Left: " << event.left);
+ if (event.left == 0)
+ m_serviceManager->Close(event.connectionID);
+}
+
+bool UsbAskUserService::processOne(const ConnectionID &conn, MessageBuffer &buffer) {
+ LogDebug("Iteration begin");
+
+ std::string path;
+
+
+ int retCode = USD_API_ERROR_SERVER_ERROR;
+
+
+ if (!buffer.Ready()) {
+ return false;
+ }
+
+ Try {
+ Deserialization::Deserialize(buffer, path);
+ PolicySubjectId subject(conn.sock);
+ USBDeviceId device(path, USBDevicePath::PATH_TYPE_DEV);
+ USBAccessMapKey mk(subject, device);
+ pid_t pid = dbusmanager.addPopupRequest(mk);
+ if (dbusmanager.waitForPopupHandled(pid))
+ retCode = USD_API_SUCCESS;
+ else
+ retCode = USD_API_ERROR_AUTHENTICATION_FAILED;
+ } Catch (MessageBuffer::Exception::Base) {
+ LogError("Broken protocol. Closing socket.");
+ m_serviceManager->Close(conn);
+ return false;
+ } catch (int e) {
+ LogError("Something wrong, ret code: " << e);
+ } catch (...) {
+ LogError("Something wrong.");
+ }
+ LogDebug("Processing finished, returning " << retCode);
+ MessageBuffer sendBuffer;
+ Serialization::Serialize(sendBuffer, retCode);
+ m_serviceManager->Write(conn, sendBuffer.Pop());
+
+ return true;
+}
+
+void UsbAskUserService::process(const ReadEvent &event) {
+ LogDebug("Read event for counter: " << event.connectionID.counter);
+ auto &buffer = m_messageBufferMap[event.connectionID.counter];
+ buffer.Push(event.rawBuffer);
+
+ // We can get several requests in one package.
+ // Extract and process them all
+ while(processOne(event.connectionID, buffer));
+}
+
+void UsbAskUserService::close(const CloseEvent &event) {
+ LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+ m_messageBufferMap.erase(event.connectionID.counter);
+}
+
+} /* namespace USD */
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Karol Lewandowski <k.lewandowsk@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with 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
+ */
+/*
+ * @file usb-ask-user-service.cpp
+ * @author Jan Cybulski <j.cybulski@samsung.com>
+ * @version 1.0
+ * @brief Implementation of service asking users for access.
+ */
+
+#ifndef _USD_ASK_USER_SERVICE_
+#define _USD_ASK_USER_SERVICE_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <dpl/serialization.h>
+#include <message-buffer.h>
+#include <usb-access-map.h>
+
+
+namespace USD {
+
+class UsbAskUserService :
+ public USD::GenericSocketService
+ , public USD::ServiceThread<UsbAskUserService>
+{
+public:
+ typedef std::map<int, MessageBuffer> MessageBufferMap;
+
+ ServiceDescriptionVector GetServiceDescription();
+
+ DECLARE_THREAD_EVENT(AcceptEvent, accept)
+ DECLARE_THREAD_EVENT(WriteEvent, write)
+ DECLARE_THREAD_EVENT(ReadEvent, process)
+ DECLARE_THREAD_EVENT(CloseEvent, close)
+
+ void accept(const AcceptEvent &event);
+ void write(const WriteEvent &event);
+ void process(const ReadEvent &event);
+ void close(const CloseEvent &event);
+private:
+ bool processOne(const ConnectionID &conn, MessageBuffer &buffer);
+ MessageBufferMap m_messageBufferMap;
+
+
+};
+
+} /* namespace USD*/
+
+#endif
INSTALL(FILES
${CMAKE_SOURCE_DIR}/USD/systemd/usd.service
${CMAKE_SOURCE_DIR}/USD/systemd/usd-access.socket
+ ${CMAKE_SOURCE_DIR}/USD/systemd/usd-ask-user.socket
DESTINATION
${SYSTEMD_DIR}
)
--- /dev/null
+[Socket]
+ListenStream=/run/usd/usd-api-ask-user.socket
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=usd.service
+
+
+[Install]
+WantedBy=sockets.target
Type=notify
ExecStart=/usr/bin/usd
Sockets=usd-access.socket
+Sockets=usd-ask-user.socket
+
[Install]
WantedBy=multi-user.target
mkdir -p %{buildroot}%{_unitdir}/sockets.target.wants
ln -s ../usd.service %{buildroot}%{_unitdir}/multi-user.target.wants/usd.service
ln -s ../usd-access.socket %{buildroot}%{_unitdir}/sockets.target.wants/usd-access.socket
+ln -s ../usd-ask-user.socket %{buildroot}%{_unitdir}/sockets.target.wants/usd-ask-user.socket
%post -p /sbin/ldconfig
%attr(-,root,root) %{_unitdir}/multi-user.target.wants/usd.service
%attr(-,root,root) %{_unitdir}/usd.service
%attr(-,root,root) %{_unitdir}/sockets.target.wants/usd-access.socket
+%attr(-,root,root) %{_unitdir}/sockets.target.wants/usd-ask-user.socket
%attr(-,root,root) %{_unitdir}/usd-access.socket
+%attr(-,root,root) %{_unitdir}/usd-ask-user.socket
%{_datadir}/license/%{name}
%files libusd-client