From d07dc362d58ded5d65178c10bd0979d6b0487b95 Mon Sep 17 00:00:00 2001
From: Ralph Castain <rhc@open-mpi.org>
Date: Sat, 28 Mar 2015 20:34:26 -0700
Subject: [PATCH] Ensure we can authenticate when crossing security domains by
 including all available credentials, and letting the receiver use the highest
 priority one they have in common.

---
 opal/mca/pmix/native/usock.c              |  18 ++--
 opal/mca/pmix/native/usock_sendrecv.c     |  14 ++-
 opal/mca/sec/base/base.h                  |   4 +-
 opal/mca/sec/base/sec_base_stubs.c        | 119 +++++++++++++++++-----
 opal/mca/sec/basic/sec_basic.c            |  17 ++--
 opal/mca/sec/keystone/sec_keystone.c      |   4 +-
 opal/mca/sec/munge/sec_munge.c            |  11 +-
 opal/mca/sec/sec.h                        |   8 +-
 orte/mca/oob/tcp/oob_tcp_connection.c     |  49 +++++----
 orte/mca/oob/usock/oob_usock_connection.c |  32 +++---
 orte/orted/pmix/pmix_server_connection.c  |  40 ++++----
 orte/orted/pmix/pmix_server_sendrecv.c    |   9 +-
 12 files changed, 208 insertions(+), 117 deletions(-)

diff --git a/opal/mca/pmix/native/usock.c b/opal/mca/pmix/native/usock.c
index 4d06639e18..f1a10f1f31 100644
--- a/opal/mca/pmix/native/usock.c
+++ b/opal/mca/pmix/native/usock.c
@@ -347,8 +347,9 @@ int usock_send_connect_ack(void)
     pmix_usock_hdr_t hdr;
     int rc;
     size_t sdsize;
-    opal_sec_cred_t *cred;
-
+    char *cred;
+    size_t credsize;
+    
     opal_output_verbose(2, opal_pmix_base_framework.framework_output,
                         "%s SEND CONNECT ACK",
                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME));
@@ -359,15 +360,15 @@ int usock_send_connect_ack(void)
     hdr.type = PMIX_USOCK_IDENT;
 
     /* get our security credential */
-    if (OPAL_SUCCESS != (rc = opal_sec.get_my_credential(NULL, opal_dstore_internal, &OPAL_PROC_MY_NAME, &cred))) {
+    if (OPAL_SUCCESS != (rc = opal_sec.get_my_credential(NULL, opal_dstore_internal, &OPAL_PROC_MY_NAME, &cred, &credsize))) {
         return rc;
     }
 
     /* set the number of bytes to be read beyond the header */
-    hdr.nbytes = strlen(opal_version_string) + 1 + strlen(cred->method) + 1 + cred->size;
+    hdr.nbytes = strlen(opal_version_string) + 1 + credsize;
 
     /* create a space for our message */
-    sdsize = (sizeof(hdr) + strlen(opal_version_string) + 1 + strlen(cred->method) + 1 + cred->size);
+    sdsize = (sizeof(hdr) + strlen(opal_version_string) + 1 + credsize);
     if (NULL == (msg = (char*)malloc(sdsize))) {
         return OPAL_ERR_OUT_OF_RESOURCE;
     }
@@ -376,9 +377,10 @@ int usock_send_connect_ack(void)
     /* load the message */
     memcpy(msg, &hdr, sizeof(hdr));
     memcpy(msg+sizeof(hdr), opal_version_string, strlen(opal_version_string));
-    memcpy(msg+sizeof(hdr)+strlen(opal_version_string)+1, cred->method, strlen(cred->method));
-    memcpy(msg+sizeof(hdr)+strlen(opal_version_string)+1+strlen(cred->method)+1, cred->credential, cred->size);
-
+    memcpy(msg+sizeof(hdr)+strlen(opal_version_string)+1, cred, credsize);
+    if (NULL != cred) {
+        free(cred);
+    }
 
     if (OPAL_SUCCESS != usock_send_blocking(msg, sdsize)) {
         free(msg);
diff --git a/opal/mca/pmix/native/usock_sendrecv.c b/opal/mca/pmix/native/usock_sendrecv.c
index bef5078582..b012d36be2 100644
--- a/opal/mca/pmix/native/usock_sendrecv.c
+++ b/opal/mca/pmix/native/usock_sendrecv.c
@@ -545,7 +545,8 @@ static int usock_recv_connect_ack(void)
     char *msg;
     char *version;
     int rc;
-    opal_sec_cred_t creds;
+    char *cred;
+    size_t credsize;
     pmix_usock_hdr_t hdr;
 
     opal_output_verbose(2, opal_pmix_base_framework.framework_output,
@@ -632,11 +633,14 @@ static int usock_recv_connect_ack(void)
                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME));
 
     /* check security token */
-    creds.method = (char*)(msg + strlen(version) + 1);
-    creds.credential = (char*)(msg + strlen(version) + 1 + strlen(creds.method) + 1);
-    creds.size = hdr.nbytes - strlen(version) - 1 - strlen(creds.method) - 1;
-    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(&creds))) {
+    cred = (char*)(msg + strlen(version) + 1);
+    credsize = hdr.nbytes - strlen(version) - 1;
+    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(cred, credsize, NULL))) {
         OPAL_ERROR_LOG(rc);
+        mca_pmix_native_component.state = PMIX_USOCK_FAILED;
+        CLOSE_THE_SOCKET(mca_pmix_native_component.sd);
+        free(msg);
+        return OPAL_ERR_UNREACH;
     }
     free(msg);
 
