Merge branch 'issue/54'

This commit is contained in:
Daniel Roethlisberger 2014-11-13 22:19:21 +01:00
commit 767f02aadb
3 changed files with 129 additions and 6 deletions

View File

@ -111,8 +111,10 @@ typedef struct pxy_conn_ctx {
unsigned int enomem : 1; /* 1 if out of memory */
unsigned int sni_peek_retries : 6; /* max 64 SNI parse retries */
/* local process id, or -1 */
pid_t local_pid;
/* local process ids, or -1 */
pid_t pid;
uid_t uid;
gid_t gid;
/* server name indicated by client in SNI TLS extension */
char *sni;
@ -136,6 +138,11 @@ typedef struct pxy_conn_ctx {
char *ssl_names;
char *ssl_orignames;
/* log strings from process info */
char *exec_path;
char *user;
char *group;
/* content log context */
log_content_ctx_t logctx;
@ -176,7 +183,7 @@ pxy_conn_ctx_new(proxyspec_t *spec, opts_t *opts,
ctx->spec = spec;
ctx->opts = opts;
ctx->fd = fd;
ctx->local_pid = -1;
ctx->pid = -1;
ctx->thridx = pxy_thrmgr_attach(thrmgr, &ctx->evbase, &ctx->dnsbase);
ctx->thrmgr = thrmgr;
#ifdef DEBUG_PROXY
@ -233,6 +240,15 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx)
if (ctx->ssl_orignames) {
free(ctx->ssl_orignames);
}
if (ctx->exec_path) {
free(ctx->exec_path);
}
if (ctx->user) {
free(ctx->user);
}
if (ctx->group) {
free(ctx->group);
}
if (ctx->origcrt) {
X509_free(ctx->origcrt);
}
@ -1924,7 +1940,7 @@ pxy_conn_setup(evutil_socket_t fd,
/* NAT engine lookup */
ctx->addrlen = sizeof(struct sockaddr_storage);
if (spec->natlookup((struct sockaddr *)&ctx->addr,
&ctx->addrlen, &ctx->local_pid, fd,
&ctx->addrlen, &ctx->pid, fd,
peeraddr, peeraddrlen) == -1) {
log_err_printf("Connection not found in NAT "
"state table, aborting connection\n");
@ -1954,8 +1970,14 @@ pxy_conn_setup(evutil_socket_t fd,
if (!ctx->src_str)
goto memout;
if (ctx->local_pid != -1) {
// TODO
if (ctx->pid != -1) {
if (sys_proc_info(ctx->pid, &ctx->exec_path, &ctx->uid, &ctx->gid) == 0) {
ctx->user = sys_user_str(ctx->uid);
ctx->group = sys_group_str(ctx->gid);
if (!ctx->user || !ctx->group) {
goto memout;
}
}
}
}

96
sys.c
View File

@ -50,6 +50,10 @@
#include <sys/sysctl.h>
#endif /* !_SC_NPROCESSORS_ONLN */
#if HAVE_DARWIN_LIBPROC
#include <libproc.h>
#endif
#include <event2/util.h>
/*
@ -193,6 +197,98 @@ sys_pidf_close(int fd, const char *fn)
close(fd);
}
/*
* Fetch process info for the given pid.
* On success, returns 0 and fills in path, uid, and gid.
* Caller must free returned path string.
* Returns -1 on failure, or if unsupported on this platform.
*/
int
sys_proc_info(pid_t pid, char **path, uid_t *uid, gid_t *gid) {
#if HAVE_DARWIN_LIBPROC
/* fetch process structure */
struct proc_bsdinfo bsd_info;
if (proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &bsd_info, sizeof(bsd_info)) == -1) {
return -1;
}
*uid = bsd_info.pbi_uid;
*gid = bsd_info.pbi_gid;
/* fetch process path */
*path = malloc(PROC_PIDPATHINFO_MAXSIZE);
if (!*path) {
return -1;
}
int path_len = proc_pidpath(pid, *path, PROC_PIDPATHINFO_MAXSIZE);
if (path_len == -1) {
free(*path);
return -1;
}
return 0;
#else
/* unsupported */
return -1;
#endif
}
/*
* Converts a local uid into a printable string representation.
* Returns an allocated buffer which must be freed by caller, or NULL on error.
*/
char *
sys_user_str(uid_t uid)
{
int bufsize;
if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
log_err_printf("failed to get password bufsize: %s\n",
strerror(errno));
return NULL;
}
char buffer[bufsize];
struct passwd pwd, *result = NULL;
if (getpwuid_r(uid, &pwd, buffer, bufsize, &result) != 0 || !result) {
/* no entry found; return the integer representation */
char *name;
if (asprintf(&name, "%llu", (long long) uid) == -1) {
return NULL;
}
return name;
}
return strdup(pwd.pw_name);
}
/*
* Converts a local gid into a printable string representation.
* Returns an allocated buffer which must be freed by caller, or NULL on error.
*/
char *
sys_group_str(gid_t gid)
{
int bufsize;
if ((bufsize = sysconf(_SC_GETGR_R_SIZE_MAX)) == -1) {
log_err_printf("failed to get group bufsize: %s\n",
strerror(errno));
return NULL;
}
char buffer[bufsize];
struct group grp, *result = NULL;
if (getgrgid_r(gid, &grp, buffer, bufsize, &result) != 0 || !result) {
/* no entry found; return the integer representation */
char *name;
if (asprintf(&name, "%llu", (long long) gid) == -1) {
return NULL;
}
return name;
}
return strdup(grp.gr_name);
}
/*
* Parse an ascii host/IP and port tuple into a sockaddr_storage.
* On success, returns address family and fills in addr, addrlen.

5
sys.h
View File

@ -41,6 +41,11 @@ int sys_pidf_open(const char *) NONNULL(1) WUNRES;
int sys_pidf_write(int) WUNRES;
void sys_pidf_close(int, const char *) NONNULL(2);
int sys_proc_info(pid_t, char **, uid_t *, gid_t *) WUNRES NONNULL(2,3,4);
char * sys_user_str(uid_t) WUNRES MALLOC;
char * sys_group_str(gid_t) WUNRES MALLOC;
int sys_sockaddr_parse(struct sockaddr_storage *, socklen_t *,
char *, char *, int, int) NONNULL(1,2,3,4) WUNRES;
char * sys_sockaddr_str(struct sockaddr *, socklen_t) NONNULL(1) MALLOC;