/*
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 *
 * SPDX-License-Identifier: MPL-2.0
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
 */

#pragma once

/*! \file dst/gssapi.h */

#include <inttypes.h>
#include <stdbool.h>

#include <isc/formatcheck.h>
#include <isc/lang.h>
#include <isc/types.h>

#include <dns/types.h>

typedef void *dns_gss_cred_id_t;
typedef void *dns_gss_ctx_id_t;

ISC_LANG_BEGINDECLS

/***
 *** Types
 ***/

/***
 *** Functions
 ***/

isc_result_t
dst_gssapi_acquirecred(const dns_name_t *name, bool initiate,
		       dns_gss_cred_id_t *cred);
/*
 *	Acquires GSS credentials.
 *
 *	Requires:
 *	'name'	    is a valid name, preferably one known by the GSS provider
 *	'initiate'  indicates whether the credentials are for initiating or
 *		    accepting contexts
 *      'cred'      is a pointer to NULL, which will be allocated with the
 *		    credential handle.  Call dst_gssapi_releasecred to free
 *		    the memory.
 *
 *	Returns:
 *		ISC_R_SUCCESS msg was successfully updated to include the
 *				      query to be sent
 *		other		  an error occurred while building the message
 */

isc_result_t
dst_gssapi_releasecred(dns_gss_cred_id_t *cred);
/*
 *	Releases GSS credentials.  Calling this function does release the
 *	  memory allocated for the credential in dst_gssapi_acquirecred()
 *
 *	Requires:
 *      'mctx'  is a valid memory context
 *      'cred'  is a pointer to the credential to be released
 *
 *	Returns:
 *		ISC_R_SUCCESS	credential was released successfully
 *		other		an error occurred while releaseing
 *				the credential
 */

isc_result_t
dst_gssapi_initctx(const dns_name_t *name, isc_buffer_t *intoken,
		   isc_buffer_t *outtoken, dns_gss_ctx_id_t *gssctx,
		   isc_mem_t *mctx, char **err_message);
/*
 *	Initiates a GSS context.
 *
 *	Requires:
 *	'name'     is a valid name, preferably one known by the GSS
 *	provider
 *	'intoken'  is a token received from the acceptor, or NULL if
 *		   there isn't one
 *	'outtoken' is a buffer to receive the token generated by
 *		   gss_init_sec_context() to be sent to the acceptor
 *      'context'  is a pointer to a valid dns_gss_ctx_id_t
 *                 (which may have the value DNS_GSS_C_NO_CONTEXT)
 *
 *	Returns:
 *		ISC_R_SUCCESS   msg was successfully updated to include the
 *				query to be sent
 *		other		an error occurred while building the message
 *		*err_message	optional error message
 */

isc_result_t
dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
		     isc_region_t *intoken, isc_buffer_t **outtoken,
		     dns_gss_ctx_id_t *context, dns_name_t *principal,
		     isc_mem_t *mctx);
/*
 *	Accepts a GSS context.
 *
 *	Requires:
 *	'mctx'     is a valid memory context
 *      'cred'     is the acceptor's valid GSS credential handle
 *	'intoken'  is a token received from the initiator
 *	'outtoken' is a pointer a buffer pointer used to return the token
 *		   generated by gss_accept_sec_context() to be sent to the
 *		   initiator
 *      'context'  is a valid pointer to receive the generated context handle.
 *
 *	Requires:
 *		'outtoken' != NULL && *outtoken == NULL.
 *		'context'  != NULL && *context  == NULL.
 *
 *	Returns:
 *		ISC_R_SUCCESS		msg was successfully updated to include
 *					the query to be sent
 *		DNS_R_INVALIDTKEY	an error occurred while accepting the
 * 					context
 *		ISC_R_FAILURE		other error occurred
 */

isc_result_t
dst_gssapi_deletectx(isc_mem_t *mctx, dns_gss_ctx_id_t *gssctx);
/*
 *	Destroys a GSS context.  This function deletes the context from the GSS
 *	provider and then frees the memory used by the context pointer.
 *
 *	Requires:
 *      'mctx'    is a valid memory context
 *	'context' is a valid GSS context
 *
 *	Returns:
 *		ISC_R_SUCCESS
 */

void
gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
/*
 * Logging function for GSS.
 *
 *  Requires
 *      'level' is the log level to be used, as an integer
 *      'fmt'   is a printf format specifier
 */

char *
gss_error_tostring(uint32_t major, uint32_t minor, char *buf, size_t buflen);
/*
 *	Render a GSS major status/minor status pair into a string
 *
 *	Requires:
 *      'major' is a GSS major status code
 *	'minor' is a GSS minor status code
 *
 *	Returns:
 *		A string containing the text representation of the error codes.
 *		Users should copy the string if they wish to keep it.
 */

bool
dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer,
				    const dns_name_t *name,
				    const dns_name_t *realm, bool subdomain);
/*
 *	Compare a "signer" (in the format of a Kerberos-format Kerberos5
 *	principal: host/example.com@EXAMPLE.COM) to the realm name stored
 *	in "name" (which represents the realm name).
 *
 */

bool
dst_gssapi_identitymatchesrealmms(const dns_name_t *signer,
				  const dns_name_t *name,
				  const dns_name_t *realm, bool subdomain);
/*
 *	Compare a "signer" (in the format of a Kerberos-format Kerberos5
 *	principal: host/example.com@EXAMPLE.COM) to the realm name stored
 *	in "name" (which represents the realm name).
 *
 */

ISC_LANG_ENDDECLS