diff --git a/opal/mca/sec/base/base.h b/opal/mca/sec/base/base.h
index 8e007cf649..09437cb6fe 100644
--- a/opal/mca/sec/base/base.h
+++ b/opal/mca/sec/base/base.h
@@ -45,9 +45,9 @@ OPAL_DECLSPEC int opal_sec_base_select(void);
 OPAL_DECLSPEC int opal_sec_base_get_cred(char *method,
                                          int dstorehandle,
                                          opal_process_name_t *my_id,
-                                         opal_sec_cred_t **cred);
+                                         char **payload, size_t *size);
 
-OPAL_DECLSPEC int opal_sec_base_validate(opal_sec_cred_t *cred);
+OPAL_DECLSPEC int opal_sec_base_validate(char *payload, size_t size, char **method);
 
 END_C_DECLS
 
diff --git a/opal/mca/sec/base/sec_base_stubs.c b/opal/mca/sec/base/sec_base_stubs.c
index 041a4605e3..d689786637 100644
--- a/opal/mca/sec/base/sec_base_stubs.c
+++ b/opal/mca/sec/base/sec_base_stubs.c
@@ -12,12 +12,26 @@
 #include "opal/constants.h"
 
 #include "opal/mca/mca.h"
+#include "opal/util/error.h"
 #include "opal/util/output.h"
 #include "opal/mca/base/base.h"
 #include "opal/dss/dss_types.h"
 
 #include "opal/mca/sec/base/base.h"
 
