2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +00:00

2105. [func] GSS-TSIG support (RFC 3645).

This commit is contained in:
Mark Andrews
2006-12-04 01:54:53 +00:00
parent 6292befae7
commit 289ae548d5
58 changed files with 7620 additions and 1244 deletions

View File

@@ -1,3 +1,5 @@
2105. [func] GSS-TSIG support (RFC 3645).
2104. [port] Fix Solaris SMF error message.
2103. [port] Add /usr/sfw to list of locations for OpenSSL

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.c,v 1.239 2006/07/22 01:00:04 marka Exp $ */
/* $Id: client.c,v 1.240 2006/12/04 01:52:45 marka Exp $ */
#include <config.h>
@@ -1227,6 +1227,7 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
{
dns_view_t *view;
dns_tsigkey_t *key;
dns_name_t *tsig = NULL;
isc_netaddr_t netsrc;
isc_netaddr_t netdst;
@@ -1241,7 +1242,6 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
dns_name_t *tsig = NULL;
if (view->matchrecursiveonly)
continue;
@@ -1253,14 +1253,14 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
isc_boolean_t match;
isc_result_t result;
tsig = &mykey->name;
result = dns_view_gettsig(view, tsig, &key);
result = dns_view_gettsig(view, &mykey->name, &key);
if (result != ISC_R_SUCCESS)
continue;
match = dst_key_compare(mykey->key, key->key);
dns_tsigkey_detach(&key);
if (!match)
continue;
tsig = dns_tsigkey_identity(mykey);
}
if (allowed(&netsrc, tsig, view->matchclients) &&
@@ -1590,10 +1590,11 @@ client_request(isc_task_t *task, isc_event_t *event) {
client->message->rdclass == dns_rdataclass_any)
{
dns_name_t *tsig = NULL;
sigresult = dns_message_rechecksig(client->message,
view);
if (sigresult == ISC_R_SUCCESS)
tsig = client->message->tsigname;
tsig = dns_tsigkey_identity(client->message->tsigkey);
if (allowed(&netaddr, tsig, view->matchclients) &&
allowed(&destaddr, tsig, view->matchdestinations) &&
@@ -1672,12 +1673,28 @@ client_request(isc_task_t *task, isc_event_t *event) {
/* There is a signature, but it is bad. */
if (dns_message_gettsig(client->message, &name) != NULL) {
char namebuf[DNS_NAME_FORMATSIZE];
char cnamebuf[DNS_NAME_FORMATSIZE];
dns_name_format(name, namebuf, sizeof(namebuf));
if (client->message->tsigkey->generated) {
dns_name_format(client->message->tsigkey->creator,
cnamebuf, sizeof(cnamebuf));
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
NS_LOGMODULE_CLIENT,
ISC_LOG_ERROR,
"request has invalid signature: "
"TSIG %s (%s): %s (%s)", namebuf,
cnamebuf,
isc_result_totext(result),
tsigrcode);
} else {
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT,
ISC_LOG_ERROR,
"request has invalid signature: "
"TSIG %s: %s (%s)", namebuf,
isc_result_totext(result), tsigrcode);
isc_result_totext(result),
tsigrcode);
}
} else {
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: control.c,v 1.28 2006/03/10 00:23:21 marka Exp $ */
/* $Id: control.c,v 1.29 2006/12/04 01:52:45 marka Exp $ */
/*! \file */
@@ -158,6 +158,10 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
result = ns_server_flushname(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_STATUS)) {
result = ns_server_status(ns_g_server, text);
} else if (command_compare(command, NS_COMMAND_TSIGLIST)) {
result = ns_server_tsiglist(ns_g_server, text);
} else if (command_compare(command, NS_COMMAND_TSIGDELETE)) {
result = ns_server_tsigdelete(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_FREEZE)) {
result = ns_server_freeze(ns_g_server, ISC_TRUE, command);
} else if (command_compare(command, NS_COMMAND_UNFREEZE) ||

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: control.h,v 1.22 2006/03/09 23:39:00 marka Exp $ */
/* $Id: control.h,v 1.23 2006/12/04 01:52:45 marka Exp $ */
#ifndef NAMED_CONTROL_H
#define NAMED_CONTROL_H 1
@@ -47,6 +47,8 @@
#define NS_COMMAND_FLUSH "flush"
#define NS_COMMAND_FLUSHNAME "flushname"
#define NS_COMMAND_STATUS "status"
#define NS_COMMAND_TSIGLIST "tsig-list"
#define NS_COMMAND_TSIGDELETE "tsig-delete"
#define NS_COMMAND_FREEZE "freeze"
#define NS_COMMAND_UNFREEZE "unfreeze"
#define NS_COMMAND_THAW "thaw"

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.h,v 1.83 2006/03/09 23:39:00 marka Exp $ */
/* $Id: server.h,v 1.84 2006/12/04 01:52:45 marka Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
@@ -203,6 +203,18 @@ ns_server_flushname(ns_server_t *server, char *args);
isc_result_t
ns_server_status(ns_server_t *server, isc_buffer_t *text);
/*%
* Report a list of dynamic and static tsig keys, per view.
*/
isc_result_t
ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text);
/*%
* Delete a specific key (with optional view).
*/
isc_result_t
ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text);
/*%
* Enable or disable updates for a zone.
*/

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: notify.c,v 1.33 2005/04/29 00:22:29 marka Exp $ */
/* $Id: notify.c,v 1.34 2006/12/04 01:52:45 marka Exp $ */
#include <config.h>
@@ -25,6 +25,7 @@
#include <dns/message.h>
#include <dns/rdataset.h>
#include <dns/result.h>
#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
@@ -80,7 +81,7 @@ ns_notify_start(ns_client_t *client) {
dns_zone_t *zone = NULL;
char namebuf[DNS_NAME_FORMATSIZE];
char tsigbuf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
dns_name_t *tsigname;
dns_tsigkey_t *tsigkey;
/*
* Interpret the question section.
@@ -119,10 +120,20 @@ ns_notify_start(ns_client_t *client) {
goto formerr;
}
tsigname = NULL;
if (dns_message_gettsig(request, &tsigname) != NULL) {
dns_name_format(tsigname, namebuf, sizeof(namebuf));
snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'", namebuf);
tsigkey = dns_message_gettsigkey(request);
if (tsigkey != NULL) {
dns_name_format(&tsigkey->name, namebuf, sizeof(namebuf));
if (tsigkey->generated) {
char cnamebuf[DNS_NAME_FORMATSIZE];
dns_name_format(tsigkey->creator, cnamebuf,
sizeof(cnamebuf));
snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s' (%s)",
namebuf, cnamebuf);
} else {
snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'",
namebuf);
}
} else
tsigbuf[0] = '\0';
dns_name_format(zonename, namebuf, sizeof(namebuf));

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.466 2006/07/24 05:51:22 marka Exp $ */
/* $Id: server.c,v 1.467 2006/12/04 01:52:45 marka Exp $ */
/*! \file */
@@ -60,6 +60,7 @@
#include <dns/order.h>
#include <dns/peer.h>
#include <dns/portlist.h>
#include <dns/rbt.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
@@ -68,6 +69,7 @@
#include <dns/secalg.h>
#include <dns/stats.h>
#include <dns/tkey.h>
#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
@@ -4687,6 +4689,235 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
return (ISC_R_SUCCESS);
}
static isc_result_t
delete_keynames(dns_tsig_keyring_t *ring, char *target,
unsigned int *foundkeys)
{
char namestr[DNS_NAME_FORMATSIZE];
isc_result_t result;
dns_rbtnodechain_t chain;
dns_name_t foundname;
dns_fixedname_t fixedorigin;
dns_name_t *origin;
dns_rbtnode_t *node;
dns_tsigkey_t *tkey;
dns_name_init(&foundname, NULL);
dns_fixedname_init(&fixedorigin);
origin = dns_fixedname_name(&fixedorigin);
again:
dns_rbtnodechain_init(&chain, ring->mctx);
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname,
origin);
if (result == ISC_R_NOTFOUND) {
dns_rbtnodechain_invalidate(&chain);
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
for (;;) {
node = NULL;
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data;
if (tkey != NULL) {
if (!tkey->generated)
goto nextkey;
dns_name_format(&tkey->name, namestr, sizeof(namestr));
if (strcmp(namestr, target) == 0) {
(*foundkeys)++;
dns_rbtnodechain_invalidate(&chain);
(void)dns_rbt_deletename(ring->keys,
&tkey->name,
ISC_FALSE);
goto again;
}
}
nextkey:
result = dns_rbtnodechain_next(&chain, &foundname, origin);
if (result == ISC_R_NOMORE)
break;
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
}
return (ISC_R_SUCCESS);
}
isc_result_t
ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text) {
isc_result_t result;
unsigned int n;
dns_view_t *view;
unsigned int foundkeys = 0;
char *target;
char *viewname;
(void)next_token(&command, " \t"); /* skip command name */
target = next_token(&command, " \t");
if (target == NULL)
return (ISC_R_UNEXPECTEDEND);
viewname = next_token(&command, " \t");
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
if (viewname == NULL || strcmp(view->name, viewname) == 0) {
RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_write);
result = delete_keynames(view->dynamickeys, target,
&foundkeys);
RWUNLOCK(&view->dynamickeys->lock,
isc_rwlocktype_write);
if (result != ISC_R_SUCCESS) {
isc_task_endexclusive(server->task);
return (result);
}
}
}
isc_task_endexclusive(server->task);
n = snprintf((char *)isc_buffer_used(text),
isc_buffer_availablelength(text),
"%d tsig keys deleted.\n", foundkeys);
if (n >= isc_buffer_availablelength(text)) {
isc_task_endexclusive(server->task);
return (ISC_R_NOSPACE);
}
isc_buffer_add(text, n);
return (ISC_R_SUCCESS);
}
static isc_result_t
list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t *text,
unsigned int *foundkeys)
{
char namestr[DNS_NAME_FORMATSIZE];
char creatorstr[DNS_NAME_FORMATSIZE];
isc_result_t result;
dns_rbtnodechain_t chain;
dns_name_t foundname;
dns_fixedname_t fixedorigin;
dns_name_t *origin;
dns_rbtnode_t *node;
dns_tsigkey_t *tkey;
unsigned int n;
const char *viewname;
if (view != NULL)
viewname = view->name;
else
viewname = "(global)";
dns_name_init(&foundname, NULL);
dns_fixedname_init(&fixedorigin);
origin = dns_fixedname_name(&fixedorigin);
dns_rbtnodechain_init(&chain, ring->mctx);
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname,
origin);
if (result == ISC_R_NOTFOUND) {
dns_rbtnodechain_invalidate(&chain);
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
for (;;) {
node = NULL;
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data;
if (tkey != NULL) {
(*foundkeys)++;
dns_name_format(&tkey->name, namestr, sizeof(namestr));
if (tkey->generated) {
dns_name_format(tkey->creator, creatorstr,
sizeof(creatorstr));
n = snprintf((char *)isc_buffer_used(text),
isc_buffer_availablelength(text),
"view \"%s\"; type \"dynamic\"; key \"%s\"; creator \"%s\";\n",
viewname, namestr, creatorstr);
} else {
n = snprintf((char *)isc_buffer_used(text),
isc_buffer_availablelength(text),
"view \"%s\"; type \"static\"; key \"%s\";\n",
viewname, namestr);
}
if (n >= isc_buffer_availablelength(text)) {
dns_rbtnodechain_invalidate(&chain);
return (ISC_R_NOSPACE);
}
isc_buffer_add(text, n);
}
result = dns_rbtnodechain_next(&chain, &foundname, origin);
if (result == ISC_R_NOMORE)
break;
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return (result);
}
}
return (ISC_R_SUCCESS);
}
isc_result_t
ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
isc_result_t result;
unsigned int n;
dns_view_t *view;
unsigned int foundkeys = 0;
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
RWLOCK(&view->statickeys->lock, isc_rwlocktype_read);
result = list_keynames(view, view->statickeys, text,
&foundkeys);
RWUNLOCK(&view->statickeys->lock, isc_rwlocktype_read);
if (result != ISC_R_SUCCESS) {
isc_task_endexclusive(server->task);
return (result);
}
RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_read);
result = list_keynames(view, view->dynamickeys, text,
&foundkeys);
RWUNLOCK(&view->dynamickeys->lock, isc_rwlocktype_read);
if (result != ISC_R_SUCCESS) {
isc_task_endexclusive(server->task);
return (result);
}
}
isc_task_endexclusive(server->task);
if (foundkeys == 0) {
n = snprintf((char *)isc_buffer_used(text),
isc_buffer_availablelength(text),
"no tsig keys found.\n");
if (n >= isc_buffer_availablelength(text)) {
isc_task_endexclusive(server->task);
return (ISC_R_NOSPACE);
}
isc_buffer_add(text, n);
}
return (ISC_R_SUCCESS);
}
/*
* Act on a "freeze" or "thaw" command from the command channel.
*/

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: tkeyconf.c,v 1.26 2006/03/02 00:37:23 marka Exp $ */
/* $Id: tkeyconf.c,v 1.27 2006/12/04 01:52:45 marka Exp $ */
/*! \file */
@@ -42,6 +42,13 @@
goto failure; \
} while (0)
#include<named/log.h>
#define LOG(msg) \
isc_log_write(ns_g_lctx, \
NS_LOGCATEGORY_GENERAL, \
NS_LOGMODULE_SERVER, \
ISC_LOG_ERROR, \
"%s", msg)
isc_result_t
ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
@@ -100,6 +107,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
result = cfg_map_get(options, "tkey-gssapi-credential", &obj);
if (result == ISC_R_SUCCESS) {
s = cfg_obj_asstring(obj);
isc_buffer_init(&b, s, strlen(s));
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: update.c,v 1.129 2006/03/06 01:27:51 marka Exp $ */
/* $Id: update.c,v 1.130 2006/12/04 01:52:45 marka Exp $ */
#include <config.h>
@@ -55,8 +55,8 @@
*/
/*
XXX TODO:
- document strict minimality
* XXX TODO:
* - document strict minimality
*/
/**************************************************************************/
@@ -262,6 +262,13 @@ checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message,
msg = "approved";
}
if (client->signer != NULL) {
dns_name_format(client->signer, namebuf, sizeof(namebuf));
ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
NS_LOGMODULE_UPDATE, ISC_LOG_INFO,
"signer \"%s\" %s", namebuf, msg);
}
dns_name_format(zonename, namebuf, sizeof(namebuf));
dns_rdataclass_format(client->view->rdclass, classbuf,
sizeof(classbuf));
@@ -281,8 +288,7 @@ checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message,
* ownership has been transferred to the diff.
*/
static isc_result_t
do_one_tuple(dns_difftuple_t **tuple,
dns_db_t *db, dns_dbversion_t *ver,
do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
dns_diff_t *diff)
{
dns_diff_t temp_diff;
@@ -341,8 +347,8 @@ do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver,
static isc_result_t
update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
dns_diffop_t op, dns_name_t *name,
dns_ttl_t ttl, dns_rdata_t *rdata)
dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
dns_rdata_t *rdata)
{
dns_difftuple_t *tuple = NULL;
isc_result_t result;
@@ -423,11 +429,8 @@ foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) {
* If 'action' returns an error, abort iteration and return the error.
*/
static isc_result_t
foreach_rrset(dns_db_t *db,
dns_dbversion_t *ver,
dns_name_t *name,
rrset_func *action,
void *action_data)
foreach_rrset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
rrset_func *action, void *action_data)
{
isc_result_t result;
dns_dbnode_t *node;
@@ -482,11 +485,8 @@ foreach_rrset(dns_db_t *db,
* and return the error.
*/
static isc_result_t
foreach_node_rr(dns_db_t *db,
dns_dbversion_t *ver,
dns_name_t *name,
rr_func *rr_action,
void *rr_action_data)
foreach_node_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
rr_func *rr_action, void *rr_action_data)
{
foreach_node_rr_ctx_t ctx;
ctx.rr_action = rr_action;
@@ -506,12 +506,8 @@ foreach_node_rr(dns_db_t *db,
* If 'action' returns an error, abort iteration and return the error.
*/
static isc_result_t
foreach_rr(dns_db_t *db,
dns_dbversion_t *ver,
dns_name_t *name,
dns_rdatatype_t type,
dns_rdatatype_t covers,
rr_func *rr_action,
foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_rdatatype_t type, dns_rdatatype_t covers, rr_func *rr_action,
void *rr_action_data)
{
@@ -609,8 +605,8 @@ rrset_exists_action(void *data, rr_t *rr) {
* to false otherwise.
*/
static isc_result_t
rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers,
rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_boolean_t *exists)
{
isc_result_t result;
@@ -696,7 +692,8 @@ name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
}
typedef struct {
dns_name_t *name, *signer;
dns_name_t *name;
dns_name_t *signer;
dns_ssutable_t *table;
} ssu_check_t;
@@ -1075,14 +1072,9 @@ delete_if_action(void *data, rr_t *rr) {
* deletions in 'diff'.
*/
static isc_result_t
delete_if(rr_predicate *predicate,
dns_db_t *db,
dns_dbversion_t *ver,
dns_name_t *name,
dns_rdatatype_t type,
dns_rdatatype_t covers,
dns_rdata_t *update_rr,
dns_diff_t *diff)
delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver,
dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdata_t *update_rr, dns_diff_t *diff)
{
conditional_delete_ctx_t ctx;
ctx.predicate = predicate;
@@ -1139,10 +1131,8 @@ add_rr_prepare_action(void *data, rr_t *rr) {
* be deleted before the update RR is added.
*/
if (replaces_p(ctx->update_rr, &rr->rdata)) {
CHECK(dns_difftuple_create(ctx->del_diff.mctx,
DNS_DIFFOP_DEL, ctx->name,
rr->ttl,
&rr->rdata,
CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL,
ctx->name, rr->ttl, &rr->rdata,
&tuple));
dns_diff_append(&ctx->del_diff, &tuple);
return (ISC_R_SUCCESS);
@@ -1153,18 +1143,15 @@ add_rr_prepare_action(void *data, rr_t *rr) {
* its TTL must be adjusted.
*/
if (rr->ttl != ctx->update_rr_ttl) {
CHECK(dns_difftuple_create(ctx->del_diff.mctx,
DNS_DIFFOP_DEL, ctx->name,
rr->ttl,
&rr->rdata,
CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL,
ctx->name, rr->ttl, &rr->rdata,
&tuple));
dns_diff_append(&ctx->del_diff, &tuple);
if (!equal) {
CHECK(dns_difftuple_create(ctx->add_diff.mctx,
DNS_DIFFOP_ADD, ctx->name,
ctx->update_rr_ttl,
&rr->rdata,
&tuple));
&rr->rdata, &tuple));
dns_diff_append(&ctx->add_diff, &tuple);
}
}
@@ -1186,10 +1173,9 @@ add_rr_prepare_action(void *data, rr_t *rr) {
*/
static void
get_current_rr(dns_message_t *msg, dns_section_t section,
dns_rdataclass_t zoneclass,
dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers,
dns_ttl_t *ttl,
dns_rdataclass_t *update_class)
dns_rdataclass_t zoneclass, dns_name_t **name,
dns_rdata_t *rdata, dns_rdatatype_t *covers,
dns_ttl_t *ttl, dns_rdataclass_t *update_class)
{
dns_rdataset_t *rdataset;
isc_result_t result;
@@ -1274,8 +1260,7 @@ increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
*/
static isc_result_t
check_soa_increment(dns_db_t *db, dns_dbversion_t *ver,
dns_rdata_t *update_rdata,
isc_boolean_t *ok)
dns_rdata_t *update_rdata, isc_boolean_t *ok)
{
isc_uint32_t db_serial;
isc_uint32_t update_serial;
@@ -1381,8 +1366,7 @@ non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
dns_name_t *name, isc_boolean_t *exists)
{
isc_result_t result;
result = foreach_rrset(db, ver, name,
is_non_nsec_action, NULL);
result = foreach_rrset(db, ver, name, is_non_nsec_action, NULL);
RETURN_EXISTENCE_FLAG;
}
@@ -1431,8 +1415,7 @@ is_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = dns_db_find(db, name, ver, dns_rdatatype_any,
DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
(isc_stdtime_t) 0, NULL,
dns_fixedname_name(&foundname),
NULL, NULL);
dns_fixedname_name(&foundname), NULL, NULL);
if (result == ISC_R_SUCCESS) {
*flag = ISC_FALSE;
return (ISC_R_SUCCESS);
@@ -1571,7 +1554,8 @@ add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
*/
static isc_result_t
add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_diff_t *diff) {
dns_diff_t *diff)
{
isc_result_t result;
dns_difftuple_t *tuple = NULL;
isc_region_t r;
@@ -1666,8 +1650,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
/* Get the rdataset to sign. */
CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
CHECK(dns_db_findrdataset(db, node, ver, type, 0,
(isc_stdtime_t) 0,
&rdataset, NULL));
(isc_stdtime_t) 0, &rdataset, NULL));
dns_db_detachnode(db, &node);
for (i = 0; i < nkeys; i++) {
@@ -2110,8 +2093,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
*/
result = dns_message_firstname(request, DNS_SECTION_ZONE);
if (result != ISC_R_SUCCESS)
FAILC(DNS_R_FORMERR,
"update zone section empty");
FAILC(DNS_R_FORMERR, "update zone section empty");
/*
* The zone section must contain exactly one "question", and
@@ -2136,8 +2118,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
result = dns_zt_find(client->view->zonetable, zonename, 0, NULL,
&zone);
if (result != ISC_R_SUCCESS)
FAILC(DNS_R_NOTAUTH,
"not authoritative for update zone");
FAILC(DNS_R_NOTAUTH, "not authoritative for update zone");
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
@@ -2155,8 +2136,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
CHECK(send_forward_event(client, zone));
break;
default:
FAILC(DNS_R_NOTAUTH,
"not authoritative for update zone");
FAILC(DNS_R_NOTAUTH, "not authoritative for update zone");
}
return;
@@ -2671,8 +2651,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
sizeof(namestr));
dns_rdatatype_format(rdata.type, typestr,
sizeof(typestr));
update_log(client, zone,
LOGLEVEL_PROTOCOL,
update_log(client, zone, LOGLEVEL_PROTOCOL,
"adding an RR at '%s' %s",
namestr, typestr);
}
@@ -2731,8 +2710,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
} else if (dns_name_equal(name, zonename) &&
(rdata.type == dns_rdatatype_soa ||
rdata.type == dns_rdatatype_ns)) {
update_log(client, zone,
LOGLEVEL_PROTOCOL,
update_log(client, zone, LOGLEVEL_PROTOCOL,
"attempt to delete all SOA "
"or NS records ignored");
continue;

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zoneconf.c,v 1.134 2006/06/04 23:17:06 marka Exp $ */
/* $Id: zoneconf.c,v 1.135 2006/12/04 01:52:45 marka Exp $ */
/*% */
@@ -158,6 +158,14 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
mtype = DNS_SSUMATCHTYPE_SELFSUB;
else if (strcasecmp(str, "selfwild") == 0)
mtype = DNS_SSUMATCHTYPE_SELFWILD;
else if (strcasecmp(str, "ms-self") == 0)
mtype = DNS_SSUMATCHTYPE_SELFMS;
else if (strcasecmp(str, "krb5-self") == 0)
mtype = DNS_SSUMATCHTYPE_SELFKRB5;
else if (strcasecmp(str, "ms-subdomain") == 0)
mtype = DNS_SSUMATCHTYPE_SUBDOMAINMS;
else if (strcasecmp(str, "krb5-subdomain") == 0)
mtype = DNS_SSUMATCHTYPE_SUBDOMAINKRB5;
else
INSIST(0);

View File

@@ -1,5 +1,5 @@
# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.23 2004/07/20 07:13:34 marka Exp $
# $Id: Makefile.in,v 1.24 2006/12/04 01:52:45 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,9 +24,9 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \
${ISC_INCLUDES}
${ISC_INCLUDES} @DST_GSSAPI_INC@
CDEFINES =
CDEFINES = @USE_GSSAPI@
CWARNINGS =
LWRESLIBS = ../../lib/lwres/liblwres.@A@

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: nsupdate.c,v 1.144 2006/06/09 07:26:42 marka Exp $ */
/* $Id: nsupdate.c,v 1.145 2006/12/04 01:52:45 marka Exp $ */
/*! \file */
@@ -35,8 +35,10 @@
#include <isc/event.h>
#include <isc/hash.h>
#include <isc/lex.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/parseint.h>
#include <isc/random.h>
#include <isc/region.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
@@ -52,6 +54,7 @@
#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/fixedname.h>
#include <dns/log.h>
#include <dns/masterdump.h>
#include <dns/message.h>
#include <dns/name.h>
@@ -64,6 +67,7 @@
#include <dns/rdatatype.h>
#include <dns/request.h>
#include <dns/result.h>
#include <dns/tkey.h>
#include <dns/tsig.h>
#include <dst/dst.h>
@@ -71,8 +75,12 @@
#include <lwres/lwres.h>
#include <lwres/net.h>
#ifdef GSSAPI
#include <dst/gssapi.h>
#endif
#include <bind9/getaddresses.h>
#ifdef HAVE_ADDRINFO
#ifdef HAVE_GETADDRINFO
#ifdef HAVE_GAISTRERROR
@@ -107,9 +115,13 @@ static isc_boolean_t have_ipv4 = ISC_FALSE;
static isc_boolean_t have_ipv6 = ISC_FALSE;
static isc_boolean_t is_dst_up = ISC_FALSE;
static isc_boolean_t usevc = ISC_FALSE;
static isc_boolean_t usegsstsig = ISC_FALSE;
static isc_boolean_t use_win2k_gsstsig = ISC_FALSE;
static isc_boolean_t tried_other_gsstsig = ISC_FALSE;
static isc_taskmgr_t *taskmgr = NULL;
static isc_task_t *global_task = NULL;
static isc_event_t *global_event = NULL;
static isc_log_t *lctx = NULL;
static isc_mem_t *mctx = NULL;
static dns_dispatchmgr_t *dispatchmgr = NULL;
static dns_requestmgr_t *requestmgr = NULL;
@@ -120,6 +132,10 @@ static dns_dispatch_t *dispatchv6 = NULL;
static dns_message_t *updatemsg = NULL;
static dns_fixedname_t fuserzone;
static dns_name_t *userzone = NULL;
static dns_name_t *zonename = NULL;
static dns_name_t tmpzonename;
static dns_name_t restart_master;
static dns_tsig_keyring_t *gssring = NULL;
static dns_tsigkey_t *tsigkey = NULL;
static dst_key_t *sig0key;
static lwres_context_t *lwctx = NULL;
@@ -129,6 +145,8 @@ static int ns_inuse = 0;
static int ns_total = 0;
static isc_sockaddr_t *userserver = NULL;
static isc_sockaddr_t *localaddr = NULL;
static isc_sockaddr_t *serveraddr = NULL;
static isc_sockaddr_t tempaddr;
static char *keystr = NULL, *keyfile = NULL;
static isc_entropy_t *entp = NULL;
static isc_boolean_t shuttingdown = ISC_FALSE;
@@ -137,6 +155,7 @@ static isc_boolean_t interactive = ISC_TRUE;
static isc_boolean_t seenerror = ISC_FALSE;
static const dns_master_style_t *style;
static int requests = 0;
static unsigned int logdebuglevel = 0;
static unsigned int timeout = 300;
static unsigned int udp_timeout = 3;
static unsigned int udp_retries = 3;
@@ -161,6 +180,27 @@ debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
static void
ddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
#ifdef GSSAPI
static dns_fixedname_t fkname;
static isc_sockaddr_t *kserver = NULL;
static char servicename[DNS_NAME_FORMATSIZE];
static dns_name_t *keyname;
typedef struct nsu_gssinfo {
dns_message_t *msg;
isc_sockaddr_t *addr;
gss_ctx_id_t context;
} nsu_gssinfo_t;
static void
start_gssrequest(dns_name_t *master);
static void
send_gssrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
dns_message_t *msg, dns_request_t **request,
gss_ctx_id_t context);
static void
recvgss(isc_task_t *task, isc_event_t *event);
#endif /* GSSAPI */
#define STATUS_MORE (isc_uint16_t)0
#define STATUS_SEND (isc_uint16_t)1
#define STATUS_QUIT (isc_uint16_t)2
@@ -282,6 +322,13 @@ reset_system(void) {
check_result(result, "dns_message_create");
}
updatemsg->opcode = dns_opcode_update;
if (usegsstsig) {
if (tsigkey != NULL)
dns_tsigkey_detach(&tsigkey);
if (gssring != NULL)
dns_tsigkeyring_destroy(&gssring);
tried_other_gsstsig = ISC_FALSE;
}
}
static isc_uint16_t
@@ -559,6 +606,7 @@ setup_system(void) {
lwres_result_t lwresult;
unsigned int attrs, attrmask;
int i;
isc_logconfig_t *logconfig = NULL;
ddebug("setup_system()");
@@ -578,6 +626,18 @@ setup_system(void) {
result = isc_mem_create(0, 0, &mctx);
check_result(result, "isc_mem_create");
result = isc_log_create(mctx, &lctx, &logconfig);
check_result(result, "isc_log_create");
isc_log_setcontext(lctx);
dns_log_init(lctx);
dns_log_setcontext(lctx);
result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL);
check_result(result, "isc_log_usechannel");
isc_log_setdebuglevel(lctx, logdebuglevel);
lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1);
if (lwresult != LWRES_R_SUCCESS)
fatal("lwres_context_create failed");
@@ -697,10 +757,12 @@ get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
static void
parse_args(int argc, char **argv) {
int ch;
isc_uint32_t i;
isc_result_t result;
debug("parse_args");
while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:r:t:u:")) != -1)
while ((ch = isc_commandline_parse(argc, argv, "dDMl:y:govk:r:t:u:")
) != -1)
{
switch (ch) {
case 'd':
@@ -717,6 +779,16 @@ parse_args(int argc, char **argv) {
isc_mem_debugging = ISC_MEM_DEBUGTRACE |
ISC_MEM_DEBUGRECORD;
break;
case 'l':
result = isc_parse_uint32(&i, isc_commandline_argument,
10);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "bad library debug value "
"'%s'\n", isc_commandline_argument);
exit(1);
}
logdebuglevel = i;
break;
case 'y':
keystr = isc_commandline_argument;
break;
@@ -726,6 +798,14 @@ parse_args(int argc, char **argv) {
case 'k':
keyfile = isc_commandline_argument;
break;
case 'g':
usegsstsig = ISC_TRUE;
use_win2k_gsstsig = ISC_FALSE;
break;
case 'o':
usegsstsig = ISC_TRUE;
use_win2k_gsstsig = ISC_TRUE;
break;
case 't':
result = isc_parse_uint32(&timeout,
isc_commandline_argument, 10);
@@ -758,8 +838,8 @@ parse_args(int argc, char **argv) {
fprintf(stderr, "%s: invalid argument -%c\n",
argv[0], ch);
fprintf(stderr, "usage: nsupdate [-d] "
"[-y keyname:secret | -k keyfile] [-v] "
"[filename]\n");
"[-g | -o | -y keyname:secret | -k keyfile] "
"[-v] [filename]\n");
exit(1);
}
}
@@ -769,6 +849,21 @@ parse_args(int argc, char **argv) {
exit(1);
}
#ifdef GSSAPI
if (usegsstsig && (keyfile != NULL || keystr != NULL)) {
fprintf(stderr, "%s: cannot specify -g with -k or -y\n",
argv[0]);
exit(1);
}
#else
if (usegsstsig) {
fprintf(stderr, "%s: cannot specify -g or -o, " \
"program not linked with GSS API Library\n",
argv[0]);
exit(1);
}
#endif
if (argv[isc_commandline_index] != NULL) {
if (strcmp(argv[isc_commandline_index], "-") == 0) {
input = stdin;
@@ -1457,7 +1552,7 @@ setzone(dns_name_t *zonename) {
}
static void
show_message(dns_message_t *msg) {
show_message(FILE *stream, dns_message_t *msg, const char *description) {
isc_result_t result;
isc_buffer_t *buf = NULL;
int bufsz;
@@ -1485,9 +1580,8 @@ show_message(dns_message_t *msg) {
isc_buffer_free(&buf);
return;
}
printf("Outgoing update query:\n%.*s",
(int)isc_buffer_usedlength(buf),
(char*)isc_buffer_base(buf));
fprintf(stream, "%s\n%.*s", description,
(int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf));
isc_buffer_free(&buf);
}
@@ -1533,16 +1627,34 @@ get_next_command(void) {
if (strcasecmp(word, "send") == 0)
return (STATUS_SEND);
if (strcasecmp(word, "show") == 0) {
show_message(updatemsg);
show_message(stdout, updatemsg, "Outgoing update query:");
return (STATUS_MORE);
}
if (strcasecmp(word, "answer") == 0) {
if (answer != NULL)
show_message(answer);
show_message(stdout, answer, "Answer:");
return (STATUS_MORE);
}
if (strcasecmp(word, "key") == 0)
return (evaluate_key(cmdline));
if (strcasecmp(word, "gsstsig") == 0) {
#ifdef GSSAPI
usegsstsig = ISC_TRUE;
use_win2k_gsstsig = ISC_FALSE;
#else
fprintf(stderr, "gsstsig not supported\n");
#endif
return (STATUS_MORE);
}
if (strcasecmp(word, "oldgsstsig") == 0) {
#ifdef GSSAPI
usegsstsig = ISC_TRUE;
use_win2k_gsstsig = ISC_TRUE;
#else
fprintf(stderr, "gsstsig not supported\n");
#endif
return (STATUS_MORE);
}
fprintf(stderr, "incorrect section name: %s\n", word);
return (STATUS_SYNTAX);
}
@@ -1626,12 +1738,23 @@ update_completed(isc_task_t *task, isc_event_t *event) {
DNS_MESSAGEPARSE_PRESERVEORDER);
switch (result) {
case ISC_R_SUCCESS:
if (answer->verify_attempted)
ddebug("tsig verification successful");
break;
case DNS_R_CLOCKSKEW:
case DNS_R_EXPECTEDTSIG:
case DNS_R_TSIGERRORSET:
case DNS_R_TSIGVERIFYFAILURE:
case DNS_R_UNEXPECTEDTSIG:
case ISC_R_FAILURE:
#if 0
if (usegsstsig && answer->rcode == dns_rcode_noerror) {
/*
* For MS DNS that violates RFC 2845, section 4.2
*/
break;
}
#endif
fprintf(stderr, "; TSIG error with server: %s\n",
isc_result_totext(result));
seenerror = ISC_TRUE;
@@ -1657,32 +1780,15 @@ update_completed(isc_task_t *task, isc_event_t *event) {
(int)isc_buffer_usedlength(&b), buf);
}
}
if (debugging) {
isc_buffer_t *buf = NULL;
int bufsz;
if (debugging)
show_message(stderr, answer, "\nReply from update query:");
bufsz = INITTEXT;
do {
if (bufsz > MAXTEXT) {
fprintf(stderr, "could not allocate large "
"enough buffer to display message\n");
exit(1);
}
if (buf != NULL)
isc_buffer_free(&buf);
result = isc_buffer_allocate(mctx, &buf, bufsz);
check_result(result, "isc_buffer_allocate");
result = dns_message_totext(answer, style, 0, buf);
bufsz *= 2;
} while (result == ISC_R_NOSPACE);
check_result(result, "dns_message_totext");
fprintf(stderr, "\nReply from update query:\n%.*s\n",
(int)isc_buffer_usedlength(buf),
(char*)isc_buffer_base(buf));
isc_buffer_free(&buf);
}
done:
dns_request_destroy(&request);
if (usegsstsig) {
dns_name_free(&tmpzonename, mctx);
dns_name_free(&restart_master, mctx);
}
isc_event_free(&event);
done_update();
}
@@ -1711,6 +1817,7 @@ send_update(dns_name_t *zonename, isc_sockaddr_t *master,
isc_sockaddr_format(master, addrbuf, sizeof(addrbuf));
fprintf(stderr, "Sending update to %s\n", addrbuf);
}
result = dns_request_createvia3(requestmgr, updatemsg, srcaddr,
master, options, tsigkey, timeout,
udp_timeout, udp_retries, global_task,
@@ -1718,7 +1825,7 @@ send_update(dns_name_t *zonename, isc_sockaddr_t *master,
check_result(result, "dns_request_createvia3");
if (debugging)
show_message(updatemsg);
show_message(stdout, updatemsg, "Outgoing update query:");
requests++;
}
@@ -1736,8 +1843,6 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
dns_rdata_t soarr = DNS_RDATA_INIT;
int pass = 0;
dns_name_t master;
isc_sockaddr_t *serveraddr, tempaddr;
dns_name_t *zonename;
nsu_requestinfo_t *reqinfo;
dns_message_t *soaquery = NULL;
isc_sockaddr_t *addr;
@@ -1821,28 +1926,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
}
check_result(result, "dns_request_getresponse");
section = DNS_SECTION_ANSWER;
if (debugging) {
isc_buffer_t *buf = NULL;
int bufsz;
bufsz = INITTEXT;
do {
if (buf != NULL)
isc_buffer_free(&buf);
if (bufsz > MAXTEXT) {
fprintf(stderr, "could not allocate enough "
"space for debugging message\n");
exit(1);
}
result = isc_buffer_allocate(mctx, &buf, bufsz);
check_result(result, "isc_buffer_allocate");
result = dns_message_totext(rcvmsg, style, 0, buf);
} while (result == ISC_R_NOSPACE);
check_result(result, "dns_message_totext");
fprintf(stderr, "Reply from SOA query:\n%.*s\n",
(int)isc_buffer_usedlength(buf),
(char*)isc_buffer_base(buf));
isc_buffer_free(&buf);
}
if (debugging)
show_message(stderr, rcvmsg, "Reply from SOA query:");
if (rcvmsg->rcode != dns_rcode_noerror &&
rcvmsg->rcode != dns_rcode_nxdomain)
@@ -1872,12 +1957,9 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
if (section == DNS_SECTION_ANSWER) {
dns_rdataset_t *tset = NULL;
if (dns_message_findtype(name, dns_rdatatype_cname, 0,
&tset) == ISC_R_SUCCESS
||
&tset) == ISC_R_SUCCESS ||
dns_message_findtype(name, dns_rdatatype_dname, 0,
&tset) == ISC_R_SUCCESS
)
{
&tset) == ISC_R_SUCCESS ) {
seencname = ISC_TRUE;
break;
}
@@ -1937,8 +2019,21 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
}
dns_rdata_freestruct(&soa);
#ifdef GSSAPI
if (usegsstsig) {
dns_name_init(&tmpzonename, NULL);
dns_name_dup(zonename, mctx, &tmpzonename);
dns_name_init(&restart_master, NULL);
dns_name_dup(&master, mctx, &restart_master);
start_gssrequest(&master);
} else {
send_update(zonename, serveraddr, localaddr);
setzoneclass(dns_rdataclass_none);
}
#else
send_update(zonename, serveraddr, localaddr);
setzoneclass(dns_rdataclass_none);
#endif
dns_message_destroy(&soaquery);
dns_request_destroy(&request);
@@ -1965,8 +2060,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
if (userserver != NULL)
sendrequest(localaddr, userserver, soaquery, &request);
else
sendrequest(localaddr, &servers[ns_inuse], soaquery,
&request);
sendrequest(localaddr, &servers[ns_inuse], soaquery, &request);
goto out;
}
@@ -1990,6 +2084,265 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
requests++;
}
#ifdef GSSAPI
static void
start_gssrequest(dns_name_t *master)
{
gss_ctx_id_t context;
isc_buffer_t buf;
isc_result_t result;
isc_uint32_t val = 0;
dns_message_t *rmsg;
dns_request_t *request = NULL;
dns_name_t *servname;
dns_fixedname_t fname;
char namestr[DNS_NAME_FORMATSIZE];
char keystr[DNS_NAME_FORMATSIZE];
debug("start_gssrequest");
usevc = ISC_TRUE;
if (gssring != NULL)
dns_tsigkeyring_destroy(&gssring);
gssring = NULL;
result = dns_tsigkeyring_create(mctx, &gssring);
dns_name_format(master, namestr, sizeof(namestr));
if (kserver == NULL) {
kserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t));
if (kserver == NULL)
fatal("out of memory");
}
if (userserver == NULL)
get_address(namestr, DNSDEFAULTPORT, kserver);
else
(void)memcpy(kserver, userserver, sizeof(isc_sockaddr_t));
dns_fixedname_init(&fname);
servname = dns_fixedname_name(&fname);
sprintf(servicename,"DNS/%s", namestr);
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
result = dns_name_fromtext(servname, &buf, dns_rootname,
ISC_FALSE, NULL);
dns_fixedname_init(&fkname);
keyname = dns_fixedname_name(&fkname);
isc_random_get(&val);
sprintf(keystr, "%u.sig-%s", val, namestr);
isc_buffer_init(&buf, keystr, strlen(keystr));
isc_buffer_add(&buf, strlen(keystr));
result = dns_name_fromtext(keyname, &buf, dns_rootname,
ISC_FALSE, NULL);
INSIST(result == ISC_R_SUCCESS);
/* Windows doesn't recognize name compression in the key name. */
keyname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
rmsg = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &rmsg);
INSIST(result == ISC_R_SUCCESS);
/* Build first request. */
context = GSS_C_NO_CONTEXT;
result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
&context, use_win2k_gsstsig);
if (result == ISC_R_FAILURE)
fatal("Check your Kerberos ticket, it may have expired.");
INSIST(result == ISC_R_SUCCESS);
send_gssrequest(localaddr, kserver, rmsg, &request, context);
}
static void
send_gssrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
dns_message_t *msg, dns_request_t **request,
gss_ctx_id_t context)
{
isc_result_t result;
nsu_gssinfo_t *reqinfo;
unsigned int options = 0;
debug("send_gssrequest");
reqinfo = isc_mem_get(mctx, sizeof(nsu_gssinfo_t));
if (reqinfo == NULL)
fatal("out of memory");
reqinfo->msg = msg;
reqinfo->addr = destaddr;
reqinfo->context = context;
options |= DNS_REQUESTOPT_TCP;
result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr,
options, tsigkey, FIND_TIMEOUT * 20,
FIND_TIMEOUT, 3, global_task, recvgss,
reqinfo, request);
check_result(result, "dns_request_createvia3");
if (debugging)
show_message(stdout, msg, "Outgoing update query:");
requests++;
}
static void
recvgss(isc_task_t *task, isc_event_t *event) {
dns_requestevent_t *reqev = NULL;
dns_request_t *request = NULL;
isc_result_t result, eresult;
dns_message_t *rcvmsg = NULL;
nsu_gssinfo_t *reqinfo;
dns_message_t *tsigquery = NULL;
isc_sockaddr_t *addr;
gss_ctx_id_t context;
isc_buffer_t buf;
dns_name_t *servname;
dns_fixedname_t fname;
UNUSED(task);
ddebug("recvgss()");
requests--;
REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
reqev = (dns_requestevent_t *)event;
request = reqev->request;
eresult = reqev->result;
reqinfo = reqev->ev_arg;
tsigquery = reqinfo->msg;
context = reqinfo->context;
addr = reqinfo->addr;
if (shuttingdown) {
dns_request_destroy(&request);
dns_message_destroy(&tsigquery);
isc_mem_put(mctx, reqinfo, sizeof(nsu_gssinfo_t));
isc_event_free(&event);
maybeshutdown();
return;
}
if (eresult != ISC_R_SUCCESS) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf));
fprintf(stderr, "; Communication with %s failed: %s\n",
addrbuf, isc_result_totext(eresult));
if (userserver != NULL)
fatal("could not talk to specified name server");
else if (++ns_inuse >= lwconf->nsnext)
fatal("could not talk to any default name server");
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
dns_message_renderreset(tsigquery);
sendrequest(localaddr, &servers[ns_inuse], tsigquery,
&request);
isc_mem_put(mctx, reqinfo, sizeof(nsu_gssinfo_t));
isc_event_free(&event);
return;
}
isc_mem_put(mctx, reqinfo, sizeof(nsu_gssinfo_t));
isc_event_free(&event);
reqev = NULL;
ddebug("recvgss creating rcvmsg");
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
check_result(result, "dns_message_create");
result = dns_request_getresponse(request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
check_result(result, "dns_request_getresponse");
if (debugging)
show_message(stderr, rcvmsg,
"recvmsg reply from GSS-TSIG query");
if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) {
ddebug("recvgss trying %s GSS-TSIG",
use_win2k_gsstsig ? "Standard" : "Win2k");
if (use_win2k_gsstsig)
use_win2k_gsstsig = ISC_FALSE;
else
use_win2k_gsstsig = ISC_TRUE;
tried_other_gsstsig = ISC_TRUE;
start_gssrequest(&restart_master);
goto done;
}
if (rcvmsg->rcode != dns_rcode_noerror &&
rcvmsg->rcode != dns_rcode_nxdomain)
fatal("response to GSS-TSIG query was unsuccessful");
dns_fixedname_init(&fname);
servname = dns_fixedname_name(&fname);
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
result = dns_name_fromtext(servname, &buf, dns_rootname,
ISC_FALSE, NULL);
check_result(result, "dns_name_fromtext");
tsigkey = NULL;
result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname,
&context, &tsigkey, gssring,
use_win2k_gsstsig);
switch (result) {
case DNS_R_CONTINUE:
send_gssrequest(localaddr, kserver, tsigquery, &request,
context);
break;
case ISC_R_SUCCESS:
/*
* XXXSRA Waaay too much fun here. There's no good
* reason why we need a TSIG here (the people who put
* it into the spec admitted at the time that it was
* not a security issue), and Windows clients don't
* seem to work if named complies with the spec and
* includes the gratuitous TSIG. So we're in the
* bizzare situation of having to choose between
* complying with a useless requirement in the spec
* and interoperating. This is nuts. If we can
* confirm this behavior, we should ask the WG to
* consider removing the requirement for the
* gratuitous TSIG here. For the moment, we ignore
* the TSIG -- this too is a spec violation, but it's
* the least insane thing to do.
*/
#if 0
/*
* Verify the signature.
*/
rcvmsg->state = DNS_SECTION_ANY;
dns_message_setquerytsig(rcvmsg, NULL);
result = dns_message_settsigkey(rcvmsg, tsigkey);
check_result(result, "dns_message_settsigkey");
result = dns_message_checksig(rcvmsg, NULL);
ddebug("tsig verification: %s", dns_result_totext(result));
check_result(result, "dns_message_checksig");
#endif /* 0 */
send_update(&tmpzonename, serveraddr, localaddr);
setzoneclass(dns_rdataclass_none);
break;
default:
fatal("dns_tkey_negotiategss: %s", isc_result_totext(result));
}
done:
dns_request_destroy(&request);
dns_message_destroy(&tsigquery);
dns_message_destroy(&rcvmsg);
ddebug("Out of recvgss");
}
#endif
static void
start_update(void) {
isc_result_t result;
@@ -2014,7 +2367,7 @@ start_update(void) {
return;
}
if (userzone != NULL && userserver != NULL) {
if (userzone != NULL && userserver != NULL && ! usegsstsig) {
send_update(userzone, userserver, localaddr);
setzoneclass(dns_rdataclass_none);
return;
@@ -2057,6 +2410,21 @@ cleanup(void) {
if (answer != NULL)
dns_message_destroy(&answer);
#ifdef GSSAPI
if (usegsstsig) {
if (tsigkey != NULL) {
ddebug("detach tsigkey x%p", tsigkey);
dns_tsigkey_detach(&tsigkey);
}
ddebug("Destroying GSS-TSIG keyring");
if (gssring != NULL)
dns_tsigkeyring_destroy(&gssring);
}
if (kserver != NULL)
isc_mem_put(mctx, kserver, sizeof(isc_sockaddr_t));
#endif
ddebug("Shutting down task manager");
isc_taskmgr_destroy(&taskmgr);
@@ -2075,6 +2443,9 @@ cleanup(void) {
ddebug("Destroying name state");
dns_name_destroy();
ddebug("Removing log context");
isc_log_destroy(&lctx);
ddebug("Destroying memory context");
if (memdebugging)
isc_mem_stats(mctx, stderr);

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rndc.c,v 1.113 2006/08/04 02:55:37 marka Exp $ */
/* $Id: rndc.c,v 1.114 2006/12/04 01:52:45 marka Exp $ */
/*! \file */
@@ -369,7 +369,7 @@ rndc_connected(isc_task_t *task, isc_event_t *event) {
r.base = databuf;
isccc_ccmsg_init(mctx, sock, &ccmsg);
isccc_ccmsg_setmaxsize(&ccmsg, 1024);
isccc_ccmsg_setmaxsize(&ccmsg, 1024 * 1024);
DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task,
rndc_recvnonce, NULL));

View File

@@ -1,6 +1,7 @@
Makefile
dst_test
t_dst
gsstest
.libs
randomfile
*.lo

View File

@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.36 2004/07/20 07:13:36 marka Exp $
# $Id: Makefile.in,v 1.37 2006/12/04 01:52:45 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -21,7 +21,8 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \
@DST_GSSAPI_INC@
CDEFINES =
CWARNINGS =
@@ -38,9 +39,9 @@ LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
TLIB = ../../../lib/tests/libt_api.@A@
TARGETS = dst_test@EXEEXT@ t_dst@EXEEXT@
TARGETS = dst_test@EXEEXT@ t_dst@EXEEXT@ gsstest@EXEEXT@
SRCS = dst_test.c t_dst.c
SRCS = dst_test.c t_dst.c gsstest.c
@BIND9_MAKE_RULES@
@@ -50,6 +51,9 @@ dst_test@EXEEXT@: dst_test.@O@ ${DEPLIBS}
t_dst@EXEEXT@: t_dst.@O@ ${DEPLIBS} ${TLIB}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ t_dst.@O@ ${TLIB} ${LIBS}
gsstest@EXEEXT@: gsstest.@O@ ${DEPLIBS} ${TLIB}
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ gsstest.@O@ ${TLIB} ${LIBS}
test: t_dst@EXEEXT@
../genrandom@EXEEXT@ 100 randomfile
-@ ./t_dst@EXEEXT@ -b @srcdir@ -q 1800 -a

566
bin/tests/dst/gsstest.c Executable file
View File

@@ -0,0 +1,566 @@
/*
* Copyright (C) 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: gsstest.c,v 1.2 2006/12/04 01:52:45 marka Exp $ */
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <isc/app.h>
#include <isc/base64.h>
#include <isc/entropy.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/dispatch.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/request.h>
#include <dns/result.h>
#include <dns/tkey.h>
#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/masterdump.h>
#include <dns/rdataset.h>
#include <dns/resolver.h>
#include <dns/types.h>
#include <dst/result.h>
#ifdef GSSAPI
#include ISC_PLATFORM_GSSAPIHEADER
struct dst_context {
unsigned int magic;
dst_key_t *key;
isc_mem_t *mctx;
void *opaque;
};
#define CHECK(str, x) { \
if ((x) != ISC_R_SUCCESS) { \
fprintf(stderr, "I:%d:%s: %s\n", __LINE__, (str), isc_result_totext(x)); \
goto end; \
} \
}
static char contextname[512];
static char gssid[512];
static char serveraddress[512];
static dns_fixedname_t servername, gssname;
static isc_mem_t *mctx;
static dns_requestmgr_t *requestmgr;
static isc_sockaddr_t address;
static dns_tsig_keyring_t *ring;
static dns_tsigkey_t *tsigkey = NULL;
static gss_ctx_id_t gssctx;
static gss_ctx_id_t *gssctxp = &gssctx;
#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
#define PORT 53
#define TIMEOUT 30
static void initctx1(isc_task_t *task, isc_event_t *event);
static void sendquery(isc_task_t *task, isc_event_t *event);
static void setup();
static void
console(isc_task_t *task, isc_event_t *event)
{
char buf[32];
isc_event_t *ev = NULL;
isc_event_free(&event);
while(1) {
printf("\nCommand => ");
scanf("%s", buf);
if(strcmp(buf, "quit") == 0) {
isc_app_shutdown();
return;
}
if(strcmp(buf, "initctx") == 0) {
ev = isc_event_allocate(mctx, (void *)1, 1, initctx1,
NULL, sizeof(*event));
isc_task_send(task, &ev);
return;
}
if(strcmp(buf, "query") == 0) {
ev = isc_event_allocate(mctx, (void *)1, 1, sendquery,
NULL, sizeof(*event));
isc_task_send(task, &ev);
return;
}
printf("Unknown command\n");
}
}
static void
recvresponse(isc_task_t *task, isc_event_t *event) {
dns_requestevent_t *reqev = (dns_requestevent_t *)event;
isc_result_t result, result2;
dns_message_t *query, *response = NULL;
isc_buffer_t outtoken;
isc_buffer_t outbuf;
char output[10 * 1024];
unsigned char array[DNS_NAME_MAXTEXT + 1];
isc_buffer_init(&outtoken, array, sizeof(array));
UNUSED(task);
REQUIRE(reqev != NULL);
if (reqev->result != ISC_R_SUCCESS) {
fprintf(stderr, "I:request event result: %s\n",
isc_result_totext(reqev->result));
goto end;
}
query = reqev->ev_arg;
response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result);
printf("\nReceived Response:\n");
result2 = dns_request_getresponse(reqev->request, response,
DNS_MESSAGEPARSE_PRESERVEORDER);
isc_buffer_init(&outbuf, output, sizeof(output));
result = dns_message_totext(response, &dns_master_style_debug, 0,
&outbuf);
CHECK("dns_message_totext", result);
printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf),
(char *)isc_buffer_base(&outbuf));
CHECK("dns_request_getresponse", result2);
if (response)
dns_message_destroy(&response);
end:
if (query)
dns_message_destroy(&query);
if (reqev->request)
dns_request_destroy(&reqev->request);
isc_event_free(&event);
event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
sizeof(*event));
isc_task_send(task, &event);
return;
}
static void
sendquery(isc_task_t *task, isc_event_t *event)
{
dns_request_t *request = NULL;
dns_message_t *message = NULL;
dns_name_t *qname = NULL;
dns_rdataset_t *qrdataset = NULL;
isc_result_t result;
dns_fixedname_t queryname;
isc_buffer_t buf;
isc_buffer_t outbuf;
char output[10 * 1024];
static char host[256];
isc_event_free(&event);
printf("Query => ");
scanf("%s", host);
dns_fixedname_init(&queryname);
isc_buffer_init(&buf, host, strlen(host));
isc_buffer_add(&buf, strlen(host));
result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf,
dns_rootname, ISC_FALSE, NULL);
CHECK("dns_name_fromtext", result);
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
message->opcode = dns_opcode_query;
message->rdclass = dns_rdataclass_in;
message->id = (unsigned short)(random() & 0xFFFF);
result = dns_message_gettempname(message, &qname);
if (result != ISC_R_SUCCESS)
goto end;
result = dns_message_gettemprdataset(message, &qrdataset);
if (result != ISC_R_SUCCESS)
goto end;
dns_name_init(qname, NULL);
dns_name_clone(dns_fixedname_name(&queryname), qname);
dns_rdataset_init(qrdataset);
dns_rdataset_makequestion(qrdataset, dns_rdataclass_in,
dns_rdatatype_a);
ISC_LIST_APPEND(qname->list, qrdataset, link);
dns_message_addname(message, qname, DNS_SECTION_QUESTION);
result = dns_request_create(requestmgr, message, &address, 0, tsigkey,
TIMEOUT, task, recvresponse,
message, &request);
CHECK("dns_request_create", result);
printf("Submitting query:\n");
isc_buffer_init(&outbuf, output, sizeof(output));
result = dns_message_totext(message, &dns_master_style_debug, 0,
&outbuf);
CHECK("dns_message_totext", result);
printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf),
(char *)isc_buffer_base(&outbuf));
return;
end:
if (qname != NULL)
dns_message_puttempname(message, &qname);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
if (message != NULL)
dns_message_destroy(&message);
}
static void
initctx2(isc_task_t *task, isc_event_t *event) {
dns_requestevent_t *reqev = (dns_requestevent_t *)event;
isc_result_t result;
dns_message_t *query, *response = NULL;
isc_buffer_t outtoken;
unsigned char array[DNS_NAME_MAXTEXT + 1];
dns_rdataset_t *rdataset;
dns_rdatatype_t qtype;
dns_name_t *question_name;
UNUSED(task);
REQUIRE(reqev != NULL);
if (reqev->result != ISC_R_SUCCESS) {
fprintf(stderr, "I:request event result: %s\n",
isc_result_totext(reqev->result));
goto end;
}
query = reqev->ev_arg;
response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result);
result = dns_request_getresponse(reqev->request, response,
DNS_MESSAGEPARSE_PRESERVEORDER);
CHECK("dns_request_getresponse", result);
if (response->rcode != dns_rcode_noerror) {
result = ISC_RESULTCLASS_DNSRCODE + response->rcode;
fprintf(stderr, "I:response rcode: %s\n",
isc_result_totext(result));
goto end;
}
printf("Received token from server, calling gss_init_sec_context()\n");
isc_buffer_init(&outtoken, array, DNS_NAME_MAXTEXT + 1);
result = dns_tkey_processgssresponse(query, response,
dns_fixedname_name(&gssname),
&gssctx, &outtoken,
&tsigkey, ring);
gssctx = *gssctxp;
CHECK("dns_tkey_processgssresponse", result);
printf("Context accepted\n");
question_name = NULL;
dns_message_currentname(response, DNS_SECTION_ANSWER, &question_name);
rdataset = ISC_LIST_HEAD(question_name->list);
INSIST(rdataset != NULL);
qtype = rdataset->type;
if(qtype == dns_rdatatype_tkey) {
printf("Received TKEY response from server\n");
printf("Context completed\n");
} else {
printf("Did not receive TKEY response from server\n");
printf("Context not completed\n");
dns_tsigkey_detach(&tsigkey);
tsigkey = NULL;
}
if(response)
dns_message_destroy(&response);
end:
if(query)
dns_message_destroy(&query);
if(reqev->request)
dns_request_destroy(&reqev->request);
isc_event_free(&event);
event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
sizeof(*event));
isc_task_send(task, &event);
return;
}
static void
initctx1(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_buffer_t buf;
dns_message_t *query;
dns_request_t *request;
isc_event_free(&event);
printf("Initctx - GSS name => ");
scanf("%s", gssid);
sprintf(contextname, "gsstest.context.%d.", (int)time(NULL));
printf("Initctx - context name we're using: %s\n", contextname);
printf("Negotiating GSSAPI context: ");
printf(gssid);
printf("\n");
/*
* Setup a GSSAPI context with the server
*/
dns_fixedname_init(&servername);
isc_buffer_init(&buf, contextname, strlen(contextname));
isc_buffer_add(&buf, strlen(contextname));
result = dns_name_fromtext(dns_fixedname_name(&servername), &buf,
dns_rootname, ISC_FALSE, NULL);
CHECK("dns_name_fromtext", result);
/* Make name happen */
dns_fixedname_init(&gssname);
isc_buffer_init(&buf, gssid, strlen(gssid));
isc_buffer_add(&buf, strlen(gssid));
result = dns_name_fromtext(dns_fixedname_name(&gssname), &buf,
dns_rootname, ISC_FALSE, NULL);
CHECK("dns_name_fromtext", result);
query = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
CHECK("dns_message_create", result);
printf("Calling gss_init_sec_context()\n");
gssctx = GSS_C_NO_CONTEXT;
result = dns_tkey_buildgssquery(query, dns_fixedname_name(&servername),
dns_fixedname_name(&gssname),
NULL, 36000, &gssctx, ISC_TRUE);
CHECK("dns_tkey_buildgssquery", result);
printf("Sending context token to server\n");
request = NULL;
result = dns_request_create(requestmgr, query, &address, 0, NULL,
TIMEOUT, task, initctx2, query, &request);
CHECK("dns_request_create", result);
return;
end:
event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
sizeof(*event));
isc_task_send(task, &event);return;
}
static void
setup(void)
{
struct in_addr inaddr;
while (1) {
printf("Server IP => ");
scanf("%s", serveraddress);
if(strcmp(serveraddress, "quit") == 0) {
isc_app_shutdown();
return;
}
if (inet_pton(AF_INET, serveraddress, &inaddr) == 1) {
isc_sockaddr_fromin(&address, &inaddr, PORT);
return;
}
};
}
int
main(int argc, char *argv[]) {
isc_taskmgr_t *taskmgr;
isc_timermgr_t *timermgr;
isc_socketmgr_t *socketmgr;
isc_socket_t *sock;
unsigned int attrs, attrmask;
isc_sockaddr_t bind_any;
dns_dispatchmgr_t *dispatchmgr;
dns_dispatch_t *dispatchv4;
dns_view_t *view;
isc_entropy_t *ectx;
isc_task_t *task;
isc_log_t *lctx = NULL;
isc_logconfig_t *lcfg = NULL;
isc_logdestination_t destination;
UNUSED(argv);
UNUSED(argc);
RUNCHECK(isc_app_start());
dns_result_register();
mctx = NULL;
RUNCHECK(isc_mem_create(0, 0, &mctx));
RUNCHECK(isc_log_create(mctx, &lctx, &lcfg));
isc_log_setcontext(lctx);
dns_log_init(lctx);
dns_log_setcontext(lctx);
/*
* Create and install the default channel.
*/
destination.file.stream = stderr;
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
RUNCHECK(isc_log_createchannel(lcfg, "_default",
ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC,
&destination, ISC_LOG_PRINTTIME));
RUNCHECK(isc_log_usechannel(lcfg, "_default", NULL, NULL));
isc_log_setdebuglevel(lctx, 9);
ectx = NULL;
RUNCHECK(isc_entropy_create(mctx, &ectx));
RUNCHECK(isc_entropy_createfilesource(ectx, "/dev/urandom"));
RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY));
taskmgr = NULL;
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
RUNCHECK(isc_timermgr_create(mctx, &timermgr));
socketmgr = NULL;
RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
dispatchmgr = NULL;
RUNCHECK(dns_dispatchmgr_create(mctx, ectx, &dispatchmgr));
isc_sockaddr_any(&bind_any);
attrs = DNS_DISPATCHATTR_UDP |
DNS_DISPATCHATTR_MAKEQUERY |
DNS_DISPATCHATTR_IPV4;
attrmask = DNS_DISPATCHATTR_UDP |
DNS_DISPATCHATTR_TCP |
DNS_DISPATCHATTR_IPV4 |
DNS_DISPATCHATTR_IPV6;
dispatchv4 = NULL;
RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
&bind_any, 4096, 4, 2, 3, 5,
attrs, attrmask, &dispatchv4));
requestmgr = NULL;
RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
dispatchmgr, dispatchv4, NULL,
&requestmgr));
ring = NULL;
RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
view = NULL;
RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
dns_view_setkeyring(view, ring);
sock = NULL;
RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
&sock));
setup();
RUNCHECK(isc_app_onrun(mctx, task, console, NULL));
(void)isc_app_run();
if (tsigkey)
dns_tsigkey_detach(&tsigkey);
dns_requestmgr_shutdown(requestmgr);
dns_requestmgr_detach(&requestmgr);
dns_dispatch_detach(&dispatchv4);
dns_dispatchmgr_destroy(&dispatchmgr);
isc_timermgr_destroy(&timermgr);
isc_task_detach(&task);
isc_taskmgr_destroy(&taskmgr);
isc_socket_detach(&sock);
isc_socketmgr_destroy(&socketmgr);
isc_mem_stats(mctx, stdout);
dns_view_detach(&view);
dst_lib_destroy();
isc_entropy_detach(&ectx);
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);
isc_app_finish();
return (0);
}
#else
int
main(int argc, char *argv[]) {
UNUSED(argc);
UNUSED(argv);
fprintf(stderr, "R:GSSAPIONLY\n");
return (0);
}
#endif

