Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:47:25

0001 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
0002 /*
0003  * Copyright (c) 2007-2008 Cisco Systems, Inc.  All rights reserved.
0004  * Copyright (c) 2015-2020 Intel, Inc.  All rights reserved.
0005  *
0006  * Copyright (c) 2015      Research Organization for Information Science
0007  *                         and Technology (RIST). All rights reserved.
0008  * Copyright (c) 2019      Mellanox Technologies, Inc. All rights reserved.
0009  * Copyright (c) 2021-2022 Nanook Consulting.  All rights reserved.
0010  * $COPYRIGHT$
0011  *
0012  * Additional copyrights may follow
0013  *
0014  * $HEADER$
0015  */
0016 
0017 /**
0018  * @file
0019  *
0020  * This interface is for psecurity support. PMIx doesn't need much in
0021  * this regard, but we do need a mechanism for authenticating connections.
0022  *
0023  * Only *one* plugin will be active in a client, but multiple plugins may
0024  * be active in a server. Thus, this is a multi-select framework.
0025  *
0026  * Available plugins may be defined at runtime via the typical MCA parameter
0027  * syntax.
0028  */
0029 
0030 #ifndef PMIX_PSEC_H
0031 #define PMIX_PSEC_H
0032 
0033 #include "src/include/pmix_config.h"
0034 
0035 #include "src/mca/base/pmix_mca_base_framework.h"
0036 #include "src/mca/base/pmix_mca_base_var.h"
0037 #include "src/mca/mca.h"
0038 #include "src/mca/ptl/ptl_types.h"
0039 
0040 BEGIN_C_DECLS
0041 
0042 /* forward declaration */
0043 struct pmix_peer_t;
0044 
0045 /******    MODULE DEFINITION    ******/
0046 
0047 /**
0048  * Initialize the module. Returns an error if the module cannot
0049  * run, success if it can and wants to be used.
0050  */
0051 typedef pmix_status_t (*pmix_psec_base_module_init_fn_t)(void);
0052 
0053 /**
0054  * Finalize the module. Tear down any allocated storage, disconnect
0055  * from any system support (e.g., LDAP server)
0056  */
0057 typedef void (*pmix_psec_base_module_fini_fn_t)(void);
0058 
0059 /****    CLIENT-SIDE FUNCTIONS    ****/
0060 /**
0061  * Create and return a credential for this client - this
0062  * could be a string or a byte array, which is why we must
0063  * also return the length. The directives contain info on
0064  * desired credential type, or other directives used by
0065  * the credential agent. The returned info array typically
0066  * contains the name of the agent issuing the credential,
0067  * plus any other info the agent chooses to return.
0068  */
0069 typedef pmix_status_t (*pmix_psec_base_module_create_cred_fn_t)(struct pmix_peer_t *peer,
0070                                                                 const pmix_info_t directives[],
0071                                                                 size_t ndirs, pmix_info_t **info,
0072                                                                 size_t *ninfo,
0073                                                                 pmix_byte_object_t *cred);
0074 
0075 /**
0076  * Perform the client-side handshake. Note that it is not required
0077  * (and indeed, would be rare) for a protocol to use both the
0078  * credential and handshake interfaces. It is acceptable, therefore,
0079  * for one of them to be NULL */
0080 typedef pmix_status_t (*pmix_psec_base_module_client_hndshk_fn_t)(int sd);
0081 
0082 /****    SERVER-SIDE FUNCTIONS    ****/
0083 /**
0084  * Validate a client's credential - the credential could be a string
0085  * or an array of bytes, which is why we include the length. The directives
0086  * contain information provided by the requestor to aid in the validation
0087  * process - e.g., the uid/gid of the process seeking validation, or
0088  * the name of the agent being asked to perform the validation. The
0089  * returned info array typically contains the name of the agent that
0090  * actually performed the validation, plus any other info the agent
0091  * chooses to return (e.g., the uid/gid contained in the credential)
0092  */
0093 typedef pmix_status_t (*pmix_psec_base_module_validate_cred_fn_t)(struct pmix_peer_t *peer,
0094                                                                   const pmix_info_t directives[],
0095                                                                   size_t ndirs, pmix_info_t **info,
0096                                                                   size_t *ninfo,
0097                                                                   const pmix_byte_object_t *cred);
0098 
0099 /**
0100  * Perform the server-side handshake. Note that it is not required
0101  * (and indeed, would be rare) for a protocol to use both the
0102  * credential and handshake interfaces. It is acceptable, therefore,
0103  * for one of them to be NULL */
0104 typedef pmix_status_t (*pmix_psec_base_module_server_hndshk_fn_t)(int sd);
0105 
0106 /**
0107  * Base structure for a PSEC module
0108  */
0109 typedef struct {
0110     char *name;
0111     /* init/finalize */
0112     pmix_psec_base_module_init_fn_t init;
0113     pmix_psec_base_module_fini_fn_t finalize;
0114     /** Client-side */
0115     pmix_psec_base_module_create_cred_fn_t create_cred;
0116     pmix_psec_base_module_client_hndshk_fn_t client_handshake;
0117     /** Server-side */
0118     pmix_psec_base_module_validate_cred_fn_t validate_cred;
0119     pmix_psec_base_module_server_hndshk_fn_t server_handshake;
0120 } pmix_psec_module_t;
0121 
0122 /* define an API module */
0123 
0124 /* get a list of available options - caller must free results
0125  * when done */
0126 PMIX_EXPORT char *pmix_psec_base_get_available_modules(void);
0127 
0128 /* Select a psec module for a given peer */
0129 PMIX_EXPORT pmix_psec_module_t *pmix_psec_base_assign_module(const char *options);
0130 
0131 /* MACROS FOR EXECUTING PSEC FUNCTIONS */
0132 
0133 #define PMIX_PSEC_CREATE_CRED(r, p, d, nd, in, nin, c) \
0134     (r) = (p)->nptr->compat.psec->create_cred((struct pmix_peer_t *) (p), (d), (nd), (in), (nin), c)
0135 
0136 #define PMIX_PSEC_CLIENT_HANDSHAKE(r, p, sd) (r) = (p)->nptr->compat.psec->client_handshake(sd)
0137 
0138 #define PMIX_PSEC_VALIDATE_CRED(r, p, d, nd, in, nin, c)                                     \
0139     (r) = (p)->nptr->compat.psec->validate_cred((struct pmix_peer_t *) (p), (d), (nd), (in), \
0140                                                 (nin), c)
0141 
0142 #define PMIX_PSEC_VALIDATE_CONNECTION(r, p, d, nd, in, nin, c)                                     \
0143     do {                                                                                           \
0144         int _r;                                                                                    \
0145         /* if a credential is available, then check it */                                          \
0146         if (NULL != (p)->nptr->compat.psec->validate_cred) {                                       \
0147             _r = (p)->nptr->compat.psec->validate_cred((struct pmix_peer_t *) (p), (d), (nd),      \
0148                                                        (in), (nin), c);                            \
0149             if (PMIX_SUCCESS != _r) {                                                              \
0150                 pmix_output_verbose(2, pmix_globals.debug_output,                                  \
0151                                     "validation of credential failed: %s", PMIx_Error_string(_r)); \
0152             } else {                                                                               \
0153                 pmix_output_verbose(2, pmix_globals.debug_output, "credential validated");         \
0154             }                                                                                      \
0155             (r) = _r;                                                                              \
0156         } else if (NULL != (p)->nptr->compat.psec->server_handshake) {                             \
0157             /* request the handshake if the security mode calls for it */                          \
0158             pmix_output_verbose(2, pmix_globals.debug_output, "requesting handshake");             \
0159             _r = PMIX_ERR_READY_FOR_HANDSHAKE;                                                     \
0160             (r) = _r;                                                                              \
0161         } else {                                                                                   \
0162             /* this is not allowed */                                                              \
0163             (r) = PMIX_ERR_NOT_SUPPORTED;                                                          \
0164         }                                                                                          \
0165     } while (0)
0166 
0167 #define PMIX_PSEC_SERVER_HANDSHAKE_IFNEED(r, p, d, nd, in, nin, c)                    \
0168     if (PMIX_ERR_READY_FOR_HANDSHAKE == r) {                                          \
0169         int _r;                                                                       \
0170         /* execute the handshake if the security mode calls for it */                 \
0171         pmix_output_verbose(2, pmix_globals.debug_output, "executing handshake");     \
0172         if (PMIX_SUCCESS != (_r = p->nptr->compat.psec->server_handshake((p)->sd))) { \
0173             PMIX_ERROR_LOG(_r);                                                       \
0174         }                                                                             \
0175         /* Update the reply status */                                                 \
0176         (r) = _r;                                                                     \
0177     }
0178 
0179 /****    COMPONENT STRUCTURE DEFINITION    ****/
0180 
0181 /* define a component-level API for initializing the component */
0182 typedef pmix_status_t (*pmix_psec_base_component_init_fn_t)(void);
0183 
0184 /* define a component-level API for finalizing the component */
0185 typedef void (*pmix_psec_base_component_finalize_fn_t)(void);
0186 
0187 /* define a component-level API for getting a module */
0188 typedef pmix_psec_module_t *(*pmix_psec_base_component_assign_module_fn_t)(void);
0189 
0190 /*
0191  * the standard component data structure
0192  */
0193 struct pmix_psec_base_component_t {
0194     pmix_mca_base_component_t base;
0195     int priority;
0196     pmix_psec_base_component_init_fn_t init;
0197     pmix_psec_base_component_finalize_fn_t finalize;
0198     pmix_psec_base_component_assign_module_fn_t assign_module;
0199 };
0200 typedef struct pmix_psec_base_component_t pmix_psec_base_component_t;
0201 
0202 /*
0203  * Macro for use in components that are of type psec
0204  */
0205 #define PMIX_PSEC_BASE_VERSION_1_0_0 PMIX_MCA_BASE_VERSION_1_0_0("psec", 1, 0, 0)
0206 
0207 END_C_DECLS
0208 
0209 #endif