+static void cleanup_cred(opal_sec_cred_t *cred)
+{
+    if (NULL == cred) {
+        return;
+    }
+    if (NULL != cred->method) {
+        free(cred->method);
+    }
+    if (NULL != cred->credential) {
+        free(cred->credential);
+    }
+}
+
 int opal_sec_base_get_cred(char *method,
                            int dstorehandle,
                            opal_process_name_t *my_id,
@@ -26,6 +40,7 @@ int opal_sec_base_get_cred(char *method,
     opal_sec_handle_t *hdl;
     opal_sec_cred_t cred;
     opal_buffer_t buf;
+    int rc;
     
     opal_output_verbose(5, opal_sec_base_framework.framework_output,
                         "Requesting credential from source %s",
@@ -40,54 +55,110 @@ int opal_sec_base_get_cred(char *method,
             opal_output_verbose(5, opal_sec_base_framework.framework_output,
                                 "Created credential from source %s", hdl->component->mca_component_name);
             /* pack the credential */
-            if (OPAL_SUCCESS != opal_dss.pack(&buf, &cred, 1, OPAL_SEC_CRED)) {
-                
+            if (OPAL_SUCCESS != (rc = opal_dss.pack(&buf, &cred.method, 1, OPAL_STRING))) {
+                OPAL_ERROR_LOG(rc);
+                cleanup_cred(&cred);
+                OBJ_DESTRUCT(&buf);
+                return rc;
             }
-            /* record the source */
-            (*cred)->method = strdup(hdl->component->mca_component_name);
-            return OPAL_SUCCESS;
+            if (OPAL_SUCCESS != (rc = opal_dss.pack(&buf, &cred.size, 1, OPAL_SIZE))) {
+                OPAL_ERROR_LOG(rc);
+                cleanup_cred(&cred);
+                OBJ_DESTRUCT(&buf);
+                return rc;
+            }
+            if (0 < cred.size) {
+                if (OPAL_SUCCESS != (rc = opal_dss.pack(&buf, cred.credential, cred.size, OPAL_BYTE))) {
+                    OPAL_ERROR_LOG(rc);
+                    cleanup_cred(&cred);
+                    OBJ_DESTRUCT(&buf);
+                    return rc;
+                }
+            }
+            opal_output_verbose(5, opal_sec_base_framework.framework_output,
+                                "opal_sec: Created credential %s of size %lu",
+                                cred.credential, (unsigned long)cred.size);
+            cleanup_cred(&cred);
         }
     }
-    return OPAL_ERROR;
+    if (0 == buf.bytes_used) {
+        OBJ_DESTRUCT(&buf);
+        return OPAL_ERROR;
+    }
+    *payload = buf.base_ptr;
+    *size = buf.bytes_used;
+    buf.base_ptr = NULL;
+    buf.bytes_used = 0;
+    OBJ_DESTRUCT(&buf);
+    return OPAL_SUCCESS;
 }
 
 
-int opal_sec_base_validate(char *payload, size_t size)
+int opal_sec_base_validate(char *payload, size_t size, char **method)
 {
     opal_sec_handle_t *hdl;
     opal_buffer_t buf;
-    int cnt;
-    opal_sec_cred_t *cred;
+    int cnt, rc;
+    opal_sec_cred_t cred;
     
     opal_output_verbose(5, opal_sec_base_framework.framework_output,
-                        "Received credential %s from source %s",
-                        (NULL == cred->credential) ? "NULL" : cred->credential,
-                        (NULL == cred->method) ? "NULL" : cred->method);
+                        "opal_sec: Received credential of size %lu",
+                        (unsigned long)size);
     
     OBJ_CONSTRUCT(&buf, opal_buffer_t);
-    buf.base_ptr = payload;
-    buf.bytes_used = size;
+    opal_dss.load(&buf, payload, size);
     
     cnt = 1;
-    while (OPAL_SUCCESS == opal_dss.unpack(&buf, &cred, &cnt, OPAL_SEC_CRED)) {
+    while (OPAL_SUCCESS == (rc = opal_dss.unpack(&buf, &cred.method, &cnt, OPAL_STRING))) {
+        opal_output_verbose(5, opal_sec_base_framework.framework_output,
+                            "Received credential from source %s", cred.method);
+        cnt=1;
+        if (OPAL_SUCCESS != (rc = opal_dss.unpack(&buf, &cred.size, &cnt, OPAL_SIZE))) {
+            OPAL_ERROR_LOG(rc);
+            cleanup_cred(&cred);
+            goto done;
+        }
+        opal_output_verbose(5, opal_sec_base_framework.framework_output,
+                            "Received credential of size %lu", (unsigned long)cred.size);
+        if (0 < cred.size) {
+            cred.credential = (char*)malloc(cred.size);
+            cnt=cred.size;
+            if (OPAL_SUCCESS != (rc = opal_dss.unpack(&buf, cred.credential, &cnt, OPAL_BYTE))) {
+                OPAL_ERROR_LOG(rc);
+                cleanup_cred(&cred);
+                goto done;
+            }
+            opal_output_verbose(5, opal_sec_base_framework.framework_output,
+                                "Received credential %s", cred.credential);
+        }
         OPAL_LIST_FOREACH(hdl, &opal_sec_base_actives, opal_sec_handle_t) {
-            if (NULL != cred->method &&
-                0 != strcmp(cred->method, hdl->component->mca_component_name)) {
-                OBJ_RELEASE(cred);
+            if (NULL != cred.method &&
+                0 != strcmp(cred.method, hdl->component->mca_component_name)) {
                 continue;
             }
-            if (OPAL_SUCCESS == hdl->module->authenticate(cred)) {
-                OBJ_RELEASE(cred);
-                buf.base_ptr = NULL;
-                OBJ_DESTRUCT(&buf);
-                return OPAL_SUCCESS;
+            if (OPAL_SUCCESS == hdl->module->authenticate(&cred)) {
+                rc = OPAL_SUCCESS;
+                /* record the method */
+                if (NULL != method) {
+                    if (NULL != *method) {
+                        free(*method);
+                    }
+                    *method = strdup(cred.method);
+                }
+                cleanup_cred(&cred);
+                goto done;
             }
         }
+        cleanup_cred(&cred);
         cnt = 1;
     }
+    /* if we get here, then nothing authenticated */
+    rc = OPAL_ERR_AUTHENTICATION_FAILED;
+    
+ done:
     buf.base_ptr = NULL;
     OBJ_DESTRUCT(&buf);
-    return OPAL_ERROR;
+    return rc;
 }
 
 
diff --git a/opal/mca/sec/basic/sec_basic.c b/opal/mca/sec/basic/sec_basic.c
index 0e3753b029..37845f1ef7 100644
--- a/opal/mca/sec/basic/sec_basic.c
+++ b/opal/mca/sec/basic/sec_basic.c
@@ -29,7 +29,7 @@ static int init(void);
 static void finalize(void);
 static int get_my_cred(int dstorehandle,
                        opal_process_name_t *my_id,
-                       opal_sec_cred_t **cred);
+                       opal_sec_cred_t *cred);
 static int authenticate(opal_sec_cred_t *cred);
 
 opal_sec_base_module_t opal_sec_basic_module = {
@@ -56,7 +56,7 @@ static void finalize(void)
 
 static int get_my_cred(int dstorehandle,
                        opal_process_name_t *my_id,
-                       opal_sec_cred_t **cred)
+                       opal_sec_cred_t *cred)
 {
     opal_list_t vals;
     opal_value_t *kv;
@@ -77,26 +77,31 @@ static int get_my_cred(int dstorehandle,
                 my_cred.size = strlen(my_cred.credential)+1;  // include the NULL
             } else {
                 my_cred.credential = strdup(kv->data.string);
-                my_cred.size = strlen(kv->data.string);
+                my_cred.size = strlen(kv->data.string)+1;  // include the NULL
                 OBJ_RELEASE(kv);
             }
         } else {
-            my_cred.credential = strdup("12345");
+            my_cred.credential = strdup("1234567");
             my_cred.size = strlen(my_cred.credential)+1;  // include the NULL
         }
         OPAL_LIST_DESTRUCT(&vals);
     }
     initialized = true;
 
-    *cred = &my_cred;
+    cred->method = strdup("basic");
+    cred->credential = strdup(my_cred.credential);
+    cred->size = my_cred.size;
 
     return OPAL_SUCCESS;
 }
 
 static int authenticate(opal_sec_cred_t *cred)
 {
+    opal_output_verbose(5, opal_sec_base_framework.framework_output,
+                        "opal_sec:basic Received credential %s of size %lu",
+                        cred->credential, (unsigned long)cred->size);
 
-    if (0 == strncmp(cred->credential, "12345", strlen("12345"))) {
+    if (0 == strncmp(cred->credential, "1234567", strlen("1234567"))) {
         return OPAL_SUCCESS;
     }
     return OPAL_ERR_AUTHENTICATION_FAILED;
diff --git a/opal/mca/sec/keystone/sec_keystone.c b/opal/mca/sec/keystone/sec_keystone.c
index b08b3f0ec0..cdaf5c0988 100644
--- a/opal/mca/sec/keystone/sec_keystone.c
+++ b/opal/mca/sec/keystone/sec_keystone.c
@@ -34,7 +34,7 @@ static int init(void);
 static void finalize(void);
 static int get_my_cred(int dstorehandle,
                        opal_process_name_t *my_id,
-                       opal_sec_cred_t **cred);
+                       opal_sec_cred_t *cred);
 static int authenticate(opal_sec_cred_t *cred);
 
 opal_sec_base_module_t opal_sec_keystone_module = {
@@ -66,7 +66,7 @@ static size_t op_cbfunc(void *ptr, size_t size, size_t count, void *stream)
 
 static int get_my_cred(int dstorehandle,
                        opal_process_name_t *my_id,
-                       opal_sec_cred_t **cred)
+                       opal_sec_cred_t *cred)
 {
     char *cmd;
     CURL *curl;
diff --git a/opal/mca/sec/munge/sec_munge.c b/opal/mca/sec/munge/sec_munge.c
index 32650b3f60..e6980f1c0f 100644
--- a/opal/mca/sec/munge/sec_munge.c
+++ b/opal/mca/sec/munge/sec_munge.c
@@ -32,7 +32,7 @@ static int init(void);
 static void finalize(void);
 static int get_my_cred(int dstorehandle,
                        opal_process_name_t *my_id,
-                       opal_sec_cred_t **cred);
+                       opal_sec_cred_t *cred);
 static int authenticate(opal_sec_cred_t *cred);
 
 opal_sec_base_module_t opal_sec_munge_module = {
@@ -79,13 +79,12 @@ static void finalize(void)
 
 static int get_my_cred(int dstorehandle,
                        opal_process_name_t *my_id,
-                       opal_sec_cred_t **cred)
+                       opal_sec_cred_t *cred)
 {
     int rc;
     
     if (initialized) {
         if (!refresh) {
-            *cred = &my_cred;
             refresh = true;
         } else {
             /* get a new credential as munge will not
@@ -98,10 +97,12 @@ static int get_my_cred(int dstorehandle,
             }
             /* include the '\0' termination string character */
             my_cred.size = strlen(my_cred.credential)+1;
-            *cred = &my_cred;
         }
+        cred->method = strdup("munge");
+        cred->credential = strdup(my_cred.credential);
+        cred->size = my_cred.size;
     } else {
-        *cred = NULL;
+        rc = OPAL_ERROR;
     }
     
     return OPAL_SUCCESS;
diff --git a/opal/mca/sec/sec.h b/opal/mca/sec/sec.h
index 4fff46bfe0..242c442658 100644
--- a/opal/mca/sec/sec.h
+++ b/opal/mca/sec/sec.h
@@ -79,12 +79,12 @@ typedef void (*opal_sec_base_module_finalize_fn_t)(void);
  */
 typedef int (*opal_sec_base_module_get_my_cred_fn_t)(int dstorehandle,
                                                      opal_process_name_t *my_id,
-                                                     opal_sec_cred_t **cred);
+                                                     opal_sec_cred_t *cred);
 
 typedef int (*opal_sec_API_module_get_my_cred_fn_t)(char *method,
                                                     int dstorehandle,
                                                     opal_process_name_t *my_id,
-                                                    opal_sec_cred_t **cred);
+                                                    char **payload, size_t *size);
 /*
  * Authenticate a security credential - given a security credential,
  * determine if the credential is valid. The credential is passed in
@@ -95,6 +95,8 @@ typedef int (*opal_sec_API_module_get_my_cred_fn_t)(char *method,
  */
 typedef int (*opal_sec_base_module_auth_fn_t)(opal_sec_cred_t *cred);
 
+typedef int (*opal_sec_API_module_auth_fn_t)(char *payload, size_t size, char **method);
+
 /*
  * the standard module data structure
  */
@@ -110,7 +112,7 @@ typedef struct opal_sec_base_module_1_0_0_t opal_sec_base_module_t;
 /* the API structure */
 typedef struct {
     opal_sec_API_module_get_my_cred_fn_t    get_my_credential;
-    opal_sec_base_module_auth_fn_t          authenticate;
+    opal_sec_API_module_auth_fn_t           authenticate;
 } opal_sec_API_module_t;
 
 /*
diff --git a/orte/mca/oob/tcp/oob_tcp_connection.c b/orte/mca/oob/tcp/oob_tcp_connection.c
index a2af5063b8..4a5bca883c 100644
--- a/orte/mca/oob/tcp/oob_tcp_connection.c
+++ b/orte/mca/oob/tcp/oob_tcp_connection.c
@@ -13,7 +13,7 @@
  *                         All rights reserved.
  * Copyright (c) 2009-2014 Cisco Systems, Inc.  All rights reserved.
  * Copyright (c) 2011      Oak Ridge National Labs.  All rights reserved.
- * Copyright (c) 2013-2014 Intel, Inc.  All rights reserved.
+ * Copyright (c) 2013-2015 Intel, Inc.  All rights reserved.
  * Copyright (c) 2014-2015 Research Organization for Information Science
  *                         and Technology (RIST). All rights reserved.
  * $COPYRIGHT$
@@ -355,8 +355,9 @@ static int tcp_peer_send_connect_ack(mca_oob_tcp_peer_t* peer)
     mca_oob_tcp_hdr_t hdr;
     int rc;
     size_t sdsize;
-    opal_sec_cred_t *cred;
-
+    char *cred;
+    size_t credsize;
+    
     opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
                         "%s SEND CONNECT ACK", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
 
@@ -369,17 +370,22 @@ static int tcp_peer_send_connect_ack(mca_oob_tcp_peer_t* peer)
     /* get our security credential*/
     if (OPAL_SUCCESS != (rc = opal_sec.get_my_credential(peer->auth_method,
                                                          opal_dstore_internal,
-                                                         ORTE_PROC_MY_NAME, &cred))) {
+                                                         ORTE_PROC_MY_NAME,
+                                                         &cred, &credsize))) {
         ORTE_ERROR_LOG(rc);
         return rc;
     }