View File

@@ -16,7 +16,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: config.h.in,v 1.82 2006/08/10 01:57:41 marka Exp $ */
/* $Id: config.h.in,v 1.83 2006/12/04 01:54:53 marka Exp $ */
/*! \file */
@@ -169,6 +169,12 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
#undef HAVE_GSSAPI_GSSAPI_H
/* Define to 1 if you have the <gssapi.h> header file. */
#undef HAVE_GSSAPI_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

551
configure vendored
View File

@@ -14,7 +14,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# $Id: configure,v 1.406 2006/11/10 17:55:20 marka Exp $
# $Id: configure,v 1.407 2006/12/04 01:54:53 marka Exp $
#
# Portions Copyright (C) 1996-2001 Nominum, Inc.
#
@@ -29,7 +29,7 @@
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# From configure.in Revision: 1.418 .
# From configure.in Revision: 1.419 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
@@ -495,7 +495,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S STD_CINCLUDES STD_CDEFINES STD_CWARNINGS CCOPT AR ARFLAGS LN ETAGS PERL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP ISC_SOCKADDR_LEN_T ISC_PLATFORM_HAVELONGLONG ISC_PLATFORM_HAVELIFCONF ISC_PLATFORM_NEEDSYSSELECTH LWRES_PLATFORM_NEEDSYSSELECTH USE_OPENSSL DST_OPENSSL_INC USE_GSSAPI DST_GSSAPI_INC DNS_CRYPTO_LIBS ALWAYS_DEFINES ISC_PLATFORM_USETHREADS ISC_THREAD_DIR MKDEPCC MKDEPCFLAGS MKDEPPROG IRIX_DNSSEC_WARNINGS_HACK purify_path PURIFY ECHO ac_ct_AR STRIP ac_ct_STRIP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL O A SA LIBTOOL_MKDEP_SED LIBTOOL_MODE_COMPILE LIBTOOL_MODE_INSTALL LIBTOOL_MODE_LINK LIBTOOL_ALLOW_UNDEFINED LIBTOOL_IN_MAIN LIBBIND ISC_PLATFORM_HAVEIPV6 LWRES_PLATFORM_HAVEIPV6 ISC_PLATFORM_NEEDNETINETIN6H LWRES_PLATFORM_NEEDNETINETIN6H ISC_PLATFORM_NEEDNETINET6IN6H LWRES_PLATFORM_NEEDNETINET6IN6H ISC_PLATFORM_HAVEINADDR6 LWRES_PLATFORM_HAVEINADDR6 ISC_PLATFORM_NEEDIN6ADDRANY LWRES_PLATFORM_NEEDIN6ADDRANY ISC_PLATFORM_NEEDIN6ADDRLOOPBACK LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK ISC_PLATFORM_HAVEIN6PKTINFO ISC_PLATFORM_FIXIN6ISADDR ISC_IPV6_H ISC_IPV6_O ISC_ISCIPV6_O ISC_IPV6_C LWRES_HAVE_SIN6_SCOPE_ID ISC_PLATFORM_HAVESCOPEID ISC_PLATFORM_HAVEIF_LADDRREQ ISC_PLATFORM_HAVEIF_LADDRCONF ISC_PLATFORM_NEEDNTOP ISC_PLATFORM_NEEDPTON ISC_PLATFORM_NEEDATON ISC_PLATFORM_HAVESALEN LWRES_PLATFORM_HAVESALEN ISC_PLATFORM_MSGHDRFLAVOR ISC_PLATFORM_NEEDPORTT ISC_LWRES_NEEDADDRINFO ISC_LWRES_NEEDRRSETINFO ISC_LWRES_SETHOSTENTINT ISC_LWRES_ENDHOSTENTINT ISC_LWRES_GETNETBYADDRINADDR ISC_LWRES_SETNETENTINT ISC_LWRES_ENDNETENTINT ISC_LWRES_GETHOSTBYADDRVOID ISC_LWRES_NEEDHERRNO ISC_LWRES_GETIPNODEPROTO ISC_LWRES_GETADDRINFOPROTO ISC_LWRES_GETNAMEINFOPROTO ISC_PLATFORM_NEEDSTRSEP ISC_PLATFORM_NEEDMEMMOVE ISC_PLATFORM_NEEDSTRTOUL LWRES_PLATFORM_NEEDSTRTOUL GENRANDOMLIB ISC_PLATFORM_NEEDSTRLCPY ISC_PLATFORM_NEEDSTRLCAT ISC_PLATFORM_NEEDSPRINTF LWRES_PLATFORM_NEEDSPRINTF ISC_PLATFORM_NEEDVSNPRINTF LWRES_PLATFORM_NEEDVSNPRINTF ISC_EXTRA_OBJS ISC_EXTRA_SRCS ISC_PLATFORM_QUADFORMAT LWRES_PLATFORM_QUADFORMAT ISC_PLATFORM_HAVESYSUNH ISC_PLATFORM_RLIMITTYPE ISC_PLATFORM_USEDECLSPEC LWRES_PLATFORM_USEDECLSPEC ISC_PLATFORM_BRACEPTHREADONCEINIT ISC_PLATFORM_HAVEIFNAMETOINDEX ISC_PLATFORM_HAVEXADD ISC_PLATFORM_HAVECMPXCHG ISC_PLATFORM_HAVEATOMICSTORE ISC_PLATFORM_USEGCCASM ISC_PLATFORM_USEOSFASM ISC_PLATFORM_USESTDASM ISC_ARCH_DIR LATEX PDFLATEX W3M XSLTPROC XMLLINT XSLT_DOCBOOK_STYLE_HTML XSLT_DOCBOOK_STYLE_XHTML XSLT_DOCBOOK_STYLE_MAN XSLT_DOCBOOK_CHUNK_HTML XSLT_DOCBOOK_CHUNK_XHTML XSLT_DOCBOOK_CHUNKTOC_HTML XSLT_DOCBOOK_CHUNKTOC_XHTML XSLT_DOCBOOK_MAKETOC_HTML XSLT_DOCBOOK_MAKETOC_XHTML XSLT_DB2LATEX_STYLE XSLT_DB2LATEX_ADMONITIONS IDNLIBS BIND9_TOP_BUILDDIR BIND9_ISC_BUILDINCLUDE BIND9_ISCCC_BUILDINCLUDE BIND9_ISCCFG_BUILDINCLUDE BIND9_DNS_BUILDINCLUDE BIND9_LWRES_BUILDINCLUDE BIND9_BIND9_BUILDINCLUDE BIND9_VERSION PG_CONFIG USE_DLZ DLZ_DRIVER_INCLUDES DLZ_DRIVER_LIBS DLZ_DRIVER_SRCS DLZ_DRIVER_OBJS BUILD_CC BUILD_CFLAGS BUILD_CPPFLAGS BUILD_LDFLAGS BUILD_LIBS LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S STD_CINCLUDES STD_CDEFINES STD_CWARNINGS CCOPT AR ARFLAGS LN ETAGS PERL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP ISC_SOCKADDR_LEN_T ISC_PLATFORM_HAVELONGLONG ISC_PLATFORM_HAVELIFCONF ISC_PLATFORM_NEEDSYSSELECTH LWRES_PLATFORM_NEEDSYSSELECTH USE_OPENSSL DST_OPENSSL_INC ISC_PLATFORM_HAVEGSSAPI ISC_PLATFORM_GSSAPIHEADER USE_GSSAPI DST_GSSAPI_INC DNS_GSSAPI_LIBS DNS_CRYPTO_LIBS ALWAYS_DEFINES ISC_PLATFORM_USETHREADS ISC_THREAD_DIR MKDEPCC MKDEPCFLAGS MKDEPPROG IRIX_DNSSEC_WARNINGS_HACK purify_path PURIFY ECHO ac_ct_AR STRIP ac_ct_STRIP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL O A SA LIBTOOL_MKDEP_SED LIBTOOL_MODE_COMPILE LIBTOOL_MODE_INSTALL LIBTOOL_MODE_LINK LIBTOOL_ALLOW_UNDEFINED LIBTOOL_IN_MAIN LIBBIND ISC_PLATFORM_HAVEIPV6 LWRES_PLATFORM_HAVEIPV6 ISC_PLATFORM_NEEDNETINETIN6H LWRES_PLATFORM_NEEDNETINETIN6H ISC_PLATFORM_NEEDNETINET6IN6H LWRES_PLATFORM_NEEDNETINET6IN6H ISC_PLATFORM_HAVEINADDR6 LWRES_PLATFORM_HAVEINADDR6 ISC_PLATFORM_NEEDIN6ADDRANY LWRES_PLATFORM_NEEDIN6ADDRANY ISC_PLATFORM_NEEDIN6ADDRLOOPBACK LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK ISC_PLATFORM_HAVEIN6PKTINFO ISC_PLATFORM_FIXIN6ISADDR ISC_IPV6_H ISC_IPV6_O ISC_ISCIPV6_O ISC_IPV6_C LWRES_HAVE_SIN6_SCOPE_ID ISC_PLATFORM_HAVESCOPEID ISC_PLATFORM_HAVEIF_LADDRREQ ISC_PLATFORM_HAVEIF_LADDRCONF ISC_PLATFORM_NEEDNTOP ISC_PLATFORM_NEEDPTON ISC_PLATFORM_NEEDATON ISC_PLATFORM_HAVESALEN LWRES_PLATFORM_HAVESALEN ISC_PLATFORM_MSGHDRFLAVOR ISC_PLATFORM_NEEDPORTT ISC_LWRES_NEEDADDRINFO ISC_LWRES_NEEDRRSETINFO ISC_LWRES_SETHOSTENTINT ISC_LWRES_ENDHOSTENTINT ISC_LWRES_GETNETBYADDRINADDR ISC_LWRES_SETNETENTINT ISC_LWRES_ENDNETENTINT ISC_LWRES_GETHOSTBYADDRVOID ISC_LWRES_NEEDHERRNO ISC_LWRES_GETIPNODEPROTO ISC_LWRES_GETADDRINFOPROTO ISC_LWRES_GETNAMEINFOPROTO ISC_PLATFORM_NEEDSTRSEP ISC_PLATFORM_NEEDMEMMOVE ISC_PLATFORM_NEEDSTRTOUL LWRES_PLATFORM_NEEDSTRTOUL GENRANDOMLIB ISC_PLATFORM_NEEDSTRLCPY ISC_PLATFORM_NEEDSTRLCAT ISC_PLATFORM_NEEDSPRINTF LWRES_PLATFORM_NEEDSPRINTF ISC_PLATFORM_NEEDVSNPRINTF LWRES_PLATFORM_NEEDVSNPRINTF ISC_EXTRA_OBJS ISC_EXTRA_SRCS USE_ISC_SPNEGO DST_EXTRA_OBJS DST_EXTRA_SRCS ISC_PLATFORM_QUADFORMAT LWRES_PLATFORM_QUADFORMAT ISC_PLATFORM_HAVESYSUNH ISC_PLATFORM_RLIMITTYPE ISC_PLATFORM_USEDECLSPEC LWRES_PLATFORM_USEDECLSPEC ISC_PLATFORM_BRACEPTHREADONCEINIT ISC_PLATFORM_HAVEIFNAMETOINDEX ISC_PLATFORM_HAVEXADD ISC_PLATFORM_HAVECMPXCHG ISC_PLATFORM_HAVEATOMICSTORE ISC_PLATFORM_USEGCCASM ISC_PLATFORM_USEOSFASM ISC_PLATFORM_USESTDASM ISC_ARCH_DIR LATEX PDFLATEX W3M XSLTPROC XMLLINT XSLT_DOCBOOK_STYLE_HTML XSLT_DOCBOOK_STYLE_XHTML XSLT_DOCBOOK_STYLE_MAN XSLT_DOCBOOK_CHUNK_HTML XSLT_DOCBOOK_CHUNK_XHTML XSLT_DOCBOOK_CHUNKTOC_HTML XSLT_DOCBOOK_CHUNKTOC_XHTML XSLT_DOCBOOK_MAKETOC_HTML XSLT_DOCBOOK_MAKETOC_XHTML XSLT_DB2LATEX_STYLE XSLT_DB2LATEX_ADMONITIONS IDNLIBS BIND9_TOP_BUILDDIR BIND9_ISC_BUILDINCLUDE BIND9_ISCCC_BUILDINCLUDE BIND9_ISCCFG_BUILDINCLUDE BIND9_DNS_BUILDINCLUDE BIND9_LWRES_BUILDINCLUDE BIND9_BIND9_BUILDINCLUDE BIND9_VERSION PG_CONFIG USE_DLZ DLZ_DRIVER_INCLUDES DLZ_DRIVER_LIBS DLZ_DRIVER_SRCS DLZ_DRIVER_OBJS BUILD_CC BUILD_CFLAGS BUILD_CPPFLAGS BUILD_LDFLAGS BUILD_LIBS LIBOBJS LTLIBOBJS'
ac_subst_files='BIND9_MAKE_INCLUDES BIND9_MAKE_RULES LIBISC_API LIBISCCC_API LIBISCCFG_API LIBDNS_API LIBBIND9_API LIBLWRES_API DLZ_DRIVER_RULES'
# Initialize some variables set by options.
@@ -1065,6 +1065,7 @@ Optional Features:
--enable-ipv6 use IPv6 default=autodetect
--enable-getifaddrs Enable the use of getifaddrs() [yes|no|glibc].
glibc: Use getifaddrs() in glibc if you know it supports IPv6.
--disable-isc-spnego use SPNEGO from GSSAPI library
--disable-linux-caps disable linux capabilities
--enable-atomic enable machine specific atomic operations
[default=autodetect]
@@ -1074,6 +1075,7 @@ Optional Packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-openssl=PATH Build with OpenSSL yes|no|path.
(Required for DNSSEC)
--with-gssapi=PATH Specify path for system-supplied GSSAPI
--with-randomdev=PATH Specify path for random device
--with-ptl2 on NetBSD, use the ptl2 thread library (experimental)
--with-purify=PATH use Rational purify
@@ -4924,8 +4926,8 @@ echo "$as_me: error: OpenSSL was not found in any of $openssldirs; use --with-op
;;
esac
fi
echo "$as_me:$LINENO: result: using openssl from $use_openssl/lib and $use_openssl/include" >&5
echo "${ECHO_T}using openssl from $use_openssl/lib and $use_openssl/include" >&6
echo "$as_me:$LINENO: result: using OpenSSL from $use_openssl/lib and $use_openssl/include" >&5
echo "${ECHO_T}using OpenSSL from $use_openssl/lib and $use_openssl/include" >&6
saved_cflags="$CFLAGS"
saved_libs="$LIBS"
@@ -5483,39 +5485,363 @@ esac
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
#
# was --with-gssapi specified?
#
#AC_MSG_CHECKING(for GSSAPI library)
#AC_ARG_WITH(gssapi,
#[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
# use_gssapi="$withval", use_gssapi="no")
#
#case "$use_gssapi" in
# no)
# USE_GSSAPI=''
# DST_GSSAPI_INC=''
# DNS_GSSAPI_LIBS=''
# AC_MSG_RESULT(not specified)
# ;;
# yes)
# AC_MSG_ERROR([--with-gssapi must specify a path])
# ;;
# *)
# USE_GSSAPI='-DGSSAPI'
# DST_GSSAPI_INC="-I$use_gssapi/include"
# DNS_GSSAPI_LIBS="-L$use_gssapi/lib -lgssapi_krb5"
# AC_MSG_RESULT(using gssapi from $use_gssapi/lib and $use_gssapi/include)
# ;;
#esac
echo "$as_me:$LINENO: checking for GSSAPI library" >&5
echo $ECHO_N "checking for GSSAPI library... $ECHO_C" >&6
# Check whether --with-gssapi or --without-gssapi was given.
if test "${with_gssapi+set}" = set; then
withval="$with_gssapi"
use_gssapi="$withval"
else
use_gssapi="no"
fi;
gssapidirs="/usr/local /usr/pkg /usr/kerberos /usr"
if test "$use_gssapi" = "yes"
then
for d in $gssapidirs
do
if test -f $d/include/gssapi/gssapi.h -o -f $d/gssapi.h
then
use_gssapi=$d
break
fi
done
fi
case "$use_gssapi" in
no)
echo "$as_me:$LINENO: result: disabled" >&5
echo "${ECHO_T}disabled" >&6
USE_GSSAPI=''
DST_GSSAPI_INC=''
DNS_GSSAPI_LIBS=''
;;
yes)
{ { echo "$as_me:$LINENO: error: --with-gssapi must specify a path" >&5
echo "$as_me: error: --with-gssapi must specify a path" >&2;}
{ (exit 1); exit 1; }; }
;;
*)
echo "$as_me:$LINENO: result: looking in $use_gssapi/lib" >&5
echo "${ECHO_T}looking in $use_gssapi/lib" >&6
USE_GSSAPI='-DGSSAPI'
saved_cppflags="$CPPFLAGS"
CPPFLAGS="-I$use_gssapi/include $CPPFLAGS"
for ac_header in gssapi.h gssapi/gssapi.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------ ##
## Report this to the AC_PACKAGE_NAME lists. ##
## ------------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
ISC_PLATFORM_GSSAPIHEADER="#define ISC_PLATFORM_GSSAPIHEADER <$ac_header>"
fi
done
if test "$ISC_PLATFORM_GSSAPIHEADER" = ""; then
{ { echo "$as_me:$LINENO: error: gssapi.h not found" >&5
echo "$as_me: error: gssapi.h not found" >&2;}
{ (exit 1); exit 1; }; }
fi
CPPFLAGS="$saved_cppflags"
#
# XXXDCL This probably doesn't work right on all systems.
# It will need to be worked on as problems become evident.
#
# Essentially the problems here relate to two different
# areas. The first area is building with either KTH
# or MIT Kerberos, particularly when both are present on
# the machine. The other is static versus dynamic linking.
#
# On the KTH vs MIT issue, Both have libkrb5 that can mess
# up the works if one implementation ends up trying to
# use the other's krb. This is unfortunately a situation
# that very easily arises.
#
# Dynamic linking when the dependency information is built
# into MIT's libgssapi_krb5 or KTH's libgssapi magically makes
# all such problems go away, but when that setup is not
# present, because either the dynamic libraries lack
# dependencies or static linking is being done, then the
# problems start to show up.
saved_libs="$LIBS"
for TRY_LIBS in \
"-lgssapi_krb5" \
"-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err" \
"-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv" \
"-lgssapi" \
"-lgssapi -lkrb5 -ldes -lcrypt -lasn1 -lroken -lcom_err" \
"-lgssapi -lkrb5 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \
"-lgss"
do
# Note that this does not include $saved_libs, because
# on FreeBSD machines this configure script has added
# -L/usr/local/lib to LIBS, which can make the
# -lgssapi_krb5 test succeed with shared libraries even
# when you are trying to build with KTH in /usr/lib.
LIBS="-L$use_gssapi/lib $TRY_LIBS"
echo "$as_me:$LINENO: checking linking as $TRY_LIBS" >&5
echo $ECHO_N "checking linking as $TRY_LIBS... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
gss_acquire_cred();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
gssapi_linked=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
gssapi_linked=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
case $gssapi_linked in
yes) echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; break ;;
no) echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6 ;;
esac
done
case $gssapi_linked in
no) { { echo "$as_me:$LINENO: error: could not determine proper GSSAPI linkage" >&5
echo "$as_me: error: could not determine proper GSSAPI linkage" >&2;}
{ (exit 1); exit 1; }; } ;;
esac
#
# XXXDCL Major kludge. Tries to cope with KTH in /usr/lib
# but MIT in /usr/local/lib and trying to build with KTH.
# /usr/local/lib can end up earlier on the link lines.
# Like most kludges, this one is not only inelegant it
# is also likely to be the wrong thing to do at least as
# many times as it is the right thing. Something better
# needs to be done.
#
if test "$use_gssapi" = "/usr" -a \
-f /usr/local/lib/libkrb5.a; then
FIX_KTH_VS_MIT=yes
fi
case "$FIX_KTH_VS_MIT" in
yes)
case "$enable_static_linking" in
yes) gssapi_lib_suffix=".a" ;;
*) gssapi_lib_suffix=".so" ;;
esac
for lib in $LIBS; do
case $lib in
-L*)
;;
-l*)
new_lib=`echo $lib |
sed -e s%^-l%$use_gssapi/lib/lib% \
-e s%$%$gssapi_lib_suffix%`
NEW_LIBS="$NEW_LIBS $new_lib"
;;
*)
{ { echo "$as_me:$LINENO: error: KTH vs MIT Kerberos confusion!" >&5
echo "$as_me: error: KTH vs MIT Kerberos confusion!" >&2;}
{ (exit 1); exit 1; }; }
;;
esac
done
LIBS="$NEW_LIBS"
;;
esac
DST_GSSAPI_INC="-I$use_gssapi/include"
DNS_GSSAPI_LIBS="$LIBS"
echo "$as_me:$LINENO: result: using GSSAPI from $use_gssapi/lib and $use_gssapi/include" >&5
echo "${ECHO_T}using GSSAPI from $use_gssapi/lib and $use_gssapi/include" >&6
LIBS="$saved_libs"
;;
esac
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_GSSAPI_LIBS"
DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_LIBS"
#
# Applications linking with libdns also need to link with these libraries.
@@ -8851,7 +9177,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 8854 "configure"' > conftest.$ac_ext
echo '#line 9180 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -9848,7 +10174,7 @@ fi
# Provide some information about the compiler.
echo "$as_me:9851:" \
echo "$as_me:10177:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -10909,11 +11235,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:10912: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11238: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:10916: \$? = $ac_status" >&5
echo "$as_me:11242: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@@ -11152,11 +11478,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11155: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11481: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:11159: \$? = $ac_status" >&5
echo "$as_me:11485: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@@ -11212,11 +11538,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11215: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11541: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:11219: \$? = $ac_status" >&5
echo "$as_me:11545: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -13397,7 +13723,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 13400 "configure"
#line 13726 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13495,7 +13821,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 13498 "configure"
#line 13824 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15692,11 +16018,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:15695: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16021: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:15699: \$? = $ac_status" >&5
echo "$as_me:16025: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@@ -15752,11 +16078,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:15755: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16081: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:15759: \$? = $ac_status" >&5
echo "$as_me:16085: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -17113,7 +17439,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 17116 "configure"
#line 17442 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -17211,7 +17537,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 17214 "configure"
#line 17540 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18048,11 +18374,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:18051: $lt_compile\"" >&5)
(eval echo "\"\$as_me:18377: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:18055: \$? = $ac_status" >&5
echo "$as_me:18381: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@@ -18108,11 +18434,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:18111: $lt_compile\"" >&5)
(eval echo "\"\$as_me:18437: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:18115: \$? = $ac_status" >&5
echo "$as_me:18441: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -20147,11 +20473,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:20150: $lt_compile\"" >&5)
(eval echo "\"\$as_me:20476: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:20154: \$? = $ac_status" >&5
echo "$as_me:20480: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@@ -20390,11 +20716,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:20393: $lt_compile\"" >&5)
(eval echo "\"\$as_me:20719: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:20397: \$? = $ac_status" >&5
echo "$as_me:20723: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@@ -20450,11 +20776,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:20453: $lt_compile\"" >&5)
(eval echo "\"\$as_me:20779: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:20457: \$? = $ac_status" >&5
echo "$as_me:20783: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -22635,7 +22961,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 22638 "configure"
#line 22964 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -22733,7 +23059,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 22736 "configure"
#line 23062 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -26777,6 +27103,37 @@ fi
#
# Use our own SPNEGO implementation?
#
# Check whether --enable-isc-spnego or --disable-isc-spnego was given.
if test "${enable_isc_spnego+set}" = set; then
enableval="$enable_isc_spnego"
fi;
if test -n "$USE_GSSAPI"
then
case "$enable_isc_spnego" in
yes|'')
USE_ISC_SPNEGO='-DUSE_ISC_SPNEGO'
DST_EXTRA_OBJS="$DST_EXTRA_OBJS spnego.$O"
DST_EXTRA_SRCS="$DST_EXTRA_SRCS spnego.c"
echo "$as_me:$LINENO: result: using SPNEGO from lib/dns" >&5
echo "${ECHO_T}using SPNEGO from lib/dns" >&6
;;
no)
echo "$as_me:$LINENO: result: using SPNEGO from GSSAPI library" >&5
echo "${ECHO_T}using SPNEGO from GSSAPI library" >&6
;;
esac
fi
# Determine the printf format characters to use when printing
# values of type isc_int64_t. This will normally be "ll", but where
# the compiler treats "long long" as a alias for "long" and printf
@@ -30175,6 +30532,72 @@ else
BUILD_LIBS="$LIBS"
fi
NEWFLAGS=""
for e in $BUILD_LDFLAGS ; do
case $e in
-L*)
case $host_os in
netbsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
freebsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
esac
;;
*)
NEWFLAGS="$NEWFLAGS $e"
;;
esac
done
BUILD_LDFLAGS="$NEWFLAGS"
NEWFLAGS=""
for e in $DNS_GSSAPI_LIBS ; do
case $e in
-L*)
case $host_os in
netbsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
freebsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
esac
;;
*)
NEWFLAGS="$NEWFLAGS $e"
;;
esac
done
DNS_GSSAPI_LIBS="$NEWFLAGS"
NEWFLAGS=""
for e in $DNS_CRYPTO_LIBS ; do
case $e in
-L*)
case $host_os in
netbsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
freebsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
esac
;;
*)
NEWFLAGS="$NEWFLAGS $e"
;;
esac
done
DNS_CRYPTO_LIBS="$NEWFLAGS"
@@ -30937,8 +31360,11 @@ s,@ISC_PLATFORM_NEEDSYSSELECTH@,$ISC_PLATFORM_NEEDSYSSELECTH,;t t
s,@LWRES_PLATFORM_NEEDSYSSELECTH@,$LWRES_PLATFORM_NEEDSYSSELECTH,;t t
s,@USE_OPENSSL@,$USE_OPENSSL,;t t
s,@DST_OPENSSL_INC@,$DST_OPENSSL_INC,;t t
s,@ISC_PLATFORM_HAVEGSSAPI@,$ISC_PLATFORM_HAVEGSSAPI,;t t
s,@ISC_PLATFORM_GSSAPIHEADER@,$ISC_PLATFORM_GSSAPIHEADER,;t t
s,@USE_GSSAPI@,$USE_GSSAPI,;t t
s,@DST_GSSAPI_INC@,$DST_GSSAPI_INC,;t t
s,@DNS_GSSAPI_LIBS@,$DNS_GSSAPI_LIBS,;t t
s,@DNS_CRYPTO_LIBS@,$DNS_CRYPTO_LIBS,;t t
s,@ALWAYS_DEFINES@,$ALWAYS_DEFINES,;t t
s,@ISC_PLATFORM_USETHREADS@,$ISC_PLATFORM_USETHREADS,;t t
@@ -31025,6 +31451,9 @@ s,@ISC_PLATFORM_NEEDVSNPRINTF@,$ISC_PLATFORM_NEEDVSNPRINTF,;t t
s,@LWRES_PLATFORM_NEEDVSNPRINTF@,$LWRES_PLATFORM_NEEDVSNPRINTF,;t t
s,@ISC_EXTRA_OBJS@,$ISC_EXTRA_OBJS,;t t
s,@ISC_EXTRA_SRCS@,$ISC_EXTRA_SRCS,;t t
s,@USE_ISC_SPNEGO@,$USE_ISC_SPNEGO,;t t
s,@DST_EXTRA_OBJS@,$DST_EXTRA_OBJS,;t t
s,@DST_EXTRA_SRCS@,$DST_EXTRA_SRCS,;t t
s,@ISC_PLATFORM_QUADFORMAT@,$ISC_PLATFORM_QUADFORMAT,;t t
s,@LWRES_PLATFORM_QUADFORMAT@,$LWRES_PLATFORM_QUADFORMAT,;t t
s,@ISC_PLATFORM_HAVESYSUNH@,$ISC_PLATFORM_HAVESYSUNH,;t t

