Esempio n. 1
0
static int
doit (Shishi * h, Shishi_ap * ap, int verbose)
{
  Shishi_asn1 asn1safe;
  Shishi_safe *safe;
  char *userdata;
  size_t userdatalen;
  int res;

  printf ("Application exchange start.  Press ^D to finish.\n");

  while ((res = shishi_safe_parse (h, stdin, &asn1safe)) == SHISHI_OK)
    {
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not read SAFE:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}

      res = shishi_safe (h, &safe);
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not create SAFE:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}

      shishi_safe_safe_set (safe, asn1safe);

      res = shishi_safe_verify (safe, shishi_ap_key (ap));
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not verify SAFE:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}

      printf ("Verified SAFE successfully...\n");

      res = shishi_safe_user_data (h, asn1safe, &userdata, &userdatalen);
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not extract user data:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}
      userdata[userdatalen] = '\0';
      printf ("user data: `%s'\n", userdata);

    }

  if (ferror (stdin))
    {
      printf ("error reading stdin\n");
      return 1;
    }

  return 0;
}
Esempio n. 2
0
static int
doit (Shishi * handle, Shishi_ap * ap, int verbose)
{
  char line[BUFSIZ];
  int res;

  printf ("Application exchange start.  Press ^D to finish.\n");

  while (fgets (line, sizeof (line), stdin))
    {
      Shishi_safe *safe;

      line[strlen(line)-1] = '\0';
      printf ("read: %s\n", line);

      res = shishi_safe (handle, &safe);
      if (res != SHISHI_OK)
	{
	  printf ("Could not build SAFE: %s\n", shishi_strerror (res));
	  return res;
	}

      res = shishi_safe_set_user_data (handle, shishi_safe_safe (safe),
				       line, strlen (line));
      if (res != SHISHI_OK)
	{
	  printf ("Could not set application data in SAFE: %s\n",
		  shishi_strerror (res));
	  return res;
	}

      res = shishi_safe_build (safe, shishi_ap_key (ap));
      if (res != SHISHI_OK)
	{
	  printf ("Could not build SAFE: %s\n", shishi_strerror (res));
	  return res;
	}

      res = shishi_safe_print (handle, stdout, shishi_safe_safe (safe));
      if (res != SHISHI_OK)
	{
	  printf ("Could not print SAFE: %s\n", shishi_strerror (res));
	  return res;
	}
    }

  if (ferror (stdin))
    {
      printf ("error reading stdin\n");
      return 1;
    }

  return 0;
}
Esempio n. 3
0
/* Allows a remotely initiated security context between the
   application and a remote peer to be established, using krb5.
   Assumes context_handle is valid. */