-
+    opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
+                        "%s SENDING CREDENTIAL OF SIZE %lu",
+                        ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
+                        (unsigned long)credsize);
+    
     /* set the number of bytes to be read beyond the header */
-    hdr.nbytes = strlen(orte_version_string) + 1 + strlen(cred->method) + 1 + cred->size;
+    hdr.nbytes = strlen(orte_version_string) + 1 + credsize;
     MCA_OOB_TCP_HDR_HTON(&hdr);
 
     /* create a space for our message */
-    sdsize = (sizeof(hdr) + strlen(orte_version_string) + 1 + strlen(cred->method) + 1 + cred->size);
+    sdsize = sizeof(hdr) + strlen(orte_version_string) + 1 + credsize;
     if (NULL == (msg = (char*)malloc(sdsize))) {
         return ORTE_ERR_OUT_OF_RESOURCE;
     }
@@ -388,9 +394,12 @@ static int tcp_peer_send_connect_ack(mca_oob_tcp_peer_t* peer)
     /* load the message */
     memcpy(msg, &hdr, sizeof(hdr));
     memcpy(msg+sizeof(hdr), orte_version_string, strlen(orte_version_string));
-    memcpy(msg+sizeof(hdr)+strlen(orte_version_string)+1, cred->method, strlen(cred->method));
-    memcpy(msg+sizeof(hdr)+strlen(orte_version_string)+1+strlen(cred->method)+1, cred->credential, cred->size);
-
+    memcpy(msg+sizeof(hdr)+strlen(orte_version_string)+1, cred, credsize);
+    /* clear the memory */
+    if (NULL != cred) {
+        free(cred);
+    }
+    
     /* send it */
     if (ORTE_SUCCESS != tcp_peer_send_blocking(peer->sd, msg, sdsize)) {
         free(msg);
@@ -618,7 +627,8 @@ int mca_oob_tcp_peer_recv_connect_ack(mca_oob_tcp_peer_t* pr,
     char *msg;
     char *version;
     int rc;
-    opal_sec_cred_t creds;
+    char *cred;
+    size_t credsize;
     mca_oob_tcp_hdr_t hdr;
     mca_oob_tcp_peer_t *peer;
     uint64_t *ui64;
@@ -799,22 +809,19 @@ int mca_oob_tcp_peer_recv_connect_ack(mca_oob_tcp_peer_t* pr,
                         ORTE_NAME_PRINT(&peer->name));
 
     /* check security token */
-    creds.method = (char*)(msg + strlen(version) + 1);
-    creds.credential = (char*)(msg + strlen(version) + 1 + strlen(creds.method) + 1);
-    creds.size = hdr.nbytes - strlen(version) - 1 - strlen(creds.method) - 1;
-    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(&creds))) {
+    cred = (char*)(msg + strlen(version) + 1);
+    credsize = hdr.nbytes - strlen(version) - 1;
+    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(cred, credsize, &peer->auth_method))) {
         char *hostname;
         hostname = orte_get_proc_hostname(&peer->name);
         orte_show_help("help-oob-tcp.txt", "authent-fail", true,
-                       orte_process_info.nodename,
-                       (NULL == hostname) ? "unknown" : hostname);
+                       (NULL == hostname) ? "unknown" : hostname,
+                       orte_process_info.nodename);
+        peer->state = MCA_OOB_TCP_FAILED;
+        mca_oob_tcp_peer_close(peer);
         free(msg);
         return ORTE_ERR_CONNECTION_REFUSED;
     }