View File

@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
AC_REVISION($Revision: 1.418 $)
AC_REVISION($Revision: 1.419 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
@@ -434,7 +434,7 @@ case "$use_openssl" in
;;
esac
fi
AC_MSG_RESULT(using openssl from $use_openssl/lib and $use_openssl/include)
AC_MSG_RESULT(using OpenSSL from $use_openssl/lib and $use_openssl/include)
saved_cflags="$CFLAGS"
saved_libs="$LIBS"
@@ -539,39 +539,150 @@ AC_SUBST(USE_OPENSSL)
AC_SUBST(DST_OPENSSL_INC)
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
#
# was --with-gssapi specified?
#
#AC_MSG_CHECKING(for GSSAPI library)
#AC_ARG_WITH(gssapi,
#[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
# use_gssapi="$withval", use_gssapi="no")
#
#case "$use_gssapi" in
# no)
# USE_GSSAPI=''
# DST_GSSAPI_INC=''
# DNS_GSSAPI_LIBS=''
# AC_MSG_RESULT(not specified)
# ;;
# yes)
# AC_MSG_ERROR([--with-gssapi must specify a path])
# ;;
# *)
# USE_GSSAPI='-DGSSAPI'
# DST_GSSAPI_INC="-I$use_gssapi/include"
# DNS_GSSAPI_LIBS="-L$use_gssapi/lib -lgssapi_krb5"
# AC_MSG_RESULT(using gssapi from $use_gssapi/lib and $use_gssapi/include)
# ;;
#esac
AC_MSG_CHECKING(for GSSAPI library)
AC_ARG_WITH(gssapi,
[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
use_gssapi="$withval", use_gssapi="no")
gssapidirs="/usr/local /usr/pkg /usr/kerberos /usr"
if test "$use_gssapi" = "yes"
then
for d in $gssapidirs
do
if test -f $d/include/gssapi/gssapi.h -o -f $d/gssapi.h
then
use_gssapi=$d
break
fi
done
fi
case "$use_gssapi" in
no)
AC_MSG_RESULT(disabled)
USE_GSSAPI=''
DST_GSSAPI_INC=''
DNS_GSSAPI_LIBS=''
;;
yes)
AC_MSG_ERROR([--with-gssapi must specify a path])
;;
*)
AC_MSG_RESULT(looking in $use_gssapi/lib)
USE_GSSAPI='-DGSSAPI'
saved_cppflags="$CPPFLAGS"
CPPFLAGS="-I$use_gssapi/include $CPPFLAGS"
AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h,
[ISC_PLATFORM_GSSAPIHEADER="#define ISC_PLATFORM_GSSAPIHEADER <$ac_header>"])
if test "$ISC_PLATFORM_GSSAPIHEADER" = ""; then
AC_MSG_ERROR([gssapi.h not found])
fi
CPPFLAGS="$saved_cppflags"
#
# XXXDCL This probably doesn't work right on all systems.
# It will need to be worked on as problems become evident.
#
# Essentially the problems here relate to two different
# areas. The first area is building with either KTH
# or MIT Kerberos, particularly when both are present on
# the machine. The other is static versus dynamic linking.
#
# On the KTH vs MIT issue, Both have libkrb5 that can mess
# up the works if one implementation ends up trying to
# use the other's krb. This is unfortunately a situation
# that very easily arises.
#
# Dynamic linking when the dependency information is built
# into MIT's libgssapi_krb5 or KTH's libgssapi magically makes
# all such problems go away, but when that setup is not
# present, because either the dynamic libraries lack
# dependencies or static linking is being done, then the
# problems start to show up.
saved_libs="$LIBS"
for TRY_LIBS in \
"-lgssapi_krb5" \
"-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err" \
"-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv" \
"-lgssapi" \
"-lgssapi -lkrb5 -ldes -lcrypt -lasn1 -lroken -lcom_err" \
"-lgssapi -lkrb5 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \
"-lgss"
do
# Note that this does not include $saved_libs, because
# on FreeBSD machines this configure script has added
# -L/usr/local/lib to LIBS, which can make the
# -lgssapi_krb5 test succeed with shared libraries even
# when you are trying to build with KTH in /usr/lib.
LIBS="-L$use_gssapi/lib $TRY_LIBS"
AC_MSG_CHECKING(linking as $TRY_LIBS)
AC_TRY_LINK( , [gss_acquire_cred();],
gssapi_linked=yes, gssapi_linked=no)
case $gssapi_linked in
yes) AC_MSG_RESULT(yes); break ;;
no) AC_MSG_RESULT(no) ;;
esac
done
case $gssapi_linked in
no) AC_MSG_ERROR(could not determine proper GSSAPI linkage) ;;
esac
#
# XXXDCL Major kludge. Tries to cope with KTH in /usr/lib
# but MIT in /usr/local/lib and trying to build with KTH.
# /usr/local/lib can end up earlier on the link lines.
# Like most kludges, this one is not only inelegant it
# is also likely to be the wrong thing to do at least as
# many times as it is the right thing. Something better
# needs to be done.
#
if test "$use_gssapi" = "/usr" -a \
-f /usr/local/lib/libkrb5.a; then
FIX_KTH_VS_MIT=yes
fi
case "$FIX_KTH_VS_MIT" in
yes)
case "$enable_static_linking" in
yes) gssapi_lib_suffix=".a" ;;
*) gssapi_lib_suffix=".so" ;;
esac
for lib in $LIBS; do
case $lib in
-L*)
;;
-l*)
new_lib=`echo $lib |
sed -e s%^-l%$use_gssapi/lib/lib% \
-e s%$%$gssapi_lib_suffix%`
NEW_LIBS="$NEW_LIBS $new_lib"
;;
*)
AC_MSG_ERROR([KTH vs MIT Kerberos confusion!])
;;
esac
done
LIBS="$NEW_LIBS"
;;
esac
DST_GSSAPI_INC="-I$use_gssapi/include"
DNS_GSSAPI_LIBS="$LIBS"
AC_MSG_RESULT(using GSSAPI from $use_gssapi/lib and $use_gssapi/include)
LIBS="$saved_libs"
;;
esac
AC_SUBST(ISC_PLATFORM_HAVEGSSAPI)
AC_SUBST(ISC_PLATFORM_GSSAPIHEADER)
AC_SUBST(USE_GSSAPI)
AC_SUBST(DST_GSSAPI_INC)
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_GSSAPI_LIBS"
AC_SUBST(DNS_GSSAPI_LIBS)
DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_LIBS"
#
# Applications linking with libdns also need to link with these libraries.
@@ -1645,6 +1756,32 @@ AC_CHECK_FUNC(strerror, AC_DEFINE(HAVE_STRERROR))
AC_SUBST(ISC_EXTRA_OBJS)
AC_SUBST(ISC_EXTRA_SRCS)
#
# Use our own SPNEGO implementation?
#
AC_ARG_ENABLE(isc-spnego,
[ --disable-isc-spnego use SPNEGO from GSSAPI library])
if test -n "$USE_GSSAPI"
then
case "$enable_isc_spnego" in
yes|'')
USE_ISC_SPNEGO='-DUSE_ISC_SPNEGO'
DST_EXTRA_OBJS="$DST_EXTRA_OBJS spnego.$O"
DST_EXTRA_SRCS="$DST_EXTRA_SRCS spnego.c"
AC_MSG_RESULT(using SPNEGO from lib/dns)
;;
no)
AC_MSG_RESULT(using SPNEGO from GSSAPI library)
;;
esac
fi
AC_SUBST(USE_ISC_SPNEGO)
AC_SUBST(DST_EXTRA_OBJS)
AC_SUBST(DST_EXTRA_SRCS)
# Determine the printf format characters to use when printing
# values of type isc_int64_t. This will normally be "ll", but where
# the compiler treats "long long" as a alias for "long" and printf
@@ -2378,6 +2515,72 @@ else
BUILD_LIBS="$LIBS"
fi
NEWFLAGS=""
for e in $BUILD_LDFLAGS ; do
case $e in
-L*)
case $host_os in
netbsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
freebsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
esac
;;
*)
NEWFLAGS="$NEWFLAGS $e"
;;
esac
done
BUILD_LDFLAGS="$NEWFLAGS"
NEWFLAGS=""
for e in $DNS_GSSAPI_LIBS ; do
case $e in
-L*)
case $host_os in
netbsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
freebsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
esac
;;
*)
NEWFLAGS="$NEWFLAGS $e"
;;
esac
done
DNS_GSSAPI_LIBS="$NEWFLAGS"
NEWFLAGS=""
for e in $DNS_CRYPTO_LIBS ; do
case $e in
-L*)
case $host_os in
netbsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
freebsd*)
ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'`
NEWFLAGS="$NEWFLAGS $e $ee"
;;
esac
;;
*)
NEWFLAGS="$NEWFLAGS $e"
;;
esac
done
DNS_CRYPTO_LIBS="$NEWFLAGS"
AC_SUBST(BUILD_CC)
AC_SUBST(BUILD_CFLAGS)
AC_SUBST(BUILD_CPPFLAGS)

View File

