LCOV - code coverage report
Current view: top level - lib - context.c (source / functions) Hit Total Coverage
Test: GNU Generic Security Service Lines: 39 94 41.5 %
Date: 2010-05-20 Functions: 3 9 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 21 64 32.8 %

           Branch data     Line data    Source code
       1                 :            : /* context.c --- Implementation of GSS-API Context functions.
       2                 :            :  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010  Simon Josefsson
       3                 :            :  *
       4                 :            :  * This file is part of the Generic Security Service (GSS).
       5                 :            :  *
       6                 :            :  * GSS is free software; you can redistribute it and/or modify it
       7                 :            :  * under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 3 of the License, or
       9                 :            :  * (at your option) any later version.
      10                 :            :  *
      11                 :            :  * GSS is distributed in the hope that it will be useful, but WITHOUT
      12                 :            :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      13                 :            :  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      14                 :            :  * License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with GSS; if not, see http://www.gnu.org/licenses or write to
      18                 :            :  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth
      19                 :            :  * Floor, Boston, MA 02110-1301, USA.
      20                 :            :  *
      21                 :            :  */
      22                 :            : 
      23                 :            : #include "internal.h"
      24                 :            : 
      25                 :            : /* _gss_find_mech */
      26                 :            : #include "meta.h"
      27                 :            : 
      28                 :            : /**
      29                 :            :  * gss_init_sec_context:
      30                 :            :  * @minor_status: (integer, modify) Mechanism specific status code.
      31                 :            :  * @initiator_cred_handle: (gss_cred_id_t, read, optional) Handle for
      32                 :            :  *   credentials claimed.  Supply GSS_C_NO_CREDENTIAL to act as a
      33                 :            :  *   default initiator principal.  If no default initiator is defined,
      34                 :            :  *   the function will return GSS_S_NO_CRED.
      35                 :            :  * @context_handle: (gss_ctx_id_t, read/modify) Context handle for new
      36                 :            :  *   context.  Supply GSS_C_NO_CONTEXT for first call; use value
      37                 :            :  *   returned by first call in continuation calls.  Resources
      38                 :            :  *   associated with this context-handle must be released by the
      39                 :            :  *   application after use with a call to gss_delete_sec_context().
      40                 :            :  * @target_name: (gss_name_t, read) Name of target.
      41                 :            :  * @mech_type: (OID, read, optional) Object ID of desired
      42                 :            :  *   mechanism. Supply GSS_C_NO_OID to obtain an implementation
      43                 :            :  *   specific default.
      44                 :            :  * @req_flags: (bit-mask, read) Contains various independent flags,
      45                 :            :  *   each of which requests that the context support a specific
      46                 :            :  *   service option.  Symbolic names are provided for each flag, and
      47                 :            :  *   the symbolic names corresponding to the required flags should be
      48                 :            :  *   logically-ORed together to form the bit-mask value.  See below
      49                 :            :  *   for the flags.
      50                 :            :  * @time_req: (Integer, read, optional) Desired number of seconds for
      51                 :            :  *   which context should remain valid.  Supply 0 to request a default
      52                 :            :  *   validity period.
      53                 :            :  * @input_chan_bindings: (channel bindings, read, optional)
      54                 :            :  *   Application-specified bindings.  Allows application to securely
      55                 :            :  *   bind channel identification information to the security context.
      56                 :            :  *   Specify GSS_C_NO_CHANNEL_BINDINGS if channel bindings are not
      57                 :            :  *   used.
      58                 :            :  * @input_token: (buffer, opaque, read, optional) Token received from
      59                 :            :  *   peer application.  Supply GSS_C_NO_BUFFER, or a pointer to a
      60                 :            :  *   buffer containing the value GSS_C_EMPTY_BUFFER on initial call.
      61                 :            :  * @actual_mech_type: (OID, modify, optional) Actual mechanism used.
      62                 :            :  *   The OID returned via this parameter will be a pointer to static
      63                 :            :  *   storage that should be treated as read-only; In particular the
      64                 :            :  *   application should not attempt to free it.  Specify NULL if not
      65                 :            :  *   required.
      66                 :            :  * @output_token: (buffer, opaque, modify) Token to be sent to peer
      67                 :            :  *   application.  If the length field of the returned buffer is zero,
      68                 :            :  *   no token need be sent to the peer application.  Storage
      69                 :            :  *   associated with this buffer must be freed by the application
      70                 :            :  *   after use with a call to gss_release_buffer().
      71                 :            :  * @ret_flags: (bit-mask, modify, optional) Contains various
      72                 :            :  *   independent flags, each of which indicates that the context
      73                 :            :  *   supports a specific service option.  Specify NULL if not
      74                 :            :  *   required.  Symbolic names are provided for each flag, and the
      75                 :            :  *   symbolic names corresponding to the required flags should be
      76                 :            :  *   logically-ANDed with the ret_flags value to test whether a given
      77                 :            :  *   option is supported by the context.  See below for the flags.
      78                 :            :  * @time_rec: (Integer, modify, optional) Number of seconds for which
      79                 :            :  *   the context will remain valid. If the implementation does not
      80                 :            :  *   support context expiration, the value GSS_C_INDEFINITE will be
      81                 :            :  *   returned.  Specify NULL if not required.
      82                 :            :  *
      83                 :            :  * Initiates the establishment of a security context between the
      84                 :            :  * application and a remote peer.  Initially, the input_token
      85                 :            :  * parameter should be specified either as GSS_C_NO_BUFFER, or as a
      86                 :            :  * pointer to a gss_buffer_desc object whose length field contains the
      87                 :            :  * value zero.  The routine may return a output_token which should be
      88                 :            :  * transferred to the peer application, where the peer application
      89                 :            :  * will present it to gss_accept_sec_context.  If no token need be
      90                 :            :  * sent, gss_init_sec_context will indicate this by setting the length
      91                 :            :  * field of the output_token argument to zero. To complete the context
      92                 :            :  * establishment, one or more reply tokens may be required from the
      93                 :            :  * peer application; if so, gss_init_sec_context will return a status
      94                 :            :  * containing the supplementary information bit GSS_S_CONTINUE_NEEDED.
      95                 :            :  * In this case, gss_init_sec_context should be called again when the
      96                 :            :  * reply token is received from the peer application, passing the
      97                 :            :  * reply token to gss_init_sec_context via the input_token parameters.
      98                 :            :  *
      99                 :            :  * Portable applications should be constructed to use the token length
     100                 :            :  * and return status to determine whether a token needs to be sent or
     101                 :            :  * waited for.  Thus a typical portable caller should always invoke
     102                 :            :  * gss_init_sec_context within a loop:
     103                 :            :  *
     104                 :            :  * ---------------------------------------------------
     105                 :            :  * int context_established = 0;
     106                 :            :  * gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
     107                 :            :  *        ...
     108                 :            :  * input_token->length = 0;
     109                 :            :  *
     110                 :            :  * while (!context_established) {
     111                 :            :  *   maj_stat = gss_init_sec_context(&min_stat,
     112                 :            :  *                                   cred_hdl,
     113                 :            :  *                                   &context_hdl,
     114                 :            :  *                                   target_name,
     115                 :            :  *                                   desired_mech,
     116                 :            :  *                                   desired_services,
     117                 :            :  *                                   desired_time,
     118                 :            :  *                                   input_bindings,
     119                 :            :  *                                   input_token,
     120                 :            :  *                                   &actual_mech,
     121                 :            :  *                                   output_token,
     122                 :            :  *                                   &actual_services,
     123                 :            :  *                                   &actual_time);
     124                 :            :  *   if (GSS_ERROR(maj_stat)) {
     125                 :            :  *     report_error(maj_stat, min_stat);
     126                 :            :  *   };
     127                 :            :  *
     128                 :            :  *   if (output_token->length != 0) {
     129                 :            :  *     send_token_to_peer(output_token);
     130                 :            :  *     gss_release_buffer(&min_stat, output_token)
     131                 :            :  *   };
     132                 :            :  *   if (GSS_ERROR(maj_stat)) {
     133                 :            :  *
     134                 :            :  *     if (context_hdl != GSS_C_NO_CONTEXT)
     135                 :            :  *       gss_delete_sec_context(&min_stat,
     136                 :            :  *                              &context_hdl,
     137                 :            :  *                              GSS_C_NO_BUFFER);
     138                 :            :  *     break;
     139                 :            :  *   };
     140                 :            :  *
     141                 :            :  *   if (maj_stat & GSS_S_CONTINUE_NEEDED) {
     142                 :            :  *     receive_token_from_peer(input_token);
     143                 :            :  *   } else {
     144                 :            :  *     context_established = 1;
     145                 :            :  *   };
     146                 :            :  * };
     147                 :            :  * ---------------------------------------------------
     148                 :            :  *
     149                 :            :  * Whenever the routine returns a major status that includes the value
     150                 :            :  * GSS_S_CONTINUE_NEEDED, the context is not fully established and the
     151                 :            :  * following restrictions apply to the output parameters:
     152                 :            :  *
     153                 :            :  * - The value returned via the time_rec parameter is undefined unless
     154                 :            :  * the accompanying ret_flags parameter contains the bit
     155                 :            :  * GSS_C_PROT_READY_FLAG, indicating that per-message services may be
     156                 :            :  * applied in advance of a successful completion status, the value
     157                 :            :  * returned via the actual_mech_type parameter is undefined until the
     158                 :            :  * routine returns a major status value of GSS_S_COMPLETE.
     159                 :            :  *
     160                 :            :  * - The values of the GSS_C_DELEG_FLAG, GSS_C_MUTUAL_FLAG,
     161                 :            :  * GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG,
     162                 :            :  * GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned via the
     163                 :            :  * ret_flags parameter should contain the values that the
     164                 :            :  * implementation expects would be valid if context establishment were
     165                 :            :  * to succeed.  In particular, if the application has requested a
     166                 :            :  * service such as delegation or anonymous authentication via the
     167                 :            :  * req_flags argument, and such a service is unavailable from the
     168                 :            :  * underlying mechanism, gss_init_sec_context should generate a token
     169                 :            :  * that will not provide the service, and indicate via the ret_flags
     170                 :            :  * argument that the service will not be supported.  The application
     171                 :            :  * may choose to abort the context establishment by calling
     172                 :            :  * gss_delete_sec_context (if it cannot continue in the absence of the
     173                 :            :  * service), or it may choose to transmit the token and continue
     174                 :            :  * context establishment (if the service was merely desired but not
     175                 :            :  * mandatory).
     176                 :            :  *
     177                 :            :  * - The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
     178                 :            :  * within ret_flags should indicate the actual state at the time
     179                 :            :  * gss_init_sec_context returns, whether or not the context is fully
     180                 :            :  * established.
     181                 :            :  *
     182                 :            :  * - GSS-API implementations that support per-message protection are
     183                 :            :  * encouraged to set the GSS_C_PROT_READY_FLAG in the final ret_flags
     184                 :            :  * returned to a caller (i.e. when accompanied by a GSS_S_COMPLETE
     185                 :            :  * status code).  However, applications should not rely on this
     186                 :            :  * behavior as the flag was not defined in Version 1 of the GSS-API.
     187                 :            :  * Instead, applications should determine what per-message services
     188                 :            :  * are available after a successful context establishment according to
     189                 :            :  * the GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG values.
     190                 :            :  *
     191                 :            :  * - All other bits within the ret_flags argument should be set to
     192                 :            :  * zero.
     193                 :            :  *
     194                 :            :  * If the initial call of gss_init_sec_context() fails, the
     195                 :            :  * implementation should not create a context object, and should leave
     196                 :            :  * the value of the context_handle parameter set to GSS_C_NO_CONTEXT
     197                 :            :  * to indicate this.  In the event of a failure on a subsequent call,
     198                 :            :  * the implementation is permitted to delete the "half-built" security
     199                 :            :  * context (in which case it should set the context_handle parameter
     200                 :            :  * to GSS_C_NO_CONTEXT), but the preferred behavior is to leave the
     201                 :            :  * security context untouched for the application to delete (using
     202                 :            :  * gss_delete_sec_context).
     203                 :            :  *
     204                 :            :  * During context establishment, the informational status bits
     205                 :            :  * GSS_S_OLD_TOKEN and GSS_S_DUPLICATE_TOKEN indicate fatal errors,
     206                 :            :  * and GSS-API mechanisms should always return them in association
     207                 :            :  * with a routine error of GSS_S_FAILURE.  This requirement for
     208                 :            :  * pairing did not exist in version 1 of the GSS-API specification, so
     209                 :            :  * applications that wish to run over version 1 implementations must
     210                 :            :  * special-case these codes.
     211                 :            :  *
     212                 :            :  * The `req_flags` values:
     213                 :            :  *
     214                 :            :  * `GSS_C_DELEG_FLAG`::
     215                 :            :  * - True - Delegate credentials to remote peer.
     216                 :            :  * - False - Don't delegate.
     217                 :            :  *
     218                 :            :  * `GSS_C_MUTUAL_FLAG`::
     219                 :            :  * - True - Request that remote peer authenticate itself.
     220                 :            :  * - False - Authenticate self to remote peer only.
     221                 :            :  *
     222                 :            :  * `GSS_C_REPLAY_FLAG`::
     223                 :            :  * - True - Enable replay detection for messages protected with
     224                 :            :  * gss_wrap or gss_get_mic.
     225                 :            :  * - False - Don't attempt to detect replayed messages.
     226                 :            :  *
     227                 :            :  * `GSS_C_SEQUENCE_FLAG`::
     228                 :            :  * - True - Enable detection of out-of-sequence protected messages.
     229                 :            :  * - False - Don't attempt to detect out-of-sequence messages.
     230                 :            :  *
     231                 :            :  * `GSS_C_CONF_FLAG`::
     232                 :            :  * - True - Request that confidentiality service be made available
     233                 :            :  * (via gss_wrap).
     234                 :            :  * - False - No per-message confidentiality service is required.
     235                 :            :  *
     236                 :            :  * `GSS_C_INTEG_FLAG`::
     237                 :            :  * - True - Request that integrity service be made available (via
     238                 :            :  * gss_wrap or gss_get_mic).
     239                 :            :  * - False - No per-message integrity service is required.
     240                 :            :  *
     241                 :            :  * `GSS_C_ANON_FLAG`::
     242                 :            :  * - True - Do not reveal the initiator's identity to the acceptor.
     243                 :            :  * - False - Authenticate normally.
     244                 :            :  *
     245                 :            :  * The `ret_flags` values:
     246                 :            :  *
     247                 :            :  * `GSS_C_DELEG_FLAG`::
     248                 :            :  * - True - Credentials were delegated to the remote peer.
     249                 :            :  * - False - No credentials were delegated.
     250                 :            :  *
     251                 :            :  * `GSS_C_MUTUAL_FLAG`::
     252                 :            :  * - True - The remote peer has authenticated itself.
     253                 :            :  * - False - Remote peer has not authenticated itself.
     254                 :            :  *
     255                 :            :  * `GSS_C_REPLAY_FLAG`::
     256                 :            :  * - True - replay of protected messages will be detected.
     257                 :            :  * - False - replayed messages will not be detected.
     258                 :            :  *
     259                 :            :  * `GSS_C_SEQUENCE_FLAG`::
     260                 :            :  * - True - out-of-sequence protected messages will be detected.
     261                 :            :  * - False - out-of-sequence messages will not be detected.
     262                 :            :  *
     263                 :            :  * `GSS_C_CONF_FLAG`::
     264                 :            :  * - True - Confidentiality service may be invoked by calling gss_wrap
     265                 :            :  * routine.
     266                 :            :  * - False - No confidentiality service (via gss_wrap)
     267                 :            :  * available. gss_wrap will provide message encapsulation, data-origin
     268                 :            :  * authentication and integrity services only.
     269                 :            :  *
     270                 :            :  * `GSS_C_INTEG_FLAG`::
     271                 :            :  * - True - Integrity service may be invoked by calling either
     272                 :            :  * gss_get_mic or gss_wrap routines.
     273                 :            :  * - False - Per-message integrity service unavailable.
     274                 :            :  *
     275                 :            :  * `GSS_C_ANON_FLAG`::
     276                 :            :  * - True - The initiator's identity has not been revealed, and will
     277                 :            :  * not be revealed if any emitted token is passed to the acceptor.
     278                 :            :  * - False - The initiator's identity has been or will be
     279                 :            :  * authenticated normally.
     280                 :            :  *
     281                 :            :  * `GSS_C_PROT_READY_FLAG`::
     282                 :            :  * - True - Protection services (as specified by the states of the
     283                 :            :  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available for use if the
     284                 :            :  * accompanying major status return value is either GSS_S_COMPLETE or
     285                 :            :  * GSS_S_CONTINUE_NEEDED.
     286                 :            :  * - False - Protection services (as specified by the states of the
     287                 :            :  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
     288                 :            :  * accompanying major status return value is GSS_S_COMPLETE.
     289                 :            :  *
     290                 :            :  * `GSS_C_TRANS_FLAG`::
     291                 :            :  * - True - The resultant security context may be transferred to other
     292                 :            :  * processes via a call to gss_export_sec_context().
     293                 :            :  * - False - The security context is not transferable.
     294                 :            :  *
     295                 :            :  * All other bits should be set to zero.
     296                 :            :  *
     297                 :            :  * Return value:
     298                 :            :  *
     299                 :            :  * `GSS_S_COMPLETE`: Successful completion.
     300                 :            :  *
     301                 :            :  * `GSS_S_CONTINUE_NEEDED`: Indicates that a token from the peer
     302                 :            :  * application is required to complete the context, and that
     303                 :            :  * gss_init_sec_context must be called again with that token.
     304                 :            :  *
     305                 :            :  * `GSS_S_DEFECTIVE_TOKEN`: Indicates that consistency checks
     306                 :            :  * performed on the input_token failed.
     307                 :            :  *
     308                 :            :  * `GSS_S_DEFECTIVE_CREDENTIAL`: Indicates that consistency checks
     309                 :            :  * performed on the credential failed.
     310                 :            :  *
     311                 :            :  * `GSS_S_NO_CRED`: The supplied credentials were not valid for
     312                 :            :  * context initiation, or the credential handle did not reference any
     313                 :            :  * credentials.
     314                 :            :  *
     315                 :            :  * `GSS_S_CREDENTIALS_EXPIRED`: The referenced credentials have
     316                 :            :  * expired.
     317                 :            :  *
     318                 :            :  * `GSS_S_BAD_BINDINGS`: The input_token contains different channel
     319                 :            :  * bindings to those specified via the input_chan_bindings parameter.
     320                 :            :  *
     321                 :            :  * `GSS_S_BAD_SIG`: The input_token contains an invalid MIC, or a MIC
     322                 :            :  * that could not be verified.
     323                 :            :  *
     324                 :            :  * `GSS_S_OLD_TOKEN`: The input_token was too old.  This is a fatal
     325                 :            :  * error during context establishment.
     326                 :            :  *
     327                 :            :  * `GSS_S_DUPLICATE_TOKEN`: The input_token is valid, but is a
     328                 :            :  * duplicate of a token already processed.  This is a fatal error
     329                 :            :  * during context establishment.
     330                 :            :  *
     331                 :            :  * `GSS_S_NO_CONTEXT`: Indicates that the supplied context handle did
     332                 :            :  * not refer to a valid context.
     333                 :            :  *
     334                 :            :  * `GSS_S_BAD_NAMETYPE`: The provided target_name parameter contained
     335                 :            :  * an invalid or unsupported type of name.
     336                 :            :  *
     337                 :            :  * `GSS_S_BAD_NAME`: The provided target_name parameter was
     338                 :            :  * ill-formed.
     339                 :            :  *
     340                 :            :  * `GSS_S_BAD_MECH`: The specified mechanism is not supported by the
     341                 :            :  * provided credential, or is unrecognized by the implementation.
     342                 :            :  **/
     343                 :            : OM_uint32
     344                 :          5 : gss_init_sec_context (OM_uint32 * minor_status,
     345                 :            :                       const gss_cred_id_t initiator_cred_handle,
     346                 :            :                       gss_ctx_id_t * context_handle,
     347                 :            :                       const gss_name_t target_name,
     348                 :            :                       const gss_OID mech_type,
     349                 :            :                       OM_uint32 req_flags,
     350                 :            :                       OM_uint32 time_req,
     351                 :            :                       const gss_channel_bindings_t input_chan_bindings,
     352                 :            :                       const gss_buffer_t input_token,
     353                 :            :                       gss_OID * actual_mech_type,
     354                 :            :                       gss_buffer_t output_token,
     355                 :            :                       OM_uint32 * ret_flags, OM_uint32 * time_rec)
     356                 :            : {
     357                 :            :   OM_uint32 maj_stat;
     358                 :            :   _gss_mech_api_t mech;
     359                 :          5 :   int freecontext = 0;
     360                 :            : 
     361         [ +  - ]:          5 :   if (output_token)
     362                 :            :     {
     363                 :          5 :       output_token->length = 0;
     364                 :          5 :       output_token->value = NULL;
     365                 :            :     }
     366                 :            : 
     367         [ +  + ]:          5 :   if (ret_flags)
     368                 :          2 :     *ret_flags = 0;
     369                 :            : 
     370         [ -  + ]:          5 :   if (!context_handle)
     371                 :            :     {
     372         [ #  # ]:          0 :       if (minor_status)
     373                 :          0 :         *minor_status = 0;
     374                 :          0 :       return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
     375                 :            :     }
     376                 :            : 
     377         [ -  + ]:          5 :   if (output_token == GSS_C_NO_BUFFER)
     378                 :            :     {
     379         [ #  # ]:          0 :       if (minor_status)
     380                 :          0 :         *minor_status = 0;
     381                 :          0 :       return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
     382                 :            :     }
     383                 :            : 
     384         [ +  + ]:          5 :   if (*context_handle == GSS_C_NO_CONTEXT)
     385                 :          3 :     mech = _gss_find_mech (mech_type);
     386                 :            :   else
     387                 :          2 :     mech = _gss_find_mech ((*context_handle)->mech);
     388         [ -  + ]:          5 :   if (mech == NULL)
     389                 :            :     {
     390         [ #  # ]:          0 :       if (minor_status)
     391                 :          0 :         *minor_status = 0;
     392                 :          0 :       return GSS_S_BAD_MECH;
     393                 :            :     }
     394                 :            : 
     395         [ -  + ]:          5 :   if (actual_mech_type)
     396                 :          0 :     *actual_mech_type = mech->mech;
     397                 :            : 
     398         [ +  + ]:          5 :   if (*context_handle == GSS_C_NO_CONTEXT)
     399                 :            :     {
     400                 :          3 :       *context_handle = calloc (sizeof (**context_handle), 1);
     401         [ -  + ]:          3 :       if (!*context_handle)
     402                 :            :         {
     403         [ #  # ]:          0 :           if (minor_status)
     404                 :          0 :             *minor_status = ENOMEM;
     405                 :          0 :           return GSS_S_FAILURE;
     406                 :            :         }
     407                 :          3 :       (*context_handle)->mech = mech->mech;
     408                 :          3 :       freecontext = 1;
     409                 :            :     }
     410                 :            : 
     411                 :          5 :   maj_stat = mech->init_sec_context (minor_status,
     412                 :            :                                      initiator_cred_handle,
     413                 :            :                                      context_handle,
     414                 :            :                                      target_name,
     415                 :            :                                      mech_type,
     416                 :            :                                      req_flags,
     417                 :            :                                      time_req,
     418                 :            :                                      input_chan_bindings,
     419                 :            :                                      input_token,
     420                 :            :                                      actual_mech_type,
     421                 :            :                                      output_token, ret_flags, time_rec);
     422                 :            : 
     423   [ -  +  #  # ]:          5 :   if (GSS_ERROR (maj_stat) && freecontext)
     424                 :            :     {
     425                 :          0 :       free (*context_handle);
     426                 :          0 :       *context_handle = GSS_C_NO_CONTEXT;
     427                 :            :     }
     428                 :            : 
     429                 :          5 :   return maj_stat;
     430                 :            : }
     431                 :            : 
     432                 :            : /**
     433                 :            :  * gss_accept_sec_context:
     434                 :            :  * @minor_status: (Integer, modify) Mechanism specific status code.
     435                 :            :  * @context_handle: (gss_ctx_id_t, read/modify) Context handle for new
     436                 :            :  *   context.  Supply GSS_C_NO_CONTEXT for first call; use value
     437                 :            :  *   returned in subsequent calls.  Once gss_accept_sec_context() has
     438                 :            :  *   returned a value via this parameter, resources have been assigned
     439                 :            :  *   to the corresponding context, and must be freed by the
     440                 :            :  *   application after use with a call to gss_delete_sec_context().
     441                 :            :  * @acceptor_cred_handle: (gss_cred_id_t, read) Credential handle
     442                 :            :  *   claimed by context acceptor. Specify GSS_C_NO_CREDENTIAL to
     443                 :            :  *   accept the context as a default principal.  If
     444                 :            :  *   GSS_C_NO_CREDENTIAL is specified, but no default acceptor
     445                 :            :  *   principal is defined, GSS_S_NO_CRED will be returned.
     446                 :            :  * @input_token_buffer: (buffer, opaque, read) Token obtained from
     447                 :            :  *   remote application.
     448                 :            :  * @input_chan_bindings: (channel bindings, read, optional)
     449                 :            :  *   Application- specified bindings.  Allows application to securely
     450                 :            :  *   bind channel identification information to the security context.
     451                 :            :  *   If channel bindings are not used, specify
     452                 :            :  *   GSS_C_NO_CHANNEL_BINDINGS.
     453                 :            :  * @src_name: (gss_name_t, modify, optional) Authenticated name of
     454                 :            :  *   context initiator.  After use, this name should be deallocated by
     455                 :            :  *   passing it to gss_release_name().  If not required, specify NULL.
     456                 :            :  * @mech_type: (Object ID, modify, optional) Security mechanism used.
     457                 :            :  *   The returned OID value will be a pointer into static storage, and
     458                 :            :  *   should be treated as read-only by the caller (in particular, it
     459                 :            :  *   does not need to be freed).  If not required, specify NULL.
     460                 :            :  * @output_token: (buffer, opaque, modify) Token to be passed to peer
     461                 :            :  *   application.  If the length field of the returned token buffer is
     462                 :            :  *   0, then no token need be passed to the peer application.  If a
     463                 :            :  *   non- zero length field is returned, the associated storage must
     464                 :            :  *   be freed after use by the application with a call to
     465                 :            :  *   gss_release_buffer().
     466                 :            :  * @ret_flags: (bit-mask, modify, optional) Contains various
     467                 :            :  *   independent flags, each of which indicates that the context
     468                 :            :  *   supports a specific service option.  If not needed, specify NULL.
     469                 :            :  *   Symbolic names are provided for each flag, and the symbolic names
     470                 :            :  *   corresponding to the required flags should be logically-ANDed
     471                 :            :  *   with the ret_flags value to test whether a given option is
     472                 :            :  *   supported by the context.  See below for the flags.
     473                 :            :  * @time_rec: (Integer, modify, optional) Number of seconds for which
     474                 :            :  *   the context will remain valid. Specify NULL if not required.
     475                 :            :  * @delegated_cred_handle: (gss_cred_id_t, modify, optional
     476                 :            :  *   credential) Handle for credentials received from context
     477                 :            :  *   initiator.  Only valid if deleg_flag in ret_flags is true, in
     478                 :            :  *   which case an explicit credential handle (i.e. not
     479                 :            :  *   GSS_C_NO_CREDENTIAL) will be returned; if deleg_flag is false,
     480                 :            :  *   gss_accept_sec_context() will set this parameter to
     481                 :            :  *   GSS_C_NO_CREDENTIAL.  If a credential handle is returned, the
     482                 :            :  *   associated resources must be released by the application after
     483                 :            :  *   use with a call to gss_release_cred().  Specify NULL if not
     484                 :            :  *   required.
     485                 :            :  *
     486                 :            :  * Allows a remotely initiated security context between the
     487                 :            :  * application and a remote peer to be established.  The routine may
     488                 :            :  * return a output_token which should be transferred to the peer
     489                 :            :  * application, where the peer application will present it to
     490                 :            :  * gss_init_sec_context.  If no token need be sent,
     491                 :            :  * gss_accept_sec_context will indicate this by setting the length
     492                 :            :  * field of the output_token argument to zero.  To complete the
     493                 :            :  * context establishment, one or more reply tokens may be required
     494                 :            :  * from the peer application; if so, gss_accept_sec_context will
     495                 :            :  * return a status flag of GSS_S_CONTINUE_NEEDED, in which case it
     496                 :            :  * should be called again when the reply token is received from the
     497                 :            :  * peer application, passing the token to gss_accept_sec_context via
     498                 :            :  * the input_token parameters.
     499                 :            :  *
     500                 :            :  * Portable applications should be constructed to use the token length
     501                 :            :  * and return status to determine whether a token needs to be sent or
     502                 :            :  * waited for.  Thus a typical portable caller should always invoke
     503                 :            :  * gss_accept_sec_context within a loop:
     504                 :            :  *
     505                 :            :  * ---------------------------------------------------
     506                 :            :  * gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
     507                 :            :  *
     508                 :            :  * do {
     509                 :            :  *   receive_token_from_peer(input_token);
     510                 :            :  *   maj_stat = gss_accept_sec_context(&min_stat,
     511                 :            :  *                                     &context_hdl,
     512                 :            :  *                                     cred_hdl,
     513                 :            :  *                                     input_token,
     514                 :            :  *                                     input_bindings,
     515                 :            :  *                                     &client_name,
     516                 :            :  *                                     &mech_type,
     517                 :            :  *                                     output_token,
     518                 :            :  *                                     &ret_flags,
     519                 :            :  *                                     &time_rec,
     520                 :            :  *                                     &deleg_cred);
     521                 :            :  *   if (GSS_ERROR(maj_stat)) {
     522                 :            :  *     report_error(maj_stat, min_stat);
     523                 :            :  *   };
     524                 :            :  *   if (output_token->length != 0) {
     525                 :            :  *     send_token_to_peer(output_token);
     526                 :            :  *
     527                 :            :  *     gss_release_buffer(&min_stat, output_token);
     528                 :            :  *   };
     529                 :            :  *   if (GSS_ERROR(maj_stat)) {
     530                 :            :  *     if (context_hdl != GSS_C_NO_CONTEXT)
     531                 :            :  *       gss_delete_sec_context(&min_stat,
     532                 :            :  *                              &context_hdl,
     533                 :            :  *                              GSS_C_NO_BUFFER);
     534                 :            :  *     break;
     535                 :            :  *   };
     536                 :            :  * } while (maj_stat & GSS_S_CONTINUE_NEEDED);
     537                 :            :  * ---------------------------------------------------
     538                 :            :  *
     539                 :            :  *
     540                 :            :  * Whenever the routine returns a major status that includes the value
     541                 :            :  * GSS_S_CONTINUE_NEEDED, the context is not fully established and the
     542                 :            :  * following restrictions apply to the output parameters:
     543                 :            :  *
     544                 :            :  * The value returned via the time_rec parameter is undefined Unless the
     545                 :            :  * accompanying ret_flags parameter contains the bit
     546                 :            :  * GSS_C_PROT_READY_FLAG, indicating that per-message services may be
     547                 :            :  * applied in advance of a successful completion status, the value
     548                 :            :  * returned via the mech_type parameter may be undefined until the
     549                 :            :  * routine returns a major status value of GSS_S_COMPLETE.
     550                 :            :  *
     551                 :            :  * The values of the GSS_C_DELEG_FLAG,
     552                 :            :  * GSS_C_MUTUAL_FLAG,GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG,
     553                 :            :  * GSS_C_CONF_FLAG,GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned
     554                 :            :  * via the ret_flags parameter should contain the values that the
     555                 :            :  * implementation expects would be valid if context establishment were
     556                 :            :  * to succeed.
     557                 :            :  *
     558                 :            :  * The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
     559                 :            :  * within ret_flags should indicate the actual state at the time
     560                 :            :  * gss_accept_sec_context returns, whether or not the context is fully
     561                 :            :  * established.
     562                 :            :  *
     563                 :            :  * Although this requires that GSS-API implementations set the
     564                 :            :  * GSS_C_PROT_READY_FLAG in the final ret_flags returned to a caller
     565                 :            :  * (i.e. when accompanied by a GSS_S_COMPLETE status code), applications
     566                 :            :  * should not rely on this behavior as the flag was not defined in
     567                 :            :  * Version 1 of the GSS-API. Instead, applications should be prepared to
     568                 :            :  * use per-message services after a successful context establishment,
     569                 :            :  * according to the GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG values.
     570                 :            :  *
     571                 :            :  * All other bits within the ret_flags argument should be set to zero.
     572                 :            :  * While the routine returns GSS_S_CONTINUE_NEEDED, the values returned
     573                 :            :  * via the ret_flags argument indicate the services that the
     574                 :            :  * implementation expects to be available from the established context.
     575                 :            :  *
     576                 :            :  * If the initial call of gss_accept_sec_context() fails, the
     577                 :            :  * implementation should not create a context object, and should leave
     578                 :            :  * the value of the context_handle parameter set to GSS_C_NO_CONTEXT to
     579                 :            :  * indicate this.  In the event of a failure on a subsequent call, the
     580                 :            :  * implementation is permitted to delete the "half-built" security
     581                 :            :  * context (in which case it should set the context_handle parameter to
     582                 :            :  * GSS_C_NO_CONTEXT), but the preferred behavior is to leave the
     583                 :            :  * security context (and the context_handle parameter) untouched for the
     584                 :            :  * application to delete (using gss_delete_sec_context).
     585                 :            :  *
     586                 :            :  * During context establishment, the informational status bits
     587                 :            :  * GSS_S_OLD_TOKEN and GSS_S_DUPLICATE_TOKEN indicate fatal errors, and
     588                 :            :  * GSS-API mechanisms should always return them in association with a
     589                 :            :  * routine error of GSS_S_FAILURE.  This requirement for pairing did not
     590                 :            :  * exist in version 1 of the GSS-API specification, so applications that
     591                 :            :  * wish to run over version 1 implementations must special-case these
     592                 :            :  * codes.
     593                 :            :  *
     594                 :            :  * The `ret_flags` values:
     595                 :            :  *
     596                 :            :  * `GSS_C_DELEG_FLAG`::
     597                 :            :  * - True - Delegated credentials are available via the
     598                 :            :  * delegated_cred_handle parameter.
     599                 :            :  * - False - No credentials were delegated.
     600                 :            :  *
     601                 :            :  * `GSS_C_MUTUAL_FLAG`::
     602                 :            :  * - True - Remote peer asked for mutual authentication.
     603                 :            :  * - False - Remote peer did not ask for mutual authentication.
     604                 :            :  *
     605                 :            :  * `GSS_C_REPLAY_FLAG`::
     606                 :            :  * - True - replay of protected messages will be detected.
     607                 :            :  * - False - replayed messages will not be detected.
     608                 :            :  *
     609                 :            :  * `GSS_C_SEQUENCE_FLAG`::
     610                 :            :  * - True - out-of-sequence protected messages will be detected.
     611                 :            :  * - False - out-of-sequence messages will not be detected.
     612                 :            :  *
     613                 :            :  * `GSS_C_CONF_FLAG`::
     614                 :            :  * - True - Confidentiality service may be invoked by calling the
     615                 :            :  * gss_wrap routine.
     616                 :            :  * - False - No confidentiality service (via gss_wrap)
     617                 :            :  * available. gss_wrap will provide message encapsulation, data-origin
     618                 :            :  * authentication and integrity services only.
     619                 :            :  *
     620                 :            :  * `GSS_C_INTEG_FLAG`::
     621                 :            :  * - True - Integrity service may be invoked by calling either
     622                 :            :  * gss_get_mic or gss_wrap routines.
     623                 :            :  * - False - Per-message integrity service unavailable.
     624                 :            :  *
     625                 :            :  * `GSS_C_ANON_FLAG`::
     626                 :            :  * - True - The initiator does not wish to be authenticated; the
     627                 :            :  * src_name parameter (if requested) contains an anonymous internal
     628                 :            :  * name.
     629                 :            :  * - False - The initiator has been authenticated normally.
     630                 :            :  *
     631                 :            :  * `GSS_C_PROT_READY_FLAG`::
     632                 :            :  * - True - Protection services (as specified by the states of the
     633                 :            :  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available if the
     634                 :            :  * accompanying major status return value is either GSS_S_COMPLETE or
     635                 :            :  * GSS_S_CONTINUE_NEEDED.
     636                 :            :  * - False - Protection services (as specified by the states of the
     637                 :            :  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
     638                 :            :  * accompanying major status return value is GSS_S_COMPLETE.
     639                 :            :  *
     640                 :            :  * `GSS_C_TRANS_FLAG`::
     641                 :            :  * - True - The resultant security context may be transferred to other
     642                 :            :  * processes via a call to gss_export_sec_context().
     643                 :            :  * - False - The security context is not transferable.
     644                 :            :  *
     645                 :            :  * All other bits should be set to zero.
     646                 :            :  *
     647                 :            :  * Return value:
     648                 :            :  *
     649                 :            :  * `GSS_S_CONTINUE_NEEDED`: Indicates that a token from the peer
     650                 :            :  * application is required to complete the context, and that
     651                 :            :  * gss_accept_sec_context must be called again with that token.
     652                 :            :  *
     653                 :            :  * `GSS_S_DEFECTIVE_TOKEN`: Indicates that consistency checks
     654                 :            :  * performed on the input_token failed.
     655                 :            :  *
     656                 :            :  * `GSS_S_DEFECTIVE_CREDENTIAL`: Indicates that consistency checks
     657                 :            :  * performed on the credential failed.
     658                 :            :  *
     659                 :            :  * `GSS_S_NO_CRED`: The supplied credentials were not valid for
     660                 :            :  * context acceptance, or the credential handle did not reference any
     661                 :            :  * credentials.
     662                 :            :  *
     663                 :            :  * `GSS_S_CREDENTIALS_EXPIRED`: The referenced credentials have
     664                 :            :  * expired.
     665                 :            :  *
     666                 :            :  * `GSS_S_BAD_BINDINGS`: The input_token contains different channel
     667                 :            :  * bindings to those specified via the input_chan_bindings parameter.
     668                 :            :  *
     669                 :            :  * `GSS_S_NO_CONTEXT`: Indicates that the supplied context handle did
     670                 :            :  * not refer to a valid context.
     671                 :            :  *
     672                 :            :  * `GSS_S_BAD_SIG`: The input_token contains an invalid MIC.
     673                 :            :  *
     674                 :            :  * `GSS_S_OLD_TOKEN`: The input_token was too old.  This is a fatal
     675                 :            :  * error during context establishment.
     676                 :            :  *
     677                 :            :  * `GSS_S_DUPLICATE_TOKEN`: The input_token is valid, but is a
     678                 :            :  * duplicate of a token already processed.  This is a fatal error
     679                 :            :  * during context establishment.
     680                 :            :  *
     681                 :            :  * `GSS_S_BAD_MECH`: The received token specified a mechanism that is
     682                 :            :  * not supported by the implementation or the provided credential.
     683                 :            :  **/
     684                 :            : OM_uint32
     685                 :          3 : gss_accept_sec_context (OM_uint32 * minor_status,
     686                 :            :                         gss_ctx_id_t * context_handle,
     687                 :            :                         const gss_cred_id_t acceptor_cred_handle,
     688                 :            :                         const gss_buffer_t input_token_buffer,
     689                 :            :                         const gss_channel_bindings_t input_chan_bindings,
     690                 :            :                         gss_name_t * src_name,
     691                 :            :                         gss_OID * mech_type,
     692                 :            :                         gss_buffer_t output_token,
     693                 :            :                         OM_uint32 * ret_flags,
     694                 :            :                         OM_uint32 * time_rec,
     695                 :            :                         gss_cred_id_t * delegated_cred_handle)
     696                 :            : {
     697                 :            :   _gss_mech_api_t mech;
     698                 :            : 
     699         [ -  + ]:          3 :   if (!context_handle)
     700                 :            :     {
     701         [ #  # ]:          0 :       if (minor_status)
     702                 :          0 :         *minor_status = 0;
     703                 :          0 :       return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
     704                 :            :     }
     705                 :            : 
     706         [ +  - ]:          3 :   if (*context_handle == GSS_C_NO_CONTEXT)
     707                 :            :     {
     708                 :            :       /* FIXME: We should extract GSS-API mechanism OID from token
     709                 :            :          here, and use it to find the proper mechanism. */
     710                 :          3 :       mech = _gss_find_mech (GSS_C_NO_OID);
     711                 :            :     }
     712                 :            :   else
     713                 :          0 :     mech = _gss_find_mech ((*context_handle)->mech);
     714         [ -  + ]:          3 :   if (mech == NULL)
     715                 :            :     {
     716         [ #  # ]:          0 :       if (minor_status)
     717                 :          0 :         *minor_status = 0;
     718                 :          0 :       return GSS_S_BAD_MECH;
     719                 :            :     }
     720                 :            : 
     721         [ -  + ]:          3 :   if (mech_type)
     722                 :          0 :     *mech_type = mech->mech;
     723                 :            : 
     724                 :          3 :   return mech->accept_sec_context (minor_status,
     725                 :            :                                    context_handle,
     726                 :            :                                    acceptor_cred_handle,
     727                 :            :                                    input_token_buffer,
     728                 :            :                                    input_chan_bindings,
     729                 :            :                                    src_name,
     730                 :            :                                    mech_type,
     731                 :            :                                    output_token,
     732                 :            :                                    ret_flags,
     733                 :            :                                    time_rec, delegated_cred_handle);
     734                 :            : }
     735                 :            : 
     736                 :            : /**
     737                 :            :  * gss_delete_sec_context:
     738                 :            :  * @minor_status: (Integer, modify) Mechanism specific status code.
     739                 :            :  * @context_handle: (gss_ctx_id_t, modify) Context handle identifying
     740                 :            :  *   context to delete.  After deleting the context, the GSS-API will
     741                 :            :  *   set this context handle to GSS_C_NO_CONTEXT.
     742                 :            :  * @output_token: (buffer, opaque, modify, optional) Token to be sent
     743                 :            :  *   to remote application to instruct it to also delete the context.
     744                 :            :  *   It is recommended that applications specify GSS_C_NO_BUFFER for
     745                 :            :  *   this parameter, requesting local deletion only.  If a buffer
     746                 :            :  *   parameter is provided by the application, the mechanism may
     747                 :            :  *   return a token in it; mechanisms that implement only local
     748                 :            :  *   deletion should set the length field of this token to zero to
     749                 :            :  *   indicate to the application that no token is to be sent to the
     750                 :            :  *   peer.
     751                 :            :  *
     752                 :            :  * Delete a security context.  gss_delete_sec_context will delete the
     753                 :            :  * local data structures associated with the specified security
     754                 :            :  * context, and may generate an output_token, which when passed to the
     755                 :            :  * peer gss_process_context_token will instruct it to do likewise.  If
     756                 :            :  * no token is required by the mechanism, the GSS-API should set the
     757                 :            :  * length field of the output_token (if provided) to zero.  No further
     758                 :            :  * security services may be obtained using the context specified by
     759                 :            :  * context_handle.
     760                 :            :  *
     761                 :            :  * In addition to deleting established security contexts,
     762                 :            :  * gss_delete_sec_context must also be able to delete "half-built"
     763                 :            :  * security contexts resulting from an incomplete sequence of
     764                 :            :  * gss_init_sec_context()/gss_accept_sec_context() calls.
     765                 :            :  *
     766                 :            :  * The output_token parameter is retained for compatibility with
     767                 :            :  * version 1 of the GSS-API.  It is recommended that both peer
     768                 :            :  * applications invoke gss_delete_sec_context passing the value
     769                 :            :  * GSS_C_NO_BUFFER for the output_token parameter, indicating that no
     770                 :            :  * token is required, and that gss_delete_sec_context should simply
     771                 :            :  * delete local context data structures.  If the application does pass
     772                 :            :  * a valid buffer to gss_delete_sec_context, mechanisms are encouraged
     773                 :            :  * to return a zero-length token, indicating that no peer action is
     774                 :            :  * necessary, and that no token should be transferred by the
     775                 :            :  * application.
     776                 :            :  *
     777                 :            :  * Return value:
     778                 :            :  *
     779                 :            :  * `GSS_S_COMPLETE`: Successful completion.
     780                 :            :  *
     781                 :            :  * `GSS_S_NO_CONTEXT`: No valid context was supplied.
     782                 :            :  **/
     783                 :            : OM_uint32
     784                 :          6 : gss_delete_sec_context (OM_uint32 * minor_status,
     785                 :            :                         gss_ctx_id_t * context_handle,
     786                 :            :                         gss_buffer_t output_token)
     787                 :            : {
     788                 :            :   _gss_mech_api_t mech;
     789                 :            :   OM_uint32 ret;
     790                 :            : 
     791         [ -  + ]:          6 :   if (!context_handle)
     792                 :            :     {
     793         [ #  # ]:          0 :       if (minor_status)
     794                 :          0 :         *minor_status = 0;
     795                 :          0 :       return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
     796                 :            :     }
     797                 :            : 
     798         [ -  + ]:          6 :   if (*context_handle == GSS_C_NO_CONTEXT)
     799                 :            :     {
     800         [ #  # ]:          0 :       if (minor_status)
     801                 :          0 :         *minor_status = 0;
     802                 :          0 :       return GSS_S_NO_CONTEXT | GSS_S_CALL_BAD_STRUCTURE;
     803                 :            :     }
     804                 :            : 
     805         [ -  + ]:          6 :   if (output_token != GSS_C_NO_BUFFER)
     806                 :            :     {
     807                 :          0 :       output_token->length = 0;
     808                 :          0 :       output_token->value = NULL;
     809                 :            :     }
     810                 :            : 
     811                 :          6 :   mech = _gss_find_mech ((*context_handle)->mech);
     812         [ -  + ]:          6 :   if (mech == NULL)
     813                 :            :     {
     814         [ #  # ]:          0 :       if (minor_status)
     815                 :          0 :         *minor_status = 0;
     816                 :          0 :       return GSS_S_BAD_MECH;
     817                 :            :     }
     818                 :            : 
     819                 :          6 :   ret = mech->delete_sec_context (NULL, context_handle, output_token);
     820                 :            : 
     821                 :          6 :   free (*context_handle);
     822                 :          6 :   *context_handle = GSS_C_NO_CONTEXT;
     823                 :            : 
     824                 :          6 :   return ret;
     825                 :            : }
     826                 :            : 
     827                 :            : /**
     828                 :            :  * gss_process_context_token:
     829                 :            :  * @minor_status: (Integer, modify) Implementation specific status code.
     830                 :            :  * @context_handle: (gss_ctx_id_t, read) Context handle of context on
     831                 :            :  *   which token is to be processed
     832                 :            :  * @token_buffer: (buffer, opaque, read) Token to process.
     833                 :            :  *
     834                 :            :  * Provides a way to pass an asynchronous token to the security
     835                 :            :  * service.  Most context-level tokens are emitted and processed
     836                 :            :  * synchronously by gss_init_sec_context and gss_accept_sec_context,
     837                 :            :  * and the application is informed as to whether further tokens are
     838                 :            :  * expected by the GSS_C_CONTINUE_NEEDED major status bit.
     839                 :            :  * Occasionally, a mechanism may need to emit a context-level token at
     840                 :            :  * a point when the peer entity is not expecting a token.  For
     841                 :            :  * example, the initiator's final call to gss_init_sec_context may
     842                 :            :  * emit a token and return a status of GSS_S_COMPLETE, but the
     843                 :            :  * acceptor's call to gss_accept_sec_context may fail.  The acceptor's
     844                 :            :  * mechanism may wish to send a token containing an error indication
     845                 :            :  * to the initiator, but the initiator is not expecting a token at
     846                 :            :  * this point, believing that the context is fully established.
     847                 :            :  * Gss_process_context_token provides a way to pass such a token to
     848                 :            :  * the mechanism at any time.
     849                 :            :  *
     850                 :            :  * Return value:
     851                 :            :  *
     852                 :            :  * `GSS_S_COMPLETE`: Successful completion.
     853                 :            :  *
     854                 :            :  * `GSS_S_DEFECTIVE_TOKEN`: Indicates that consistency checks
     855                 :            :  * performed on the token failed.
     856                 :            :  *
     857                 :            :  * `GSS_S_NO_CONTEXT`: The context_handle did not refer to a valid
     858                 :            :  * context.
     859                 :            :  **/
     860                 :            : OM_uint32
     861                 :          0 : gss_process_context_token (OM_uint32 * minor_status,
     862                 :            :                            const gss_ctx_id_t context_handle,
     863                 :            :                            const gss_buffer_t token_buffer)
     864                 :            : {
     865                 :          0 :   return GSS_S_FAILURE;
     866                 :            : }
     867                 :            : 
     868                 :            : /**
     869                 :            :  * gss_context_time:
     870                 :            :  * @minor_status: (Integer, modify) Implementation specific status
     871                 :            :  *   code.
     872                 :            :  * @context_handle: (gss_ctx_id_t, read) Identifies the context to be
     873                 :            :  *   interrogated.
     874                 :            :  * @time_rec: (Integer, modify) Number of seconds that the context
     875                 :            :  *   will remain valid.  If the context has already expired, zero will
     876                 :            :  *   be returned.
     877                 :            :  *
     878                 :            :  * Determines the number of seconds for which the specified context
     879                 :            :  * will remain valid.
     880                 :            :  *
     881                 :            :  * Return value:
     882                 :            :  *
     883                 :            :  * `GSS_S_COMPLETE`: Successful completion.
     884                 :            :  *
     885                 :            :  * `GSS_S_CONTEXT_EXPIRED`: The context has already expired.
     886                 :            :  *
     887                 :            :  * `GSS_S_NO_CONTEXT`: The context_handle parameter did not identify a
     888                 :            :  * valid context
     889                 :            :  **/
     890                 :            : OM_uint32
     891                 :          0 : gss_context_time (OM_uint32 * minor_status,
     892                 :            :                   const gss_ctx_id_t context_handle, OM_uint32 * time_rec)
     893                 :            : {
     894                 :            :   _gss_mech_api_t mech;
     895                 :            : 
     896         [ #  # ]:          0 :   if (context_handle == GSS_C_NO_CONTEXT)
     897                 :            :     {
     898         [ #  # ]:          0 :       if (minor_status)
     899                 :          0 :         *minor_status = 0;
     900                 :          0 :       return GSS_S_NO_CONTEXT | GSS_S_CALL_BAD_STRUCTURE;
     901                 :            :     }
     902                 :            : 
     903                 :          0 :   mech = _gss_find_mech (context_handle->mech);
     904         [ #  # ]:          0 :   if (mech == NULL)
     905                 :            :     {
     906         [ #  # ]:          0 :       if (minor_status)
     907                 :          0 :         *minor_status = 0;
     908                 :          0 :       return GSS_S_BAD_MECH;
     909                 :            :     }
     910                 :            : 
     911                 :          0 :   return mech->context_time (minor_status, context_handle, time_rec);
     912                 :            : }
     913                 :            : 
     914                 :            : /**
     915                 :            :  * gss_inquire_context:
     916                 :            :  * @minor_status: (Integer, modify) Mechanism specific status code.
     917                 :            :  * @context_handle: (gss_ctx_id_t, read) A handle that refers to the
     918                 :            :  *   security context.
     919                 :            :  * @src_name: (gss_name_t, modify, optional) The name of the context
     920                 :            :  *   initiator.  If the context was established using anonymous
     921                 :            :  *   authentication, and if the application invoking
     922                 :            :  *   gss_inquire_context is the context acceptor, an anonymous name
     923                 :            :  *   will be returned.  Storage associated with this name must be
     924                 :            :  *   freed by the application after use with a call to
     925                 :            :  *   gss_release_name().  Specify NULL if not required.
     926                 :            :  * @targ_name: (gss_name_t, modify, optional) The name of the context
     927                 :            :  *   acceptor.  Storage associated with this name must be freed by the
     928                 :            :  *   application after use with a call to gss_release_name().  If the
     929                 :            :  *   context acceptor did not authenticate itself, and if the
     930                 :            :  *   initiator did not specify a target name in its call to
     931                 :            :  *   gss_init_sec_context(), the value GSS_C_NO_NAME will be returned.
     932                 :            :  *   Specify NULL if not required.
     933                 :            :  * @lifetime_rec: (Integer, modify, optional) The number of seconds
     934                 :            :  *   for which the context will remain valid.  If the context has
     935                 :            :  *   expired, this parameter will be set to zero.  If the
     936                 :            :  *   implementation does not support context expiration, the value
     937                 :            :  *   GSS_C_INDEFINITE will be returned.  Specify NULL if not required.
     938                 :            :  * @mech_type: (gss_OID, modify, optional) The security mechanism
     939                 :            :  *   providing the context.  The returned OID will be a pointer to
     940                 :            :  *   static storage that should be treated as read-only by the
     941                 :            :  *   application; in particular the application should not attempt to
     942                 :            :  *   free it.  Specify NULL if not required.
     943                 :            :  * @ctx_flags: (bit-mask, modify, optional) Contains various
     944                 :            :  *   independent flags, each of which indicates that the context
     945                 :            :  *   supports (or is expected to support, if ctx_open is false) a
     946                 :            :  *   specific service option.  If not needed, specify NULL.  Symbolic
     947                 :            :  *   names are provided for each flag, and the symbolic names
     948                 :            :  *   corresponding to the required flags should be logically-ANDed
     949                 :            :  *   with the ret_flags value to test whether a given option is
     950                 :            :  *   supported by the context.  See below for the flags.
     951                 :            :  * @locally_initiated: (Boolean, modify) Non-zero if the invoking
     952                 :            :  *   application is the context initiator.  Specify NULL if not
     953                 :            :  *   required.
     954                 :            :  * @open: (Boolean, modify) Non-zero if the context is fully
     955                 :            :  *   established; Zero if a context-establishment token is expected
     956                 :            :  *   from the peer application.  Specify NULL if not required.
     957                 :            :  *
     958                 :            :  * Obtains information about a security context.  The caller must
     959                 :            :  * already have obtained a handle that refers to the context, although
     960                 :            :  * the context need not be fully established.
     961                 :            :  *
     962                 :            :  * The `ctx_flags` values:
     963                 :            :  *
     964                 :            :  * `GSS_C_DELEG_FLAG`::
     965                 :            :  * - True - Credentials were delegated from the initiator to the
     966                 :            :  * acceptor.
     967                 :            :  * - False - No credentials were delegated.
     968                 :            :  *
     969                 :            :  * `GSS_C_MUTUAL_FLAG`::
     970                 :            :  * - True - The acceptor was authenticated to the initiator.
     971                 :            :  * - False - The acceptor did not authenticate itself.
     972                 :            :  *
     973                 :            :  * `GSS_C_REPLAY_FLAG`::
     974                 :            :  * - True - replay of protected messages will be detected.
     975                 :            :  * - False - replayed messages will not be detected.
     976                 :            :  *
     977                 :            :  * `GSS_C_SEQUENCE_FLAG`::
     978                 :            :  * - True - out-of-sequence protected messages will be detected.
     979                 :            :  * - False - out-of-sequence messages will not be detected.
     980                 :            :  *
     981                 :            :  * `GSS_C_CONF_FLAG`::
     982                 :            :  * - True - Confidentiality service may be invoked by calling gss_wrap
     983                 :            :  * routine.
     984                 :            :  * - False - No confidentiality service (via gss_wrap)
     985                 :            :  * available. gss_wrap will provide message encapsulation, data-origin
     986                 :            :  * authentication and integrity services only.
     987                 :            :  *
     988                 :            :  * `GSS_C_INTEG_FLAG`::
     989                 :            :  * - True - Integrity service may be invoked by calling either
     990                 :            :  * gss_get_mic or gss_wrap routines.
     991                 :            :  * - False - Per-message integrity service unavailable.
     992                 :            :  *
     993                 :            :  * `GSS_C_ANON_FLAG`::
     994                 :            :  * - True - The initiator's identity will not be revealed to the
     995                 :            :  * acceptor.  The src_name parameter (if requested) contains an
     996                 :            :  * anonymous internal name.
     997                 :            :  * - False - The initiator has been authenticated normally.
     998                 :            :  *
     999                 :            :  * `GSS_C_PROT_READY_FLAG`::
    1000                 :            :  * - True - Protection services (as specified by the states of the
    1001                 :            :  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available for use.
    1002                 :            :  * - False - Protection services (as specified by the states of the
    1003                 :            :  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
    1004                 :            :  * context is fully established (i.e. if the open parameter is
    1005                 :            :  * non-zero).
    1006                 :            :  *
    1007                 :            :  * `GSS_C_TRANS_FLAG`::
    1008                 :            :  * - True - The resultant security context may be transferred to other
    1009                 :            :  * processes via a call to gss_export_sec_context().
    1010                 :            :  * - False - The security context is not transferable.
    1011                 :            :  *
    1012                 :            :  * Return value:
    1013                 :            :  *
    1014                 :            :  * `GSS_S_COMPLETE`: Successful completion.
    1015                 :            :  *
    1016                 :            :  * `GSS_S_NO_CONTEXT`: The referenced context could not be accessed.
    1017                 :            :  **/
    1018                 :            : OM_uint32
    1019                 :          0 : gss_inquire_context (OM_uint32 * minor_status,
    1020                 :            :                      const gss_ctx_id_t context_handle,
    1021                 :            :                      gss_name_t * src_name,
    1022                 :            :                      gss_name_t * targ_name,
    1023                 :            :                      OM_uint32 * lifetime_rec,
    1024                 :            :                      gss_OID * mech_type,
    1025                 :            :                      OM_uint32 * ctx_flags, int *locally_initiated, int *open)
    1026                 :            : {
    1027                 :          0 :   return GSS_S_FAILURE;
    1028                 :            : }
    1029                 :            : 
    1030                 :            : /**
    1031                 :            :  * gss_wrap_size_limit:
    1032                 :            :  * @minor_status: (Integer, modify) Mechanism specific status code.
    1033                 :            :  * @context_handle: (gss_ctx_id_t, read) A handle that refers to the
    1034                 :            :  *   security over which the messages will be sent.
    1035                 :            :  * @conf_req_flag: (Boolean, read) Indicates whether gss_wrap will be
    1036                 :            :  *   asked to apply confidentiality protection in addition to
    1037                 :            :  *   integrity protection.  See the routine description for gss_wrap
    1038                 :            :  *   for more details.
    1039                 :            :  * @qop_req: (gss_qop_t, read) Indicates the level of protection that
    1040                 :            :  *   gss_wrap will be asked to provide.  See the routine description
    1041                 :            :  *   for gss_wrap for more details.
    1042                 :            :  * @req_output_size: (Integer, read) The desired maximum size for
    1043                 :            :  *   tokens emitted by gss_wrap.
    1044                 :            :  * @max_input_size: (Integer, modify) The maximum input message size
    1045                 :            :  *   that may be presented to gss_wrap in order to guarantee that the
    1046                 :            :  *   emitted token shall be no larger than req_output_size bytes.
    1047                 :            :  *
    1048                 :            :  * Allows an application to determine the maximum message size that,
    1049                 :            :  * if presented to gss_wrap with the same conf_req_flag and qop_req
    1050                 :            :  * parameters, will result in an output token containing no more than
    1051                 :            :  * req_output_size bytes.
    1052                 :            :  *
    1053                 :            :  * This call is intended for use by applications that communicate over
    1054                 :            :  * protocols that impose a maximum message size.  It enables the
    1055                 :            :  * application to fragment messages prior to applying protection.
    1056                 :            :  *
    1057                 :            :  * GSS-API implementations are recommended but not required to detect
    1058                 :            :  * invalid QOP values when gss_wrap_size_limit() is called. This
    1059                 :            :  * routine guarantees only a maximum message size, not the
    1060                 :            :  * availability of specific QOP values for message protection.
    1061                 :            :  *
    1062                 :            :  * Successful completion of this call does not guarantee that gss_wrap
    1063                 :            :  * will be able to protect a message of length max_input_size bytes,
    1064                 :            :  * since this ability may depend on the availability of system
    1065                 :            :  * resources at the time that gss_wrap is called.  However, if the
    1066                 :            :  * implementation itself imposes an upper limit on the length of
    1067                 :            :  * messages that may be processed by gss_wrap, the implementation
    1068                 :            :  * should not return a value via max_input_bytes that is greater than
    1069                 :            :  * this length.
    1070                 :            :  *
    1071                 :            :  * Return value:
    1072                 :            :  *
    1073                 :            :  * `GSS_S_COMPLETE`: Successful completion.
    1074                 :            :  *
    1075                 :            :  * `GSS_S_NO_CONTEXT`: The referenced context could not be accessed.
    1076                 :            :  *
    1077                 :            :  * `GSS_S_CONTEXT_EXPIRED`: The context has expired.
    1078                 :            :  *
    1079                 :            :  * `GSS_S_BAD_QOP`: The specified QOP is not supported by the
    1080                 :            :  * mechanism.
    1081                 :            :  **/
    1082                 :            : OM_uint32
    1083                 :          0 : gss_wrap_size_limit (OM_uint32 * minor_status,
    1084                 :            :                      const gss_ctx_id_t context_handle,
    1085                 :            :                      int conf_req_flag,
    1086                 :            :                      gss_qop_t qop_req,
    1087                 :            :                      OM_uint32 req_output_size, OM_uint32 * max_input_size)
    1088                 :            : {
    1089                 :          0 :   return GSS_S_FAILURE;
    1090                 :            : }
    1091                 :            : 
    1092                 :            : /**
    1093                 :            :  * gss_export_sec_context:
    1094                 :            :  * @minor_status: (Integer, modify) Mechanism specific status code.
    1095                 :            :  * @context_handle: (gss_ctx_id_t, modify) Context handle identifying
    1096                 :            :  *   the context to transfer.
    1097                 :            :  * @interprocess_token: (buffer, opaque, modify) Token to be
    1098                 :            :  *   transferred to target process.  Storage associated with this
    1099                 :            :  *   token must be freed by the application after use with a call to
    1100                 :            :  *   gss_release_buffer().
    1101                 :            :  *
    1102                 :            :  * Provided to support the sharing of work between multiple processes.
    1103                 :            :  * This routine will typically be used by the context-acceptor, in an
    1104                 :            :  * application where a single process receives incoming connection
    1105                 :            :  * requests and accepts security contexts over them, then passes the
    1106                 :            :  * established context to one or more other processes for message
    1107                 :            :  * exchange. gss_export_sec_context() deactivates the security context
    1108                 :            :  * for the calling process and creates an interprocess token which,
    1109                 :            :  * when passed to gss_import_sec_context in another process, will
    1110                 :            :  * re-activate the context in the second process. Only a single
    1111                 :            :  * instantiation of a given context may be active at any one time; a
    1112                 :            :  * subsequent attempt by a context exporter to access the exported
    1113                 :            :  * security context will fail.
    1114                 :            :  *
    1115                 :            :  * The implementation may constrain the set of processes by which the
    1116                 :            :  * interprocess token may be imported, either as a function of local
    1117                 :            :  * security policy, or as a result of implementation decisions.  For
    1118                 :            :  * example, some implementations may constrain contexts to be passed
    1119                 :            :  * only between processes that run under the same account, or which
    1120                 :            :  * are part of the same process group.
    1121                 :            :  *
    1122                 :            :  * The interprocess token may contain security-sensitive information
    1123                 :            :  * (for example cryptographic keys).  While mechanisms are encouraged
    1124                 :            :  * to either avoid placing such sensitive information within
    1125                 :            :  * interprocess tokens, or to encrypt the token before returning it to
    1126                 :            :  * the application, in a typical object-library GSS-API implementation
    1127                 :            :  * this may not be possible. Thus the application must take care to
    1128                 :            :  * protect the interprocess token, and ensure that any process to
    1129                 :            :  * which the token is transferred is trustworthy.
    1130                 :            :  *
    1131                 :            :  * If creation of the interprocess token is successful, the
    1132                 :            :  * implementation shall deallocate all process-wide resources
    1133                 :            :  * associated with the security context, and set the context_handle to
    1134                 :            :  * GSS_C_NO_CONTEXT.  In the event of an error that makes it
    1135                 :            :  * impossible to complete the export of the security context, the
    1136                 :            :  * implementation must not return an interprocess token, and should
    1137                 :            :  * strive to leave the security context referenced by the
    1138                 :            :  * context_handle parameter untouched.  If this is impossible, it is
    1139                 :            :  * permissible for the implementation to delete the security context,
    1140                 :            :  * providing it also sets the context_handle parameter to
    1141                 :            :  * GSS_C_NO_CONTEXT.
    1142                 :            :  *
    1143                 :            :  * Return value:
    1144                 :            :  *
    1145                 :            :  * `GSS_S_COMPLETE`: Successful completion.
    1146                 :            :  *
    1147                 :            :  * `GSS_S_CONTEXT_EXPIRED`: The context has expired.
    1148                 :            :  *
    1149                 :            :  * `GSS_S_NO_CONTEXT`: The context was invalid.
    1150                 :            :  *
    1151                 :            :  * `GSS_S_UNAVAILABLE`: The operation is not supported.
    1152                 :            :  **/
    1153                 :            : OM_uint32
    1154                 :          0 : gss_export_sec_context (OM_uint32 * minor_status,
    1155                 :            :                         gss_ctx_id_t * context_handle,
    1156                 :            :                         gss_buffer_t interprocess_token)
    1157                 :            : {
    1158                 :          0 :   return GSS_S_UNAVAILABLE;
    1159                 :            : }
    1160                 :            : 
    1161                 :            : /**
    1162                 :            :  * gss_import_sec_context:
    1163                 :            :  * @minor_status: (Integer, modify) Mechanism specific status code.
    1164                 :            :  * @interprocess_token: (buffer, opaque, modify) Token received from
    1165                 :            :  *   exporting process
    1166                 :            :  * @context_handle: (gss_ctx_id_t, modify) Context handle of newly
    1167                 :            :  *   reactivated context.  Resources associated with this context
    1168                 :            :  *   handle must be released by the application after use with a call
    1169                 :            :  *   to gss_delete_sec_context().
    1170                 :            :  *
    1171                 :            :  * Allows a process to import a security context established by
    1172                 :            :  * another process.  A given interprocess token may be imported only
    1173                 :            :  * once.  See gss_export_sec_context.
    1174                 :            :  *
    1175                 :            :  * Return value:
    1176                 :            :  *
    1177                 :            :  * `GSS_S_COMPLETE`: Successful completion.
    1178                 :            :  *
    1179                 :            :  * `GSS_S_NO_CONTEXT`: The token did not contain a valid context
    1180                 :            :  * reference.
    1181                 :            :  *
    1182                 :            :  * `GSS_S_DEFECTIVE_TOKEN`: The token was invalid.
    1183                 :            :  *
    1184                 :            :  * `GSS_S_UNAVAILABLE`: The operation is unavailable.
    1185                 :            :  *
    1186                 :            :  * `GSS_S_UNAUTHORIZED`: Local policy prevents the import of this
    1187                 :            :  *  context by the current process.
    1188                 :            :  **/
    1189                 :            : OM_uint32
    1190                 :          0 : gss_import_sec_context (OM_uint32 * minor_status,
    1191                 :            :                         const gss_buffer_t interprocess_token,
    1192                 :            :                         gss_ctx_id_t * context_handle)
    1193                 :            : {
    1194                 :          0 :   return GSS_S_UNAVAILABLE;
    1195                 :            : }

Generated by: LCOV version 1.8