-    /* record the method they used so we can reciprocate */
-    if (NULL == peer->auth_method) {
-        peer->auth_method = strdup(creds.method);
-    }
     free(msg);
 
     opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
diff --git a/orte/mca/oob/usock/oob_usock_connection.c b/orte/mca/oob/usock/oob_usock_connection.c
index 8201793628..ab9ba573cf 100644
--- a/orte/mca/oob/usock/oob_usock_connection.c
+++ b/orte/mca/oob/usock/oob_usock_connection.c
@@ -277,8 +277,9 @@ static int usock_peer_send_connect_ack(mca_oob_usock_peer_t* peer)
     mca_oob_usock_hdr_t hdr;
     int rc;
     size_t sdsize;
-    opal_sec_cred_t *cred;
-
+    char *cred;
+    size_t credsize;
+    
     opal_output_verbose(OOB_USOCK_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
                         "%s SEND CONNECT ACK", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
 
@@ -293,16 +294,16 @@ static int usock_peer_send_connect_ack(mca_oob_usock_peer_t* peer)
     /* get our security credential*/
     if (OPAL_SUCCESS != (rc = opal_sec.get_my_credential(peer->auth_method,
                                                          opal_dstore_internal,
-                                                         ORTE_PROC_MY_NAME, &cred))) {
+                                                         ORTE_PROC_MY_NAME, &cred, &credsize))) {
         ORTE_ERROR_LOG(rc);
         return rc;
     }
 
     /* set the number of bytes to be read beyond the header */