@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.308 2006/09/13 00:15:37 marka Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.309 2006/12/04 01:52:45 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@@ -1619,10 +1619,15 @@ controls {
</para>
<para>
Dynamic update is enabled by
including an <command>allow-update</command> or
<command>update-policy</command> clause in the
<command>zone</command> statement.
Dynamic update is enabled by including an
<command>allow-update</command> or <command>update-policy</command>
clause in the <command>zone</command> statement. The
<command>tkey-gssapi-credential</command> and
<command>tkey-domain</command> clauses in the
<command>options</command> statement enable the
server to negotiate keys that can be matched against those
in <command>update-policy</command> or
<command>allow-update</command>.
</para>
<para>
@@ -2155,12 +2160,13 @@ allow-update { key host1-host2. ;};
<para>
This allows dynamic updates to succeed only if the request
was signed by a key named
"<command>host1-host2.</command>".
was signed by a key named "<command>host1-host2.</command>".
</para>
<para>
You may want to read about the more
powerful <command>update-policy</command> statement in <xref linkend="dynamic_update_policies"/>.
You may want to read about the more powerful
<command>update-policy</command> statement in
<xref linkend="dynamic_update_policies"/>.
</para>
</sect2>
@@ -4369,6 +4375,7 @@ category notify { null; };
<optional> directory <replaceable>path_name</replaceable>; </optional>
<optional> key-directory <replaceable>path_name</replaceable>; </optional>
<optional> named-xfer <replaceable>path_name</replaceable>; </optional>
<optional> tkey-gssapi-credential <replaceable>principal</replaceable>; </optional>
<optional> tkey-domain <replaceable>domainname</replaceable>; </optional>
<optional> tkey-dhkey <replaceable>key_name</replaceable> <replaceable>key_tag</replaceable>; </optional>
<optional> cache-file <replaceable>path_name</replaceable>; </optional>
@@ -4565,13 +4572,31 @@ category notify { null; };
<term><command>named-xfer</command></term>
<listitem>
<para>
<emphasis>This option is obsolete.</emphasis>
It was used in <acronym>BIND</acronym> 8 to
specify the pathname to the <command>named-xfer</command> program.
In <acronym>BIND</acronym> 9, no separate <command>named-xfer</command> program is
needed; its functionality is built into the name server.
<emphasis>This option is obsolete.</emphasis> It
was used in <acronym>BIND</acronym> 8 to specify
the pathname to the <command>named-xfer</command>
program. In <acronym>BIND</acronym> 9, no separate
<command>named-xfer</command> program is needed;
its functionality is built into the name server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>tkey-gssapi-credential</command></term>
<listitem>
<para>
The security credential with which the server should
authenticate keys requested by the GSS-TSIG protocol.
Currently only Kerberos 5 authentication is available
and the credential is a Kerberos principal which
the server can aquire through the default system
key file, normally <filename>/etc/krb5.keytab</filename>.
Normally this principal is of the form
"<userinput>dns/</userinput><varname>server.domain</varname>".
To use GSS-TSIG, <command>tkey-domain</command>
must also be set.
</para>
</listitem>
</varlistentry>
@@ -4579,20 +4604,20 @@ category notify { null; };
<term><command>tkey-domain</command></term>
<listitem>
<para>
The domain appended to the names of all
shared keys generated with
<command>TKEY</command>. When a client
requests a <command>TKEY</command> exchange, it
may or may not specify
the desired name for the key. If present, the name of the
shared
key will be "<varname>client specified part</varname>" +
"<varname>tkey-domain</varname>".
Otherwise, the name of the shared key will be "<varname>random hex
digits</varname>" + "<varname>tkey-domain</varname>". In most cases,
the <command>domainname</command> should be the
server's domain
name.
The domain appended to the names of all shared keys
generated with <command>TKEY</command>. When a
client requests a <command>TKEY</command> exchange,
it may or may not specify the desired name for the
key. If present, the name of the shared key will
will be <varname>client specified part</varname> +
<varname>tkey-domain</varname>. Otherwise, the
name of the shared key will be <varname>random hex
digits</varname> + <varname>tkey-domain</varname>.
In most cases, the <command>domainname</command>
should be the server's domain name, or an otherwise
non-existent subdomain like
"_tkey.<varname>domainname</varname>". If you are
using GSS-TSIG, this variable must be defined
</para>
</listitem>
</varlistentry>
@@ -8886,45 +8911,40 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</sect3>
<sect3 id="dynamic_update_policies">
<title>Dynamic Update Policies</title>
<para>
<acronym>BIND</acronym> 9 supports two alternative
methods of granting clients
the right to perform dynamic updates to a zone,
configured by the <command>allow-update</command>
and
<command>update-policy</command> option,
respectively.
<para><acronym>BIND</acronym> 9 supports two alternative
methods of granting clients the right to perform
dynamic updates to a zone, configured by the
<command>allow-update</command> and
<command>update-policy</command> option, respectively.
</para>
<para>
The <command>allow-update</command> clause works the
same
way as in previous versions of <acronym>BIND</acronym>. It grants given clients the
permission to update any record of any name in the zone.
same way as in previous versions of <acronym>BIND</acronym>.
It grants given clients the permission to update any
record of any name in the zone.
</para>
<para>
The <command>update-policy</command> clause is new
in <acronym>BIND</acronym>
9 and allows more fine-grained control over what updates are
allowed.
A set of rules is specified, where each rule either grants or
denies
permissions for one or more names to be updated by one or more
identities.
If the dynamic update request message is signed (that is, it
includes
either a TSIG or SIG(0) record), the identity of the signer can
be determined.
in <acronym>BIND</acronym> 9 and allows more fine-grained
control over what updates are allowed. A set of rules
is specified, where each rule either grants or denies
permissions for one or more names to be updated by
one or more identities. If the dynamic update request
message is signed (that is, it includes either a TSIG
or SIG(0) record), the identity of the signer can be
determined.
</para>
<para>
Rules are specified in the <command>update-policy</command> zone
option, and are only meaningful for master zones. When the <command>update-policy</command> statement
is present, it is a configuration error for the <command>allow-update</command> statement
to be present. The <command>update-policy</command>
statement only
examines the signer of a message; the source address is not
relevant.
Rules are specified in the <command>update-policy</command>
zone option, and are only meaningful for master zones.
When the <command>update-policy</command> statement
is present, it is a configuration error for the
<command>allow-update</command> statement to be
present. The <command>update-policy</command> statement
only examines the signer of a message; the source
address is not relevant.
</para>
<para>
This is how a rule definition looks:
</para>
@@ -8942,20 +8962,21 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
matches
the types specified in the type field.
</para>
<para>
The identity field specifies a name or a wildcard name.
Normally, this
is the name of the TSIG or SIG(0) key used to sign the update
request. When a
TKEY exchange has been used to create a shared secret, the
identity of the
shared secret is the same as the identity of the key used to
authenticate the
TKEY exchange. When the <replaceable>identity</replaceable> field specifies a
wildcard name, it is subject to DNS wildcard expansion, so the
rule will apply
to multiple identities. The <replaceable>identity</replaceable> field must
The identity field specifies a name or a wildcard
name. Normally, this is the name of the TSIG or
SIG(0) key used to sign the update request. When a
TKEY exchange has been used to create a shared secret,
the identity of the shared secret is the same as the
identity of the key used to authenticate the TKEY
exchange. TKEY is also the negotiation method used
by GSS-TSIG, which establishes an identity that is
the Kerberos principal of the client, such as
<userinput>"user@host.domain"</userinput>. When the
<replaceable>identity</replaceable> field specifies
a wildcard name, it is subject to DNS wildcard
expansion, so the rule will apply to multiple identities.
The <replaceable>identity</replaceable> field must
contain a fully qualified domain name.
</para>

View File

@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.154 2006/01/06 00:01:44 marka Exp $
# $Id: Makefile.in,v 1.155 2006/12/04 01:52:46 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -32,7 +32,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} \
${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@
CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@
CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@ @USE_ISC_SPNEGO@
CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@
@@ -43,7 +43,8 @@ LIBS = @LIBS@
# Alphabetically
DSTOBJS = dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
DSTOBJS = @DST_EXTRA_OBJS@ \
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ key.@O@ \
openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
opensslrsa_link.@O@
@@ -68,7 +69,8 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS}
# Alphabetically
DSTSRCS = dst_api.c dst_lib.c dst_parse.c \
DSTSRCS = @DST_EXTRA_SRCS@ \
dst_api.c dst_lib.c dst_parse.c \
dst_result.c gssapi_link.c gssapictx.c \
hmac_link.c key.c \
openssl_link.c openssldh_link.c \
@@ -169,3 +171,5 @@ subdirs: include/dns/enumtype.h include/dns/enumclass.h \
include/dns/rdatastruct.h code.h
${OBJS}: include/dns/enumtype.h include/dns/enumclass.h \
include/dns/rdatastruct.h
spnego.@O@: spnego_asn1.c spnego.h

View File

@@ -18,7 +18,7 @@
/*
* Principal Author: Brian Wellington
* $Id: dst_api.c,v 1.7 2006/01/27 23:57:46 marka Exp $
* $Id: dst_api.c,v 1.8 2006/12/04 01:52:46 marka Exp $
*/
/*! \file */
@@ -60,6 +60,8 @@ static isc_entropy_t *dst_entropy_pool = NULL;
static unsigned int dst_entropy_flags = 0;
static isc_boolean_t dst_initialized = ISC_FALSE;
void gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
isc_mem_t *dst__memory_pool = NULL;
/*
@@ -223,7 +225,7 @@ dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
if (key->func->createctx == NULL)
return (DST_R_UNSUPPORTEDALG);
if (key->opaque == NULL)
if (key->keydata.generic == NULL)
return (DST_R_NULLKEY);
dctx = isc_mem_get(mctx, sizeof(dst_context_t));
@@ -273,7 +275,7 @@ dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) {
key = dctx->key;
CHECKALG(key->key_alg);
if (key->opaque == NULL)
if (key->keydata.generic == NULL)
return (DST_R_NULLKEY);
if (key->func->sign == NULL)
return (DST_R_NOTPRIVATEKEY);
@@ -290,7 +292,7 @@ dst_context_verify(dst_context_t *dctx, isc_region_t *sig) {
REQUIRE(sig != NULL);
CHECKALG(dctx->key->key_alg);
if (dctx->key->opaque == NULL)
if (dctx->key->keydata.generic == NULL)
return (DST_R_NULLKEY);
if (dctx->key->func->verify == NULL)
return (DST_R_NOTPUBLICKEY);
@@ -309,7 +311,7 @@ dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
CHECKALG(pub->key_alg);
CHECKALG(priv->key_alg);
if (pub->opaque == NULL || priv->opaque == NULL)
if (pub->keydata.generic == NULL || priv->keydata.generic == NULL)
return (DST_R_NULLKEY);
if (pub->key_alg != priv->key_alg ||
@@ -383,10 +385,8 @@ dst_key_fromfile(dns_name_t *name, dns_keytag_t id,
return (result);
}
if (!dns_name_equal(name, key->key_name) ||
id != key->key_id ||
alg != key->key_alg)
{
if (!dns_name_equal(name, key->key_name) || id != key->key_id ||
alg != key->key_alg) {
dst_key_free(&key);
return (DST_R_INVALIDPRIVATEKEY);
}
@@ -427,8 +427,7 @@ dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
return (result);
if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC ||
(pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
{
(pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) {
result = computeid(pubkey);
if (result != ISC_R_SUCCESS) {
dst_key_free(&pubkey);
@@ -512,7 +511,7 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
& 0xffff));
}
if (key->opaque == NULL) /*%< NULL KEY */
if (key->keydata.generic == NULL) /*%< NULL KEY */
return (ISC_R_SUCCESS);
return (key->func->todns(key, target));
@@ -620,20 +619,29 @@ dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) {
return (result);
}
gss_ctx_id_t
dst_key_getgssctx(const dst_key_t *key)
{
REQUIRE(key != NULL);
return (key->keydata.gssctx);
}
isc_result_t
dst_key_fromgssapi(dns_name_t *name, void *opaque, isc_mem_t *mctx,
dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
dst_key_t **keyp)
{
dst_key_t *key;
REQUIRE(opaque != NULL);
REQUIRE(gssctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL);
key = get_key_struct(name, DST_ALG_GSSAPI, 0, DNS_KEYPROTO_DNSSEC,
0, dns_rdataclass_in, mctx);
if (key == NULL)
return (ISC_R_NOMEMORY);
key->opaque = opaque;
key->keydata.gssctx = gssctx;
*keyp = key;
return (ISC_R_SUCCESS);
}
@@ -734,7 +742,7 @@ dst_key_free(dst_key_t **keyp) {
key = *keyp;
mctx = key->mctx;
if (key->opaque != NULL) {
if (key->keydata.generic != NULL) {
INSIST(key->func->destroy != NULL);
key->func->destroy(key);
}
@@ -860,7 +868,7 @@ get_key_struct(dns_name_t *name, unsigned int alg,
key->key_flags = flags;
key->key_proto = protocol;
key->mctx = mctx;
key->opaque = NULL;
key->keydata.generic = NULL;
key->key_size = bits;
key->key_class = rdclass;
key->func = dst_t_func[alg];
@@ -1116,8 +1124,10 @@ buildfilename(dns_name_t *name, dns_keytag_t id,
len = 1 + 3 + 1 + 5 + strlen(suffix) + 1;
if (isc_buffer_availablelength(out) < len)
return (ISC_R_NOSPACE);
sprintf((char *) isc_buffer_used(out), "+%03d+%05d%s", alg, id, suffix);
sprintf((char *) isc_buffer_used(out), "+%03d+%05d%s", alg, id,
suffix);
isc_buffer_add(out, len);
return (ISC_R_SUCCESS);
}
@@ -1219,3 +1229,8 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
flags &= ~ISC_ENTROPY_GOODONLY;
return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
}
unsigned int
dst__entropy_status(void) {
return (isc_entropy_status(dst_entropy_pool));
}

View File

@@ -16,7 +16,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dst_internal.h,v 1.5 2006/01/27 23:57:46 marka Exp $ */
/* $Id: dst_internal.h,v 1.6 2006/12/04 01:52:46 marka Exp $ */
#ifndef DST_DST_INTERNAL_H
#define DST_DST_INTERNAL_H 1
@@ -27,9 +27,21 @@
#include <isc/magic.h>
#include <isc/region.h>
#include <isc/types.h>
#include <isc/md5.h>
#include <isc/sha1.h>
#include <isc/hmacmd5.h>
#include <isc/hmacsha.h>
#include <dst/dst.h>
#ifdef OPENSSL
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/rsa.h>
#endif
ISC_LANG_BEGINDECLS
#define KEY_MAGIC ISC_MAGIC('D','S','T','K')
@@ -46,6 +58,13 @@ extern isc_mem_t *dst__memory_pool;
typedef struct dst_func dst_func_t;
typedef struct dst_hmacmd5_key dst_hmacmd5_key_t;
typedef struct dst_hmacsha1_key dst_hmacsha1_key_t;
typedef struct dst_hmacsha224_key dst_hmacsha224_key_t;
typedef struct dst_hmacsha256_key dst_hmacsha256_key_t;
typedef struct dst_hmacsha384_key dst_hmacsha384_key_t;
typedef struct dst_hmacsha512_key dst_hmacsha512_key_t;
/*% DST Key Structure */
struct dst_key {
unsigned int magic;
@@ -58,7 +77,22 @@ struct dst_key {
isc_uint16_t key_bits; /*%< hmac digest bits */
dns_rdataclass_t key_class; /*%< class of the key record */
isc_mem_t *mctx; /*%< memory context */
void * opaque; /*%< pointer to key in crypto pkg fmt */
union {
void *generic;
gss_ctx_id_t gssctx;
#ifdef OPENSSL
RSA *rsa;
DSA *dsa;
DH *dh;
#endif
dst_hmacmd5_key_t *hmacmd5;
dst_hmacsha1_key_t *hmacsha1;
dst_hmacsha224_key_t *hmacsha224;
dst_hmacsha256_key_t *hmacsha256;
dst_hmacsha384_key_t *hmacsha384;
dst_hmacsha512_key_t *hmacsha512;
} keydata; /*%< pointer to key in crypto pkg fmt */
dst_func_t * func; /*%< crypto package specific functions */
};
@@ -66,7 +100,18 @@ struct dst_context {
unsigned int magic;
dst_key_t *key;
isc_mem_t *mctx;
void *opaque;
union {
void *generic;
dst_gssapi_signverifyctx_t *gssctx;
isc_md5_t *md5ctx;
isc_sha1_t *sha1ctx;
isc_hmacmd5_t *hmacmd5ctx;
isc_hmacsha1_t *hmacsha1ctx;
isc_hmacsha224_t *hmacsha224ctx;
isc_hmacsha256_t *hmacsha256ctx;
isc_hmacsha384_t *hmacsha384ctx;
isc_hmacsha512_t *hmacsha512ctx;
} ctxdata;
};
struct dst_func {
@@ -136,6 +181,11 @@ void * dst__mem_realloc(void *ptr, size_t size);
isc_result_t dst__entropy_getdata(void *buf, unsigned int len,
isc_boolean_t pseudo);
/*
* Entropy status hook.
*/
unsigned int dst__entropy_status(void);
ISC_LANG_ENDDECLS
#endif /* DST_DST_INTERNAL_H */

View File

@@ -16,13 +16,13 @@
*/
/*
* $Id: gssapi_link.c,v 1.3 2005/04/29 00:22:47 marka Exp $
* $Id: gssapi_link.c,v 1.4 2006/12/04 01:52:46 marka Exp $
*/
#ifdef GSSAPI
#include <config.h>
#ifdef GSSAPI
#include <isc/buffer.h>
#include <isc/mem.h>
#include <isc/string.h>
@@ -33,7 +33,7 @@
#include "dst_internal.h"
#include "dst_parse.h"
#include <gssapi/gssapi.h>
#include <dst/gssapi.h>
#define INITIAL_BUFFER_SIZE 1024
#define BUFFER_EXTRA 1024
@@ -44,49 +44,62 @@
(gb).value = (r).base; \
} while (0)
typedef struct gssapi_ctx {
struct dst_gssapi_signverifyctx {
isc_buffer_t *buffer;
gss_ctx_id_t *context_id;
} gssapi_ctx_t;
};
/*%
* Allocate a temporary "context" for use in gathering data for signing
* or verifying.
*/
static isc_result_t
gssapi_createctx(dst_key_t *key, dst_context_t *dctx) {
gssapi_ctx_t *ctx;
gssapi_create_signverify_ctx(dst_key_t *key, dst_context_t *dctx) {
dst_gssapi_signverifyctx_t *ctx;
isc_result_t result;
UNUSED(key);
ctx = isc_mem_get(dctx->mctx, sizeof(gssapi_ctx_t));
ctx = isc_mem_get(dctx->mctx, sizeof(dst_gssapi_signverifyctx_t));
if (ctx == NULL)
return (ISC_R_NOMEMORY);
ctx->buffer = NULL;
result = isc_buffer_allocate(dctx->mctx, &ctx->buffer,
INITIAL_BUFFER_SIZE);
if (result != ISC_R_SUCCESS) {
isc_mem_put(dctx->mctx, ctx, sizeof(gssapi_ctx_t));
isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t));
return (result);
}
ctx->context_id = key->opaque;
dctx->opaque = ctx;
dctx->ctxdata.gssctx = ctx;
return (ISC_R_SUCCESS);
}
/*%
* Destroy the temporary sign/verify context.
*/
static void
gssapi_destroyctx(dst_context_t *dctx) {
gssapi_ctx_t *ctx = dctx->opaque;
gssapi_destroy_signverify_ctx(dst_context_t *dctx) {
dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
if (ctx != NULL) {
if (ctx->buffer != NULL)
isc_buffer_free(&ctx->buffer);
isc_mem_put(dctx->mctx, ctx, sizeof(gssapi_ctx_t));
dctx->opaque = NULL;
isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t));
dctx->ctxdata.gssctx = NULL;
}
}
/*%
* Add data to our running buffer of data we will be signing or verifying.
* This code will see if the new data will fit in our existing buffer, and
* copy it in if it will. If not, it will attempt to allocate a larger
* buffer and copy old+new into it, and free the old buffer.
*/
static isc_result_t
gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) {
gssapi_ctx_t *ctx = dctx->opaque;
dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
isc_buffer_t *newbuffer = NULL;
isc_region_t r;
unsigned int length;
@@ -112,56 +125,128 @@ gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) {
return (ISC_R_SUCCESS);
}
/*%
* Sign.
*/
static isc_result_t
gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) {
gssapi_ctx_t *ctx = dctx->opaque;
dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
isc_region_t message;
gss_buffer_desc gmessage, gsig;
OM_uint32 minor, gret;
gss_ctx_id_t gssctx = dctx->key->keydata.gssctx;
char buf[1024];
/*
* Convert the data we wish to sign into a structure gssapi can
* understand.
*/
isc_buffer_usedregion(ctx->buffer, &message);
REGION_TO_GBUFFER(message, gmessage);
gret = gss_get_mic(&minor, ctx->context_id,
GSS_C_QOP_DEFAULT, &gmessage, &gsig);
if (gret != 0)
return (ISC_R_FAILURE);
/*
* Generate the signature.
*/
gret = gss_get_mic(&minor, gssctx, GSS_C_QOP_DEFAULT, &gmessage,
&gsig);
/*
* If it did not complete, we log the result and return a generic
* failure code.
*/
if (gret != GSS_S_COMPLETE) {
gss_log(3, "GSS sign error: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
return (ISC_R_FAILURE);
}
/*
* If it will not fit in our allocated buffer, return that we need
* more space.
*/
if (gsig.length > isc_buffer_availablelength(sig)) {
gss_release_buffer(&minor, &gsig);
return (ISC_R_NOSPACE);
}
/*
* Copy the output into our buffer space, and release the gssapi
* allocated space.
*/
isc_buffer_putmem(sig, gsig.value, gsig.length);
gss_release_buffer(&minor, &gsig);
return (ISC_R_SUCCESS);
}
/*%
* Verify.
*/
static isc_result_t
gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) {
gssapi_ctx_t *ctx = dctx->opaque;
isc_region_t message;
dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
isc_region_t message, r;
gss_buffer_desc gmessage, gsig;
OM_uint32 minor, gret;
gss_ctx_id_t gssctx = dctx->key->keydata.gssctx;
unsigned char *buf;
char err[1024];
/*
* Convert the data we wish to sign into a structure gssapi can
* understand.
*/
isc_buffer_usedregion(ctx->buffer, &message);
REGION_TO_GBUFFER(message, gmessage);
REGION_TO_GBUFFER(*sig, gsig);
gret = gss_verify_mic(&minor, ctx->context_id, &gmessage, &gsig, NULL);
if (gret != 0)
/*
* XXXMLG
* It seem that gss_verify_mic() modifies the signature buffer,
* at least on Heimdal's implementation. Copy it here to an allocated
* buffer.
*/
buf = isc_mem_allocate(dst__memory_pool, sig->length);
if (buf == NULL)
return (ISC_R_FAILURE);
memcpy(buf, sig->base, sig->length);
r.base = buf;
r.length = sig->length;
REGION_TO_GBUFFER(r, gsig);
/*
* Verify the data.
*/
gret = gss_verify_mic(&minor, gssctx, &gmessage, &gsig, NULL);
isc_mem_free(dst__memory_pool, buf);
/*
* Convert return codes into something useful to us.
*/
if (gret != GSS_S_COMPLETE) {
gss_log(3, "GSS verify error: %s",
gss_error_tostring(gret, minor, err, sizeof(err)));
if (gret == GSS_S_DEFECTIVE_TOKEN ||
gret == GSS_S_BAD_SIG ||
gret == GSS_S_DUPLICATE_TOKEN ||
gret == GSS_S_OLD_TOKEN ||
gret == GSS_S_UNSEQ_TOKEN ||
gret == GSS_S_GAP_TOKEN ||
gret == GSS_S_CONTEXT_EXPIRED ||
gret == GSS_S_NO_CONTEXT ||
gret == GSS_S_FAILURE)
return(DST_R_VERIFYFAILURE);
else
return (ISC_R_FAILURE);
}
return (ISC_R_SUCCESS);
}
static isc_boolean_t
gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) {
gss_ctx_id_t gsskey1 = key1->opaque;
gss_ctx_id_t gsskey2 = key2->opaque;
gss_ctx_id_t gsskey1 = key1->keydata.gssctx;
gss_ctx_id_t gsskey2 = key2->keydata.gssctx;
/* No idea */
return (ISC_TF(gsskey1 == gsskey2));
@@ -184,13 +269,14 @@ gssapi_isprivate(const dst_key_t *key) {
static void
gssapi_destroy(dst_key_t *key) {
UNUSED(key);
/* No idea */
REQUIRE(key != NULL);
dst_gssapi_deletectx(key->mctx, &key->keydata.gssctx);
key->keydata.gssctx = NULL;
}
static dst_func_t gssapi_functions = {
gssapi_createctx,
gssapi_destroyctx,
gssapi_create_signverify_ctx,
gssapi_destroy_signverify_ctx,
gssapi_adddata,
gssapi_sign,
gssapi_verify,

View File

@@ -15,11 +15,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: gssapictx.c,v 1.3 2005/04/29 00:22:47 marka Exp $ */
/* $Id: gssapictx.c,v 1.4 2006/12/04 01:52:46 marka Exp $ */
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <isc/buffer.h>
#include <isc/dir.h>
@@ -39,21 +40,55 @@
#include <dns/result.h>
#include <dns/types.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dst/gssapi.h>
#include <dst/result.h>
#include "dst_internal.h"
#ifdef GSSAPI
/*
* If we're using our own SPNEGO implementation (see configure.in),
* pull it in now. Otherwise, we just use whatever GSSAPI supplies.
*/
#if defined(GSSAPI) && defined(USE_ISC_SPNEGO)
#include "spnego.h"
#define gss_accept_sec_context gss_accept_sec_context_spnego
#define gss_init_sec_context gss_init_sec_context_spnego
#endif
#include <gssapi/gssapi.h>
/*
* Solaris8 apparently needs an explicit OID set, and Solaris10 needs
* one for anything but Kerberos. Supplying an explicit OID set
* doesn't appear to hurt anything in other implementations, so we
* always use one. If we're not using our own SPNEGO implementation,
* we include SPNEGO's OID.
*/
#if defined(GSSAPI)
#define RETERR(x) do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
goto out; \
} while (0)
static unsigned char krb5_mech_oid_bytes[] = {
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02
};
#ifndef USE_ISC_SPNEGO
static unsigned char spnego_mech_oid_bytes[] = {
0x2b, 0x06, 0x01, 0x05, 0x05, 0x02
};
#endif
static gss_OID_desc mech_oid_set_array[] = {
{ sizeof(krb5_mech_oid_bytes), krb5_mech_oid_bytes },
#ifndef USE_ISC_SPNEGO
{ sizeof(spnego_mech_oid_bytes), spnego_mech_oid_bytes },
#endif
};
static gss_OID_set_desc mech_oid_set = {
sizeof(mech_oid_set_array) / sizeof(*mech_oid_set_array),
mech_oid_set_array
};
#endif
#define REGION_TO_GBUFFER(r, gb) \
do { \
@@ -67,6 +102,14 @@
(r).base = (gb).value; \
} while (0)
#define RETERR(x) do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
goto out; \
} while (0)
#ifdef GSSAPI
static inline void
name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer,
gss_buffer_desc *gbuffer)
@@ -77,7 +120,8 @@ name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer,
if (!dns_name_isabsolute(name))
namep = name;
else {
else
{
unsigned int labels;
dns_name_init(&tname, NULL);
labels = dns_name_countlabels(name);
@@ -91,8 +135,64 @@ name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer,
REGION_TO_GBUFFER(r, *gbuffer);
}
static void
log_cred(const gss_cred_id_t cred) {
OM_uint32 gret, minor, lifetime;
gss_name_t gname;
gss_buffer_desc gbuffer;
gss_cred_usage_t usage;
const char *usage_text;
char buf[1024];
gret = gss_inquire_cred(&minor, cred, &gname, &lifetime, &usage, NULL);
if (gret != GSS_S_COMPLETE) {
gss_log(3, "failed gss_inquire_cred: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
return;
}
gret = gss_display_name(&minor, gname, &gbuffer, NULL);
if (gret != GSS_S_COMPLETE)
gss_log(3, "failed gss_display_name: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
else {
switch (usage) {
case GSS_C_BOTH:
usage_text = "GSS_C_BOTH";
break;
case GSS_C_INITIATE:
usage_text = "GSS_C_INITIATE";
break;
case GSS_C_ACCEPT:
usage_text = "GSS_C_ACCEPT";
break;
default:
usage_text = "???";
}
gss_log(3, "gss cred: \"%s\", %s, %lu", (char *)gbuffer.value,
usage_text, (unsigned long)lifetime);
}
if (gret == GSS_S_COMPLETE) {
gret = gss_release_buffer(&minor, &gbuffer);
if (gret != GSS_S_COMPLETE)
gss_log(3, "failed gss_release_buffer: %s",
gss_error_tostring(gret, minor, buf,
sizeof(buf)));
}
gret = gss_release_name(&minor, &gname);
if (gret != GSS_S_COMPLETE)
gss_log(3, "failed gss_release_name: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
}
#endif
isc_result_t
dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) {
dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
gss_cred_id_t *cred)
{
#ifdef GSSAPI
isc_buffer_t namebuf;
gss_name_t gname;
gss_buffer_desc gnamebuf;
@@ -101,164 +201,527 @@ dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) {
gss_OID_set mechs;
OM_uint32 lifetime;
gss_cred_usage_t usage;
char buf[1024];
REQUIRE(cred != NULL && *cred == NULL);
/*
* XXXSRA In theory we could use GSS_C_NT_HOSTBASED_SERVICE
* here when we're in the acceptor role, which would let us
* default the hostname and use a compiled in default service
* name of "DNS", giving one less thing to configure in
* named.conf. Unfortunately, this creates a circular
* dependency due to DNS-based realm lookup in at least one
* GSSAPI implementation (Heimdal). Oh well.
*/
if (name != NULL) {
isc_buffer_init(&namebuf, array, sizeof(array));
name_to_gbuffer(name, &namebuf, &gnamebuf);
gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID,
&gname);
if (gret != GSS_S_COMPLETE)
gret = gss_import_name(&minor, &gnamebuf,
GSS_C_NO_OID, &gname);
if (gret != GSS_S_COMPLETE) {
gss_log(3, "failed gss_import_name: %s",
gss_error_tostring(gret, minor, buf,
sizeof(buf)));
return (ISC_R_FAILURE);
}
} else
gname = NULL;
/* Get the credentials. */
if (gname != NULL)
gss_log(3, "acquiring credentials for %s",
(char *)gnamebuf.value);
else {
/* XXXDCL does this even make any sense? */
gss_log(3, "acquiring credentials for ?");
}
if (initiate)
usage = GSS_C_INITIATE;
else
usage = GSS_C_ACCEPT;
gret = gss_acquire_cred(&minor, gname, GSS_C_INDEFINITE,
GSS_C_NO_OID_SET, usage,
cred, &mechs, &lifetime);
if (gret != GSS_S_COMPLETE)
&mech_oid_set,
usage, cred, &mechs, &lifetime);
if (gret != GSS_S_COMPLETE) {
gss_log(3, "failed to acquire %s credentials for %s: %s",
initiate ? "initiate" : "accept",
(char *)gnamebuf.value,
gss_error_tostring(gret, minor, buf, sizeof(buf)));
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
}
isc_result_t
dst_gssapi_initctx(dns_name_t *name, void *cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
void **context)
{
isc_region_t r;
isc_buffer_t namebuf;
gss_buffer_desc gnamebuf, gintoken, *gintokenp, gouttoken;
OM_uint32 gret, minor, flags, ret_flags;
gss_OID mech_type, ret_mech_type;
OM_uint32 lifetime;
gss_name_t gname;
isc_result_t result;
unsigned char array[DNS_NAME_MAXTEXT + 1];
gss_log(4, "acquired %s credentials for %s",
initiate ? "initiate" : "accept",
(char *)gnamebuf.value);
isc_buffer_init(&namebuf, array, sizeof(array));
name_to_gbuffer(name, &namebuf, &gnamebuf);
gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
if (gret != GSS_S_COMPLETE)
return (ISC_R_FAILURE);
if (intoken != NULL) {
REGION_TO_GBUFFER(*intoken, gintoken);
gintokenp = &gintoken;
} else
gintokenp = NULL;
if (*context == NULL)
*context = GSS_C_NO_CONTEXT;
flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG |
GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG;
mech_type = GSS_C_NO_OID;
gret = gss_init_sec_context(&minor, cred, context, gname,
mech_type, flags, 0,
GSS_C_NO_CHANNEL_BINDINGS, gintokenp,
&ret_mech_type, &gouttoken, &ret_flags,
&lifetime);
if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED)
return (ISC_R_FAILURE);
GBUFFER_TO_REGION(gouttoken, r);
RETERR(isc_buffer_copyregion(outtoken, &r));
if (gret == GSS_S_COMPLETE)
return (ISC_R_SUCCESS);
else
return (DNS_R_CONTINUE);
out:
return (result);
}
isc_result_t
dst_gssapi_acceptctx(dns_name_t *name, void *cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
void **context)
{
isc_region_t r;
isc_buffer_t namebuf;
gss_buffer_desc gnamebuf, gintoken, gouttoken;
OM_uint32 gret, minor, flags;
gss_OID mech_type;
OM_uint32 lifetime;
gss_cred_id_t delegated_cred;
gss_name_t gname;
isc_result_t result;
unsigned char array[DNS_NAME_MAXTEXT + 1];
isc_buffer_init(&namebuf, array, sizeof(array));
name_to_gbuffer(name, &namebuf, &gnamebuf);
gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
if (gret != GSS_S_COMPLETE)
return (ISC_R_FAILURE);
REGION_TO_GBUFFER(*intoken, gintoken);
if (*context == NULL)
*context = GSS_C_NO_CONTEXT;
gret = gss_accept_sec_context(&minor, context, cred, &gintoken,
GSS_C_NO_CHANNEL_BINDINGS, gname,
&mech_type, &gouttoken, &flags,
&lifetime, &delegated_cred);
if (gret != GSS_S_COMPLETE)
return (ISC_R_FAILURE);
GBUFFER_TO_REGION(gouttoken, r);
RETERR(isc_buffer_copyregion(outtoken, &r));
log_cred(*cred);
return (ISC_R_SUCCESS);
out:
return (result);
}
#else
isc_result_t
dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) {
UNUSED(name);
UNUSED(initiate);
UNUSED(cred);
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
dst_gssapi_initctx(dns_name_t *name, void *cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
void **context)
{
UNUSED(name);
UNUSED(cred);
UNUSED(intoken);
UNUSED(outtoken);
UNUSED(context);
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
dst_gssapi_acceptctx(dns_name_t *name, void *cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
void **context)
{
UNUSED(name);
UNUSED(cred);
UNUSED(intoken);
UNUSED(outtoken);
UNUSED(context);
return (ISC_R_NOTIMPLEMENTED);
}
#endif
}
isc_boolean_t
dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
dns_name_t *realm)
{
#ifdef GSSAPI
char sbuf[DNS_NAME_FORMATSIZE];
char nbuf[DNS_NAME_FORMATSIZE];
char rbuf[DNS_NAME_FORMATSIZE];
char *sname;
char *rname;
/*
* It is far, far easier to write the names we are looking at into
* a string, and do string operations on them.
*/
dns_name_format(signer, sbuf, sizeof(sbuf));
if (name != NULL)
dns_name_format(name, nbuf, sizeof(nbuf));
dns_name_format(realm, rbuf, sizeof(rbuf));
/*
* Find the realm portion. This is the part after the @. If it
* does not exist, we don't have something we like, so we fail our
* compare.
*/
rname = strstr(sbuf, "\\@");
if (rname == NULL)
return (isc_boolean_false);
*rname = '\0';
rname += 2;
/*
* Find the host portion of the signer's name. We do this by
* searching for the first / character. We then check to make
* certain the instance name is "host"
*
* This will work for
* host/example.com@EXAMPLE.COM
*/
sname = strchr(sbuf, '/');
if (sname == NULL)
return (isc_boolean_false);
*sname = '\0';
sname++;
if (strcmp(sbuf, "host") != 0)
return (isc_boolean_false);
/*
* Now, we do a simple comparison between the name and the realm.
*/
if (name != NULL) {
if ((strcasecmp(sname, nbuf) == 0)
&& (strcmp(rname, rbuf) == 0))
return (isc_boolean_true);
} else {
if (strcmp(rname, rbuf) == 0)
return (isc_boolean_true);
}
return (isc_boolean_false);
#else
UNUSED(signer);
UNUSED(name);
UNUSED(realm);
return (isc_boolean_false);
#endif
}
isc_boolean_t
dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
dns_name_t *realm)
{
#ifdef GSSAPI
char sbuf[DNS_NAME_FORMATSIZE];
char nbuf[DNS_NAME_FORMATSIZE];
char rbuf[DNS_NAME_FORMATSIZE];
char *sname;
char *nname;
char *rname;
/*
* It is far, far easier to write the names we are looking at into
* a string, and do string operations on them.
*/
dns_name_format(signer, sbuf, sizeof(sbuf));
if (name != NULL)
dns_name_format(name, nbuf, sizeof(nbuf));
dns_name_format(realm, rbuf, sizeof(rbuf));
/*
* Find the realm portion. This is the part after the @. If it
* does not exist, we don't have something we like, so we fail our
* compare.
*/
rname = strstr(sbuf, "\\@");
if (rname == NULL)
return (isc_boolean_false);
sname = strstr(sbuf, "\\$");
if (sname == NULL)
return (isc_boolean_false);
/*
* Verify that the $ and @ follow one another.
*/
if (rname - sname != 2)
return (isc_boolean_false);
/*
* Find the host portion of the signer's name. Zero out the $ so
* it terminates the signer's name, and skip past the @ for
* the realm.
*
* All service principals in Microsoft format seem to be in
* machinename$@EXAMPLE.COM
* format.
*/
*rname = '\0';
rname += 2;
*sname = '\0';
sname = sbuf;
/*
* Find the first . in the target name, and make it the end of
* the string. The rest of the name has to match the realm.
*/
if (name != NULL) {
nname = strchr(nbuf, '.');
if (nname == NULL)
return (isc_boolean_false);
*nname++ = '\0';
}
/*
* Now, we do a simple comparison between the name and the realm.
*/
if (name != NULL) {
if ((strcasecmp(sname, nbuf) == 0)
&& (strcmp(rname, rbuf) == 0)
&& (strcasecmp(nname, rbuf) == 0))
return (isc_boolean_true);
} else {
if (strcmp(rname, rbuf) == 0)
return (isc_boolean_true);
}
return (isc_boolean_false);
#else
UNUSED(signer);
UNUSED(name);
UNUSED(realm);
return (isc_boolean_false);
#endif
}
isc_result_t
dst_gssapi_releasecred(gss_cred_id_t *cred) {
#ifdef GSSAPI
OM_uint32 gret, minor;
char buf[1024];
REQUIRE(cred != NULL && *cred != NULL);
gret = gss_release_cred(&minor, cred);
if (gret != GSS_S_COMPLETE) {
/* Log the error, but still free the credential's memory */
gss_log(3, "failed releasing credential: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
}
*cred = NULL;
return(ISC_R_SUCCESS);
#else
UNUSED(cred);
return (ISC_R_NOTIMPLEMENTED);
#endif
}
isc_result_t
dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
isc_buffer_t *outtoken, gss_ctx_id_t *gssctx)
{
#ifdef GSSAPI
isc_region_t r;
isc_buffer_t namebuf;
gss_name_t gname;
OM_uint32 gret, minor, ret_flags, flags;
gss_buffer_desc gintoken, *gintokenp, gouttoken;
isc_result_t result;
gss_buffer_desc gnamebuf;
unsigned char array[DNS_NAME_MAXTEXT + 1];
char buf[1024];
/* Client must pass us a valid gss_ctx_id_t here */
REQUIRE(gssctx != NULL);
isc_buffer_init(&namebuf, array, sizeof(array));
name_to_gbuffer(name, &namebuf, &gnamebuf);
/* Get the name as a GSS name */
gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
if (gret != GSS_S_COMPLETE) {
result = ISC_R_FAILURE;
goto out;
}
if (intoken != NULL) {
/* Don't call gss_release_buffer for gintoken! */
REGION_TO_GBUFFER(*intoken, gintoken);
gintokenp = &gintoken;
} else {
gintokenp = NULL;
}
flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG |
GSS_C_SEQUENCE_FLAG | GSS_C_INTEG_FLAG;
gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx,
gname, GSS_SPNEGO_MECHANISM, flags,
0, NULL, gintokenp,
NULL, &gouttoken, &ret_flags, NULL);
if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) {
gss_log(3, "Failure initiating security context");
gss_log(3, "%s", gss_error_tostring(gret, minor,
buf, sizeof(buf)));
result = ISC_R_FAILURE;
goto out;
}
/*
* XXXSRA Not handled yet: RFC 3645 3.1.1: check ret_flags
* MUTUAL and INTEG flags, fail if either not set.
*/
GBUFFER_TO_REGION(gouttoken, r);
RETERR(isc_buffer_copyregion(outtoken, &r));
(void)gss_release_name(&minor, &gname);
(void)gss_release_buffer(&minor, &gouttoken);
if (gret == GSS_S_COMPLETE)
result = ISC_R_SUCCESS;
else
result = DNS_R_CONTINUE;
out:
return (result);
#else
UNUSED(name);
UNUSED(intoken);
UNUSED(outtoken);
UNUSED(gssctx);
return (ISC_R_NOTIMPLEMENTED);
#endif
}
isc_result_t
dst_gssapi_acceptctx(gss_cred_id_t cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
gss_ctx_id_t *ctxout, dns_name_t *principal,
isc_mem_t *mctx)
{
#ifdef GSSAPI
isc_region_t r;
isc_buffer_t namebuf;
gss_buffer_desc gnamebuf, gintoken, gouttoken;
OM_uint32 gret, minor;
gss_ctx_id_t context = GSS_C_NO_CONTEXT;
gss_name_t gname = NULL;
isc_result_t result;
char buf[1024];
log_cred(cred);
REGION_TO_GBUFFER(*intoken, gintoken);
if (*ctxout == NULL)
context = GSS_C_NO_CONTEXT;
else
context = *ctxout;
gret = gss_accept_sec_context(&minor, &context, cred, &gintoken,
GSS_C_NO_CHANNEL_BINDINGS, &gname,
NULL, &gouttoken, NULL, NULL, NULL);
result = ISC_R_FAILURE;
switch (gret) {
case GSS_S_COMPLETE:
result = ISC_R_SUCCESS;
break;
case GSS_S_CONTINUE_NEEDED:
result = DNS_R_CONTINUE;
break;
case GSS_S_DEFECTIVE_TOKEN:
case GSS_S_DEFECTIVE_CREDENTIAL:
case GSS_S_BAD_SIG:
case GSS_S_DUPLICATE_TOKEN:
case GSS_S_OLD_TOKEN:
case GSS_S_NO_CRED:
case GSS_S_CREDENTIALS_EXPIRED:
case GSS_S_BAD_BINDINGS:
case GSS_S_NO_CONTEXT:
case GSS_S_BAD_MECH:
case GSS_S_FAILURE:
result = DNS_R_INVALIDTKEY;
/* fall through */
default:
gss_log(3, "failed gss_accept_sec_context: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
return (result);
}
INSIST(outtoken != NULL && !ISC_BUFFER_VALID(outtoken));
if (gouttoken.length > 0) {
void *o = isc_mem_get(mctx, gouttoken.length);
if (o == NULL)
RETERR(ISC_R_NOMEMORY);
isc_buffer_init(outtoken, o, gouttoken.length);
GBUFFER_TO_REGION(gouttoken, r);
RETERR(isc_buffer_copyregion(outtoken, &r));
}
if (gret == GSS_S_COMPLETE) {
gret = gss_display_name(&minor, gname, &gnamebuf, NULL);
if (gret != GSS_S_COMPLETE) {
gss_log(3, "failed gss_display_name: %s",
gss_error_tostring(gret, minor,
buf, sizeof(buf)));
RETERR(ISC_R_FAILURE);
}
/*
* Compensate for a bug in Solaris8's implementation
* of gss_display_name(). Should be harmless in any
* case, since principal names really should not
* contain null characters.
*/
if (gnamebuf.length > 0 &&
((char *)gnamebuf.value)[gnamebuf.length - 1] == '\0')
gnamebuf.length--;
gss_log(3, "gss-api source name (accept) is %.*s",
(int)gnamebuf.length, (char *)gnamebuf.value);
GBUFFER_TO_REGION(gnamebuf, r);
isc_buffer_init(&namebuf, r.base, r.length);
isc_buffer_add(&namebuf, r.length);
RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname,
ISC_FALSE, NULL));
gret = gss_release_buffer(&minor, &gnamebuf);
if (gret != GSS_S_COMPLETE)
gss_log(3, "failed gss_release_buffer: %s",
gss_error_tostring(gret, minor, buf,
sizeof(buf)));
}
*ctxout = context;
out:
if (gname != NULL) {
gret = gss_release_name(&minor, &gname);
if (gret != GSS_S_COMPLETE)
gss_log(3, "failed gss_release_name: %s",
gss_error_tostring(gret, minor, buf,
sizeof(buf)));
}
return (result);
#else
UNUSED(cred);
UNUSED(intoken);
UNUSED(outtoken);
UNUSED(ctxout);
UNUSED(principal);
UNUSED(mctx);
return (ISC_R_NOTIMPLEMENTED);
#endif
}
isc_result_t
dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx)
{
#ifdef GSSAPI
OM_uint32 gret, minor;
char buf[1024];
UNUSED(mctx);
REQUIRE(gssctx != NULL && *gssctx != NULL);
/* Delete the context from the GSS provider */
gret = gss_delete_sec_context(&minor, gssctx, GSS_C_NO_BUFFER);
if (gret != GSS_S_COMPLETE) {
/* Log the error, but still free the context's memory */
gss_log(3, "Failure deleting security context %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
}
return(ISC_R_SUCCESS);
#else
UNUSED(mctx);
UNUSED(gssctx);
return (ISC_R_NOTIMPLEMENTED);
#endif
}
char *
gss_error_tostring(isc_uint32_t major, isc_uint32_t minor,
char *buf, size_t buflen) {
#ifdef GSSAPI
gss_buffer_desc msg_minor, msg_major;
OM_uint32 msg_ctx, minor_stat;
/* Handle major status */
msg_ctx = 0;
(void)gss_display_status(&minor_stat, major, GSS_C_GSS_CODE,
GSS_C_NULL_OID, &msg_ctx, &msg_major);
/* Handle minor status */
msg_ctx = 0;
(void)gss_display_status(&minor_stat, minor, GSS_C_MECH_CODE,
GSS_C_NULL_OID, &msg_ctx, &msg_minor);
snprintf(buf, buflen, "GSSAPI error: Major = %s, Minor = %s.",
(char *)msg_major.value, (char *)msg_minor.value);
(void)gss_release_buffer(&minor_stat, &msg_major);
(void)gss_release_buffer(&minor_stat, &msg_minor);
return(buf);
#else
snprintf(buf, buflen, "GSSAPI error: Major = %u, Minor = %u.",
major, minor);
return (buf);
#endif
}
void
gss_log(int level, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_TKEY, ISC_LOG_DEBUG(level), fmt, ap);
va_end(ap);
}
/*! \file */

