Example #1
0
void
kerberos5_forward(kstream ks)
{
    krb5_error_code r;
    krb5_ccache ccache;
    krb5_principal client = 0;
    krb5_principal server = 0;
    krb5_data forw_creds;

    forw_creds.data = 0;

    if ((r = krb5_cc_default(k5_context, &ccache))) {
      com_err(NULL, r, "Kerberos V5: could not get default ccache");
      return;
    }

    if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) {
      com_err(NULL, r, "Kerberos V5: could not get default principal");
      goto cleanup;
    }

    if ((r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME,
				     KRB5_NT_SRV_HST, &server))) {
      com_err(NULL, r, "Kerberos V5: could not make server principal");
      goto cleanup;
    }

    if ((r = krb5_auth_con_genaddrs(k5_context, auth_context, ks->fd,
			    KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) {
      com_err(NULL, r, "Kerberos V5: could not gen local full address");
      goto cleanup;
    }

    if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client, server,
			        ccache, forwardable_flag, &forw_creds)) {
      com_err(NULL, r, "Kerberos V5: error getting forwarded creds");
      goto cleanup;
    }
    
    /* Send forwarded credentials */
    if (!Data(ks, KRB_FORWARD, forw_creds.data, forw_creds.length)) {
      MessageBox(HWND_DESKTOP,
		 "Not enough room for authentication data", "",
		 MB_OK | MB_ICONEXCLAMATION);
    }
    
cleanup:
    if (client)
      krb5_free_principal(k5_context, client);
    if (server)
      krb5_free_principal(k5_context, server);
#if 0 /* XXX */
	if (forw_creds.data)
      free(forw_creds.data);
