Supports DevTools socket access authentication based on Android permissions.
BUG=399567
Review URL: https://codereview.chromium.org/382143005
Cr-Commit-Position: refs/heads/master@{#288273}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288273 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/socket/unix_domain_client_socket_posix_unittest.cc b/net/socket/unix_domain_client_socket_posix_unittest.cc
index d791122..d22aaf6 100644
--- a/net/socket/unix_domain_client_socket_posix_unittest.cc
+++ b/net/socket/unix_domain_client_socket_posix_unittest.cc
@@ -21,10 +21,14 @@
const char kSocketFilename[] = "socket_for_testing";
-bool UserCanConnectCallback(bool allow_user, uid_t uid, gid_t gid) {
+bool UserCanConnectCallback(
+ bool allow_user, const UnixDomainServerSocket::Credentials& credentials) {
// Here peers are running in same process.
- EXPECT_EQ(getuid(), uid);
- EXPECT_EQ(getgid(), gid);
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ EXPECT_EQ(getpid(), credentials.process_id);
+#endif
+ EXPECT_EQ(getuid(), credentials.user_id);
+ EXPECT_EQ(getgid(), credentials.group_id);
return allow_user;
}
diff --git a/net/socket/unix_domain_listen_socket_posix.cc b/net/socket/unix_domain_listen_socket_posix.cc
index 7bab4ff..dc7c19c9 100644
--- a/net/socket/unix_domain_listen_socket_posix.cc
+++ b/net/socket/unix_domain_listen_socket_posix.cc
@@ -113,10 +113,9 @@
SocketDescriptor conn = StreamListenSocket::AcceptSocket();
if (conn == kInvalidSocket)
return;
- uid_t user_id;
- gid_t group_id;
- if (!UnixDomainServerSocket::GetPeerIds(conn, &user_id, &group_id) ||
- !auth_callback_.Run(user_id, group_id)) {
+ UnixDomainServerSocket::Credentials credentials;
+ if (!UnixDomainServerSocket::GetPeerCredentials(conn, &credentials) ||
+ !auth_callback_.Run(credentials)) {
if (IGNORE_EINTR(close(conn)) < 0)
LOG(ERROR) << "close() error";
return;
diff --git a/net/socket/unix_domain_listen_socket_posix_unittest.cc b/net/socket/unix_domain_listen_socket_posix_unittest.cc
index 5fe50173..6fcbfd5 100644
--- a/net/socket/unix_domain_listen_socket_posix_unittest.cc
+++ b/net/socket/unix_domain_listen_socket_posix_unittest.cc
@@ -138,7 +138,7 @@
bool UserCanConnectCallback(
bool allow_user, const scoped_refptr<EventManager>& event_manager,
- uid_t, gid_t) {
+ const UnixDomainServerSocket::Credentials&) {
event_manager->Notify(
allow_user ? EVENT_AUTH_GRANTED : EVENT_AUTH_DENIED);
return allow_user;
diff --git a/net/socket/unix_domain_server_socket_posix.cc b/net/socket/unix_domain_server_socket_posix.cc
index 8f2f2d6..a81f1ce03 100644
--- a/net/socket/unix_domain_server_socket_posix.cc
+++ b/net/socket/unix_domain_server_socket_posix.cc
@@ -28,19 +28,20 @@
}
// static
-bool UnixDomainServerSocket::GetPeerIds(SocketDescriptor socket,
- uid_t* user_id,
- gid_t* group_id) {
+bool UnixDomainServerSocket::GetPeerCredentials(SocketDescriptor socket,
+ Credentials* credentials) {
#if defined(OS_LINUX) || defined(OS_ANDROID)
struct ucred user_cred;
socklen_t len = sizeof(user_cred);
if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &user_cred, &len) < 0)
return false;
- *user_id = user_cred.uid;
- *group_id = user_cred.gid;
+ credentials->process_id = user_cred.pid;
+ credentials->user_id = user_cred.uid;
+ credentials->group_id = user_cred.gid;
return true;
#else
- return getpeereid(socket, user_id, group_id) == 0;
+ return getpeereid(
+ socket, &credentials->user_id, &credentials->group_id) == 0;
#endif
}
@@ -130,10 +131,9 @@
scoped_ptr<StreamSocket>* socket) {
DCHECK(accept_socket_);
- uid_t user_id;
- gid_t group_id;
- if (!GetPeerIds(accept_socket_->socket_fd(), &user_id, &group_id) ||
- !auth_callback_.Run(user_id, group_id)) {
+ Credentials credentials;
+ if (!GetPeerCredentials(accept_socket_->socket_fd(), &credentials) ||
+ !auth_callback_.Run(credentials)) {
accept_socket_.reset();
return false;
}
diff --git a/net/socket/unix_domain_server_socket_posix.h b/net/socket/unix_domain_server_socket_posix.h
index 06fb8d3..85c743d2 100644
--- a/net/socket/unix_domain_server_socket_posix.h
+++ b/net/socket/unix_domain_server_socket_posix.h
@@ -25,20 +25,30 @@
// Linux and Android.
class NET_EXPORT UnixDomainServerSocket : public ServerSocket {
public:
+ // Credentials of a peer process connected to the socket.
+ struct NET_EXPORT Credentials {
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ // Linux/Android API provides more information about the connected peer
+ // than Windows/OS X. It's useful for permission-based authorization on
+ // Android.
+ pid_t process_id;
+#endif
+ uid_t user_id;
+ gid_t group_id;
+ };
+
// Callback that returns whether the already connected client, identified by
- // its process |user_id| and |group_id|, is allowed to keep the connection
- // open. Note that the socket is closed immediately in case the callback
- // returns false.
- typedef base::Callback<bool (uid_t user_id, gid_t group_id)> AuthCallback;
+ // its credentials, is allowed to keep the connection open. Note that
+ // the socket is closed immediately in case the callback returns false.
+ typedef base::Callback<bool (const Credentials&)> AuthCallback;
UnixDomainServerSocket(const AuthCallback& auth_callack,
bool use_abstract_namespace);
virtual ~UnixDomainServerSocket();
- // Gets UID and GID of peer to check permissions.
- static bool GetPeerIds(SocketDescriptor socket_fd,
- uid_t* user_id,
- gid_t* group_id);
+ // Gets credentials of peer to check permissions.
+ static bool GetPeerCredentials(SocketDescriptor socket_fd,
+ Credentials* credentials);
// ServerSocket implementation.
virtual int Listen(const IPEndPoint& address, int backlog) OVERRIDE;
diff --git a/net/socket/unix_domain_server_socket_posix_unittest.cc b/net/socket/unix_domain_server_socket_posix_unittest.cc
index 07209f6..d8a5281 100644
--- a/net/socket/unix_domain_server_socket_posix_unittest.cc
+++ b/net/socket/unix_domain_server_socket_posix_unittest.cc
@@ -24,10 +24,14 @@
const char kSocketFilename[] = "socket_for_testing";
const char kInvalidSocketPath[] = "/invalid/path";
-bool UserCanConnectCallback(bool allow_user, uid_t uid, gid_t gid) {
+bool UserCanConnectCallback(bool allow_user,
+ const UnixDomainServerSocket::Credentials& credentials) {
// Here peers are running in same process.
- EXPECT_EQ(getuid(), uid);
- EXPECT_EQ(getgid(), gid);
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ EXPECT_EQ(getpid(), credentials.process_id);
+#endif
+ EXPECT_EQ(getuid(), credentials.user_id);
+ EXPECT_EQ(getgid(), credentials.group_id);
return allow_user;
}