View File

@@ -18,7 +18,7 @@
/*
* Principal Author: Brian Wellington
* $Id: hmac_link.c,v 1.5 2006/01/27 23:57:46 marka Exp $
* $Id: hmac_link.c,v 1.6 2006/12/04 01:52:46 marka Exp $
*/
#include <config.h>
@@ -43,9 +43,9 @@
static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
typedef struct hmackey {
struct dst_hmacmd5_key {
unsigned char key[HMAC_LEN];
} HMAC_Key;
};
static isc_result_t
getkeybits(dst_key_t *key, struct dst_private_element *element) {
@@ -61,30 +61,30 @@ getkeybits(dst_key_t *key, struct dst_private_element *element) {
static isc_result_t
hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_hmacmd5_t *hmacmd5ctx;
HMAC_Key *hkey = key->opaque;
dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
if (hmacmd5ctx == NULL)
return (ISC_R_NOMEMORY);
isc_hmacmd5_init(hmacmd5ctx, hkey->key, HMAC_LEN);
dctx->opaque = hmacmd5ctx;
dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
return (ISC_R_SUCCESS);
}
static void
hmacmd5_destroyctx(dst_context_t *dctx) {
isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
if (hmacmd5ctx != NULL) {
isc_hmacmd5_invalidate(hmacmd5ctx);
isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
dctx->opaque = NULL;
dctx->ctxdata.hmacmd5ctx = NULL;
}
}
static isc_result_t
hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -92,7 +92,7 @@ hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
unsigned char *digest;
if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
@@ -106,7 +106,7 @@ hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_hmacmd5_t *hmacmd5ctx = dctx->opaque;
isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
if (sig->length > ISC_MD5_DIGESTLENGTH)
return (DST_R_VERIFYFAILURE);
@@ -119,10 +119,10 @@ hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
static isc_boolean_t
hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
HMAC_Key *hkey1, *hkey2;
dst_hmacmd5_key_t *hkey1, *hkey2;
hkey1 = (HMAC_Key *)key1->opaque;
hkey2 = (HMAC_Key *)key2->opaque;
hkey1 = key1->keydata.hmacmd5;
hkey2 = key2->keydata.hmacmd5;
if (hkey1 == NULL && hkey2 == NULL)
return (ISC_TRUE);
@@ -170,20 +170,20 @@ hmacmd5_isprivate(const dst_key_t *key) {
static void
hmacmd5_destroy(dst_key_t *key) {
HMAC_Key *hkey = key->opaque;
memset(hkey, 0, sizeof(HMAC_Key));
isc_mem_put(key->mctx, hkey, sizeof(HMAC_Key));
key->opaque = NULL;
dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
memset(hkey, 0, sizeof(dst_hmacmd5_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t));
key->keydata.hmacmd5 = NULL;
}
static isc_result_t
hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
HMAC_Key *hkey;
dst_hmacmd5_key_t *hkey;
unsigned int bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.hmacmd5 != NULL);
hkey = (HMAC_Key *) key->opaque;
hkey = key->keydata.hmacmd5;
bytes = (key->key_size + 7) / 8;
if (isc_buffer_availablelength(data) < bytes)
@@ -195,7 +195,7 @@ hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
HMAC_Key *hkey;
dst_hmacmd5_key_t *hkey;
int keylen;
isc_region_t r;
isc_md5_t md5ctx;
@@ -204,7 +204,7 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
if (r.length == 0)
return (ISC_R_SUCCESS);
hkey = (HMAC_Key *) isc_mem_get(key->mctx, sizeof(HMAC_Key));
hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t));
if (hkey == NULL)
return (ISC_R_NOMEMORY);
@@ -222,7 +222,7 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
}
key->key_size = keylen * 8;
key->opaque = hkey;
key->keydata.hmacmd5 = hkey;
return (ISC_R_SUCCESS);
}
@@ -230,15 +230,15 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacmd5_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0;
HMAC_Key *hkey;
dst_hmacmd5_key_t *hkey;
dst_private_t priv;
int bytes = (key->key_size + 7) / 8;
unsigned char buf[2];
if (key->opaque == NULL)
if (key->keydata.hmacmd5 == NULL)
return (DST_R_NULLKEY);
hkey = (HMAC_Key *) key->opaque;
hkey = key->keydata.hmacmd5;
priv.elements[cnt].tag = TAG_HMACMD5_KEY;
priv.elements[cnt].length = bytes;
@@ -322,37 +322,37 @@ dst__hmacmd5_init(dst_func_t **funcp) {
static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
typedef struct {
struct dst_hmacsha1_key {
unsigned char key[ISC_SHA1_DIGESTLENGTH];
} HMACSHA1_Key;
};
static isc_result_t
hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_hmacsha1_t *hmacsha1ctx;
HMACSHA1_Key *hkey = key->opaque;
dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
if (hmacsha1ctx == NULL)
return (ISC_R_NOMEMORY);
isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_DIGESTLENGTH);
dctx->opaque = hmacsha1ctx;
dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
return (ISC_R_SUCCESS);
}
static void
hmacsha1_destroyctx(dst_context_t *dctx) {
isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
if (hmacsha1ctx != NULL) {
isc_hmacsha1_invalidate(hmacsha1ctx);
isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
dctx->opaque = NULL;
dctx->ctxdata.hmacsha1ctx = NULL;
}
}
static isc_result_t
hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -360,7 +360,7 @@ hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
unsigned char *digest;
if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
@@ -374,7 +374,7 @@ hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_hmacsha1_t *hmacsha1ctx = dctx->opaque;
isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
return (DST_R_VERIFYFAILURE);
@@ -387,10 +387,10 @@ hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
static isc_boolean_t
hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
HMACSHA1_Key *hkey1, *hkey2;
dst_hmacsha1_key_t *hkey1, *hkey2;
hkey1 = (HMACSHA1_Key *)key1->opaque;
hkey2 = (HMACSHA1_Key *)key2->opaque;
hkey1 = key1->keydata.hmacsha1;
hkey2 = key2->keydata.hmacsha1;
if (hkey1 == NULL && hkey2 == NULL)
return (ISC_TRUE);
@@ -438,20 +438,20 @@ hmacsha1_isprivate(const dst_key_t *key) {
static void
hmacsha1_destroy(dst_key_t *key) {
HMACSHA1_Key *hkey = key->opaque;
memset(hkey, 0, sizeof(HMACSHA1_Key));
isc_mem_put(key->mctx, hkey, sizeof(HMACSHA1_Key));
key->opaque = NULL;
dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
memset(hkey, 0, sizeof(dst_hmacsha1_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t));
key->keydata.hmacsha1 = NULL;
}
static isc_result_t
hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
HMACSHA1_Key *hkey;
dst_hmacsha1_key_t *hkey;
unsigned int bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.hmacsha1 != NULL);
hkey = (HMACSHA1_Key *) key->opaque;
hkey = key->keydata.hmacsha1;
bytes = (key->key_size + 7) / 8;
if (isc_buffer_availablelength(data) < bytes)
@@ -463,7 +463,7 @@ hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
HMACSHA1_Key *hkey;
dst_hmacsha1_key_t *hkey;
int keylen;
isc_region_t r;
isc_sha1_t sha1ctx;
@@ -472,7 +472,7 @@ hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
if (r.length == 0)
return (ISC_R_SUCCESS);
hkey = (HMACSHA1_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA1_Key));
hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t));
if (hkey == NULL)
return (ISC_R_NOMEMORY);
@@ -490,7 +490,7 @@ hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
}
key->key_size = keylen * 8;
key->opaque = hkey;
key->keydata.hmacsha1 = hkey;
return (ISC_R_SUCCESS);
}
@@ -498,15 +498,15 @@ hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha1_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0;
HMACSHA1_Key *hkey;
dst_hmacsha1_key_t *hkey;
dst_private_t priv;
int bytes = (key->key_size + 7) / 8;
unsigned char buf[2];
if (key->opaque == NULL)
if (key->keydata.hmacsha1 == NULL)
return (DST_R_NULLKEY);
hkey = (HMACSHA1_Key *) key->opaque;
hkey = key->keydata.hmacsha1;
priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
priv.elements[cnt].length = bytes;
@@ -591,37 +591,37 @@ dst__hmacsha1_init(dst_func_t **funcp) {
static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
typedef struct {
struct dst_hmacsha224_key {
unsigned char key[ISC_SHA224_DIGESTLENGTH];
} HMACSHA224_Key;
};
static isc_result_t
hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_hmacsha224_t *hmacsha224ctx;
HMACSHA224_Key *hkey = key->opaque;
dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
if (hmacsha224ctx == NULL)
return (ISC_R_NOMEMORY);
isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_DIGESTLENGTH);
dctx->opaque = hmacsha224ctx;
dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
return (ISC_R_SUCCESS);
}
static void
hmacsha224_destroyctx(dst_context_t *dctx) {
isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
if (hmacsha224ctx != NULL) {
isc_hmacsha224_invalidate(hmacsha224ctx);
isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
dctx->opaque = NULL;
dctx->ctxdata.hmacsha224ctx = NULL;
}
}
static isc_result_t
hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -629,7 +629,7 @@ hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
unsigned char *digest;
if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
@@ -643,7 +643,7 @@ hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_hmacsha224_t *hmacsha224ctx = dctx->opaque;
isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
return (DST_R_VERIFYFAILURE);
@@ -656,10 +656,10 @@ hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
static isc_boolean_t
hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
HMACSHA224_Key *hkey1, *hkey2;
dst_hmacsha224_key_t *hkey1, *hkey2;
hkey1 = (HMACSHA224_Key *)key1->opaque;
hkey2 = (HMACSHA224_Key *)key2->opaque;
hkey1 = key1->keydata.hmacsha224;
hkey2 = key2->keydata.hmacsha224;
if (hkey1 == NULL && hkey2 == NULL)
return (ISC_TRUE);
@@ -707,20 +707,20 @@ hmacsha224_isprivate(const dst_key_t *key) {
static void
hmacsha224_destroy(dst_key_t *key) {
HMACSHA224_Key *hkey = key->opaque;
memset(hkey, 0, sizeof(HMACSHA224_Key));
isc_mem_put(key->mctx, hkey, sizeof(HMACSHA224_Key));
key->opaque = NULL;
dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
memset(hkey, 0, sizeof(dst_hmacsha224_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t));
key->keydata.hmacsha224 = NULL;
}
static isc_result_t
hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
HMACSHA224_Key *hkey;
dst_hmacsha224_key_t *hkey;
unsigned int bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.hmacsha224 != NULL);
hkey = (HMACSHA224_Key *) key->opaque;
hkey = key->keydata.hmacsha224;
bytes = (key->key_size + 7) / 8;
if (isc_buffer_availablelength(data) < bytes)
@@ -732,7 +732,7 @@ hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
HMACSHA224_Key *hkey;
dst_hmacsha224_key_t *hkey;
int keylen;
isc_region_t r;
isc_sha224_t sha224ctx;
@@ -741,7 +741,7 @@ hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
if (r.length == 0)
return (ISC_R_SUCCESS);
hkey = (HMACSHA224_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA224_Key));
hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t));
if (hkey == NULL)
return (ISC_R_NOMEMORY);
@@ -759,7 +759,7 @@ hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
}
key->key_size = keylen * 8;
key->opaque = hkey;
key->keydata.hmacsha224 = hkey;
return (ISC_R_SUCCESS);
}
@@ -767,15 +767,15 @@ hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha224_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0;
HMACSHA224_Key *hkey;
dst_hmacsha224_key_t *hkey;
dst_private_t priv;
int bytes = (key->key_size + 7) / 8;
unsigned char buf[2];
if (key->opaque == NULL)
if (key->keydata.hmacsha224 == NULL)
return (DST_R_NULLKEY);
hkey = (HMACSHA224_Key *) key->opaque;
hkey = key->keydata.hmacsha224;
priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
priv.elements[cnt].length = bytes;
@@ -860,37 +860,37 @@ dst__hmacsha224_init(dst_func_t **funcp) {
static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
typedef struct {
struct dst_hmacsha256_key {
unsigned char key[ISC_SHA256_DIGESTLENGTH];
} HMACSHA256_Key;
};
static isc_result_t
hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_hmacsha256_t *hmacsha256ctx;
HMACSHA256_Key *hkey = key->opaque;
dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
if (hmacsha256ctx == NULL)
return (ISC_R_NOMEMORY);
isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_DIGESTLENGTH);
dctx->opaque = hmacsha256ctx;
dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
return (ISC_R_SUCCESS);
}
static void
hmacsha256_destroyctx(dst_context_t *dctx) {
isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
if (hmacsha256ctx != NULL) {
isc_hmacsha256_invalidate(hmacsha256ctx);
isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
dctx->opaque = NULL;
dctx->ctxdata.hmacsha256ctx = NULL;
}
}
static isc_result_t
hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -898,7 +898,7 @@ hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
unsigned char *digest;
if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
@@ -912,7 +912,7 @@ hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_hmacsha256_t *hmacsha256ctx = dctx->opaque;
isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
return (DST_R_VERIFYFAILURE);
@@ -925,10 +925,10 @@ hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
static isc_boolean_t
hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
HMACSHA256_Key *hkey1, *hkey2;
dst_hmacsha256_key_t *hkey1, *hkey2;
hkey1 = (HMACSHA256_Key *)key1->opaque;
hkey2 = (HMACSHA256_Key *)key2->opaque;
hkey1 = key1->keydata.hmacsha256;
hkey2 = key2->keydata.hmacsha256;
if (hkey1 == NULL && hkey2 == NULL)
return (ISC_TRUE);
@@ -976,20 +976,20 @@ hmacsha256_isprivate(const dst_key_t *key) {
static void
hmacsha256_destroy(dst_key_t *key) {
HMACSHA256_Key *hkey = key->opaque;
memset(hkey, 0, sizeof(HMACSHA256_Key));
isc_mem_put(key->mctx, hkey, sizeof(HMACSHA256_Key));
key->opaque = NULL;
dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
memset(hkey, 0, sizeof(dst_hmacsha256_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t));
key->keydata.hmacsha256 = NULL;
}
static isc_result_t
hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
HMACSHA256_Key *hkey;
dst_hmacsha256_key_t *hkey;
unsigned int bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.hmacsha256 != NULL);
hkey = (HMACSHA256_Key *) key->opaque;
hkey = key->keydata.hmacsha256;
bytes = (key->key_size + 7) / 8;
if (isc_buffer_availablelength(data) < bytes)
@@ -1001,7 +1001,7 @@ hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
HMACSHA256_Key *hkey;
dst_hmacsha256_key_t *hkey;
int keylen;
isc_region_t r;
isc_sha256_t sha256ctx;
@@ -1010,7 +1010,7 @@ hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
if (r.length == 0)
return (ISC_R_SUCCESS);
hkey = (HMACSHA256_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA256_Key));
hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t));
if (hkey == NULL)
return (ISC_R_NOMEMORY);
@@ -1028,7 +1028,7 @@ hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
}
key->key_size = keylen * 8;
key->opaque = hkey;
key->keydata.hmacsha256 = hkey;
return (ISC_R_SUCCESS);
}
@@ -1036,15 +1036,15 @@ hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha256_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0;
HMACSHA256_Key *hkey;
dst_hmacsha256_key_t *hkey;
dst_private_t priv;
int bytes = (key->key_size + 7) / 8;
unsigned char buf[2];
if (key->opaque == NULL)
if (key->keydata.hmacsha256 == NULL)
return (DST_R_NULLKEY);
hkey = (HMACSHA256_Key *) key->opaque;
hkey = key->keydata.hmacsha256;
priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
priv.elements[cnt].length = bytes;
@@ -1129,37 +1129,37 @@ dst__hmacsha256_init(dst_func_t **funcp) {
static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
typedef struct {
struct dst_hmacsha384_key {
unsigned char key[ISC_SHA384_DIGESTLENGTH];
} HMACSHA384_Key;
};
static isc_result_t
hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_hmacsha384_t *hmacsha384ctx;
HMACSHA384_Key *hkey = key->opaque;
dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
if (hmacsha384ctx == NULL)
return (ISC_R_NOMEMORY);
isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_DIGESTLENGTH);
dctx->opaque = hmacsha384ctx;
dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
return (ISC_R_SUCCESS);
}
static void
hmacsha384_destroyctx(dst_context_t *dctx) {
isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
if (hmacsha384ctx != NULL) {
isc_hmacsha384_invalidate(hmacsha384ctx);
isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
dctx->opaque = NULL;
dctx->ctxdata.hmacsha384ctx = NULL;
}
}
static isc_result_t
hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -1167,7 +1167,7 @@ hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
unsigned char *digest;
if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
@@ -1181,7 +1181,7 @@ hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_hmacsha384_t *hmacsha384ctx = dctx->opaque;
isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
return (DST_R_VERIFYFAILURE);
@@ -1194,10 +1194,10 @@ hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
static isc_boolean_t
hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
HMACSHA384_Key *hkey1, *hkey2;
dst_hmacsha384_key_t *hkey1, *hkey2;
hkey1 = (HMACSHA384_Key *)key1->opaque;
hkey2 = (HMACSHA384_Key *)key2->opaque;
hkey1 = key1->keydata.hmacsha384;
hkey2 = key2->keydata.hmacsha384;
if (hkey1 == NULL && hkey2 == NULL)
return (ISC_TRUE);
@@ -1245,20 +1245,20 @@ hmacsha384_isprivate(const dst_key_t *key) {
static void
hmacsha384_destroy(dst_key_t *key) {
HMACSHA384_Key *hkey = key->opaque;
memset(hkey, 0, sizeof(HMACSHA384_Key));
isc_mem_put(key->mctx, hkey, sizeof(HMACSHA384_Key));
key->opaque = NULL;
dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
memset(hkey, 0, sizeof(dst_hmacsha384_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t));
key->keydata.hmacsha384 = NULL;
}
static isc_result_t
hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
HMACSHA384_Key *hkey;
dst_hmacsha384_key_t *hkey;
unsigned int bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.hmacsha384 != NULL);
hkey = (HMACSHA384_Key *) key->opaque;
hkey = key->keydata.hmacsha384;
bytes = (key->key_size + 7) / 8;
if (isc_buffer_availablelength(data) < bytes)
@@ -1270,7 +1270,7 @@ hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
HMACSHA384_Key *hkey;
dst_hmacsha384_key_t *hkey;
int keylen;
isc_region_t r;
isc_sha384_t sha384ctx;
@@ -1279,7 +1279,7 @@ hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
if (r.length == 0)
return (ISC_R_SUCCESS);
hkey = (HMACSHA384_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA384_Key));
hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t));
if (hkey == NULL)
return (ISC_R_NOMEMORY);
@@ -1297,7 +1297,7 @@ hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
}
key->key_size = keylen * 8;
key->opaque = hkey;
key->keydata.hmacsha384 = hkey;
return (ISC_R_SUCCESS);
}
@@ -1305,15 +1305,15 @@ hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha384_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0;
HMACSHA384_Key *hkey;
dst_hmacsha384_key_t *hkey;
dst_private_t priv;
int bytes = (key->key_size + 7) / 8;
unsigned char buf[2];
if (key->opaque == NULL)
if (key->keydata.hmacsha384 == NULL)
return (DST_R_NULLKEY);
hkey = (HMACSHA384_Key *) key->opaque;
hkey = key->keydata.hmacsha384;
priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
priv.elements[cnt].length = bytes;
@@ -1398,37 +1398,37 @@ dst__hmacsha384_init(dst_func_t **funcp) {
static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
typedef struct {
struct dst_hmacsha512_key {
unsigned char key[ISC_SHA512_DIGESTLENGTH];
} HMACSHA512_Key;
};
static isc_result_t
hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_hmacsha512_t *hmacsha512ctx;
HMACSHA512_Key *hkey = key->opaque;
dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
if (hmacsha512ctx == NULL)
return (ISC_R_NOMEMORY);
isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_DIGESTLENGTH);
dctx->opaque = hmacsha512ctx;
dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
return (ISC_R_SUCCESS);
}
static void
hmacsha512_destroyctx(dst_context_t *dctx) {
isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
if (hmacsha512ctx != NULL) {
isc_hmacsha512_invalidate(hmacsha512ctx);
isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
dctx->opaque = NULL;
dctx->ctxdata.hmacsha512ctx = NULL;
}
}
static isc_result_t
hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -1436,7 +1436,7 @@ hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
unsigned char *digest;
if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
@@ -1450,7 +1450,7 @@ hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_hmacsha512_t *hmacsha512ctx = dctx->opaque;
isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
return (DST_R_VERIFYFAILURE);
@@ -1463,10 +1463,10 @@ hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
static isc_boolean_t
hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
HMACSHA512_Key *hkey1, *hkey2;
dst_hmacsha512_key_t *hkey1, *hkey2;
hkey1 = (HMACSHA512_Key *)key1->opaque;
hkey2 = (HMACSHA512_Key *)key2->opaque;
hkey1 = key1->keydata.hmacsha512;
hkey2 = key2->keydata.hmacsha512;
if (hkey1 == NULL && hkey2 == NULL)
return (ISC_TRUE);
@@ -1514,20 +1514,20 @@ hmacsha512_isprivate(const dst_key_t *key) {
static void
hmacsha512_destroy(dst_key_t *key) {
HMACSHA512_Key *hkey = key->opaque;
memset(hkey, 0, sizeof(HMACSHA512_Key));
isc_mem_put(key->mctx, hkey, sizeof(HMACSHA512_Key));
key->opaque = NULL;
dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
memset(hkey, 0, sizeof(dst_hmacsha512_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t));
key->keydata.hmacsha512 = NULL;
}
static isc_result_t
hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
HMACSHA512_Key *hkey;
dst_hmacsha512_key_t *hkey;
unsigned int bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.hmacsha512 != NULL);
hkey = (HMACSHA512_Key *) key->opaque;
hkey = key->keydata.hmacsha512;
bytes = (key->key_size + 7) / 8;
if (isc_buffer_availablelength(data) < bytes)
@@ -1539,7 +1539,7 @@ hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
HMACSHA512_Key *hkey;
dst_hmacsha512_key_t *hkey;
int keylen;
isc_region_t r;
isc_sha512_t sha512ctx;
@@ -1548,7 +1548,7 @@ hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
if (r.length == 0)
return (ISC_R_SUCCESS);
hkey = (HMACSHA512_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA512_Key));
hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t));
if (hkey == NULL)
return (ISC_R_NOMEMORY);
@@ -1566,7 +1566,7 @@ hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
}
key->key_size = keylen * 8;
key->opaque = hkey;
key->keydata.hmacsha512 = hkey;
return (ISC_R_SUCCESS);
}
@@ -1574,15 +1574,15 @@ hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t
hmacsha512_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0;
HMACSHA512_Key *hkey;
dst_hmacsha512_key_t *hkey;
dst_private_t priv;
int bytes = (key->key_size + 7) / 8;
unsigned char buf[2];
if (key->opaque == NULL)
if (key->keydata.hmacsha512 == NULL)
return (DST_R_NULLKEY);
hkey = (HMACSHA512_Key *) key->opaque;
hkey = key->keydata.hmacsha512;
priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
priv.elements[cnt].length = bytes;

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: name.h,v 1.122 2006/03/02 00:37:23 marka Exp $ */
/* $Id: name.h,v 1.123 2006/12/04 01:52:46 marka Exp $ */
#ifndef DNS_NAME_H
#define DNS_NAME_H 1
@@ -131,6 +131,7 @@ struct dns_name {
#define DNS_NAMEATTR_READONLY 0x0002
#define DNS_NAMEATTR_DYNAMIC 0x0004
#define DNS_NAMEATTR_DYNOFFSETS 0x0008
#define DNS_NAMEATTR_NOCOMPRESS 0x0010
/*
* Attributes below 0x0100 reserved for name.c usage.
*/

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: ssu.h,v 1.17 2006/02/16 23:51:33 marka Exp $ */
/* $Id: ssu.h,v 1.18 2006/12/04 01:52:46 marka Exp $ */
#ifndef DNS_SSU_H
#define DNS_SSU_H 1
@@ -34,8 +34,11 @@ ISC_LANG_BEGINDECLS
#define DNS_SSUMATCHTYPE_SELF 3
#define DNS_SSUMATCHTYPE_SELFSUB 4
#define DNS_SSUMATCHTYPE_SELFWILD 5
#define DNS_SSUMATCHTYPE_MAX 5 /* maximum defined value */
#define DNS_SSUMATCHTYPE_SELFKRB5 6
#define DNS_SSUMATCHTYPE_SELFMS 7
#define DNS_SSUMATCHTYPE_SUBDOMAINMS 8
#define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 9
#define DNS_SSUMATCHTYPE_MAX 9 /* max value */
isc_result_t
dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table);
@@ -91,8 +94,8 @@ dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
* at that name.
*
* Notes:
*\li If 'matchtype' is SELF, this rule only matches if the name
* to be updated matches the signing identity.
*\li If 'matchtype' is of SELF type, this rule only matches if the
* name to be updated matches the signing identity.
*
*\li If 'ntypes' is 0, this rule applies to all types except
* NS, SOA, RRSIG, and NSEC.

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: tkey.h,v 1.21 2005/04/29 00:23:05 marka Exp $ */
/* $Id: tkey.h,v 1.22 2006/12/04 01:52:46 marka Exp $ */
#ifndef DNS_TKEY_H
#define DNS_TKEY_H 1
@@ -27,6 +27,7 @@
#include <dns/types.h>
#include <dst/dst.h>
#include <dst/gssapi.h>
ISC_LANG_BEGINDECLS
@@ -40,13 +41,14 @@ ISC_LANG_BEGINDECLS
struct dns_tkeyctx {
dst_key_t *dhkey;
dns_name_t *domain;
void *gsscred;
gss_cred_id_t gsscred;
isc_mem_t *mctx;
isc_entropy_t *ectx;
};
isc_result_t
dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp);
dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx,
dns_tkeyctx_t **tctxp);
/*%<
* Create an empty TKEY context.
*
@@ -119,13 +121,29 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
*/
isc_result_t
dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name,
dns_name_t *gname, void *cred,
isc_uint32_t lifetime, void **context);
dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
isc_buffer_t *intoken, isc_uint32_t lifetime,
gss_ctx_id_t *context, isc_boolean_t win2k);
/*%<
* XXX
* Builds a query containing a TKEY that will generate a GSSAPI context.
* The key is requested to have the specified lifetime (in seconds).
*
* Requires:
*\li 'msg' is a valid message
*\li 'name' is a valid name
*\li 'gname' is a valid name
*\li 'context' is a pointer to a valid gss_ctx_id_t
* (which may have the value GSS_C_NO_CONTEXT)
*\li 'win2k' when true says to turn on some hacks to work
* with the non-standard GSS-TSIG of Windows 2000
*
* Returns:
*\li ISC_R_SUCCESS msg was successfully updated to include the
* query to be sent
*\li other an error occurred while building the message
*/
isc_result_t
dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key);
/*%<
@@ -167,8 +185,9 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
isc_result_t
dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *gname, void *cred, void **context,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring);
dns_name_t *gname, gss_ctx_id_t *context,
isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
dns_tsig_keyring_t *ring);
/*%<
* XXX
*/
@@ -193,6 +212,39 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
*/
isc_result_t
dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *server, gss_ctx_id_t *context,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
isc_boolean_t win2k);
/*
* Client side negotiation of GSS-TSIG. Process the respsonse
* to a TKEY, and establish a TSIG key if negotiation was successful.
* Build a response to the input TKEY message. Can take multiple
* calls to successfully establish the context.
*
* Requires:
* 'qmsg' is a valid message, the original TKEY request;
* it will be filled with the new message to send
* 'rmsg' is a valid message, the incoming TKEY message
* 'server' is the server name
* 'context' is the input context handle
* 'outkey' receives the established key, if non-NULL;
* if non-NULL must point to NULL
* 'ring' is the keyring in which to establish the key,
* or NULL
* 'win2k' when true says to turn on some hacks to work
* with the non-standard GSS-TSIG of Windows 2000
*
* Returns:
* ISC_R_SUCCESS context was successfully established
* ISC_R_NOTFOUND couldn't find a needed part of the query
* or response
* DNS_R_CONTINUE additional context negotiation is required;
* send the new qmsg to the server
*/
ISC_LANG_ENDDECLS
#endif /* DNS_TKEY_H */

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: tsig.h,v 1.47 2006/01/27 23:57:46 marka Exp $ */
/* $Id: tsig.h,v 1.48 2006/12/04 01:52:46 marka Exp $ */
#ifndef DNS_TSIG_H
#define DNS_TSIG_H 1
@@ -59,6 +59,7 @@ LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name;
struct dns_tsig_keyring {
dns_rbt_t *keys;
unsigned int writecount;
isc_rwlock_t lock;
isc_mem_t *mctx;
};
@@ -79,7 +80,9 @@ struct dns_tsigkey {
};
#define dns_tsigkey_identity(tsigkey) \
((tsigkey)->generated ? ((tsigkey)->creator) : (&((tsigkey)->name)))
((tsigkey) == NULL ? NULL : \
(tsigkey)->generated ? ((tsigkey)->creator) : \
(&((tsigkey)->name)))
ISC_LANG_BEGINDECLS

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: types.h,v 1.121 2006/05/02 13:04:54 shane Exp $ */
/* $Id: types.h,v 1.122 2006/12/04 01:52:46 marka Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
@@ -118,6 +118,15 @@ typedef ISC_LIST(dns_zone_t) dns_zonelist_t;
typedef struct dns_zonemgr dns_zonemgr_t;
typedef struct dns_zt dns_zt_t;
/*
* If we are not using GSSAPI, define the types we use as opaque types here.
*/
#ifndef GSSAPI
typedef struct not_defined_gss_cred_id *gss_cred_id_t;
typedef struct not_defined_gss_ctx *gss_ctx_id_t;
#endif
typedef struct dst_gssapi_signverifyctx dst_gssapi_signverifyctx_t;
typedef enum {
dns_fwdpolicy_none = 0,
dns_fwdpolicy_first = 1,

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dst.h,v 1.5 2006/01/27 23:57:46 marka Exp $ */
/* $Id: dst.h,v 1.6 2006/12/04 01:52:46 marka Exp $ */
#ifndef DST_DST_H
#define DST_DST_H 1
@@ -26,6 +26,8 @@
#include <dns/types.h>
#include <dst/gssapi.h>
ISC_LANG_BEGINDECLS
/***
@@ -398,16 +400,28 @@ dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer);
*\li If successful, key will contain a valid private key.
*/
gss_ctx_id_t
dst_key_getgssctx(const dst_key_t *key);
/*%<
* Returns the opaque key data.
* Be cautions when using this value unless you know what you are doing.
*
* Requires:
*\li "key" is not NULL.
*
* Returns:
*\li gssctx key data, possibly NULL.
*/
isc_result_t
dst_key_fromgssapi(dns_name_t *name, void *opaque, isc_mem_t *mctx,
dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
dst_key_t **keyp);
/*%<
* Converts a GSSAPI opaque context id into a DST key.
*
* Requires:
*\li "name" is a valid absolute dns name.
*\li "opaque" is a GSSAPI context id.
*\li "gssctx" is a GSSAPI context id.
*\li "mctx" is a valid memory context.
*\li "keyp" is not NULL and "*keyp" is NULL.
*

View File

@@ -15,16 +15,32 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: gssapi.h,v 1.3 2005/04/29 00:23:06 marka Exp $ */
/* $Id: gssapi.h,v 1.4 2006/12/04 01:52:46 marka Exp $ */
#ifndef DST_GSSAPI_H
#define DST_GSSAPI_H 1
/*! \file */
#include <isc/formatcheck.h>
#include <isc/lang.h>
#include <isc/platform.h>
#include <isc/types.h>
#include <dns/types.h>
#ifdef GSSAPI
#ifdef _WINDOWS
/*
* MSVC does not like macros in #include lines.
*/
#include <gssapi/gssapi.h>
#else
#include ISC_PLATFORM_GSSAPIHEADER
#endif
#ifndef GSS_SPNEGO_MECHANISM
#define GSS_SPNEGO_MECHANISM ((void*)0)
#endif
#endif
ISC_LANG_BEGINDECLS
@@ -37,20 +53,149 @@ ISC_LANG_BEGINDECLS
***/
isc_result_t
dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred);
isc_result_t
dst_gssapi_initctx(dns_name_t *name, void *cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
void **context);
isc_result_t
dst_gssapi_acceptctx(dns_name_t *name, void *cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
void **context);
dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
gss_cred_id_t *cred);
/*
* XXX
* 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(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(dns_name_t *name, isc_buffer_t *intoken,
isc_buffer_t *outtoken, gss_ctx_id_t *gssctx);
/*
* 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 gss_ctx_id_t
* (which may have the value 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
*/
isc_result_t
dst_gssapi_acceptctx(gss_cred_id_t cred,
isc_region_t *intoken, isc_buffer_t *outtoken,
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 buffer to receive 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.
* On the initial call, it should be a pointer to NULL, which
* will be allocated as a gss_ctx_id_t. Subsequent calls
* should pass in the handle generated on the first call.
* Call dst_gssapi_releasecred to delete the context and 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_deletectx(isc_mem_t *mctx, 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);
/*
* Loging 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(isc_uint32_t major, isc_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.
*/
isc_boolean_t
dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
dns_name_t *realm);
/*
* Compare a "signer" (in the format of a Kerberos-format Kerberos5
* printipal: host/example.com@EXAMPLE.COM) to the realm name stored
* in "name" (which represents the realm name).
*
*/
isc_boolean_t
dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
dns_name_t *realm);
/*
* Compare a "signer" (in the format of a Kerberos-format Kerberos5
* printipal: host/example.com@EXAMPLE.COM) to the realm name stored
* in "name" (which represents the realm name).
*
*/
ISC_LANG_ENDDECLS

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: message.c,v 1.232 2006/03/02 01:57:20 marka Exp $ */
/* $Id: message.c,v 1.233 2006/12/04 01:52:46 marka Exp $ */
/*! \file */
@@ -45,6 +45,35 @@
#include <dns/tsig.h>
#include <dns/view.h>
#ifdef SKAN_MSG_DEBUG
static void
hexdump(const char *msg, const char *msg2, void *base, size_t len) {
unsigned char *p;
unsigned int cnt;
p = base;
cnt = 0;
printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base);
while (cnt < len) {
if (cnt % 16 == 0)
printf("%p: ", p);
else if (cnt % 8 == 0)
printf(" |");
printf(" %02x %c", *p, (isprint(*p) ? *p : ' '));
p++;
cnt++;
if (cnt % 16 == 0)
printf("\n");
}
if (cnt % 16 != 0)
printf("\n");
}
#endif
#define DNS_MESSAGE_OPCODE_MASK 0x7800U
#define DNS_MESSAGE_OPCODE_SHIFT 11
#define DNS_MESSAGE_RCODE_MASK 0x000fU
@@ -2891,6 +2920,30 @@ dns_message_rechecksig(dns_message_t *msg, dns_view_t *view) {
return (dns_message_checksig(msg, view));
}
#ifdef SKAN_MSG_DEBUG
void
dns_message_dumpsig(dns_message_t *msg, char *txt1) {
dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
dns_rdata_any_tsig_t querytsig;
if (msg->tsig != NULL) {
dns_rdataset_first(msg->tsig);
dns_rdataset_current(msg->tsig, &querytsigrdata);
dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
hexdump(txt1, "TSIG", querytsig.signature,
querytsig.siglen);
}
if (msg->querytsig != NULL) {
dns_rdataset_first(msg->querytsig);
dns_rdataset_current(msg->querytsig, &querytsigrdata);
dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
hexdump(txt1, "QUERYTSIG", querytsig.signature,
querytsig.siglen);
}
}
#endif
isc_result_t
dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
isc_buffer_t b, msgb;
@@ -2899,10 +2952,14 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL)
return (ISC_R_SUCCESS);
INSIST(msg->saved.base != NULL);
isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
isc_buffer_add(&msgb, msg->saved.length);
if (msg->tsigkey != NULL || msg->tsig != NULL) {
#ifdef SKAN_MSG_DEBUG
dns_message_dumpsig(msg, "dns_message_checksig#1");
#endif
if (view != NULL)
return (dns_view_checksig(view, &msgb, msg));
else

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: name.c,v 1.159 2006/02/28 02:39:51 marka Exp $ */
/* $Id: name.c,v 1.160 2006/12/04 01:52:46 marka Exp $ */
/*! \file */
@@ -1932,7 +1932,8 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
methods = dns_compress_getmethods(cctx);
if ((methods & DNS_COMPRESS_GLOBAL14) != 0)
if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
(methods & DNS_COMPRESS_GLOBAL14) != 0)
gf = dns_compress_findglobal(cctx, name, &gp, &go);
else
gf = ISC_FALSE;

