summaryrefslogtreecommitdiffstats
path: root/proxy/src/gp_socket.c
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-06-21 20:36:20 -0400
committerGünther Deschner <gdeschner@redhat.com>2013-07-02 16:17:23 +0200
commitacc3b87b655cf7c6c0c7d698f5a5867b6732a69f (patch)
tree97f3d944770bfc78c92f1fff854d66b78df76de7 /proxy/src/gp_socket.c
parentf66a585e042fbb2f313c1cbde329088fac86cea6 (diff)
downloadgss-proxy-acc3b87b655cf7c6c0c7d698f5a5867b6732a69f.tar.gz
gss-proxy-acc3b87b655cf7c6c0c7d698f5a5867b6732a69f.tar.xz
gss-proxy-acc3b87b655cf7c6c0c7d698f5a5867b6732a69f.zip
Add service match using SeLinux Context
Using getpeercon we can know the elinux context of the process talking to gssproxy. Use this information as an optional additional filter to match processes to service definitions. If a selinux_context option with a full user;role;type context is specified into a service section, then the connecting process must also be running under the specified selinux context in order to be allowed to connect. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Günther Deschner <gdeschner@redhat.com>
Diffstat (limited to 'proxy/src/gp_socket.c')
-rw-r--r--proxy/src/gp_socket.c67
1 files changed, 54 insertions, 13 deletions
diff --git a/proxy/src/gp_socket.c b/proxy/src/gp_socket.c
index 02bc882..24eed28 100644
--- a/proxy/src/gp_socket.c
+++ b/proxy/src/gp_socket.c
@@ -35,13 +35,7 @@
#include <netinet/in.h>
#include "gp_proxy.h"
#include "gp_creds.h"
-
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#define SEC_CTX security_context_t
-#else
-#define SEC_CTX void *
-#endif /* HAVE_SELINUX */
+#include "gp_selinux.h"
#define FRAGMENT_BIT (1 << 31)
@@ -58,7 +52,7 @@ struct gp_conn {
struct gp_sock_ctx *sock_ctx;
struct unix_sock_conn us;
struct gp_creds creds;
- SEC_CTX secctx;
+ SELINUX_CTX selinux_ctx;
};
struct gp_buffer {
@@ -68,6 +62,40 @@ struct gp_buffer {
size_t pos;
};
+bool gp_conn_check_selinux(struct gp_conn *conn, SELINUX_CTX ctx)
+{
+ const char *ra, *rb;
+
+ if (ctx == NULL) {
+ return true;
+ }
+
+ if (!(conn->creds.type | CRED_TYPE_SELINUX) ||
+ (conn->selinux_ctx == NULL)) {
+ return false;
+ }
+
+ if (strcmp(SELINUX_context_user_get(ctx),
+ SELINUX_context_user_get(conn->selinux_ctx)) != 0) {
+ return false;
+ }
+ if (strcmp(SELINUX_context_role_get(ctx),
+ SELINUX_context_role_get(conn->selinux_ctx)) != 0) {
+ return false;
+ }
+ if (strcmp(SELINUX_context_type_get(ctx),
+ SELINUX_context_type_get(conn->selinux_ctx)) != 0) {
+ return false;
+ }
+ ra = SELINUX_context_range_get(ctx);
+ rb = SELINUX_context_range_get(conn->selinux_ctx);
+ if (ra && rb && (strcmp(ra, rb) != 0)) {
+ return false;
+ }
+
+ return true;
+}
+
struct gp_creds *gp_conn_get_creds(struct gp_conn *conn)
{
return &conn->creds;
@@ -85,6 +113,7 @@ void gp_conn_free(struct gp_conn *conn)
if (conn->us.sd != -1) {
close(conn->us.sd);
}
+ SELINUX_context_free(conn->selinux_ctx);
free(conn);
}
@@ -202,6 +231,7 @@ done:
static int get_peercred(int fd, struct gp_conn *conn)
{
+ SEC_CTX secctx;
socklen_t len;
int ret;
@@ -219,17 +249,17 @@ static int get_peercred(int fd, struct gp_conn *conn)
conn->creds.type |= CRED_TYPE_UNIX;
-#ifdef HAVE_SELINUX
- ret = getpeercon(fd, &conn->secctx);
+ ret = SELINUX_getpeercon(fd, &secctx);
if (ret == 0) {
conn->creds.type |= CRED_TYPE_SELINUX;
+ conn->selinux_ctx = SELINUX_context_new(secctx);
+ SELINUX_freecon(secctx);
} else {
ret = errno;
GPDEBUG("Failed to get peer's SELinux context (%d:%s)\n",
ret, strerror(ret));
/* consider thisnot fatal, selinux may be disabled */
}
-#endif /* HAVE_SELINUX */
return 0;
}
@@ -507,8 +537,6 @@ void accept_sock_conn(verto_ctx *vctx, verto_ev *ev)
}
conn->us.sd = fd;
- GPDEBUG("Client connected(fd = %d)\n", fd);
-
ret = set_status_flags(fd, O_NONBLOCK);
if (ret) {
GPDEBUG("Failed to set O_NONBLOCK on %d!\n", fd);
@@ -526,6 +554,19 @@ void accept_sock_conn(verto_ctx *vctx, verto_ev *ev)
goto done;
}
+ GPDEBUG("Client connected (fd = %d)", fd);
+ if (conn->creds.type & CRED_TYPE_UNIX) {
+ GPDEBUG(" (pid = %d) (uid = %d) (gid = %d)",
+ conn->creds.ucred.pid,
+ conn->creds.ucred.uid,
+ conn->creds.ucred.gid);
+ }
+ if (conn->creds.type & CRED_TYPE_SELINUX) {
+ GPDEBUG(" (context = %s)",
+ SELINUX_context_str(conn->selinux_ctx));
+ }
+ GPDEBUG("\n");
+
gp_setup_reader(vctx, conn);
ret = 0;