-    hdr.nbytes = strlen(orte_version_string) + 1 + strlen(cred->method) + 1 + cred->size;
+    hdr.nbytes = strlen(orte_version_string) + 1 + credsize;
 
     /* create a space for our message */
-    sdsize = (sizeof(hdr) + strlen(orte_version_string) + 1 + strlen(cred->method) + 1 + cred->size);
+    sdsize = (sizeof(hdr) + strlen(orte_version_string) + 1 + credsize);
     if (NULL == (msg = (char*)malloc(sdsize))) {
         return ORTE_ERR_OUT_OF_RESOURCE;
     }
@@ -311,10 +312,9 @@ static int usock_peer_send_connect_ack(mca_oob_usock_peer_t* peer)
     /* load the message */
     memcpy(msg, &hdr, sizeof(hdr));
     memcpy(msg+sizeof(hdr), orte_version_string, strlen(orte_version_string));
-    memcpy(msg+sizeof(hdr)+strlen(orte_version_string)+1, cred->method, strlen(cred->method));
-    memcpy(msg+sizeof(hdr)+strlen(orte_version_string)+1+strlen(cred->method)+1, cred->credential, cred->size);
-
-
+    memcpy(msg+sizeof(hdr)+strlen(orte_version_string)+1, cred, credsize);
+    free(cred);
+    
     if (ORTE_SUCCESS != usock_peer_send_blocking(peer, peer->sd, msg, sdsize)) {
         ORTE_ERROR_LOG(ORTE_ERR_UNREACH);
         free(msg);
@@ -488,7 +488,8 @@ int mca_oob_usock_peer_recv_connect_ack(mca_oob_usock_peer_t* pr, int sd,
     char *msg;
     char *version;
     int rc, cmpval;
-    opal_sec_cred_t creds;
+    char *cred;
+    size_t credsize;
     mca_oob_usock_peer_t *peer;
     mca_oob_usock_hdr_t hdr;
     uint64_t *ui64;
@@ -668,16 +669,11 @@ int mca_oob_usock_peer_recv_connect_ack(mca_oob_usock_peer_t* pr, int sd,
                         ORTE_NAME_PRINT(&peer->name));
 
     /* check security token */
-    creds.method = (char*)(msg + strlen(version) + 1);
-    creds.credential = (char*)(msg + strlen(version) + 1 + strlen(creds.method) + 1);
-    creds.size = hdr.nbytes - strlen(version) - 1;
-    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(&creds))) {
+    cred = (char*)(msg + strlen(version) + 1);
+    credsize = hdr.nbytes - strlen(version) - 1;
+    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(cred, credsize, &peer->auth_method))) {
         ORTE_ERROR_LOG(rc);
     }