View File

@@ -18,7 +18,7 @@
/*
* Principal Author: Brian Wellington
* $Id: openssl_link.c,v 1.9 2006/05/23 23:51:05 marka Exp $
* $Id: openssl_link.c,v 1.10 2006/12/04 01:52:46 marka Exp $
*/
#ifdef OPENSSL
@@ -49,7 +49,10 @@
#include <openssl/engine.h>
#endif
#ifdef OVERRIDE_OPENSSL_RAND
static RAND_METHOD *rm = NULL;
#endif
static isc_mutex_t *locks = NULL;
static int nlocks;
@@ -57,7 +60,7 @@ static int nlocks;
static ENGINE *e;
#endif
#ifdef OVERRIDE_OPENSSL_RAND
static int
entropy_get(unsigned char *buf, int num) {
isc_result_t result;
@@ -67,6 +70,11 @@ entropy_get(unsigned char *buf, int num) {
return (result == ISC_R_SUCCESS ? num : -1);
}
static int
entropy_status(void) {
return (dst__entropy_status() > 32);
}
static int
entropy_getpseudo(unsigned char *buf, int num) {
isc_result_t result;
@@ -85,6 +93,7 @@ entropy_add(const void *buf, int num, double entropy) {
UNUSED(num);
UNUSED(entropy);
}
#endif
static void
lock_callback(int mode, int type, const char *file, int line) {
@@ -149,6 +158,8 @@ dst__openssl_init() {
goto cleanup_mutexalloc;
CRYPTO_set_locking_callback(lock_callback);
CRYPTO_set_id_callback(id_callback);
#ifdef OVERRIDE_OPENSSL_RAND
rm = mem_alloc(sizeof(RAND_METHOD));
if (rm == NULL) {
result = ISC_R_NOMEMORY;
@@ -159,7 +170,7 @@ dst__openssl_init() {
rm->cleanup = NULL;
rm->add = entropy_add;
rm->pseudorand = entropy_getpseudo;
rm->status = NULL;
rm->status = entropy_status;
#ifdef USE_ENGINE
e = ENGINE_new();
if (e == NULL) {
@@ -170,15 +181,18 @@ dst__openssl_init() {
RAND_set_rand_method(rm);
#else
RAND_set_rand_method(rm);
#endif
#endif /* USE_ENGINER */
#endif /* OVERRIDE_OPENSSL_RAND */
return (ISC_R_SUCCESS);
#ifdef OVERRIDE_OPENSSL_RAND
#ifdef USE_ENGINE
cleanup_rm:
mem_free(rm);
#endif
cleanup_mutexinit:
DESTROYMUTEXBLOCK(locks, nlocks);
#endif
cleanup_mutexalloc:
mem_free(locks);
return (result);
@@ -225,12 +239,14 @@ dst__openssl_destroy() {
DESTROYMUTEXBLOCK(locks, nlocks);
mem_free(locks);
}
#ifdef OVERRIDE_OPENSSL_RAND
if (rm != NULL) {
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
RAND_cleanup();
#endif
mem_free(rm);
}
#endif
}
isc_result_t

View File

@@ -18,7 +18,7 @@
/*
* Principal Author: Brian Wellington
* $Id: openssldh_link.c,v 1.6 2006/03/02 00:37:23 marka Exp $
* $Id: openssldh_link.c,v 1.7 2006/12/04 01:52:46 marka Exp $
*/
#ifdef OPENSSL
@@ -37,8 +37,6 @@
#include "dst_openssl.h"
#include "dst_parse.h"
#include <openssl/dh.h>
#define PRIME768 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088" \
"A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25" \
"F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
@@ -71,11 +69,11 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
isc_region_t r;
unsigned int len;
REQUIRE(pub->opaque != NULL);
REQUIRE(priv->opaque != NULL);
REQUIRE(pub->keydata.dh != NULL);
REQUIRE(priv->keydata.dh != NULL);
dhpub = (DH *) pub->opaque;
dhpriv = (DH *) priv->opaque;
dhpub = pub->keydata.dh;
dhpriv = priv->keydata.dh;
len = DH_size(dhpriv);
isc_buffer_availableregion(secret, &r);
@@ -93,8 +91,8 @@ openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
DH *dh1, *dh2;
dh1 = (DH *) key1->opaque;
dh2 = (DH *) key2->opaque;
dh1 = key1->keydata.dh;
dh2 = key2->keydata.dh;
if (dh1 == NULL && dh2 == NULL)
return (ISC_TRUE);
@@ -122,8 +120,8 @@ openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
DH *dh1, *dh2;
dh1 = (DH *) key1->opaque;
dh2 = (DH *) key2->opaque;
dh1 = key1->keydata.dh;
dh2 = key2->keydata.dh;
if (dh1 == NULL && dh2 == NULL)
return (ISC_TRUE);
@@ -248,20 +246,20 @@ openssldh_generate(dst_key_t *key, int generator) {
}
dh->flags &= ~DH_FLAG_CACHE_MONT_P;
key->opaque = dh;
key->keydata.dh = dh;
return (ISC_R_SUCCESS);
}
static isc_boolean_t
openssldh_isprivate(const dst_key_t *key) {
DH *dh = (DH *) key->opaque;
DH *dh = key->keydata.dh;
return (ISC_TF(dh != NULL && dh->priv_key != NULL));
}
static void
openssldh_destroy(dst_key_t *key) {
DH *dh = key->opaque;
DH *dh = key->keydata.dh;
if (dh == NULL)
return;
@@ -271,7 +269,7 @@ openssldh_destroy(dst_key_t *key) {
if (dh->g == &bn2)
dh->g = NULL;
DH_free(dh);
key->opaque = NULL;
key->keydata.dh = NULL;
}
static void
@@ -298,9 +296,9 @@ openssldh_todns(const dst_key_t *key, isc_buffer_t *data) {
isc_region_t r;
isc_uint16_t dnslen, plen, glen, publen;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.dh != NULL);
dh = (DH *) key->opaque;
dh = key->keydata.dh;
isc_buffer_availableregion(data, &r);
@@ -457,7 +455,7 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) {
isc_buffer_forward(data, plen + glen + publen + 6);
key->opaque = (void *) dh;
key->keydata.dh = dh;
return (ISC_R_SUCCESS);
}
@@ -470,10 +468,10 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
unsigned char *bufs[4];
isc_result_t result;
if (key->opaque == NULL)
if (key->keydata.dh == NULL)
return (DST_R_NULLKEY);
dh = (DH *) key->opaque;
dh = key->keydata.dh;
for (i = 0; i < 4; i++) {
bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p));
@@ -540,7 +538,7 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
if (dh == NULL)
DST_RET(ISC_R_NOMEMORY);
dh->flags &= ~DH_FLAG_CACHE_MONT_P;
key->opaque = dh;
key->keydata.dh = dh;
for (i = 0; i < priv.nelements; i++) {
BIGNUM *bn;

View File

@@ -16,7 +16,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: openssldsa_link.c,v 1.5 2006/03/02 00:37:23 marka Exp $ */
/* $Id: openssldsa_link.c,v 1.6 2006/12/04 01:52:46 marka Exp $ */
#ifdef OPENSSL
@@ -47,24 +47,24 @@ openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) {
sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
isc_sha1_init(sha1ctx);
dctx->opaque = sha1ctx;
dctx->ctxdata.sha1ctx = sha1ctx;
return (ISC_R_SUCCESS);
}
static void
openssldsa_destroyctx(dst_context_t *dctx) {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
if (sha1ctx != NULL) {
isc_sha1_invalidate(sha1ctx);
isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
dctx->opaque = NULL;
dctx->ctxdata.sha1ctx = NULL;
}
}
static isc_result_t
openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_update(sha1ctx, data->base, data->length);
return (ISC_R_SUCCESS);
@@ -81,9 +81,9 @@ BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
static isc_result_t
openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
dst_key_t *key = dctx->key;
DSA *dsa = key->opaque;
DSA *dsa = key->keydata.dsa;
DSA_SIG *dsasig;
isc_region_t r;
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
@@ -111,9 +111,9 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
dst_key_t *key = dctx->key;
DSA *dsa = key->opaque;
DSA *dsa = key->keydata.dsa;
DSA_SIG *dsasig;
int status = 0;
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
@@ -144,8 +144,8 @@ openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
DSA *dsa1, *dsa2;
dsa1 = (DSA *) key1->opaque;
dsa2 = (DSA *) key2->opaque;
dsa1 = key1->keydata.dsa;
dsa2 = key2->keydata.dsa;
if (dsa1 == NULL && dsa2 == NULL)
return (ISC_TRUE);
@@ -272,22 +272,22 @@ openssldsa_generate(dst_key_t *key, int unused) {
}
dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
key->opaque = dsa;
key->keydata.dsa = dsa;
return (ISC_R_SUCCESS);
}
static isc_boolean_t
openssldsa_isprivate(const dst_key_t *key) {
DSA *dsa = (DSA *) key->opaque;
DSA *dsa = key->keydata.dsa;
return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
}
static void
openssldsa_destroy(dst_key_t *key) {
DSA *dsa = key->opaque;
DSA *dsa = key->keydata.dsa;
DSA_free(dsa);
key->opaque = NULL;
key->keydata.dsa = NULL;
}
@@ -298,9 +298,9 @@ openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) {
int dnslen;
unsigned int t, p_bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.dsa != NULL);
dsa = (DSA *) key->opaque;
dsa = key->keydata.dsa;
isc_buffer_availableregion(data, &r);
@@ -374,7 +374,7 @@ openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
key->opaque = (void *) dsa;
key->keydata.dsa = dsa;
return (ISC_R_SUCCESS);
}
@@ -387,10 +387,10 @@ openssldsa_tofile(const dst_key_t *key, const char *directory) {
dst_private_t priv;
unsigned char bufs[5][128];
if (key->opaque == NULL)
if (key->keydata.dsa == NULL)
return (DST_R_NULLKEY);
dsa = (DSA *) key->opaque;
dsa = key->keydata.dsa;
priv.elements[cnt].tag = TAG_DSA_PRIME;
priv.elements[cnt].length = BN_num_bytes(dsa->p);
@@ -444,7 +444,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
if (dsa == NULL)
DST_RET(ISC_R_NOMEMORY);
dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
key->opaque = dsa;
key->keydata.dsa = dsa;
for (i=0; i < priv.nelements; i++) {
BIGNUM *bn;

View File

@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
* $Id: opensslrsa_link.c,v 1.12 2006/11/07 21:22:11 marka Exp $
* $Id: opensslrsa_link.c,v 1.13 2006/12/04 01:52:46 marka Exp $
*/
#ifdef OPENSSL
@@ -112,7 +112,7 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
if (md5ctx == NULL)
return (ISC_R_NOMEMORY);
isc_md5_init(md5ctx);
dctx->opaque = md5ctx;
dctx->ctxdata.md5ctx = md5ctx;
} else {
isc_sha1_t *sha1ctx;
@@ -120,7 +120,7 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
if (sha1ctx == NULL)
return (ISC_R_NOMEMORY);
isc_sha1_init(sha1ctx);
dctx->opaque = sha1ctx;
dctx->ctxdata.sha1ctx = sha1ctx;
}
return (ISC_R_SUCCESS);
@@ -132,21 +132,22 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
dctx->key->key_alg == DST_ALG_RSASHA1);
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->opaque;
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
if (md5ctx != NULL) {
isc_md5_invalidate(md5ctx);
isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
dctx->ctxdata.md5ctx = NULL;
}
} else {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
if (sha1ctx != NULL) {
isc_sha1_invalidate(sha1ctx);
isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
dctx->ctxdata.sha1ctx = NULL;
}
}
dctx->opaque = NULL;
}
static isc_result_t
@@ -155,10 +156,10 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
dctx->key->key_alg == DST_ALG_RSASHA1);
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->opaque;
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
isc_md5_update(md5ctx, data->base, data->length);
} else {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_update(sha1ctx, data->base, data->length);
}
return (ISC_R_SUCCESS);
@@ -167,7 +168,7 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
static isc_result_t
opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
dst_key_t *key = dctx->key;
RSA *rsa = key->opaque;
RSA *rsa = key->keydata.rsa;
isc_region_t r;
/* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
@@ -189,12 +190,12 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
return (ISC_R_NOSPACE);
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->opaque;
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
isc_md5_final(md5ctx, digest);
type = NID_md5;
digestlen = ISC_MD5_DIGESTLENGTH;
} else {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_final(sha1ctx, digest);
type = NID_sha1;
digestlen = ISC_SHA1_DIGESTLENGTH;
@@ -219,7 +220,7 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static isc_result_t
opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dst_key_t *key = dctx->key;
RSA *rsa = key->opaque;
RSA *rsa = key->keydata.rsa;
/* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
int status = 0;
@@ -230,12 +231,12 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dctx->key->key_alg == DST_ALG_RSASHA1);
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->opaque;
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
isc_md5_final(md5ctx, digest);
type = NID_md5;
digestlen = ISC_MD5_DIGESTLENGTH;
} else {
isc_sha1_t *sha1ctx = dctx->opaque;
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_final(sha1ctx, digest);
type = NID_sha1;
digestlen = ISC_SHA1_DIGESTLENGTH;
@@ -257,8 +258,8 @@ opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
RSA *rsa1, *rsa2;
rsa1 = (RSA *) key1->opaque;
rsa2 = (RSA *) key2->opaque;
rsa1 = key1->keydata.rsa;
rsa2 = key2->keydata.rsa;
if (rsa1 == NULL && rsa2 == NULL)
return (ISC_TRUE);
@@ -309,7 +310,7 @@ opensslrsa_generate(dst_key_t *key, int exp) {
if (RSA_generate_key_ex(rsa, key->key_size, e, &cb)) {
BN_free(e);
SET_FLAGS(rsa);
key->opaque = rsa;
key->keydata.opaque = rsa;
return (ISC_R_SUCCESS);
}
@@ -331,7 +332,7 @@ err:
if (rsa == NULL)
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
SET_FLAGS(rsa);
key->opaque = rsa;
key->keydata.opaque = rsa;
return (ISC_R_SUCCESS);
#endif
@@ -339,15 +340,15 @@ err:
static isc_boolean_t
opensslrsa_isprivate(const dst_key_t *key) {
RSA *rsa = (RSA *) key->opaque;
RSA *rsa = (RSA *) key->keydata.opaque;
return (ISC_TF(rsa != NULL && rsa->d != NULL));
}
static void
opensslrsa_destroy(dst_key_t *key) {
RSA *rsa = key->opaque;
RSA *rsa = key->keydata.opaque;
RSA_free(rsa);
key->opaque = NULL;
key->keydata.opaque = NULL;
}
@@ -358,9 +359,9 @@ opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
unsigned int e_bytes;
unsigned int mod_bytes;
REQUIRE(key->opaque != NULL);
REQUIRE(key->keydata.rsa != NULL);
rsa = (RSA *) key->opaque;
rsa = key->keydata.rsa;
isc_buffer_availableregion(data, &r);
@@ -437,7 +438,7 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
isc_buffer_forward(data, r.length);
key->opaque = (void *) rsa;
key->keydata.rsa = rsa;
return (ISC_R_SUCCESS);
}
@@ -451,10 +452,10 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
unsigned char *bufs[8];
isc_result_t result;
if (key->opaque == NULL)
if (key->keydata.rsa == NULL)
return (DST_R_NULLKEY);
rsa = (RSA *) key->opaque;
rsa = key->keydata.rsa;
for (i = 0; i < 8; i++) {
bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
@@ -543,7 +544,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
if (rsa == NULL)
DST_RET(ISC_R_NOMEMORY);
SET_FLAGS(rsa);
key->opaque = rsa;
key->keydata.rsa = rsa;
for (i = 0; i < priv.nelements; i++) {
BIGNUM *bn;

52
lib/dns/spnego.asn1 Normal file
View File

@@ -0,0 +1,52 @@
-- Copyright (C) The Internet Society 2005. This version of
-- this module is part of RFC 4178; see the RFC itself for
-- full legal notices.
-- (The above copyright notice is per RFC 3978 5.6 (a), q.v.)
-- $Id: spnego.asn1,v 1.2 2006/12/04 01:52:46 marka Exp $
-- This is the SPNEGO ASN.1 module from RFC 4178, tweaked
-- to get the Heimdal ASN.1 compiler to accept it.
SPNEGOASNOneSpec DEFINITIONS ::= BEGIN
MechType ::= OBJECT IDENTIFIER
MechTypeList ::= SEQUENCE OF MechType
ContextFlags ::= BIT STRING {
delegFlag (0),
mutualFlag (1),
replayFlag (2),
sequenceFlag (3),
anonFlag (4),
confFlag (5),
integFlag (6)
}
NegTokenInit ::= SEQUENCE {
mechTypes [0] MechTypeList,
reqFlags [1] ContextFlags OPTIONAL,
mechToken [2] OCTET STRING OPTIONAL,
mechListMIC [3] OCTET STRING OPTIONAL
}
NegTokenResp ::= SEQUENCE {
negState [0] ENUMERATED {
accept-completed (0),
accept-incomplete (1),
reject (2),
request-mic (3)
} OPTIONAL,
supportedMech [1] MechType OPTIONAL,
responseToken [2] OCTET STRING OPTIONAL,
mechListMIC [3] OCTET STRING OPTIONAL
}
NegotiationToken ::= CHOICE {
negTokenInit [0] NegTokenInit,
negTokenResp [1] NegTokenResp
}
END

1883
lib/dns/spnego.c Normal file

File diff suppressed because it is too large Load Diff

71
lib/dns/spnego.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: spnego.h,v 1.2 2006/12/04 01:52:46 marka Exp $ */
/*! \file
* \brief
* Entry points into portable SPNEGO implementation.
* See spnego.c for information on the SPNEGO implementation itself.
*/
#ifndef _SPNEGO_H_
#define _SPNEGO_H_
/*%
* Wrapper for GSSAPI gss_init_sec_context(), using portable SPNEGO
* implementation instead of the one that's part of the GSSAPI
* library. Takes arguments identical to the standard GSSAPI
* function, uses standard gss_init_sec_context() to handle
* everything inside the SPNEGO wrapper.
*/
OM_uint32
gss_init_sec_context_spnego(OM_uint32 *,
const gss_cred_id_t,
gss_ctx_id_t *,
const gss_name_t,
const gss_OID,
OM_uint32,
OM_uint32,
const gss_channel_bindings_t,
const gss_buffer_t,
gss_OID *,
gss_buffer_t,
OM_uint32 *,
OM_uint32 *);
/*%
* Wrapper for GSSAPI gss_accept_sec_context(), using portable SPNEGO
* implementation instead of the one that's part of the GSSAPI
* library. Takes arguments identical to the standard GSSAPI
* function. Checks the OID of the input token to see if it's SPNEGO;
* if so, processes it, otherwise hands the call off to the standard
* gss_accept_sec_context() function.
*/
OM_uint32 gss_accept_sec_context_spnego(OM_uint32 *,
gss_ctx_id_t *,
const gss_cred_id_t,
const gss_buffer_t,
const gss_channel_bindings_t,
gss_name_t *,
gss_OID *,
gss_buffer_t,
OM_uint32 *,
OM_uint32 *,
gss_cred_id_t *);
#endif

