Skip to content
Permalink
Browse files

Merge pull request #355 from rmatev/gssapi-ssh-forwarding

Support GSSAPI auth with custom service principal name
  • Loading branch information...
shawnl committed Jul 24, 2019
2 parents 57843ec + 71106e2 commit 6fb446ff116b54be7b1ceb1ca937817b0594f499
Showing with 62 additions and 34 deletions.
  1. +3 −0 .gitignore
  2. +7 −1 man/distcc.1
  3. +1 −1 popt/popthelp.c
  4. +4 −1 src/auth.h
  5. +30 −29 src/auth_distcc.c
  6. +12 −0 src/hosts.c
  7. +1 −0 src/hosts.h
  8. +2 −0 src/lock.c
  9. +1 −1 src/remote.c
  10. +1 −1 src/rpc.c
@@ -8,6 +8,7 @@ distccd
distccmon-text
lsdistcc
pump
update-distcc-symlinks

# files generated by build tools
Makefile
@@ -24,3 +25,5 @@ src/config.h.in
src/config.h.stamp
man/*.gz
_testtmp/
__pycache__/
/h_*
@@ -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
@@ -332,7 +332,7 @@ static void singleOptionHelp(FILE * fp, int maxLeftCol,
/*@-boundsread@*/
while (helpLength > lineLength) {
const char * ch;
char format[16];
char format[30];

ch = help + lineLength - 1;
while (ch > help && !isspace(*ch)) ch--;
@@ -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;
}
@@ -218,7 +218,7 @@ int dcc_r_sometoken_int(int ifd, char *token, unsigned *val)
return ret;
}

strncpy(token, buf, 4);
memcpy(token, buf, 4);
token[4] = '\0';

buf[12] = '\0'; /* terminate */

0 comments on commit 6fb446f

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