Skip to content
Permalink
Browse files

Support auth with custom service principal name

Add an optional element to the hosts spec, AUTH_NAME, which is
the "canonical" name to use for the service principal name instead
of HOSTNAME (or its corresponding fqdn). This option is useful in case of
accessing an authenticated server via ssh port forwarding, in which case
the HOSTNAME is 127.0.0.1.
  • Loading branch information...
rmatev committed May 5, 2019
1 parent 57843ec commit 5bb67e55d674669c6af427a298f8b38444307456
Showing with 57 additions and 32 deletions.
  1. +7 −1 man/distcc.1
  2. +4 −1 src/auth.h
  3. +30 −29 src/auth_distcc.c
  4. +12 −0 src/hosts.c
  5. +1 −0 src/hosts.h
  6. +2 −0 src/lock.c
  7. +1 −1 src/remote.c
@@ -516,7 +516,7 @@ The syntax is
OLDSTYLE_TCP_HOST = HOSTID[/LIMIT][:PORT][OPTIONS]
HOSTID = HOSTNAME | IPV4 | IPV6
OPTIONS = ,OPTION[OPTIONS]
OPTION = lzo | cpp | auth
OPTION = lzo | cpp | auth[=AUTH_NAME]
GLOBAL_OPTION = --randomize
ZEROCONF = +zeroconf
.fi
@@ -577,6 +577,12 @@ wrapped in the pump script in order to start the include server.
.B ,auth
Enables GSSAPI-based mutual authentication for this host.
.TP
.B AUTH_NAME
The "canonical" name to use for the service principal name instead
of HOSTNAME (or its corresponding fqdn). This option is useful in case of
accessing an authenticated server via ssh port forwarding, in which case
the HOSTNAME is 127.0.0.1.
.TP
.B --randomize
Randomize the order of the host list before execution.
.TP
@@ -27,12 +27,15 @@
/* Notification of server access denied. */
#define NO_ACCESS 'n'

struct dcc_hostdef;