885
lib/dns/spnego_asn1.c Normal file
View File

@@ -0,0 +1,885 @@
/*
* Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: spnego_asn1.c,v 1.2 2006/12/04 01:52:46 marka Exp $ */
/*! \file
* \brief Method routines generated from SPNEGO ASN.1 module.
* See spnego_asn1.pl for details. Do not edit.
*/
/* Generated from spnego.asn1 */
/* Do not edit */
#ifndef __asn1_h__
#define __asn1_h__
#ifndef __asn1_common_definitions__
#define __asn1_common_definitions__
typedef struct octet_string {
size_t length;
void *data;
} octet_string;
typedef char *general_string;
typedef char *utf8_string;
typedef struct oid {
size_t length;
unsigned *components;
} oid;
#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
do { \
(BL) = length_##T((S)); \
(B) = malloc((BL)); \
if((B) == NULL) { \
(R) = ENOMEM; \
} else { \
(R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
(S), (L)); \
if((R) != 0) { \
free((B)); \
(B) = NULL; \
} \
} \
} while (0)
#endif
/*
* MechType ::= OBJECT IDENTIFIER
*/
typedef oid MechType;
static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *);
static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *);
static void free_MechType(MechType *);
/* unused declaration: length_MechType */
/* unused declaration: copy_MechType */
/*
* MechTypeList ::= SEQUENCE OF MechType
*/
typedef struct MechTypeList {
unsigned int len;
MechType *val;
} MechTypeList;
static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *);
static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *);
static void free_MechTypeList(MechTypeList *);
/* unused declaration: length_MechTypeList */
/* unused declaration: copy_MechTypeList */
/*
* ContextFlags ::= BIT STRING { delegFlag(0), mutualFlag(1), replayFlag(2),
* sequenceFlag(3), anonFlag(4), confFlag(5), integFlag(6) }
*/
typedef struct ContextFlags {
unsigned int delegFlag:1;
unsigned int mutualFlag:1;
unsigned int replayFlag:1;
unsigned int sequenceFlag:1;
unsigned int anonFlag:1;
unsigned int confFlag:1;
unsigned int integFlag:1;
} ContextFlags;
static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *);
static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *);
static void free_ContextFlags(ContextFlags *);
/* unused declaration: length_ContextFlags */
/* unused declaration: copy_ContextFlags */
/* unused declaration: ContextFlags2int */
/* unused declaration: int2ContextFlags */
/* unused declaration: asn1_ContextFlags_units */
/*
* NegTokenInit ::= SEQUENCE { mechTypes[0] MechTypeList, reqFlags[1]
* ContextFlags OPTIONAL, mechToken[2] OCTET STRING OPTIONAL,
* mechListMIC[3] OCTET STRING OPTIONAL }
*/
typedef struct NegTokenInit {
MechTypeList mechTypes;
ContextFlags *reqFlags;
octet_string *mechToken;
octet_string *mechListMIC;
} NegTokenInit;
static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *);
static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *);
static void free_NegTokenInit(NegTokenInit *);
/* unused declaration: length_NegTokenInit */
/* unused declaration: copy_NegTokenInit */
/*
* NegTokenResp ::= SEQUENCE { negState[0] ENUMERATED {
* accept-completed(0), accept-incomplete(1), reject(2), request-mic(3) }
* OPTIONAL, supportedMech[1] MechType OPTIONAL, responseToken[2] OCTET
* STRING OPTIONAL, mechListMIC[3] OCTET STRING OPTIONAL }
*/
typedef struct NegTokenResp {
enum {
accept_completed = 0,
accept_incomplete = 1,
reject = 2,
request_mic = 3
} *negState;
MechType *supportedMech;
octet_string *responseToken;
octet_string *mechListMIC;
} NegTokenResp;
static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *);
static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *);
static void free_NegTokenResp(NegTokenResp *);
/* unused declaration: length_NegTokenResp */
/* unused declaration: copy_NegTokenResp */
#endif /* __asn1_h__ */
/* Generated from spnego.asn1 */
/* Do not edit */
#define BACK if (e) return e; p -= l; len -= l; ret += l
static int
encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size)
{
size_t ret = 0;
size_t l;
int i, e;
i = 0;
e = encode_oid(p, len, data, &l);
BACK;
*size = ret;
return 0;
}
#define FORW if(e) goto fail; p += l; len -= l; ret += l
static int
decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size)
{
size_t ret = 0, reallen;
size_t l;
int e;
memset(data, 0, sizeof(*data));
reallen = 0;
e = decode_oid(p, len, data, &l);
FORW;
if (size)
*size = ret;
return 0;
fail:
free_MechType(data);
return e;
}
static void
free_MechType(MechType * data)
{
free_oid(data);
}
/* unused function: length_MechType */
/* unused function: copy_MechType */
/* Generated from spnego.asn1 */
/* Do not edit */
#define BACK if (e) return e; p -= l; len -= l; ret += l
static int
encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size)
{
size_t ret = 0;
size_t l;
int i, e;
i = 0;
for (i = (data)->len - 1; i >= 0; --i) {
int oldret = ret;
ret = 0;
e = encode_MechType(p, len, &(data)->val[i], &l);
BACK;
ret += oldret;
}
e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
BACK;
*size = ret;
return 0;
}
#define FORW if(e) goto fail; p += l; len -= l; ret += l
static int
decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size)
{
size_t ret = 0, reallen;
size_t l;
int e;
memset(data, 0, sizeof(*data));
reallen = 0;
e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
FORW;
if (len < reallen)
return ASN1_OVERRUN;
len = reallen;
{
size_t origlen = len;
int oldret = ret;
ret = 0;
(data)->len = 0;
(data)->val = NULL;
while (ret < origlen) {
(data)->len++;
(data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l);
FORW;
len = origlen - ret;
}
ret += oldret;
}
if (size)
*size = ret;
return 0;
fail:
free_MechTypeList(data);
return e;
}
static void
free_MechTypeList(MechTypeList * data)
{
while ((data)->len) {
free_MechType(&(data)->val[(data)->len - 1]);
(data)->len--;
}
free((data)->val);
(data)->val = NULL;
}
/* unused function: length_MechTypeList */
/* unused function: copy_MechTypeList */
/* Generated from spnego.asn1 */
/* Do not edit */
#define BACK if (e) return e; p -= l; len -= l; ret += l
static int
encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size)
{
size_t ret = 0;
size_t l;
int i, e;
i = 0;
{
unsigned char c = 0;
*p-- = c;
len--;
ret++;
c = 0;
*p-- = c;
len--;
ret++;
c = 0;
*p-- = c;
len--;
ret++;
c = 0;
if (data->integFlag)
c |= 1 << 1;
if (data->confFlag)
c |= 1 << 2;
if (data->anonFlag)
c |= 1 << 3;
if (data->sequenceFlag)
c |= 1 << 4;
if (data->replayFlag)
c |= 1 << 5;
if (data->mutualFlag)
c |= 1 << 6;
if (data->delegFlag)
c |= 1 << 7;
*p-- = c;
*p-- = 0;
len -= 2;
ret += 2;
}
e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l);
BACK;
*size = ret;
return 0;
}
#define FORW if(e) goto fail; p += l; len -= l; ret += l
static int
decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size)
{
size_t ret = 0, reallen;
size_t l;
int e;
memset(data, 0, sizeof(*data));
reallen = 0;
e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l);
FORW;
if (len < reallen)
return ASN1_OVERRUN;
p++;
len--;
reallen--;
ret++;
data->delegFlag = (*p >> 7) & 1;
data->mutualFlag = (*p >> 6) & 1;
data->replayFlag = (*p >> 5) & 1;
data->sequenceFlag = (*p >> 4) & 1;
data->anonFlag = (*p >> 3) & 1;
data->confFlag = (*p >> 2) & 1;
data->integFlag = (*p >> 1) & 1;
p += reallen;
len -= reallen;
ret += reallen;
if (size)
*size = ret;
return 0;
fail:
free_ContextFlags(data);
return e;
}
static void
free_ContextFlags(ContextFlags * data)
{
(void)data;
}
/* unused function: length_ContextFlags */
/* unused function: copy_ContextFlags */
/* unused function: ContextFlags2int */
/* unused function: int2ContextFlags */
/* unused variable: ContextFlags_units */
/* unused function: asn1_ContextFlags_units */
/* Generated from spnego.asn1 */
/* Do not edit */
#define BACK if (e) return e; p -= l; len -= l; ret += l
static int
encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size)
{
size_t ret = 0;
size_t l;
int i, e;
i = 0;
if ((data)->mechListMIC) {
int oldret = ret;
ret = 0;
e = encode_octet_string(p, len, (data)->mechListMIC, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
BACK;
ret += oldret;
}
if ((data)->mechToken) {
int oldret = ret;
ret = 0;
e = encode_octet_string(p, len, (data)->mechToken, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
BACK;
ret += oldret;
}
if ((data)->reqFlags) {
int oldret = ret;
ret = 0;
e = encode_ContextFlags(p, len, (data)->reqFlags, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
BACK;
ret += oldret;
} {
int oldret = ret;
ret = 0;
e = encode_MechTypeList(p, len, &(data)->mechTypes, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
BACK;
ret += oldret;
}
e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
BACK;
*size = ret;
return 0;
}
#define FORW if(e) goto fail; p += l; len -= l; ret += l
static int
decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size)
{
size_t ret = 0, reallen;
size_t l;
int e;
memset(data, 0, sizeof(*data));
reallen = 0;
e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
FORW;
{
int dce_fix;
if ((dce_fix = fix_dce(reallen, &len)) < 0)
return ASN1_BAD_FORMAT;
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
if (e)
return e;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
e = decode_MechTypeList(p, len, &(data)->mechTypes, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
if (e)
(data)->reqFlags = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->reqFlags = malloc(sizeof(*(data)->reqFlags));
if ((data)->reqFlags == NULL)
return ENOMEM;
e = decode_ContextFlags(p, len, (data)->reqFlags, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
if (e)
(data)->mechToken = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->mechToken = malloc(sizeof(*(data)->mechToken));
if ((data)->mechToken == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->mechToken, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
if (e)
(data)->mechListMIC = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
if ((data)->mechListMIC == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->mechListMIC, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
}
}
if (size)
*size = ret;
return 0;
fail:
free_NegTokenInit(data);
return e;
}
static void
free_NegTokenInit(NegTokenInit * data)
{
free_MechTypeList(&(data)->mechTypes);
if ((data)->reqFlags) {
free_ContextFlags((data)->reqFlags);
free((data)->reqFlags);
(data)->reqFlags = NULL;
}
if ((data)->mechToken) {
free_octet_string((data)->mechToken);
free((data)->mechToken);
(data)->mechToken = NULL;
}
if ((data)->mechListMIC) {
free_octet_string((data)->mechListMIC);
free((data)->mechListMIC);
(data)->mechListMIC = NULL;
}
}
/* unused function: length_NegTokenInit */
/* unused function: copy_NegTokenInit */
/* Generated from spnego.asn1 */
/* Do not edit */
#define BACK if (e) return e; p -= l; len -= l; ret += l
static int
encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size)
{
size_t ret = 0;
size_t l;
int i, e;
i = 0;
if ((data)->mechListMIC) {
int oldret = ret;
ret = 0;
e = encode_octet_string(p, len, (data)->mechListMIC, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
BACK;
ret += oldret;
}
if ((data)->responseToken) {
int oldret = ret;
ret = 0;
e = encode_octet_string(p, len, (data)->responseToken, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
BACK;
ret += oldret;
}
if ((data)->supportedMech) {
int oldret = ret;
ret = 0;
e = encode_MechType(p, len, (data)->supportedMech, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
BACK;
ret += oldret;
}
if ((data)->negState) {
int oldret = ret;
ret = 0;
e = encode_enumerated(p, len, (data)->negState, &l);
BACK;
e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
BACK;
ret += oldret;
}
e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
BACK;
*size = ret;
return 0;
}
#define FORW if(e) goto fail; p += l; len -= l; ret += l
static int
decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size)
{
size_t ret = 0, reallen;
size_t l;
int e;
memset(data, 0, sizeof(*data));
reallen = 0;
e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
FORW;
{
int dce_fix;
if ((dce_fix = fix_dce(reallen, &len)) < 0)
return ASN1_BAD_FORMAT;
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
if (e)
(data)->negState = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->negState = malloc(sizeof(*(data)->negState));
if ((data)->negState == NULL)
return ENOMEM;
e = decode_enumerated(p, len, (data)->negState, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
if (e)
(data)->supportedMech = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->supportedMech = malloc(sizeof(*(data)->supportedMech));
if ((data)->supportedMech == NULL)
return ENOMEM;
e = decode_MechType(p, len, (data)->supportedMech, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
if (e)
(data)->responseToken = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->responseToken = malloc(sizeof(*(data)->responseToken));
if ((data)->responseToken == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->responseToken, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
{
size_t newlen, oldlen;
e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
if (e)
(data)->mechListMIC = NULL;
else {
p += l;
len -= l;
ret += l;
e = der_get_length(p, len, &newlen, &l);
FORW;
{
int dce_fix;
oldlen = len;
if ((dce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
if ((data)->mechListMIC == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->mechListMIC, &l);
FORW;
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
len = oldlen - newlen;
}
}
}
if (dce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
}
}
if (size)
*size = ret;
return 0;
fail:
free_NegTokenResp(data);
return e;
}
static void
free_NegTokenResp(NegTokenResp * data)
{
if ((data)->negState) {
free((data)->negState);
(data)->negState = NULL;
}
if ((data)->supportedMech) {
free_MechType((data)->supportedMech);
free((data)->supportedMech);
(data)->supportedMech = NULL;
}
if ((data)->responseToken) {
free_octet_string((data)->responseToken);
free((data)->responseToken);
(data)->responseToken = NULL;
}
if ((data)->mechListMIC) {
free_octet_string((data)->mechListMIC);
free((data)->mechListMIC);
(data)->mechListMIC = NULL;
}
}
/* unused function: length_NegTokenResp */
/* unused function: copy_NegTokenResp */
/* Generated from spnego.asn1 */
/* Do not edit */
/* CHOICE */
/* unused variable: asn1_NegotiationToken_dummy_holder */

200
lib/dns/spnego_asn1.pl Normal file
View File

@@ -0,0 +1,200 @@
#!/bin/bin/perl -w
#
# Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: spnego_asn1.pl,v 1.2 2006/12/04 01:52:46 marka Exp $
# Our SPNEGO implementation uses some functions generated by the
# Heimdal ASN.1 compiler, which this script then whacks a bit to make
# them work properly in this stripped down implementation. We don't
# want to require our users to have a copy of the compiler, so we ship
# the output of this script, but we need to keep the script around in
# any case to cope with future changes to the SPNEGO ASN.1 code, so we
# might as well supply the script for users who want it.
# Overall plan: run the ASN.1 compiler, run each of its output files
# through indent, fix up symbols and whack everything to be static.
# We use indent for two reasons: (1) to whack the Heimdal compiler's
# output into something closer to ISC's coding standard, and (2) to
# make it easier for this script to parse the result.
# Output from this script is C code which we expect to be #included
# into another C file, which is why everything generated by this
# script is marked "static". The intent is to minimize the number of
# extern symbols exported by the SPNEGO implementation, to avoid
# potential conflicts with the GSSAPI libraries.
###
# Filename of the ASN.1 specification. Hardcoded for the moment
# since this script is intended for compiling exactly one module.
my $asn1_source = $ENV{ASN1_SOURCE} || "spnego.asn1";
# Heimdal ASN.1 compiler. This script was written using the version
# from Heimdal 0.7.1. To build this, download a copy of
# heimdal-0.7.1.tar.gz, configure and build with the default options,
# then look for the compiler in heimdal-0.7.1/lib/asn1/asn1_compile.
my $asn1_compile = $ENV{ASN1_COMPILE} || "asn1_compile";
# BSD indent program. This script was written using the version of
# indent that comes with FreeBSD 4.11-STABLE. The GNU project, as
# usual, couldn't resist the temptation to monkey with indent's
# command line syntax, so this probably won't work with GNU indent.
my $indent = $ENV{INDENT} || "indent";
###
# Step 1: run the compiler. Input is the ASN.1 file. Outputs are a
# header file (name specified on command line without the .h suffix),
# a file called "asn1_files" listing the names of the other output
# files, and a set of files containing C code generated by the
# compiler for each data type that the compiler found.
if (! -r $asn1_source || system($asn1_compile, $asn1_source, "asn1")) {
die("Couldn't compile ASN.1 source file $asn1_source\n");
}
my @files = ("asn1.h");
open(F, "asn1_files")
or die("Couldn't open asn1_files: $!\n");
push(@files, split)
while (<F>);
close(F);
unlink("asn1_files");
###
# Step 2: generate header block.
print(q~/*
* Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: spnego_asn1.pl,v 1.2 2006/12/04 01:52:46 marka Exp $ */
/*! \file
* \brief Method routines generated from SPNEGO ASN.1 module.
* See spnego_asn1.pl for details. Do not edit.
*/
~);
###
# Step 3: read and process each generated file, then delete it.
my $output;
for my $file (@files) {
my $is_static = 0;
system($indent, "-di1", "-ldi1", $file) == 0
or die("Couldn't indent $file");
unlink("$file.BAK");
open(F, $file)
or die("Couldn't open $file: $!");
while (<F>) {
# Symbol name fixups
s/heim_general_string/general_string/g;
s/heim_octet_string/octet_string/g;
s/heim_oid/oid/g;
s/heim_utf8_string/utf8_string/g;
# Convert all externs to statics
if (/^static/) {
$is_static = 1;
}
if (!/^typedef/ &&
!$is_static &&
/^[A-Za-z_][0-9A-Za-z_]*[ \t]*($|[^:0-9A-Za-z_])/) {
$_ = "static " . $_;
$is_static = 1;
}
if (/[{};]/) {
$is_static = 0;
}
# Suppress file inclusion, pass anything else through
if (!/#include/) {
$output .= $_;
}
}
close(F);
unlink($file);
}
# Step 4: Delete unused stuff to avoid code bloat and compiler warnings.
my @unused_functions = qw(ContextFlags2int
int2ContextFlags
asn1_ContextFlags_units
length_NegTokenInit
copy_NegTokenInit
length_NegTokenResp
copy_NegTokenResp
length_MechTypeList
length_MechType
copy_MechTypeList
length_ContextFlags
copy_ContextFlags
copy_MechType);
$output =~ s<^static [^\n]+\n$_\(.+?^}></* unused function: $_ */\n>ms
foreach (@unused_functions);
$output =~ s<^static .+$_\(.*\);$></* unused declaration: $_ */>m
foreach (@unused_functions);
$output =~ s<^static struct units ContextFlags_units\[\].+?^};>
</* unused variable: ContextFlags_units */>ms;
$output =~ s<^static int asn1_NegotiationToken_dummy_holder = 1;>
</* unused variable: asn1_NegotiationToken_dummy_holder */>ms;
$output =~ s<^static void\nfree_ContextFlags\(ContextFlags \* data\)\n{\n>
<$&\t(void)data;\n>ms;
# Step 5: Write the result.
print($output);

View File

@@ -17,7 +17,7 @@
/*! \file */
/*
* $Id: ssu.c,v 1.28 2006/02/16 23:51:33 marka Exp $
* $Id: ssu.c,v 1.29 2006/12/04 01:52:46 marka Exp $
* Principal Author: Brian Wellington
*/
@@ -33,6 +33,8 @@
#include <dns/name.h>
#include <dns/ssu.h>
#include <dst/gssapi.h>
#define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T')
#define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
@@ -261,34 +263,52 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
if (signer == NULL)
return (ISC_FALSE);
rule = ISC_LIST_HEAD(table->rules);
rule = ISC_LIST_NEXT(rule, link);
for (rule = ISC_LIST_HEAD(table->rules);
rule != NULL;
rule = ISC_LIST_NEXT(rule, link))
{
switch (rule->matchtype) {
case DNS_SSUMATCHTYPE_NAME:
case DNS_SSUMATCHTYPE_SUBDOMAIN:
case DNS_SSUMATCHTYPE_WILDCARD:
case DNS_SSUMATCHTYPE_SELF:
case DNS_SSUMATCHTYPE_SELFSUB:
case DNS_SSUMATCHTYPE_SELFWILD:
if (dns_name_iswildcard(rule->identity)) {
if (!dns_name_matcheswildcard(signer, rule->identity))
if (!dns_name_matcheswildcard(signer,
rule->identity))
continue;
} else if (!dns_name_equal(signer, rule->identity))
}
else {
if (!dns_name_equal(signer, rule->identity))
continue;
}
break;
}
if (rule->matchtype == DNS_SSUMATCHTYPE_NAME) {
switch (rule->matchtype) {
case DNS_SSUMATCHTYPE_NAME:
if (!dns_name_equal(name, rule->name))
continue;
} else if (rule->matchtype == DNS_SSUMATCHTYPE_SUBDOMAIN) {
break;
case DNS_SSUMATCHTYPE_SUBDOMAIN:
if (!dns_name_issubdomain(name, rule->name))
continue;
} else if (rule->matchtype == DNS_SSUMATCHTYPE_WILDCARD) {
break;
case DNS_SSUMATCHTYPE_WILDCARD:
if (!dns_name_matcheswildcard(name, rule->name))
continue;
} else if (rule->matchtype == DNS_SSUMATCHTYPE_SELF) {
break;
case DNS_SSUMATCHTYPE_SELF:
if (!dns_name_equal(signer, name))
continue;
} else if (rule->matchtype == DNS_SSUMATCHTYPE_SELFSUB) {
break;
case DNS_SSUMATCHTYPE_SELFSUB:
if (!dns_name_issubdomain(name, signer))
continue;
} else if (rule->matchtype == DNS_SSUMATCHTYPE_SELFWILD) {
break;
case DNS_SSUMATCHTYPE_SELFWILD:
dns_fixedname_init(&fixed);
wildcard = dns_fixedname_name(&fixed);
result = dns_name_concatenate(dns_wildcardname, signer,
@@ -297,6 +317,31 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
continue;
if (!dns_name_matcheswildcard(name, wildcard))
continue;
break;
case DNS_SSUMATCHTYPE_SELFKRB5:
if (!dst_gssapi_identitymatchesrealmkrb5(signer, name,
rule->identity))
continue;
break;
case DNS_SSUMATCHTYPE_SELFMS:
if (!dst_gssapi_identitymatchesrealmms(signer, name,
rule->identity))
continue;
break;
case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
if (!dns_name_issubdomain(name, rule->name))
continue;
if (!dst_gssapi_identitymatchesrealmkrb5(signer, NULL,
rule->identity))
continue;
break;
case DNS_SSUMATCHTYPE_SUBDOMAINMS:
if (!dns_name_issubdomain(name, rule->name))
continue;
if (!dst_gssapi_identitymatchesrealmms(signer, NULL,
rule->identity))
continue;
break;
}
if (rule->ntypes == 0) {

View File

@@ -16,7 +16,7 @@
*/
/*
* $Id: tkey.c,v 1.81 2005/11/30 03:33:49 marka Exp $
* $Id: tkey.c,v 1.82 2006/12/04 01:52:46 marka Exp $
*/
/*! \file */
#include <config.h>
@@ -66,6 +66,20 @@ tkey_log(const char *fmt, ...) {
va_end(ap);
}
static void
_dns_tkey_dumpmessage(dns_message_t *msg) {
isc_buffer_t outbuf;
unsigned char output[2048];
isc_result_t result;
isc_buffer_init(&outbuf, output, sizeof(output));
result = dns_message_totext(msg, &dns_master_style_debug, 0,
&outbuf);
/* XXXMLG ignore result */
fprintf(stderr, "%.*s\n", (int)isc_buffer_usedlength(&outbuf),
(char *)isc_buffer_base(&outbuf));
}
isc_result_t
dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp)
{
@@ -107,6 +121,8 @@ dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) {
dns_name_free(tctx->domain, mctx);
isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t));
}
if (tctx->gsscred != NULL)
dst_gssapi_releasecred(&tctx->gsscred);
isc_entropy_detach(&tctx->ectx);
isc_mem_put(mctx, tctx, sizeof(dns_tkeyctx_t));
isc_mem_detach(&mctx);
@@ -280,8 +296,7 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
*/
for (result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
result == ISC_R_SUCCESS && !found_key;
result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL))
{
result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL)) {
keyname = NULL;
dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);
keyset = NULL;
@@ -292,8 +307,7 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
for (result = dns_rdataset_first(keyset);
result == ISC_R_SUCCESS && !found_key;
result = dns_rdataset_next(keyset))
{
result = dns_rdataset_next(keyset)) {
dns_rdataset_current(keyset, &keyrdata);
pubkey = NULL;
result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
@@ -410,13 +424,16 @@ process_gsstkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
{
isc_result_t result = ISC_R_SUCCESS;
dst_key_t *dstkey = NULL;
void *gssctx = NULL;
dns_tsigkey_t *tsigkey = NULL;
dns_fixedname_t principal;
isc_stdtime_t now;
isc_region_t intoken;
unsigned char array[1024];
isc_buffer_t outtoken;
isc_buffer_t *outtoken_p = &outtoken;
gss_ctx_id_t gss_ctx = NULL;
UNUSED(namelist);
UNUSED(signer);
if (tctx->gsscred == NULL)
return (ISC_R_NOPERM);
@@ -424,48 +441,76 @@ process_gsstkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) &&
!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
tkeyout->error = dns_tsigerror_badalg;
tkey_log("process_gsstkey(): dns_tsigerror_badalg"); /* XXXSRA */
return (ISC_R_SUCCESS);
}
/*
* XXXDCL need to check for key expiry per 4.1.1
* XXXDCL need a way to check fully established, perhaps w/key_flags
*/
intoken.base = tkeyin->key;
intoken.length = tkeyin->keylen;
isc_buffer_init(&outtoken, array, sizeof(array));
RETERR(dst_gssapi_acceptctx(name, tctx->gsscred, &intoken,
&outtoken, &gssctx));
result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
if (result == ISC_R_SUCCESS)
gss_ctx = dst_key_getgssctx(tsigkey->key);
dstkey = NULL;
RETERR(dst_key_fromgssapi(name, gssctx, msg->mctx, &dstkey));
memset(&outtoken, 0, sizeof(outtoken));
result = dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
dstkey, ISC_TRUE, signer,
tkeyin->inception, tkeyin->expire,
msg->mctx, ring, NULL);
#if 1
if (result != ISC_R_SUCCESS)
goto failure;
#else
if (result == ISC_R_NOTFOUND) {
tkeyout->error = dns_tsigerror_badalg;
dns_fixedname_init(&principal);
result = dst_gssapi_acceptctx(tctx->gsscred, &intoken,
&outtoken, &gss_ctx,
dns_fixedname_name(&principal),
tctx->mctx);
if (tsigkey != NULL)
dns_tsigkey_detach(&tsigkey);
if (result == DNS_R_INVALIDTKEY) {
tkeyout->error = dns_tsigerror_badkey;
tkey_log("process_gsstkey(): dns_tsigerror_badkey"); /* XXXSRA */
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS)
} else if (result == ISC_R_FAILURE)
goto failure;
#endif
ENSURE(result == DNS_R_CONTINUE || result == ISC_R_SUCCESS);
/*
* XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times.
*/
if (tsigkey == NULL) {
RETERR(dst_key_fromgssapi(name, gss_ctx, msg->mctx, &dstkey));
RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
dstkey, ISC_TRUE,
dns_fixedname_name(&principal),
tkeyin->inception,
tkeyin->expire,
msg->mctx, ring, NULL));
}
/* This key is good for a long time */
isc_stdtime_get(&now);
tkeyout->inception = tkeyin->inception;
tkeyout->expire = tkeyin->expire;
tkeyout->key = isc_mem_get(msg->mctx,
isc_buffer_usedlength(&outtoken));
if (ISC_BUFFER_VALID(outtoken_p)) {
tkeyout->key = isc_buffer_base(&outtoken);
tkeyout->keylen = isc_buffer_usedlength(&outtoken);
isc_buffer_invalidate(&outtoken);
} else {
tkeyout->key = isc_mem_get(msg->mctx, tkeyin->keylen);
if (tkeyout->key == NULL) {
result = ISC_R_NOMEMORY;
goto failure;
}
tkeyout->keylen = isc_buffer_usedlength(&outtoken);
memcpy(tkeyout->key, isc_buffer_base(&outtoken), tkeyout->keylen);
tkeyout->keylen = tkeyin->keylen;
memcpy(tkeyout->key, tkeyin->key, tkeyin->keylen);
}
tkeyout->error = dns_rcode_noerror;
tkey_log("process_gsstkey(): dns_tsigerror_noerror"); /* XXXSRA */
return (ISC_R_SUCCESS);
@@ -473,6 +518,13 @@ process_gsstkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
if (dstkey != NULL)
dst_key_free(&dstkey);
if (ISC_BUFFER_VALID(outtoken_p))
isc_mem_put(tctx->mctx, isc_buffer_base(&outtoken),
isc_buffer_length(&outtoken));
tkey_log("process_gsstkey(): %s",
isc_result_totext(result)); /* XXXSRA */
return (result);
}
@@ -564,8 +616,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
*/
if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname,
dns_rdatatype_tkey, 0, &name,
&tkeyset) != ISC_R_SUCCESS)
{
&tkeyset) != ISC_R_SUCCESS) {
result = DNS_R_FORMERR;
tkey_log("dns_tkey_processquery: couldn't find a TKEY "
"matching the question");
@@ -632,7 +683,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
if (tkeyin.mode != DNS_TKEYMODE_DELETE) {
dns_tsigkey_t *tsigkey = NULL;
if (tctx->domain == NULL) {
if (tctx->domain == NULL && tkeyin.mode != DNS_TKEYMODE_GSSAPI) {
tkey_log("dns_tkey_processquery: tkey-domain not set");
result = DNS_R_REFUSED;
goto failure;
@@ -674,12 +725,22 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
if (result != ISC_R_SUCCESS)
goto failure;
}
if (tkeyin.mode == DNS_TKEYMODE_GSSAPI) {
/* Yup. This is a hack */
result = dns_name_concatenate(keyname, dns_rootname,
keyname, NULL);
if (result != ISC_R_SUCCESS)
goto failure;
} else {
result = dns_name_concatenate(keyname, tctx->domain,
keyname, NULL);
if (result != ISC_R_SUCCESS)
goto failure;
}
result = dns_tsigkey_find(&tsigkey, keyname, NULL, ring);
if (result == ISC_R_SUCCESS) {
tkeyout.error = dns_tsigerror_badname;
dns_tsigkey_detach(&tsigkey);
@@ -701,6 +762,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
RETERR(process_gsstkey(msg, signer, keyname, &tkeyin,
tctx, &tkeyout, ring,
&namelist));
break;
case DNS_TKEYMODE_DELETE:
tkeyout.error = dns_rcode_noerror;
@@ -759,7 +821,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
static isc_result_t
buildquery(dns_message_t *msg, dns_name_t *name,
dns_rdata_tkey_t *tkey)
dns_rdata_tkey_t *tkey, isc_boolean_t win2k)
{
dns_name_t *qname = NULL, *aname = NULL;
dns_rdataset_t *question = NULL, *tkeyset = NULL;
@@ -780,8 +842,9 @@ buildquery(dns_message_t *msg, dns_name_t *name,
dns_rdataset_makequestion(question, dns_rdataclass_any,
dns_rdatatype_tkey);
RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 512));
RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 2048));
RETERR(dns_message_gettemprdata(msg, &rdata));
RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any,
dns_rdatatype_tkey, tkey, dynbuf));
dns_message_takebuffer(msg, &dynbuf);
@@ -808,6 +871,14 @@ buildquery(dns_message_t *msg, dns_name_t *name,
ISC_LIST_APPEND(aname->list, tkeyset, link);
dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
/*
* Windows 2000 needs this in the answer section, not the additional
* section where the RFC specifies.
*/
if (win2k)
dns_message_addname(msg, aname, DNS_SECTION_ANSWER);
else
dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
return (ISC_R_SUCCESS);
@@ -823,6 +894,7 @@ buildquery(dns_message_t *msg, dns_name_t *name,
}
if (dynbuf != NULL)
isc_buffer_free(&dynbuf);
printf("buildquery error\n");
return (result);
}
@@ -869,7 +941,7 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
tkey.other = NULL;
tkey.otherlen = 0;
RETERR(buildquery(msg, name, &tkey));
RETERR(buildquery(msg, name, &tkey, ISC_FALSE));
if (nonce == NULL)
isc_mem_put(msg->mctx, r.base, 0);
@@ -900,23 +972,25 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
}
isc_result_t
dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name,
dns_name_t *gname, void *cred,
isc_uint32_t lifetime, void **context)
dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
isc_buffer_t *intoken, isc_uint32_t lifetime,
gss_ctx_id_t *context, isc_boolean_t win2k)
{
dns_rdata_tkey_t tkey;
isc_result_t result;
isc_stdtime_t now;
isc_buffer_t token;
unsigned char array[1024];
unsigned char array[2048];
UNUSED(intoken);
REQUIRE(msg != NULL);
REQUIRE(name != NULL);
REQUIRE(gname != NULL);
REQUIRE(context != NULL && *context == NULL);
REQUIRE(context != NULL);
isc_buffer_init(&token, array, sizeof(array));
result = dst_gssapi_initctx(gname, cred, NULL, &token, context);
result = dst_gssapi_initctx(gname, NULL, &token, context);
if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
return (result);
@@ -925,7 +999,12 @@ dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name,
ISC_LINK_INIT(&tkey.common, link);
tkey.mctx = NULL;
dns_name_init(&tkey.algorithm, NULL);
if (win2k)
dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm);
else
dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm);
isc_stdtime_get(&now);
tkey.inception = now;
tkey.expire = now + lifetime;
@@ -936,7 +1015,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name,
tkey.other = NULL;
tkey.otherlen = 0;
RETERR(buildquery(msg, name, &tkey));
RETERR(buildquery(msg, name, &tkey, win2k));
return (ISC_R_SUCCESS);
@@ -963,7 +1042,7 @@ dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) {
tkey.keylen = tkey.otherlen = 0;
tkey.key = tkey.other = NULL;
return (buildquery(msg, &key->name, &tkey));
return (buildquery(msg, &key->name, &tkey, ISC_FALSE));
}
static isc_result_t
@@ -1034,10 +1113,9 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
rtkey.mode != DNS_TKEYMODE_DIFFIEHELLMAN ||
rtkey.mode != qtkey.mode ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
rmsg->rcode != dns_rcode_noerror)
{
rmsg->rcode != dns_rcode_noerror) {
tkey_log("dns_tkey_processdhresponse: tkey mode invalid "
"or error set");
"or error set(1)");
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&qtkey);
goto failure;
@@ -1127,18 +1205,19 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
isc_result_t
dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *gname, void *cred, void **context,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring)
dns_name_t *gname, gss_ctx_id_t *context,
isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
dns_tsig_keyring_t *ring)
{
dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname;
dns_rdata_tkey_t rtkey, qtkey;
isc_buffer_t outtoken;
dst_key_t *dstkey = NULL;
isc_region_t r;
isc_buffer_t intoken;
isc_result_t result;
unsigned char array[1024];
REQUIRE(outtoken != NULL);
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
REQUIRE(gname != NULL);
@@ -1150,31 +1229,42 @@ dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ADDITIONAL));
/*
* Win2k puts the item in the ANSWER section, while the RFC
* specifies it should be in the ADDITIONAL section. Check first
* where it should be, and then where it may be.
*/
result = find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ADDITIONAL);
if (result == ISC_R_NOTFOUND)
result = find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ANSWER);
if (result != ISC_R_SUCCESS)
goto failure;
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
if (rtkey.error != dns_rcode_noerror ||
rtkey.mode != DNS_TKEYMODE_GSSAPI ||
!dns_name_equal(&rtkey.algorithm, &rtkey.algorithm))
{
tkey_log("dns_tkey_processdhresponse: tkey mode invalid "
"or error set");
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm)) {
tkey_log("dns_tkey_processgssresponse: tkey mode invalid "
"or error set(2) %d", rtkey.error);
_dns_tkey_dumpmessage(qmsg);
_dns_tkey_dumpmessage(rmsg);
result = DNS_R_INVALIDTKEY;
goto failure;
}
isc_buffer_init(&outtoken, array, sizeof(array));
r.base = rtkey.key;
r.length = rtkey.keylen;
RETERR(dst_gssapi_initctx(gname, cred, &r, &outtoken, context));
isc_buffer_init(outtoken, array, sizeof(array));
isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context));
dstkey = NULL;
RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx,
&dstkey));
RETERR(dns_tsigkey_createfromkey(tkeyname, DNS_TSIG_GSSAPI_NAME,
dstkey, ISC_TRUE, NULL,
dstkey, ISC_FALSE, NULL,
rtkey.inception, rtkey.expire,
rmsg->mctx, ring, outkey));
@@ -1182,6 +1272,9 @@ dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
return (result);
failure:
/*
* XXXSRA This probably leaks memory from rtkey and qtkey.
*/
return (result);
}
@@ -1212,10 +1305,9 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
rtkey.mode != DNS_TKEYMODE_DELETE ||
rtkey.mode != qtkey.mode ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
rmsg->rcode != dns_rcode_noerror)
{
rmsg->rcode != dns_rcode_noerror) {
tkey_log("dns_tkey_processdeleteresponse: tkey mode invalid "
"or error set");
"or error set(3)");
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&qtkey);
dns_rdata_freestruct(&rtkey);
@@ -1240,3 +1332,84 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
failure:
return (result);
}
isc_result_t
dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *server, gss_ctx_id_t *context,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
isc_boolean_t win2k)
{
dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname;
dns_rdata_tkey_t rtkey, qtkey;
isc_buffer_t intoken, outtoken;
dst_key_t *dstkey = NULL;
isc_result_t result;
unsigned char array[1024];
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
REQUIRE(server != NULL);
if (outkey != NULL)
REQUIRE(*outkey == NULL);
if (rmsg->rcode != dns_rcode_noerror)
return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
if (win2k == ISC_TRUE)
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ANSWER));
else
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
DNS_SECTION_ADDITIONAL));
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
if (rtkey.error != dns_rcode_noerror ||
rtkey.mode != DNS_TKEYMODE_GSSAPI ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm))
{
tkey_log("dns_tkey_processdhresponse: tkey mode invalid "
"or error set(4)");
result = DNS_R_INVALIDTKEY;
goto failure;
}
isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
isc_buffer_init(&outtoken, array, sizeof(array));
result = dst_gssapi_initctx(server, &intoken, &outtoken, context);
if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
return (result);
dstkey = NULL;
RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx,
&dstkey));
/*
* XXXSRA This seems confused. If we got CONTINUE from initctx,
* the GSS negotiation hasn't completed yet, so we can't sign
* anything yet.
*/
RETERR(dns_tsigkey_createfromkey(tkeyname,
(win2k
? DNS_TSIG_GSSAPIMS_NAME
: DNS_TSIG_GSSAPI_NAME),
dstkey, ISC_TRUE, NULL,
rtkey.inception, rtkey.expire,
rmsg->mctx, ring, outkey));
dns_rdata_freestruct(&rtkey);
return (result);
failure:
/*
* XXXSRA This probably leaks memory from qtkey.
*/
dns_rdata_freestruct(&rtkey);
return (result);
}