#endif
    krb5_cc_close(k5_context, ccache);
}
int Condor_Auth_Kerberos :: forward_tgt_creds(krb5_creds      * cred,
                                              krb5_ccache       ccache)
{
    krb5_error_code  code;
    krb5_data        request;
    int              message, rc = 1;
	MyString         hostname;
    
	hostname = get_hostname(mySock_->peer_addr());
	char* hostname_char = strdup(hostname.Value());
    
    if ((code = krb5_fwd_tgt_creds(krb_context_, 
                                  auth_context_,
	                              hostname_char,
                                  cred->client, 
                                  cred->server,
                                  ccache, 
                                  KDC_OPT_FORWARDABLE,
                                  &request))) {
		free(hostname_char);
        goto error;
    }
	free(hostname_char);
    
    // Now, send it
    
    message = KERBEROS_FORWARD;
    mySock_->encode();
    if ((!mySock_->code(message)) || (!mySock_->end_of_message())) {
        dprintf(D_ALWAYS, "Failed to send KERBEROS_FORWARD response\n");
        goto cleanup;
    }
    
    rc = !(send_request(&request) == KERBEROS_GRANT);
    
    goto cleanup;
    
 error:
    dprintf( D_ALWAYS, "KERBEROS: %s\n", error_message(code) );
    
 cleanup:
    
    free(request.data);
    
    return rc;
}
Example #3
0
int
auks_krb5_cred_get_fwd(char *ccachefilename, char *serverName,
		       char **p_buffer,
		       size_t * p_buffer_length)
{

	int fstatus = AUKS_ERROR ;

	/* kerberos related variables */
	krb5_error_code err_code;
	krb5_context context;
	krb5_ccache ccache;
	krb5_principal principal;
	krb5_creds **out_creds_array = NULL;
	krb5_auth_context auth_context;
	krb5_flags authopts;
	krb5_data outbuf;
	krb5_data *p_outbuf;
	krb5_replay_data krdata;

	authopts = AP_OPTS_MUTUAL_REQUIRED;
	authopts &= (~OPTS_FORWARD_CREDS);
	authopts &= (~OPTS_FORWARDABLE_CREDS);

	if ( serverName == NULL ) {
		auks_error("no host specified");
		fstatus = AUKS_ERROR_KRB5_CRED_NO_HOST_SPECIFIED ;
		goto exit;
	}

	/* initialize kerberos context */
	err_code = krb5_init_context(&context);
	if (err_code) {
		auks_error("unable to initialize kerberos context : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_CTX ;
		goto exit;
	}
	auks_log("kerberos context successfully initialized");

	/* initialize kerberos credential cache structure */
	if (ccachefilename == NULL)
		err_code = krb5_cc_default(context, &ccache);
	else
		err_code = krb5_cc_resolve(context,ccachefilename,&ccache);
	if (err_code) {
		auks_error("unable to resolve credential cache : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_OPEN_CC ;
		goto ctx_exit ;
	}
	auks_log("credential cache successfully resolved");

	/* get principal using credential cache */
	err_code = krb5_cc_get_principal(context,ccache,&principal);
	if (err_code) {
		auks_error("unable to get principal from credential cache : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_GET_PRINC ;
		goto cc_exit ;
	}
	auks_log("principal successfully extracted from credential cache");

	/* initialize kerberos authentication context */
	err_code = krb5_auth_con_init(context,&auth_context);
	if (err_code) {
		auks_error("unable to initialize kerberos authentication "
			   "context : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ;
		goto princ_exit;
	}
	auks_log("kerberos authentication context successfully initialized");

	/* do replay detection using timestamps */
	krb5_auth_con_setflags(context,auth_context,KRB5_AUTH_CONTEXT_RET_TIME);

	/* get forwarded credential for server */
	err_code = krb5_fwd_tgt_creds(context,auth_context,serverName,
				      principal,NULL,NULL,authopts,&outbuf);
	if (err_code) {
		auks_error("unable to get serialized and crypted forwarded "
			   "credential for %s from KDC : %s",
			   serverName,error_message(err_code));
		fstatus =  AUKS_ERROR_KRB5_CRED_GET_FWD_CRED ;
		goto auth_ctx_exit;
	}
	auks_log("serialized and crypted forwarded credential for %s "
		 "successfully got from KDC",serverName);

	/* desactive replay detection */
	krb5_auth_con_setflags(context,auth_context,0);

	/* decrypt (using session key stored in auth context) and */
	/* unserialized forwarded credential in a kerberos credential */
	/* structure */
	err_code = krb5_rd_cred(context,auth_context,&outbuf,&out_creds_array,
				&krdata);
	if (err_code) {
		auks_error("unable to unserialize and decrypt forwarded "
			   "credential for %s : %s",serverName,
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_RD_CRED ;
		goto fwd_exit;
	}
	auks_log("unserialization and decryption of forwarded "
		 "credential for %s succesfully done",serverName);

	/* Reinitialize kerberos authentication context in order to */
	/* write credential to output buffer */
	krb5_auth_con_free(context,auth_context);
	err_code = krb5_auth_con_init(context,&auth_context);
	if (err_code) {
		auks_error("unable to reinitialize kerberos connection "
			   "authentication context : %s",error_message
			   (err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ;
		goto rd_cred_exit;
	}
	auks_log("kerberos connection authentication context "
		 "reinitialization successfully done");

	/* no flags */
	krb5_auth_con_setflags(context,auth_context,0);

	/* serialize forwarded credential (no encryption because auth */
	/* context session key is nullified) */
	err_code = krb5_mk_1cred(context,auth_context,*out_creds_array,
				 &p_outbuf,&krdata);
	if (err_code) {
		auks_error("unable to serialize forwarded credential for "
			   "%s : %s",serverName,error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_MK_CRED ;
		goto rd_cred_exit;
	}
	auks_log("forwarded credential for %s successfully serialized",
		 serverName);

	/* allocate output buffer and store serialized credential */
	(*p_buffer) = (char *) malloc(p_outbuf->length * sizeof(char));
	if ((*p_buffer) == NULL) {
		auks_error("unable to allocate serialized credential output "
			   "buffer for %s",serverName);
		*p_buffer_length = 0 ;
		fstatus = AUKS_ERROR_KRB5_CRED_MALLOC ;
	} else {
		/* copy data */
		memcpy(*p_buffer,p_outbuf->data,p_outbuf->length);
		*p_buffer_length = p_outbuf->length;
		auks_log("forwarded credential successfully stored "
			 "in output buffer");
		fstatus	= AUKS_SUCCESS ;
	}

	krb5_free_data(context,p_outbuf);

rd_cred_exit:
	krb5_free_creds(context,*out_creds_array);
	free(out_creds_array);

fwd_exit:
	krb5_free_data_contents(context, &outbuf);

auth_ctx_exit:
	krb5_auth_con_free(context,auth_context);

princ_exit:
	krb5_free_principal(context, principal);

cc_exit:
	krb5_cc_close(context, ccache);

ctx_exit:
	krb5_free_context(context);

exit:
	return fstatus;
}
Example #4
0
void
kerberos5_forward (TN_Authenticator * ap)
{
  krb5_error_code r;
  krb5_ccache ccache;
  krb5_principal client = 0;
  krb5_principal server = 0;
  krb5_data forw_creds;

  forw_creds.data = 0;

  if ((r = krb5_cc_default (telnet_context, &ccache)))
    {
      DEBUG (("Kerberos V5: could not get default ccache - %s\r\n",
	      error_message (r)));
      return;
    }

  for (;;)			/* Fake loop */
    {
      if ((r = krb5_cc_get_principal (telnet_context, ccache, &client)))
	{
	  DEBUG (("Kerberos V5: could not get default principal - %s\r\n",
		  error_message (r)));
	  break;
	}
      if ((r =
	   krb5_sname_to_principal (telnet_context, RemoteHostName, "host",
				    KRB5_NT_SRV_HST, &server)))
	{
	  DEBUG (("Kerberos V5: could not make server principal - %s\r\n",
		  error_message (r)));
	  break;
	}
      if ((r = krb5_auth_con_genaddrs (telnet_context, auth_context, net,
				       KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR)))
	{
	  DEBUG (("Kerberos V5: could not gen local full address - %s\r\n",
		  error_message (r)));
	  break;
	}
      if ((r = krb5_fwd_tgt_creds (telnet_context, auth_context, 0, client,
				   server, ccache,
				   forward_flags & OPTS_FORWARDABLE_CREDS,
				   &forw_creds)))
	{
	  DEBUG (("Kerberos V5: error getting forwarded creds - %s\r\n",
		  error_message (r)));
	  break;
	}

      /* Send forwarded credentials */
      if (!Data (ap, KRB_FORWARD, forw_creds.data, forw_creds.length))
	{
	  DEBUG (("Not enough room for authentication data\r\n"));
	}
      else
	{
	  DEBUG (("Forwarded local Kerberos V5 credentials to server\r\n"));
	}
      break;
    }

  if (client)
    krb5_free_principal (telnet_context, client);
  if (server)
    krb5_free_principal (telnet_context, server);
  free (forw_creds.data);
  krb5_cc_close (telnet_context, ccache);
}