int dcc_gssapi_acquire_credentials(void);
void dcc_gssapi_release_credentials(void);
int dcc_gssapi_obtain_list(int mode);
void dcc_gssapi_free_list(void);
int dcc_gssapi_check_client(int to_net_fd, int from_net_fd);
int dcc_gssapi_perform_requested_security(int to_net_fd,
int dcc_gssapi_perform_requested_security(const struct dcc_hostdef *host,
int to_net_fd,
int from_net_fd);
void dcc_gssapi_status_to_log(OM_uint32 status_code, int status_type);
void dcc_gssapi_cleanup(gss_buffer_desc *input_tok,
@@ -32,10 +32,12 @@
#include "auth.h"
#include "distcc.h"
#include "exitcode.h"
#include "hosts.h"
#include "netutil.h"
#include "trace.h"

static int dcc_gssapi_establish_secure_context(int to_net_sd,
static int dcc_gssapi_establish_secure_context(const struct dcc_hostdef *host,
int to_net_sd,
int from_net_sd,
OM_uint32 req_flags,
OM_uint32 *ret_flags);
@@ -58,14 +60,16 @@ gss_ctx_id_t distcc_ctx_handle = GSS_C_NO_CONTEXT;
*
* Returns 0 on success, otherwise error.
*/
int dcc_gssapi_perform_requested_security(int to_net_sd,
int dcc_gssapi_perform_requested_security(const struct dcc_hostdef *host,
int to_net_sd,
int from_net_sd) {
int ret;
OM_uint32 req_flags, ret_flags;

req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;

if ((ret = dcc_gssapi_establish_secure_context(to_net_sd,
if ((ret = dcc_gssapi_establish_secure_context(host,
to_net_sd,
from_net_sd,
req_flags,
&ret_flags)) != 0) {
@@ -108,7 +112,8 @@ int dcc_gssapi_perform_requested_security(int to_net_sd,
*
* Returns 0 on success, otherwise error.
*/
static int dcc_gssapi_establish_secure_context(int to_net_sd,
static int dcc_gssapi_establish_secure_context(const struct dcc_hostdef *host,
int to_net_sd,
int from_net_sd,
OM_uint32 req_flags,
OM_uint32 *ret_flags) {
@@ -126,40 +131,37 @@ static int dcc_gssapi_establish_secure_context(int to_net_sd,
struct hostent *hp;
struct sockaddr_in addr;

addr_len = sizeof(addr);
if (!host->auth_name) {
addr_len = sizeof(addr);

if ((ret = getpeername(to_net_sd, (struct sockaddr *)&addr, &addr_len)) != 0) {
rs_log_error("Failed to look up peer address using socket \"%d\": %s.",
to_net_sd,
hstrerror(h_errno));
return EXIT_CONNECT_FAILED;
}
if ((ret = getpeername(to_net_sd, (struct sockaddr *)&addr, &addr_len)) != 0) {
rs_log_error("Failed to look up peer address using socket \"%d\": %s.",
to_net_sd,
hstrerror(h_errno));
return EXIT_CONNECT_FAILED;
}

rs_log_info("Successfully looked up IP address %s using socket %d.",
rs_log_info("Successfully looked up IP address %s using socket %d.",
inet_ntoa(addr.sin_addr),
to_net_sd);

if ((hp = gethostbyaddr((char *) &addr.sin_addr,
sizeof(addr.sin_addr),
AF_INET)) == NULL) {
rs_log_error("Failed to look up host by address \"%s\": %s.",
inet_ntoa(addr.sin_addr),
hstrerror(h_errno));
return EXIT_CONNECT_FAILED;
}
if ((hp = gethostbyaddr((char *) &addr.sin_addr,
sizeof(addr.sin_addr),
AF_INET)) == NULL) {
rs_log_error("Failed to look up host by address \"%s\": %s.",
inet_ntoa(addr.sin_addr),
hstrerror(h_errno));
return EXIT_CONNECT_FAILED;
}

rs_log_info("Successfully looked up host %s using IP address %s.",
rs_log_info("Successfully looked up host %s using IP address %s.",
hp->h_name,
inet_ntoa(addr.sin_addr));

if ((full_name = malloc(strlen(hp->h_name) + 1)) == NULL) {
rs_log_error("malloc failed : %ld bytes: out of memory.",
(long) (strlen(hp->h_name) + 1));
return EXIT_OUT_OF_MEMORY;
full_name = hp->h_name;
} else {
full_name = host->auth_name;
}

strcpy(full_name, hp->h_name);

if ((princ_env_val = getenv("DISTCC_PRINCIPAL"))) {
if (asprintf(&ext_princ_name, "%s@%s", princ_env_val, full_name) < 0) {
rs_log_error("Failed to allocate memory for asprintf.");
@@ -176,7 +178,6 @@ static int dcc_gssapi_establish_secure_context(int to_net_sd,
name_type = GSS_C_NT_USER_NAME;
}

free(full_name);
name_buffer.value = ext_princ_name;
name_buffer.length = strlen(ext_princ_name);

@@ -245,6 +245,7 @@ static int dcc_parse_options(const char **psrc,
host->cpp_where = DCC_CPP_ON_CLIENT;
#ifdef HAVE_GSSAPI
host->authenticate = 0;
host->auth_name = NULL;
#endif

while (p[0] == ',') {
@@ -266,6 +267,17 @@ static int dcc_parse_options(const char **psrc,
rs_trace("got GSSAPI option");
host->authenticate = 1;
p += 4;
if (p[0] == '=') {
p++;
int ret;
if ((ret = dcc_dup_part(&p, &host->auth_name, "/: \t\n\r\f,")))
return ret;

if (host->auth_name) {
rs_trace("using \"%s\" server name instead of fqdn "
"lookup for GSS-API auth", host->auth_name);
}
}
#endif
} else {
rs_log_error("unrecognized option in host specification: %s",
@@ -62,6 +62,7 @@ struct dcc_hostdef {
#ifdef HAVE_GSSAPI
/* Are we authenticating with this host? */
int authenticate;
char * auth_name;
#endif

struct dcc_hostdef *next;
@@ -103,6 +103,7 @@ struct dcc_hostdef _dcc_local = {
DCC_CPP_ON_CLIENT, /* where to cpp (ignored) */
#ifdef HAVE_GSSAPI
0, /* Authentication? */
NULL, /* Authentication name */
#endif
NULL
};
@@ -123,6 +124,7 @@ struct dcc_hostdef _dcc_local_cpp = {
DCC_CPP_ON_CLIENT, /* where to cpp (ignored) */
#ifdef HAVE_GSSAPI
0, /* Authentication? */
NULL, /* Authentication name */
#endif
NULL
};
@@ -231,7 +231,7 @@ int dcc_compile_remote(char **argv,
if(host->authenticate) {
rs_log_info("Performing authentication.");

if ((ret = dcc_gssapi_perform_requested_security(to_net_fd, from_net_fd)) != 0) {
if ((ret = dcc_gssapi_perform_requested_security(host, to_net_fd, from_net_fd)) != 0) {
rs_log_crit("Failed to perform authentication.");
goto out;
}

0 comments on commit 5bb67e5

Please sign in to comment.
You can’t perform that action at this time.