View File

@@ -16,7 +16,7 @@
*/
/*
* $Id: tsig.c,v 1.126 2006/05/02 04:07:36 marka Exp $
* $Id: tsig.c,v 1.127 2006/12/04 01:52:46 marka Exp $
*/
/*! \file */
#include <config.h>
@@ -28,10 +28,12 @@
#include <isc/refcount.h>
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/util.h>
#include <isc/time.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/fixedname.h>
#include <dns/rbt.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
@@ -74,7 +76,6 @@ dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5;
static unsigned char gsstsig_ndata[] = "\010gss-tsig";
static unsigned char gsstsig_offsets[] = { 0, 9 };
static dns_name_t gsstsig = {
DNS_NAME_MAGIC,
gsstsig_ndata, 10, 2,
@@ -83,13 +84,14 @@ static dns_name_t gsstsig = {
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapi_name = &gsstsig;
/* It's nice of Microsoft to conform to their own standard. */
/*
* Since Microsoft doesn't follow its own standard, we will use this
* alternate name as a second guess.
*/
static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com";
static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 };
static dns_name_t gsstsigms = {
DNS_NAME_MAGIC,
gsstsigms_ndata, 19, 4,
@@ -98,7 +100,6 @@ static dns_name_t gsstsigms = {
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapims_name = &gsstsigms;
static unsigned char hmacsha1_ndata[] = "\011hmac-sha1";
@@ -178,11 +179,17 @@ static void
tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
static void
cleanup_ring(dns_tsig_keyring_t *ring);
static void
tsigkey_free(dns_tsigkey_t *key);
static void
tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
va_list ap;
char message[4096];
char namestr[DNS_NAME_FORMATSIZE];
char creatorstr[DNS_NAME_FORMATSIZE];
if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
return;
@@ -190,10 +197,21 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
dns_name_format(&key->name, namestr, sizeof(namestr));
else
strcpy(namestr, "<null>");
if (key != NULL && key->generated)
dns_name_format(key->creator, creatorstr, sizeof(creatorstr));
va_start(ap, fmt);
vsnprintf(message, sizeof(message), fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG,
if (key != NULL && key->generated)
isc_log_write(dns_lctx,
DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG,
level, "tsig key '%s' (%s): %s",
namestr, creatorstr, message);
else
isc_log_write(dns_lctx,
DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG,
level, "tsig key '%s': %s", namestr, message);
}
@@ -329,6 +347,16 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
if (ring != NULL) {
RWLOCK(&ring->lock, isc_rwlocktype_write);
ring->writecount++;
/*
* Do on the fly cleaning. Find some nodes we might not
* want around any more.
*/
if (ring->writecount > 10) {
cleanup_ring(ring);
ring->writecount = 0;
}
ret = dns_rbt_addname(ring->keys, name, tkey);
if (ret != ISC_R_SUCCESS) {
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
@@ -337,7 +365,12 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
}
if (dstkey != NULL && dst_key_size(dstkey) < 64) {
/*
* Ignore this if it's a GSS key, since the key size is meaningless.
*/
if (dstkey != NULL && dst_key_size(dstkey) < 64 &&
!dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) &&
!dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
char namestr[DNS_NAME_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
@@ -374,6 +407,67 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
return (ret);
}
/*
* Find a few nodes to destroy if possible.
*/
static void
cleanup_ring(dns_tsig_keyring_t *ring)
{
isc_result_t result;
dns_rbtnodechain_t chain;
dns_name_t foundname;
dns_fixedname_t fixedorigin;
dns_name_t *origin;
isc_stdtime_t now;
dns_rbtnode_t *node;
dns_tsigkey_t *tkey;
/*
* Start up a new iterator each time.
*/
isc_stdtime_get(&now);
dns_name_init(&foundname, NULL);
dns_fixedname_init(&fixedorigin);
origin = dns_fixedname_name(&fixedorigin);
again:
dns_rbtnodechain_init(&chain, ring->mctx);
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname,
origin);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return;
}
for (;;) {
node = NULL;
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data;
if (tkey != NULL) {
tsig_log(tkey, 2, "tsig expire: generated=%d, refs=%d, expire=%d)", tkey->generated, isc_refcount_current(&tkey->refs), now - tkey->expire);
if (tkey->generated
&& isc_refcount_current(&tkey->refs) == 1
&& tkey->inception != tkey->expire
&& tkey->expire < now) {
tsig_log(tkey, 2, "tsig expire: deleting");
/* delete the key */
dns_rbtnodechain_invalidate(&chain);
(void)dns_rbt_deletename(ring->keys,
&tkey->name,
ISC_FALSE);
goto again;
}
}
result = dns_rbtnodechain_next(&chain, &foundname,
origin);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
dns_rbtnodechain_invalidate(&chain);
return;
}
}
}
isc_result_t
dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
unsigned char *secret, int length, isc_boolean_t generated,
@@ -539,17 +633,6 @@ dns_tsigkey_setdeleted(dns_tsigkey_t *key) {
RWUNLOCK(&key->ring->lock, isc_rwlocktype_write);
}
static void
buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
isc_uint16_t valhi;
isc_uint32_t vallo;
valhi = (isc_uint16_t)(val >> 32);
vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
isc_buffer_putuint16(b, valhi);
isc_buffer_putuint32(b, vallo);
}
isc_result_t
dns_tsig_sign(dns_message_t *msg) {
dns_tsigkey_t *key;
@@ -612,7 +695,7 @@ dns_tsig_sign(dns_message_t *msg) {
tsig.otherlen = BADTIMELEN;
tsig.other = badtimedata;
isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen);
buffer_putuint48(&otherbuf, tsig.timesigned);
isc_buffer_putuint48(&otherbuf, tsig.timesigned);
}
if (key->key != NULL && tsig.error != dns_tsigerror_badsig) {
@@ -640,8 +723,7 @@ dns_tsig_sign(dns_message_t *msg) {
goto cleanup_context;
isc_buffer_putuint16(&databuf, querytsig.siglen);
if (isc_buffer_availablelength(&databuf) <
querytsig.siglen)
{
querytsig.siglen) {
ret = ISC_R_NOSPACE;
goto cleanup_context;
}
@@ -699,7 +781,7 @@ dns_tsig_sign(dns_message_t *msg) {
isc_buffer_clear(&databuf);
if (tsig.error == dns_tsigerror_badtime)
tsig.timesigned = querytsig.timesigned;
buffer_putuint48(&databuf, tsig.timesigned);
isc_buffer_putuint48(&databuf, tsig.timesigned);
isc_buffer_putuint16(&databuf, tsig.fudge);
isc_buffer_usedregion(&databuf, &r);
ret = dst_context_adddata(ctx, &r);
@@ -851,6 +933,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
REQUIRE(source != NULL);
REQUIRE(DNS_MESSAGE_VALID(msg));
tsigkey = dns_message_gettsigkey(msg);
REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
msg->verify_attempted = 1;
@@ -906,8 +989,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
*/
if (is_response(msg) &&
(!dns_name_equal(keyname, &tsigkey->name) ||
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm)))
{
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm))) {
msg->tsigstatus = dns_tsigerror_badkey;
tsig_log(msg->tsigkey, 2,
"key name and algorithm do not match");
@@ -1083,7 +1165,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
goto cleanup_context;
isc_buffer_clear(&databuf);
buffer_putuint48(&databuf, tsig.timesigned);
isc_buffer_putuint48(&databuf, tsig.timesigned);
isc_buffer_putuint16(&databuf, tsig.fudge);
isc_buffer_putuint16(&databuf, tsig.error);
isc_buffer_putuint16(&databuf, tsig.otherlen);
@@ -1105,15 +1187,14 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
msg->tsigstatus = dns_tsigerror_badsig;
ret = DNS_R_TSIGVERIFYFAILURE;
tsig_log(msg->tsigkey, 2,
"signature failed to verify");
"signature failed to verify(1)");
goto cleanup_context;
} else if (ret != ISC_R_SUCCESS)
goto cleanup_context;
dst_context_destroy(&ctx);
} else if (tsig.error != dns_tsigerror_badsig &&
tsig.error != dns_tsigerror_badkey)
{
tsig.error != dns_tsigerror_badkey) {
msg->tsigstatus = dns_tsigerror_badsig;
tsig_log(msg->tsigkey, 2, "signature was empty");
return (DNS_R_TSIGVERIFYFAILURE);
@@ -1200,8 +1281,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
* Do the key name and algorithm match that of the query?
*/
if (!dns_name_equal(keyname, &tsigkey->name) ||
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm))
{
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm)) {
msg->tsigstatus = dns_tsigerror_badkey;
ret = DNS_R_TSIGVERIFYFAILURE;
tsig_log(msg->tsigkey, 2,
@@ -1220,8 +1300,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
ret = DNS_R_CLOCKSKEW;
goto cleanup_querystruct;
} else if (now + msg->timeadjust <
tsig.timesigned - tsig.fudge)
{
tsig.timesigned - tsig.fudge) {
msg->tsigstatus = dns_tsigerror_badtime;
tsig_log(msg->tsigkey, 2,
"signature is in the future");
@@ -1311,7 +1390,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
*/
if (has_tsig) {
isc_buffer_init(&databuf, data, sizeof(data));
buffer_putuint48(&databuf, tsig.timesigned);
isc_buffer_putuint48(&databuf, tsig.timesigned);
isc_buffer_putuint16(&databuf, tsig.fudge);
isc_buffer_usedregion(&databuf, &r);
ret = dst_context_adddata(msg->tsigctx, &r);
@@ -1338,7 +1417,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
if (ret == DST_R_VERIFYFAILURE) {
msg->tsigstatus = dns_tsigerror_badsig;
tsig_log(msg->tsigkey, 2,
"signature failed to verify");
"signature failed to verify(2)");
ret = DNS_R_TSIGVERIFYFAILURE;
goto cleanup_context;
}
@@ -1374,6 +1453,10 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
REQUIRE(name != NULL);
REQUIRE(ring != NULL);
RWLOCK(&ring->lock, isc_rwlocktype_write);
cleanup_ring(ring);
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
isc_stdtime_get(&now);
RWLOCK(&ring->lock, isc_rwlocktype_read);
key = NULL;
@@ -1441,6 +1524,7 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) {
}
ring->mctx = mctx;
ring->writecount = 0;
*ringp = ring;
return (ISC_R_SUCCESS);

View File

@@ -686,6 +686,10 @@ SOURCE=..\gssapictx.c
# End Source File
# Begin Source File
SOURCE=..\spnego.c
# End Source File
# Begin Source File
SOURCE=..\hmac_link.c
# End Source File
# Begin Source File

View File

@@ -143,6 +143,7 @@ CLEAN :
-@erase "$(INTDIR)\forward.obj"
-@erase "$(INTDIR)\gssapi_link.obj"
-@erase "$(INTDIR)\gssapictx.obj"
-@erase "$(INTDIR)\spnego.obj"
-@erase "$(INTDIR)\hmac_link.obj"
-@erase "$(INTDIR)\journal.obj"
-@erase "$(INTDIR)\key.obj"
@@ -316,6 +317,7 @@ LINK32_OBJS= \
"$(INTDIR)\dst_result.obj" \
"$(INTDIR)\gssapi_link.obj" \
"$(INTDIR)\gssapictx.obj" \
"$(INTDIR)\spnego.obj" \
"$(INTDIR)\hmac_link.obj" \
"$(INTDIR)\key.obj" \
"$(INTDIR)\openssl_link.obj" \
@@ -399,6 +401,8 @@ CLEAN :
-@erase "$(INTDIR)\gssapi_link.sbr"
-@erase "$(INTDIR)\gssapictx.obj"
-@erase "$(INTDIR)\gssapictx.sbr"
-@erase "$(INTDIR)\spnego.obj"
-@erase "$(INTDIR)\spnego.sbr"
-@erase "$(INTDIR)\hmac_link.obj"
-@erase "$(INTDIR)\hmac_link.sbr"
-@erase "$(INTDIR)\journal.obj"
@@ -622,6 +626,7 @@ BSC32_SBRS= \
"$(INTDIR)\dst_result.sbr" \
"$(INTDIR)\gssapi_link.sbr" \
"$(INTDIR)\gssapictx.sbr" \
"$(INTDIR)\spnego.sbr" \
"$(INTDIR)\hmac_link.sbr" \
"$(INTDIR)\key.sbr" \
"$(INTDIR)\openssl_link.sbr" \
@@ -707,6 +712,7 @@ LINK32_OBJS= \
"$(INTDIR)\dst_result.obj" \
"$(INTDIR)\gssapi_link.obj" \
"$(INTDIR)\gssapictx.obj" \
"$(INTDIR)\spnego.obj" \
"$(INTDIR)\hmac_link.obj" \
"$(INTDIR)\key.obj" \
"$(INTDIR)\openssl_link.obj" \
@@ -1957,6 +1963,24 @@ SOURCE=..\gssapictx.c
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
SOURCE=..\spnego.c
!IF "$(CFG)" == "libdns - Win32 Release"
"$(INTDIR)\spnego.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "libdns - Win32 Debug"
"$(INTDIR)\spnego.obj" "$(INTDIR)\spnego.sbr" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
SOURCE=..\hmac_link.c

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: buffer.c,v 1.42 2005/04/29 00:23:23 marka Exp $ */
/* $Id: buffer.c,v 1.43 2006/12/04 01:52:46 marka Exp $ */
/*! \file */
@@ -318,6 +318,45 @@ isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
ISC__BUFFER_PUTUINT32(b, val);
}
isc_uint64_t
isc_buffer_getuint48(isc_buffer_t *b) {
unsigned char *cp;
isc_uint64_t result;
/*
* Read an unsigned 48-bit integer in network byte order from 'b',
* convert it to host byte order, and return it.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(b->used - b->current >= 6);
cp = isc_buffer_current(b);
b->current += 6;
result = ((isc_int64_t)(cp[0])) << 40;
result |= ((isc_int64_t)(cp[1])) << 32;
result |= ((isc_int64_t)(cp[2])) << 24;
result |= ((isc_int64_t)(cp[3])) << 16;
result |= ((isc_int64_t)(cp[4])) << 8;
result |= ((isc_int64_t)(cp[5]));
return (result);
}
void
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
isc_uint16_t valhi;
isc_uint32_t vallo;
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(b->used + 6 <= b->length);
valhi = (isc_uint16_t)(val >> 32);
vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
ISC__BUFFER_PUTUINT16(b, valhi);
ISC__BUFFER_PUTUINT32(b, vallo);
}
void
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
unsigned int length)

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: entropy.c,v 1.14 2005/07/12 01:00:17 marka Exp $ */
/* $Id: entropy.c,v 1.15 2006/12/04 01:52:46 marka Exp $ */
/*! \file
* \brief
@@ -1102,6 +1102,17 @@ isc_entropy_stats(isc_entropy_t *ent, FILE *out) {
UNLOCK(&ent->lock);
}
unsigned int
isc_entropy_status(isc_entropy_t *ent) {
unsigned int estimate;
LOCK(&ent->lock);
estimate = ent->pool.entropy;
UNLOCK(&ent->lock);
return estimate;
}
void
isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp) {
REQUIRE(VALID_ENTROPY(ent));

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: buffer.h,v 1.45 2005/04/29 00:23:34 marka Exp $ */
/* $Id: buffer.h,v 1.46 2006/12/04 01:52:46 marka Exp $ */
#ifndef ISC_BUFFER_H
#define ISC_BUFFER_H 1
@@ -539,6 +539,42 @@ isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
*\li The used pointer in 'b' is advanced by 4.
*/
isc_uint64_t
isc_buffer_getuint48(isc_buffer_t *b);
/*!<
* \brief Read an unsigned 48-bit integer in network byte order from 'b',
* convert it to host byte order, and return it.
*
* Requires:
*
*\li 'b' is a valid buffer.
*
*\li The length of the available region of 'b' is at least 6.
*
* Ensures:
*
*\li The current pointer in 'b' is advanced by 6.
*
* Returns:
*
*\li A 48-bit unsigned integer (stored in a 64-bit integer).
*/
void
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val);
/*!<
* \brief Store an unsigned 48-bit integer in host byte order from 'val'
* into 'b' in network byte order.
*
* Requires:
*\li 'b' is a valid buffer.
*
*\li The length of the unused region of 'b' is at least 6.
*
* Ensures:
*\li The used pointer in 'b' is advanced by 6.
*/
void
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
unsigned int length);
@@ -808,4 +844,9 @@ ISC_LANG_ENDDECLS
#define isc_buffer_putuint32 isc__buffer_putuint32
#endif
/*
* No inline method for this one (yet).
*/
#define isc_buffer_putuint48 isc__buffer_putuint48
#endif /* ISC_BUFFER_H */

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: entropy.h,v 1.27 2005/04/29 00:23:35 marka Exp $ */
/* $Id: entropy.h,v 1.28 2006/12/04 01:52:46 marka Exp $ */
#ifndef ISC_ENTROPY_H
#define ISC_ENTROPY_H 1
@@ -267,6 +267,13 @@ isc_entropy_stats(isc_entropy_t *ent, FILE *out);
* \brief Dump some (trivial) stats to the stdio stream "out".
*/
unsigned int
isc_entropy_status(isc_entropy_t *end);
/*
* Returns the number of bits the pool currently contains. This is just
* an estimate.
*/
isc_result_t
isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
const char *randomfile, int use_keyboard);

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: platform.h.in,v 1.39 2005/06/16 21:57:59 jinmei Exp $ */
/* $Id: platform.h.in,v 1.40 2006/12/04 01:52:46 marka Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
@@ -104,19 +104,21 @@
@ISC_PLATFORM_NEEDPORTT@
/*! \brief
* If the system needs strsep(), ISC_PLATFORM_NEEDSTRSEP will be defined.
* Define if the system has struct lifconf which is a extended struct ifconf
* for IPv6.
*/
@ISC_PLATFORM_NEEDSTRSEP@
@ISC_PLATFORM_HAVELIFCONF@
/*! \brief
* If the system needs strlcpy(), ISC_PLATFORM_NEEDSTRLCPY will be defined.
* Define if the system has struct if_laddrconf which is a extended struct
* ifconf for IPv6.
*/
@ISC_PLATFORM_NEEDSTRLCPY@
@ISC_PLATFORM_HAVEIF_LADDRCONF@
/*! \brief
* If the system needs strlcat(), ISC_PLATFORM_NEEDSTRLCAT will be defined.
* Define if the system has struct if_laddrreq.
*/
@ISC_PLATFORM_NEEDSTRLCAT@
@ISC_PLATFORM_HAVEIF_LADDRREQ@
/*! \brief
* Define either ISC_PLATFORM_BSD44MSGHDR or ISC_PLATFORM_BSD43MSGHDR.
@@ -124,10 +126,9 @@
@ISC_PLATFORM_MSGHDRFLAVOR@
/*! \brief
* Define if PTHREAD_ONCE_INIT should be surrounded by braces to
* prevent compiler warnings (such as with gcc on Solaris 2.8).
* Define if the system supports if_nametoindex.
*/
@ISC_PLATFORM_BRACEPTHREADONCEINIT@
@ISC_PLATFORM_HAVEIFNAMETOINDEX@
/*! \brief
* Define on some UnixWare systems to fix erroneous definitions of various
@@ -155,63 +156,75 @@
*/
@ISC_PLATFORM_QUADFORMAT@
/*! \brief
* Defined if we are using threads.
/***
*** String functions.
***/
/*
* If the system needs strsep(), ISC_PLATFORM_NEEDSTRSEP will be defined.
*/
@ISC_PLATFORM_USETHREADS@
@ISC_PLATFORM_NEEDSTRSEP@
/*! \brief
* Defined if unistd.h does not cause fd_set to be delared.
/*
* If the system needs strlcpy(), ISC_PLATFORM_NEEDSTRLCPY will be defined.
*/
@ISC_PLATFORM_NEEDSYSSELECTH@
@ISC_PLATFORM_NEEDSTRLCPY@
/*! \brief
* Type used for resource limits.
/*
* If the system needs strlcat(), ISC_PLATFORM_NEEDSTRLCAT will be defined.
*/
@ISC_PLATFORM_RLIMITTYPE@
@ISC_PLATFORM_NEEDSTRLCAT@
/*! \brief
* Define if your compiler supports "long long int".
*/
@ISC_PLATFORM_HAVELONGLONG@
/*! \brief
* Define if the system has struct lifconf which is a extended struct ifconf
* for IPv6.
*/
@ISC_PLATFORM_HAVELIFCONF@
/*! \brief
* Define if the system has struct if_laddrconf which is a extended struct
* ifconf for IPv6.
*/
@ISC_PLATFORM_HAVEIF_LADDRCONF@
/*! \brief
* Define if the system has struct if_laddrreq.
*/
@ISC_PLATFORM_HAVEIF_LADDRREQ@
/*! \brief
* Used to control how extern data is linked; needed for Win32 platforms.
*/
@ISC_PLATFORM_USEDECLSPEC@
/*! \brief
* Define if the system supports if_nametoindex.
*/
@ISC_PLATFORM_HAVEIFNAMETOINDEX@
/*! \brief
/*
* Define if this system needs strtoul.
*/
@ISC_PLATFORM_NEEDSTRTOUL@
/*! \brief
/*
* Define if this system needs memmove.
*/
@ISC_PLATFORM_NEEDMEMMOVE@
/***
*** Miscellaneous.
***/
/*
* Defined if we are using threads.
*/
@ISC_PLATFORM_USETHREADS@
/*
* Defined if unistd.h does not cause fd_set to be delared.
*/
@ISC_PLATFORM_NEEDSYSSELECTH@
/*
* Defined to <gssapi.h> or <gssapi/gssapi.h> for how to include
* the GSSAPI header.
*/
@ISC_PLATFORM_GSSAPIHEADER@
/*
* Type used for resource limits.
*/
@ISC_PLATFORM_RLIMITTYPE@
/*
* Define if your compiler supports "long long int".
*/
@ISC_PLATFORM_HAVELONGLONG@
/*
* Define if PTHREAD_ONCE_INIT should be surrounded by braces to
* prevent compiler warnings (such as with gcc on Solaris 2.8).
*/
@ISC_PLATFORM_BRACEPTHREADONCEINIT@
/*
* Used to control how extern data is linked; needed for Win32 platforms.
*/
@ISC_PLATFORM_USEDECLSPEC@
/*
* Define if the platform has <sys/un.h>.
*/
@@ -250,6 +263,10 @@
*/
@ISC_PLATFORM_USESTDASM@
/***
*** Windows dll support.
***/
#ifndef ISC_PLATFORM_USEDECLSPEC
#define LIBISC_EXTERNAL_DATA
#define LIBDNS_EXTERNAL_DATA

View File

@@ -19,6 +19,7 @@ isc__buffer_putmem
isc__buffer_putstr
isc__buffer_putuint16
isc__buffer_putuint32
isc__buffer_putuint48
isc__buffer_putuint8
isc__buffer_region
isc__buffer_remainingregion
@@ -85,6 +86,7 @@ isc_entropy_detach
isc_entropy_getdata
isc_entropy_putdata
isc_entropy_stats
isc_entropy_status
isc_entropy_stopcallbacksources
isc_entropy_usebestsource
isc_error_fatal

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: namedconf.c,v 1.70 2006/06/04 23:17:07 marka Exp $ */
/* $Id: namedconf.c,v 1.71 2006/12/04 01:52:46 marka Exp $ */
/*! \file */
@@ -258,7 +258,8 @@ static cfg_type_t cfg_type_mode = {
};
static const char *matchtype_enums[] = {
"name", "subdomain", "wildcard", "self", "selfsub", "selfwild", NULL };
"name", "subdomain", "wildcard", "self", "selfsub", "selfwild",
"krb5-self", "ms-self", "krb5-subdomain", "ms-subdomain", NULL };
static cfg_type_t cfg_type_matchtype = {
"matchtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
&matchtype_enums

View File

@@ -1,5 +1,13 @@
#!/bin/sh -
##
## Modified to handle -vpath <path> option by Michael Graff, ISC.
## The purpose of this is to allow this script to run outside of the
## source directory, for instance when running configure with
## ../bind9-mainline/configure
## and still have "make depend" work.
##
## ++Copyright++ 1987
## -
## Copyright (c) 1987 Regents of the University of California.
@@ -60,6 +68,10 @@ MAKE=Makefile # default makefile name is "Makefile"
while :
do case "$1" in
# -vpath allows one to select a virtual path for .c files
-vpath)
VPATH=$2;
shift; shift ;;
# -f allows you to select a makefile name
-f)
MAKE=$2
@@ -76,7 +88,7 @@ while :
done
if [ $# = 0 ] ; then
echo 'usage: mkdep [-p] [-f makefile] [flags] file ...'
echo 'usage: mkdep [-vpath path] [-p] [-f makefile] [flags] file ...'
exit 1
fi
@@ -107,11 +119,26 @@ _EOF_
# egrep '^#include[ ]*".*"' /dev/null $* |
# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' |
if [ X"${VPATH}" != X ] ; then
for arg in $* ; do
case "$arg" in
-*)
newargs="$newargs $arg"
;;
*)
newargs="$newargs $VPATH/$arg"
;;
esac
done
else
newargs="$*";
fi
MKDEPPROG="@MKDEPPROG@"
if [ X"${MKDEPPROG}" != X ]; then
@SHELL@ -c "${MKDEPPROG} $*"
@SHELL@ -c "${MKDEPPROG} ${newargs}"
else
@MKDEPCC@ @MKDEPCFLAGS@ $* |
@MKDEPCC@ @MKDEPCFLAGS@ ${newargs} |
sed "
s; \./; ;g
@LIBTOOL_MKDEP_SED@

View File

@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: rules.in,v 1.57 2006/01/06 00:01:44 marka Exp $
# $Id: rules.in,v 1.58 2006/12/04 01:52:46 marka Exp $
###
### Common Makefile rules for BIND 9.
@@ -150,7 +150,24 @@ depend:
(cd $$i; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" $@) || exit 1; \
fi; \
done
@if [ X"${SRCS}" != X -a X"${PSRCS}" != X ] ; then \
@if [ X"${VPATH}" != X ] ; then \
if [ X"${SRCS}" != X -a X"${PSRCS}" != X ] ; then \
echo ${MKDEP} -vpath ${VPATH} ${ALL_CPPFLAGS} ${SRCS}; \
${MKDEP} -vpath ${VPATH} ${ALL_CPPFLAGS} ${SRCS}; \
echo ${MKDEP} -vpath ${VPATH} -ap ${ALL_CPPFLAGS} ${PSRCS}; \
${MKDEP} -vpath ${VPATH} -ap ${ALL_CPPFLAGS} ${PSRCS}; \
${DEPENDEXTRA} \
elif [ X"${SRCS}" != X ] ; then \
echo ${MKDEP} -vpath ${VPATH} ${ALL_CPPFLAGS} ${SRCS}; \
${MKDEP} -vpath ${VPATH} ${ALL_CPPFLAGS} ${SRCS}; \
${DEPENDEXTRA} \
elif [ X"${PSRCS}" != X ] ; then \
echo ${MKDEP} -vpath ${VPATH} ${ALL_CPPFLAGS} ${PSRCS}; \
${MKDEP} -vpath ${VPATH} -p ${ALL_CPPFLAGS} ${PSRCS}; \
${DEPENDEXTRA} \
fi \
else \
if [ X"${SRCS}" != X -a X"${PSRCS}" != X ] ; then \
echo ${MKDEP} ${ALL_CPPFLAGS} ${SRCS}; \
${MKDEP} ${ALL_CPPFLAGS} ${SRCS}; \
echo ${MKDEP} -ap ${ALL_CPPFLAGS} ${PSRCS}; \
@@ -164,6 +181,7 @@ depend:
echo ${MKDEP} ${ALL_CPPFLAGS} ${PSRCS}; \
${MKDEP} -p ${ALL_CPPFLAGS} ${PSRCS}; \
${DEPENDEXTRA} \
fi \
fi
FORCE: