Only allow root clients to talk to daemon

We don't want normal users on the system to be able to
manipulate plymouth. This will be especially important
later when we run plymouth for post-bootup reasons. This
patch checks peer credentials and sends back a NAK to
clients who aren't root.
calculate-0.9.5
Ray Strode 16 years ago
parent a4cffffd94
commit a0092f35c5

@ -1,4 +1,3 @@
- fix the tests so that they work better with "make check"
- Allow plymouth to be started from nash instead of the other way around
- Drop all the make ram disk and copy code. That was just to make bolting things on easier. We can integrate now.
- check peer credentials on client to make sure it's not running unprivileged

@ -103,6 +103,7 @@ static int
ply_open_unix_socket (const char *path)
{
int fd;
const int should_pass_credentials = true;
assert (path != NULL);
@ -120,6 +121,15 @@ ply_open_unix_socket (const char *path)
return -1;
}
if (setsockopt (fd, SOL_SOCKET, SO_PASSCRED,
&should_pass_credentials, sizeof (should_pass_credentials)) < 0)
{
ply_save_errno ();
close (fd);
ply_restore_errno ();
return -1;
}
return fd;
}
@ -232,6 +242,35 @@ ply_listen_to_unix_socket (const char *path,
return fd;
}
bool
ply_get_credentials_from_fd (int fd,
pid_t *pid,
uid_t *uid,
gid_t *gid)
{
struct ucred credentials;
socklen_t credential_size;
credential_size = sizeof (credentials);
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &credentials,
&credential_size) < 0)
return false;
if (credential_size < sizeof (credentials))
return false;
if (pid != NULL)
*pid = credentials.pid;
if (uid != NULL)
*uid = credentials.uid;
if (gid != NULL)
*gid = credentials.gid;
return true;
}
int
ply_create_unix_socket (const char *path)
{

@ -48,6 +48,10 @@ int ply_connect_to_unix_socket (const char *path,
bool is_abstract);
int ply_listen_to_unix_socket (const char *path,
bool is_abstract);
bool ply_get_credentials_from_fd (int fd,
pid_t *pid,
uid_t *uid,
gid_t *gid);
bool ply_write (int fd,
const void *buffer,

@ -30,6 +30,7 @@
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD "*"
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH "$"
#define PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK "\x6"
#define PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK "\x15"
#define PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER "\x2"
#endif /* PLY_BOOT_PROTOCOL_H */

@ -169,6 +169,17 @@ ply_boot_connection_read_request (ply_boot_connection_t *connection,
return true;
}
static bool
ply_boot_connection_is_from_root (ply_boot_connection_t *connection)
{
uid_t uid;
if (!ply_get_credentials_from_fd (connection->fd, NULL, &uid, NULL))
return false;
return uid == 0;
}
static void
ply_boot_connection_on_request (ply_boot_connection_t *connection)
{
@ -185,6 +196,18 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
&command, &argument))
return;
if (!ply_boot_connection_is_from_root (connection))
{
ply_error ("request came from non-root user");
if (!ply_write (connection->fd,
PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK,
strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
ply_error ("could not write bytes: %m");
return;
}
if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE) == 0)
{
if (server->update_handler != NULL)
@ -238,6 +261,12 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING) != 0)
{
ply_error ("received unknown command '%s' from client", command);
if (!ply_write (connection->fd,
PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK,
strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
ply_error ("could not write bytes: %m");
return;
}

Loading…
Cancel
Save