OM_uint32
gss_krb5_accept_sec_context (OM_uint32 * minor_status,
                             gss_ctx_id_t * context_handle,
                             const gss_cred_id_t acceptor_cred_handle,
                             const gss_buffer_t input_token_buffer,
                             const gss_channel_bindings_t input_chan_bindings,
                             gss_name_t * src_name,
                             gss_OID * mech_type,
                             gss_buffer_t output_token,
                             OM_uint32 * ret_flags,
                             OM_uint32 * time_rec,
                             gss_cred_id_t * delegated_cred_handle)
{
    gss_buffer_desc data;
    char *in;
    size_t inlen;
    gss_ctx_id_t cx;
    _gss_krb5_ctx_t cxk5;
    _gss_krb5_cred_t crk5;
    int rc;

    if (minor_status)
        *minor_status = 0;

    if (ret_flags)
        *ret_flags = 0;

    if (!acceptor_cred_handle)
        /* XXX support GSS_C_NO_CREDENTIAL: acquire_cred() default server */
        return GSS_S_NO_CRED;

    if (*context_handle)
        return GSS_S_FAILURE;

    crk5 = acceptor_cred_handle->krb5;

    cx = calloc (sizeof (*cx), 1);
    if (!cx)
    {
        if (minor_status)
            *minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }

    cxk5 = calloc (sizeof (*cxk5), 1);
    if (!cxk5)
    {
        free (cx);
        if (minor_status)
            *minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }

    cx->mech = GSS_KRB5;
    cx->krb5 = cxk5;
    /* XXX cx->peer?? */
    *context_handle = cx;

    cxk5->sh = crk5->sh;
    cxk5->key = crk5->key;
    cxk5->acceptor = 1;

    rc = shishi_ap (cxk5->sh, &cxk5->ap);
    if (rc != SHISHI_OK)
        return GSS_S_FAILURE;

    rc = gss_decapsulate_token (input_token_buffer, GSS_KRB5, &in, &inlen);
    if (!rc)
        return GSS_S_BAD_MIC;

    if (inlen < TOK_LEN)
        return GSS_S_BAD_MIC;

    if (memcmp (in, TOK_AP_REQ, TOK_LEN) != 0)
        return GSS_S_BAD_MIC;

    rc = shishi_ap_req_der_set (cxk5->ap, in + TOK_LEN, inlen - TOK_LEN);
    if (rc != SHISHI_OK)
        return GSS_S_FAILURE;

    rc = shishi_ap_req_process (cxk5->ap, crk5->key);
    if (rc != SHISHI_OK)
    {
        if (minor_status)
            *minor_status = GSS_KRB5_S_G_VALIDATE_FAILED;
        return GSS_S_FAILURE;
    }

    rc = shishi_authenticator_seqnumber_get (cxk5->sh,
            shishi_ap_authenticator (cxk5->ap),
            &cxk5->initseqnr);
    if (rc != SHISHI_OK)
        return GSS_S_FAILURE;

    rc = _gss_krb5_checksum_parse (minor_status,
                                   context_handle,
                                   input_chan_bindings);
    if (rc != GSS_S_COMPLETE)
        return GSS_S_FAILURE;

    cxk5->tkt = shishi_ap_tkt (cxk5->ap);
    cxk5->key = shishi_ap_key (cxk5->ap);

    if (shishi_apreq_mutual_required_p (crk5->sh, shishi_ap_req (cxk5->ap)))
    {
        Shishi_asn1 aprep;

        rc = shishi_ap_rep_asn1 (cxk5->ap, &aprep);
        if (rc != SHISHI_OK)
        {
            printf ("Error creating AP-REP: %s\n", shishi_strerror (rc));
            return GSS_S_FAILURE;
        }

        rc = shishi_encapreppart_seqnumber_get (cxk5->sh,
                                                shishi_ap_encapreppart (cxk5->
                                                        ap),
                                                &cxk5->acceptseqnr);
        if (rc != SHISHI_OK)
        {
            /* A strict 1964 implementation would return
               GSS_S_DEFECTIVE_TOKEN here.  gssapi-cfx permit absent
               sequence number, though. */
            cxk5->acceptseqnr = 0;
        }

        {
            char *der;
            size_t len;

            rc = shishi_asn1_to_der (crk5->sh, aprep, &der, &len);
            if (rc != SHISHI_OK)
            {
                printf ("Error der encoding aprep: %s\n", shishi_strerror (rc));
                return GSS_S_FAILURE;
            }
            data.value = der;
            data.length = len;
        }

        rc = gss_encapsulate_token_prefix (&data, TOK_AP_REP, TOK_LEN,
                                           GSS_KRB5, output_token);
        if (!rc)
            return GSS_S_FAILURE;

        if (ret_flags)
            *ret_flags = GSS_C_MUTUAL_FLAG;
    }
    else
    {
        output_token->value = NULL;
        output_token->length = 0;
    }

    if (src_name)
    {
        gss_name_t p;

        p = malloc (sizeof (*p));
        if (!p)
        {
            if (minor_status)
                *minor_status = ENOMEM;
            return GSS_S_FAILURE;
        }

        rc = shishi_encticketpart_client (cxk5->sh,
                                          shishi_tkt_encticketpart (cxk5->tkt),
                                          &p->value, &p->length);
        if (rc != SHISHI_OK)
            return GSS_S_FAILURE;

        p->type = GSS_KRB5_NT_PRINCIPAL_NAME;

        *src_name = p;
    }

    /* PROT_READY is not mentioned in 1964/gssapi-cfx but we support
       it anyway. */
    if (ret_flags)
        *ret_flags |= GSS_C_PROT_READY_FLAG;

    if (minor_status)
        *minor_status = 0;
    return GSS_S_COMPLETE;
}
Esempio n. 4
0
/* Initiates the establishment of a krb5 security context between the
   application and a remote peer.  Assumes that context_handle and
   output_token are valid and cleared. */
OM_uint32
gss_krb5_init_sec_context (OM_uint32 * minor_status,
                           const gss_cred_id_t initiator_cred_handle,
                           gss_ctx_id_t * context_handle,
                           const gss_name_t target_name,
                           const gss_OID mech_type,
                           OM_uint32 req_flags,
                           OM_uint32 time_req,
                           const gss_channel_bindings_t input_chan_bindings,
                           const gss_buffer_t input_token,
                           gss_OID * actual_mech_type,
                           gss_buffer_t output_token,
                           OM_uint32 * ret_flags, OM_uint32 * time_rec)
{
    gss_ctx_id_t ctx = *context_handle;
    _gss_krb5_ctx_t k5 = ctx->krb5;
    OM_uint32 maj_stat;
    int rc;

    if (minor_status)
        *minor_status = 0;

    if (initiator_cred_handle)
    {
        /* We only support the default initiator.  See k5internal.h for
           adding a Shishi_tkt to the credential structure.  I'm not sure
           what the use would be -- user-to-user authentication perhaps?
           Later: if you have tickets for foo@BAR and bar@FOO, it may be
           useful to call gss_acquire_cred first to chose which one to
           initiate the context with.  Not many applications need this. */
        return GSS_S_NO_CRED;
    }

    if (k5 == NULL)
    {
        k5 = ctx->krb5 = calloc (sizeof (*k5), 1);
        if (!k5)
        {
            if (minor_status)
                *minor_status = ENOMEM;
            return GSS_S_FAILURE;
        }

        rc = shishi_init (&k5->sh);
        if (rc != SHISHI_OK)
            return GSS_S_FAILURE;
    }

    if (!k5->reqdone)
    {
        maj_stat = init_request (minor_status,
                                 initiator_cred_handle,
                                 context_handle,
                                 target_name,
                                 mech_type,
                                 req_flags,
                                 time_req,
                                 input_chan_bindings,
                                 input_token,
                                 actual_mech_type,
                                 output_token, ret_flags, time_rec);
        if (GSS_ERROR (maj_stat))
            return maj_stat;

        k5->flags = req_flags & (	/* GSS_C_DELEG_FLAG | */
                        GSS_C_MUTUAL_FLAG |
                        GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG |
                        GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG);
        /* PROT_READY is not mentioned in 1964/gssapi-cfx but we support
           it anyway. */
        k5->flags |= GSS_C_PROT_READY_FLAG;

        if (ret_flags)
            *ret_flags = k5->flags;

        k5->key = shishi_ap_key (k5->ap);
        k5->reqdone = 1;
    }
    else if (k5->reqdone && k5->flags & GSS_C_MUTUAL_FLAG && !k5->repdone)
    {
        maj_stat = init_reply (minor_status,
                               initiator_cred_handle,
                               context_handle,
                               target_name,
                               mech_type,
                               req_flags,
                               time_req,
                               input_chan_bindings,
                               input_token,
                               actual_mech_type,
                               output_token, ret_flags, time_rec);
        if (GSS_ERROR (maj_stat))
            return maj_stat;

        if (ret_flags)
            *ret_flags = k5->flags;

        k5->repdone = 1;
    }
    else
        maj_stat = GSS_S_FAILURE;

    if (time_rec)
        *time_rec = gss_krb5_tktlifetime (k5->tkt);

    return maj_stat;
}