-    /* record the method they used so we can reciprocate */
-    if (NULL == peer->auth_method) {
-        peer->auth_method = strdup(creds.method);
-    }
     free(msg);
 
     opal_output_verbose(OOB_USOCK_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
diff --git a/orte/orted/pmix/pmix_server_connection.c b/orte/orted/pmix/pmix_server_connection.c
index d57f13e885..e18b7c919a 100644
--- a/orte/orted/pmix/pmix_server_connection.c
+++ b/orte/orted/pmix/pmix_server_connection.c
@@ -83,8 +83,9 @@ int pmix_server_send_connect_ack(pmix_server_peer_t* peer)
     pmix_server_hdr_t hdr;
     int rc;
     size_t sdsize;
-    opal_sec_cred_t *cred;
-
+    char *cred;
+    size_t credsize;
+    
     opal_output_verbose(2, pmix_server_output,
                         "%s SEND CONNECT ACK", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
 
@@ -98,16 +99,16 @@ int pmix_server_send_connect_ack(pmix_server_peer_t* peer)
     /* get our security credential*/
     if (OPAL_SUCCESS != (rc = opal_sec.get_my_credential(peer->auth_method,
                                                          opal_dstore_internal,
-                                                         ORTE_PROC_MY_NAME, &cred))) {
+                                                         ORTE_PROC_MY_NAME, &cred, &credsize))) {
         ORTE_ERROR_LOG(rc);
         return rc;
     }
 
     /* set the number of bytes to be read beyond the header */
-    hdr.nbytes = strlen(orte_version_string) + 1 + + strlen(cred->method) + 1 + cred->size;
+    hdr.nbytes = strlen(orte_version_string) + 1 + credsize;
 
     /* create a space for our message */
-    sdsize = (sizeof(hdr) + strlen(opal_version_string) + 1 + strlen(cred->method) + 1 + cred->size);
+    sdsize = (sizeof(hdr) + strlen(opal_version_string) + 1 + credsize);
     if (NULL == (msg = (char*)malloc(sdsize))) {
         return ORTE_ERR_OUT_OF_RESOURCE;
     }
@@ -116,9 +117,8 @@ int pmix_server_send_connect_ack(pmix_server_peer_t* peer)
     /* load the message */
     memcpy(msg, &hdr, sizeof(hdr));
     memcpy(msg+sizeof(hdr), opal_version_string, strlen(opal_version_string));
-    memcpy(msg+sizeof(hdr)+strlen(opal_version_string)+1, cred->method, strlen(cred->method));
-    memcpy(msg+sizeof(hdr)+strlen(opal_version_string)+1+strlen(cred->method)+1, cred->credential, cred->size);
-
+    memcpy(msg+sizeof(hdr)+strlen(opal_version_string)+1, cred, credsize);
+    free(cred);
 
     if (ORTE_SUCCESS != usock_peer_send_blocking(peer, peer->sd, msg, sdsize)) {
         ORTE_ERROR_LOG(ORTE_ERR_UNREACH);
@@ -212,7 +212,8 @@ int pmix_server_recv_connect_ack(pmix_server_peer_t* pr, int sd,
     char *msg;
     char *version;
     int rc;
-    opal_sec_cred_t creds;
+    char *cred;
+    size_t credsize;
     pmix_server_peer_t *peer;
     pmix_server_hdr_t hdr;
     orte_process_name_t sender;
@@ -367,15 +368,14 @@ int pmix_server_recv_connect_ack(pmix_server_peer_t* pr, int sd,
                         ORTE_NAME_PRINT(&peer->name));
 
     /* check security token */
-    creds.method =  (char*)(msg + strlen(version) + 1);
-    creds.credential = (char*)(msg + strlen(version) + 1 + strlen(creds.method) + 1);
-    creds.size = strlen(creds.credential);
-    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(&creds))) {
+    cred =  (char*)(msg + strlen(version) + 1);
+    credsize = hdr.nbytes - strlen(version) - 1;
+    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(cred, credsize, &peer->auth_method))) {
         ORTE_ERROR_LOG(rc);
-    }
-    /* record the method they used so we can reciprocate */
-    if (NULL == peer->auth_method) {
-        peer->auth_method = strdup(creds.method);
+        peer->state = PMIX_SERVER_FAILED;
+        CLOSE_THE_SOCKET(peer->sd);
+        free(msg);
+        return ORTE_ERR_UNREACH;
     }
     free(msg);
 
@@ -459,8 +459,10 @@ static bool usock_peer_recv_blocking(pmix_server_peer_t* peer,
                                 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
                                 (NULL == peer) ? "UNKNOWN" : ORTE_NAME_PRINT(&(peer->name)),
                                 (NULL == peer) ? 0 : peer->state);
-            peer->state = PMIX_SERVER_FAILED;
-            CLOSE_THE_SOCKET(peer->sd);
+            if (NULL != peer) {
+                peer->state = PMIX_SERVER_FAILED;
+                CLOSE_THE_SOCKET(peer->sd);
+            }
             return false;
         }
 
diff --git a/orte/orted/pmix/pmix_server_sendrecv.c b/orte/orted/pmix/pmix_server_sendrecv.c
index b1ab68d836..146326af7a 100644
--- a/orte/orted/pmix/pmix_server_sendrecv.c
+++ b/orte/orted/pmix/pmix_server_sendrecv.c
@@ -569,7 +569,8 @@ int pmix_server_peer_recv_connect_ack(pmix_server_peer_t* pr,
     char *msg;
     char *version;
     int rc;
-    opal_sec_cred_t creds;
+    char *cred;
+    size_t credsize;
     pmix_server_hdr_t hdr;
     pmix_server_peer_t *peer;
     uint64_t *ui64;
@@ -720,9 +721,9 @@ int pmix_server_peer_recv_connect_ack(pmix_server_peer_t* pr,
                         ORTE_NAME_PRINT(&peer->name));
 
     /* check security token */
-    creds.credential = (char*)(msg + strlen(version) + 1);
-    creds.size = hdr.nbytes - strlen(version) - 1;
-    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(&creds))) {
+    cred = (char*)(msg + strlen(version) + 1);
+    credsize = hdr.nbytes - strlen(version) - 1;
+    if (OPAL_SUCCESS != (rc = opal_sec.authenticate(cred, credsize, NULL))) {
         ORTE_ERROR_LOG(rc);
     }
     free(msg);