summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaMont Jones <lamont@debian.org>2009-11-16 19:26:14 -0600
committerLaMont Jones <lamont@debian.org>2009-11-16 19:26:14 -0600
commite3246fedd37d119c2bf6efb28d7492b3a595373a (patch)
treeaed2129efc2efb2bb526e1e4abf9080d3ec9ab6b
parentf133ad6c8e92691761b732d65cca85e4e27d6f51 (diff)
downloadbind9-e3246fedd37d119c2bf6efb28d7492b3a595373a.tar.gz
9.7.0a3
-rw-r--r--CHANGES106
-rw-r--r--FAQ9
-rw-r--r--FAQ.xml11
-rw-r--r--Makefile.in8
-rw-r--r--README18
-rw-r--r--README.libdns275
-rw-r--r--README.pkcs11318
-rw-r--r--README.rfc501160
-rw-r--r--bin/check/Makefile.in22
-rw-r--r--bin/check/check-tool.c5
-rw-r--r--bin/confgen/Makefile.in17
-rw-r--r--bin/dig/Makefile.in22
-rw-r--r--bin/dig/dighost.c18
-rw-r--r--bin/dig/host.c5
-rw-r--r--bin/dnssec/Makefile.in23
-rw-r--r--bin/dnssec/dnssec-dsfromkey.813
-rw-r--r--bin/dnssec/dnssec-dsfromkey.c8
-rw-r--r--bin/dnssec/dnssec-dsfromkey.docbook9
-rw-r--r--bin/dnssec/dnssec-dsfromkey.html23
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.855
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.c177
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.docbook124
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.html99
-rw-r--r--bin/dnssec/dnssec-keygen.88
-rw-r--r--bin/dnssec/dnssec-keygen.c118
-rw-r--r--bin/dnssec/dnssec-keygen.docbook17
-rw-r--r--bin/dnssec/dnssec-keygen.html29
-rw-r--r--bin/dnssec/dnssec-revoke.c50
-rw-r--r--bin/dnssec/dnssec-settime.833
-rw-r--r--bin/dnssec/dnssec-settime.c314
-rw-r--r--bin/dnssec/dnssec-settime.docbook50
-rw-r--r--bin/dnssec/dnssec-settime.html42
-rw-r--r--bin/dnssec/dnssec-signzone.818
-rw-r--r--bin/dnssec/dnssec-signzone.c71
-rw-r--r--bin/dnssec/dnssec-signzone.docbook29
-rw-r--r--bin/dnssec/dnssec-signzone.html30
-rw-r--r--bin/dnssec/dnssectool.c38
-rw-r--r--bin/dnssec/dnssectool.h8
-rw-r--r--bin/named/Makefile.in18
-rw-r--r--bin/named/bind.keys.h14
-rwxr-xr-xbin/named/bindkeys.pl16
-rw-r--r--bin/named/config.c10
-rw-r--r--bin/named/lwdgabn.c6
-rw-r--r--bin/named/lwdgrbn.c6
-rw-r--r--bin/named/lwresd.c7
-rw-r--r--bin/named/main.c83
-rw-r--r--bin/named/server.c79
-rw-r--r--bin/named/tkeyconf.c16
-rw-r--r--bin/named/tsigconf.c4
-rw-r--r--bin/named/unix/Makefile.in6
-rw-r--r--bin/named/unix/include/named/os.h4
-rw-r--r--bin/named/unix/os.c10
-rw-r--r--bin/named/update.c17
-rw-r--r--bin/named/win32/include/named/os.h4
-rw-r--r--bin/named/zoneconf.c7
-rw-r--r--bin/nsupdate/Makefile.in10
-rw-r--r--bin/nsupdate/nsupdate.18
-rw-r--r--bin/nsupdate/nsupdate.c22
-rw-r--r--bin/nsupdate/nsupdate.docbook5
-rw-r--r--bin/nsupdate/nsupdate.html16
-rw-r--r--bin/rndc/Makefile.in15
-rw-r--r--bin/tests/Makefile.in40
-rw-r--r--bin/tests/adb_test.c7
-rw-r--r--bin/tests/backtrace_test.c97
-rw-r--r--bin/tests/byname_test.c6
-rw-r--r--bin/tests/db/Makefile.in6
-rw-r--r--bin/tests/db/t_db.c30
-rw-r--r--bin/tests/db_test.c16
-rw-r--r--bin/tests/dst/Makefile.in4
-rw-r--r--bin/tests/dst/dst_test.c6
-rwxr-xr-xbin/tests/dst/gsstest.c34
-rw-r--r--bin/tests/dst/t_dst.c8
-rw-r--r--bin/tests/master/Makefile.in6
-rw-r--r--bin/tests/master/t_master.c4
-rw-r--r--bin/tests/master_test.c8
-rw-r--r--bin/tests/mem/Makefile.in6
-rw-r--r--bin/tests/name_test.c13
-rw-r--r--bin/tests/names/Makefile.in6
-rw-r--r--bin/tests/names/t_names.c30
-rw-r--r--bin/tests/net/Makefile.in6
-rw-r--r--bin/tests/nsecify.c6
-rw-r--r--bin/tests/rbt/Makefile.in6
-rw-r--r--bin/tests/rbt/t_rbt.c10
-rw-r--r--bin/tests/rbt_test.c7
-rw-r--r--bin/tests/sig0_test.c9
-rw-r--r--bin/tests/sockaddr/Makefile.in4
-rw-r--r--bin/tests/system/lwresd/Makefile.in6
-rw-r--r--bin/tests/system/nsupdate/tests.sh20
-rw-r--r--bin/tests/system/tkey/Makefile.in6
-rw-r--r--bin/tests/system/tkey/keycreate.c6
-rw-r--r--bin/tests/tasks/Makefile.in4
-rw-r--r--bin/tests/timers/Makefile.in4
-rw-r--r--bin/tests/zone_test.c30
-rw-r--r--bin/tools/Makefile.in19
-rw-r--r--bin/win32/BINDInstall/BINDInstall.rc110
-rw-r--r--bin/win32/BINDInstall/BINDInstallDlg.cpp218
-rw-r--r--bin/win32/BINDInstall/BINDInstallDlg.h13
-rw-r--r--bin/win32/BINDInstall/resource.h1
-rw-r--r--bind.keys9
-rw-r--r--config.h.in14
-rw-r--r--config.h.win3211
-rwxr-xr-xconfigure603
-rw-r--r--configure.in246
-rw-r--r--contrib/dbus/dbus_mgr.c6
-rw-r--r--contrib/dlz/bin/dlzbdb/Makefile.in6
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h8
-rw-r--r--contrib/pkcs11-keygen/PKCS11-NOTES94
-rw-r--r--contrib/pkcs11-keygen/README2
-rw-r--r--contrib/pkcs11-keygen/destroyobj.c7
-rw-r--r--contrib/pkcs11-keygen/genkey.c7
-rw-r--r--contrib/pkcs11-keygen/listobjs.c7
-rw-r--r--contrib/pkcs11-keygen/opencryptoki/apiclient.h481
-rw-r--r--contrib/pkcs11-keygen/opencryptoki/pkcs11.h297
-rw-r--r--contrib/pkcs11-keygen/opencryptoki/pkcs11types.h1865
-rw-r--r--contrib/pkcs11-keygen/openssl-0.9.8g-patch8715
-rw-r--r--contrib/pkcs11-keygen/openssl-0.9.8i-patch14000
-rw-r--r--contrib/pkcs11-keygen/readkey.c7
-rw-r--r--contrib/pkcs11-keygen/set_key_id.c7
-rw-r--r--contrib/pkcs11-keygen/writekey.c7
-rw-r--r--contrib/sdb/bdb/zone2bdb.c4
-rw-r--r--contrib/sdb/ldap/zone2ldap.c2
-rw-r--r--contrib/sdb/pgsql/zonetodb.c6
-rw-r--r--contrib/sdb/sqlite/zone2sqlite.c4
-rw-r--r--doc/arm/Bv9ARM-book.xml239
-rw-r--r--doc/arm/Bv9ARM.ch04.html108
-rw-r--r--doc/arm/Bv9ARM.ch05.html6
-rw-r--r--doc/arm/Bv9ARM.ch06.html290
-rw-r--r--doc/arm/Bv9ARM.ch07.html14
-rw-r--r--doc/arm/Bv9ARM.ch08.html18
-rw-r--r--doc/arm/Bv9ARM.ch09.html180
-rw-r--r--doc/arm/Bv9ARM.html81
-rw-r--r--doc/arm/man.ddns-confgen.html10
-rw-r--r--doc/arm/man.dig.html20
-rw-r--r--doc/arm/man.dnssec-dsfromkey.html23
-rw-r--r--doc/arm/man.dnssec-keyfromlabel.html99
-rw-r--r--doc/arm/man.dnssec-keygen.html31
-rw-r--r--doc/arm/man.dnssec-revoke.html10
-rw-r--r--doc/arm/man.dnssec-settime.html48
-rw-r--r--doc/arm/man.dnssec-signzone.html34
-rw-r--r--doc/arm/man.host.html10
-rw-r--r--doc/arm/man.named-checkconf.html12
-rw-r--r--doc/arm/man.named-checkzone.html12
-rw-r--r--doc/arm/man.named.html16
-rw-r--r--doc/arm/man.nsupdate.html16
-rw-r--r--doc/arm/man.rndc-confgen.html12
-rw-r--r--doc/arm/man.rndc.conf.html12
-rw-r--r--doc/arm/man.rndc.html12
-rw-r--r--doc/draft/draft-ietf-dnsext-dnssec-bis-updates-09.txt (renamed from doc/draft/draft-ietf-dnsext-dnssec-bis-updates-08.txt)312
-rw-r--r--doc/draft/draft-ietf-dnsext-tsig-sha-06.txt522
-rw-r--r--doc/misc/options7
-rw-r--r--lib/bind9/Makefile.in6
-rw-r--r--lib/bind9/check.c37
-rw-r--r--lib/dns/Makefile.in8
-rw-r--r--lib/dns/byaddr.c47
-rw-r--r--lib/dns/cache.c8
-rw-r--r--lib/dns/client.c3008
-rw-r--r--lib/dns/db.c12
-rw-r--r--lib/dns/dispatch.c85
-rw-r--r--lib/dns/dnssec.c24
-rw-r--r--lib/dns/dst_api.c95
-rw-r--r--lib/dns/dst_internal.h11
-rw-r--r--lib/dns/dst_parse.c56
-rw-r--r--lib/dns/dst_parse.h6
-rw-r--r--lib/dns/ecdb.c797
-rw-r--r--lib/dns/forward.c22
-rw-r--r--lib/dns/gssapictx.c6
-rw-r--r--lib/dns/hmac_link.c22
-rw-r--r--lib/dns/include/dns/client.h621
-rw-r--r--lib/dns/include/dns/dnssec.h3
-rw-r--r--lib/dns/include/dns/ecdb.h52
-rw-r--r--lib/dns/include/dns/events.h4
-rw-r--r--lib/dns/include/dns/forward.h19
-rw-r--r--lib/dns/include/dns/lib.h18
-rw-r--r--lib/dns/include/dns/message.h5
-rw-r--r--lib/dns/include/dns/name.h73
-rw-r--r--lib/dns/include/dns/rdata.h18
-rw-r--r--lib/dns/include/dns/resolver.h3
-rw-r--r--lib/dns/include/dns/soa.h20
-rw-r--r--lib/dns/include/dns/tsec.h135
-rw-r--r--lib/dns/include/dns/types.h7
-rw-r--r--lib/dns/include/dst/dst.h37
-rw-r--r--lib/dns/journal.c8
-rw-r--r--lib/dns/lib.c109
-rw-r--r--lib/dns/master.c4
-rw-r--r--lib/dns/masterdump.c6
-rw-r--r--lib/dns/name.c11
-rw-r--r--lib/dns/openssl_link.c15
-rw-r--r--lib/dns/openssldh_link.c7
-rw-r--r--lib/dns/openssldsa_link.c5
-rw-r--r--lib/dns/opensslrsa_link.c125
-rw-r--r--lib/dns/peer.c6
-rw-r--r--lib/dns/rbtdb.c63
-rw-r--r--lib/dns/rdata.c95
-rw-r--r--lib/dns/rdata/generic/hip_55.c4
-rw-r--r--lib/dns/request.c5
-rw-r--r--lib/dns/resolver.c37
-rw-r--r--lib/dns/sdb.c4
-rw-r--r--lib/dns/sdlz.c4
-rw-r--r--lib/dns/soa.c11
-rw-r--r--lib/dns/tkey.c7
-rw-r--r--lib/dns/tsec.c161
-rw-r--r--lib/dns/view.c56
-rw-r--r--lib/dns/win32/libdns.def3
-rw-r--r--lib/dns/win32/libdns.dsp8
-rw-r--r--lib/dns/win32/libdns.mak8
-rw-r--r--lib/dns/zone.c208
-rw-r--r--lib/export/Makefile.in27
-rw-r--r--lib/export/dns/Makefile.in172
-rw-r--r--lib/export/dns/include/Makefile.in23
-rw-r--r--lib/export/dns/include/dns/Makefile.in56
-rw-r--r--lib/export/dns/include/dst/Makefile.in36
-rw-r--r--lib/export/irs/Makefile.in85
-rw-r--r--lib/export/irs/include/Makefile.in24
-rw-r--r--lib/export/irs/include/irs/Makefile.in46
-rw-r--r--lib/export/isc/Makefile.in136
-rw-r--r--lib/export/isc/include/Makefile.in24
-rw-r--r--lib/export/isc/include/isc/Makefile.in63
-rw-r--r--lib/export/isc/nls/Makefile.in35
-rw-r--r--lib/export/isc/nothreads/Makefile.in38
-rw-r--r--lib/export/isc/nothreads/include/Makefile.in24
-rw-r--r--lib/export/isc/nothreads/include/isc/Makefile.in36
-rw-r--r--lib/export/isc/pthreads/Makefile.in38
-rw-r--r--lib/export/isc/pthreads/include/Makefile.in24
-rw-r--r--lib/export/isc/pthreads/include/isc/Makefile.in36
-rw-r--r--lib/export/isc/unix/Makefile.in57
-rw-r--r--lib/export/isc/unix/include/Makefile.in24
-rw-r--r--lib/export/isc/unix/include/isc/Makefile.in37
-rw-r--r--lib/export/isccfg/Makefile.in81
-rw-r--r--lib/export/isccfg/include/Makefile.in24
-rw-r--r--lib/export/isccfg/include/isccfg/Makefile.in42
-rw-r--r--lib/export/samples/Makefile-postinstall.in78
-rw-r--r--lib/export/samples/Makefile.in96
-rw-r--r--lib/export/samples/nsprobe.c1217
-rw-r--r--lib/export/samples/sample-async.c399
-rw-r--r--lib/export/samples/sample-gai.c77
-rw-r--r--lib/export/samples/sample-request.c260
-rw-r--r--lib/export/samples/sample-update.c751
-rw-r--r--lib/export/samples/sample.c375
-rw-r--r--lib/irs/Makefile.in80
-rw-r--r--lib/irs/api3
-rw-r--r--lib/irs/context.c396
-rw-r--r--lib/irs/dnsconf.c269
-rw-r--r--lib/irs/gai_strerror.c93
-rw-r--r--lib/irs/getaddrinfo.c1295
-rw-r--r--lib/irs/getnameinfo.c410
-rw-r--r--lib/irs/include/Makefile.in24
-rw-r--r--lib/irs/include/irs/Makefile.in44
-rw-r--r--lib/irs/include/irs/context.h159
-rw-r--r--lib/irs/include/irs/dnsconf.h94
-rw-r--r--lib/irs/include/irs/netdb.h.in167
-rw-r--r--lib/irs/include/irs/platform.h.in45
-rw-r--r--lib/irs/include/irs/resconf.h113
-rw-r--r--lib/irs/include/irs/types.h31
-rw-r--r--lib/irs/include/irs/version.h27
-rw-r--r--lib/irs/resconf.c636
-rw-r--r--lib/irs/version.c27
-rw-r--r--lib/isc/Makefile.in39
-rw-r--r--lib/isc/app_api.c136
-rw-r--r--lib/isc/assertions.c43
-rw-r--r--lib/isc/backtrace-emptytbl.c34
-rw-r--r--lib/isc/backtrace.c285
-rw-r--r--lib/isc/hash.c16
-rw-r--r--lib/isc/include/isc/app.h173
-rw-r--r--lib/isc/include/isc/backtrace.h131
-rw-r--r--lib/isc/include/isc/file.h17
-rw-r--r--lib/isc/include/isc/lib.h13
-rw-r--r--lib/isc/include/isc/mem.h160
-rw-r--r--lib/isc/include/isc/namespace.h161
-rw-r--r--lib/isc/include/isc/platform.h.in7
-rw-r--r--lib/isc/include/isc/result.h5
-rw-r--r--lib/isc/include/isc/resultclass.h5
-rw-r--r--lib/isc/include/isc/socket.h108
-rw-r--r--lib/isc/include/isc/task.h100
-rw-r--r--lib/isc/include/isc/timer.h93
-rw-r--r--lib/isc/include/isc/types.h6
-rw-r--r--lib/isc/lib.c34
-rw-r--r--lib/isc/mem.c564
-rw-r--r--lib/isc/mem_api.c296
-rw-r--r--lib/isc/nls/Makefile.in6
-rw-r--r--lib/isc/nothreads/Makefile.in10
-rw-r--r--lib/isc/pthreads/Makefile.in6
-rw-r--r--lib/isc/socket_api.c196
-rw-r--r--lib/isc/task.c497
-rw-r--r--lib/isc/task_api.c201
-rw-r--r--lib/isc/task_p.h8
-rw-r--r--lib/isc/timer.c331
-rw-r--r--lib/isc/timer_api.c144
-rw-r--r--lib/isc/timer_p.h8
-rw-r--r--lib/isc/unix/Makefile.in6
-rw-r--r--lib/isc/unix/app.c530
-rw-r--r--lib/isc/unix/file.c37
-rw-r--r--lib/isc/unix/socket.c877
-rw-r--r--lib/isc/unix/socket_p.h9
-rw-r--r--lib/isc/win32/Makefile.in6
-rw-r--r--lib/isc/win32/app.c22
-rw-r--r--lib/isc/win32/file.c44
-rw-r--r--lib/isc/win32/libisc.def232
-rw-r--r--lib/isc/win32/libisc.dsp24
-rw-r--r--lib/isc/win32/libisc.mak52
-rw-r--r--lib/isc/win32/net.c6
-rw-r--r--lib/isc/win32/socket.c103
-rw-r--r--lib/isc/win32/time.c34
-rw-r--r--lib/isccc/Makefile.in6
-rw-r--r--lib/isccfg/Makefile.in6
-rw-r--r--lib/isccfg/aclconf.c4
-rw-r--r--lib/isccfg/dnsconf.c69
-rw-r--r--lib/isccfg/include/isccfg/dnsconf.h35
-rw-r--r--lib/isccfg/namedconf.c42
-rw-r--r--lib/isccfg/parser.c6
-rw-r--r--lib/lwres/context.c15
-rw-r--r--lib/lwres/getipnode.c100
-rw-r--r--lib/tests/Makefile.in6
-rw-r--r--make/rules.in91
-rwxr-xr-xutil/mksymtbl.pl127
-rw-r--r--version4
-rw-r--r--win32utils/readme1st.txt9
-rw-r--r--win32utils/win32-build.txt4
317 files changed, 40411 insertions, 12561 deletions
diff --git a/CHANGES b/CHANGES
index cb02c43f..6e81eb29 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,106 @@
+ --- 9.7.0a3 released ---
+
+2674. [bug] "dnssec-lookaside auto;" crashed if named was built
+ without openssl. [RT #20231]
+
+2673. [bug] The managed-keys.bind zone file could fail to
+ load due to a spurious result from sync_keyzone()
+ [RT #20045]
+
+2672. [bug] Don't enable searching in 'host' when doing reverse
+ lookups. [RT #20218]
+
+2671. [bug] Add support for PKCS#11 providers not returning
+ the public exponent in RSA private keys
+ (OpenCryptoki for instance) in
+ dnssec-keyfromlabel. [RT #19294]
+
+2670. [bug] Unexpected connect failures failed to log enough
+ information to be useful. [RT #20205]
+
+2669. [func] Update PKCS#11 support to support Keyper HSM.
+ Update PKCS#11 patch to be against openssl-0.9.8i.
+
+2668. [func] Several improvements to dnssec-* tools, including:
+ - dnssec-keygen and dnssec-settime can now set key
+ metadata fields 0 (to unset a value, use "none")
+ - dnssec-revoke sets the revocation date in
+ addition to the revoke bit
+ - dnssec-settime can now print individual metadata
+ fields instead of always printing all of them,
+ and can print them in unix epoch time format for
+ use by scripts
+ [RT #19942]
+
+2667. [func] Add support for logging stack backtrace on assertion
+ failure (not available for all platforms). [RT #19780]
+
+2666. [func] Added an 'options' argument to dns_name_fromstring()
+ (API change from 9.7.0a2). [RT #20196]
+
+2665. [func] Clarify syntax for managed-keys {} statement, add
+ ARM documentation about RFC 5011 support. [RT #19874]
+
+2664. [bug] create_keydata() and minimal_update() in zone.c
+ didn't properly check return values for some
+ functions. [RT #19956]
+
+2663. [func] win32: allow named to run as a service using
+ "NT AUTHORITY\LocalService" as the account. [RT #19977]
+
+2662. [bug] lwres_getipnodebyname() and lwres_getipnodebyaddr()
+ returned a misleading error code when lwresd was
+ down. [RT #20028]
+
+2661. [bug] Check whether socket fd exceeds FD_SETSIZE when
+ creating lwres context. [RT #20029]
+
+2660. [func] Add a new set of DNS libraries for non-BIND9
+ applications. See README.libdns. [RT #19369]
+
+2659. [doc] Clarify dnssec-keygen doc: key name must match zone
+ name for DNSSEC keys. [RT #19938]
+
+2658. [bug] dnssec-settime and dnssec-revoke didn't process
+ key file paths correctly. [RT #20078]
+
+2657. [cleanup] Lower "journal file <path> does not exist, creating it"
+ log level to debug 1. [RT #20058]
+
+2656. [func] win32: add a "tools only" check box to the installer
+ which causes it to only install dig, host, nslookup,
+ nsupdate and relevant DLLs. [RT #19998]
+
+2655. [doc] Document that key-directory does not affect
+ bind.keys, rndc.key or session.key. [RT #20155]
+
+2654. [bug] Improve error reporting on duplicated names for
+ deny-answer-xxx. [RT #20164]
+
+2653. [bug] Treat ENGINE_load_private_key() failures as key
+ not found rather than out of memory. [RT #18033]
+
+2652. [func] Provide more detail about what record is being
+ deleted. [RT #20061]
+
+2651. [bug] Dates could print incorrectly in K*.key files on
+ 64-bit systems. [RT #20076]
+
+2650. [bug] Assertion failure in dnssec-signzone when trying
+ to read keyset-* files. [RT #20075]
+
+2649. [bug] Set the domain for forward only zones. [RT #19944]
+
+2648. [port] win32: isc_time_seconds() was broken. [RT #19900]
+
+2647. [bug] Remove unnecessary SOA updates when a new KSK is
+ added. [RT #19913]
+
+2646. [bug] Incorrect cleanup on error in socket.c. [RT #19987]
+
+2645. [port] "gcc -m32" didn't work on amd64 and x86_64 platforms
+ which default to 64 bits. [RT #19927]
+
--- 9.7.0a2 released ---
2644. [bug] Change #2628 caused a regression on some systems;
@@ -55,7 +158,8 @@
2630. [func] Improved syntax for DDNS autoconfiguration: use
"update-policy local;" to switch on local DDNS in a
- zone. [RT #19875]
+ zone. (The "ddns-autoconf" option has been removed.)
+ [RT #19875]
2629. [port] Check for seteuid()/setegid(), use setresuid()/
setresgid() if not present. [RT #19932]
diff --git a/FAQ b/FAQ
index 2846b31f..4df1d764 100644
--- a/FAQ
+++ b/FAQ
@@ -157,12 +157,17 @@ A: BIND 9.3 and later: Use TSIG to select the appropriate view.
secret "xxxxxxxx";
};
view "internal" {
- match-clients { !key external; 10.0.1/24; };
+ match-clients { !key external; // reject message ment for the
+ // external view.
+ 10.0.1/24; }; // accept from these addresses.
...
};
view "external" {
match-clients { key external; any; };
- server 10.0.1.2 { keys external; };
+ server 10.0.1.2 { keys external; }; // tag messages from the
+ // external view to the
+ // other servers for the
+ // view.
recursion no;
...
};
diff --git a/FAQ.xml b/FAQ.xml
index 8c671140..7e7a4bab 100644
--- a/FAQ.xml
+++ b/FAQ.xml
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: FAQ.xml,v 1.49 2009/02/18 22:48:52 jreed Exp $ -->
+<!-- $Id: FAQ.xml,v 1.50 2009/08/19 23:38:11 marka Exp $ -->
<article class="faq">
<title>Frequently Asked Questions about BIND 9</title>
@@ -323,12 +323,17 @@ Master 10.0.1.1:
secret "xxxxxxxx";
};
view "internal" {
- match-clients { !key external; 10.0.1/24; };
+ match-clients { !key external; // reject message ment for the
+ // external view.
+ 10.0.1/24; }; // accept from these addresses.
...
};
view "external" {
match-clients { key external; any; };
- server 10.0.1.2 { keys external; };
+ server 10.0.1.2 { keys external; }; // tag messages from the
+ // external view to the
+ // other servers for the
+ // view.
recursion no;
...
};
diff --git a/Makefile.in b/Makefile.in
index 0021dadc..f2b730e3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -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.56 2009/06/25 17:06:42 each Exp $
+# $Id: Makefile.in,v 1.57 2009/09/01 00:22:24 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -21,13 +21,13 @@ top_srcdir = @top_srcdir@
@BIND9_VERSION@
-SUBDIRS = make lib bin doc
+SUBDIRS = make lib bin doc @LIBEXPORT@
TARGETS =
MANPAGES = isc-config.sh.1
-
+
HTMLPAGES = isc-config.sh.html
-
+
MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
diff --git a/README b/README
index 51dd5781..eae294c6 100644
--- a/README
+++ b/README
@@ -62,16 +62,24 @@ BIND 9.7.0
share a single cache.
- DNS rebinding attack prevention.
- New default values for dnssec-keygen parameters.
- - Support for RFC 5011 (automated trust anchor maintenance)
+ - Support for RFC 5011 automated trust anchor maintenance
+ (see README.rfc5011 for additional details).
- Smart signing: simplified tools for zone signing and key
- maintenance
- - The "statistics-channels" option is now available on Windows
+ maintenance.
+ - The "statistics-channels" option is now available on Windows.
+ - A new DNSSEC-aware libdns API for use by non-BIND9 applications
+ (see README.libdns for details).
+ - On some platforms, named and other binaries can now print out
+ a stack backtrace an assertion failure, to aid in debugging.
+ - A "tools only" installation mode on Windows, which only installs
+ dig, host, nslookup and nsupdate.
+ - Improved PKCS#11 support, including Keyper support (see
+ README.pkcs11 for additional details).
Planned but not complete in this alpha:
- Fully automatic signing of zones by "named"
- - DNSSEC-aware libdns API
- - Improved PKCS#11 support, including Keyper support
+ - Additional PKCS#11 support, including multiple OpenSSL engines
BIND 9.6.0
diff --git a/README.libdns b/README.libdns
new file mode 100644
index 00000000..2a16b7b1
--- /dev/null
+++ b/README.libdns
@@ -0,0 +1,275 @@
+
+ BIND-9 DNS Library Support
+
+This version of BIND9 "exports" its internal libraries so that they
+can be used by third-party applications more easily (we call them
+"export" libraries in this document). In addition to all major
+DNS-related APIs BIND9 is currently using, the export libraries
+provide the following features:
+
+- The newly created "DNS client" module. This is a higher level API
+ that provides an interface to name resolution, single DNS
+ transaction with a particular server, and dynamic update. Regarding
+ name resolution, it supports advanced features such as DNSSEC
+ validation and caching. This module supports both synchronous and
+ asynchronous mode.
+- The new "IRS" (Information Retrieval System) library. It provides
+ an interface to parse the traditional resolv.conf file and more
+ advanced, DNS-specific configuration file for the rest of this
+ package (see the description for the dns.conf file below).
+- As part of the IRS library, newly implemented standard address-name
+ mapping functions, getaddrinfo() and getnameinfo(), are provided.
+ They use the DNSSEC-aware validating resolver backend, and could use
+ other advanced features of the BIND9 libraries such as caching. The
+ getaddrinfo() function resolves both A and AAAA RRs concurrently
+ (when the address family is unspecified).
+- An experimental framework to support other event libraries than
+ BIND9's internal event task system.
+
+* Prerequisite
+
+GNU make is required to build the export libraries (other part of
+BIND9 can still be built with other types of make). In the reminder
+of this document, "make" means GNU make. Note that in some platforms
+you may need to invoke a different command name than "make"
+(e.g. "gmake") to indicate it's GNU make.
+
+* Compilation
+
+1. ./configure --enable-exportlib [other flags]
+2. make
+
+This will create (in addition to usual BIND9 programs) and a separate
+set of libraries under the lib/export directory. For example,
+lib/export/dns/libdns.a is the archive file of the export version of
+the BIND9 DNS library.
+
+Sample application programs using the libraries will also be built
+under the lib/export/samples directory (see below).
+
+* Installation
+
+1. cd lib/export
+2. make install (root privilege is normally required)
+ (make install at the top directory will do the same)
+
+This will install library object files under the directory specified
+by the --with-export-libdir configure option (default:
+EPREFIX/lib/bind9), and header files under the directory specified by
+the --with-export-installdir configure option (default:
+PREFIX/include/bind9).
+
+To see how to build your own application after the installation, see
+lib/export/samples/Makefile-postinstall.in
+
+* Known Defects/Restrictions
+
+- Currently, win32 is not supported for the export library. (Normal
+ BIND9 application can be built as before).
+- The "fixed" RRset order is not (currently) supported in the export
+ library. If you want to use "fixed" RRset order for, e.g. named
+ while still building the export library even without the fixed
+ order support, build them separately:
+ % ./configure --enable-fixed-rrset [other flags, but not --enable-exportlib]
+ % make (this doesn't have to be make)
+ % ./configure --enable-exportlib [other flags, but not --enable-fixed-rrset]
+ % cd lib/export
+ % make
+- The client module and the IRS library currently do not support
+ DNSSEC validation using DLV (the underlying modules can handle it,
+ but there is no tunable interface to enable the feature).
+- RFC5011 is not supported in the validating stub resolver of the
+ export library. In fact, it is not clear whether it should: trust
+ anchors would be a system-wide configuration which would be managed
+ by an administrator, while the stub resolver will be used by
+ ordinary applications run by a normal user.
+- Not all common /etc/resolv.conf options are supported in the IRS library.
+ The only available options in this version are "debug" and "ndots".
+
+* The dns.conf File
+
+The IRS library supports an "advanced" configuration file related to
+the DNS library for configuration parameters that would be beyond the
+capability of the resolv.conf file. Specifically, it is intended to
+provide DNSSEC related configuration parameters.
+
+By default the path to this configuration file is /etc/dns.conf.
+
+This module is very experimental and the configuration syntax or
+library interfaces may change in future versions. Currently, only the
+'trusted-keys' statement is supported, whose syntax is the same as the
+same name of statement for named.conf.
+
+* Sample Applications
+
+Some sample application programs using this API are provided for
+reference. The following is a brief description of these
+applications.
+
+- sample: a simple stub resolver utility.
+
+ It sends a query of a given name (of a given optional RR type)
+ to a specified recursive server, and prints the result as a list of
+ RRs. It can also act as a validating stub resolver if a trust
+ anchor is given via a set of command line options.
+
+ Usage: sample [options] server_address hostname
+
+ Options and Arguments:
+ -t RRtype
+ specify the RR type of the query. The default is the A RR.
+ [-a algorithm] [-e] -k keyname -K keystring
+ specify a command-line DNS key to validate the answer. For
+ example, to specify the following DNSKEY of example.com:
+ example.com. 3600 IN DNSKEY 257 3 5 xxx
+ specify the options as follows:
+ -e -k example.com -K "xxx"
+ -e means that this key is a zone's "key signing key" (as known
+ as "secure Entry point").
+ when -a is omitted rsasha1 will be used by default.
+ -s domain:alt_server_address
+ specify a separate recursive server address for the specific
+ "domain". Example: -s example.com:2001:db8::1234
+ server_address
+ an IP(v4/v6) address of the recursive server to which queries
+ are sent.
+ hostname
+ the domain name for the query
+
+- sample-async: a simple stub resolver, working asynchronously.
+
+ Similar to "sample", but accepts a list of (query) domain names as a
+ separate file and resolves the names asynchronously.
+
+ Usage: sample-async [-s server_address] [-t RR_type] input_file
+ Options and Arguments:
+ -s server_address
+ an IPv4 address of the recursive server to which queries are
+ sent. (IPv6 addresses are not supported in this implementation)
+ -t RR_type
+ specify the RR type of the queries. The default is the A RR.
+ input_file
+ a list of domain names to be resolved. each line consists of a
+ single domain name. Example:
+ www.example.com
+ mx.examle.net
+ ns.xxx.example
+
+- sample-request: a simple DNS transaction client.
+
+ It sends a query to a specified server, and prints the response with
+ minimal processing. It doesn't act as a "stub resolver": it stops
+ the processing once it gets any response from the server, whether
+ it's a referral or an alias (CNAME or DNAME) that would require
+ further queries to get the ultimate answer. In other words, this
+ utility acts as a very simplified dig.
+
+ Usage: sample-request [-t RRtype] server_address hostname
+ Options and Arguments:
+ -t RRtype
+ specify the RR type of the queries. The default is the A RR.
+ server_address
+ an IP(v4/v6) address of the recursive server to which the query is
+ sent.
+ hostname
+ the domain name for the query
+
+- sample-gai: getaddrinfo() and getnameinfo() test code.
+
+ This is a test program to check getaddrinfo() and getnameinfo()
+ behavior. It takes a host name as an argument, calls getaddrinfo()
+ with the given host name, and calls getnameinfo() with the resulting
+ IP addresses returned by getaddrinfo(). If the dns.conf file exists
+ and defines a trust anchor, the underlying resolver will act as a
+ validating resolver, and getaddrinfo()/getnameinfo() will fail with
+ an EAI_INSECUREDATA error when DNSSEC validation fails.
+
+ Usage: sample-gai hostname
+
+- sample-update: a simple dynamic update client program
+
+ It accepts a single update command as a command-line argument, sends
+ an update request message to the authoritative server, and shows the
+ response from the server. In other words, this is a simplified
+ nsupdate.
+
+ Usage: sample-update [options] (add|delete) "update data"
+ Options and Arguments:
+ -a auth_server
+ An IP address of the authoritative server that has authority
+ for the zone containing the update name. This should normally
+ be the primary authoritative server that accepts dynamic
+ updates. It can also be a secondary server that is configured
+ to forward update requests to the primary server.
+ -k keyfile
+ A TSIG key file to secure the update transaction. The keyfile
+ format is the same as that for the nsupdate utility.
+ -p prerequisite
+ A prerequisite for the update (only one prerequisite can be
+ specified). The prerequisite format is the same as that is
+ accepted by the nsupdate utility.
+ -r recursive_server
+ An IP address of a recursive server that this utility will
+ use. A recursive server may be necessary to identify the
+ authoritative server address to which the update request is
+ sent.
+ -z zonename
+ The domain name of the zone that contains
+ (add|delete)
+ Specify the type of update operation. Either "add" or "delete"
+ must be specified.
+ "update data"
+ Specify the data to be updated. A typical example of the data
+ would look like "name TTL RRtype RDATA".
+
+ Note: in practice, either -a or -r must be specified. Others can
+ be optional; the underlying library routine tries to identify the
+ appropriate server and the zone name for the update.
+
+ Examples: assuming the primary authoritative server of the
+ dynamic.example.com zone has an IPv6 address 2001:db8::1234,
+ + sample-update -a sample-update -k Kxxx.+nnn+mmmm.key add "foo.dynamic.example.com 30 IN A 192.168.2.1"
+ adds an A RR for foo.dynamic.example.com using the given key.
+ + sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com 30 IN A"
+ removes all A RRs for foo.dynamic.example.com using the given key.
+ + sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com"
+ removes all RRs for foo.dynamic.example.com using the given key.
+
+- nsprobe: domain/name server checker in terms of RFC4074.
+
+ It checks a set of domains to see the name servers of the domains
+ behave correctly in terms of RFC4074. This is included in the set
+ of sample programs to show how the export library can be used in a
+ DNS-related application.
+
+ Usage: nsprobe [-d] [-v [-v...]] [-c cache_address] [input_file]
+ Options
+ -d
+ run in the "debug" mode. with this option nsprobe will dump
+ every RRs it receives.
+ -v
+ increase verbosity of other normal log messages. This can be
+ specified multiple times
+ -c cache_address
+ specify an IP address of a recursive (caching) name server.
+ nsprobe uses this server to get the NS RRset of each domain and
+ the A and/or AAAA RRsets for the name servers. The default
+ value is 127.0.0.1.
+ input_file
+ a file name containing a list of domain (zone) names to be
+ probed. when omitted the standard input will be used. Each
+ line of the input file specifies a single domain name such as
+ "example.com". In general this domain name must be the apex
+ name of some DNS zone (unlike normal "host names" such as
+ "www.example.com"). nsprobe first identifies the NS RRsets for
+ the given domain name, and sends A and AAAA queries to these
+ servers for some "widely used" names under the zone;
+ specifically, adding "www" and "ftp" to the zone name.
+
+* Library References
+
+As of this writing, there is no formal "manual" of the libraries,
+except this document, header files (some of them provide pretty
+detailed explanations), and sample application programs.
+
+; $Id: README.libdns,v 1.2 2009/09/01 00:22:24 jinmei Exp $
diff --git a/README.pkcs11 b/README.pkcs11
index b58640de..72103732 100644
--- a/README.pkcs11
+++ b/README.pkcs11
@@ -1,61 +1,289 @@
- BIND-9 PKCS#11 support
+ BIND 9 PKCS #11 (Cryptoki) support
-Prerequisite
+INTRODUCTION
-The PKCS#11 support needs a PKCS#11 OpenSSL engine based on the Solaris one,
-released the 2007-11-21 for OpenSSL 0.9.8g, with a bug fix (call to free)
-and some improvements, including user friendly PIN management.
+PKCS #11 (Public Key Cryptography Standard #11) defines a platform-
+independent API for the control of hardware security modules (HSMs)
+and other cryptographic support devices.
-Compilation
+BIND 9 is known to work with two HSMs: The Sun SCA 6000 cryptographic
+acceration board, tested under Solaris x86, and the AEP Keyper
+network-attached key storage device, tested with a Debian Linux system.
+(The Keyper has also been tested with Windows Server 2003 and found to
+work, but with some stability problems that have not yet been resolved.)
-"configure --with-pkcs11 ..."
+PREREQUISITES
-PKCS#11 Libraries
+See the HSM vendor documentation for information about installing,
+initializing, testing and troubleshooting the HSM.
-Tested with Solaris one with a SCA board and with openCryptoki with the
-software token.
+BIND 9 uses OpenSSL for cryptography, but stock OpenSSL does not
+yet fully support PKCS #11. However, a PKCS #11 engine for OpenSSL
+is available from the OpenSolaris project. It has been modified by
+ISC to work with with BIND 9 and to provide new features such as
+PIN management and key by reference.
-OpenSSL Engines
+The modified OpenSSL depends on a "PKCS #11 provider". This is a shared
+library object, providing a low-level PKCS #11 interface to the HSM
+hardware; it is dynamically loaded by OpenSSL at runtime. The PKCS #11
+provider comes from the HSM vendor, and and is specific to the HSM to be
+controlled.
-With PKCS#11 support the PKCS#11 engine is statically loaded but at its
-initialization it dynamically loads the PKCS#11 objects.
-Even the pre commands are therefore unused they are defined with:
- SO_PATH:
- define: PKCS11_SO_PATH
- default: /usr/local/lib/engines/engine_pkcs11.so
- MODULE_PATH:
- define: PKCS11_MODULE_PATH
- default: /usr/lib/libpkcs11.so
-Without PKCS#11 support, a specific OpenSSL engine can be still used
-by defining ENGINE_ID at compile time.
+The modified OpenSSL code is included in BIND 9.7.0a3 release in the form
+of a context diff against OpenSSL 0.9.8i. Before building BIND 9 with
+PKCS #11 support, it will be necessary to build OpenSSL with this patch
+in place and inform it of the path to the HSM-specific PKCS #11 provider
+library.
-PKCS#11 tools
+Obtain OpenSSL 0.9.8i:
-The contrib/pkcs11-keygen directory contains a set of experimental tools
-to handle keys stored in a Hardware Security Module at the benefit of BIND.
+ wget http://www.openssl.org/source/openssl-0.9.8i.tar.gz
-The patch for OpenSSL 0.9.8g is in this directory. Read its README.pkcs11
-for the way to use it (these are the original notes so with the original
-path, etc. Define OPENCRYPTOKI to use it with openCryptoki.)
+Extract the tarball:
-PIN management
+ tar zxf openssl-0.9.8i.tar.gz
-With the just fixed PKCS#11 OpenSSL engine, the PIN should be entered
-each time it is required. With the improved engine, the PIN should be
-entered the first time it is required or can be configured in the
-OpenSSL configuration file (aka. openssl.cnf) by adding in it:
- - at the beginning:
- openssl_conf = openssl_def
- - at any place these sections:
- [ openssl_def ]
- engines = engine_section
- [ engine_section ]
- pkcs11 = pkcs11_section
- [ pkcs11_section ]
- PIN = put__your__pin__value__here
+Apply the patch from the BIND 9 release:
-Note
+ patch -p1 -d openssl-0.9.8i \
+ < bind-9.7.0a3/contrib/pkcs11-keygen/openssl-0.9.8i-patch
-Some names here are registered trademarks, at least Solaris is a trademark
-of Sun Microsystems Inc...
+(Note that the patch file may not be compatible with the "patch" utility
+on all operating systems. You may need to install GNU patch.)
+
+When building OpenSSL, place it in a non-standard location so that it
+does not interfere with OpenSSL libraries elsewhere on the system.
+In the following examples, we choose to install into "/opt/pkcs11/usr".
+We will use this location when we configure BIND 9.
+
+ EXAMPLE 1--BUILDING OPENSSL FOR THE AEP KEYPER ON LINUX:
+
+ The AEP Keyper is a highly-secured key storage device, but it does
+ not provide hardware cryptographic acceleration. It can carry out
+ cryptographic operations, but it is probably slower than your
+ system's CPU, so it is most efficient to use it only for operations
+ that require the secured private key.
+
+ The patched OpenSSL source tree includes two versions of the PKCS #11
+ engine; one uses the HSM for all cryptographic operations, and the
+ other only uses it for signing. The signing-only engine is recommended
+ for the Keyper. To build OpenSSL with the signing-only engine:
+
+ cp openssl-0.9.8i/crypto/engine/hw_pk11-kp.c \
+ openssl-0.9.8i/crypto/engine/hw_pk11.c
+ cp openssl-0.9.8i/crypto/engine/hw_pk11_pub-kp.c \
+ openssl-0.9.8i/crypto/engine/hw_pk11_pub.c
+
+ The Keyper-specific PKCS #11 provider library is delivered with the
+ Keyper software. In this example, we place it /opt/pkcs11/usr/lib:
+
+ cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so
+
+ This library is only available for Linux as a 32-bit binary. If we are
+ compiling on a 64-bit Linux system, it is necessary to force a 32-bit
+ build, by specifying -m32 in the build options.
+
+ Finally, the Keyper library requires threads, so we must specify -pthread.
+
+ cd openssl-0.9.8i
+ ./Configure linux-generic32 -m32 -pthread \
+ --pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \
+ --prefix=/opt/pkcs11/usr
+
+ After configuring, run "make" and "make test". If "make test" fails
+ with "pthread_atfork() not found", you forgot to add the -pthread
+ above.
+
+ EXAMPLE 2--BUILDING OPENSSL FOR THE SCA 6000 ON SOLARIS:
+
+ The SCA-6000 PKCS #11 provider is installed as a system library,
+ libpkcs11.
+
+ In this example, we are building on Solaris x86 on an AMD64 system.
+
+ cd openssl-0.9.8i
+ ./Configure solaris64-x86_64-cc \
+ --pk11-libname=/usr/lib/64/libpkcs11.so \
+ --prefix=/opt/pkcs11/usr
+
+ (For a 32-bit build, use "solaris-x86-cc" and /usr/lib/libpkcs11.so.)
+
+ After configuring, run "make" and "make test".
+
+Once you have built OpenSSL, run "apps/openssl engine" to confirm that
+PKCS #11 support was compiled in correctly. The output should include the
+line:
+
+ (pkcs11) PKCS #11 engine support
+
+If the output is correct, run "make install".
+
+BUILDING BIND 9
+
+When building BIND 9, the location of the custom-built OpenSSL
+library must be specified via configure.
+
+ EXAMPLE 3--CONFIGURING BIND 9 FOR LINUX
+
+ To link with the PKCS #11 provider, threads must be enabled in the
+ BIND 9 build.
+
+ The PKCS #11 library is only available as a 32-bit binary. If
+ we are building on a 64-bit host, we must force a 32-bit build by
+ adding "-m32" to the CC options on the "configure" command line.
+
+ cd ../bind-9.7.0a3
+ ./configure CC="gcc -m32" --enable-threads \
+ --with-openssl=/opt/pkcs11/usr
+
+ EXAMPLE 4--CONFIGURING BIND 9 FOR SOLARIS
+
+ To link with the PKCS #11 provider, threads must be enabled in the
+ BIND 9 build.
+
+ cd ../bind-9.7.0a3
+ ./configure CC="cc -xarch=amd64" --enable-threads \
+ --with-openssl=/opt/pkcs11/usr
+
+ (For a 32-bit build, omit CC="cc -xarch=amd64".)
+
+If configure complains about OpenSSL not working, you may have a 32/64-bit
+architecture mismatch. Or, you may have incorrectly specified the path to
+OpenSSL (it should be the same as the --prefix argument to the OpenSSL
+Configure).
+
+After configuring, run "make", "make test" and "make install".
+
+PKCS #11 TOOLS
+
+The contrib/pkcs11-keygen directory contains a set of experimental
+tools to operate an HSM for the benefit of BIND 9, including "genkey" to
+generate a new key pair within the HSM, and "listobjs" to list keys
+currently available.
+
+These tools are not yet complete, not documented, and not supported
+by ISC. As of BIND 9.7.0a3, they still lack such basic amenities as
+a Makefile. Other commercial or open-source PKCS #11 tools may be
+available which are better-suited to the job. However, in the
+absence of those tools, the ones provided in contrib/pkcs11-keygen
+can get you started.
+
+ EXAMPLE 5--BUILDING TOOLS ON LINUX:
+
+ gcc -m32 -DHAVE_GETPASS -I. -L /opt/pkcs11/usr/lib \
+ genkey.c -o genkey -lpkcs11
+ gcc -m32 -DHAVE_GETPASS -I. -L /opt/pkcs11/usr/lib \
+ listobjs.c -o listobjs -lpkcs11
+ gcc -m32 -DHAVE_GETPASS -I. -L /opt/pkcs11/usr/lib \
+ destroyobj.c -o destroyobj -lpkcs11
+ cd ../..
+
+ EXAMPLE 6--BUILDING TOOLS ON SOLARIS WITH SCA 6000:
+
+ cc -I. genkey.c -o genkey -lpkcs11
+ cc -I. listobjs.c -o listobjs -lpkcs11
+ cc -I. destroyobj.c -o destroyobj -lpkcs11
+ cd ../..
+
+USING THE HSM
+
+First, we must set up the runtime environment so the OpenSSL and PKCS #11
+libraries can be loaded:
+
+ export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH}
+
+When operating an AEP Keyper, it is also necessary to specify the
+location of the "machine" file, which stores information about the Keyper
+for use by PKCS #11 provider library. If the machine file is in
+/opt/Keyper/PKCS11Provider/machine, use:
+
+ export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider
+
+These environment variables must be set whenever running any tool
+which uses the HSM, including genkey, listobjs, destroyobj,
+dnssec-keyfromlabel, dnssec-signzone, and named.
+
+We can now create and use keys in the HSM. In this case, we will
+create a 2048 bit key and give it the label "sample-ksk":
+
+ contrib/pkcs11-keygen/genkey -b 2048 -l sample-ksk
+
+To confirm that the key exists:
+
+ contrib/pkcs11-keygen/listobjs
+ Enter PIN:
+ object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0]
+ object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0]
+
+Before using this key to sign a zone, we must create a pair of BIND 9
+key files. The "dnssec-keyfromlabel" utility does this. In this case,
+we will be using the HSM key "sample-ksk" as the key-signing key for
+"example.net":
+
+ dnssec-keyfromlabel -a NSEC3RSASHA1 -l pkcs11:sample-ksk -f KSK example.net
+
+(Note: It is necessary to specify "pkcs11:" before the key's label;
+otherwise the PCKS #11 engine will look for the key on disk rather than
+in the HSM. If you forget to do this, dnssec-keyfromlabel will return
+"not found".)
+
+The resulting K*.key and K*.private files can now be used to sign the
+zone. Unlike normal K* files, which contain both public and private
+key data, these files will contain only the public key data, plus an
+identifier for the private key which remains stored within the HSM.
+The HSM handles signing with the private key.
+
+If you wish to generate a second key in the HSM for use as a zone-signing
+key, follow the same procedure above, using a different keylabel, a
+smaller key size, and omitting "-f KSK" from the dnssec-keyfromlabel
+arguments:
+
+ contrib/pkcs11-keygen/genkey -b 1024 -l sample-zsk
+ dnssec-keyfromlabel -a NSEC3RSASHA1 -l pkcs11:sample-zsk example.net
+
+Alternatively, you may prefer to generate a conventional on-disk key, using
+dnssec-keygen:
+
+ dnssec-keygen -a NSEC3RSASHA1 -b 1024 example.net
+
+This provides less security than an HSM key, but since HSMs are often
+slower at signing than your system's CPU, it may be more efficient to
+reserve HSM keys for the less-frequent key-signing operation. The
+zone-signing key can be rolled more frequently, if you wish, to
+compensate for a reduction in key security.
+
+Now you can sign the zone. (Note: If not using the -S option to
+dnssec-signzone, it will be necessary to add the contents of both
+K*.key files to the zone master file before signing it.)
+
+ dnssec-signzone -S example.net
+ Enter PIN:
+ Verifying the zone using the following algorithms: NSEC3RSASHA1.
+ Zone signing complete:
+ Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by
+ example.net.signed
+
+RUNNING NAMED WITH AUTOMATIC ZONE RE-SIGNING
+
+If you want named to dynamically re-sign zones using HSM keys, and/or to
+to sign new records inserted via nsupdate, then named must have access
+to the HSM PIN. This can be accomplished by placing the PIN into the
+openssl.cnf file (in the above examples, /opt/pkcs11/usr/ssl/openssl.cnf).
+
+The location of the openssl.cnf file can be overridden by setting the
+OPENSSL_CONF environment variable before running named.
+
+Sample openssl.cnf:
+
+ openssl_conf = openssl_def
+ [ openssl_def ]
+ engines = engine_section
+ [ engine_section ]
+ pkcs11 = pkcs11_section
+ [ pkcs11_section ]
+ PIN = <PLACE PIN HERE>
+
+PLEASE NOTE: Placing the HSM's PIN in a text file in this manner
+may reduce the security advantage of using an HSM. Be sure this
+is what you want to do before configuring BIND 9 in this way.
diff --git a/README.rfc5011 b/README.rfc5011
index e8f07d0f..02aac566 100644
--- a/README.rfc5011
+++ b/README.rfc5011
@@ -1,11 +1,18 @@
+
+ BIND 9 RFC 5011 support
+
BIND 9.7.0 introduces support for RFC 5011, dynamic trust anchor
management. Using this feature allows named to keep track of changes to
critical DNSSEC keys without any need for the operator to make changes to
configuration files.
-As of 9.7.0a1, the syntax for using RFC5011 is expected to change, so
-proper documentation has yet to be written. This file is intended to
-provide enough information to get started.
+VALIDATING RESOLVER
+-------------------
+
+To configure a validating resolver to use RFC5011 to maintain a trust
+anchor, configure the trust anchor using a "managed-keys" statement.
+Information about this can be found in the ARM, in the section titled
+"managed-keys Statement Definition".
AUTHORITATIVE SERVER
--------------------
@@ -22,6 +29,14 @@ will recheck the zone periodically, and after 30 days, if the new key is
still there, then the key will be accepted by the resolver as a valid
trust anchor for the zone.
+The easiest way to place a stand-by key in a zone is to use the "smart
+signing" features of dnssec-signzone. If a key with a publication date
+in the past, but an activation date in the future, "dnssec-signzone -S"
+will include the DNSKEY record in the zone, but will not sign with it:
+
+ $ dnssec-keygen -K keys -f KSK -P now -A now+2y example.net
+ $ dnssec-signzone -S -K keys example.net
+
At any time after this 30-day acceptance timer has expired, the active
KSK can be revoked and the zone can be "rolled over" to one of the
standby KSKs.
@@ -31,37 +46,12 @@ the REVOKED bit to the key flags and re-generates the K*.key and K*.private
files.
After revoking the active key, the zone must be signed with both the
-revoked KSK and the new active KSK. Once a key has been revoked and
-used to sign the DNSKEY RRset in which it appears, that key will never
-again be accepted as a valid trust anchor by the resolver. However,
-validation can proceed using the new active key (which had been accepted
-by the resolver when it was a stand-by key).
-
-See RFC 5011 for more details on key rollover scenarios.
+revoked KSK and the new active KSK. (Smart signing takes care of this
+automatically.)
-VALIDATING RESOLVER
--------------------
+Once a key has been revoked and used to sign the DNSKEY RRset in which it
+appears, that key will never again be accepted as a valid trust anchor by
+the resolver. However, validation can proceed using the new active key
+(which had been accepted by the resolver when it was a stand-by key).
-NOTE: This is expected to change before 9.7.0 is final!
-
-To configure a validating resolver to use RFC5011 to maintain a trust
-anchor, configure the trust anchor using a "managed-keys" statement
-instead of a "trusted-keys" statement.
-
-The syntax for "managed-keys" is identical to that for "trusted-keys".
-However, whereas a trusted key is trusted permanently until it is removed
-from named.conf, a managed key is only trusted for as long as it takes to
-initialize RFC5011 key maintenance.
-
-When named loads for the first time with a managed key configured, it
-will fetch the DNSKEY RRset directly from the zone apex and check its
-signature against the key specified in the "managed-keys" statement.
-If it is validly signed, then the DNSKEY RRset is used as the basis for a
-new managed keys database.
-
-From that point on, when named loads, it will see the "managed-keys"
-statement, check to make sure RFC5011 key maintenance has already been
-initialized for the specified zone, and if so, it will simply move on.
-No action will be taken unless a key is *removed* from the "managed-keys"
-statement--in which case that zone is removed from the managed keys
-database as well, and RFC5011 key maintenance will no longer be used.
+See RFC 5011 for more details on key rollover scenarios.
diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in
index 06f55418..b586b5ba 100644
--- a/bin/check/Makefile.in
+++ b/bin/check/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.32 2007/06/19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.35 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -26,12 +26,13 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISCCFG_INCLUDES} \
${ISC_INCLUDES}
-CDEFINES = -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\"
+CDEFINES = -DBIND9 -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\"
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
@@ -39,7 +40,8 @@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-LIBS = @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
SUBDIRS =
@@ -69,14 +71,14 @@ named-checkzone.@O@: named-checkzone.c
named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \
${ISCCFGDEPLIBS} ${BIND9DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- named-checkconf.@O@ check-tool.@O@ ${BIND9LIBS} ${ISCCFGLIBS} \
- ${DNSLIBS} ${ISCLIBS} ${LIBS}
+ export BASEOBJS="named-checkconf.@O@ check-tool.@O@"; \
+ export LIBS0="${BIND9LIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- named-checkzone.@O@ check-tool.@O@ ${ISCCFGLIBS} ${DNSLIBS} \
- ${ISCLIBS} ${LIBS}
+ export BASEOBJS="named-checkzone.@O@ check-tool.@O@"; \
+ export LIBS0="${ISCCFGLIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c
index 0bad407a..09fd2c99 100644
--- a/bin/check/check-tool.c
+++ b/bin/check/check-tool.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.c,v 1.38 2009/01/20 02:01:11 marka Exp $ */
+/* $Id: check-tool.c,v 1.39 2009/09/01 00:22:24 jinmei Exp $ */
/*! \file */
@@ -597,8 +597,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
isc_buffer_add(&buffer, strlen(zonename));
dns_fixedname_init(&fixorigin);
origin = dns_fixedname_name(&fixorigin);
- CHECK(dns_name_fromtext(origin, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
CHECK(dns_zone_setorigin(zone, origin));
CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype));
CHECK(dns_zone_setfile2(zone, filename, fileformat));
diff --git a/bin/confgen/Makefile.in b/bin/confgen/Makefile.in
index b67ccdd0..5bfdc6ad 100644
--- a/bin/confgen/Makefile.in
+++ b/bin/confgen/Makefile.in
@@ -12,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.4 2009/07/14 22:54:56 each Exp $
+# $Id: Makefile.in,v 1.6 2009/09/01 18:40:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,7 +25,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \
${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
@@ -43,7 +43,10 @@ BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
-CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+
+NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
+
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
SRCS= rndc-confgen.c ddns-confgen.c
@@ -71,12 +74,12 @@ ddns-confgen.@O@: ddns-confgen.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c ${srcdir}/ddns-confgen.c
rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc-confgen.@O@ util.@O@ keygen.@O@ \
- ${UOBJS} ${CONFLIBS}
+ export BASEOBJS="rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
ddns-confgen@EXEEXT@: ddns-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ddns-confgen.@O@ util.@O@ keygen.@O@ \
- ${UOBJS} ${CONFLIBS}
+ export BASEOBJS="ddns-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in
index bc9d34f0..3cb1bd1f 100644
--- a/bin/dig/Makefile.in
+++ b/bin/dig/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.41 2007/06/19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.44 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -26,13 +26,14 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \
${ISC_INCLUDES} ${LWRES_INCLUDES}
-CDEFINES = -DVERSION=\"${VERSION}\"
+CDEFINES = -DBIND9 -DVERSION=\"${VERSION}\"
CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
@@ -47,6 +48,9 @@ DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \
LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} \
${ISCCFGLIBS} @IDNLIBS@ @LIBS@
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCNOSYMLIBS} \
+ ${ISCCFGLIBS} @IDNLIBS@ @LIBS@
+
SUBDIRS =
TARGETS = dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@
@@ -66,16 +70,16 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dig.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="dig.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
host@EXEEXT@: host.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- host.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="host.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
nslookup@EXEEXT@: nslookup.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- nslookup.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="nslookup.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 271f806e..f1fa25ef 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dighost.c,v 1.323 2009/07/19 04:18:03 each Exp $ */
+/* $Id: dighost.c,v 1.324 2009/09/01 00:22:24 jinmei Exp $ */
/*! \file
* \note
@@ -921,9 +921,7 @@ setup_text_key(void) {
secretsize = isc_buffer_usedlength(&secretbuf);
- result = dns_name_fromtext(&keyname, namebuf,
- dns_rootname, ISC_FALSE,
- namebuf);
+ result = dns_name_fromtext(&keyname, namebuf, dns_rootname, 0, namebuf);
if (result != ISC_R_SUCCESS)
goto failure;
@@ -1890,7 +1888,7 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&b, lookup->origin->origin, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->oname, &b, dns_rootname,
- ISC_FALSE, &lookup->onamebuf);
+ 0, &lookup->onamebuf);
if (result != ISC_R_SUCCESS) {
dns_message_puttempname(lookup->sendmsg,
&lookup->name);
@@ -1907,7 +1905,7 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&b, lookup->textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
- lookup->oname, ISC_FALSE,
+ lookup->oname, 0,
&lookup->namebuf);
}
if (result != ISC_R_SUCCESS) {
@@ -1931,16 +1929,14 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&b, idn_textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
- dns_rootname,
- ISC_FALSE,
+ dns_rootname, 0,
&lookup->namebuf);
#else
len = strlen(lookup->textname);
isc_buffer_init(&b, lookup->textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
- dns_rootname,
- ISC_FALSE,
+ dns_rootname, 0,
&lookup->namebuf);
#endif
}
@@ -4085,7 +4081,7 @@ nameFromString(const char *str, dns_name_t *p_ret) {
dns_fixedname_init(&fixedname);
result = dns_name_fromtext(dns_fixedname_name(&fixedname), &buffer,
- dns_rootname, ISC_TRUE, NULL);
+ dns_rootname, DNS_NAME_DOWNCASE, NULL);
check_result(result, "nameFromString");
if (dns_name_dynamic(p_ret))
diff --git a/bin/dig/host.c b/bin/dig/host.c
index 8e414a48..a278a3df 100644
--- a/bin/dig/host.c
+++ b/bin/dig/host.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: host.c,v 1.118 2009/05/06 23:47:50 tbox Exp $ */
+/* $Id: host.c,v 1.119 2009/09/08 23:23:22 marka Exp $ */
/*! \file */
@@ -839,11 +839,10 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
} else {
strncpy(lookup->textname, hostname, sizeof(lookup->textname));
lookup->textname[sizeof(lookup->textname)-1]=0;
+ usesearch = ISC_TRUE;
}
lookup->new_search = ISC_TRUE;
ISC_LIST_APPEND(lookup_list, lookup, link);
-
- usesearch = ISC_TRUE;
}
int
diff --git a/bin/dnssec/Makefile.in b/bin/dnssec/Makefile.in
index af6f3a55..2af3838f 100644
--- a/bin/dnssec/Makefile.in
+++ b/bin/dnssec/Makefile.in
@@ -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.38 2009/07/19 04:18:04 each Exp $
+# $Id: Makefile.in,v 1.40 2009/09/01 18:40:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,11 +25,12 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES = -DVERSION=\"${VERSION}\"
+CDEFINES = -DBIND9 -DVERSION=\"${VERSION}\"
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
@@ -38,6 +39,8 @@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
+
# Alphabetically
TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \
dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \
@@ -60,24 +63,24 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
dnssec-dsfromkey@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-dsfromkey.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-dsfromkey.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-keyfromlabel@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-keyfromlabel.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-keyfromlabel.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-keygen.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-keygen.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-signzone.@O@: dnssec-signzone.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
-c ${srcdir}/dnssec-signzone.c
dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-signzone.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-revoke@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
diff --git a/bin/dnssec/dnssec-dsfromkey.8 b/bin/dnssec/dnssec-dsfromkey.8
index 9fd4cec2..907c1083 100644
--- a/bin/dnssec/dnssec-dsfromkey.8
+++ b/bin/dnssec/dnssec-dsfromkey.8
@@ -12,18 +12,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-dsfromkey.8,v 1.10 2009/07/19 04:27:55 tbox Exp $
+.\" $Id: dnssec-dsfromkey.8,v 1.11 2009/08/27 01:14:39 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: dnssec\-dsfromkey
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: November 29, 2008
+.\" Date: August 26, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "DNSSEC\-DSFROMKEY" "8" "November 29, 2008" "BIND9" "BIND9"
+.TH "DNSSEC\-DSFROMKEY" "8" "August 26, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -32,9 +32,9 @@
dnssec\-dsfromkey \- DNSSEC DS RR generation tool
.SH "SYNOPSIS"
.HP 17
-\fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] {keyfile}
+\fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] {keyfile}
.HP 17
-\fBdnssec\-dsfromkey\fR {\-s} [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-s\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-A\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {dnsname}
+\fBdnssec\-dsfromkey\fR {\-s} [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-s\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-A\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {dnsname}
.SH "DESCRIPTION"
.PP
\fBdnssec\-dsfromkey\fR
@@ -82,7 +82,7 @@ Include ZSK's when generating DS records. Without this option, only keys which h
.RS 4
Generate a DLV set instead of a DS set. The specified
\fBdomain\fR
-is appended to the name for each record in the set.
+is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431.
.RE
.PP
\-s
@@ -133,6 +133,7 @@ A keyfile error can give a "file not found" even if the file exists.
\fBdnssec\-signzone\fR(8),
BIND 9 Administrator Reference Manual,
RFC 3658,
+RFC 4431.
RFC 4509.
.SH "AUTHOR"
.PP
diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c
index 18fb64e9..9b1b55a8 100644
--- a/bin/dnssec/dnssec-dsfromkey.c
+++ b/bin/dnssec/dnssec-dsfromkey.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-dsfromkey.c,v 1.11 2009/07/19 23:47:55 tbox Exp $ */
+/* $Id: dnssec-dsfromkey.c,v 1.13 2009/09/01 00:22:24 jinmei Exp $ */
/*! \file */
@@ -72,7 +72,7 @@ initname(char *setname) {
isc_buffer_init(&buf, setname, strlen(setname));
isc_buffer_add(&buf, strlen(setname));
- result = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
return (result);
}
@@ -367,7 +367,7 @@ main(int argc, char **argv) {
/* fall through */
case 'K':
dir = isc_commandline_argument;
- if (strlen(dir) == 0)
+ if (strlen(dir) == 0U)
fatal("directory must be non-empty string");
break;
case 'f':
@@ -375,7 +375,7 @@ main(int argc, char **argv) {
break;
case 'l':
lookaside = isc_commandline_argument;
- if (strlen(lookaside) == 0)
+ if (strlen(lookaside) == 0U)
fatal("lookaside must be a non-empty string");
break;
case 's':
diff --git a/bin/dnssec/dnssec-dsfromkey.docbook b/bin/dnssec/dnssec-dsfromkey.docbook
index 7f777b76..df24df14 100644
--- a/bin/dnssec/dnssec-dsfromkey.docbook
+++ b/bin/dnssec/dnssec-dsfromkey.docbook
@@ -17,10 +17,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-dsfromkey.docbook,v 1.9 2009/07/19 04:18:04 each Exp $ -->
+<!-- $Id: dnssec-dsfromkey.docbook,v 1.10 2009/08/26 21:56:05 jreed Exp $ -->
<refentry id="man.dnssec-dsfromkey">
<refentryinfo>
- <date>November 29, 2008</date>
+ <date>August 26, 2009</date>
</refentryinfo>
<refmeta>
@@ -49,6 +49,7 @@
<arg><option>-1</option></arg>
<arg><option>-2</option></arg>
<arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
+ <arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg choice="req">keyfile</arg>
</cmdsynopsis>
<cmdsynopsis>
@@ -58,6 +59,7 @@
<arg><option>-2</option></arg>
<arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg><option>-s</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">file</replaceable></option></arg>
@@ -150,6 +152,8 @@
Generate a DLV set instead of a DS set. The specified
<option>domain</option> is appended to the name for each
record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</para>
</listitem>
</varlistentry>
@@ -233,6 +237,7 @@
</citerefentry>,
<citetitle>BIND 9 Administrator Reference Manual</citetitle>,
<citetitle>RFC 3658</citetitle>,
+ <citetitle>RFC 4431</citetitle>.
<citetitle>RFC 4509</citetitle>.
</para>
</refsect1>
diff --git a/bin/dnssec/dnssec-dsfromkey.html b/bin/dnssec/dnssec-dsfromkey.html
index e143f310..45f9a3ac 100644
--- a/bin/dnssec/dnssec-dsfromkey.html
+++ b/bin/dnssec/dnssec-dsfromkey.html
@@ -14,7 +14,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-dsfromkey.html,v 1.10 2009/07/19 04:27:55 tbox Exp $ -->
+<!-- $Id: dnssec-dsfromkey.html,v 1.11 2009/08/27 01:14:39 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,18 +29,18 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] {keyfile}</p></div>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] {keyfile}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543444"></a><h2>DESCRIPTION</h2>
+<a name="id2543461"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-dsfromkey</strong></span>
outputs the Delegation Signer (DS) resource record (RR), as defined in
RFC 3658 and RFC 4509, for the given key(s).
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543456"></a><h2>OPTIONS</h2>
+<a name="id2543473"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-1</span></dt>
<dd><p>
@@ -81,6 +81,8 @@
Generate a DLV set instead of a DS set. The specified
<code class="option">domain</code> is appended to the name for each
record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</p></dd>
<dt><span class="term">-s</span></dt>
<dd><p>
@@ -99,7 +101,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543642"></a><h2>EXAMPLE</h2>
+<a name="id2543659"></a><h2>EXAMPLE</h2>
<p>
To build the SHA-256 DS RR from the
<strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
@@ -114,7 +116,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543672"></a><h2>FILES</h2>
+<a name="id2543689"></a><h2>FILES</h2>
<p>
The keyfile can be designed by the key identification
<code class="filename">Knnnn.+aaa+iiiii</code> or the full file name
@@ -128,22 +130,23 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543707"></a><h2>CAVEAT</h2>
+<a name="id2543724"></a><h2>CAVEAT</h2>
<p>
A keyfile error can give a "file not found" even if the file exists.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543717"></a><h2>SEE ALSO</h2>
+<a name="id2543734"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 3658</em>,
+ <em class="citetitle">RFC 4431</em>.
<em class="citetitle">RFC 4509</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543753"></a><h2>AUTHOR</h2>
+<a name="id2543773"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-keyfromlabel.8 b/bin/dnssec/dnssec-keyfromlabel.8
index 10c46edb..62e261df 100644
--- a/bin/dnssec/dnssec-keyfromlabel.8
+++ b/bin/dnssec/dnssec-keyfromlabel.8
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keyfromlabel.8,v 1.9 2009/07/20 01:13:18 tbox Exp $
+.\" $Id: dnssec-keyfromlabel.8,v 1.10 2009/09/08 01:14:42 tbox Exp $
.\"
.hy 0
.ad l
@@ -32,18 +32,22 @@
dnssec\-keyfromlabel \- DNSSEC key generation tool
.SH "SYNOPSIS"
.HP 20
-\fBdnssec\-keyfromlabel\fR {\-a\ \fIalgorithm\fR} {\-l\ \fIlabel\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+\fBdnssec\-keyfromlabel\fR {\-a\ \fIalgorithm\fR} {\-l\ \fIlabel\fR} [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-U\ \fR\fB\fIdate/offset\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
.SH "DESCRIPTION"
.PP
\fBdnssec\-keyfromlabel\fR
gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034.
+.PP
+The
+\fBname\fR
+of the key is specified on the command line. This must match the name of the zone for which the key is being generated.
.SH "OPTIONS"
.PP
\-a \fIalgorithm\fR
.RS 4
Selects the cryptographic algorithm. The value of
\fBalgorithm\fR
-must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). These values are case insensitive.
+must be one of RSAMD5 (RSA), RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). These values are case insensitive.
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended.
.sp
@@ -62,6 +66,15 @@ Specifies the owner type of the key. The value of
must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.
.RE
.PP
+\-C
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keyfromlabel\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.RE
+.PP
\-c \fIclass\fR
.RS 4
Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.
@@ -69,13 +82,13 @@ Indicates that the DNS record containing the key should have the specified class
.PP
\-f \fIflag\fR
.RS 4
-Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flag is KSK (Key Signing Key) DNSKEY.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
.RE
.PP
\-h
.RS 4
Prints a short summary of the options and arguments to
-\fBdnssec\-keygen\fR.
+\fBdnssec\-keyfromlabel\fR.
.RE
.PP
\-K \fIdirectory\fR
@@ -90,7 +103,7 @@ Generate KEY records rather than DNSKEY records.
.PP
\-p \fIprotocol\fR
.RS 4
-Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
+Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
.RE
.PP
\-t \fItype\fR
@@ -104,6 +117,34 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included and the zone and used to sign it.
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-U \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be unpublished. After that date, the key will no longer be included in the zone, but it may remain in the key repository.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key can be removed from the key repository. NOTE: Keys are not currently deleted automatically; this field is included for informational purposes and for future development.
+.RE
.SH "GENERATED KEY FILES"
.PP
When
@@ -137,7 +178,7 @@ file contains a DNS KEY record that can be inserted into a zone file (directly o
.PP
The
\fI.private\fR
-file contains algorithm specific fields. For obvious security reasons, this file does not have general read permission.
+file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission.
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c
index 02bba62a..af3504d7 100644
--- a/bin/dnssec/dnssec-keyfromlabel.c
+++ b/bin/dnssec/dnssec-keyfromlabel.c
@@ -14,12 +14,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keyfromlabel.c,v 1.9 2009/07/19 04:18:04 each Exp $ */
+/* $Id: dnssec-keyfromlabel.c,v 1.13 2009/09/07 23:11:48 fdupont Exp $ */
/*! \file */
#include <config.h>
+#include <ctype.h>
#include <stdlib.h>
#include <isc/buffer.h>
@@ -58,25 +59,32 @@ usage(void) {
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Required options:\n");
fprintf(stderr, " -a algorithm: %s\n", algs);
- fprintf(stderr, " -l label: label of the key\n");
+ fprintf(stderr, " -l label: label of the key pair\n");
fprintf(stderr, " name: owner of the key\n");
fprintf(stderr, "Other options:\n");
- fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
- fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
fprintf(stderr, " -c <class> (default: IN)\n");
- fprintf(stderr, " -f keyflag (KSK or REVOKE)\n");
+ fprintf(stderr, " -f keyflag: KSK | REVOKE\n");
fprintf(stderr, " -K directory: directory in which to place "
"key files\n");
+ fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+ fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
+ fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
+ fprintf(stderr, " -p <protocol>: default: 3 [dnssec]\n");
fprintf(stderr, " -t <type>: "
"AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
"(default: AUTHCONF)\n");
- fprintf(stderr, " -p <protocol>: "
- "default: 3 [dnssec]\n");
fprintf(stderr, " -v <verbose level>\n");
- fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+ fprintf(stderr, "Date options:\n");
+ fprintf(stderr, " -P date/[+-]offset: set key publication date\n");
+ fprintf(stderr, " -A date/[+-]offset: set key activation date\n");
+ fprintf(stderr, " -R date/[+-]offset: set key revocation date\n");
+ fprintf(stderr, " -U date/[+-]offset: set key unpublication date\n");
+ fprintf(stderr, " -D date/[+-]offset: set key deletion date\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting"
+ " dates\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K<name>+<alg>+<id>.key, "
- "K<name>+<alg>+<id>.private\n");
+ "K<name>+<alg>+<id>.private\n");
exit (-1);
}
@@ -84,15 +92,15 @@ usage(void) {
int
main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
- char *directory = NULL;
+ const char *directory = NULL;
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL, *oldkey = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0, revoke = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
- isc_boolean_t null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch;
int protocol = -1, signatory = 0;
@@ -104,7 +112,16 @@ main(int argc, char **argv) {
isc_entropy_t *ectx = NULL;
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
- char *label = NULL;
+ char *label = NULL, *engine = NULL;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t unpublish = 0, delete = 0;
+ isc_stdtime_t now;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setunpub = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetunpub = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
if (argc == 1)
usage();
@@ -115,22 +132,26 @@ main(int argc, char **argv) {
isc_commandline_errprint = ISC_FALSE;
+ isc_stdtime_get(&now);
+
while ((ch = isc_commandline_parse(argc, argv,
- "a:c:f:K:kl:n:p:t:v:Fh")) != -1)
+ "a:Cc:f:K:kl:n:p:t:v:FhP:A:R:U:D:")) != -1)
{
switch (ch) {
case 'a':
algname = isc_commandline_argument;
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
- else if (strcasecmp(isc_commandline_argument,
- "REVOKE") == 0)
- revoke = DNS_KEYFLAG_REVOKE;
+ if (toupper(isc_commandline_argument[0]) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(isc_commandline_argument[0]) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -161,6 +182,66 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'U':
+ if (setunpub || unsetunpub)
+ fatal("-U specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setunpub = ISC_TRUE;
+ unpublish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetunpub = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
case 'F':
/* Reserved for FIPS mode */
/* FALLTHROUGH */
@@ -245,11 +326,14 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY */
flags |= signatory;
else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
- flags |= ksk;
- flags |= revoke;
+ flags |= kskflag;
+ flags |= revflag;
}
if (protocol == -1)
@@ -273,19 +357,16 @@ main(int argc, char **argv) {
isc_buffer_init(&buf, argv[isc_commandline_index],
strlen(argv[isc_commandline_index]));
isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
- ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
if (ret != ISC_R_SUCCESS)
fatal("invalid key name %s: %s", argv[isc_commandline_index],
isc_result_totext(ret));
- if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
- null_key = ISC_TRUE;
-
isc_buffer_init(&buf, filename, sizeof(filename) - 1);
/* associate the key */
ret = dst_key_fromlabel(name, alg, flags, protocol,
- rdclass, "", label, NULL, mctx, &key);
+ rdclass, engine, label, NULL, mctx, &key);
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
@@ -293,16 +374,43 @@ main(int argc, char **argv) {
char algstr[ALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
alg_format(alg, algstr, sizeof(algstr));
- fatal("failed to generate key %s/%s: %s\n",
+ fatal("failed to get key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
exit(-1);
}
/*
+ * Set key timing metadata (unless using -C)
+ */
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, activate);
+ if (setrev)
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
+ if (setunpub)
+ dst_key_settime(key, DST_TIME_UNPUBLISH, unpublish);
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setunpub ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetunpub || unsetdel)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -U, or -D options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
+ }
+
+ /*
* Try to read a key with the same name, alg and id from disk.
- * If there is one we must continue generating a new one
- * unless we were asked to generate a null key, in which
- * case we return failure.
+ * If there is one we must return failure.
*/
ret = dst_key_fromfile(name, dst_key_id(key), alg,
DST_TYPE_PRIVATE, directory, mctx, &oldkey);
@@ -310,10 +418,7 @@ main(int argc, char **argv) {
if (ret == ISC_R_SUCCESS) {
isc_buffer_clear(&buf);
ret = dst_key_buildfilename(key, 0, directory, &buf);
- fprintf(stderr, "%s: %s already exists\n",
- program, filename);
- dst_key_free(&key);
- exit (1);
+ fatal("%s: %s already exists\n", program, filename);
}
ret = dst_key_tofile(key, options, directory);
@@ -325,7 +430,7 @@ main(int argc, char **argv) {
}
isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, directory, &buf);
+ ret = dst_key_buildfilename(key, 0, NULL, &buf);
printf("%s\n", filename);
dst_key_free(&key);
diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook
index 1e478d93..4beb25b9 100644
--- a/bin/dnssec/dnssec-keyfromlabel.docbook
+++ b/bin/dnssec/dnssec-keyfromlabel.docbook
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.docbook,v 1.8 2009/07/19 23:47:55 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.docbook,v 1.9 2009/09/07 12:54:59 fdupont Exp $ -->
<refentry id="man.dnssec-keyfromlabel">
<refentryinfo>
<date>February 8, 2008</date>
@@ -47,13 +47,18 @@
<command>dnssec-keyfromlabel</command>
<arg choice="req">-a <replaceable class="parameter">algorithm</replaceable></arg>
<arg choice="req">-l <replaceable class="parameter">label</replaceable></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
<arg><option>-k</option></arg>
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-p <replaceable class="parameter">protocol</replaceable></option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">type</replaceable></option></arg>
+ <arg><option>-U <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
<arg choice="req">name</arg>
</cmdsynopsis>
@@ -66,6 +71,11 @@
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</para>
+ <para>
+ The <option>name</option> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </para>
</refsect1>
<refsect1>
@@ -77,8 +87,8 @@
<listitem>
<para>
Selects the cryptographic algorithm. The value of
- <option>algorithm</option> must be one of RSAMD5 (RSA)
- or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ <option>algorithm</option> must be one of RSAMD5 (RSA),
+ RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
These values are case insensitive.
</para>
<para>
@@ -110,8 +120,22 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C</term>
+ <listitem>
+ <para>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <command>dnssec-keyfromlabel</command>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <option>-C</option> option suppresses them.
</para>
</listitem>
</varlistentry>
@@ -131,7 +155,7 @@
<listitem>
<para>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
</para>
</listitem>
</varlistentry>
@@ -141,7 +165,7 @@
<listitem>
<para>
Prints a short summary of the options and arguments to
- <command>dnssec-keygen</command>.
+ <command>dnssec-keyfromlabel</command>.
</para>
</listitem>
</varlistentry>
@@ -168,7 +192,7 @@
<term>-p <replaceable class="parameter">protocol</replaceable></term>
<listitem>
<para>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -201,6 +225,80 @@
</refsect1>
<refsect1>
+ <title>TIMING OPTIONS</title>
+
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included and the zone and used to sign
+ it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-U <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be unpublished. After that
+ date, the key will no longer be included in the zone, but it
+ may remain in the key repository.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key can be removed from the key repository.
+ NOTE: Keys are not currently deleted automatically; this field
+ is included for informational purposes and for future
+ development.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
<title>GENERATED KEY FILES</title>
<para>
When <command>dnssec-keyfromlabel</command> completes
@@ -216,8 +314,7 @@
</listitem>
<listitem>
<para><filename>aaa</filename> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</para>
</listitem>
<listitem>
@@ -231,8 +328,7 @@
on the printed string. <filename>Knnnn.+aaa+iiiii.key</filename>
contains the public key, and
<filename>Knnnn.+aaa+iiiii.private</filename> contains the
- private
- key.
+ private key.
</para>
<para>
The <filename>.key</filename> file contains a DNS KEY record
@@ -241,8 +337,8 @@
statement).
</para>
<para>
- The <filename>.private</filename> file contains algorithm
- specific
+ The <filename>.private</filename> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</para>
diff --git a/bin/dnssec/dnssec-keyfromlabel.html b/bin/dnssec/dnssec-keyfromlabel.html
index c081c2e0..2764a5a1 100644
--- a/bin/dnssec/dnssec-keyfromlabel.html
+++ b/bin/dnssec/dnssec-keyfromlabel.html
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.html,v 1.8 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.html,v 1.9 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -28,25 +28,30 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-U <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543425"></a><h2>DESCRIPTION</h2>
+<a name="id2543467"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543436"></a><h2>OPTIONS</h2>
+<a name="id2543485"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5 (RSA)
- or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5 (RSA),
+ RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
These values are case insensitive.
</p>
<p>
@@ -69,8 +74,17 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keyfromlabel</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
@@ -80,12 +94,12 @@
<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
<dd><p>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
</p></dd>
<dt><span class="term">-h</span></dt>
<dd><p>
Prints a short summary of the options and arguments to
- <span><strong class="command">dnssec-keygen</strong></span>.
+ <span><strong class="command">dnssec-keyfromlabel</strong></span>.
</p></dd>
<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
@@ -97,7 +111,7 @@
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -116,7 +130,54 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543648"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2543717"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included and the zone and used to sign
+ it.
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-U <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be unpublished. After that
+ date, the key will no longer be included in the zone, but it
+ may remain in the key repository.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key can be removed from the key repository.
+ NOTE: Keys are not currently deleted automatically; this field
+ is included for informational purposes and for future
+ development.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543815"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -128,8 +189,7 @@
<li><p><code class="filename">nnnn</code> is the key name.
</p></li>
<li><p><code class="filename">aaa</code> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</p></li>
<li><p><code class="filename">iiiii</code> is the key identifier (or
footprint).
@@ -140,8 +200,7 @@
on the printed string. <code class="filename">Knnnn.+aaa+iiiii.key</code>
contains the public key, and
<code class="filename">Knnnn.+aaa+iiiii.private</code> contains the
- private
- key.
+ private key.
</p>
<p>
The <code class="filename">.key</code> file contains a DNS KEY record
@@ -150,14 +209,14 @@
statement).
</p>
<p>
- The <code class="filename">.private</code> file contains algorithm
- specific
+ The <code class="filename">.private</code> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543720"></a><h2>SEE ALSO</h2>
+<a name="id2544024"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -167,7 +226,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543760"></a><h2>AUTHOR</h2>
+<a name="id2544064"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-keygen.8 b/bin/dnssec/dnssec-keygen.8
index 4882e78c..f171a1b8 100644
--- a/bin/dnssec/dnssec-keygen.8
+++ b/bin/dnssec/dnssec-keygen.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keygen.8,v 1.45 2009/07/19 04:27:55 tbox Exp $
+.\" $Id: dnssec-keygen.8,v 1.47 2009/09/03 01:14:41 tbox Exp $
.\"
.hy 0
.ad l
@@ -38,6 +38,10 @@ dnssec\-keygen \- DNSSEC key generation tool
.PP
\fBdnssec\-keygen\fR
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930.
+.PP
+The
+\fBname\fR
+of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated.
.SH "OPTIONS"
.PP
\-a \fIalgorithm\fR
@@ -165,7 +169,7 @@ Sets the debugging level.
.RE
.SH "TIMING OPTIONS"
.PP
-Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. If such an offset is followed by one of the characters 'y', 'm', 'w', 'd', or 'h', then the offset is computed in years, months, weeks, days, or hours, respectively; otherwise it is computed in seconds.
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
.PP
\-P \fIdate/offset\fR
.RS 4
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c
index d2188478..c5e696ec 100644
--- a/bin/dnssec/dnssec-keygen.c
+++ b/bin/dnssec/dnssec-keygen.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keygen.c,v 1.89 2009/07/19 23:47:55 tbox Exp $ */
+/* $Id: dnssec-keygen.c,v 1.94 2009/09/07 12:54:59 fdupont Exp $ */
/*! \file */
@@ -174,6 +174,12 @@ main(int argc, char **argv) {
isc_stdtime_t publish = 0, activate = 0, revoke = 0;
isc_stdtime_t unpublish = 0, delete = 0;
isc_stdtime_t now;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setunpub = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetunpub = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
if (argc == 1)
usage();
@@ -305,24 +311,64 @@ main(int argc, char **argv) {
/* already the default */
break;
case 'P':
- publish = strtotime(isc_commandline_argument,
- now, now);
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
break;
case 'A':
- activate = strtotime(isc_commandline_argument,
- now, now);
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
break;
case 'R':
- revoke = strtotime(isc_commandline_argument,
- now, now);
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
break;
case 'U':
- unpublish = strtotime(isc_commandline_argument,
- now, now);
+ if (setunpub || unsetunpub)
+ fatal("-U specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setunpub = ISC_TRUE;
+ unpublish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetunpub = ISC_TRUE;
+ }
break;
case 'D':
- delete = strtotime(isc_commandline_argument,
- now, now);
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
break;
case 'F':
/* Reserved for FIPS mode */
@@ -567,7 +613,7 @@ main(int argc, char **argv) {
isc_buffer_init(&buf, argv[isc_commandline_index],
strlen(argv[isc_commandline_index]));
isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
- ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
if (ret != ISC_R_SUCCESS)
fatal("invalid key name %s: %s", argv[isc_commandline_index],
isc_result_totext(ret));
@@ -618,29 +664,48 @@ main(int argc, char **argv) {
dst_key_setbits(key, dbits);
/*
- * Set key timing metadata
+ * Set key timing metadata (unless using -C)
*/
if (!oldstyle) {
dst_key_settime(key, DST_TIME_CREATED, now);
- dst_key_settime(key, DST_TIME_PUBLISH, publish);
- dst_key_settime(key, DST_TIME_ACTIVATE, activate);
- dst_key_settime(key, DST_TIME_REVOKE, revoke);
- dst_key_settime(key, DST_TIME_REMOVE, unpublish);
- dst_key_settime(key, DST_TIME_DELETE, delete);
- } else if (publish != 0 || activate != 0 || revoke != 0 ||
- unpublish != 0 || delete != 0) {
- fatal("cannot use -C together with "
- "-P, -A, -R, -U, or -D options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH,
+ publish);
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE,
+ activate);
+ if (setrev)
+ dst_key_settime(key, DST_TIME_REVOKE,
+ revoke);
+ if (setunpub)
+ dst_key_settime(key, DST_TIME_UNPUBLISH,
+ unpublish);
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE,
+ delete);
+ } else {
+ if (setpub || setact || setrev || setunpub ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetunpub || unsetdel)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -U, or -D options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
}
/*
* Try to read a key with the same name, alg and id from disk.
- * If there is one we must continue generating a new one
- * unless we were asked to generate a null key, in which
+ * If there is one we must continue generating a different
+ * key unless we were asked to generate a null key, in which
* case we return failure.
*/
ret = dst_key_fromfile(name, dst_key_id(key), alg,
- DST_TYPE_PRIVATE, NULL, mctx, &oldkey);
+ DST_TYPE_PRIVATE, directory,
+ mctx, &oldkey);
/* do not overwrite an existing key */
if (ret == ISC_R_SUCCESS) {
dst_key_free(&oldkey);
@@ -651,7 +716,8 @@ main(int argc, char **argv) {
if (conflict == ISC_TRUE) {
if (verbose > 0) {
isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, NULL, &buf);
+ ret = dst_key_buildfilename(key, 0, directory,
+ &buf);
fprintf(stderr,
"%s: %s already exists, "
"generating a new key\n",
diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook
index 5ba3862e..2ff764ac 100644
--- a/bin/dnssec/dnssec-keygen.docbook
+++ b/bin/dnssec/dnssec-keygen.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.docbook,v 1.25 2009/07/19 04:18:04 each Exp $ -->
+<!-- $Id: dnssec-keygen.docbook,v 1.27 2009/09/02 06:29:00 each Exp $ -->
<refentry id="man.dnssec-keygen">
<refentryinfo>
<date>June 30, 2000</date>
@@ -91,6 +91,11 @@
TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
(Transaction Key) as defined in RFC 2930.
</para>
+ <para>
+ The <option>name</option> of the key is specified on the command
+ line. For DNSSEC keys, this must match the name of the zone for
+ which the key is being generated.
+ </para>
</refsect1>
<refsect1>
@@ -345,10 +350,12 @@
<para>
Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
If the argument begins with a '+' or '-', it is interpreted as
- an offset from the present time. If such an offset is followed
- by one of the characters 'y', 'm', 'w', 'd', or 'h', then the
- offset is computed in years, months, weeks, days, or hours,
- respectively; otherwise it is computed in seconds.
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
</para>
<variablelist>
diff --git a/bin/dnssec/dnssec-keygen.html b/bin/dnssec/dnssec-keygen.html
index 8aa2981f..518f71bc 100644
--- a/bin/dnssec/dnssec-keygen.html
+++ b/bin/dnssec/dnssec-keygen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.html,v 1.37 2009/07/19 04:27:55 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.html,v 1.39 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -39,9 +39,14 @@
TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
(Transaction Key) as defined in RFC 2930.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. For DNSSEC keys, this must match the name of the zone for
+ which the key is being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543553"></a><h2>OPTIONS</h2>
+<a name="id2543559"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
@@ -203,14 +208,16 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544052"></a><h2>TIMING OPTIONS</h2>
+<a name="id2544058"></a><h2>TIMING OPTIONS</h2>
<p>
Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
If the argument begins with a '+' or '-', it is interpreted as
- an offset from the present time. If such an offset is followed
- by one of the characters 'y', 'm', 'w', 'd', or 'h', then the
- offset is computed in years, months, weeks, days, or hours,
- respectively; otherwise it is computed in seconds.
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
</p>
<div class="variablelist"><dl>
<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
@@ -248,7 +255,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544150"></a><h2>GENERATED KEYS</h2>
+<a name="id2544156"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -294,7 +301,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544232"></a><h2>EXAMPLE</h2>
+<a name="id2543078"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -315,7 +322,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544276"></a><h2>SEE ALSO</h2>
+<a name="id2543122"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
@@ -324,7 +331,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544307"></a><h2>AUTHOR</h2>
+<a name="id2543153"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-revoke.c b/bin/dnssec/dnssec-revoke.c
index 613ceec4..4a86d74f 100644
--- a/bin/dnssec/dnssec-revoke.c
+++ b/bin/dnssec/dnssec-revoke.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-revoke.c,v 1.6 2009/07/19 05:26:05 each Exp $ */
+/* $Id: dnssec-revoke.c,v 1.11 2009/09/04 16:57:22 each Exp $ */
/*! \file */
@@ -27,6 +27,7 @@
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/entropy.h>
+#include <isc/file.h>
#include <isc/hash.h>
#include <isc/mem.h>
#include <isc/print.h>
@@ -66,7 +67,7 @@ usage(void) {
int
main(int argc, char **argv) {
isc_result_t result;
- char *filename = NULL, *dir= NULL;
+ char *filename = NULL, *dir = NULL;
char newname[1024], oldname[1024];
char keystr[KEY_FORMATSIZE];
char *endp;
@@ -95,7 +96,15 @@ main(int argc, char **argv) {
force = ISC_TRUE;
break;
case 'K':
- dir = isc_commandline_argument;
+ /*
+ * We don't have to copy it here, but do it to
+ * simplify cleanup later
+ */
+ dir = isc_mem_strdup(mctx, isc_commandline_argument);
+ if (dir == NULL) {
+ fatal("Failed to allocate memory for "
+ "directory");
+ }
break;
case 'r':
remove = ISC_TRUE;
@@ -126,30 +135,11 @@ main(int argc, char **argv) {
if (argc > isc_commandline_index + 1)
fatal("Extraneous arguments");
- if (dir == NULL) {
- char *slash;
-#ifdef _WIN32
- char *backslash;
-#endif
-
- dir = strdup(argv[isc_commandline_index]);
- filename = dir;
-
- /* Figure out the directory name from the key name */
- slash = strrchr(dir, '/');
-#ifdef _WIN32
- backslash = strrchr(dir, '\\');
- if ((slash != NULL && backslash != NULL && backslash > slash) ||
- (slash == NULL && backslash != NULL))
- slash = backslash;
-#endif
- if (slash != NULL) {
- *slash++ = '\0';
- filename = slash;
- } else {
- free(dir);
- dir = strdup(".");
- }
+ if (dir != NULL) {
+ filename = argv[isc_commandline_index];
+ } else {
+ isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &dir, &filename);
}
if (ectx == NULL)
@@ -179,6 +169,11 @@ main(int argc, char **argv) {
flags = dst_key_flags(key);
if ((flags & DNS_KEYFLAG_REVOKE) == 0) {
+ isc_stdtime_t now;
+
+ isc_stdtime_get(&now);
+ dst_key_settime(key, DST_TIME_REVOKE, now);
+
dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE);
isc_buffer_init(&buf, newname, sizeof(newname));
@@ -232,6 +227,7 @@ cleanup:
cleanup_entropy(&ectx);
if (verbose > 10)
isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, dir);
isc_mem_destroy(&mctx);
return (0);
diff --git a/bin/dnssec/dnssec-settime.8 b/bin/dnssec/dnssec-settime.8
index c3f6e982..42a21d11 100644
--- a/bin/dnssec/dnssec-settime.8
+++ b/bin/dnssec/dnssec-settime.8
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-settime.8,v 1.4 2009/07/19 23:47:55 tbox Exp $
+.\" $Id: dnssec-settime.8,v 1.5 2009/09/03 01:14:41 tbox Exp $
.\"
.hy 0
.ad l
@@ -78,7 +78,7 @@ Sets the debugging level.
.RE
.SH "TIMING OPTIONS"
.PP
-Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. If such an offset is followed by one of the characters 'y', 'm', 'w', 'd', or 'h', then the offset is computed in years, months, weeks, days, or hours, respectively; otherwise it is computed in seconds.
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none'.
.PP
\-P \fIdate/offset\fR
.RS 4
@@ -104,6 +104,35 @@ Sets the date on which the key is to be unpublished. After that date, the key wi
.RS 4
Sets the date on which the key is to be deleted. After that date, the key can be removed from the key repository. NOTE: Keys are not currently deleted automatically; this field is included for informational purposes and for future development.
.RE
+.SH "PRINTING OPTIONS"
+.PP
+\fBdnssec\-settime\fR
+can also be used to print the timing metadata associated with a key.
+.PP
+\-u
+.RS 4
+Print times in UNIX epoch format.
+.RE
+.PP
+\-p \fIC/P/A/R/U/D/all\fR
+.RS 4
+Print a specific metadata value or set of metadata values. The
+\fB\-p\fR
+option may be followed by one or more of the following letters to indicate which value or values to print:
+\fBC\fR
+for the creation date,
+\fBP\fR
+for the publication date,
+\fBA\fR
+for the activation date,
+\fBR\fR
+for the revokation date,
+\fBU\fR
+for the unpublication date, or
+\fBD\fR
+for the deletion date. To print all of the metadata, use
+\fB\-p all\fR.
+.RE
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
diff --git a/bin/dnssec/dnssec-settime.c b/bin/dnssec/dnssec-settime.c
index cc696d45..10e972d1 100644
--- a/bin/dnssec/dnssec-settime.c
+++ b/bin/dnssec/dnssec-settime.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-settime.c,v 1.6 2009/07/21 02:57:39 jinmei Exp $ */
+/* $Id: dnssec-settime.c,v 1.11 2009/09/04 16:57:22 each Exp $ */
/*! \file */
@@ -29,6 +29,7 @@
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/entropy.h>
+#include <isc/file.h>
#include <isc/hash.h>
#include <isc/mem.h>
#include <isc/print.h>
@@ -52,18 +53,29 @@ usage(void) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, " %s [options] keyfile\n\n", program);
fprintf(stderr, "Version: %s\n", VERSION);
- fprintf(stderr, "Options:\n");
+ fprintf(stderr, "General options:\n");
fprintf(stderr, " -f: force update of old-style "
"keys\n");
fprintf(stderr, " -K directory: set key file location\n");
- fprintf(stderr, " -h: help\n");
- fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, " -h: help\n");
fprintf(stderr, "Timing options:\n");
- fprintf(stderr, " -P date/[+-]offset: set key publication date\n");
- fprintf(stderr, " -A date/[+-]offset: set key activation date\n");
- fprintf(stderr, " -R date/[+-]offset: set key revocation date\n");
- fprintf(stderr, " -U date/[+-]offset: set key unpublication date\n");
- fprintf(stderr, " -D date/[+-]offset: set key deletion date\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set/unset key "
+ "publication date\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set key "
+ "activation date\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set key "
+ "revocation date\n");
+ fprintf(stderr, " -U date/[+-]offset/none: set key "
+ "unpublication date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set key "
+ "deletion date\n");
+ fprintf(stderr, "Printing options:\n");
+ fprintf(stderr, " -p C/P/A/R/U/D/all: print a particular time "
+ "value or values "
+ "[default: all]\n");
+ fprintf(stderr, " -u: print times in unix epoch "
+ "format\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K<name>+<alg>+<new id>.key, "
"K<name>+<alg>+<new id>.private\n");
@@ -72,19 +84,26 @@ usage(void) {
}
static void
-printtime(dst_key_t *key, int type, const char *tag, FILE *stream) {
+printtime(dst_key_t *key, int type, const char *tag, isc_boolean_t epoch,
+ FILE *stream)
+{
isc_result_t result;
- time_t when;
- const char *output;
+ const char *output = NULL;
+ isc_stdtime_t when;
- result = dst_key_gettime(key, type, (isc_stdtime_t *) &when);
- if (result == ISC_R_NOTFOUND || when == 0) {
- fprintf(stream, "%s: NOT SET\n", tag);
- return;
- }
+ if (tag != NULL)
+ fprintf(stream, "%s: ", tag);
- output = ctime(&when);
- fprintf(stream, "%s: %s", tag, output);
+ result = dst_key_gettime(key, type, &when);
+ if (result == ISC_R_NOTFOUND) {
+ fprintf(stream, "UNSET\n");
+ } else if (epoch) {
+ fprintf(stream, "%d\n", (int) when);
+ } else {
+ time_t time = when;
+ output = ctime(&time);
+ fprintf(stream, "%s", output);
+ }
}
int
@@ -93,18 +112,26 @@ main(int argc, char **argv) {
char *filename = NULL, *directory = NULL;
char newname[1024];
char keystr[KEY_FORMATSIZE];
- char *endp;
+ char *endp, *p;
int ch;
isc_entropy_t *ectx = NULL;
dst_key_t *key = NULL;
isc_buffer_t buf;
- isc_stdtime_t now, when;
+ int major, minor;
+ isc_stdtime_t now;
isc_stdtime_t pub = 0, act = 0, rev = 0, unpub = 0, del = 0;
isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
isc_boolean_t setrev = ISC_FALSE, setunpub = ISC_FALSE;
isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetunpub = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t printcreate = ISC_FALSE, printpub = ISC_FALSE;
+ isc_boolean_t printact = ISC_FALSE, printrev = ISC_FALSE;
+ isc_boolean_t printunpub = ISC_FALSE, printdel = ISC_FALSE;
isc_boolean_t forceupdate = ISC_FALSE;
- isc_boolean_t print = ISC_TRUE;
+ isc_boolean_t epoch = ISC_FALSE;
+ isc_boolean_t changed = ISC_FALSE;
if (argc == 1)
usage();
@@ -120,11 +147,54 @@ main(int argc, char **argv) {
isc_stdtime_get(&now);
while ((ch = isc_commandline_parse(argc, argv,
- "fK:hv:P:A:R:U:D:")) != -1) {
+ "fK:uhp:v:P:A:R:U:D:")) != -1) {
switch (ch) {
case 'f':
forceupdate = ISC_TRUE;
break;
+ case 'p':
+ p = isc_commandline_argument;
+ if (!strcasecmp(p, "all")) {
+ printcreate = ISC_TRUE;
+ printpub = ISC_TRUE;
+ printact = ISC_TRUE;
+ printrev = ISC_TRUE;
+ printunpub = ISC_TRUE;
+ printdel = ISC_TRUE;
+ break;
+ }
+
+ do {
+ switch (*p++) {
+ case 'C':
+ printcreate = ISC_TRUE;
+ break;
+ case 'P':
+ printpub = ISC_TRUE;
+ break;
+ case 'A':
+ printact = ISC_TRUE;
+ break;
+ case 'R':
+ printrev = ISC_TRUE;
+ break;
+ case 'U':
+ printunpub = ISC_TRUE;
+ break;
+ case 'D':
+ printdel = ISC_TRUE;
+ break;
+ case ' ':
+ break;
+ default:
+ usage();
+ break;
+ }
+ } while (*p != '\0');
+ break;
+ case 'u':
+ epoch = ISC_TRUE;
+ break;
case 'K':
/*
* We don't have to copy it here, but do it to
@@ -133,7 +203,7 @@ main(int argc, char **argv) {
directory = isc_mem_strdup(mctx,
isc_commandline_argument);
if (directory == NULL) {
- fatal("Failed to memory allocation for "
+ fatal("Failed to allocate memory for "
"directory");
}
break;
@@ -143,29 +213,69 @@ main(int argc, char **argv) {
fatal("-v must be followed by a number");
break;
case 'P':
- print = ISC_FALSE;
- setpub = ISC_TRUE;
- pub = strtotime(isc_commandline_argument, now, now);
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetpub = ISC_TRUE;
+ } else {
+ setpub = ISC_TRUE;
+ pub = strtotime(isc_commandline_argument,
+ now, now);
+ }
break;
case 'A':
- print = ISC_FALSE;
- setact = ISC_TRUE;
- act = strtotime(isc_commandline_argument, now, now);
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetact = ISC_TRUE;
+ } else {
+ setact = ISC_TRUE;
+ act = strtotime(isc_commandline_argument,
+ now, now);
+ }
break;
case 'R':
- print = ISC_FALSE;
- setrev = ISC_TRUE;
- rev = strtotime(isc_commandline_argument, now, now);
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetrev = ISC_TRUE;
+ } else {
+ setrev = ISC_TRUE;
+ rev = strtotime(isc_commandline_argument,
+ now, now);
+ }
break;
case 'U':
- print = ISC_FALSE;
- setunpub = ISC_TRUE;
- unpub = strtotime(isc_commandline_argument, now, now);
+ if (setunpub || unsetunpub)
+ fatal("-U specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetunpub = ISC_TRUE;
+ } else {
+ setunpub = ISC_TRUE;
+ unpub = strtotime(isc_commandline_argument,
+ now, now);
+ }
break;
case 'D':
- print = ISC_FALSE;
- setdel = ISC_TRUE;
- del = strtotime(isc_commandline_argument, now, now);
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetdel = ISC_TRUE;
+ } else {
+ setdel = ISC_TRUE;
+ del = strtotime(isc_commandline_argument,
+ now, now);
+ }
break;
case '?':
if (isc_commandline_option != '?')
@@ -188,39 +298,12 @@ main(int argc, char **argv) {
if (argc > isc_commandline_index + 1)
fatal("Extraneous arguments");
- if (directory == NULL) {
- char *slash;
-#ifdef _WIN32
- char *backslash;
-#endif
-
- directory = isc_mem_strdup(mctx, argv[isc_commandline_index]);
- if (directory == NULL)
- fatal("Failed to memory allocation for directory");
- filename = directory;
-
- /* Figure out the directory name from the key name */
- slash = strrchr(directory, '/');
-#ifdef _WIN32
- backslash = strrchr(directory, '\\');
- if ((slash != NULL && backslash != NULL && backslash > slash) ||
- (slash == NULL && backslash != NULL))
- slash = backslash;
-#endif
- if (slash != NULL) {
- *slash++ = '\0';
- filename = slash;
- } else {
- isc_mem_free(mctx, directory);
- /* strdup could be skipped (see above) */
- directory = isc_mem_strdup(mctx, ".");
- if (directory == NULL) {
- fatal("Failed to memory allocation "
- "for directory");
- }
- }
- } else
+ if (directory != NULL) {
filename = argv[isc_commandline_index];
+ } else {
+ isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &directory, &filename);
+ }
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
@@ -246,41 +329,84 @@ main(int argc, char **argv) {
key_format(key, keystr, sizeof(keystr));
/* Is this an old-style key? */
- result = dst_key_gettime(key, DST_TIME_CREATED, &when);
- if (result == ISC_R_NOTFOUND) {
- if (forceupdate)
+ dst_key_getprivateformat(key, &major, &minor);
+ if (major <= 1 && minor <= 2) {
+ if (forceupdate) {
+ /*
+ * Updating to new-style key: set
+ * Private-key-format to 1.3
+ */
+ dst_key_setprivateformat(key, 1, 3);
dst_key_settime(key, DST_TIME_CREATED, now);
- else
+ } else
fatal("Incompatible key %s, "
- "use -f force update.", keystr);
+ "use -f to force update.", keystr);
}
if (verbose > 2)
fprintf(stderr, "%s: %s\n", program, keystr);
- if (print) {
- printtime(key, DST_TIME_CREATED, "Created", stdout);
- printtime(key, DST_TIME_PUBLISH, "Publish", stdout);
- printtime(key, DST_TIME_ACTIVATE, "Activate", stdout);
- printtime(key, DST_TIME_REVOKE, "Revoke", stdout);
- printtime(key, DST_TIME_REMOVE, "Remove", stdout);
- printtime(key, DST_TIME_DELETE, "Delete", stdout);
- } else {
- if (setpub)
- dst_key_settime(key, DST_TIME_PUBLISH, pub);
+ /*
+ * Set time values.
+ */
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, pub);
+ else if (unsetpub)
+ dst_key_unsettime(key, DST_TIME_PUBLISH);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, act);
+ else if (unsetact)
+ dst_key_unsettime(key, DST_TIME_ACTIVATE);
+
+ if (setrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0 && rev > now)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; changing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ dst_key_settime(key, DST_TIME_REVOKE, rev);
+ } else if (unsetrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; removing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ dst_key_unsettime(key, DST_TIME_REVOKE);
+ }
+
+ if (setunpub)
+ dst_key_settime(key, DST_TIME_UNPUBLISH, unpub);
+ else if (unsetunpub)
+ dst_key_unsettime(key, DST_TIME_UNPUBLISH);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, del);
+ else if (unsetdel)
+ dst_key_unsettime(key, DST_TIME_DELETE);
+
+ /*
+ * Print out time values, if -p was used.
+ */
+ if (printcreate)
+ printtime(key, DST_TIME_CREATED, "Created", epoch, stdout);
+
+ if (printpub)
+ printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout);
- if (setact)
- dst_key_settime(key, DST_TIME_ACTIVATE, act);
+ if (printact)
+ printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout);
- if (setrev)
- dst_key_settime(key, DST_TIME_REVOKE, rev);
+ if (printrev)
+ printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout);
- if (setunpub)
- dst_key_settime(key, DST_TIME_REMOVE, unpub);
+ if (printunpub)
+ printtime(key, DST_TIME_UNPUBLISH, "Unpublish", epoch, stdout);
- if (setdel)
- dst_key_settime(key, DST_TIME_DELETE, del);
+ if (printdel)
+ printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout);
+ if (changed) {
isc_buffer_init(&buf, newname, sizeof(newname));
result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory,
&buf);
diff --git a/bin/dnssec/dnssec-settime.docbook b/bin/dnssec/dnssec-settime.docbook
index 7e0142e8..224df4d3 100644
--- a/bin/dnssec/dnssec-settime.docbook
+++ b/bin/dnssec/dnssec-settime.docbook
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-settime.docbook,v 1.2 2009/07/19 04:18:04 each Exp $ -->
+<!-- $Id: dnssec-settime.docbook,v 1.3 2009/09/02 06:29:00 each Exp $ -->
<refentry id="man.dnssec-settime">
<refentryinfo>
<date>July 15, 2009</date>
@@ -135,10 +135,12 @@
<para>
Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
If the argument begins with a '+' or '-', it is interpreted as
- an offset from the present time. If such an offset is followed
- by one of the characters 'y', 'm', 'w', 'd', or 'h', then the
- offset is computed in years, months, weeks, days, or hours,
- respectively; otherwise it is computed in seconds.
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
</para>
<variablelist>
@@ -203,6 +205,44 @@
</refsect1>
<refsect1>
+ <title>PRINTING OPTIONS</title>
+ <para>
+ <command>dnssec-settime</command> can also be used to print the
+ timing metadata associated with a key.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-u</term>
+ <listitem>
+ <para>
+ Print times in UNIX epoch format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p <replaceable class="parameter">C/P/A/R/U/D/all</replaceable></term>
+ <listitem>
+ <para>
+ Print a specific metadata value or set of metadata values.
+ The <option>-p</option> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <option>C</option> for the creation date,
+ <option>P</option> for the publication date,
+ <option>A</option> for the activation date,
+ <option>R</option> for the revokation date,
+ <option>U</option> for the unpublication date, or
+ <option>D</option> for the deletion date.
+ To print all of the metadata, use <option>-p all</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
<title>SEE ALSO</title>
<para><citerefentry>
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
diff --git a/bin/dnssec/dnssec-settime.html b/bin/dnssec/dnssec-settime.html
index 06dda04c..aa711d3d 100644
--- a/bin/dnssec/dnssec-settime.html
+++ b/bin/dnssec/dnssec-settime.html
@@ -14,7 +14,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-settime.html,v 1.4 2009/07/19 23:47:55 tbox Exp $ -->
+<!-- $Id: dnssec-settime.html,v 1.5 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -87,10 +87,12 @@
<p>
Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
If the argument begins with a '+' or '-', it is interpreted as
- an offset from the present time. If such an offset is followed
- by one of the characters 'y', 'm', 'w', 'd', or 'h', then the
- offset is computed in years, months, weeks, days, or hours,
- respectively; otherwise it is computed in seconds.
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
</p>
<div class="variablelist"><dl>
<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
@@ -128,7 +130,33 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543628"></a><h2>SEE ALSO</h2>
+<a name="id2543628"></a><h2>PRINTING OPTIONS</h2>
+<p>
+ <span><strong class="command">dnssec-settime</strong></span> can also be used to print the
+ timing metadata associated with a key.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Print times in UNIX epoch format.
+ </p></dd>
+<dt><span class="term">-p <em class="replaceable"><code>C/P/A/R/U/D/all</code></em></span></dt>
+<dd><p>
+ Print a specific metadata value or set of metadata values.
+ The <code class="option">-p</code> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <code class="option">C</code> for the creation date,
+ <code class="option">P</code> for the publication date,
+ <code class="option">A</code> for the activation date,
+ <code class="option">R</code> for the revokation date,
+ <code class="option">U</code> for the unpublication date, or
+ <code class="option">D</code> for the deletion date.
+ To print all of the metadata, use <code class="option">-p all</code>.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543706"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -136,7 +164,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543661"></a><h2>AUTHOR</h2>
+<a name="id2543739"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-signzone.8 b/bin/dnssec/dnssec-signzone.8
index 6dbfaa4a..f14bd18b 100644
--- a/bin/dnssec/dnssec-signzone.8
+++ b/bin/dnssec/dnssec-signzone.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-signzone.8,v 1.51 2009/07/19 04:27:55 tbox Exp $
+.\" $Id: dnssec-signzone.8,v 1.52 2009/09/03 01:14:41 tbox Exp $
.\"
.hy 0
.ad l
@@ -52,6 +52,16 @@ Verify all generated signatures.
Specifies the DNS class of the zone.
.RE
.PP
+\-C
+.RS 4
+Compatibility mode: Generate a
+\fIkeyset\-\fR\fI\fIzonename\fR\fR
+file in addition to
+\fIdsset\-\fR\fI\fIzonename\fR\fR
+when signing a zone, for use by older versions of
+\fBdnssec\-signzone\fR.
+.RE
+.PP
\-d \fIdirectory\fR
.RS 4
Look for
@@ -99,6 +109,9 @@ Specify the date and time when the generated RRSIG records expire. As with
\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no
\fBend\-time\fR
is specified, 30 days from the start time is used as a default.
+\fBend\-time\fR
+must be later than
+\fBstart\-time\fR.
.RE
.PP
\-f \fIoutput\-file\fR
@@ -247,7 +260,8 @@ If either of the key's unpublication or deletion dates are set and in the past,
.PP
\-T \fIttl\fR
.RS 4
-Specifies the TTL of new DNSKEY records imported to the zone from the key repository. Only useful with the \-S option.
+Specifies the TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the minimum TTL value from the zone's SOA record. This option is ignored when signing without
+\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them.
.RE
.PP
\-t
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
index 87eb60b4..a9e35642 100644
--- a/bin/dnssec/dnssec-signzone.c
+++ b/bin/dnssec/dnssec-signzone.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.225 2009/07/21 03:27:38 marka Exp $ */
+/* $Id: dnssec-signzone.c,v 1.229 2009/09/02 06:29:00 each Exp $ */
/*! \file */
@@ -130,6 +130,7 @@ static isc_boolean_t printstats = ISC_FALSE;
static isc_mem_t *mctx = NULL;
static isc_entropy_t *ectx = NULL;
static dns_ttl_t zone_soa_min_ttl;
+static dns_ttl_t soa_ttl;
static FILE *fp;
static char *tempfile = NULL;
static const dns_master_style_t *masterstyle;
@@ -160,7 +161,8 @@ static unsigned int serialformat = SOA_SERIAL_KEEP;
static unsigned int hash_length = 0;
static isc_boolean_t unknownalg = ISC_FALSE;
static isc_boolean_t disable_zone_check = ISC_FALSE;
-static int keyttl = 3600;
+static isc_boolean_t set_keyttl = ISC_FALSE;
+static dns_ttl_t keyttl;
#define INCSTAT(counter) \
if (printstats) { \
@@ -826,6 +828,12 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
return (ISC_R_NOTFOUND);
}
+ result = dns_db_findnode(db, name, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detach(&db);
+ return (result);
+ }
+
dns_rdataset_init(&keyset);
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
&keyset, NULL);
@@ -1122,17 +1130,15 @@ active_node(dns_dbnode_t *node) {
}
/*%
- * Extracts the minimum TTL from the SOA.
+ * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
*/
-static dns_ttl_t
-soa_min_ttl(void) {
+static void
+get_soa_ttls(void) {
dns_rdataset_t soaset;
dns_fixedname_t fname;
dns_name_t *name;
isc_result_t result;
- dns_ttl_t ttl;
dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_soa_t soa;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -1146,11 +1152,9 @@ soa_min_ttl(void) {
result = dns_rdataset_first(&soaset);
check_result(result, "dns_rdataset_first");
dns_rdataset_current(&soaset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- check_result(result, "dns_rdata_tostruct");
- ttl = soa.minimum;
+ zone_soa_min_ttl = dns_soa_getminimum(&rdata);
+ soa_ttl = soaset.ttl;
dns_rdataset_disassociate(&soaset);
- return (ttl);
}
/*%
@@ -2480,7 +2484,7 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("failed converting name '%s' to dns format: %s",
origin, isc_result_totext(result));
@@ -2524,6 +2528,14 @@ loadzonekeys(dns_db_t *db) {
&rdataset, NULL);
if (result == ISC_R_SUCCESS) {
+ if (set_keyttl && keyttl != rdataset.ttl) {
+ fprintf(stderr, "User-specified TTL (%d) conflicts "
+ "with existing DNSKEY RRset TTL.\n",
+ keyttl);
+ fprintf(stderr, "Imported keys will use the RRSet "
+ "TTL (%d) instead.\n",
+ rdataset.ttl);
+ }
keyttl = rdataset.ttl;
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
@@ -2738,7 +2750,7 @@ build_final_keylist(dns_db_t *db, const char *directory, isc_mem_t *mctx) {
make_dnskey(key1->key, &dnskey);
alg_format(dst_key_alg(key1->key), alg, sizeof(alg));
- fprintf(stderr, "Fetching %s %d/%s from key %s.\n",
+ fprintf(stderr, "Fetching %s %d/%s from key %s\n",
isksk(key1) ?
(iszsk(key1) ? "KSK/ZSK" : "KSK") :
"ZSK",
@@ -2747,6 +2759,19 @@ build_final_keylist(dns_db_t *db, const char *directory, isc_mem_t *mctx) {
"file" :
"repository");
+ if (key1->prepublish && keyttl > key1->prepublish) {
+ char keystr[KEY_FORMATSIZE];
+ key_format(key1->key, keystr, sizeof(keystr));
+ fatal("Key %s is scheduled to\n"
+ "become active in %d seconds. "
+ "This is less than the DNSKEY TTL\n"
+ "value of %d seconds. Reduce "
+ "the TTL, or change the activation\n"
+ "date of the key using "
+ "'dnssec-settime -A'.",
+ keystr, key1->prepublish, keyttl);
+ }
+
/* add key to the zone */
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
gorigin, keyttl,
@@ -3203,7 +3228,7 @@ main(int argc, char *argv[]) {
case 'd':
dsdir = isc_commandline_argument;
- if (strlen(dsdir) == 0)
+ if (strlen(dsdir) == 0U)
fatal("DS directory must be non-empty string");
break;
@@ -3268,8 +3293,8 @@ main(int argc, char *argv[]) {
dns_fixedname_init(&dlv_fixed);
dlv = dns_fixedname_name(&dlv_fixed);
- result = dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(dlv, &b, dns_rootname, 0,
+ NULL);
check_result(result, "dns_name_fromtext(dlv)");
break;
@@ -3318,9 +3343,8 @@ main(int argc, char *argv[]) {
case 'T':
endp = NULL;
- keyttl = strtol(isc_commandline_argument, &endp, 0);
- if (*endp != '\0')
- fatal("key TTL must be numeric");
+ set_keyttl = ISC_TRUE;
+ keyttl = strtottl(isc_commandline_argument);
break;
case 't':
@@ -3376,15 +3400,11 @@ main(int argc, char *argv[]) {
isc_stdtime_get(&now);
if (startstr != NULL) {
- if (startstr[0] == '-' || strncmp(startstr, "now-", 4) == 0)
- fatal("time value %s is invalid", startstr);
starttime = strtotime(startstr, now, now);
} else
starttime = now - 3600; /* Allow for some clock skew. */
if (endstr != NULL) {
- if (endstr[0] == '-' || strncmp(endstr, "now-", 4) == 0)
- fatal("time value %s is invalid", endstr);
endtime = strtotime(endstr, now, starttime);
} else
endtime = starttime + (30 * 24 * 60 * 60);
@@ -3465,7 +3485,10 @@ main(int argc, char *argv[]) {
loadzone(file, origin, rdclass, &gdb);
gorigin = dns_db_origin(gdb);
gclass = dns_db_class(gdb);
- zone_soa_min_ttl = soa_min_ttl();
+ get_soa_ttls();
+
+ if (!set_keyttl)
+ keyttl = soa_ttl;
if (IS_NSEC3) {
isc_boolean_t answer;
diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook
index d22fd6c0..d6e5bb79 100644
--- a/bin/dnssec/dnssec-signzone.docbook
+++ b/bin/dnssec/dnssec-signzone.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.35 2009/07/19 04:18:04 each Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.36 2009/09/02 06:29:00 each Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
<date>June 05, 2009</date>
@@ -125,6 +125,20 @@
</varlistentry>
<varlistentry>
+ <term>-C</term>
+ <listitem>
+ <para>
+ Compatibility mode: Generate a
+ <filename>keyset-<replaceable>zonename</replaceable></filename>
+ file in addition to
+ <filename>dsset-<replaceable>zonename</replaceable></filename>
+ when signing a zone, for use by older versions of
+ <command>dnssec-signzone</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-d <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
@@ -202,6 +216,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <option>end-time</option> is
specified, 30 days from the start time is used as a default.
+ <option>end-time</option> must be later than
+ <option>start-time</option>.
</para>
</listitem>
</varlistentry>
@@ -477,8 +493,15 @@
<term>-T <replaceable class="parameter">ttl</replaceable></term>
<listitem>
<para>
- Specifies the TTL of new DNSKEY records imported to the zone
- from the key repository. Only useful with the -S option.
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <option>-S</option>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
</para>
</listitem>
</varlistentry>
diff --git a/bin/dnssec/dnssec-signzone.html b/bin/dnssec/dnssec-signzone.html
index 35e934d6..c72b7026 100644
--- a/bin/dnssec/dnssec-signzone.html
+++ b/bin/dnssec/dnssec-signzone.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.html,v 1.37 2009/07/19 04:27:55 tbox Exp $ -->
+<!-- $Id: dnssec-signzone.html,v 1.38 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -53,6 +53,15 @@
<dd><p>
Specifies the DNS class of the zone.
</p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: Generate a
+ <code class="filename">keyset-<em class="replaceable"><code>zonename</code></em></code>
+ file in addition to
+ <code class="filename">dsset-<em class="replaceable"><code>zonename</code></em></code>
+ when signing a zone, for use by older versions of
+ <span><strong class="command">dnssec-signzone</strong></span>.
+ </p></dd>
<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
Look for <code class="filename">dsset-</code> or
@@ -99,6 +108,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <code class="option">end-time</code> is
specified, 30 days from the start time is used as a default.
+ <code class="option">end-time</code> must be later than
+ <code class="option">start-time</code>.
</p></dd>
<dt><span class="term">-f <em class="replaceable"><code>output-file</code></em></span></dt>
<dd><p>
@@ -279,8 +290,15 @@
</dd>
<dt><span class="term">-T <em class="replaceable"><code>ttl</code></em></span></dt>
<dd><p>
- Specifies the TTL of new DNSKEY records imported to the zone
- from the key repository. Only useful with the -S option.
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <code class="option">-S</code>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
</p></dd>
<dt><span class="term">-t</span></dt>
<dd><p>
@@ -326,7 +344,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544633"></a><h2>EXAMPLE</h2>
+<a name="id2544877"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
@@ -355,14 +373,14 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2544753"></a><h2>SEE ALSO</h2>
+<a name="id2545065"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 4033</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544914"></a><h2>AUTHOR</h2>
+<a name="id2545090"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c
index df58ad3d..62f3da33 100644
--- a/bin/dnssec/dnssectool.c
+++ b/bin/dnssec/dnssectool.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.c,v 1.49 2009/07/19 23:47:55 tbox Exp $ */
+/* $Id: dnssectool.c,v 1.53 2009/09/03 00:12:23 each Exp $ */
/*! \file */
@@ -266,12 +266,23 @@ cleanup_entropy(isc_entropy_t **ectx) {
}
static isc_stdtime_t
-time_units(isc_stdtime_t offset, char suffix, const char *str) {
- switch(suffix) {
+time_units(isc_stdtime_t offset, char *suffix, const char *str) {
+ switch (suffix[0]) {
case 'Y': case 'y':
return (offset * (365 * 24 * 3600));
case 'M': case 'm':
- return (offset * (30 * 24 * 3600));
+ switch (suffix[1]) {
+ case 'O': case 'o':
+ return (offset * (30 * 24 * 3600));
+ case 'I': case 'i':
+ return (offset * 60);
+ case '\0':
+ fatal("'%s' ambiguous: use 'mi' for minutes "
+ "or 'mo' for months", str);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ break;
case 'W': case 'w':
return (offset * (7 * 24 * 3600));
case 'D': case 'd':
@@ -286,6 +297,19 @@ time_units(isc_stdtime_t offset, char suffix, const char *str) {
return(0); /* silence compiler warning */
}
+dns_ttl_t
+strtottl(const char *str) {
+ const char *orig = str;
+ dns_ttl_t ttl;
+ char *endp;
+
+ ttl = strtol(str, &endp, 0);
+ if (ttl == 0 && endp == str)
+ fatal("TTL must be numeric");
+ ttl = time_units(ttl, endp, orig);
+ return (ttl);
+}
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
isc_int64_t val, offset;
@@ -293,7 +317,7 @@ strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
const char *orig = str;
char *endp;
- if (strlen(str) == 1 && (str[0] == '0' || str[0] == '-'))
+ if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
return ((isc_stdtime_t) 0);
if (strncmp(str, "now", 3) == 0) {
@@ -305,11 +329,11 @@ strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
return ((isc_stdtime_t) base);
else if (str[0] == '+') {
offset = strtol(str + 1, &endp, 0);
- offset = time_units(offset, *endp, orig);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
val = base + offset;
} else if (str[0] == '-') {
offset = strtol(str + 1, &endp, 0);
- offset = time_units(offset, *endp, orig);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
val = base - offset;
} else if (strlen(str) == 8U) {
char timestr[15];
diff --git a/bin/dnssec/dnssectool.h b/bin/dnssec/dnssectool.h
index ee476f4e..df714e70 100644
--- a/bin/dnssec/dnssectool.h
+++ b/bin/dnssec/dnssectool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.h,v 1.22 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: dnssectool.h,v 1.25 2009/09/04 02:31:29 marka Exp $ */
#ifndef DNSSECTOOL_H
#define DNSSECTOOL_H 1
@@ -45,7 +45,7 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size);
void
alg_format(const dns_secalg_t alg, char *cp, unsigned int size);
-#define ALG_FORMATSIZE 10
+#define ALG_FORMATSIZE 20
void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size);
@@ -67,6 +67,8 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx);
void
cleanup_entropy(isc_entropy_t **ectx);
+dns_ttl_t strtottl(const char *str);
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base);
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in
index 69438e2f..a5cbc1e4 100644
--- a/bin/named/Makefile.in
+++ b/bin/named/Makefile.in
@@ -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.104 2009/03/05 23:47:35 tbox Exp $
+# $Id: Makefile.in,v 1.106 2009/09/01 18:40:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -45,7 +45,7 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \
${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \
${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES}
-CDEFINES = @USE_DLZ@
+CDEFINES = -DBIND9 @USE_DLZ@
CWARNINGS =
@@ -53,6 +53,7 @@ DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
@@ -70,6 +71,10 @@ LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \
${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \
${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \
+ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \
+ ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@
+
SUBDIRS = unix
TARGETS = named@EXEEXT@ lwresd@EXEEXT@
@@ -86,10 +91,12 @@ OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \
UOBJS = unix/os.@O@
+SYMOBJS = symtbl.@O@
+
SRCS = builtin.c client.c config.c control.c \
controlconf.c interfacemgr.c \
listenlist.c log.c logconf.c main.c notify.c \
- query.c server.c sortlist.c statschannel.c \
+ query.c server.c sortlist.c statschannel.c symtbl.c symtbl-empty.c \
tkeyconf.c tsigconf.c update.c xfrout.c \
zoneconf.c \
lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \
@@ -122,8 +129,9 @@ config.@O@: config.c bind.keys.h
-c ${srcdir}/config.c
named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- ${OBJS} ${UOBJS} ${LIBS}
+ export MAKE_SYMTABLE="yes"; \
+ export BASEOBJS="${OBJS} ${UOBJS}"; \
+ ${FINALBUILDCMD}
lwresd@EXEEXT@: named@EXEEXT@
rm -f lwresd@EXEEXT@
diff --git a/bin/named/bind.keys.h b/bin/named/bind.keys.h
index 1b287a51..1c8a4aba 100644
--- a/bin/named/bind.keys.h
+++ b/bin/named/bind.keys.h
@@ -1,7 +1,17 @@
#define TRUSTED_KEYS "\
trusted-keys {\n\
- # NOTE: This key expires September 2009 \n\
- # Go to https://www.isc.org/solutions/dlv to download a replacement\n\
+ # NOTE: This key is current as of September 2009.\n\
+ # If it fails to initialize correctly, it may have expired;\n\
+ # see https://www.isc.org/solutions/dlv for a replacement.\n\
dlv.isc.org. 257 3 5 \"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh\";\n\
};\n\
"
+
+#define MANAGED_KEYS "\
+managed-keys {\n\
+ # NOTE: This key is current as of September 2009.\n\
+ # If it fails to initialize correctly, it may have expired;\n\
+ # see https://www.isc.org/solutions/dlv for a replacement.\n\
+ dlv.isc.org. initial-key 257 3 5 \"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh\";\n\
+};\n\
+"
diff --git a/bin/named/bindkeys.pl b/bin/named/bindkeys.pl
index c68002b9..3ab3ec98 100755
--- a/bin/named/bindkeys.pl
+++ b/bin/named/bindkeys.pl
@@ -14,13 +14,12 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: bindkeys.pl,v 1.2 2009/03/04 02:42:30 each Exp $
+# $Id: bindkeys.pl,v 1.3 2009/09/01 07:14:25 each Exp $
use strict;
use warnings;
-my $lines = '#define TRUSTED_KEYS "\\' . "\n";
-
+my $lines;
while (<>) {
chomp;
s/\"/\\\"/g;
@@ -28,5 +27,12 @@ while (<>) {
$lines .= $_ . "\n";
}
-$lines .= '"' . "\n";
-print $lines;
+my $mkey = '#define MANAGED_KEYS "\\' . "\n" . $lines . "\"\n";
+
+$lines =~ s/managed-keys/trusted-keys/;
+$lines =~ s/\s+initial-key//;
+my $tkey = '#define TRUSTED_KEYS "\\' . "\n" . $lines . "\"\n";
+
+print $tkey;
+print "\n";
+print $mkey;
diff --git a/bin/named/config.c b/bin/named/config.c
index 8d89c89c..3d72c557 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.c,v 1.99 2009/07/14 22:54:56 each Exp $ */
+/* $Id: config.c,v 1.101 2009/09/01 07:14:25 each Exp $ */
/*! \file */
@@ -248,12 +248,12 @@ view \"_meta\" in {\n\
# (used if \"dnssec-lookaside auto;\" is set and\n\
# sysconfdir/bind.keys doesn't exist).\n\
#\n\
-# BEGIN TRUSTED KEYS\n"
+# BEGIN MANAGED KEYS\n"
/* Imported from bind.keys.h: */
-TRUSTED_KEYS
+MANAGED_KEYS
-"# END TRUSTED KEYS\n\
+"# END MANAGED KEYS\n\
";
isc_result_t
@@ -651,7 +651,7 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
isc_buffer_add(&b, strlen(keystr));
dns_fixedname_init(&fname);
result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_name_dup(dns_fixedname_name(&fname), mctx,
diff --git a/bin/named/lwdgabn.c b/bin/named/lwdgabn.c
index dec1e1a5..c4b598be 100644
--- a/bin/named/lwdgabn.c
+++ b/bin/named/lwdgabn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwdgabn.c,v 1.22 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: lwdgabn.c,v 1.24 2009/09/02 23:48:01 tbox Exp $ */
/*! \file */
@@ -619,7 +619,7 @@ ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) {
dns_fixedname_init(&client->target_name);
dns_fixedname_init(&client->query_name);
result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
- &namebuf, NULL, ISC_FALSE, NULL);
+ &namebuf, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
goto out;
ns_lwsearchctx_init(&client->searchctx,
diff --git a/bin/named/lwdgrbn.c b/bin/named/lwdgrbn.c
index b54e83d0..5c858cbe 100644
--- a/bin/named/lwdgrbn.c
+++ b/bin/named/lwdgrbn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwdgrbn.c,v 1.20 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: lwdgrbn.c,v 1.22 2009/09/02 23:48:01 tbox Exp $ */
/*! \file */
@@ -472,7 +472,7 @@ ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) {
dns_fixedname_init(&client->query_name);
result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
- &namebuf, NULL, ISC_FALSE, NULL);
+ &namebuf, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
goto out;
ns_lwsearchctx_init(&client->searchctx,
diff --git a/bin/named/lwresd.c b/bin/named/lwresd.c
index 4e245fdb..11198a43 100644
--- a/bin/named/lwresd.c
+++ b/bin/named/lwresd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwresd.c,v 1.58 2008/07/23 23:27:54 marka Exp $ */
+/* $Id: lwresd.c,v 1.60 2009/09/02 23:48:01 tbox Exp $ */
/*! \file
* \brief
@@ -372,8 +372,7 @@ ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres,
strlen(searchstr));
isc_buffer_add(&namebuf, strlen(searchstr));
result = dns_name_fromtext(name, &namebuf,
- dns_rootname, ISC_FALSE,
- NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
diff --git a/bin/named/main.c b/bin/named/main.c
index a05daf15..b0f05141 100644
--- a/bin/named/main.c
+++ b/bin/named/main.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: main.c,v 1.172 2009/05/07 09:33:52 fdupont Exp $ */
+/* $Id: main.c,v 1.173 2009/09/01 18:40:25 jinmei Exp $ */
/*! \file */
@@ -26,6 +26,7 @@
#include <string.h>
#include <isc/app.h>
+#include <isc/backtrace.h>
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/entropy.h>
@@ -81,6 +82,13 @@
#include <dlz/dlz_drivers.h>
#endif
+/*
+ * The maximum number of stack frames to dump on assertion failure.
+ */
+#ifndef BACKTRACE_MAXFRAME
+#define BACKTRACE_MAXFRAME 128
+#endif
+
static isc_boolean_t want_stats = ISC_FALSE;
static char program_name[ISC_DIR_NAMEMAX] = "named";
static char absolute_conffile[ISC_DIR_PATHMAX];
@@ -134,6 +142,12 @@ static void
assertion_failed(const char *file, int line, isc_assertiontype_t type,
const char *cond)
{
+ void *tracebuf[BACKTRACE_MAXFRAME];
+ int i, nframes;
+ isc_result_t result;
+ const char *logsuffix = "";
+ const char *fname;
+
/*
* Handle assertion failures.
*/
@@ -145,10 +159,40 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
*/
isc_assertion_setcallback(NULL);
+ result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME,
+ &nframes);
+ if (result == ISC_R_SUCCESS && nframes > 0)
+ logsuffix = ", back trace";
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
- "%s:%d: %s(%s) failed", file, line,
- isc_assertion_typetotext(type), cond);
+ "%s:%d: %s(%s) failed%s", file, line,
+ isc_assertion_typetotext(type), cond, logsuffix);
+ if (result == ISC_R_SUCCESS) {
+ for (i = 0; i < nframes; i++) {
+ unsigned long offset;
+
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i],
+ &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN,
+ ISC_LOG_CRITICAL,
+ "#%d %p in %s()+0x%lx", i,
+ tracebuf[i], fname,
+ offset);
+ } else {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN,
+ ISC_LOG_CRITICAL,
+ "#%d %p in ??", i,
+ tracebuf[i]);
+ }
+ }
+ }
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
"exiting (due to assertion failure)");
@@ -585,6 +629,34 @@ destroy_managers(void) {
}
static void
+dump_symboltable() {
+ int i;
+ isc_result_t result;
+ const char *fname;
+ const void *addr;
+
+ if (isc__backtrace_nsymbols == 0)
+ return;
+
+ if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(99)))
+ return;
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
+ ISC_LOG_DEBUG(99), "Symbol table:");
+
+ for (i = 0, result = ISC_R_SUCCESS; result == ISC_R_SUCCESS; i++) {
+ addr = NULL;
+ fname = NULL;
+ result = isc_backtrace_getsymbolfromindex(i, &addr, &fname);
+ if (result == ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(99),
+ "[%d] %p %s", i, addr, fname);
+ }
+ }
+}
+
+static void
setup(void) {
isc_result_t result;
isc_resourcevalue_t old_openfiles;
@@ -691,6 +763,8 @@ setup(void) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
ISC_LOG_NOTICE, "built with %s", ns_g_configargs);
+ dump_symboltable();
+
/*
* Get the initial resource limits.
*/
@@ -902,6 +976,9 @@ main(int argc, char *argv[]) {
if (strcmp(program_name, "lwresd") == 0)
ns_g_lwresdonly = ISC_TRUE;
+ if (result != ISC_R_SUCCESS)
+ ns_main_earlyfatal("failed to build internal symbol table");
+
isc_assertion_setcallback(assertion_failed);
isc_error_setfatal(library_fatal_error);
isc_error_setunexpected(library_unexpected_error);
diff --git a/bin/named/server.c b/bin/named/server.c
index e2d682b5..4258ee9d 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.540 2009/08/05 17:35:33 each Exp $ */
+/* $Id: server.c,v 1.548 2009/09/10 01:49:29 each Exp $ */
/*! \file */
@@ -422,8 +422,7 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
str = cfg_obj_asstring(nameobj);
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
/*
* We don't need the node data, but need to set dummy data to
* avoid a partial match with an empty node. For example, if
@@ -431,7 +430,14 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
* for baz.example.com, which is not the expected result.
* We simply use (void *)1 as the dummy data.
*/
- CHECK(dns_rbt_addname(*rbtp, name, (void *)1));
+ result = dns_rbt_addname(*rbtp, name, (void *)1);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(nameobj, ns_g_lctx, ISC_LOG_ERROR,
+ "failed to add %s for %s: %s",
+ str, confname, isc_result_totext(result));
+ goto cleanup;
+ }
+
}
return (result);
@@ -469,6 +475,20 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key,
keyname = dns_fixedname_name(&fkeyname);
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
+ if (managed) {
+ const char *initmethod;
+ initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
+
+ if (strcmp(initmethod, "initial-key") != 0) {
+ cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
+ "managed key '%s': "
+ "invalid initialization method '%s'",
+ keynamestr, initmethod);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+ }
+
if (vconfig == NULL)
viewclass = dns_rdataclass_in;
else {
@@ -519,9 +539,7 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key,
dns_fixedname_init(&fkeyname);
isc_buffer_init(&namebuf, keynamestr, strlen(keynamestr));
isc_buffer_add(&namebuf, strlen(keynamestr));
- CHECK(dns_name_fromtext(keyname, &namebuf,
- dns_rootname, ISC_FALSE,
- NULL));
+ CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL));
CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf,
mctx, &dstkey));
@@ -534,7 +552,6 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key,
"ignoring %s key for '%s': no crypto support",
managed ? "managed" : "trusted",
keynamestr);
- result = ISC_R_SUCCESS;
} else {
cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
"configuring %s key for '%s': %s",
@@ -575,6 +592,8 @@ load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig,
}
cleanup:
+ if (result == DST_R_NOCRYPTO)
+ result = ISC_R_SUCCESS;
return (result);
}
@@ -705,8 +724,7 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
value = cfg_obj_asboolean(cfg_tuple_get(obj, "value"));
CHECK(dns_resolver_setmustbesecure(resolver, name, value));
}
@@ -866,7 +884,7 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
isc_buffer_add(&b, strlen(str));
dns_fixedname_init(&fixed);
result = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -1050,7 +1068,7 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
algorithms = cfg_tuple_get(disabled, "algorithms");
for (element = cfg_list_first(algorithms);
@@ -1103,7 +1121,7 @@ on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL);
+ 0, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dns_name_equal(name, zonename))
return (ISC_TRUE);
@@ -2104,7 +2122,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL));
+ 0, NULL));
#endif
str = cfg_obj_asstring(cfg_tuple_get(obj,
"trust-anchor"));
@@ -2112,7 +2130,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_buffer_add(&b, strlen(str));
dlv = dns_fixedname_name(&view->dlv_fixed);
CHECK(dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_TRUE, NULL));
+ DNS_NAME_DOWNCASE, NULL));
view->dlv = dns_fixedname_name(&view->dlv_fixed);
}
} else
@@ -2164,7 +2182,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ 0, NULL));
CHECK(dns_view_excludedelegationonly(view,
name));
}
@@ -2217,8 +2235,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
isc_buffer_init(&buffer, server, sizeof(server) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
server[isc_buffer_usedlength(&buffer)] = 0;
@@ -2232,8 +2250,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
isc_buffer_init(&buffer, contact, sizeof(contact) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
contact[isc_buffer_usedlength(&buffer)] = 0;
@@ -2259,8 +2277,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Look for zone on drop list.
*/
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
if (disablelist != NULL &&
on_disable_list(disablelist, name))
continue;
@@ -2450,8 +2468,8 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
isc_buffer_add(&buffer, strlen(str));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
portobj = cfg_tuple_get(alternate, "port");
if (cfg_obj_isuint32(portobj)) {
@@ -2664,7 +2682,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
isc_buffer_add(&buffer, strlen(zname));
dns_fixedname_init(&fixorigin);
CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
- &buffer, dns_rootname, ISC_FALSE, NULL));
+ &buffer, dns_rootname, 0, NULL));
origin = dns_fixedname_name(&fixorigin);
CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
@@ -2884,7 +2902,7 @@ add_keydata_zone(dns_view_t *view, isc_mem_t *mctx) {
CHECK(dns_zone_create(&zone, mctx));
dns_name_init(&zname, NULL);
- CHECK(dns_name_fromstring(&zname, KEYZONE, mctx));
+ CHECK(dns_name_fromstring(&zname, KEYZONE, 0, mctx));
CHECK(dns_zone_setorigin(zone, &zname));
dns_name_free(&zname, mctx);
@@ -3248,7 +3266,7 @@ set_limit(const cfg_obj_t **maps, const char *configname,
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
result == ISC_R_SUCCESS ?
ISC_LOG_DEBUG(3) : ISC_LOG_WARNING,
- "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s",
+ "set maximum %s to %" ISC_PRINT_QUADFORMAT "u: %s",
description, value, isc_result_totext(result));
}
@@ -3464,8 +3482,7 @@ configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
isc_buffer_init(&buffer, keynamestr, strlen(keynamestr));
isc_buffer_add(&buffer, strlen(keynamestr));
keyname = dns_fixedname_name(&fname);
- result = dns_name_fromtext(keyname, &buffer, dns_rootname, ISC_FALSE,
- NULL);
+ result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -5046,7 +5063,7 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
isc_buffer_add(&buf, strlen(zonetxt));
dns_fixedname_init(&name);
result = dns_name_fromtext(dns_fixedname_name(&name),
- &buf, dns_rootname, ISC_FALSE, NULL);
+ &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
goto fail1;
@@ -5887,7 +5904,7 @@ ns_server_flushname(ns_server_t *server, char *args) {
isc_buffer_add(&b, strlen(target));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/bin/named/tkeyconf.c b/bin/named/tkeyconf.c
index 82cf573b..e11aaa22 100644
--- a/bin/named/tkeyconf.c
+++ b/bin/named/tkeyconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tkeyconf.c,v 1.29 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: tkeyconf.c,v 1.31 2009/09/02 23:48:01 tbox Exp $ */
/*! \file */
@@ -77,8 +77,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY;
RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH,
type, NULL, mctx, &tctx->dhkey));
@@ -92,8 +91,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE,
- NULL));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t));
if (tctx->domain == NULL) {
result = ISC_R_NOMEMORY;
@@ -112,10 +110,8 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE,
- NULL));
- RETERR(dst_gssapi_acquirecred(name, ISC_FALSE,
- &tctx->gsscred));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred));
}
*tctxp = tctx;
diff --git a/bin/named/tsigconf.c b/bin/named/tsigconf.c
index f44dcd7e..5e06b0f6 100644
--- a/bin/named/tsigconf.c
+++ b/bin/named/tsigconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tsigconf.c,v 1.32 2009/06/11 23:47:55 tbox Exp $ */
+/* $Id: tsigconf.c,v 1.33 2009/09/01 00:22:25 jinmei Exp $ */
/*! \file */
@@ -82,7 +82,7 @@ add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
isc_buffer_add(&keynamesrc, strlen(keyid));
isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
- ISC_TRUE, &keynamebuf);
+ DNS_NAME_DOWNCASE, &keynamebuf);
if (ret != ISC_R_SUCCESS)
goto failure;
diff --git a/bin/named/unix/Makefile.in b/bin/named/unix/Makefile.in
index 50928340..dc1bf2b9 100644
--- a/bin/named/unix/Makefile.in
+++ b/bin/named/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.10 2007/06/19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.12 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \
${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
OBJS = os.@O@
diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h
index f3c51f47..c979e538 100644
--- a/bin/named/unix/include/named/os.h
+++ b/bin/named/unix/include/named/os.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.h,v 1.30 2009/08/05 17:35:33 each Exp $ */
+/* $Id: os.h,v 1.31 2009/08/05 23:47:43 tbox Exp $ */
#ifndef NS_OS_H
#define NS_OS_H 1
diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c
index 0f1159d2..a44d6c1c 100644
--- a/bin/named/unix/os.c
+++ b/bin/named/unix/os.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.100 2009/08/05 17:35:33 each Exp $ */
+/* $Id: os.c,v 1.101 2009/08/13 07:04:38 marka Exp $ */
/*! \file */
@@ -737,8 +737,8 @@ setperms(uid_t uid, gid_t gid) {
#if defined(HAVE_SETEGID)
if (getegid() != gid && setegid(gid) == -1) {
isc__strerror(errno, strbuf, sizeof(strbuf));
- ns_main_earlywarning("unable to set effective gid to %d: %s",
- gid, strbuf);
+ ns_main_earlywarning("unable to set effective gid to %ld: %s",
+ (long)gid, strbuf);
}
#elif defined(HAVE_SETRESGID)
if (getresgid(&tmpg, &oldgid, &tmpg) == -1 || oldgid != gid) {
@@ -753,8 +753,8 @@ setperms(uid_t uid, gid_t gid) {
#if defined(HAVE_SETEUID)
if (geteuid() != uid && seteuid(uid) == -1) {
isc__strerror(errno, strbuf, sizeof(strbuf));
- ns_main_earlywarning("unable to set effective uid to %d: %s",
- uid, strbuf);
+ ns_main_earlywarning("unable to set effective uid to %ld: %s",
+ (long)uid, strbuf);
}
#elif defined(HAVE_SETRESUID)
if (getresuid(&tmpu, &olduid, &tmpu) == -1 || olduid != uid) {
diff --git a/bin/named/update.c b/bin/named/update.c
index 2f580720..ea61500e 100644
--- a/bin/named/update.c
+++ b/bin/named/update.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update.c,v 1.158 2009/07/28 15:45:43 marka Exp $ */
+/* $Id: update.c,v 1.159 2009/08/17 07:18:41 marka Exp $ */
#include <config.h>
@@ -3901,6 +3901,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
&diff));
}
} else if (update_class == dns_rdataclass_none) {
+ char namestr[DNS_NAME_FORMATSIZE];
+ char typestr[DNS_RDATATYPE_FORMATSIZE];
+
/*
* The (name == zonename) condition appears in
* RFC2136 3.4.2.4 but is missing from the pseudocode.
@@ -3928,11 +3931,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
}
}
}
- update_log(client, zone,
- LOGLEVEL_PROTOCOL,
- "deleting an RR");
- CHECK(delete_if(rr_equal_p, db, ver, name,
- rdata.type, covers, &rdata, &diff));
+ dns_name_format(name, namestr, sizeof(namestr));
+ dns_rdatatype_format(rdata.type, typestr,
+ sizeof(typestr));
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "deleting an RR at %s %s", namestr, typestr);
+ CHECK(delete_if(rr_equal_p, db, ver, name, rdata.type,
+ covers, &rdata, &diff));
}
}
if (result != ISC_R_NOMORE)
diff --git a/bin/named/win32/include/named/os.h b/bin/named/win32/include/named/os.h
index 5724444d..e4eb9942 100644
--- a/bin/named/win32/include/named/os.h
+++ b/bin/named/win32/include/named/os.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.h,v 1.16 2009/08/05 18:43:37 each Exp $ */
+/* $Id: os.h,v 1.17 2009/08/05 23:47:43 tbox Exp $ */
#ifndef NS_OS_H
#define NS_OS_H 1
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index 1ecc4b96..f56da448 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.c,v 1.153 2009/07/14 23:47:53 tbox Exp $ */
+/* $Id: zoneconf.c,v 1.154 2009/09/01 00:22:25 jinmei Exp $ */
/*% */
@@ -260,7 +260,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -283,8 +283,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(dns_fixedname_name(&fname),
- &b, dns_rootname,
- ISC_FALSE, NULL);
+ &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
diff --git a/bin/nsupdate/Makefile.in b/bin/nsupdate/Makefile.in
index b479eb7e..b2ce1806 100644
--- a/bin/nsupdate/Makefile.in
+++ b/bin/nsupdate/Makefile.in
@@ -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.32 2009/07/14 22:54:56 each Exp $
+# $Id: Makefile.in,v 1.34 2009/09/01 18:40:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -26,13 +26,14 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \
${ISC_INCLUDES} ${ISCCFG_INCLUDES} @DST_GSSAPI_INC@
-CDEFINES = @USE_GSSAPI@
+CDEFINES = -DBIND9 @USE_GSSAPI@
CWARNINGS =
LWRESLIBS = ../../lib/lwres/liblwres.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
@@ -45,6 +46,8 @@ DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS}
LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCNOSYMLIBS} ${ISCCFGLIBS} @LIBS@
+
SUBDIRS =
TARGETS = nsupdate@EXEEXT@
@@ -69,7 +72,8 @@ nsupdate.@O@: nsupdate.c
-c ${srcdir}/nsupdate.c
nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsupdate.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="nsupdate.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/nsupdate/nsupdate.1 b/bin/nsupdate/nsupdate.1
index 06daaa21..e8645dd3 100644
--- a/bin/nsupdate/nsupdate.1
+++ b/bin/nsupdate/nsupdate.1
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: nsupdate.1,v 1.9 2009/07/15 01:13:10 tbox Exp $
+.\" $Id: nsupdate.1,v 1.10 2009/08/27 01:14:39 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: nsupdate
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: Jun 30, 2000
+.\" Date: Aug 25, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "NSUPDATE" "1" "Jun 30, 2000" "BIND9" "BIND9"
+.TH "NSUPDATE" "1" "Aug 25, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -33,7 +33,7 @@
nsupdate \- Dynamic DNS update utility
.SH "SYNOPSIS"
.HP 9
-\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename]
+\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-l\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename]
.SH "DESCRIPTION"
.PP
\fBnsupdate\fR
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
index 27c61742..c62a8418 100644
--- a/bin/nsupdate/nsupdate.c
+++ b/bin/nsupdate/nsupdate.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsupdate.c,v 1.171 2009/07/19 04:18:04 each Exp $ */
+/* $Id: nsupdate.c,v 1.172 2009/09/01 00:22:25 jinmei Exp $ */
/*! \file */
@@ -526,8 +526,7 @@ setup_keystr(void) {
isc_buffer_add(&keynamesrc, n - name);
debug("namefromtext");
- result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
secretlen = strlen(secretstr) * 3 / 4;
@@ -1110,8 +1109,7 @@ parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) {
dns_message_takebuffer(msg, &namebuf);
isc_buffer_init(&source, word, strlen(word));
isc_buffer_add(&source, strlen(word));
- result = dns_name_fromtext(*namep, &source, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
isc_buffer_invalidate(&source);
return (STATUS_MORE);
@@ -1433,7 +1431,7 @@ evaluate_key(char *cmdline) {
isc_buffer_init(&b, namestr, strlen(namestr));
isc_buffer_add(&b, strlen(namestr));
- result = dns_name_fromtext(keyname, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not parse key name\n");
return (STATUS_SYNTAX);
@@ -1490,8 +1488,7 @@ evaluate_zone(char *cmdline) {
userzone = dns_fixedname_name(&fuserzone);
isc_buffer_init(&b, word, strlen(word));
isc_buffer_add(&b, strlen(word));
- result = dns_name_fromtext(userzone, &b, dns_rootname, ISC_FALSE,
- NULL);
+ result = dns_name_fromtext(userzone, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
userzone = NULL; /* Lest it point to an invalid name */
fprintf(stderr, "could not parse zone name\n");
@@ -2426,8 +2423,7 @@ start_gssrequest(dns_name_t *master)
isc_result_totext(result));
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
- result = dns_name_fromtext(servname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("dns_name_fromtext(servname) failed: %s",
isc_result_totext(result));
@@ -2444,8 +2440,7 @@ start_gssrequest(dns_name_t *master)
isc_buffer_init(&buf, keystr, strlen(keystr));
isc_buffer_add(&buf, strlen(keystr));
- result = dns_name_fromtext(keyname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("dns_name_fromtext(keyname) failed: %s",
isc_result_totext(result));
@@ -2596,8 +2591,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
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);
+ result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
tsigkey = NULL;
diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook
index 242118b0..ab234b49 100644
--- a/bin/nsupdate/nsupdate.docbook
+++ b/bin/nsupdate/nsupdate.docbook
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nsupdate.docbook,v 1.39 2009/07/14 22:54:57 each Exp $ -->
+<!-- $Id: nsupdate.docbook,v 1.40 2009/08/26 21:34:44 jreed Exp $ -->
<refentry id="man.nsupdate">
<refentryinfo>
- <date>Jun 30, 2000</date>
+ <date>Aug 25, 2009</date>
</refentryinfo>
<refmeta>
<refentrytitle><application>nsupdate</application></refentrytitle>
@@ -60,6 +60,7 @@
<group>
<arg><option>-g</option></arg>
<arg><option>-o</option></arg>
+ <arg><option>-l</option></arg>
<arg><option>-y <replaceable class="parameter"><optional>hmac:</optional>keyname:secret</replaceable></option></arg>
<arg><option>-k <replaceable class="parameter">keyfile</replaceable></option></arg>
</group>
diff --git a/bin/nsupdate/nsupdate.html b/bin/nsupdate/nsupdate.html
index b48fb4cb..2c4203bf 100644
--- a/bin/nsupdate/nsupdate.html
+++ b/bin/nsupdate/nsupdate.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nsupdate.html,v 1.46 2009/07/15 01:13:10 tbox Exp $ -->
+<!-- $Id: nsupdate.html,v 1.47 2009/08/27 01:14:39 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,10 +29,10 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
+<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-l</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543449"></a><h2>DESCRIPTION</h2>
+<a name="id2543453"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">nsupdate</strong></span>
is used to submit Dynamic DNS Update requests as defined in RFC2136
to a name server.
@@ -187,7 +187,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543772"></a><h2>INPUT FORMAT</h2>
+<a name="id2543777"></a><h2>INPUT FORMAT</h2>
<p><span><strong class="command">nsupdate</strong></span>
reads input from
<em class="parameter"><code>filename</code></em>
@@ -451,7 +451,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544613"></a><h2>EXAMPLES</h2>
+<a name="id2544617"></a><h2>EXAMPLES</h2>
<p>
The examples below show how
<span><strong class="command">nsupdate</strong></span>
@@ -505,7 +505,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544657"></a><h2>FILES</h2>
+<a name="id2544661"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="constant">/etc/resolv.conf</code></span></dt>
<dd><p>
@@ -528,7 +528,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544740"></a><h2>SEE ALSO</h2>
+<a name="id2544744"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">RFC2136</span></span>,
<span class="citerefentry"><span class="refentrytitle">RFC3007</span></span>,
<span class="citerefentry"><span class="refentrytitle">RFC2104</span></span>,
@@ -542,7 +542,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2542156"></a><h2>BUGS</h2>
+<a name="id2542161"></a><h2>BUGS</h2>
<p>
The TSIG key is redundantly stored in two separate files.
This is a consequence of nsupdate using the DST library
diff --git a/bin/rndc/Makefile.in b/bin/rndc/Makefile.in
index d6892d12..3334e445 100644
--- a/bin/rndc/Makefile.in
+++ b/bin/rndc/Makefile.in
@@ -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.46 2009/06/11 23:47:55 tbox Exp $
+# $Id: Makefile.in,v 1.48 2009/09/01 18:40:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -26,12 +26,13 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \
${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
@@ -41,10 +42,11 @@ ISCDEPLIBS = ../../lib/isc/libisc.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
+
RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
-CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
SRCS= rndc.c
@@ -67,8 +69,9 @@ rndc.@O@: rndc.c
-c ${srcdir}/rndc.c
rndc@EXEEXT@: rndc.@O@ util.@O@ ${RNDCDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc.@O@ util.@O@ \
- ${RNDCLIBS}
+ export BASEOBJS="rndc.@O@ util.@O@"; \
+ export LIBS0="${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/tests/Makefile.in b/bin/tests/Makefile.in
index ac3a51ad..f92b3d13 100644
--- a/bin/tests/Makefile.in
+++ b/bin/tests/Makefile.in
@@ -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.134 2009/03/02 03:53:29 each Exp $
+# $Id: Makefile.in,v 1.137 2009/09/01 22:30:28 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,16 +24,18 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
${LWRES_INCLUDES} ${OMAPI_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCLIBS = ../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ @DNS_CRYPTO_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
+ISCDEPNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
@@ -52,6 +54,8 @@ TARGETS = cfg_test@EXEEXT@
# Alphabetically
XTARGETS = adb_test@EXEEXT@ \
byaddr_test@EXEEXT@ \
+ backtrace_test@EXEEXT@ \
+ backtrace_test_nosymtbl@EXEEXT@ \
byname_test@EXEEXT@ \
compress_test@EXEEXT@ \
db_test@EXEEXT@ \
@@ -91,6 +95,7 @@ SRCS = cfg_test.c ${XSRCS}
XSRCS = adb_test.c \
byaddr_test.c \
+ backtrace_test.c \
byname_test.c \
compress_test.c \
db_test.c \
@@ -128,12 +133,42 @@ XSRCS = adb_test.c \
@BIND9_MAKE_RULES@
+# disable optimization for backtrace test to get the expected result
+BTTEST_CFLAGS = ${EXT_CFLAGS} ${ALL_CPPFLAGS} -g ${ALWAYS_WARNINGS} \
+ ${STD_CWARNINGS} ${CWARNINGS}
+
all_tests: ${XTARGETS}
adb_test@EXEEXT@: adb_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ adb_test.@O@ \
${DNSLIBS} ${ISCLIBS} ${LIBS}
+backtrace_test_nosymtbl@EXEEXT@: backtrace_test.c ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${BTTEST_CFLAGS} ${LDFLAGS} -o $@ \
+ backtrace_test.c ${ISCLIBS} ${LIBS}
+
+backtrace_test@EXEEXT@: backtrace_test_nosymtbl@EXEEXT@
+ #first step: create a first symbol table
+ rm -f symtbl.c
+ if test X${MKSYMTBL_PROGRAM} != X; then \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ backtrace_test_nosymtbl@EXEEXT@; else \
+ cp ${top_srcdir}/lib/isc/backtrace-emptytbl.c symtbl.c; fi
+ #second step: build a binary with the first symbol table
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${BTTEST_CFLAGS} ${LDFLAGS} \
+ -o $@0 backtrace_test.c symtbl.c \
+ ${ISCNOSYMLIBS} ${LIBS}
+ rm -f symtbl.c
+ #third step: create a second symbol table
+ if test X${MKSYMTBL_PROGRAM} != X; then \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl $@0; else \
+ cp ${top_srcdir}/lib/isc/backtrace-emptytbl.c symtbl.c; fi
+ #fourth step: build the final binary
+ rm -f $@0
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${BTTEST_CFLAGS} ${LDFLAGS} \
+ -o $@ backtrace_test.c symtbl.c ${ISCNOSYMLIBS} ${LIBS}
+ rm -f symtbl.c
+
nsecify@EXEEXT@: nsecify.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsecify.@O@ \
${DNSLIBS} ${ISCLIBS} ${LIBS}
@@ -280,6 +315,7 @@ distclean::
clean distclean::
rm -f ${TARGETS} ${XTARGETS}
rm -f t_journal
+ rm -f backtrace_test_symtbl.c
check: test
diff --git a/bin/tests/adb_test.c b/bin/tests/adb_test.c
index 2ef812d7..bf44b45d 100644
--- a/bin/tests/adb_test.c
+++ b/bin/tests/adb_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb_test.c,v 1.68 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: adb_test.c,v 1.70 2009/09/02 23:48:01 tbox Exp $ */
/*! \file */
@@ -249,8 +249,7 @@ lookup(const char *target) {
isc_buffer_add(&t, strlen(target));
isc_buffer_init(&namebuf, namedata, sizeof(namedata));
dns_name_init(&name, NULL);
- result = dns_name_fromtext(&name, &t, dns_rootname, ISC_FALSE,
- &namebuf);
+ result = dns_name_fromtext(&name, &t, dns_rootname, 0, &namebuf);
check_result(result, "dns_name_fromtext %s", target);
result = dns_name_dup(&name, mctx, &client->name);
diff --git a/bin/tests/backtrace_test.c b/bin/tests/backtrace_test.c
new file mode 100644
index 00000000..9253ca77
--- /dev/null
+++ b/bin/tests/backtrace_test.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: backtrace_test.c,v 1.4 2009/09/02 23:48:01 tbox Exp $ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/backtrace.h>
+#include <isc/result.h>
+
+const char *expected_symbols[] = {
+ "func3",
+ "func2",
+ "func1",
+ "main"
+};
+
+static int
+func3() {
+ void *tracebuf[16];
+ int i, nframes;
+ int error = 0;
+ const char *fname;
+ isc_result_t result;
+ unsigned long offset;
+
+ result = isc_backtrace_gettrace(tracebuf, 16, &nframes);
+ if (result != ISC_R_SUCCESS) {
+ printf("isc_backtrace_gettrace failed: %s\n",
+ isc_result_totext(result));
+ return (1);
+ }
+
+ if (nframes < 4)
+ error++;
+
+ for (i = 0; i < 4 && i < nframes; i++) {
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i], &fname, &offset);
+ if (result != ISC_R_SUCCESS) {
+ error++;
+ continue;
+ }
+ if (strcmp(fname, expected_symbols[i]) != 0)
+ error++;
+ }
+
+ if (error) {
+ printf("Unexpected result:\n");
+ printf(" # of frames: %d (expected: at least 4)\n", nframes);
+ printf(" symbols:\n");
+ for (i = 0; i < nframes; i++) {
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i], &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS)
+ printf(" [%d] %s\n", i, fname);
+ else {
+ printf(" [%d] getsymbol failed: %s\n", i,
+ isc_result_totext(result));
+ }
+ }
+ }
+
+ return (error);
+}
+
+static int
+func2() {
+ return (func3());
+}
+
+static int
+func1() {
+ return (func2());
+}
+
+int
+main() {
+ return (func1());
+}
diff --git a/bin/tests/byname_test.c b/bin/tests/byname_test.c
index fdf45a98..ae372e85 100644
--- a/bin/tests/byname_test.c
+++ b/bin/tests/byname_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: byname_test.c,v 1.31 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: byname_test.c,v 1.33 2009/09/02 23:48:01 tbox Exp $ */
/*! \file
* \author
@@ -343,7 +343,7 @@ main(int argc, char *argv[]) {
dns_fixedname_init(&name);
dns_fixedname_init(&target);
RUNTIME_CHECK(dns_name_fromtext(dns_fixedname_name(&name), &b,
- dns_rootname, ISC_FALSE, NULL) ==
+ dns_rootname, 0, NULL) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_app_onrun(mctx, task, run, NULL) == ISC_R_SUCCESS);
diff --git a/bin/tests/db/Makefile.in b/bin/tests/db/Makefile.in
index 13ebad26..9120510e 100644
--- a/bin/tests/db/Makefile.in
+++ b/bin/tests/db/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.29 2007/06/19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.31 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
diff --git a/bin/tests/db/t_db.c b/bin/tests/db/t_db.c
index 6ec057a5..3a7a2a72 100644
--- a/bin/tests/db/t_db.c
+++ b/bin/tests/db/t_db.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_db.c,v 1.38 2009/01/22 23:47:53 tbox Exp $ */
+/* $Id: t_db.c,v 1.39 2009/09/01 00:22:25 jinmei Exp $ */
#include <config.h>
@@ -61,7 +61,7 @@ t_create(const char *db_type, const char *origin, const char *class,
isc_buffer_init(&origin_buffer, origin, len);
isc_buffer_add(&origin_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
- &origin_buffer, NULL, ISC_FALSE, NULL);
+ &origin_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -190,7 +190,7 @@ t_dns_db_load(char **av) {
isc_buffer_init(&findname_buffer, findname, len);
isc_buffer_add(&findname_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
- &findname_buffer, NULL, ISC_FALSE, NULL);
+ &findname_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -305,7 +305,7 @@ t_dns_db_zc_x(char *filename, char *db_type, char *origin, char *class,
isc_buffer_init(&origin_buffer, origin, len);
isc_buffer_add(&origin_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
- &origin_buffer, NULL, ISC_FALSE, NULL);
+ &origin_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -584,7 +584,7 @@ t_dns_db_origin(char **av) {
}
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
- &origin_buffer, NULL, ISC_FALSE, NULL);
+ &origin_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -832,7 +832,7 @@ t_dns_db_currentversion(char **av) {
isc_buffer_init(&findname_buffer, findname, len);
isc_buffer_add(&findname_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
- &findname_buffer, NULL, ISC_FALSE, NULL);
+ &findname_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -1123,7 +1123,7 @@ t_dns_db_newversion(char **av) {
isc_buffer_init(&newname_buffer, newname, len);
isc_buffer_add(&newname_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
- &newname_buffer, NULL, ISC_FALSE, NULL);
+ &newname_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -1449,7 +1449,7 @@ t_dns_db_closeversion_1(char **av) {
isc_buffer_init(&name_buffer, existing_name, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -1528,7 +1528,7 @@ t_dns_db_closeversion_1(char **av) {
isc_buffer_init(&name_buffer, new_name, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -1861,7 +1861,7 @@ t_dns_db_closeversion_2(char **av) {
isc_buffer_init(&name_buffer, existing_name, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -1942,7 +1942,7 @@ t_dns_db_closeversion_2(char **av) {
isc_buffer_init(&name_buffer, new_name, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -2279,7 +2279,7 @@ t_dns_db_expirenode(char **av) {
isc_buffer_init(&name_buffer, existing_name, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
@@ -2525,7 +2525,7 @@ t_dns_db_findnode_1(char **av) {
isc_buffer_init(&name_buffer, find_name, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
ISC_FALSE, &nodep);
@@ -2681,7 +2681,7 @@ t_dns_db_findnode_2(char **av) {
isc_buffer_init(&name_buffer, newname, len);
isc_buffer_add(&name_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name),
- &name_buffer, NULL, ISC_FALSE, NULL);
+ &name_buffer, NULL, 0, NULL);
dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
ISC_FALSE, &nodep);
@@ -2886,7 +2886,7 @@ t_dns_db_find_x(char **av) {
isc_buffer_init(&findname_buffer, findname, len);
isc_buffer_add(&findname_buffer, len);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
- &findname_buffer, NULL, ISC_FALSE, NULL);
+ &findname_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
diff --git a/bin/tests/db_test.c b/bin/tests/db_test.c
index 9b0d90d2..e800531f 100644
--- a/bin/tests/db_test.c
+++ b/bin/tests/db_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db_test.c,v 1.66 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: db_test.c,v 1.68 2009/09/02 23:48:01 tbox Exp $ */
/*! \file
* \author
@@ -134,8 +134,7 @@ select_db(char *origintext) {
isc_buffer_add(&source, len);
dns_fixedname_init(&forigin);
origin = dns_fixedname_name(&forigin);
- result = dns_name_fromtext(origin, &source, dns_rootname, ISC_FALSE,
- NULL);
+ result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
print_result("bad name", result);
return (NULL);
@@ -188,8 +187,7 @@ list(dbinfo *dbi, char *seektext) {
result = dns_name_fromtext(seekname, &source,
dns_db_origin(
dbi->db),
- ISC_FALSE,
- NULL);
+ 0, NULL);
if (result == ISC_R_SUCCESS)
result = dns_dbiterator_seek(
dbi->dbiterator,
@@ -271,8 +269,7 @@ load(const char *filename, const char *origintext, isc_boolean_t cache) {
isc_buffer_add(&source, len);
dns_fixedname_init(&forigin);
origin = dns_fixedname_name(&forigin);
- result = dns_name_fromtext(origin, &source, dns_rootname, ISC_FALSE,
- NULL);
+ result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -736,8 +733,7 @@ main(int argc, char *argv[]) {
isc_buffer_init(&source, s, len);
isc_buffer_add(&source, len);
isc_buffer_init(&target, b, sizeof(b));
- result = dns_name_fromtext(&name, &source, origin,
- ISC_FALSE, &target);
+ result = dns_name_fromtext(&name, &source, origin, 0, &target);
if (result != ISC_R_SUCCESS) {
print_result("bad name: ", result);
continue;
diff --git a/bin/tests/dst/Makefile.in b/bin/tests/dst/Makefile.in
index fad70d5a..72e6e423 100644
--- a/bin/tests/dst/Makefile.in
+++ b/bin/tests/dst/Makefile.in
@@ -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.48 2009/03/02 23:47:43 tbox Exp $
+# $Id: Makefile.in,v 1.49 2009/09/01 00:22:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} \
${ISC_INCLUDES} @DST_GSSAPI_INC@
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
diff --git a/bin/tests/dst/dst_test.c b/bin/tests/dst/dst_test.c
index 597e6356..ac1327c9 100644
--- a/bin/tests/dst/dst_test.c
+++ b/bin/tests/dst/dst_test.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_test.c,v 1.45 2009/03/02 23:47:43 tbox Exp $ */
+/* $Id: dst_test.c,v 1.46 2009/09/01 00:22:25 jinmei Exp $ */
#include <config.h>
@@ -264,7 +264,7 @@ main(void) {
name = dns_fixedname_name(&fname);
isc_buffer_init(&b, "test.", 5);
isc_buffer_add(&b, 5);
- result = dns_name_fromtext(name, &b, NULL, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
return (1);
io(name, 23616, DST_ALG_DSA, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx);
@@ -276,7 +276,7 @@ main(void) {
isc_buffer_init(&b, "dh.", 3);
isc_buffer_add(&b, 3);
- result = dns_name_fromtext(name, &b, NULL, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
return (1);
dh(name, 18602, name, 48957, mctx);
diff --git a/bin/tests/dst/gsstest.c b/bin/tests/dst/gsstest.c
index 98e16d26..6c314d22 100755
--- a/bin/tests/dst/gsstest.c
+++ b/bin/tests/dst/gsstest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gsstest.c,v 1.6 2007/06/19 23:47:00 tbox Exp $ */
+/* $Id: gsstest.c,v 1.8 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -175,7 +175,7 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
end:
if (query)
dns_message_destroy(&query);
-
+
if (reqev->request)
dns_request_destroy(&reqev->request);
@@ -184,7 +184,7 @@ end:
event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
sizeof(*event));
isc_task_send(task, &event);
- return;
+ return;
}
@@ -202,7 +202,7 @@ sendquery(isc_task_t *task, isc_event_t *event)
char output[10 * 1024];
static char host[256];
-
+
isc_event_free(&event);
printf("Query => ");
@@ -212,7 +212,7 @@ sendquery(isc_task_t *task, isc_event_t *event)
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);
+ dns_rootname, 0, NULL);
CHECK("dns_name_fromtext", result);
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
@@ -335,7 +335,7 @@ end:
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);
@@ -357,27 +357,27 @@ initctx1(isc_task_t *task, isc_event_t *event) {
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);
+ dns_rootname, 0, NULL);
CHECK("dns_name_fromtext", result);
- /* Make name happen */
+ /* 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);
+ dns_rootname, 0, NULL);
CHECK("dns_name_fromtext", result);
query = NULL;
@@ -423,7 +423,7 @@ setup(void)
isc_sockaddr_fromin(&address, &inaddr, PORT);
return;
}
-
+
};
}
@@ -446,7 +446,7 @@ main(int argc, char *argv[]) {
UNUSED(argv);
UNUSED(argc);
-
+
RUNCHECK(isc_app_start());
dns_result_register();
@@ -519,7 +519,7 @@ main(int argc, char *argv[]) {
&sock));
setup();
-
+
RUNCHECK(isc_app_onrun(mctx, task, console, NULL));
(void)isc_app_run();
@@ -529,10 +529,10 @@ main(int argc, char *argv[]) {
dns_requestmgr_shutdown(requestmgr);
dns_requestmgr_detach(&requestmgr);
-
+
dns_dispatch_detach(&dispatchv4);
dns_dispatchmgr_destroy(&dispatchmgr);
-
+
isc_timermgr_destroy(&timermgr);
isc_task_detach(&task);
diff --git a/bin/tests/dst/t_dst.c b/bin/tests/dst/t_dst.c
index c8010228..bc430ec6 100644
--- a/bin/tests/dst/t_dst.c
+++ b/bin/tests/dst/t_dst.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_dst.c,v 1.57 2009/01/22 23:47:54 tbox Exp $ */
+/* $Id: t_dst.c,v 1.58 2009/09/01 00:22:25 jinmei Exp $ */
#include <config.h>
@@ -405,7 +405,7 @@ t1(void) {
name = dns_fixedname_name(&fname);
isc_buffer_init(&b, "test.", 5);
isc_buffer_add(&b, 5);
- isc_result = dns_name_fromtext(name, &b, NULL, ISC_FALSE, NULL);
+ isc_result = dns_name_fromtext(name, &b, NULL, 0, NULL);
if (isc_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
isc_result_totext(isc_result));
@@ -427,7 +427,7 @@ t1(void) {
isc_buffer_init(&b, "dh.", 3);
isc_buffer_add(&b, 3);
- isc_result = dns_name_fromtext(name, &b, NULL, ISC_FALSE, NULL);
+ isc_result = dns_name_fromtext(name, &b, NULL, 0, NULL);
if (isc_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
isc_result_totext(isc_result));
@@ -686,7 +686,7 @@ t2_sigchk(char *datapath, char *sigpath, char *keyname,
name = dns_fixedname_name(&fname);
isc_buffer_init(&b, keyname, strlen(keyname));
isc_buffer_add(&b, strlen(keyname));
- isc_result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ isc_result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (isc_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
isc_result_totext(isc_result));
diff --git a/bin/tests/master/Makefile.in b/bin/tests/master/Makefile.in
index 03125da1..8fbe3aa0 100644
--- a/bin/tests/master/Makefile.in
+++ b/bin/tests/master/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.28 2007/06/19 23:47:00 tbox Exp $
+# $Id: Makefile.in,v 1.30 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
# Note that we do not want to use libtool for libt_api
diff --git a/bin/tests/master/t_master.c b/bin/tests/master/t_master.c
index 8df588b0..496b79aa 100644
--- a/bin/tests/master/t_master.c
+++ b/bin/tests/master/t_master.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_master.c,v 1.38 2009/01/22 23:47:54 tbox Exp $ */
+/* $Id: t_master.c,v 1.39 2009/09/01 00:22:25 jinmei Exp $ */
#include <config.h>
@@ -94,7 +94,7 @@ test_master(char *testfile, char *origin, char *class, isc_result_t exp_result)
isc_buffer_init(&target, name_buf, BUFLEN);
dns_name_init(&dns_origin, NULL);
dns_result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
- ISC_FALSE, &target);
+ 0, &target);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
dns_result_totext(dns_result));
diff --git a/bin/tests/master_test.c b/bin/tests/master_test.c
index f77c8f64..afc6c8c1 100644
--- a/bin/tests/master_test.c
+++ b/bin/tests/master_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master_test.c,v 1.30 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: master_test.c,v 1.32 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -75,7 +75,7 @@ main(int argc, char *argv[]) {
isc_buffer_init(&target, name_buf, 255);
dns_name_init(&origin, NULL);
result = dns_name_fromtext(&origin, &source, dns_rootname,
- ISC_FALSE, &target);
+ 0, &target);
if (result != ISC_R_SUCCESS) {
fprintf(stdout, "dns_name_fromtext: %s\n",
dns_result_totext(result));
@@ -85,7 +85,7 @@ main(int argc, char *argv[]) {
dns_rdatacallbacks_init_stdio(&callbacks);
callbacks.add = print_dataset;
- result = dns_master_loadfile(argv[1], &origin, &origin,
+ result = dns_master_loadfile(argv[1], &origin, &origin,
dns_rdataclass_in, 0,
&callbacks, mctx);
fprintf(stdout, "dns_master_loadfile: %s\n",
diff --git a/bin/tests/mem/Makefile.in b/bin/tests/mem/Makefile.in
index 135a8e3e..71b9f9b0 100644
--- a/bin/tests/mem/Makefile.in
+++ b/bin/tests/mem/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.34 2007/06/19 23:47:00 tbox Exp $
+# $Id: Makefile.in,v 1.36 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../../lib/isc/libisc.@A@
diff --git a/bin/tests/name_test.c b/bin/tests/name_test.c
index 799115fe..9c98685a 100644
--- a/bin/tests/name_test.c
+++ b/bin/tests/name_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name_test.c,v 1.41 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: name_test.c,v 1.43 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -73,7 +73,7 @@ main(int argc, char *argv[]) {
isc_buffer_t source;
isc_region_t r;
dns_name_t *name, *origin, *comp, *down;
- isc_boolean_t downcase = ISC_FALSE;
+ unsigned int downcase = 0;
size_t len;
isc_boolean_t quiet = ISC_FALSE;
isc_boolean_t concatenate = ISC_FALSE;
@@ -128,8 +128,7 @@ main(int argc, char *argv[]) {
dns_fixedname_init(&oname);
origin = &oname.name;
result = dns_name_fromtext(origin, &source,
- dns_rootname, ISC_FALSE,
- NULL);
+ dns_rootname, 0, NULL);
if (result != 0) {
fprintf(stderr,
"dns_name_fromtext() failed: %d\n",
@@ -151,8 +150,8 @@ main(int argc, char *argv[]) {
isc_buffer_add(&source, len);
dns_fixedname_init(&compname);
comp = &compname.name;
- result = dns_name_fromtext(comp, &source,
- origin, ISC_FALSE, NULL);
+ result = dns_name_fromtext(comp, &source, origin,
+ 0, NULL);
if (result != 0) {
fprintf(stderr,
"dns_name_fromtext() failed: %d\n",
diff --git a/bin/tests/names/Makefile.in b/bin/tests/names/Makefile.in
index 31b12fee..c901d8d9 100644
--- a/bin/tests/names/Makefile.in
+++ b/bin/tests/names/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.28 2007/06/19 23:47:00 tbox Exp $
+# $Id: Makefile.in,v 1.30 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
# Note that we do not want to use libtool for libt_api
diff --git a/bin/tests/names/t_names.c b/bin/tests/names/t_names.c
index ce776dec..d3a8b66c 100644
--- a/bin/tests/names/t_names.c
+++ b/bin/tests/names/t_names.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_names.c,v 1.48 2009/01/22 23:47:54 tbox Exp $ */
+/* $Id: t_names.c,v 1.50 2009/09/01 23:47:44 tbox Exp $ */
#include <config.h>
@@ -344,8 +344,7 @@ dname_from_tname(char *name, dns_name_t *dns_name) {
isc_buffer_init(binbuf, junk, BUFLEN);
dns_name_init(dns_name, NULL);
dns_name_setbuffer(dns_name, binbuf);
- result = dns_name_fromtext(dns_name, &txtbuf,
- NULL, ISC_FALSE, NULL);
+ result = dns_name_fromtext(dns_name, &txtbuf, NULL, 0, NULL);
} else {
result = ISC_R_NOSPACE;
if (junk != NULL)
@@ -535,7 +534,7 @@ test_dns_name_isabsolute(char *test_name, isc_boolean_t expected) {
isc_buffer_init(&binbuf, &junk[0], BUFLEN);
dns_name_init(&name, NULL);
dns_name_setbuffer(&name, &binbuf);
- result = dns_name_fromtext(&name, &buf, NULL, ISC_FALSE, NULL);
+ result = dns_name_fromtext(&name, &buf, NULL, 0, NULL);
if (result == ISC_R_SUCCESS) {
isabs_p = dns_name_isabsolute(&name);
if (isabs_p == expected)
@@ -1659,7 +1658,7 @@ static const char *a40 =
static int
test_dns_name_fromtext(char *test_name1, char *test_name2, char *test_origin,
- isc_boolean_t downcase)
+ unsigned int downcase)
{
int result;
int order;
@@ -1702,8 +1701,8 @@ test_dns_name_fromtext(char *test_name1, char *test_name2, char *test_origin,
dns_name_setbuffer(&dns_name2, &binbuf2);
dns_name_setbuffer(&dns_name3, &binbuf3);
- dns_result = dns_name_fromtext(&dns_name3, &txtbuf3, NULL,
- ISC_FALSE, &binbuf3);
+ dns_result = dns_name_fromtext(&dns_name3, &txtbuf3, NULL, 0,
+ &binbuf3);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext(dns_name3) failed, result == %s\n",
dns_result_totext(dns_result));
@@ -1718,8 +1717,8 @@ test_dns_name_fromtext(char *test_name1, char *test_name2, char *test_origin,
return (T_FAIL);
}
- dns_result = dns_name_fromtext(&dns_name2, &txtbuf2, NULL,
- ISC_FALSE, &binbuf2);
+ dns_result = dns_name_fromtext(&dns_name2, &txtbuf2, NULL, 0,
+ &binbuf2);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext(dns_name2) failed, result == %s\n",
dns_result_totext(dns_result));
@@ -1777,8 +1776,8 @@ t_dns_name_fromtext(void) {
Tokens[2],
atoi(Tokens[3])
== 0 ?
- ISC_FALSE :
- ISC_TRUE);
+ 0 :
+ DNS_NAME_DOWNCASE);
} else {
t_info("bad format at line %d\n", line);
}
@@ -1830,8 +1829,7 @@ test_dns_name_totext(char *test_name, isc_boolean_t omit_final) {
/*
* Out of the data file to dns_name1.
*/
- dns_result = dns_name_fromtext(&dns_name1, &buf1, NULL, ISC_FALSE,
- &buf2);
+ dns_result = dns_name_fromtext(&dns_name1, &buf1, NULL, 0, &buf2);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed, result == %s\n",
dns_result_totext(dns_result));
@@ -1855,8 +1853,7 @@ test_dns_name_totext(char *test_name, isc_boolean_t omit_final) {
*/
dns_name_init(&dns_name2, NULL);
isc_buffer_init(&buf3, junk3, BUFLEN);
- dns_result = dns_name_fromtext(&dns_name2, &buf1, NULL, ISC_FALSE,
- &buf3);
+ dns_result = dns_name_fromtext(&dns_name2, &buf1, NULL, 0, &buf3);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed, result == %s\n",
dns_result_totext(dns_result));
@@ -2195,8 +2192,7 @@ test_dns_name_towire(char *testname, unsigned int dc_method, char *exp_data,
isc_buffer_init(&iscbuf1, testname, len);
isc_buffer_add(&iscbuf1, len);
isc_buffer_init(&iscbuf2, buf2, BUFLEN);
- dns_result = dns_name_fromtext(&dns_name, &iscbuf1, NULL, ISC_FALSE,
- &iscbuf2);
+ dns_result = dns_name_fromtext(&dns_name, &iscbuf1, NULL, 0, &iscbuf2);
if (dns_result == ISC_R_SUCCESS) {
isc_buffer_init(&iscbuf3, buf3, buflen);
dns_result = dns_name_towire(&dns_name, &cctx, &iscbuf3);
diff --git a/bin/tests/net/Makefile.in b/bin/tests/net/Makefile.in
index 0c75c28b..59660f05 100644
--- a/bin/tests/net/Makefile.in
+++ b/bin/tests/net/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.16 2007/06/19 23:47:00 tbox Exp $
+# $Id: Makefile.in,v 1.18 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../../lib/isc/libisc.@A@
diff --git a/bin/tests/nsecify.c b/bin/tests/nsecify.c
index 2e055c66..d21b9fdd 100644
--- a/bin/tests/nsecify.c
+++ b/bin/tests/nsecify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsecify.c,v 1.8 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: nsecify.c,v 1.10 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -139,7 +139,7 @@ nsecify(char *filename) {
len = strlen(origintext);
isc_buffer_init(&b, origintext, len);
isc_buffer_add(&b, len);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext()");
db = NULL;
diff --git a/bin/tests/rbt/Makefile.in b/bin/tests/rbt/Makefile.in
index d551297b..fbf3c1d6 100644
--- a/bin/tests/rbt/Makefile.in
+++ b/bin/tests/rbt/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.28 2007/06/19 23:47:00 tbox Exp $
+# $Id: Makefile.in,v 1.30 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
# Note that we do not want to use libtool for libt_api
diff --git a/bin/tests/rbt/t_rbt.c b/bin/tests/rbt/t_rbt.c
index 848e2624..55ebfd2b 100644
--- a/bin/tests/rbt/t_rbt.c
+++ b/bin/tests/rbt/t_rbt.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: t_rbt.c,v 1.32 2009/01/22 23:47:54 tbox Exp $ */
+/* $Id: t_rbt.c,v 1.33 2009/09/01 00:22:25 jinmei Exp $ */
#include <config.h>
@@ -152,7 +152,7 @@ create_name(char *s, isc_mem_t *mctx, dns_name_t **dns_name) {
isc_buffer_init(&target, name + 1, DNSNAMELEN);
result = dns_name_fromtext(name, &source, dns_rootname,
- ISC_FALSE, &target);
+ 0, &target);
if (result != ISC_R_SUCCESS) {
++nfails;
@@ -832,7 +832,7 @@ t_dns_rbtnodechain_init(char *dbfile, char *findname,
dns_fixedname_init(&dns_nextname);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
- &isc_buffer, NULL, ISC_FALSE, NULL);
+ &isc_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
@@ -1494,7 +1494,7 @@ t_dns_rbtnodechain_next(char *dbfile, char *findname,
dns_fixedname_init(&dns_origin);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
- &isc_buffer, NULL, ISC_FALSE, NULL);
+ &isc_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
@@ -1701,7 +1701,7 @@ t_dns_rbtnodechain_prev(char *dbfile, char *findname, char *prevname,
dns_fixedname_init(&dns_origin);
dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
- &isc_buffer, NULL, ISC_FALSE, NULL);
+ &isc_buffer, NULL, 0, NULL);
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
diff --git a/bin/tests/rbt_test.c b/bin/tests/rbt_test.c
index ac8db14e..39039b3b 100644
--- a/bin/tests/rbt_test.c
+++ b/bin/tests/rbt_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt_test.c,v 1.48 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: rbt_test.c,v 1.50 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -71,8 +71,7 @@ create_name(char *s) {
dns_name_init(name, NULL);
isc_buffer_init(&target, name + 1, DNSNAMELEN);
- result = dns_name_fromtext(name, &source, dns_rootname,
- ISC_FALSE, &target);
+ result = dns_name_fromtext(name, &source, dns_rootname, 0, &target);
if (result != ISC_R_SUCCESS) {
printf("dns_name_fromtext(%s) failed: %s\n",
diff --git a/bin/tests/sig0_test.c b/bin/tests/sig0_test.c
index f36bbee0..296356af 100644
--- a/bin/tests/sig0_test.c
+++ b/bin/tests/sig0_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sig0_test.c,v 1.17 2008/07/22 23:47:04 tbox Exp $ */
+/* $Id: sig0_test.c,v 1.19 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -157,8 +157,7 @@ buildquery(void) {
isc_buffer_add(&namesrc, strlen(nametext));
isc_buffer_init(&namedst, namedata, sizeof(namedata));
dns_name_init(qname, NULL);
- result = dns_name_fromtext(qname, &namesrc, dns_rootname, ISC_FALSE,
- &namedst);
+ result = dns_name_fromtext(qname, &namesrc, dns_rootname, 0, &namedst);
CHECK("dns_name_fromtext", result);
ISC_LIST_APPEND(qname->list, question, link);
dns_message_addname(query, qname, DNS_SECTION_QUESTION);
@@ -264,7 +263,7 @@ main(int argc, char *argv[]) {
name = dns_fixedname_name(&fname);
isc_buffer_init(&b, "child.example.", strlen("child.example."));
isc_buffer_add(&b, strlen("child.example."));
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
CHECK("dns_name_fromtext", result);
key = NULL;
diff --git a/bin/tests/sockaddr/Makefile.in b/bin/tests/sockaddr/Makefile.in
index cdb3626e..83b76f11 100644
--- a/bin/tests/sockaddr/Makefile.in
+++ b/bin/tests/sockaddr/Makefile.in
@@ -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 2009/02/06 23:47:42 tbox Exp $
+# $Id: Makefile.in,v 1.24 2009/09/01 00:22:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
diff --git a/bin/tests/system/lwresd/Makefile.in b/bin/tests/system/lwresd/Makefile.in
index 807349dd..d81598c8 100644
--- a/bin/tests/system/lwresd/Makefile.in
+++ b/bin/tests/system/lwresd/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.19 2007/06/19 23:47:03 tbox Exp $
+# $Id: Makefile.in,v 1.21 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,7 +25,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${LWRES_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
LWRESLIBS = ../../../../lib/lwres/liblwres.@A@
diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh
index 0fe02c49..4de05ba9 100644
--- a/bin/tests/system/nsupdate/tests.sh
+++ b/bin/tests/system/nsupdate/tests.sh
@@ -15,13 +15,31 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.27 2009/07/29 23:47:43 tbox Exp $
+# $Id: tests.sh,v 1.28 2009/09/04 17:14:58 each Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
+# wait for zone transfer to complete
+tries=0
+while true; do
+ if [ $tries -eq 10 ]
+ then
+ exit 1
+ fi
+
+ if grep "example.nil/IN.*Transfer completed" ns2/named.run > /dev/null
+ then
+ break
+ else
+ echo "I:zones are not fully loaded, waiting..."
+ tries=`expr $tries + 1`
+ sleep 1
+ fi
+done
+
echo "I:fetching first copy of zone before update"
$DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
@10.53.0.1 axfr -p 5300 > dig.out.ns1 || status=1
diff --git a/bin/tests/system/tkey/Makefile.in b/bin/tests/system/tkey/Makefile.in
index 684fb1a6..84996c0a 100644
--- a/bin/tests/system/tkey/Makefile.in
+++ b/bin/tests/system/tkey/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001, 2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.11 2007/06/19 23:47:06 tbox Exp $
+# $Id: Makefile.in,v 1.13 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,7 +25,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
DNSLIBS = ../../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
index cbb27d31..23e6d424 100644
--- a/bin/tests/system/tkey/keycreate.c
+++ b/bin/tests/system/tkey/keycreate.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: keycreate.c,v 1.17 2009/07/19 23:47:55 tbox Exp $ */
+/* $Id: keycreate.c,v 1.18 2009/09/01 00:22:25 jinmei Exp $ */
#include <config.h>
@@ -153,14 +153,14 @@ sendquery(isc_task_t *task, isc_event_t *event) {
isc_buffer_init(&namestr, "tkeytest.", 9);
isc_buffer_add(&namestr, 9);
result = dns_name_fromtext(dns_fixedname_name(&keyname), &namestr,
- NULL, ISC_FALSE, NULL);
+ NULL, 0, NULL);
CHECK("dns_name_fromtext", result);
dns_fixedname_init(&ownername);
isc_buffer_init(&namestr, ownername_str, strlen(ownername_str));
isc_buffer_add(&namestr, strlen(ownername_str));
result = dns_name_fromtext(dns_fixedname_name(&ownername), &namestr,
- NULL, ISC_FALSE, NULL);
+ NULL, 0, NULL);
CHECK("dns_name_fromtext", result);
isc_buffer_init(&keybuf, keydata, 9);
diff --git a/bin/tests/tasks/Makefile.in b/bin/tests/tasks/Makefile.in
index 8f6e236d..8806b6a8 100644
--- a/bin/tests/tasks/Makefile.in
+++ b/bin/tests/tasks/Makefile.in
@@ -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.32 2009/02/06 23:47:42 tbox Exp $
+# $Id: Makefile.in,v 1.33 2009/09/01 00:22:26 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
diff --git a/bin/tests/timers/Makefile.in b/bin/tests/timers/Makefile.in
index 19c083d6..79240677 100644
--- a/bin/tests/timers/Makefile.in
+++ b/bin/tests/timers/Makefile.in
@@ -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.30 2009/02/06 23:47:42 tbox Exp $
+# $Id: Makefile.in,v 1.31 2009/09/01 00:22:26 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${TEST_INCLUDES} ${ISC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
diff --git a/bin/tests/zone_test.c b/bin/tests/zone_test.c
index 7983bbaa..8ce005d0 100644
--- a/bin/tests/zone_test.c
+++ b/bin/tests/zone_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone_test.c,v 1.33 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: zone_test.c,v 1.35 2009/09/02 23:48:01 tbox Exp $ */
#include <config.h>
@@ -104,7 +104,7 @@ setup(const char *zonename, const char *filename, const char *classname) {
isc_buffer_add(&buffer, strlen(zonename));
dns_fixedname_init(&fixorigin);
result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
- &buffer, dns_rootname, ISC_FALSE, NULL);
+ &buffer, dns_rootname, 0, NULL);
ERRRET(result, "dns_name_fromtext");
origin = dns_fixedname_name(&fixorigin);
@@ -137,19 +137,19 @@ setup(const char *zonename, const char *filename, const char *classname) {
static void
print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset) {
- isc_buffer_t text;
- char t[1000];
- isc_result_t result;
- isc_region_t r;
+ isc_buffer_t text;
+ char t[1000];
+ isc_result_t result;
+ isc_region_t r;
- isc_buffer_init(&text, t, sizeof(t));
- result = dns_rdataset_totext(rdataset, name, ISC_FALSE, ISC_FALSE,
+ isc_buffer_init(&text, t, sizeof(t));
+ result = dns_rdataset_totext(rdataset, name, ISC_FALSE, ISC_FALSE,
&text);
- isc_buffer_usedregion(&text, &r);
- if (result == ISC_R_SUCCESS)
- printf("%.*s", (int)r.length, (char *)r.base);
- else
- printf("%s\n", dns_result_totext(result));
+ isc_buffer_usedregion(&text, &r);
+ if (result == ISC_R_SUCCESS)
+ printf("%.*s", (int)r.length, (char *)r.base);
+ else
+ printf("%s\n", dns_result_totext(result));
}
static void
@@ -206,7 +206,7 @@ query(void) {
isc_buffer_init(&buffer, buf, strlen(buf));
isc_buffer_add(&buffer, strlen(buf));
result = dns_name_fromtext(dns_fixedname_name(&name),
- &buffer, dns_rootname, ISC_FALSE, NULL);
+ &buffer, dns_rootname, 0, NULL);
ERRCONT(result, "dns_name_fromtext");
result = dns_db_find(db, dns_fixedname_name(&name),
diff --git a/bin/tools/Makefile.in b/bin/tools/Makefile.in
index e244fde4..0ed7b66e 100644
--- a/bin/tools/Makefile.in
+++ b/bin/tools/Makefile.in
@@ -12,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.7 2009/07/21 02:41:01 marka Exp $
+# $Id: Makefile.in,v 1.9 2009/09/01 18:40:25 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,11 +23,12 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
${LWRES_INCLUDES} ${OMAPI_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCLIBS = ../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
@@ -36,7 +37,8 @@ ISCDEPLIBS = ../../lib/isc/libisc.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
-LIBS = @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
SUBDIRS =
@@ -53,13 +55,16 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
arpaname@EXEEXT@: arpaname.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ arpaname.@O@ \
${DNSLIBS} ${ISCLIBS} ${LIBS}
+
journalprint@EXEEXT@: journalprint.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ journalprint.@O@ \
- ${DNSLIBS} ${ISCLIBS} ${LIBS}
+ export BASEOBJS="journalprint.@O@"; \
+ export LIBS0="${DNSLIBS}"; \
+ ${FINALBUILDCMD}
nsec3hash@EXEEXT@: nsec3hash.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsec3hash.@O@ \
- ${DNSLIBS} ${ISCLIBS} ${LIBS}
+ export BASEOBJS="nsec3hash.@O@"; \
+ export LIBS0="${DNSLIBS}"; \
+ ${FINALBUILDCMD}
genrandom@EXEEXT@: genrandom.@O@
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ genrandom.@O@ @GENRANDOMLIB@ ${LIBS}
diff --git a/bin/win32/BINDInstall/BINDInstall.rc b/bin/win32/BINDInstall/BINDInstall.rc
index 8bcb636b..8e947346 100644
--- a/bin/win32/BINDInstall/BINDInstall.rc
+++ b/bin/win32/BINDInstall/BINDInstall.rc
@@ -1,4 +1,4 @@
-//Microsoft Developer Studio generated resource script.
+// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
@@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE
//
-1 TEXTINCLUDE DISCARDABLE
+1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
-2 TEXTINCLUDE DISCARDABLE
+2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
-3 TEXTINCLUDE DISCARDABLE
+3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
@@ -66,73 +66,65 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
-IDR_MAINFRAME ICON DISCARDABLE "res\\BINDInstall.ico"
+IDR_MAINFRAME ICON "res\\BINDInstall.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
-IDD_BINDINSTALL_DIALOG DIALOGEX 0, 0, 210, 301
-STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
- WS_SYSMENU
+IDD_BINDINSTALL_DIALOG DIALOGEX 0, 0, 210, 311
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "BIND 9 Installer"
-FONT 8, "MS Sans Serif",0,0,0x1
+FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
EDITTEXT IDC_TARGETDIR,7,62,196,14,ES_AUTOHSCROLL
EDITTEXT IDC_ACCOUNT_NAME,7,94,196,14,ES_AUTOHSCROLL
- EDITTEXT IDC_ACCOUNT_PASSWORD,7,122,196,14,ES_PASSWORD |
- ES_AUTOHSCROLL
- EDITTEXT IDC_ACCOUNT_PASSWORD_CONFIRM,7,151,196,14,ES_PASSWORD |
- ES_AUTOHSCROLL
+ EDITTEXT IDC_ACCOUNT_PASSWORD,7,122,196,14,ES_PASSWORD | ES_AUTOHSCROLL
+ EDITTEXT IDC_ACCOUNT_PASSWORD_CONFIRM,7,151,196,14,ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "&Install",IDC_INSTALL,153,7,50,14
PUSHBUTTON "E&xit",IDC_EXIT,153,39,50,14
- CONTROL "&Automatic Startup",IDC_AUTO_START,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,14,190,72,10
+ CONTROL "&Tools Only",IDC_TOOLS_ONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,185,72,10
+ CONTROL "&Automatic Startup",IDC_AUTO_START,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,195,72,10
CONTROL "&Keep Config Files After Uninstall",IDC_KEEP_FILES,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,200,116,10
- CONTROL "&Start BIND Service After Install",IDC_START,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,14,210,113,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,205,116,10
+ CONTROL "&Start BIND Service After Install",IDC_START,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,215,113,10
PUSHBUTTON "&Uninstall",IDC_UNINSTALL,153,23,50,14
PUSHBUTTON "Browse",IDC_BROWSE,7,22,50,14
LTEXT "Target Directory:",IDC_STATIC,7,53,54,8
- GROUPBOX "Progress",IDC_STATIC,7,224,196,70
- RTEXT "",IDC_COPY_TAG,14,261,78,8
- LTEXT "",IDC_COPY_FILE,105,261,90,8
- RTEXT "",IDC_SERVICE_TAG,15,271,77,8
- LTEXT "",IDC_REG_SERVICE,105,271,89,8
- RTEXT "",IDC_MESSAGE_TAG,15,281,77,8
- LTEXT "",IDC_REG_MESSAGE,105,281,88,8
- RTEXT "",IDC_DIR_TAG,15,251,77,8
- GROUPBOX "Options",IDC_STATIC,7,172,196,49
- CTEXT "Version Unknown",IDC_VERSION,7,7,61,10,SS_CENTERIMAGE |
- SS_SUNKEN
- RTEXT "Current Operation:",IDC_CURRENT_TAG,34,235,58,8
- LTEXT "",IDC_CURRENT,105,235,90,8
- LTEXT "",IDC_CREATE_DIR,105,251,88,8
+ GROUPBOX "Progress",IDC_STATIC,7,234,196,70
+ RTEXT "",IDC_COPY_TAG,14,271,78,8
+ LTEXT "",IDC_COPY_FILE,105,271,90,8
+ RTEXT "",IDC_SERVICE_TAG,15,281,77,8
+ LTEXT "",IDC_REG_SERVICE,105,281,89,8
+ RTEXT "",IDC_MESSAGE_TAG,15,291,77,8
+ LTEXT "",IDC_REG_MESSAGE,105,291,88,8
+ RTEXT "",IDC_DIR_TAG,15,261,77,8
+ GROUPBOX "Options",IDC_STATIC,7,172,196,60
+ CTEXT "Version Unknown",IDC_VERSION,7,7,61,10,SS_CENTERIMAGE | SS_SUNKEN
+ RTEXT "Current Operation:",IDC_CURRENT_TAG,34,245,58,8
+ LTEXT "",IDC_CURRENT,105,245,90,8
+ LTEXT "",IDC_CREATE_DIR,105,261,88,8
LTEXT "Service Account Name",IDC_STATIC,7,84,74,8
LTEXT "Service Account Password",IDC_STATIC,7,112,86,8
- LTEXT "Confirm Service Account Password",IDC_STATIC,7,140,112,
- 8
+ LTEXT "Confirm Service Account Password",IDC_STATIC,7,140,112,8
END
-IDD_BROWSE DIALOG DISCARDABLE 0, 0, 227, 117
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+IDD_BROWSE DIALOG 0, 0, 227, 117
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Directory"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,170,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,170,24,50,14
- LISTBOX IDC_DIRLIST,7,28,155,82,LBS_SORT | LBS_NOINTEGRALHEIGHT |
- WS_VSCROLL | WS_TABSTOP
+ LISTBOX IDC_DIRLIST,7,28,155,82,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_CURDIR,7,7,155,14,ES_AUTOHSCROLL
- COMBOBOX IDC_DRIVES,170,98,50,74,CBS_DROPDOWNLIST | CBS_SORT |
- WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_DRIVES,170,98,50,74,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
-IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+IDD_DIALOG1 DIALOG 0, 0, 186, 95
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
BEGIN
@@ -141,7 +133,6 @@ BEGIN
END
-#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
@@ -164,18 +155,14 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "Comments", "\0"
- VALUE "CompanyName", "Internet Software Consortium\0"
- VALUE "FileDescription", "ISC BIND Install Utility\0"
- VALUE "FileVersion", "2.0.0\0"
- VALUE "InternalName", "BINDInstall\0"
- VALUE "LegalCopyright", "Copyright © 2000\0"
- VALUE "LegalTrademarks", "\0"
- VALUE "OriginalFilename", "BINDInstall.EXE\0"
- VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "ISC BIND\0"
- VALUE "ProductVersion", "9.3.0\0"
- VALUE "SpecialBuild", "\0"
+ VALUE "CompanyName", "Internet Software Consortium"
+ VALUE "FileDescription", "ISC BIND Install Utility"
+ VALUE "FileVersion", "2.0.0"
+ VALUE "InternalName", "BINDInstall"
+ VALUE "LegalCopyright", "Copyright © 2000"
+ VALUE "OriginalFilename", "BINDInstall.EXE"
+ VALUE "ProductName", "ISC BIND"
+ VALUE "ProductVersion", "9.7.0"
END
END
BLOCK "VarFileInfo"
@@ -184,8 +171,6 @@ BEGIN
END
END
-#endif // !_MAC
-
/////////////////////////////////////////////////////////////////////////////
//
@@ -193,7 +178,7 @@ END
//
#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE
+GUIDELINES DESIGNINFO
BEGIN
IDD_BINDINSTALL_DIALOG, DIALOG
BEGIN
@@ -212,6 +197,7 @@ BEGIN
HORZGUIDE, 265
HORZGUIDE, 275
HORZGUIDE, 285
+ HORZGUIDE, 295
END
IDD_BROWSE, DIALOG
@@ -238,7 +224,7 @@ END
// String Table
//
-STRINGTABLE DISCARDABLE
+STRINGTABLE
BEGIN
IDS_MAINFRAME "BIND 9 Installer"
IDS_CREATEDIR "Directory %s does not exist.\nDo you wish to create it?"
@@ -253,7 +239,7 @@ BEGIN
IDS_UNINSTALL_DONE "BIND Uninstall Completed"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE
BEGIN
IDS_CREATE_KEY "Creating BIND registry key"
IDS_ADD_REMOVE "Setting up Add/Remove Programs entry"
@@ -273,7 +259,7 @@ BEGIN
IDS_START_SERVICE "Starting BIND service"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE
BEGIN
IDS_UNINSTALL_DIR "Remove Directories..."
IDS_UNINSTALL_FILES "Delete Files..."
@@ -293,7 +279,7 @@ BEGIN
IDS_ERR_CREATE_KEY "An error occured while creating registry keys\n(%s)"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE
BEGIN
IDS_ERR_SET_VALUE "An error occured while setting registry key values\n(%s)"
IDS_NO_VERSION "Version Unknown"
diff --git a/bin/win32/BINDInstall/BINDInstallDlg.cpp b/bin/win32/BINDInstall/BINDInstallDlg.cpp
index 2a43a85f..a0976641 100644
--- a/bin/win32/BINDInstall/BINDInstallDlg.cpp
+++ b/bin/win32/BINDInstall/BINDInstallDlg.cpp
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: BINDInstallDlg.cpp,v 1.42 2009/07/17 06:25:42 each Exp $ */
+/* $Id: BINDInstallDlg.cpp,v 1.44 2009/09/01 06:51:47 marka Exp $ */
/*
* Copyright (c) 1999-2000 by Nortel Networks Corporation
@@ -69,6 +69,8 @@
#define MAX_GROUPS 100
#define MAX_PRIVS 50
+#define LOCAL_SERVICE "NT AUTHORITY\\LocalService"
+
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
@@ -102,61 +104,60 @@ typedef struct _filedata {
int destination;
int importance;
BOOL checkVer;
-
+ BOOL withTools;
} FileData;
const FileData installFiles[] =
{
#ifdef BINARIES_INSTALL
# ifdef DEBUG_BINARIES
- {"msvcrtd.dll", FileData::WinSystem, FileData::Critical, TRUE},
+ {"msvcrtd.dll", FileData::WinSystem, FileData::Critical, TRUE, TRUE},
# endif
# ifdef RELEASE_BINARIES
- {"msvcrt.dll", FileData::WinSystem, FileData::Critical, TRUE},
+ {"msvcrt.dll", FileData::WinSystem, FileData::Critical, TRUE, TRUE},
# endif
#endif
#if _MSC_VER < 1400
#if _MSC_VER >= 1310
- {"mfc71.dll", FileData::WinSystem, FileData::Critical, TRUE},
- {"msvcr71.dll", FileData::WinSystem, FileData::Critical, TRUE},
+ {"mfc71.dll", FileData::WinSystem, FileData::Critical, TRUE, TRUE},
+ {"msvcr71.dll", FileData::WinSystem, FileData::Critical, TRUE, TRUE},
#elif _MSC_VER > 1200 && _MSC_VER < 1310
- {"mfc70.dll", FileData::WinSystem, FileData::Critical, TRUE},
- {"msvcr70.dll", FileData::WinSystem, FileData::Critical, TRUE},
+ {"mfc70.dll", FileData::WinSystem, FileData::Critical, TRUE, TRUE},
+ {"msvcr70.dll", FileData::WinSystem, FileData::Critical, TRUE, TRUE},
#endif
#endif
- {"bindevt.dll", FileData::BinDir, FileData::Normal, FALSE},
- {"libbind9.dll", FileData::BinDir, FileData::Critical, FALSE},
- {"libisc.dll", FileData::BinDir, FileData::Critical, FALSE},
- {"libisccfg.dll", FileData::BinDir, FileData::Critical, FALSE},
- {"libisccc.dll", FileData::BinDir, FileData::Critical, FALSE},
- {"libdns.dll", FileData::BinDir, FileData::Critical, FALSE},
- {"liblwres.dll", FileData::BinDir, FileData::Critical, FALSE},
- {"libeay32.dll", FileData::BinDir, FileData::Critical, FALSE},
+ {"bindevt.dll", FileData::BinDir, FileData::Normal, FALSE, TRUE},
+ {"libbind9.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
+ {"libisc.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
+ {"libisccfg.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
+ {"libisccc.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
+ {"libdns.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
+ {"liblwres.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
+ {"libeay32.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
#ifdef HAVE_LIBXML2
- {"libxml2.dll", FileData::BinDir, FileData::Critical, FALSE},
+ {"libxml2.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
#endif
- {"named.exe", FileData::BinDir, FileData::Critical, FALSE},
- {"nsupdate.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"BINDInstall.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"rndc.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"dig.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"host.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"nslookup.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"rndc-confgen.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"ddns-confgen.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"dnssec-keygen.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"dnssec-signzone.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"dnssec-dsfromkey.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"dnssec-keyfromlabel.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"dnssec-revoke.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"named-checkconf.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"named-checkzone.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"named-compilezone.exe", FileData::BinDir, FileData::Normal, FALSE},
- {"readme1st.txt", FileData::BinDir, FileData::Trivial, FALSE},
+ {"named.exe", FileData::BinDir, FileData::Critical, FALSE, FALSE},
+ {"nsupdate.exe", FileData::BinDir, FileData::Normal, FALSE, TRUE},
+ {"BINDInstall.exe", FileData::BinDir, FileData::Normal, FALSE, TRUE},
+ {"rndc.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"dig.exe", FileData::BinDir, FileData::Normal, FALSE, TRUE},
+ {"host.exe", FileData::BinDir, FileData::Normal, FALSE, TRUE},
+ {"nslookup.exe", FileData::BinDir, FileData::Normal, FALSE, TRUE},
+ {"rndc-confgen.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"ddns-confgen.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"dnssec-keygen.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"dnssec-signzone.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"dnssec-dsfromkey.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"dnssec-keyfromlabel.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"dnssec-revoke.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"named-checkconf.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"named-checkzone.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"named-compilezone.exe", FileData::BinDir, FileData::Normal, FALSE, FALSE},
+ {"readme1st.txt", FileData::BinDir, FileData::Trivial, FALSE, TRUE},
{NULL, -1, -1}
};
-
/////////////////////////////////////////////////////////////////////////////
// CBINDInstallDlg dialog
@@ -167,6 +168,7 @@ CBINDInstallDlg::CBINDInstallDlg(CWnd* pParent /*=NULL*/)
//{{AFX_DATA_INIT(CBINDInstallDlg)
m_targetDir = _T("");
m_version = _T("");
+ m_toolsOnly = FALSE;
m_autoStart = FALSE;
m_keepFiles = FALSE;
m_current = _T("");
@@ -201,6 +203,7 @@ void CBINDInstallDlg::DoDataExchange(CDataExchange* pDX) {
DDX_Text(pDX, IDC_ACCOUNT_NAME, m_accountName);
DDX_Text(pDX, IDC_ACCOUNT_PASSWORD, m_accountPassword);
DDX_Text(pDX, IDC_ACCOUNT_PASSWORD_CONFIRM, m_accountPasswordConfirm);
+ DDX_Check(pDX, IDC_TOOLS_ONLY, m_toolsOnly);
DDX_Check(pDX, IDC_AUTO_START, m_autoStart);
DDX_Check(pDX, IDC_KEEP_FILES, m_keepFiles);
DDX_Text(pDX, IDC_CURRENT, m_current);
@@ -409,48 +412,55 @@ void CBINDInstallDlg::OnInstall() {
UpdateData();
- /*
- * Check that the Passwords entered match.
- */
- if (m_accountPassword != m_accountPasswordConfirm) {
- MsgBox(IDS_ERR_PASSWORD);
- return;
- }
+ if (!m_toolsOnly && m_accountName != LOCAL_SERVICE) {
+ /*
+ * Check that the Passwords entered match.
+ */
+ if (m_accountPassword != m_accountPasswordConfirm) {
+ MsgBox(IDS_ERR_PASSWORD);
+ return;
+ }
- /*
- * Check that there is not leading / trailing whitespace.
- * This is for compatibility with the standard password dialog.
- * Passwords really should be treated as opaque blobs.
- */
- oldlen = m_accountPassword.GetLength();
- m_accountPassword.TrimLeft();
- m_accountPassword.TrimRight();
- if (m_accountPassword.GetLength() != oldlen) {
- MsgBox(IDS_ERR_WHITESPACE);
- return;
- }
+ /*
+ * Check that there is not leading / trailing whitespace.
+ * This is for compatibility with the standard password dialog.
+ * Passwords really should be treated as opaque blobs.
+ */
+ oldlen = m_accountPassword.GetLength();
+ m_accountPassword.TrimLeft();
+ m_accountPassword.TrimRight();
+ if (m_accountPassword.GetLength() != oldlen) {
+ MsgBox(IDS_ERR_WHITESPACE);
+ return;
+ }
- /*
- * Check the entered account name.
- */
- if (ValidateServiceAccount() == FALSE)
- return;
+ /*
+ * Check the entered account name.
+ */
+ if (ValidateServiceAccount() == FALSE)
+ return;
- /*
- * For Registration we need to know if account was changed.
- */
- if (m_accountName != m_currentAccount)
- m_accountUsed = FALSE;
+ /*
+ * For Registration we need to know if account was changed.
+ */
+ if (m_accountName != m_currentAccount)
+ m_accountUsed = FALSE;
- if (m_accountUsed == FALSE && m_serviceExists == FALSE)
- {
- /*
- * Check that the Password is not null.
- */
- if (m_accountPassword.GetLength() == 0) {
- MsgBox(IDS_ERR_NULLPASSWORD);
- return;
+ if (m_accountUsed == FALSE && m_serviceExists == FALSE)
+ {
+ /*
+ * Check that the Password is not null.
+ */
+ if (m_accountPassword.GetLength() == 0) {
+ MsgBox(IDS_ERR_NULLPASSWORD);
+ return;
+ }
}
+ } else if (m_accountName == LOCAL_SERVICE) {
+ /* The LocalService always exists. */
+ m_accountExists = TRUE;
+ if (m_accountName != m_currentAccount)
+ m_accountUsed = FALSE;
}
/* Directories */
@@ -473,14 +483,16 @@ void CBINDInstallDlg::OnInstall() {
}
}
- if (m_accountExists == FALSE) {
- success = CreateServiceAccount(m_accountName.GetBuffer(30),
- m_accountPassword.GetBuffer(30));
- if (success == FALSE) {
- MsgBox(IDS_CREATEACCOUNT_FAILED);
- return;
+ if (!m_toolsOnly) {
+ if (m_accountExists == FALSE) {
+ success = CreateServiceAccount(m_accountName.GetBuffer(30),
+ m_accountPassword.GetBuffer(30));
+ if (success == FALSE) {
+ MsgBox(IDS_CREATEACCOUNT_FAILED);
+ return;
+ }
+ m_accountExists = TRUE;
}
- m_accountExists = TRUE;
}
ProgramGroup(FALSE);
@@ -505,7 +517,8 @@ void CBINDInstallDlg::OnInstall() {
try {
CreateDirs();
CopyFiles();
- RegisterService();
+ if (!m_toolsOnly)
+ RegisterService();
RegisterMessages();
HKEY hKey;
@@ -606,6 +619,8 @@ void CBINDInstallDlg::CopyFiles() {
CString destFile;
for (int i = 0; installFiles[i].filename; i++) {
+ if (m_toolsOnly && !installFiles[i].withTools)
+ continue;
SetCurrent(IDS_COPY_FILE, installFiles[i].filename);
destFile = DestDir(installFiles[i].destination) + "\\" +
@@ -720,13 +735,16 @@ CBINDInstallDlg::GetCurrentServiceAccountName() {
}
RegCloseKey(hKey);
- if(keyFound == FALSE)
+ if (keyFound == FALSE)
m_accountName = "";
- else {
- /*
- * LocalSystem is not a regular account and is equivalent
- * to no account but with lots of privileges
- */
+ else if (!strcmp(accountName, LOCAL_SERVICE)) {
+ m_accountName = LOCAL_SERVICE;
+ m_accountUsed = TRUE;
+ } else {
+ /*
+ * LocalSystem is not a regular account and is equivalent
+ * to no account but with lots of privileges
+ */
Tmp = accountName;
if (Tmp == ".\\LocalSystem")
m_accountName = "";
@@ -782,20 +800,23 @@ void
CBINDInstallDlg::RegisterService() {
SC_HANDLE hSCManager;
SC_HANDLE hService;
- CString StartName = ".\\" + m_accountName;
+ CString StartName;
+ if (m_accountName == LOCAL_SERVICE)
+ StartName = LOCAL_SERVICE;
+ else
+ StartName = ".\\" + m_accountName;
/*
* We need to change the service rather than create it
* if the service already exists. Do nothing if we are already
* using that account
*/
- if(m_serviceExists == TRUE) {
- if(m_accountUsed == FALSE) {
- UpdateService();
+ if (m_serviceExists == TRUE) {
+ if (m_accountUsed == FALSE) {
+ UpdateService(StartName);
SetItemStatus(IDC_REG_SERVICE);
return;
- }
- else {
+ } else {
SetItemStatus(IDC_REG_SERVICE);
return;
}
@@ -834,10 +855,12 @@ CBINDInstallDlg::RegisterService() {
}
void
-CBINDInstallDlg::UpdateService() {
+CBINDInstallDlg::UpdateService(CString StartName) {
SC_HANDLE hSCManager;
SC_HANDLE hService;
- CString StartName = ".\\" + m_accountName;
+
+ if(m_toolsOnly)
+ return;
SetCurrent(IDS_OPEN_SCM);
hSCManager= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
@@ -864,11 +887,10 @@ CBINDInstallDlg::UpdateService() {
if (hSCManager)
CloseServiceHandle(hSCManager);
return;
- }
- else {
+ } else {
if (ChangeServiceConfig(hService, dwServiceType, dwStart,
SERVICE_ERROR_NORMAL, namedLoc, NULL, NULL, NULL,
- StartName, m_accountPassword,BIND_DISPLAY_NAME)
+ StartName, m_accountPassword, BIND_DISPLAY_NAME)
!= TRUE) {
DWORD err = GetLastError();
MsgBox(IDS_ERR_UPDATE_SERVICE, GetErrMessage());
diff --git a/bin/win32/BINDInstall/BINDInstallDlg.h b/bin/win32/BINDInstall/BINDInstallDlg.h
index 597f7a36..9cbc4c4c 100644
--- a/bin/win32/BINDInstall/BINDInstallDlg.h
+++ b/bin/win32/BINDInstall/BINDInstallDlg.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: BINDInstallDlg.h,v 1.8 2007/06/19 23:47:07 tbox Exp $ */
+/* $Id: BINDInstallDlg.h,v 1.11 2009/09/01 06:51:47 marka Exp $ */
/*
* Copyright (c) 1999-2000 by Nortel Networks Corporation
@@ -48,6 +48,7 @@ public:
CString m_version;
BOOL m_autoStart;
BOOL m_keepFiles;
+ BOOL m_toolsOnly;
CString m_current;
BOOL m_startOnInstall;
//}}AFX_DATA
@@ -72,12 +73,12 @@ protected:
void DeleteFiles(BOOL uninstall);
void RegisterService();
- void UpdateService();
+ void UpdateService(CString StartName);
void UnregisterService(BOOL uninstall);
void RegisterMessages();
void UnregisterMessages(BOOL uninstall);
-
+
void FailedInstall();
void SetItemStatus(UINT nID, BOOL bSuccess = TRUE);
@@ -91,7 +92,7 @@ protected:
BOOL CheckBINDService();
void SetCurrent(int id, ...);
void ProgramGroup(BOOL create = TRUE);
-
+
HICON m_hIcon;
CString m_defaultDir;
CString m_etcDir;
@@ -106,7 +107,7 @@ protected:
CString m_accountPasswordConfirm;
CString m_accountPassword;
BOOL m_serviceExists;
-
+
// Generated message map functions
//{{AFX_MSG(CBINDInstallDlg)
virtual BOOL OnInitDialog();
diff --git a/bin/win32/BINDInstall/resource.h b/bin/win32/BINDInstall/resource.h
index 14b50846..b176fe09 100644
--- a/bin/win32/BINDInstall/resource.h
+++ b/bin/win32/BINDInstall/resource.h
@@ -90,6 +90,7 @@
#define IDC_ACCOUNT_NAME 1030
#define IDC_ACCOUNT_PASSWORD 1031
#define IDC_ACCOUNT_PASSWORD_CONFIRM 1032
+#define IDC_TOOLS_ONLY 1033
// Next default values for new objects
//
diff --git a/bind.keys b/bind.keys
index 0f14287d..511dff4f 100644
--- a/bind.keys
+++ b/bind.keys
@@ -1,5 +1,6 @@
-trusted-keys {
- # NOTE: This key expires September 2009
- # Go to https://www.isc.org/solutions/dlv to download a replacement
- dlv.isc.org. 257 3 5 "BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh";
+managed-keys {
+ # NOTE: This key is current as of September 2009.
+ # If it fails to initialize correctly, it may have expired;
+ # see https://www.isc.org/solutions/dlv for a replacement.
+ dlv.isc.org. initial-key 257 3 5 "BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh";
};
diff --git a/config.h.in b/config.h.in
index 8d576629..cc78c6d3 100644
--- a/config.h.in
+++ b/config.h.in
@@ -16,7 +16,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.h.in,v 1.116 2009/07/14 22:39:30 each Exp $ */
+/* $Id: config.h.in,v 1.120 2009/09/01 18:40:25 jinmei Exp $ */
/*! \file */
@@ -292,6 +292,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Defined if extern char *optarg is not declared. */
#undef NEED_OPTARG
+/* Define to the buffer length type used by getnameinfo(3). */
+#undef IRS_GETNAMEINFO_BUFLEN_T
+
+/* Define to the flags type used by getnameinfo(3). */
+#undef IRS_GETNAMEINFO_FLAGS_T
+
+/* Define to the return type of gai_strerror(3). */
+#undef IRS_GAISTRERROR_RETURN_T
+
/* Define if connect does not honour the permission on the UNIX domain socket.
*/
#undef NEED_SECURE_DIRECTORY
@@ -325,6 +334,9 @@ int sigwait(const unsigned int *set, int *sig);
non-blocking. */
#undef USE_FIONBIO_IOCTL
+/** define if the system have backtrace function. */
+#undef HAVE_LIBCTRACE
+
/* define if idnkit support is to be included. */
#undef WITH_IDN
diff --git a/config.h.win32 b/config.h.win32
index 962ffe2b..301d2871 100644
--- a/config.h.win32
+++ b/config.h.win32
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.h.win32,v 1.21 2009/07/17 23:47:40 tbox Exp $ */
+/* $Id: config.h.win32,v 1.22 2009/09/02 23:43:54 each Exp $ */
/*
* win32 configuration file
@@ -51,7 +51,10 @@
/*
* Windows NT and 2K only
*/
+#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
+#endif
+
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -239,3 +242,9 @@ typedef long off_t;
* Define if libxml2 is present
*/
#define HAVE_LIBXML2 1
+
+/*
+ * Define when building BIND9. When building exportable versions
+ * of libisc, libdns, etc, this must be removed.
+ */
+#define BIND9 1
diff --git a/configure b/configure
index 7e0b0d5e..c5409f3b 100755
--- a/configure
+++ b/configure
@@ -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.458 2009/07/14 22:39:30 each Exp $
+# $Id: configure,v 1.463 2009/09/04 00:46:09 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.472 .
+# From configure.in Revision: 1.476 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61.
#
@@ -909,6 +909,9 @@ MKDEPPROG
IRIX_DNSSEC_WARNINGS_HACK
purify_path
PURIFY
+ISC_PLATFORM_USEBACKTRACE
+MKSYMTBL_PROGRAM
+ALWAYS_MAKE_SYMTABLE
O
A
SA
@@ -918,6 +921,10 @@ LIBTOOL_MODE_INSTALL
LIBTOOL_MODE_LINK
LIBTOOL_ALLOW_UNDEFINED
LIBTOOL_IN_MAIN
+LIBEXPORT
+BIND9_CO_RULE
+export_libdir
+export_includedir
ISC_PLATFORM_HAVEIPV6
LWRES_PLATFORM_HAVEIPV6
ISC_PLATFORM_NEEDNETINETIN6H
@@ -947,6 +954,7 @@ LWRES_PLATFORM_HAVESALEN
ISC_PLATFORM_MSGHDRFLAVOR
ISC_PLATFORM_NEEDPORTT
ISC_LWRES_NEEDADDRINFO
+ISC_IRS_NEEDADDRINFO
ISC_LWRES_NEEDRRSETINFO
ISC_LWRES_SETHOSTENTINT
ISC_LWRES_ENDHOSTENTINT
@@ -958,6 +966,7 @@ ISC_LWRES_NEEDHERRNO
ISC_LWRES_GETIPNODEPROTO
ISC_LWRES_GETADDRINFOPROTO
ISC_LWRES_GETNAMEINFOPROTO
+ISC_IRS_GETNAMEINFOSOCKLEN
ISC_PLATFORM_NEEDSTRSEP
ISC_PLATFORM_NEEDMEMMOVE
ISC_PLATFORM_NEEDSTRTOUL
@@ -980,6 +989,7 @@ ISC_PLATFORM_HAVESYSUNH
ISC_PLATFORM_RLIMITTYPE
ISC_PLATFORM_USEDECLSPEC
LWRES_PLATFORM_USEDECLSPEC
+IRS_PLATFORM_USEDECLSPEC
ISC_PLATFORM_BRACEPTHREADONCEINIT
ISC_PLATFORM_HAVESTRINGSH
ISC_PLATFORM_HAVEIFNAMETOINDEX
@@ -1040,6 +1050,7 @@ LIBISCCFG_API
LIBDNS_API
LIBBIND9_API
LIBLWRES_API
+LIBIRS_API
DLZ_DRIVER_RULES'
ac_precious_vars='build_alias
host_alias
@@ -1642,15 +1653,20 @@ Optional Features:
--enable-openssl-hash use OpenSSL for hash functions [default=no]
--enable-threads enable multithreading
--enable-largefile 64-bit file support
- --enable-ipv6 use IPv6 default=autodetect
- --enable-getifaddrs Enable the use of getifaddrs() [yes|no].
- --disable-isc-spnego use SPNEGO from GSSAPI library
- --disable-chroot disable chroot
- --disable-linux-caps disable linux capabilities
- --enable-atomic enable machine specific atomic operations
- [default=autodetect]
- --enable-fixed-rrset enable fixed rrset ordering
- [default=no]
+ --enable-backtrace log stack backtrace on abort [default=yes]
+ --enable-symtable use internal symbol table for backtrace
+ [all|minimal(default)|none]
+ --enable-exportlib build exportable library (GNU make required)
+ [default=no]
+ --enable-ipv6 use IPv6 default=autodetect
+ --enable-getifaddrs Enable the use of getifaddrs() [yes|no].
+ --disable-isc-spnego use SPNEGO from GSSAPI library
+ --disable-chroot disable chroot
+ --disable-linux-caps disable linux capabilities
+ --enable-atomic enable machine specific atomic operations
+ [default=autodetect]
+ --enable-fixed-rrset enable fixed rrset ordering
+ [default=no]
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1659,21 +1675,27 @@ Optional Packages:
--with-pic try to use only PIC/non-PIC objects [default=use
both]
--with-tags[=TAGS] include additional configurations [automatic]
- --with-openssl=PATH Build with OpenSSL yes|no|path.
+ --with-openssl=PATH Build with OpenSSL yes|no|path.
(Required for DNSSEC)
- --with-pkcs11 Build with PKCS11 support
- --with-gssapi=PATH Specify path for system-supplied GSSAPI
- --with-randomdev=PATH Specify path for random device
+ --with-pkcs11 Build with PKCS11 support
+ --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-libxml2=PATH Build with libxml2 library yes|no|path
- --with-purify=PATH use Rational purify
- --with-libtool use GNU libtool (following indented options supported)
- --with-kame=PATH use Kame IPv6 default path /usr/local/v6
- --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets
- --with-idn=MPREFIX enable IDN support using idnkit default PREFIX
- --with-libiconv=IPREFIX GNU libiconv are in IPREFIX default PREFIX
- --with-iconv=LIBSPEC specify iconv library default -liconv
- --with-idnlib=ARG specify libidnkit
+ --with-libxml2=PATH Build with libxml2 library yes|no|path
+ --with-purify=PATH use Rational purify
+ --with-libtool use GNU libtool
+ --with-export-libdir=PATH
+ installation directory for the export library
+ [EPREFIX/lib/bind9]
+ --with-export-installdir=PATH
+ installation directory for the header files of the
+ export library [PREFIX/include/bind9]
+ --with-kame=PATH use Kame IPv6 default path /usr/local/v6
+ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets
+ --with-idn=MPREFIX enable IDN support using idnkit default PREFIX
+ --with-libiconv=IPREFIX GNU libiconv are in IPREFIX default PREFIX
+ --with-iconv=LIBSPEC specify iconv library default -liconv
+ --with-idnlib=ARG specify libidnkit
--with-dlz-postgres=PATH Build with Postgres DLZ driver yes|no|path.
(Required to use Postgres with DLZ)
--with-dlz-mysql=PATH Build with MySQL DLZ driver yes|no|path.
@@ -3933,7 +3955,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 3936 "configure"' > conftest.$ac_ext
+ echo '#line 3958 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -6881,11 +6903,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:6884: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:6906: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:6888: \$? = $ac_status" >&5
+ echo "$as_me:6910: \$? = $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 other than the usual output.
@@ -7171,11 +7193,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7174: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7196: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7178: \$? = $ac_status" >&5
+ echo "$as_me:7200: \$? = $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 other than the usual output.
@@ -7275,11 +7297,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7278: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7300: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7282: \$? = $ac_status" >&5
+ echo "$as_me:7304: \$? = $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
@@ -9639,7 +9661,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9642 "configure"
+#line 9664 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9739,7 +9761,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9742 "configure"
+#line 9764 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12144,11 +12166,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12147: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12169: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:12151: \$? = $ac_status" >&5
+ echo "$as_me:12173: \$? = $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 other than the usual output.
@@ -12248,11 +12270,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12251: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12273: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:12255: \$? = $ac_status" >&5
+ echo "$as_me:12277: \$? = $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
@@ -13831,11 +13853,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13834: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13856: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13838: \$? = $ac_status" >&5
+ echo "$as_me:13860: \$? = $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 other than the usual output.
@@ -13935,11 +13957,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13938: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13960: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13942: \$? = $ac_status" >&5
+ echo "$as_me:13964: \$? = $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
@@ -16146,11 +16168,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16149: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16171: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16153: \$? = $ac_status" >&5
+ echo "$as_me:16175: \$? = $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 other than the usual output.
@@ -16436,11 +16458,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16439: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16461: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16443: \$? = $ac_status" >&5
+ echo "$as_me:16465: \$? = $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 other than the usual output.
@@ -16540,11 +16562,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16543: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16565: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:16547: \$? = $ac_status" >&5
+ echo "$as_me:16569: \$? = $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
@@ -19333,7 +19355,6 @@ It is available from http://www.isc.org as a separate download." >&2;}
;;
esac
-
#
# Make very sure that these are the first files processed by
# config.status, since we use the processed output as the input for
@@ -19475,6 +19496,8 @@ fi
#
# Perl is optional; it is used only by some of the system test scripts.
+# Note: the backtrace feature (see below) uses perl to build the symbol table,
+# but it still compiles without perl, in which case an empty table will be used.
#
for ac_prog in perl5 perl
do
@@ -25900,6 +25923,108 @@ case $use_libtool in
esac
#
+# enable/disable dumping stack backtrace. Also check if the system supports
+# glibc-compatible backtrace() function.
+#
+# Check whether --enable-backtrace was given.
+if test "${enable_backtrace+set}" = set; then
+ enableval=$enable_backtrace; want_backtrace="$enableval"
+else
+ want_backtrace="yes"
+fi
+
+case $want_backtrace in
+yes)
+ ISC_PLATFORM_USEBACKTRACE="#define ISC_PLATFORM_USEBACKTRACE 1"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <execinfo.h>
+int
+main ()
+{
+return (backtrace((void **)0, 0));
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&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); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBCTRACE
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ ;;
+*)
+ ISC_PLATFORM_USEBACKTRACE="#undef ISC_PLATFORM_USEBACKTRACE"
+ ;;
+esac
+
+
+# Check whether --enable-symtable was given.
+if test "${enable_symtable+set}" = set; then
+ enableval=$enable_symtable; want_symtable="$enableval"
+else
+ want_symtable="minimal"
+fi
+
+case $want_symtable in
+yes|all|minimal)
+
+ if test "$PERL" = ""
+ then
+ { { echo "$as_me:$LINENO: error: Internal symbol table requires perl but no perl is found.
+Install perl or explicitly disable the feature by --disable-symtable." >&5
+echo "$as_me: error: Internal symbol table requires perl but no perl is found.
+Install perl or explicitly disable the feature by --disable-symtable." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test "$use_libtool" = "yes"; then
+ { echo "$as_me:$LINENO: WARNING: Internal symbol table does not work with libtool. Disabling symtbol table." >&5
+echo "$as_me: WARNING: Internal symbol table does not work with libtool. Disabling symtbol table." >&2;}
+ else
+ MKSYMTBL_PROGRAM="$PERL"
+ if test $want_symtable = all; then
+ ALWAYS_MAKE_SYMTABLE="yes"
+ fi
+ fi
+ ;;
+*)
+ ;;
+esac
+
+
+
+#
# File name extension for static archive files, for those few places
# where they are treated differently from dynamic ones.
#
@@ -25916,6 +26041,60 @@ SA=a
#
+# build exportable DNS library?
+#
+# Check whether --enable-exportlib was given.
+if test "${enable_exportlib+set}" = set; then
+ enableval=$enable_exportlib;
+fi
+
+case "$enable_exportlib" in
+ yes)
+ gmake=
+ for x in gmake gnumake make; do
+ if $x --version 2>/dev/null | grep GNU > /dev/null; then
+ gmake=$x
+ break;
+ fi
+ done
+ if test -z "$gmake"; then
+ { { echo "$as_me:$LINENO: error: exportlib requires GNU make. Install it or disable the feature." >&5
+echo "$as_me: error: exportlib requires GNU make. Install it or disable the feature." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ LIBEXPORT=lib/export
+
+ BIND9_CO_RULE="%.$O: \${srcdir}/%.c"
+ ;;
+ no|*)
+ BIND9_CO_RULE=".c.$O:"
+ ;;
+esac
+
+
+
+# Check whether --with-export-libdir was given.
+if test "${with_export_libdir+set}" = set; then
+ withval=$with_export_libdir; export_libdir="$withval"
+fi
+
+if test -z "$export_libdir"; then
+ export_libdir="\${exec_prefix}/lib/bind9/"
+fi
+
+
+
+# Check whether --with-export-installdir was given.
+if test "${with_export_installdir+set}" = set; then
+ withval=$with_export_installdir; export_installdir="$withval"
+fi
+
+if test -z "$export_includedir"; then
+ export_includedir="\${prefix}/include/bind9/"
+fi
+
+
+#
# Here begins a very long section to determine the system's networking
# capabilities. The order of the tests is significant.
#
@@ -26886,6 +27065,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO"
+ ISC_IRS_NEEDADDRINFO="#undef ISC_IRS_NEEDADDRINFO"
cat >>confdefs.h <<\_ACEOF
#define HAVE_ADDRINFO 1
_ACEOF
@@ -26897,11 +27077,13 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"
+ ISC_IRS_NEEDADDRINFO="#define ISC_IRS_NEEDADDRINFO 1"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
#
# Check for rrsetinfo
#
@@ -27307,6 +27489,193 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+#
+# Sadly, the definitions of system-supplied getnameinfo(3) vary. Try to catch
+# known variations here:
+#
+{ echo "$as_me:$LINENO: checking for getnameinfo prototype definitions" >&5
+echo $ECHO_N "checking for getnameinfo prototype definitions... $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 <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ socklen_t, char *, socklen_t, unsigned int);
+int
+main ()
+{
+ return (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&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); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: socklen_t for buflen; u_int for flags" >&5
+echo "${ECHO_T}socklen_t for buflen; u_int for flags" >&6; }
+ cat >>confdefs.h <<\_ACEOF
+#define IRS_GETNAMEINFO_BUFLEN_T socklen_t
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define IRS_GETNAMEINFO_FLAGS_T unsigned int
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ size_t, char *, size_t, int);
+int
+main ()
+{
+ return (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&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); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: size_t for buflen; int for flags" >&5
+echo "${ECHO_T}size_t for buflen; int for flags" >&6; }
+ cat >>confdefs.h <<\_ACEOF
+#define IRS_GETNAMEINFO_BUFLEN_T size_t
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define IRS_GETNAMEINFO_FLAGS_T int
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: not match any subspecies; assume standard definition" >&5
+echo "${ECHO_T}not match any subspecies; assume standard definition" >&6; }
+cat >>confdefs.h <<\_ACEOF
+#define IRS_GETNAMEINFO_BUFLEN_T socklen_t
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
+#define IRS_GETNAMEINFO_FLAGS_T int
+_ACEOF
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+#
+# ...and same for gai_strerror().
+#
+{ echo "$as_me:$LINENO: checking for gai_strerror prototype definitions" >&5
+echo $ECHO_N "checking for gai_strerror prototype definitions... $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 <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+char *gai_strerror(int ecode);
+int
+main ()
+{
+ return (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&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); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: returning char *" >&5
+echo "${ECHO_T}returning char *" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define IRS_GAISTRERROR_RETURN_T char *
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: not match any subspecies; assume standard definition" >&5
+echo "${ECHO_T}not match any subspecies; assume standard definition" >&6; }
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >>confdefs.h <<\_ACEOF
+#define IRS_GAISTRERROR_RETURN_T const char *
+_ACEOF
+
+
{ echo "$as_me:$LINENO: checking for getipnodebyname" >&5
echo $ECHO_N "checking for getipnodebyname... $ECHO_C" >&6; }
if test "${ac_cv_func_getipnodebyname+set}" = set; then
@@ -27664,6 +28033,7 @@ fi
+
# Check whether --enable-getifaddrs was given.
if test "${enable_getifaddrs+set}" = set; then
enableval=$enable_getifaddrs; want_getifaddrs="$enableval"
@@ -30022,6 +30392,8 @@ ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC"
LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC"
+IRS_PLATFORM_USEDECLSPEC="#undef IRS_PLATFORM_USEDECLSPEC"
+
#
# Random remaining OS-specific issues involving compiler warnings.
# XXXDCL print messages to indicate some compensation is being done?
@@ -30630,8 +31002,56 @@ fi
;;
x86_64-*|amd64-*)
- have_xaddq=yes
- arch=x86_64
+if test "$cross_compiling" = yes; then
+ arch=x86_64
+ have_xaddq=yes
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+main() {
+ exit((sizeof(void *) == 8) ? 0 : 1);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ arch=x86_64
+ have_xaddq=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+arch=x86_32
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
;;
alpha*-*)
arch=alpha
@@ -30861,9 +31281,9 @@ else
fi
if test "$have_xaddq" = "yes"; then
- ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
+ ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
else
- ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
+ ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
fi
@@ -31964,6 +32384,9 @@ LIBBIND9_API=$srcdir/lib/bind9/api
LIBLWRES_API=$srcdir/lib/lwres/api
+
+LIBIRS_API=$srcdir/lib/irs/api
+
#
# Configure any DLZ drivers.
#
@@ -32801,7 +33224,7 @@ ac_config_commands="$ac_config_commands chmod"
# elsewhere if there's a good reason for doing so.
#
-ac_config_files="$ac_config_files Makefile make/Makefile make/mkdep lib/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/nls/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/named/Makefile bin/named/unix/Makefile bin/rndc/Makefile bin/dig/Makefile bin/nsupdate/Makefile bin/tests/Makefile bin/tests/names/Makefile bin/tests/master/Makefile bin/tests/rbt/Makefile bin/tests/db/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/dst/Makefile bin/tests/mem/Makefile bin/tests/net/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/lwresd/Makefile bin/tests/system/tkey/Makefile bin/tests/headerdep_test.sh bin/tools/Makefile bin/dnssec/Makefile doc/Makefile doc/arm/Makefile doc/misc/Makefile isc-config.sh doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter"
+ac_config_files="$ac_config_files Makefile make/Makefile make/mkdep lib/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/nls/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/export/Makefile lib/export/isc/Makefile lib/export/isc/include/Makefile lib/export/isc/include/isc/Makefile lib/export/isc/unix/Makefile lib/export/isc/unix/include/Makefile lib/export/isc/unix/include/isc/Makefile lib/export/isc/nls/Makefile lib/export/isc/$thread_dir/Makefile lib/export/isc/$thread_dir/include/Makefile lib/export/isc/$thread_dir/include/isc/Makefile lib/export/dns/Makefile lib/export/dns/include/Makefile lib/export/dns/include/dns/Makefile lib/export/dns/include/dst/Makefile lib/export/irs/Makefile lib/export/irs/include/Makefile lib/export/irs/include/irs/Makefile lib/export/isccfg/Makefile lib/export/isccfg/include/Makefile lib/export/isccfg/include/isccfg/Makefile lib/export/samples/Makefile lib/export/samples/Makefile-postinstall lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/named/Makefile bin/named/unix/Makefile bin/rndc/Makefile bin/dig/Makefile bin/nsupdate/Makefile bin/tests/Makefile bin/tests/names/Makefile bin/tests/master/Makefile bin/tests/rbt/Makefile bin/tests/db/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/dst/Makefile bin/tests/mem/Makefile bin/tests/net/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/lwresd/Makefile bin/tests/system/tkey/Makefile bin/tests/headerdep_test.sh bin/tools/Makefile bin/dnssec/Makefile doc/Makefile doc/arm/Makefile doc/misc/Makefile isc-config.sh doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter"
#
@@ -33395,10 +33818,38 @@ do
"lib/isccfg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccfg/Makefile" ;;
"lib/isccfg/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccfg/include/Makefile" ;;
"lib/isccfg/include/isccfg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccfg/include/isccfg/Makefile" ;;
+ "lib/irs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/irs/Makefile" ;;
+ "lib/irs/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/irs/include/Makefile" ;;
+ "lib/irs/include/irs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/irs/include/irs/Makefile" ;;
+ "lib/irs/include/irs/netdb.h") CONFIG_FILES="$CONFIG_FILES lib/irs/include/irs/netdb.h" ;;
+ "lib/irs/include/irs/platform.h") CONFIG_FILES="$CONFIG_FILES lib/irs/include/irs/platform.h" ;;
"lib/dns/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/Makefile" ;;
"lib/dns/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/include/Makefile" ;;
"lib/dns/include/dns/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/include/dns/Makefile" ;;
"lib/dns/include/dst/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/include/dst/Makefile" ;;
+ "lib/export/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/Makefile" ;;
+ "lib/export/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/Makefile" ;;
+ "lib/export/isc/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/include/Makefile" ;;
+ "lib/export/isc/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/include/isc/Makefile" ;;
+ "lib/export/isc/unix/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/unix/Makefile" ;;
+ "lib/export/isc/unix/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/unix/include/Makefile" ;;
+ "lib/export/isc/unix/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/unix/include/isc/Makefile" ;;
+ "lib/export/isc/nls/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/nls/Makefile" ;;
+ "lib/export/isc/$thread_dir/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/$thread_dir/Makefile" ;;
+ "lib/export/isc/$thread_dir/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/$thread_dir/include/Makefile" ;;
+ "lib/export/isc/$thread_dir/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isc/$thread_dir/include/isc/Makefile" ;;
+ "lib/export/dns/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/dns/Makefile" ;;
+ "lib/export/dns/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/dns/include/Makefile" ;;
+ "lib/export/dns/include/dns/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/dns/include/dns/Makefile" ;;
+ "lib/export/dns/include/dst/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/dns/include/dst/Makefile" ;;
+ "lib/export/irs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/irs/Makefile" ;;
+ "lib/export/irs/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/irs/include/Makefile" ;;
+ "lib/export/irs/include/irs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/irs/include/irs/Makefile" ;;
+ "lib/export/isccfg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isccfg/Makefile" ;;
+ "lib/export/isccfg/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isccfg/include/Makefile" ;;
+ "lib/export/isccfg/include/isccfg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/isccfg/include/isccfg/Makefile" ;;
+ "lib/export/samples/Makefile") CONFIG_FILES="$CONFIG_FILES lib/export/samples/Makefile" ;;
+ "lib/export/samples/Makefile-postinstall") CONFIG_FILES="$CONFIG_FILES lib/export/samples/Makefile-postinstall" ;;
"lib/bind9/Makefile") CONFIG_FILES="$CONFIG_FILES lib/bind9/Makefile" ;;
"lib/bind9/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/bind9/include/Makefile" ;;
"lib/bind9/include/bind9/Makefile") CONFIG_FILES="$CONFIG_FILES lib/bind9/include/bind9/Makefile" ;;
@@ -33587,12 +34038,9 @@ CPP!$CPP$ac_delim
CXX!$CXX$ac_delim
CXXFLAGS!$CXXFLAGS$ac_delim
ac_ct_CXX!$ac_ct_CXX$ac_delim
-CXXCPP!$CXXCPP$ac_delim
-F77!$F77$ac_delim
-FFLAGS!$FFLAGS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 70; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 67; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -33644,6 +34092,10 @@ d
r $LIBLWRES_API
d
}
+/^[ ]*@LIBIRS_API@[ ]*$/{
+r $LIBIRS_API
+d
+}
/^[ ]*@DLZ_DRIVER_RULES@[ ]*$/{
r $DLZ_DRIVER_RULES
d
@@ -33667,6 +34119,9 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+CXXCPP!$CXXCPP$ac_delim
+F77!$F77$ac_delim
+FFLAGS!$FFLAGS$ac_delim
ac_ct_F77!$ac_ct_F77$ac_delim
LIBTOOL!$LIBTOOL$ac_delim
INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
@@ -33708,6 +34163,9 @@ MKDEPPROG!$MKDEPPROG$ac_delim
IRIX_DNSSEC_WARNINGS_HACK!$IRIX_DNSSEC_WARNINGS_HACK$ac_delim
purify_path!$purify_path$ac_delim
PURIFY!$PURIFY$ac_delim
+ISC_PLATFORM_USEBACKTRACE!$ISC_PLATFORM_USEBACKTRACE$ac_delim
+MKSYMTBL_PROGRAM!$MKSYMTBL_PROGRAM$ac_delim
+ALWAYS_MAKE_SYMTABLE!$ALWAYS_MAKE_SYMTABLE$ac_delim
O!$O$ac_delim
A!$A$ac_delim
SA!$SA$ac_delim
@@ -33717,6 +34175,10 @@ LIBTOOL_MODE_INSTALL!$LIBTOOL_MODE_INSTALL$ac_delim
LIBTOOL_MODE_LINK!$LIBTOOL_MODE_LINK$ac_delim
LIBTOOL_ALLOW_UNDEFINED!$LIBTOOL_ALLOW_UNDEFINED$ac_delim
LIBTOOL_IN_MAIN!$LIBTOOL_IN_MAIN$ac_delim
+LIBEXPORT!$LIBEXPORT$ac_delim
+BIND9_CO_RULE!$BIND9_CO_RULE$ac_delim
+export_libdir!$export_libdir$ac_delim
+export_includedir!$export_includedir$ac_delim
ISC_PLATFORM_HAVEIPV6!$ISC_PLATFORM_HAVEIPV6$ac_delim
LWRES_PLATFORM_HAVEIPV6!$LWRES_PLATFORM_HAVEIPV6$ac_delim
ISC_PLATFORM_NEEDNETINETIN6H!$ISC_PLATFORM_NEEDNETINETIN6H$ac_delim
@@ -33746,6 +34208,7 @@ LWRES_PLATFORM_HAVESALEN!$LWRES_PLATFORM_HAVESALEN$ac_delim
ISC_PLATFORM_MSGHDRFLAVOR!$ISC_PLATFORM_MSGHDRFLAVOR$ac_delim
ISC_PLATFORM_NEEDPORTT!$ISC_PLATFORM_NEEDPORTT$ac_delim
ISC_LWRES_NEEDADDRINFO!$ISC_LWRES_NEEDADDRINFO$ac_delim
+ISC_IRS_NEEDADDRINFO!$ISC_IRS_NEEDADDRINFO$ac_delim
ISC_LWRES_NEEDRRSETINFO!$ISC_LWRES_NEEDRRSETINFO$ac_delim
ISC_LWRES_SETHOSTENTINT!$ISC_LWRES_SETHOSTENTINT$ac_delim
ISC_LWRES_ENDHOSTENTINT!$ISC_LWRES_ENDHOSTENTINT$ac_delim
@@ -33753,17 +34216,6 @@ ISC_LWRES_GETNETBYADDRINADDR!$ISC_LWRES_GETNETBYADDRINADDR$ac_delim
ISC_LWRES_SETNETENTINT!$ISC_LWRES_SETNETENTINT$ac_delim
ISC_LWRES_ENDNETENTINT!$ISC_LWRES_ENDNETENTINT$ac_delim
ISC_LWRES_GETHOSTBYADDRVOID!$ISC_LWRES_GETHOSTBYADDRVOID$ac_delim
-ISC_LWRES_NEEDHERRNO!$ISC_LWRES_NEEDHERRNO$ac_delim
-ISC_LWRES_GETIPNODEPROTO!$ISC_LWRES_GETIPNODEPROTO$ac_delim
-ISC_LWRES_GETADDRINFOPROTO!$ISC_LWRES_GETADDRINFOPROTO$ac_delim
-ISC_LWRES_GETNAMEINFOPROTO!$ISC_LWRES_GETNAMEINFOPROTO$ac_delim
-ISC_PLATFORM_NEEDSTRSEP!$ISC_PLATFORM_NEEDSTRSEP$ac_delim
-ISC_PLATFORM_NEEDMEMMOVE!$ISC_PLATFORM_NEEDMEMMOVE$ac_delim
-ISC_PLATFORM_NEEDSTRTOUL!$ISC_PLATFORM_NEEDSTRTOUL$ac_delim
-LWRES_PLATFORM_NEEDSTRTOUL!$LWRES_PLATFORM_NEEDSTRTOUL$ac_delim
-GENRANDOMLIB!$GENRANDOMLIB$ac_delim
-ISC_PLATFORM_NEEDSTRLCPY!$ISC_PLATFORM_NEEDSTRLCPY$ac_delim
-ISC_PLATFORM_NEEDSTRLCAT!$ISC_PLATFORM_NEEDSTRLCAT$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -33805,6 +34257,18 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+ISC_LWRES_NEEDHERRNO!$ISC_LWRES_NEEDHERRNO$ac_delim
+ISC_LWRES_GETIPNODEPROTO!$ISC_LWRES_GETIPNODEPROTO$ac_delim
+ISC_LWRES_GETADDRINFOPROTO!$ISC_LWRES_GETADDRINFOPROTO$ac_delim
+ISC_LWRES_GETNAMEINFOPROTO!$ISC_LWRES_GETNAMEINFOPROTO$ac_delim
+ISC_IRS_GETNAMEINFOSOCKLEN!$ISC_IRS_GETNAMEINFOSOCKLEN$ac_delim
+ISC_PLATFORM_NEEDSTRSEP!$ISC_PLATFORM_NEEDSTRSEP$ac_delim
+ISC_PLATFORM_NEEDMEMMOVE!$ISC_PLATFORM_NEEDMEMMOVE$ac_delim
+ISC_PLATFORM_NEEDSTRTOUL!$ISC_PLATFORM_NEEDSTRTOUL$ac_delim
+LWRES_PLATFORM_NEEDSTRTOUL!$LWRES_PLATFORM_NEEDSTRTOUL$ac_delim
+GENRANDOMLIB!$GENRANDOMLIB$ac_delim
+ISC_PLATFORM_NEEDSTRLCPY!$ISC_PLATFORM_NEEDSTRLCPY$ac_delim
+ISC_PLATFORM_NEEDSTRLCAT!$ISC_PLATFORM_NEEDSTRLCAT$ac_delim
ISC_PLATFORM_NEEDSPRINTF!$ISC_PLATFORM_NEEDSPRINTF$ac_delim
LWRES_PLATFORM_NEEDSPRINTF!$LWRES_PLATFORM_NEEDSPRINTF$ac_delim
ISC_PLATFORM_NEEDVSNPRINTF!$ISC_PLATFORM_NEEDVSNPRINTF$ac_delim
@@ -33820,6 +34284,7 @@ ISC_PLATFORM_HAVESYSUNH!$ISC_PLATFORM_HAVESYSUNH$ac_delim
ISC_PLATFORM_RLIMITTYPE!$ISC_PLATFORM_RLIMITTYPE$ac_delim
ISC_PLATFORM_USEDECLSPEC!$ISC_PLATFORM_USEDECLSPEC$ac_delim
LWRES_PLATFORM_USEDECLSPEC!$LWRES_PLATFORM_USEDECLSPEC$ac_delim
+IRS_PLATFORM_USEDECLSPEC!$IRS_PLATFORM_USEDECLSPEC$ac_delim
ISC_PLATFORM_BRACEPTHREADONCEINIT!$ISC_PLATFORM_BRACEPTHREADONCEINIT$ac_delim
ISC_PLATFORM_HAVESTRINGSH!$ISC_PLATFORM_HAVESTRINGSH$ac_delim
ISC_PLATFORM_HAVEIFNAMETOINDEX!$ISC_PLATFORM_HAVEIFNAMETOINDEX$ac_delim
@@ -33874,7 +34339,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 67; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 80; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 83939cdb..f2b745f8 100644
--- a/configure.in
+++ b/configure.in
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
-AC_REVISION($Revision: 1.472 $)
+AC_REVISION($Revision: 1.477 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
@@ -62,7 +62,6 @@ It is available from http://www.isc.org as a separate download.])
;;
esac
-
#
# Make very sure that these are the first files processed by
# config.status, since we use the processed output as the input for
@@ -112,6 +111,8 @@ AC_SUBST(ETAGS)
#
# Perl is optional; it is used only by some of the system test scripts.
+# Note: the backtrace feature (see below) uses perl to build the symbol table,
+# but it still compiles without perl, in which case an empty table will be used.
#
AC_PATH_PROGS(PERL, perl5 perl)
AC_SUBST(PERL)
@@ -485,7 +486,7 @@ AC_C_BIGENDIAN
OPENSSL_WARNING=
AC_MSG_CHECKING(for OpenSSL library)
AC_ARG_WITH(openssl,
-[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path].
+[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path].
(Required for DNSSEC)],
use_openssl="$withval", use_openssl="auto")
@@ -695,7 +696,7 @@ AC_SUBST(ISC_OPENSSL_INC)
AC_MSG_CHECKING(for PKCS11 support)
AC_ARG_WITH(pkcs11,
-[ --with-pkcs11 Build with PKCS11 support],
+[ --with-pkcs11 Build with PKCS11 support],
use_pkcs11="yes", use_pkcs11="no")
case "$use_pkcs11" in
@@ -713,7 +714,7 @@ AC_SUBST(USE_PKCS11)
AC_MSG_CHECKING(for GSSAPI library)
AC_ARG_WITH(gssapi,
-[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
+[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
use_gssapi="$withval", use_gssapi="no")
gssapidirs="/usr/local /usr/pkg /usr/kerberos /usr"
@@ -867,7 +868,7 @@ AC_SUBST(DNS_CRYPTO_LIBS)
#
AC_MSG_CHECKING(for random device)
AC_ARG_WITH(randomdev,
-[ --with-randomdev=PATH Specify path for random device],
+[ --with-randomdev=PATH Specify path for random device],
use_randomdev="$withval", use_randomdev="unspec")
case "$use_randomdev" in
@@ -1040,7 +1041,7 @@ AC_SUBST(ISC_THREAD_DIR)
#
AC_MSG_CHECKING(for libxml2 library)
AC_ARG_WITH(libxml2,
-[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]],
+[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]],
use_libxml2="$withval", use_libxml2="auto")
case "$use_libxml2" in
@@ -1234,7 +1235,7 @@ esac
#
AC_MSG_CHECKING(whether to use purify)
AC_ARG_WITH(purify,
- [ --with-purify[=PATH] use Rational purify],
+ [ --with-purify[=PATH] use Rational purify],
use_purify="$withval", use_purify="no")
case "$use_purify" in
@@ -1273,7 +1274,7 @@ AC_SUBST(PURIFY)
AC_ARG_WITH(libtool,
- [ --with-libtool use GNU libtool (following indented options supported)],
+ [ --with-libtool use GNU libtool],
use_libtool="$withval", use_libtool="no")
case $use_libtool in
@@ -1308,6 +1309,53 @@ case $use_libtool in
esac
#
+# enable/disable dumping stack backtrace. Also check if the system supports
+# glibc-compatible backtrace() function.
+#
+AC_ARG_ENABLE(backtrace,
+[ --enable-backtrace log stack backtrace on abort [[default=yes]]],
+ want_backtrace="$enableval", want_backtrace="yes")
+case $want_backtrace in
+yes)
+ ISC_PLATFORM_USEBACKTRACE="#define ISC_PLATFORM_USEBACKTRACE 1"
+ AC_TRY_LINK([#include <execinfo.h>],
+ [return (backtrace((void **)0, 0));],
+ [AC_DEFINE([HAVE_LIBCTRACE], [], [if system have backtrace function])],)
+ ;;
+*)
+ ISC_PLATFORM_USEBACKTRACE="#undef ISC_PLATFORM_USEBACKTRACE"
+ ;;
+esac
+AC_SUBST(ISC_PLATFORM_USEBACKTRACE)
+
+AC_ARG_ENABLE(symtable,
+[ --enable-symtable use internal symbol table for backtrace
+ [[all|minimal(default)|none]]],
+ want_symtable="$enableval", want_symtable="minimal")
+case $want_symtable in
+yes|all|minimal)
+
+ if test "$PERL" = ""
+ then
+ AC_MSG_ERROR([Internal symbol table requires perl but no perl is found.
+Install perl or explicitly disable the feature by --disable-symtable.])
+ fi
+ if test "$use_libtool" = "yes"; then
+ AC_MSG_WARN([Internal symbol table does not work with libtool. Disabling symtbol table.])
+ else
+ MKSYMTBL_PROGRAM="$PERL"
+ if test $want_symtable = all; then
+ ALWAYS_MAKE_SYMTABLE="yes"
+ fi
+ fi
+ ;;
+*)
+ ;;
+esac
+AC_SUBST(MKSYMTBL_PROGRAM)
+AC_SUBST(ALWAYS_MAKE_SYMTABLE)
+
+#
# File name extension for static archive files, for those few places
# where they are treated differently from dynamic ones.
#
@@ -1324,6 +1372,54 @@ AC_SUBST(LIBTOOL_ALLOW_UNDEFINED)
AC_SUBST(LIBTOOL_IN_MAIN)
#
+# build exportable DNS library?
+#
+AC_ARG_ENABLE(exportlib,
+ [ --enable-exportlib build exportable library (GNU make required)
+ [[default=no]]])
+case "$enable_exportlib" in
+ yes)
+ gmake=
+ for x in gmake gnumake make; do
+ if $x --version 2>/dev/null | grep GNU > /dev/null; then
+ gmake=$x
+ break;
+ fi
+ done
+ if test -z "$gmake"; then
+ AC_MSG_ERROR([exportlib requires GNU make. Install it or disable the feature.])
+ fi
+ LIBEXPORT=lib/export
+ AC_SUBST(LIBEXPORT)
+ BIND9_CO_RULE="%.$O: \${srcdir}/%.c"
+ ;;
+ no|*)
+ BIND9_CO_RULE=".c.$O:"
+ ;;
+esac
+AC_SUBST(BIND9_CO_RULE)
+
+AC_ARG_WITH(export-libdir,
+ [ --with-export-libdir[=PATH]
+ installation directory for the export library
+ [[EPREFIX/lib/bind9]]],
+ export_libdir="$withval",)
+if test -z "$export_libdir"; then
+ export_libdir="\${exec_prefix}/lib/bind9/"
+fi
+AC_SUBST(export_libdir)
+
+AC_ARG_WITH(export-installdir,
+ [ --with-export-installdir[=PATH]
+ installation directory for the header files of the
+ export library [[PREFIX/include/bind9]]],
+ export_installdir="$withval",)
+if test -z "$export_includedir"; then
+ export_includedir="\${prefix}/include/bind9/"
+fi
+AC_SUBST(export_includedir)
+
+#
# Here begins a very long section to determine the system's networking
# capabilities. The order of the tests is significant.
#
@@ -1332,7 +1428,7 @@ AC_SUBST(LIBTOOL_IN_MAIN)
# IPv6
#
AC_ARG_ENABLE(ipv6,
- [ --enable-ipv6 use IPv6 [default=autodetect]])
+ [ --enable-ipv6 use IPv6 [default=autodetect]])
case "$enable_ipv6" in
yes|''|autodetect)
@@ -1363,7 +1459,7 @@ AC_TRY_COMPILE([
#
AC_MSG_CHECKING(for Kame IPv6 support)
AC_ARG_WITH(kame,
- [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]],
+ [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]],
use_kame="$withval", use_kame="no")
case "$use_kame" in
@@ -1707,10 +1803,13 @@ AC_TRY_COMPILE([
[struct addrinfo a; return (0);],
[AC_MSG_RESULT(yes)
ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO"
+ ISC_IRS_NEEDADDRINFO="#undef ISC_IRS_NEEDADDRINFO"
AC_DEFINE(HAVE_ADDRINFO)],
[AC_MSG_RESULT(no)
- ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"])
+ ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"
+ ISC_IRS_NEEDADDRINFO="#define ISC_IRS_NEEDADDRINFO 1"])
AC_SUBST(ISC_LWRES_NEEDADDRINFO)
+AC_SUBST(ISC_IRS_NEEDADDRINFO)
#
# Check for rrsetinfo
@@ -1797,6 +1896,51 @@ AC_TRY_COMPILE([
ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1"])
AC_SUBST(ISC_LWRES_NEEDHERRNO)
+#
+# Sadly, the definitions of system-supplied getnameinfo(3) vary. Try to catch
+# known variations here:
+#
+AC_MSG_CHECKING(for getnameinfo prototype definitions)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ socklen_t, char *, socklen_t, unsigned int);],
+[ return (0);],
+ [AC_MSG_RESULT(socklen_t for buflen; u_int for flags)
+ AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t)
+ AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, unsigned int)],
+[AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ size_t, char *, size_t, int);],
+[ return (0);],
+ [AC_MSG_RESULT(size_t for buflen; int for flags)
+ AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, size_t)
+ AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)],
+[AC_MSG_RESULT(not match any subspecies; assume standard definition)
+AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t)
+AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)])])
+
+#
+# ...and same for gai_strerror().
+#
+AC_MSG_CHECKING(for gai_strerror prototype definitions)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+char *gai_strerror(int ecode);],
+[ return (0); ],
+ [AC_MSG_RESULT(returning char *)
+ AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [char *],
+ [return type of gai_srerror])],
+[AC_MSG_RESULT(not match any subspecies; assume standard definition)])
+AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [const char *])
+
AC_CHECK_FUNC(getipnodebyname,
[ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO"],
[ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1"])
@@ -1811,9 +1955,10 @@ AC_CHECK_FUNC(gai_strerror, AC_DEFINE(HAVE_GAISTRERROR))
AC_SUBST(ISC_LWRES_GETIPNODEPROTO)
AC_SUBST(ISC_LWRES_GETADDRINFOPROTO)
AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO)
+AC_SUBST(ISC_IRS_GETNAMEINFOSOCKLEN)
AC_ARG_ENABLE(getifaddrs,
-[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
+[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
want_getifaddrs="$enableval", want_getifaddrs="yes")
#
@@ -1935,7 +2080,7 @@ AC_SUBST(ISC_EXTRA_SRCS)
# Use our own SPNEGO implementation?
#
AC_ARG_ENABLE(isc-spnego,
- [ --disable-isc-spnego use SPNEGO from GSSAPI library])
+ [ --disable-isc-spnego use SPNEGO from GSSAPI library])
if test -n "$USE_GSSAPI"
then
@@ -2000,7 +2145,7 @@ AC_SUBST(LWRES_PLATFORM_QUADFORMAT)
# Note it is very recommended to *not* disable chroot(),
# this is only because chroot() was made obsolete by Posix.
AC_ARG_ENABLE(chroot,
- [ --disable-chroot disable chroot])
+ [ --disable-chroot disable chroot])
case "$enable_chroot" in
yes|'')
AC_CHECK_FUNCS(chroot)
@@ -2009,7 +2154,7 @@ case "$enable_chroot" in
;;
esac
AC_ARG_ENABLE(linux-caps,
- [ --disable-linux-caps disable linux capabilities])
+ [ --disable-linux-caps disable linux capabilities])
case "$enable_linux_caps" in
yes|'')
AC_CHECK_HEADERS(linux/capability.h sys/capability.h)
@@ -2144,6 +2289,8 @@ AC_SUBST(ISC_PLATFORM_USEDECLSPEC)
ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC"
AC_SUBST(LWRES_PLATFORM_USEDECLSPEC)
LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC"
+AC_SUBST(IRS_PLATFORM_USEDECLSPEC)
+IRS_PLATFORM_USEDECLSPEC="#undef IRS_PLATFORM_USEDECLSPEC"
#
# Random remaining OS-specific issues involving compiler warnings.
@@ -2248,8 +2395,8 @@ AC_CHECK_FUNCS(nanosleep)
# Machine architecture dependent features
#
AC_ARG_ENABLE(atomic,
- [ --enable-atomic enable machine specific atomic operations
- [[default=autodetect]]],
+ [ --enable-atomic enable machine specific atomic operations
+ [[default=autodetect]]],
enable_atomic="$enableval",
enable_atomic="autodetect")
case "$enable_atomic" in
@@ -2281,8 +2428,16 @@ main() {
[arch=x86_32])
;;
x86_64-*|amd64-*)
- have_xaddq=yes
- arch=x86_64
+AC_TRY_RUN([
+main() {
+ exit((sizeof(void *) == 8) ? 0 : 1);
+}
+],
+ [arch=x86_64
+ have_xaddq=yes],
+ [arch=x86_32],
+ [arch=x86_64
+ have_xaddq=yes])
;;
alpha*-*)
arch=alpha
@@ -2387,9 +2542,9 @@ else
fi
if test "$have_xaddq" = "yes"; then
- ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
+ ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
else
- ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
+ ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
fi
AC_SUBST(ISC_PLATFORM_HAVEXADD)
@@ -2409,14 +2564,14 @@ AC_SUBST(ISC_ARCH_DIR)
# Activate "rrset-order fixed" or not?
#
AC_ARG_ENABLE(fixed-rrset,
- [ --enable-fixed-rrset enable fixed rrset ordering
- [[default=no]]],
+ [ --enable-fixed-rrset enable fixed rrset ordering
+ [[default=no]]],
enable_fixed="$enableval",
enable_fixed="no")
case "$enable_fixed" in
yes)
AC_DEFINE(DNS_RDATASET_FIXED, 1,
- [Define to enable "rrset-order fixed" syntax.])
+ [Define to enable "rrset-order fixed" syntax.])
;;
no)
;;
@@ -2536,7 +2691,7 @@ AC_SUBST($1)
#
AC_MSG_CHECKING(for Docbook-XSL path)
AC_ARG_WITH(docbook-xsl,
-[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets],
+[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets],
docbook_path="$withval", docbook_path="auto")
case "$docbook_path" in
auto)
@@ -2604,7 +2759,7 @@ AC_SUBST(XSLT_DB2LATEX_ADMONITIONS)
# IDN support
#
AC_ARG_WITH(idn,
- [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]],
+ [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]],
use_idn="$withval", use_idn="no")
case "$use_idn" in
yes)
@@ -2624,7 +2779,7 @@ esac
iconvinc=
iconvlib=
AC_ARG_WITH(libiconv,
- [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]],
+ [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]],
use_libiconv="$withval", use_libiconv="no")
case "$use_libiconv" in
yes)
@@ -2643,7 +2798,7 @@ no)
esac
AC_ARG_WITH(iconv,
- [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]],
+ [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]],
iconvlib="$withval")
case "$iconvlib" in
no)
@@ -2655,7 +2810,7 @@ yes)
esac
AC_ARG_WITH(idnlib,
- [ --with-idnlib=ARG specify libidnkit],
+ [ --with-idnlib=ARG specify libidnkit],
idnlib="$withval", idnlib="no")
if test "$idnlib" = yes; then
AC_MSG_ERROR([You must specify ARG for --with-idnlib.])
@@ -2744,6 +2899,9 @@ LIBBIND9_API=$srcdir/lib/bind9/api
AC_SUBST_FILE(LIBLWRES_API)
LIBLWRES_API=$srcdir/lib/lwres/api
+AC_SUBST_FILE(LIBIRS_API)
+LIBIRS_API=$srcdir/lib/irs/api
+
#
# Configure any DLZ drivers.
#
@@ -2933,10 +3091,38 @@ AC_CONFIG_FILES([
lib/isccfg/Makefile
lib/isccfg/include/Makefile
lib/isccfg/include/isccfg/Makefile
+ lib/irs/Makefile
+ lib/irs/include/Makefile
+ lib/irs/include/irs/Makefile
+ lib/irs/include/irs/netdb.h
+ lib/irs/include/irs/platform.h
lib/dns/Makefile
lib/dns/include/Makefile
lib/dns/include/dns/Makefile
lib/dns/include/dst/Makefile
+ lib/export/Makefile
+ lib/export/isc/Makefile
+ lib/export/isc/include/Makefile
+ lib/export/isc/include/isc/Makefile
+ lib/export/isc/unix/Makefile
+ lib/export/isc/unix/include/Makefile
+ lib/export/isc/unix/include/isc/Makefile
+ lib/export/isc/nls/Makefile
+ lib/export/isc/$thread_dir/Makefile
+ lib/export/isc/$thread_dir/include/Makefile
+ lib/export/isc/$thread_dir/include/isc/Makefile
+ lib/export/dns/Makefile
+ lib/export/dns/include/Makefile
+ lib/export/dns/include/dns/Makefile
+ lib/export/dns/include/dst/Makefile
+ lib/export/irs/Makefile
+ lib/export/irs/include/Makefile
+ lib/export/irs/include/irs/Makefile
+ lib/export/isccfg/Makefile
+ lib/export/isccfg/include/Makefile
+ lib/export/isccfg/include/isccfg/Makefile
+ lib/export/samples/Makefile
+ lib/export/samples/Makefile-postinstall
lib/bind9/Makefile
lib/bind9/include/Makefile
lib/bind9/include/bind9/Makefile
diff --git a/contrib/dbus/dbus_mgr.c b/contrib/dbus/dbus_mgr.c
index b744790c..427aff86 100644
--- a/contrib/dbus/dbus_mgr.c
+++ b/contrib/dbus/dbus_mgr.c
@@ -914,7 +914,7 @@ dbus_mgr_get_name_list
dnsName = dns_fixedname_name(fixedname);
result= dns_name_fromtext
- ( dnsName, &buffer, ( *(endp-1) != '.') ? dns_rootname : NULL, ISC_FALSE, NULL
+ ( dnsName, &buffer, ( *(endp-1) != '.') ? dns_rootname : NULL, 0, NULL
);
if( result != ISC_R_SUCCESS )
@@ -1566,7 +1566,7 @@ dbus_mgr_handle_get_forwarders
dnsName = dns_fixedname_name(&fixedname);
result = dns_name_fromtext
- ( dnsName, &buffer, dns_rootname, ISC_FALSE, NULL
+ ( dnsName, &buffer, dns_rootname, 0, NULL
);
if( result != ISC_R_SUCCESS )
@@ -1740,7 +1740,7 @@ dns_name_t *dbus_mgr_if_reverse_ip_name
dns_name = dns_fixedname_name(fixedname);
result= dns_name_fromtext
- ( dns_name, &buffer, dns_rootname, ISC_FALSE, NULL
+ ( dns_name, &buffer, dns_rootname, 0, NULL
);
ISC_LINK_INIT(dns_name, link);
diff --git a/contrib/dlz/bin/dlzbdb/Makefile.in b/contrib/dlz/bin/dlzbdb/Makefile.in
index a31c503b..f0e20c29 100644
--- a/contrib/dlz/bin/dlzbdb/Makefile.in
+++ b/contrib/dlz/bin/dlzbdb/Makefile.in
@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.3 2007/09/07 06:53:03 marka Exp $
+# $Id: Makefile.in,v 1.4 2009/09/01 00:22:26 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,8 +27,8 @@ DLZINCLUDES = @DLZ_DRIVER_INCLUDES@
CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \
${ISC_INCLUDES} ${DLZINCLUDES}
-
-CDEFINES = @USE_DLZ@
+
+CDEFINES = -DBIND9 @USE_DLZ@
CWARNINGS =
DLZLIBS = @DLZ_DRIVER_LIBS@
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h b/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h
index ec4d8f66..29c13e2c 100644
--- a/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h
@@ -1,4 +1,4 @@
-/* $Id: selectiveencode.h,v 1.1.1.1 2003/06/04 00:27:08 marka Exp $ */
+/* $Id: selectiveencode.h,v 1.2 2009/09/01 03:31:33 jinmei Exp $ */
/*
* Copyright (c) 2000,2002 Japan Network Information Center.
* All rights reserved.
@@ -42,8 +42,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
-#ifndef IDN_SELECTIVENCODE_H
-#define IDN_SELECTIVENCODE_H 1
+#ifndef IDN_SELECTIVEENCODE_H
+#define IDN_SELECTIVEENCODE_H 1
/*
* Find where to convert.
@@ -67,4 +67,4 @@
extern idn_result_t
idn_selectiveencode_findregion(const char *s, char **startp, char **endp);
-#endif /* IDN_SELECTIVENCODE_H */
+#endif /* IDN_SELECTIVEENCODE_H */
diff --git a/contrib/pkcs11-keygen/PKCS11-NOTES b/contrib/pkcs11-keygen/PKCS11-NOTES
new file mode 100644
index 00000000..2d07e9f2
--- /dev/null
+++ b/contrib/pkcs11-keygen/PKCS11-NOTES
@@ -0,0 +1,94 @@
+
+ BIND-9 PKCS#11 support
+
+Prerequisite
+
+The PKCS#11 support needs a PKCS#11 OpenSSL engine based on the Solaris one,
+released the 2008-12-02 for OpenSSL 0.9.8i, with back port of key by reference
+and some improvements, including user friendly PIN management. You may also
+use the original engine code.
+
+Compilation
+
+"configure --with-pkcs11 ..."
+
+PKCS#11 Libraries
+
+Tested with Solaris one with a SCA board and with openCryptoki with the
+software token. Known to work on Linux and Windows 2003 server so
+should work on most operating systems. For AEP Keyper or any device used
+only for its protected key store, please switch to the sign-only engine.
+
+OpenSSL Engines
+
+With PKCS#11 support the PKCS#11 engine is statically loaded but at its
+initialization it dynamically loads the PKCS#11 objects.
+Even the pre commands are therefore unused they are defined with:
+ SO_PATH:
+ define: PKCS11_SO_PATH
+ default: /usr/local/lib/engines/engine_pkcs11.so
+ MODULE_PATH:
+ define: PKCS11_MODULE_PATH
+ default: /usr/lib/libpkcs11.so
+Without PKCS#11 support, a specific OpenSSL engine can be still used
+by defining ENGINE_ID at compile time.
+
+PKCS#11 tools
+
+The contrib/pkcs11-keygen directory contains a set of experimental tools
+to handle keys stored in a Hardware Security Module at the benefit of BIND.
+
+The patch for OpenSSL 0.9.8i is in this directory. Read its README.pkcs11
+for the way to use it (these are the original notes so with the original
+path, etc. Define HAVE_GETPASSPHRASE if you have getpassphrase() on
+a operating system which is not Solaris.)
+
+Not all tools are supported on AEP Keyper but genkey and dnssec-keyfromlabel
+are functional.
+
+PIN management
+
+With the just fixed PKCS#11 OpenSSL engine, the PIN should be entered
+each time it is required. With the improved engine, the PIN should be
+entered the first time it is required or can be configured in the
+OpenSSL configuration file (aka. openssl.cnf) by adding in it:
+ - at the beginning:
+ openssl_conf = openssl_def
+ - at any place these sections:
+ [ openssl_def ]
+ engines = engine_section
+ [ engine_section ]
+ pkcs11 = pkcs11_section
+ [ pkcs11_section ]
+ PIN = put__your__pin__value__here
+
+Slot management
+
+The engine tries to use the first best slot but it is recommended
+to simply use the slot 0 (usual default, meta-slot on Solaris).
+
+Sign-only engine
+
+openssl.../crypto/engine/hw_pk11-kp.c and hw_pk11_pub-kp.c contain
+a stripped down version of hw_pk11.c and hw_pk11_pub.c files which
+has only the useful functions (i.e., signature with a RSA private
+key in the device protected key store and key loading).
+
+This engine should be used with a device which provides mainly
+a protected store and no acceleration. AEP Keyper is an example
+of such a device (BTW with the fully capable engine, key export
+must be enabled on this device and this configuration is not yet
+supported).
+
+Original engine
+
+If you are using the original engine and getpassphrase() is not defined, add:
+#define getpassphrase(x) getpass(x)
+in openssl.../crypto/engine/hw_pk11_pub.c
+
+Notes
+
+Some names here are registered trademarks, at least Solaris is a trademark
+of Sun Microsystems Inc...
+Include files are from RSA Labs., PKCS#11 version is 2.20 amendment 3.
+The PKCS#11 support is compatible with the forthcoming FIPS 140-2 support.
diff --git a/contrib/pkcs11-keygen/README b/contrib/pkcs11-keygen/README
index 4104e17a..718208f0 100644
--- a/contrib/pkcs11-keygen/README
+++ b/contrib/pkcs11-keygen/README
@@ -4,6 +4,8 @@ an id of the keytag in hex.
Run genkey.sh to generate a new key and call the other programs in turn.
Run writekey.sh to load key to the key store from Kxxx.{key,private}.
+Run genkey, dnssec-keyfromlabel and optionally set_key_id when you have
+no perl or no Net::DNS::SEC perl module.
genkey[.c] uses PKCS11 calls to generate keys.
PEM_write_pubkey[.c] uses OpenSSL to write a public key from the key store
diff --git a/contrib/pkcs11-keygen/destroyobj.c b/contrib/pkcs11-keygen/destroyobj.c
index 9c714d8e..e7068e4d 100644
--- a/contrib/pkcs11-keygen/destroyobj.c
+++ b/contrib/pkcs11-keygen/destroyobj.c
@@ -7,12 +7,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
-#ifndef OPENCRYPTOKI
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#else
#include <opencryptoki/pkcs11.h>
-#endif
int
main(int argc, char *argv[])
@@ -93,7 +88,7 @@ main(int argc, char *argv[])
/* Login to the Token (Keystore) */
if (!pin)
-#ifndef OPENCRYPTOKI
+#ifndef HAVE_GETPASS
pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
#else
pin = (CK_UTF8CHAR *)getpass("Enter Pin: ");
diff --git a/contrib/pkcs11-keygen/genkey.c b/contrib/pkcs11-keygen/genkey.c
index fc703916..45a9e3cd 100644
--- a/contrib/pkcs11-keygen/genkey.c
+++ b/contrib/pkcs11-keygen/genkey.c
@@ -17,12 +17,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
-#ifndef OPENCRYPTOKI
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#else
#include <opencryptoki/pkcs11.h>
-#endif
/* Define static key template values */
static CK_BBOOL truevalue = TRUE;
@@ -137,7 +132,7 @@ main(int argc, char *argv[])
/* Login to the Token (Keystore) */
if (!pin)
-#ifndef OPENCRYPTOKI
+#ifndef HAVE_GETPASS
pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
#else
pin = (CK_UTF8CHAR *)getpass("Enter Pin: ");
diff --git a/contrib/pkcs11-keygen/listobjs.c b/contrib/pkcs11-keygen/listobjs.c
index 68e22ec8..3fb6eaa8 100644
--- a/contrib/pkcs11-keygen/listobjs.c
+++ b/contrib/pkcs11-keygen/listobjs.c
@@ -7,12 +7,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
-#ifndef OPENCRYPTOKI
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#else
#include <opencryptoki/pkcs11.h>
-#endif
int
main(int argc, char *argv[])
@@ -101,7 +96,7 @@ main(int argc, char *argv[])
/* Login to the Token (Keystore) */
if (!public) {
if (!pin)
-#ifndef OPENCRYPTOKI
+#ifndef HAVE_GETPASS
pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
#else
pin = (CK_UTF8CHAR *)getpass("Enter Pin: ");
diff --git a/contrib/pkcs11-keygen/opencryptoki/apiclient.h b/contrib/pkcs11-keygen/opencryptoki/apiclient.h
new file mode 100644
index 00000000..f825b89d
--- /dev/null
+++ b/contrib/pkcs11-keygen/opencryptoki/apiclient.h
@@ -0,0 +1,481 @@
+/*
+ * $Header: /proj/cvs/prod/bind9/contrib/pkcs11-keygen/opencryptoki/apiclient.h,v 1.1 2009/09/07 21:19:21 fdupont Exp $
+ */
+
+
+/*
+ Common Public License Version 0.5
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
+ THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+ REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
+ RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+ 1. DEFINITIONS
+
+ "Contribution" means:
+ a) in the case of the initial Contributor, the
+ initial code and documentation distributed under
+ this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program
+ originate from and are distributed by that
+ particular Contributor. A Contribution 'originates'
+ from a Contributor if it was added to the Program
+ by such Contributor itself or anyone acting on such
+ Contributor's behalf. Contributions do not include
+ additions to the Program which: (i) are separate
+ modules of software distributed in conjunction with
+ the Program under their own license agreement, and
+ (ii) are not derivative works of the Program.
+
+
+ "Contributor" means any person or entity that distributes
+ the Program.
+
+ "Licensed Patents " mean patent claims licensable by a
+ Contributor which are necessarily infringed by the use or
+ sale of its Contribution alone or when combined with the
+ Program.
+
+ "Program" means the Contributions distributed in
+ accordance with this Agreement.
+
+ "Recipient" means anyone who receives the Program under
+ this Agreement, including all Contributors.
+
+ 2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a
+ non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare derivative works of,
+ publicly display, publicly perform, distribute and
+ sublicense the Contribution of such Contributor, if
+ any, and such derivative works, in source code and
+ object code form.
+
+ b) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a
+ non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell,
+ offer to sell, import and otherwise transfer the
+ Contribution of such Contributor, if any, in source
+ code and object code form. This patent license
+ shall apply to the combination of the Contribution
+ and the Program if, at the time the Contribution is
+ added by the Contributor, such addition of the
+ Contribution causes such combination to be covered
+ by the Licensed Patents. The patent license shall
+ not apply to any other combinations which include
+ the Contribution. No hardware per se is licensed
+ hereunder.
+
+ c) Recipient understands that although each
+ Contributor grants the licenses to its
+ Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does
+ not infringe the patent or other intellectual
+ property rights of any other entity. Each
+ Contributor disclaims any liability to Recipient
+ for claims brought by any other entity based on
+ infringement of intellectual property rights or
+ otherwise. As a condition to exercising the rights
+ and licenses granted hereunder, each Recipient
+ hereby assumes sole responsibility to secure any
+ other intellectual property rights needed, if any.
+
+ For example, if a third party patent license is
+ required to allow Recipient to distribute the
+ Program, it is Recipient's responsibility to
+ acquire that license before distributing the
+ Program.
+
+ d) Each Contributor represents that to its
+ knowledge it has sufficient copyright rights in its
+ Contribution, if any, to grant the copyright
+ license set forth in this Agreement.
+
+ 3. REQUIREMENTS
+
+ A Contributor may choose to distribute the Program in
+ object code form under its own license agreement, provided
+ that:
+ a) it complies with the terms and conditions of
+ this Agreement; and
+
+ b) its license agreement:
+ i) effectively disclaims on behalf of all
+ Contributors all warranties and conditions, express
+ and implied, including warranties or conditions of
+ title and non-infringement, and implied warranties
+ or conditions of merchantability and fitness for a
+ particular purpose;
+
+ ii) effectively excludes on behalf of all
+ Contributors all liability for damages, including
+ direct, indirect, special, incidental and
+ consequential damages, such as lost profits;
+
+ iii) states that any provisions which differ from
+ this Agreement are offered by that Contributor
+ alone and not by any other party; and
+
+ iv) states that source code for the Program is
+ available from such Contributor, and informs
+ licensees how to obtain it in a reasonable manner
+ on or through a medium customarily used for
+ software exchange.
+
+ When the Program is made available in source code form:
+ a) it must be made available under this Agreement;
+ and
+ b) a copy of this Agreement must be included with
+ each copy of the Program.
+
+ Contributors may not remove or alter any copyright notices
+ contained within the Program.
+
+ Each Contributor must identify itself as the originator of
+ its Contribution, if any, in a manner that reasonably
+ allows subsequent Recipients to identify the originator of
+ the Contribution.
+
+
+ 4. COMMERCIAL DISTRIBUTION
+
+ Commercial distributors of software may accept certain
+ responsibilities with respect to end users, business
+ partners and the like. While this license is intended to
+ facilitate the commercial use of the Program, the
+ Contributor who includes the Program in a commercial
+ product offering should do so in a manner which does not
+ create potential liability for other Contributors.
+ Therefore, if a Contributor includes the Program in a
+ commercial product offering, such Contributor ("Commercial
+ Contributor") hereby agrees to defend and indemnify every
+ other Contributor ("Indemnified Contributor") against any
+ losses, damages and costs (collectively "Losses") arising
+ from claims, lawsuits and other legal actions brought by a
+ third party against the Indemnified Contributor to the
+ extent caused by the acts or omissions of such Commercial
+ Contributor in connection with its distribution of the
+ Program in a commercial product offering. The obligations
+ in this section do not apply to any claims or Losses
+ relating to any actual or alleged intellectual property
+ infringement. In order to qualify, an Indemnified
+ Contributor must: a) promptly notify the Commercial
+ Contributor in writing of such claim, and b) allow the
+ Commercial Contributor to control, and cooperate with the
+ Commercial Contributor in, the defense and any related
+ settlement negotiations. The Indemnified Contributor may
+ participate in any such claim at its own expense.
+
+
+ For example, a Contributor might include the Program in a
+ commercial product offering, Product X. That Contributor
+ is then a Commercial Contributor. If that Commercial
+ Contributor then makes performance claims, or offers
+ warranties related to Product X, those performance claims
+ and warranties are such Commercial Contributor's
+ responsibility alone. Under this section, the Commercial
+ Contributor would have to defend claims against the other
+ Contributors related to those performance claims and
+ warranties, and if a court requires any other Contributor
+ to pay any damages as a result, the Commercial Contributor
+ must pay those damages.
+
+
+ 5. NO WARRANTY
+
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
+ PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+ IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+ CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+ responsible for determining the appropriateness of using
+ and distributing the Program and assumes all risks
+ associated with its exercise of rights under this
+ Agreement, including but not limited to the risks and
+ costs of program errors, compliance with applicable laws,
+ damage to or loss of data, programs or equipment, and
+ unavailability or interruption of operations.
+
+ 6. DISCLAIMER OF LIABILITY
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
+ RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
+ LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
+ OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ 7. GENERAL
+
+ If any provision of this Agreement is invalid or
+ unenforceable under applicable law, it shall not affect
+ the validity or enforceability of the remainder of the
+ terms of this Agreement, and without further action by the
+ parties hereto, such provision shall be reformed to the
+ minimum extent necessary to make such provision valid and
+ enforceable.
+
+
+ If Recipient institutes patent litigation against a
+ Contributor with respect to a patent applicable to
+ software (including a cross-claim or counterclaim in a
+ lawsuit), then any patent licenses granted by that
+ Contributor to such Recipient under this Agreement shall
+ terminate as of the date such litigation is filed. In
+ addition, If Recipient institutes patent litigation
+ against any entity (including a cross-claim or
+ counterclaim in a lawsuit) alleging that the Program
+ itself (excluding combinations of the Program with other
+ software or hardware) infringes such Recipient's
+ patent(s), then such Recipient's rights granted under
+ Section 2(b) shall terminate as of the date such
+ litigation is filed.
+
+ All Recipient's rights under this Agreement shall
+ terminate if it fails to comply with any of the material
+ terms or conditions of this Agreement and does not cure
+ such failure in a reasonable period of time after becoming
+ aware of such noncompliance. If all Recipient's rights
+ under this Agreement terminate, Recipient agrees to cease
+ use and distribution of the Program as soon as reasonably
+ practicable. However, Recipient's obligations under this
+ Agreement and any licenses granted by Recipient relating
+ to the Program shall continue and survive.
+
+ Everyone is permitted to copy and distribute copies of
+ this Agreement, but in order to avoid inconsistency the
+ Agreement is copyrighted and may only be modified in the
+ following manner. The Agreement Steward reserves the right
+ to publish new versions (including revisions) of this
+ Agreement from time to time. No one other than the
+ Agreement Steward has the right to modify this Agreement.
+
+ IBM is the initial Agreement Steward. IBM may assign the
+ responsibility to serve as the Agreement Steward to a
+ suitable separate entity. Each new version of the
+ Agreement will be given a distinguishing version number.
+ The Program (including Contributions) may always be
+ distributed subject to the version of the Agreement under
+ which it was received. In addition, after a new version of
+ the Agreement is published, Contributor may elect to
+ distribute the Program (including its Contributions) under
+ the new version. Except as expressly stated in Sections
+ 2(a) and 2(b) above, Recipient receives no rights or
+ licenses to the intellectual property of any Contributor
+ under this Agreement, whether expressly, by implication,
+ estoppel or otherwise. All rights in the Program not
+ expressly granted under this Agreement are reserved.
+
+
+ This Agreement is governed by the laws of the State of New
+ York and the intellectual property laws of the United
+ States of America. No party to this Agreement will bring a
+ legal action under this Agreement more than one year after
+ the cause of action arose. Each party waives its rights to
+ a jury trial in any resulting litigation.
+
+
+
+*/
+
+/* (C) COPYRIGHT International Business Machines Corp. 2001 */
+
+
+#ifndef _APICLIENT_H
+#define _APICLIENT_H
+
+
+#include "pkcs11types.h"
+
+
+
+#define VERSION_MAJOR 2 // Version 2 of the PKCS library
+#define VERSION_MINOR 01 // minor revision .10 of PKCS11
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+CK_RV C_CancelFunction ( CK_SESSION_HANDLE );
+
+CK_RV C_CloseAllSessions ( CK_SLOT_ID );
+
+CK_RV C_CloseSession ( CK_SESSION_HANDLE );
+
+CK_RV C_CopyObject ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR );
+
+CK_RV C_CreateObject ( CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG,
+ CK_OBJECT_HANDLE_PTR );
+
+CK_RV C_Decrypt ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
+ CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_DecryptFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_DecryptInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE );
+
+CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
+ CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_DeriveKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR );
+
+CK_RV C_DestroyObject ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE );
+
+CK_RV C_Digest ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
+ CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_DigestFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_DigestInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR );
+
+CK_RV C_DigestKey ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE );
+
+CK_RV C_DigestUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_Encrypt ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_EncryptFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_EncryptInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE );
+
+CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_Finalize ( CK_VOID_PTR );
+
+CK_RV C_FindObjects ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG,
+ CK_ULONG_PTR );
+
+CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE );
+
+CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG );
+
+CK_RV C_GenerateKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
+ CK_ULONG, CK_OBJECT_HANDLE_PTR );
+
+CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
+ CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
+ CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR );
+
+CK_RV C_GenerateRandom ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_PTR, CK_ULONG );
+
+CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR );
+
+CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE );
+
+CK_RV C_GetInfo ( CK_INFO_PTR );
+
+CK_RV C_GetMechanismInfo ( CK_SLOT_ID, CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR );
+
+CK_RV C_GetMechanismList ( CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR );
+
+CK_RV C_GetObjectSize ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR );
+
+CK_RV C_GetOperationState ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE, CK_SESSION_INFO_PTR );
+
+CK_RV C_GetSlotInfo ( CK_SLOT_ID, CK_SLOT_INFO_PTR );
+
+CK_RV C_GetSlotList ( CK_BBOOL, CK_SLOT_ID_PTR, CK_ULONG_PTR );
+
+CK_RV C_GetTokenInfo ( CK_SLOT_ID, CK_TOKEN_INFO_PTR );
+
+CK_RV C_Initialize ( CK_VOID_PTR );
+
+CK_RV C_InitPIN ( CK_SESSION_HANDLE, CK_CHAR_PTR, CK_ULONG );
+
+CK_RV C_InitToken ( CK_SLOT_ID, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR );
+
+CK_RV C_Login ( CK_SESSION_HANDLE, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG );
+
+CK_RV C_Logout ( CK_SESSION_HANDLE );
+
+CK_RV C_OpenSession ( CK_SLOT_ID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY,
+ CK_SESSION_HANDLE_PTR );
+
+CK_RV C_SeedRandom ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_PTR, CK_ULONG );
+
+CK_RV C_SetOperationState ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
+ CK_OBJECT_HANDLE, CK_OBJECT_HANDLE );
+
+CK_RV C_SetPIN ( CK_SESSION_HANDLE, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG );
+
+CK_RV C_Sign ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
+ CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_SignFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+CK_RV C_SignInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE );
+
+CK_RV C_SignRecover ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE );
+
+CK_RV C_SignUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_UnwrapKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
+ CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
+ CK_OBJECT_HANDLE_PTR );
+
+CK_RV C_Verify ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_VerifyFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_VerifyInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE );
+
+CK_RV C_VerifyRecover ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
+ CK_ULONG_PTR );
+
+CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE );
+
+CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG );
+
+CK_RV C_WaitForSlotEvent ( CK_FLAGS, CK_SLOT_ID_PTR, CK_VOID_PTR );
+
+CK_RV C_WrapKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
+ CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _APICLIENT_H
+
+
diff --git a/contrib/pkcs11-keygen/opencryptoki/pkcs11.h b/contrib/pkcs11-keygen/opencryptoki/pkcs11.h
new file mode 100644
index 00000000..bf1fe59f
--- /dev/null
+++ b/contrib/pkcs11-keygen/opencryptoki/pkcs11.h
@@ -0,0 +1,297 @@
+/*
+ Common Public License Version 0.5
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
+ THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+ REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
+ RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+ 1. DEFINITIONS
+
+ "Contribution" means:
+ a) in the case of the initial Contributor, the
+ initial code and documentation distributed under
+ this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program
+ originate from and are distributed by that
+ particular Contributor. A Contribution 'originates'
+ from a Contributor if it was added to the Program
+ by such Contributor itself or anyone acting on such
+ Contributor's behalf. Contributions do not include
+ additions to the Program which: (i) are separate
+ modules of software distributed in conjunction with
+ the Program under their own license agreement, and
+ (ii) are not derivative works of the Program.
+
+
+ "Contributor" means any person or entity that distributes
+ the Program.
+
+ "Licensed Patents " mean patent claims licensable by a
+ Contributor which are necessarily infringed by the use or
+ sale of its Contribution alone or when combined with the
+ Program.
+
+ "Program" means the Contributions distributed in
+ accordance with this Agreement.
+
+ "Recipient" means anyone who receives the Program under
+ this Agreement, including all Contributors.
+
+ 2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a
+ non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare derivative works of,
+ publicly display, publicly perform, distribute and
+ sublicense the Contribution of such Contributor, if
+ any, and such derivative works, in source code and
+ object code form.
+
+ b) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a
+ non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell,
+ offer to sell, import and otherwise transfer the
+ Contribution of such Contributor, if any, in source
+ code and object code form. This patent license
+ shall apply to the combination of the Contribution
+ and the Program if, at the time the Contribution is
+ added by the Contributor, such addition of the
+ Contribution causes such combination to be covered
+ by the Licensed Patents. The patent license shall
+ not apply to any other combinations which include
+ the Contribution. No hardware per se is licensed
+ hereunder.
+
+ c) Recipient understands that although each
+ Contributor grants the licenses to its
+ Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does
+ not infringe the patent or other intellectual
+ property rights of any other entity. Each
+ Contributor disclaims any liability to Recipient
+ for claims brought by any other entity based on
+ infringement of intellectual property rights or
+ otherwise. As a condition to exercising the rights
+ and licenses granted hereunder, each Recipient
+ hereby assumes sole responsibility to secure any
+ other intellectual property rights needed, if any.
+
+ For example, if a third party patent license is
+ required to allow Recipient to distribute the
+ Program, it is Recipient's responsibility to
+ acquire that license before distributing the
+ Program.
+
+ d) Each Contributor represents that to its
+ knowledge it has sufficient copyright rights in its
+ Contribution, if any, to grant the copyright
+ license set forth in this Agreement.
+
+ 3. REQUIREMENTS
+
+ A Contributor may choose to distribute the Program in
+ object code form under its own license agreement, provided
+ that:
+ a) it complies with the terms and conditions of
+ this Agreement; and
+
+ b) its license agreement:
+ i) effectively disclaims on behalf of all
+ Contributors all warranties and conditions, express
+ and implied, including warranties or conditions of
+ title and non-infringement, and implied warranties
+ or conditions of merchantability and fitness for a
+ particular purpose;
+
+ ii) effectively excludes on behalf of all
+ Contributors all liability for damages, including
+ direct, indirect, special, incidental and
+ consequential damages, such as lost profits;
+
+ iii) states that any provisions which differ from
+ this Agreement are offered by that Contributor
+ alone and not by any other party; and
+
+ iv) states that source code for the Program is
+ available from such Contributor, and informs
+ licensees how to obtain it in a reasonable manner
+ on or through a medium customarily used for
+ software exchange.
+
+ When the Program is made available in source code form:
+ a) it must be made available under this Agreement;
+ and
+ b) a copy of this Agreement must be included with
+ each copy of the Program.
+
+ Contributors may not remove or alter any copyright notices
+ contained within the Program.
+
+ Each Contributor must identify itself as the originator of
+ its Contribution, if any, in a manner that reasonably
+ allows subsequent Recipients to identify the originator of
+ the Contribution.
+
+
+ 4. COMMERCIAL DISTRIBUTION
+
+ Commercial distributors of software may accept certain
+ responsibilities with respect to end users, business
+ partners and the like. While this license is intended to
+ facilitate the commercial use of the Program, the
+ Contributor who includes the Program in a commercial
+ product offering should do so in a manner which does not
+ create potential liability for other Contributors.
+ Therefore, if a Contributor includes the Program in a
+ commercial product offering, such Contributor ("Commercial
+ Contributor") hereby agrees to defend and indemnify every
+ other Contributor ("Indemnified Contributor") against any
+ losses, damages and costs (collectively "Losses") arising
+ from claims, lawsuits and other legal actions brought by a
+ third party against the Indemnified Contributor to the
+ extent caused by the acts or omissions of such Commercial
+ Contributor in connection with its distribution of the
+ Program in a commercial product offering. The obligations
+ in this section do not apply to any claims or Losses
+ relating to any actual or alleged intellectual property
+ infringement. In order to qualify, an Indemnified
+ Contributor must: a) promptly notify the Commercial
+ Contributor in writing of such claim, and b) allow the
+ Commercial Contributor to control, and cooperate with the
+ Commercial Contributor in, the defense and any related
+ settlement negotiations. The Indemnified Contributor may
+ participate in any such claim at its own expense.
+
+
+ For example, a Contributor might include the Program in a
+ commercial product offering, Product X. That Contributor
+ is then a Commercial Contributor. If that Commercial
+ Contributor then makes performance claims, or offers
+ warranties related to Product X, those performance claims
+ and warranties are such Commercial Contributor's
+ responsibility alone. Under this section, the Commercial
+ Contributor would have to defend claims against the other
+ Contributors related to those performance claims and
+ warranties, and if a court requires any other Contributor
+ to pay any damages as a result, the Commercial Contributor
+ must pay those damages.
+
+
+ 5. NO WARRANTY
+
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
+ PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+ IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+ CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+ responsible for determining the appropriateness of using
+ and distributing the Program and assumes all risks
+ associated with its exercise of rights under this
+ Agreement, including but not limited to the risks and
+ costs of program errors, compliance with applicable laws,
+ damage to or loss of data, programs or equipment, and
+ unavailability or interruption of operations.
+
+ 6. DISCLAIMER OF LIABILITY
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
+ RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
+ LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
+ OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ 7. GENERAL
+
+ If any provision of this Agreement is invalid or
+ unenforceable under applicable law, it shall not affect
+ the validity or enforceability of the remainder of the
+ terms of this Agreement, and without further action by the
+ parties hereto, such provision shall be reformed to the
+ minimum extent necessary to make such provision valid and
+ enforceable.
+
+
+ If Recipient institutes patent litigation against a
+ Contributor with respect to a patent applicable to
+ software (including a cross-claim or counterclaim in a
+ lawsuit), then any patent licenses granted by that
+ Contributor to such Recipient under this Agreement shall
+ terminate as of the date such litigation is filed. In
+ addition, If Recipient institutes patent litigation
+ against any entity (including a cross-claim or
+ counterclaim in a lawsuit) alleging that the Program
+ itself (excluding combinations of the Program with other
+ software or hardware) infringes such Recipient's
+ patent(s), then such Recipient's rights granted under
+ Section 2(b) shall terminate as of the date such
+ litigation is filed.
+
+ All Recipient's rights under this Agreement shall
+ terminate if it fails to comply with any of the material
+ terms or conditions of this Agreement and does not cure
+ such failure in a reasonable period of time after becoming
+ aware of such noncompliance. If all Recipient's rights
+ under this Agreement terminate, Recipient agrees to cease
+ use and distribution of the Program as soon as reasonably
+ practicable. However, Recipient's obligations under this
+ Agreement and any licenses granted by Recipient relating
+ to the Program shall continue and survive.
+
+ Everyone is permitted to copy and distribute copies of
+ this Agreement, but in order to avoid inconsistency the
+ Agreement is copyrighted and may only be modified in the
+ following manner. The Agreement Steward reserves the right
+ to publish new versions (including revisions) of this
+ Agreement from time to time. No one other than the
+ Agreement Steward has the right to modify this Agreement.
+
+ IBM is the initial Agreement Steward. IBM may assign the
+ responsibility to serve as the Agreement Steward to a
+ suitable separate entity. Each new version of the
+ Agreement will be given a distinguishing version number.
+ The Program (including Contributions) may always be
+ distributed subject to the version of the Agreement under
+ which it was received. In addition, after a new version of
+ the Agreement is published, Contributor may elect to
+ distribute the Program (including its Contributions) under
+ the new version. Except as expressly stated in Sections
+ 2(a) and 2(b) above, Recipient receives no rights or
+ licenses to the intellectual property of any Contributor
+ under this Agreement, whether expressly, by implication,
+ estoppel or otherwise. All rights in the Program not
+ expressly granted under this Agreement are reserved.
+
+
+ This Agreement is governed by the laws of the State of New
+ York and the intellectual property laws of the United
+ States of America. No party to this Agreement will bring a
+ legal action under this Agreement more than one year after
+ the cause of action arose. Each party waives its rights to
+ a jury trial in any resulting litigation.
+
+
+
+*/
+
+/* (c) COPYRIGHT International Business Machines Corp. 2001 */
+
+#ifndef OPENCRYPTOKI_PKCS11_H
+#define OPENCRYPTOKI_PKCS11_H
+
+#include <opencryptoki/pkcs11types.h>
+#include <opencryptoki/apiclient.h>
+
+#endif
diff --git a/contrib/pkcs11-keygen/opencryptoki/pkcs11types.h b/contrib/pkcs11-keygen/opencryptoki/pkcs11types.h
new file mode 100644
index 00000000..97a83a3d
--- /dev/null
+++ b/contrib/pkcs11-keygen/opencryptoki/pkcs11types.h
@@ -0,0 +1,1865 @@
+/*
+ * $Header: /proj/cvs/prod/bind9/contrib/pkcs11-keygen/opencryptoki/pkcs11types.h,v 1.1 2009/09/07 21:19:21 fdupont Exp $
+ */
+
+/*
+ Common Public License Version 0.5
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
+ THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+ REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
+ RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+ 1. DEFINITIONS
+
+ "Contribution" means:
+ a) in the case of the initial Contributor, the
+ initial code and documentation distributed under
+ this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program
+ originate from and are distributed by that
+ particular Contributor. A Contribution 'originates'
+ from a Contributor if it was added to the Program
+ by such Contributor itself or anyone acting on such
+ Contributor's behalf. Contributions do not include
+ additions to the Program which: (i) are separate
+ modules of software distributed in conjunction with
+ the Program under their own license agreement, and
+ (ii) are not derivative works of the Program.
+
+
+ "Contributor" means any person or entity that distributes
+ the Program.
+
+ "Licensed Patents " mean patent claims licensable by a
+ Contributor which are necessarily infringed by the use or
+ sale of its Contribution alone or when combined with the
+ Program.
+
+ "Program" means the Contributions distributed in
+ accordance with this Agreement.
+
+ "Recipient" means anyone who receives the Program under
+ this Agreement, including all Contributors.
+
+ 2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a
+ non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare derivative works of,
+ publicly display, publicly perform, distribute and
+ sublicense the Contribution of such Contributor, if
+ any, and such derivative works, in source code and
+ object code form.
+
+ b) Subject to the terms of this Agreement, each
+ Contributor hereby grants Recipient a
+ non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell,
+ offer to sell, import and otherwise transfer the
+ Contribution of such Contributor, if any, in source
+ code and object code form. This patent license
+ shall apply to the combination of the Contribution
+ and the Program if, at the time the Contribution is
+ added by the Contributor, such addition of the
+ Contribution causes such combination to be covered
+ by the Licensed Patents. The patent license shall
+ not apply to any other combinations which include
+ the Contribution. No hardware per se is licensed
+ hereunder.
+
+ c) Recipient understands that although each
+ Contributor grants the licenses to its
+ Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does
+ not infringe the patent or other intellectual
+ property rights of any other entity. Each
+ Contributor disclaims any liability to Recipient
+ for claims brought by any other entity based on
+ infringement of intellectual property rights or
+ otherwise. As a condition to exercising the rights
+ and licenses granted hereunder, each Recipient
+ hereby assumes sole responsibility to secure any
+ other intellectual property rights needed, if any.
+
+ For example, if a third party patent license is
+ required to allow Recipient to distribute the
+ Program, it is Recipient's responsibility to
+ acquire that license before distributing the
+ Program.
+
+ d) Each Contributor represents that to its
+ knowledge it has sufficient copyright rights in its
+ Contribution, if any, to grant the copyright
+ license set forth in this Agreement.
+
+ 3. REQUIREMENTS
+
+ A Contributor may choose to distribute the Program in
+ object code form under its own license agreement, provided
+ that:
+ a) it complies with the terms and conditions of
+ this Agreement; and
+
+ b) its license agreement:
+ i) effectively disclaims on behalf of all
+ Contributors all warranties and conditions, express
+ and implied, including warranties or conditions of
+ title and non-infringement, and implied warranties
+ or conditions of merchantability and fitness for a
+ particular purpose;
+
+ ii) effectively excludes on behalf of all
+ Contributors all liability for damages, including
+ direct, indirect, special, incidental and
+ consequential damages, such as lost profits;
+
+ iii) states that any provisions which differ from
+ this Agreement are offered by that Contributor
+ alone and not by any other party; and
+
+ iv) states that source code for the Program is
+ available from such Contributor, and informs
+ licensees how to obtain it in a reasonable manner
+ on or through a medium customarily used for
+ software exchange.
+
+ When the Program is made available in source code form:
+ a) it must be made available under this Agreement;
+ and
+ b) a copy of this Agreement must be included with
+ each copy of the Program.
+
+ Contributors may not remove or alter any copyright notices
+ contained within the Program.
+
+ Each Contributor must identify itself as the originator of
+ its Contribution, if any, in a manner that reasonably
+ allows subsequent Recipients to identify the originator of
+ the Contribution.
+
+
+ 4. COMMERCIAL DISTRIBUTION
+
+ Commercial distributors of software may accept certain
+ responsibilities with respect to end users, business
+ partners and the like. While this license is intended to
+ facilitate the commercial use of the Program, the
+ Contributor who includes the Program in a commercial
+ product offering should do so in a manner which does not
+ create potential liability for other Contributors.
+ Therefore, if a Contributor includes the Program in a
+ commercial product offering, such Contributor ("Commercial
+ Contributor") hereby agrees to defend and indemnify every
+ other Contributor ("Indemnified Contributor") against any
+ losses, damages and costs (collectively "Losses") arising
+ from claims, lawsuits and other legal actions brought by a
+ third party against the Indemnified Contributor to the
+ extent caused by the acts or omissions of such Commercial
+ Contributor in connection with its distribution of the
+ Program in a commercial product offering. The obligations
+ in this section do not apply to any claims or Losses
+ relating to any actual or alleged intellectual property
+ infringement. In order to qualify, an Indemnified
+ Contributor must: a) promptly notify the Commercial
+ Contributor in writing of such claim, and b) allow the
+ Commercial Contributor to control, and cooperate with the
+ Commercial Contributor in, the defense and any related
+ settlement negotiations. The Indemnified Contributor may
+ participate in any such claim at its own expense.
+
+
+ For example, a Contributor might include the Program in a
+ commercial product offering, Product X. That Contributor
+ is then a Commercial Contributor. If that Commercial
+ Contributor then makes performance claims, or offers
+ warranties related to Product X, those performance claims
+ and warranties are such Commercial Contributor's
+ responsibility alone. Under this section, the Commercial
+ Contributor would have to defend claims against the other
+ Contributors related to those performance claims and
+ warranties, and if a court requires any other Contributor
+ to pay any damages as a result, the Commercial Contributor
+ must pay those damages.
+
+
+ 5. NO WARRANTY
+
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
+ PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+ IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+ CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+ responsible for determining the appropriateness of using
+ and distributing the Program and assumes all risks
+ associated with its exercise of rights under this
+ Agreement, including but not limited to the risks and
+ costs of program errors, compliance with applicable laws,
+ damage to or loss of data, programs or equipment, and
+ unavailability or interruption of operations.
+
+ 6. DISCLAIMER OF LIABILITY
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
+ RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
+ LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
+ OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ 7. GENERAL
+
+ If any provision of this Agreement is invalid or
+ unenforceable under applicable law, it shall not affect
+ the validity or enforceability of the remainder of the
+ terms of this Agreement, and without further action by the
+ parties hereto, such provision shall be reformed to the
+ minimum extent necessary to make such provision valid and
+ enforceable.
+
+
+ If Recipient institutes patent litigation against a
+ Contributor with respect to a patent applicable to
+ software (including a cross-claim or counterclaim in a
+ lawsuit), then any patent licenses granted by that
+ Contributor to such Recipient under this Agreement shall
+ terminate as of the date such litigation is filed. In
+ addition, If Recipient institutes patent litigation
+ against any entity (including a cross-claim or
+ counterclaim in a lawsuit) alleging that the Program
+ itself (excluding combinations of the Program with other
+ software or hardware) infringes such Recipient's
+ patent(s), then such Recipient's rights granted under
+ Section 2(b) shall terminate as of the date such
+ litigation is filed.
+
+ All Recipient's rights under this Agreement shall
+ terminate if it fails to comply with any of the material
+ terms or conditions of this Agreement and does not cure
+ such failure in a reasonable period of time after becoming
+ aware of such noncompliance. If all Recipient's rights
+ under this Agreement terminate, Recipient agrees to cease
+ use and distribution of the Program as soon as reasonably
+ practicable. However, Recipient's obligations under this
+ Agreement and any licenses granted by Recipient relating
+ to the Program shall continue and survive.
+
+ Everyone is permitted to copy and distribute copies of
+ this Agreement, but in order to avoid inconsistency the
+ Agreement is copyrighted and may only be modified in the
+ following manner. The Agreement Steward reserves the right
+ to publish new versions (including revisions) of this
+ Agreement from time to time. No one other than the
+ Agreement Steward has the right to modify this Agreement.
+
+ IBM is the initial Agreement Steward. IBM may assign the
+ responsibility to serve as the Agreement Steward to a
+ suitable separate entity. Each new version of the
+ Agreement will be given a distinguishing version number.
+ The Program (including Contributions) may always be
+ distributed subject to the version of the Agreement under
+ which it was received. In addition, after a new version of
+ the Agreement is published, Contributor may elect to
+ distribute the Program (including its Contributions) under
+ the new version. Except as expressly stated in Sections
+ 2(a) and 2(b) above, Recipient receives no rights or
+ licenses to the intellectual property of any Contributor
+ under this Agreement, whether expressly, by implication,
+ estoppel or otherwise. All rights in the Program not
+ expressly granted under this Agreement are reserved.
+
+
+ This Agreement is governed by the laws of the State of New
+ York and the intellectual property laws of the United
+ States of America. No party to this Agreement will bring a
+ legal action under this Agreement more than one year after
+ the cause of action arose. Each party waives its rights to
+ a jury trial in any resulting litigation.
+
+
+
+*/
+
+/* (C) COPYRIGHT International Business Machines Corp. 2001 */
+
+
+//----------------------------------------------------------------------------
+//
+// File: PKCS11Types.h
+//
+//
+//----------------------------------------------------------------------------
+
+
+#ifndef _PKCS11TYPES_H_
+#define _PKCS11TYPES_H_
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+// AIX Addition for 64Bit work.
+// All types are 32bit types, therefore the longs have to be
+// typedefed to be 32bit values.
+typedef unsigned int uint_32;
+typedef int int_32;
+
+#define CK_PTR *
+
+#define CK_CALLBACK_FUNCTION(returnType, name) \
+ returnType (* name)
+
+#ifndef NULL_PTR
+ #define NULL_PTR ((void *) NULL)
+#endif /* NULL_PTR */
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
+typedef void CK_PTR CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+ CK_BYTE minor; /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+
+ /* libraryDescription and libraryVersion are new for v2.0 */
+ CK_CHAR libraryDescription[32]; /* blank padded */
+ CK_VERSION libraryVersion; /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0
+
+
+typedef CK_ULONG CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+ CK_CHAR slotDescription[64]; /* blank padded */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags;
+
+ /* hardwareVersion and firmwareVersion are new for v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
+#define CKF_HW_SLOT 0x00000004 /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+ CK_CHAR label[32]; /* blank padded */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_CHAR model[16]; /* blank padded */
+ CK_CHAR serialNumber[16]; /* blank padded */
+ CK_FLAGS flags; /* see below */
+
+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+ * changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulMaxSessionCount; /* max open sessions */
+ CK_ULONG ulSessionCount; /* sess. now open */
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
+ CK_ULONG ulMaxPinLen; /* in bytes */
+ CK_ULONG ulMinPinLen; /* in bytes */
+ CK_ULONG ulTotalPublicMemory; /* in bytes */
+ CK_ULONG ulFreePublicMemory; /* in bytes */
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
+ CK_ULONG ulFreePrivateMemory; /* in bytes */
+
+ /* hardwareVersion, firmwareVersion, and time are new for
+ * v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+ CK_CHAR utcTime[16]; /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001 /* has random #
+ * generator */
+#define CKF_WRITE_PROTECTED 0x00000002 /* token is
+ * write-
+ * protected */
+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
+ * login */
+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
+ * PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
+ * that the token has some sort of clock. The time on that
+ * clock is returned in the token info structure */
+#define CKF_CLOCK_ON_TOKEN 0x00000040
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
+
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+
+/* CKF_TOKEN_INITIALIZED is new for v2.11. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of this standard.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED 0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION is new for v2.11. If it is
+ * true, the token supports secondary authentication for private
+ * key objects. According to the 2.11 spec pg. 45, this flag
+ * is deprecated and this flags should never be true. */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW is new in v2.11. This flag is true
+ * is an incorrect user PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY is new in v2.11. This flag is true if
+ * supplying an incorrect user PIN will cause it to become
+ * locked. */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+
+/* CKF_USER_PIN_LOCKED is new in v2.11. This is true if the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED 0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED is new in v2.11. This flag is
+ * true if the user PIN value is the default value set by
+ * token initialization of manufacturing, or the PIN has
+ * been expired by the card. */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW is new in v2.11. This flag is true if
+ * and incorrect SO login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY is new in v2.11. This flag is true if
+ * supplying an incorrect SO PIN will cause it to become
+ * locked. */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+
+/* CKF_SO_PIN_LOCKED is new in v2.11. This flag is true if
+ * the SO PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_SO_PIN_LOCKED 0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED is new in v2.11. This flag is true
+ * if the SO PIN calue is the default value set by token init-
+ * ialization of manufacturing, or the PIN has been expired by
+ * the card. */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
+
+#if 0
+/* IBM extended Token Info Flags - defined by Michael Hamann */
+/* These Flags are not part of PKCS#11 Version 2.01 */
+
+/* This will be used to track the state of login retries */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+#define CKF_USER_PIN_LOCKED 0x00040000
+#define CKF_USER_PIN_MANUFACT_VALUE 0x00080000
+
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+#define CKF_SO_PIN_LOCKED 0x00400000
+#define CKF_SO_PIN_MANUFACT_VALUE 0x00800000
+#endif
+
+/* other IBM extended Token info Flags 05/29/99 */
+#define CKF_SO_PIN_DERIVED 0x01000000 // Sec Officer pin on card is derived from card id
+#define CKF_SO_CARD 0x02000000 // Security Officer Card
+/* End of IBM extented Token Info Flags */
+
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0
+/* Normal user */
+#define CKU_USER 1
+
+
+/* CK_STATE enumerates the session states */
+/* CK_STATE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0
+#define CKS_RO_USER_FUNCTIONS 1
+#define CKS_RW_PUBLIC_SESSION 2
+#define CKS_RW_USER_FUNCTIONS 3
+#define CKS_RW_SO_FUNCTIONS 4
+
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+
+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002 /* session is r/w */
+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes. It is defined
+ * as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+/* CKO_HW_FEATURE and CKO_DOMAIN_PARAMETERS are new for v2.11 */
+#define CKO_HW_FEATURE 0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_VENDOR_DEFINED 0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is a value that identifies a hardware
+ * feature type of a device. This is new for v2.11.
+ */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined: */
+#define CKH_MONOTONIC_COUNTER 0x00000001
+#define CKH_CLOCK 0x00000002
+#define CKH_VENDOR_DEFINED 0x80000000
+
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000
+#define CKK_DSA 0x00000001
+#define CKK_DH 0x00000002
+
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred */
+#define CKK_ECDSA 0x00000003
+#define CKK_EC 0x00000003
+#define CKK_X9_42_DH 0x00000004
+#define CKK_KEA 0x00000005
+
+#define CKK_GENERIC_SECRET 0x00000010
+#define CKK_RC2 0x00000011
+#define CKK_RC4 0x00000012
+#define CKK_DES 0x00000013
+#define CKK_DES2 0x00000014
+#define CKK_DES3 0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST 0x00000016
+#define CKK_CAST3 0x00000017
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred */
+#define CKK_CAST5 0x00000018
+#define CKK_CAST128 0x00000018 /* CAST128=CAST5 */
+#define CKK_RC5 0x00000019
+#define CKK_IDEA 0x0000001A
+#define CKK_SKIPJACK 0x0000001B
+#define CKK_BATON 0x0000001C
+#define CKK_JUNIPER 0x0000001D
+#define CKK_CDMF 0x0000001E
+/* CKK_AES is new for v2.11 */
+#define CKK_AES 0x0000001F
+
+#define CKK_VENDOR_DEFINED 0x80000000
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+#define CKC_X_509 0x00000000
+/* CKC_X_509_ATTR_CERT is new for v2.11 */
+#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_VENDOR_DEFINED 0x80000000
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000
+#define CKA_TOKEN 0x00000001
+#define CKA_PRIVATE 0x00000002
+#define CKA_LABEL 0x00000003
+#define CKA_APPLICATION 0x00000010
+#define CKA_VALUE 0x00000011
+/* CKA_OBJECT_ID is new for v2.11 */
+#define CKA_OBJECT_ID 0x00000012
+#define CKA_CERTIFICATE_TYPE 0x00000080
+#define CKA_ISSUER 0x00000081
+#define CKA_SERIAL_NUMBER 0x00000082
+/* CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES and CKA_TRUSTED
+ * are new for v2.11 */
+#define CKA_AC_ISSUER 0x00000083
+#define CKA_OWNER 0x00000084
+#define CKA_ATTR_TYPES 0x00000085
+#define CKA_TRUSTED 0x00000086
+
+#define CKA_KEY_TYPE 0x00000100
+#define CKA_SUBJECT 0x00000101
+#define CKA_ID 0x00000102
+#define CKA_SENSITIVE 0x00000103
+#define CKA_ENCRYPT 0x00000104
+#define CKA_DECRYPT 0x00000105
+#define CKA_WRAP 0x00000106
+#define CKA_UNWRAP 0x00000107
+#define CKA_SIGN 0x00000108
+#define CKA_SIGN_RECOVER 0x00000109
+#define CKA_VERIFY 0x0000010A
+#define CKA_VERIFY_RECOVER 0x0000010B
+#define CKA_DERIVE 0x0000010C
+#define CKA_START_DATE 0x00000110
+#define CKA_END_DATE 0x00000111
+#define CKA_MODULUS 0x00000120
+#define CKA_MODULUS_BITS 0x00000121
+#define CKA_PUBLIC_EXPONENT 0x00000122
+#define CKA_PRIVATE_EXPONENT 0x00000123
+#define CKA_PRIME_1 0x00000124
+#define CKA_PRIME_2 0x00000125
+#define CKA_EXPONENT_1 0x00000126
+#define CKA_EXPONENT_2 0x00000127
+#define CKA_COEFFICIENT 0x00000128
+#define CKA_PRIME 0x00000130
+#define CKA_SUBPRIME 0x00000131
+#define CKA_BASE 0x00000132
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS 0x00000133
+#define CKA_SUBPRIME_BITS 0x00000134
+
+#define CKA_VALUE_BITS 0x00000160
+#define CKA_VALUE_LEN 0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
+#define CKA_EXTRACTABLE 0x00000162
+#define CKA_LOCAL 0x00000163
+#define CKA_NEVER_EXTRACTABLE 0x00000164
+#define CKA_ALWAYS_SENSITIVE 0x00000165
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM 0x00000166
+#define CKA_MODIFIABLE 0x00000170
+/* CKA_ECDSA_PARAMS is deprecated in v2.11, CKA_EC_PARAMS is preferred */
+#define CKA_ECDSA_PARAMS 0x00000180
+#define CKA_EC_PARAMS 0x00000180
+#define CKA_EC_POINT 0x00000181
+/* The following are new for v2.11 */
+#define CKA_SECONDARY_AUTH 0x00000200
+#define CKA_AUTH_PIN_FLAGS 0x00000201
+#define CKA_HW_FEATURE_TYPE 0x00000300
+#define CKA_RESET_ON_INIT 0x00000301
+#define CKA_HAS_RESET 0x00000302
+
+#define CKA_VENDOR_DEFINED 0x80000000
+
+/* For use in storing objects that have an encrypted or otherwise
+ * opaque attribute. Support has been added to use this attribute
+ * in key objects only. */
+#define CKA_IBM_OPAQUE CKA_VENDOR_DEFINED + 1
+
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+
+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
+#define CKM_RSA_PKCS 0x00000001
+#define CKM_RSA_9796 0x00000002
+#define CKM_RSA_X_509 0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+ * are new for v2.0. They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS 0x00000004
+#define CKM_MD5_RSA_PKCS 0x00000005
+#define CKM_SHA1_RSA_PKCS 0x00000006
+/* The following are new for v2.11: */
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
+#define CKM_RSA_PKCS_OAEP 0x00000009
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
+#define CKM_RSA_X9_31 0x0000000B
+#define CKM_SHA1_RSA_X9_31 0x0000000C
+#define CKM_RSA_PKCS_PSS 0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
+#define CKM_DSA 0x00000011
+#define CKM_DSA_SHA1 0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
+#define CKM_DH_PKCS_DERIVE 0x00000021
+/* The following are new for v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
+#define CKM_X9_42_DH_DERIVE 0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
+#define CKM_X9_42_MQV_DERIVE 0x00000033
+
+#define CKM_SHA256_RSA_PKCS 0x00000043
+
+#define CKM_RC2_KEY_GEN 0x00000100
+#define CKM_RC2_ECB 0x00000101
+#define CKM_RC2_CBC 0x00000102
+#define CKM_RC2_MAC 0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+#define CKM_RC2_MAC_GENERAL 0x00000104
+#define CKM_RC2_CBC_PAD 0x00000105
+
+#define CKM_RC4_KEY_GEN 0x00000110
+#define CKM_RC4 0x00000111
+#define CKM_DES_KEY_GEN 0x00000120
+#define CKM_DES_ECB 0x00000121
+#define CKM_DES_CBC 0x00000122
+#define CKM_DES_MAC 0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+#define CKM_DES_MAC_GENERAL 0x00000124
+#define CKM_DES_CBC_PAD 0x00000125
+
+#define CKM_DES2_KEY_GEN 0x00000130
+#define CKM_DES3_KEY_GEN 0x00000131
+#define CKM_DES3_ECB 0x00000132
+#define CKM_DES3_CBC 0x00000133
+#define CKM_DES3_MAC 0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+#define CKM_DES3_MAC_GENERAL 0x00000135
+#define CKM_DES3_CBC_PAD 0x00000136
+#define CKM_CDMF_KEY_GEN 0x00000140
+#define CKM_CDMF_ECB 0x00000141
+#define CKM_CDMF_CBC 0x00000142
+#define CKM_CDMF_MAC 0x00000143
+#define CKM_CDMF_MAC_GENERAL 0x00000144
+#define CKM_CDMF_CBC_PAD 0x00000145
+
+#define CKM_MD2 0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD2_HMAC 0x00000201
+#define CKM_MD2_HMAC_GENERAL 0x00000202
+
+#define CKM_MD5 0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD5_HMAC 0x00000211
+#define CKM_MD5_HMAC_GENERAL 0x00000212
+
+#define CKM_SHA_1 0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+#define CKM_SHA_1_HMAC 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+
+/* The following are new for v2.11 */
+#define CKM_RIPEMD128 0x00000230
+#define CKM_RIPEMD128_HMAC 0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
+#define CKM_RIPEMD160 0x00000240
+#define CKM_RIPEMD160_HMAC 0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
+
+#define CKM_SHA256 0x00000250
+#define CKM_SHA256_HMAC 0x00000251
+#define CKM_SHA256_HMAC_GENERAL 0x00000252
+#define CKM_SHA384 0x00000260
+#define CKM_SHA384_HMAC 0x00000261
+#define CKM_SHA384_HMAC_GENERAL 0x00000262
+#define CKM_SHA512 0x00000270
+#define CKM_SHA512_HMAC 0x00000271
+#define CKM_SHA512_HMAC_GENERAL 0x00000272
+
+/* All of the following mechanisms are new for v2.0 */
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST_KEY_GEN 0x00000300
+#define CKM_CAST_ECB 0x00000301
+#define CKM_CAST_CBC 0x00000302
+#define CKM_CAST_MAC 0x00000303
+#define CKM_CAST_MAC_GENERAL 0x00000304
+#define CKM_CAST_CBC_PAD 0x00000305
+#define CKM_CAST3_KEY_GEN 0x00000310
+#define CKM_CAST3_ECB 0x00000311
+#define CKM_CAST3_CBC 0x00000312
+#define CKM_CAST3_MAC 0x00000313
+#define CKM_CAST3_MAC_GENERAL 0x00000314
+#define CKM_CAST3_CBC_PAD 0x00000315
+#define CKM_CAST5_KEY_GEN 0x00000320
+#define CKM_CAST128_KEY_GEN 0x00000320
+#define CKM_CAST5_ECB 0x00000321
+#define CKM_CAST128_ECB 0x00000321
+#define CKM_CAST5_CBC 0x00000322
+#define CKM_CAST128_CBC 0x00000322
+#define CKM_CAST5_MAC 0x00000323
+#define CKM_CAST128_MAC 0x00000323
+#define CKM_CAST5_MAC_GENERAL 0x00000324
+#define CKM_CAST128_MAC_GENERAL 0x00000324
+#define CKM_CAST5_CBC_PAD 0x00000325
+#define CKM_CAST128_CBC_PAD 0x00000325
+#define CKM_RC5_KEY_GEN 0x00000330
+#define CKM_RC5_ECB 0x00000331
+#define CKM_RC5_CBC 0x00000332
+#define CKM_RC5_MAC 0x00000333
+#define CKM_RC5_MAC_GENERAL 0x00000334
+#define CKM_RC5_CBC_PAD 0x00000335
+#define CKM_IDEA_KEY_GEN 0x00000340
+#define CKM_IDEA_ECB 0x00000341
+#define CKM_IDEA_CBC 0x00000342
+#define CKM_IDEA_MAC 0x00000343
+#define CKM_IDEA_MAC_GENERAL 0x00000344
+#define CKM_IDEA_CBC_PAD 0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
+#define CKM_XOR_BASE_AND_DATA 0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+/* The following are new for v2.11 */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+
+#define CKM_SSL3_MD5_MAC 0x00000380
+#define CKM_SSL3_SHA1_MAC 0x00000381
+#define CKM_MD5_KEY_DERIVATION 0x00000390
+#define CKM_MD2_KEY_DERIVATION 0x00000391
+#define CKM_SHA1_KEY_DERIVATION 0x00000392
+#define CKM_SHA256_KEY_DERIVATION 0x00000393
+#define CKM_PBE_MD2_DES_CBC 0x000003A0
+#define CKM_PBE_MD5_DES_CBC 0x000003A1
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
+#define CKM_PBE_SHA1_RC4_128 0x000003A6
+#define CKM_PBE_SHA1_RC4_40 0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+/* CKM_PKCS5_PBKD2 is new for v2.11 */
+#define CKM_PKCS5_PBKD2 0x000003B0
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+#define CKM_KEY_WRAP_LYNKS 0x00000400
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN 0x00001000
+#define CKM_SKIPJACK_ECB64 0x00001001
+#define CKM_SKIPJACK_CBC64 0x00001002
+#define CKM_SKIPJACK_OFB64 0x00001003
+#define CKM_SKIPJACK_CFB64 0x00001004
+#define CKM_SKIPJACK_CFB32 0x00001005
+#define CKM_SKIPJACK_CFB16 0x00001006
+#define CKM_SKIPJACK_CFB8 0x00001007
+#define CKM_SKIPJACK_WRAP 0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
+#define CKM_SKIPJACK_RELAYX 0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
+#define CKM_KEA_KEY_DERIVE 0x00001011
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
+#define CKM_BATON_KEY_GEN 0x00001030
+#define CKM_BATON_ECB128 0x00001031
+#define CKM_BATON_ECB96 0x00001032
+#define CKM_BATON_CBC128 0x00001033
+#define CKM_BATON_COUNTER 0x00001034
+#define CKM_BATON_SHUFFLE 0x00001035
+#define CKM_BATON_WRAP 0x00001036
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred. */
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
+#define CKM_ECDSA 0x00001041
+#define CKM_ECDSA_SHA1 0x00001042
+/* The following are new for v2.11 */
+#define CKM_ECDH1_DERIVE 0x00001050
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
+#define CKM_ECMQV_DERIVE 0x00001052
+
+#define CKM_JUNIPER_KEY_GEN 0x00001060
+#define CKM_JUNIPER_ECB128 0x00001061
+#define CKM_JUNIPER_CBC128 0x00001062
+#define CKM_JUNIPER_COUNTER 0x00001063
+#define CKM_JUNIPER_SHUFFLE 0x00001064
+#define CKM_JUNIPER_WRAP 0x00001065
+#define CKM_FASTHASH 0x00001070
+/* The following are new for v2.11 */
+#define CKM_AES_KEY_GEN 0x00001080
+#define CKM_AES_ECB 0x00001081
+#define CKM_AES_CBC 0x00001082
+#define CKM_AES_MAC 0x00001083
+#define CKM_AES_MAC_GENERAL 0x00001084
+#define CKM_AES_CBC_PAD 0x00001085
+#define CKM_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
+
+#define CKM_VENDOR_DEFINED 0x80000000
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+
+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism */
+typedef struct CK_MECHANISM_INFO {
+ CK_ULONG ulMinKeySize;
+ CK_ULONG ulMaxKeySize;
+ CK_FLAGS flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ * Bit Flag Mask Meaning */
+#define CKF_HW 0x00000001 /* performed by HW */
+
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
+ * and CKF_DERIVE are new for v2.0. They specify whether or not
+ * a mechanism can be used for a particular task */
+#define CKF_ENCRYPT 0x00000100
+#define CKF_DECRYPT 0x00000200
+#define CKF_DIGEST 0x00000400
+#define CKF_SIGN 0x00000800
+#define CKF_SIGN_RECOVER 0x00001000
+#define CKF_VERIFY 0x00002000
+#define CKF_VERIFY_RECOVER 0x00004000
+#define CKF_GENERATE 0x00008000
+#define CKF_GENERATE_KEY_PAIR 0x00010000
+#define CKF_WRAP 0x00020000
+#define CKF_UNWRAP 0x00040000
+#define CKF_DERIVE 0x00080000
+/* The following are new for v2.11 */
+#define CKF_EC_F_P 0x00100000
+#define CKF_EC_F_2M 0x00200000
+#define CKF_EC_ECPARAMETERS 0x00400000
+#define CKF_EC_NAMEDCURVE 0x00800000
+#define CKF_EC_UNCOMPRESS 0x01000000
+#define CKF_EC_COMPRESS 0x02000000
+
+#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000
+#define CKR_CANCEL 0x00000001
+#define CKR_HOST_MEMORY 0x00000002
+#define CKR_SLOT_ID_INVALID 0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR 0x00000005
+#define CKR_FUNCTION_FAILED 0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD 0x00000007
+#define CKR_NO_EVENT 0x00000008
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
+#define CKR_CANT_LOCK 0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
+#define CKR_DATA_INVALID 0x00000020
+#define CKR_DATA_LEN_RANGE 0x00000021
+#define CKR_DEVICE_ERROR 0x00000030
+#define CKR_DEVICE_MEMORY 0x00000031
+#define CKR_DEVICE_REMOVED 0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
+#define CKR_FUNCTION_CANCELED 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE 0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+ * v2.0 */
+#define CKR_KEY_NOT_NEEDED 0x00000064
+#define CKR_KEY_CHANGED 0x00000065
+#define CKR_KEY_NEEDED 0x00000066
+#define CKR_KEY_INDIGESTIBLE 0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+
+#define CKR_MECHANISM_INVALID 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
+#define CKR_OPERATION_ACTIVE 0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
+#define CKR_PIN_INCORRECT 0x000000A0
+#define CKR_PIN_INVALID 0x000000A1
+#define CKR_PIN_LEN_RANGE 0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED 0x000000A3
+#define CKR_PIN_LOCKED 0x000000A4
+
+#define CKR_SESSION_CLOSED 0x000000B0
+#define CKR_SESSION_COUNT 0x000000B1
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
+#define CKR_SESSION_READ_ONLY 0x000000B5
+#define CKR_SESSION_EXISTS 0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
+
+#define CKR_SIGNATURE_INVALID 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
+#define CKR_USER_NOT_LOGGED_IN 0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
+#define CKR_USER_TYPE_INVALID 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
+#define CKR_USER_TOO_MANY_TYPES 0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG 0x00000121
+/* CKR_DOMAIN_PARAMS_INVALID is new for v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+#define CKR_BUFFER_TOO_SMALL 0x00000150
+#define CKR_SAVED_STATE_INVALID 0x00000160
+#define CKR_INFORMATION_SENSITIVE 0x00000170
+#define CKR_STATE_UNSAVEABLE 0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
+#define CKR_MUTEX_BAD 0x000001A0
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
+
+#define CKR_VENDOR_DEFINED 0x80000000
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
+);
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize */
+// SAB the mutex ones had pf infront previously..
+// The spec says otherwise.
+typedef struct CK_C_INITIALIZE_ARGS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
+#define CKF_OS_LOCKING_OK 0x00000002
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+ * holds the effective keysize */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism */
+typedef struct CK_RC2_CBC_PARAMS {
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
+ * the MAC */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+ CK_CHAR_PTR pInitVector;
+ CK_CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_CHAR_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+typedef CK_RV (CK_PTR CK_C_Initialize)
+ (CK_VOID_PTR pReserved);
+typedef CK_RV (CK_PTR CK_C_Finalize)
+ (CK_VOID_PTR pReserved);
+typedef CK_RV (CK_PTR CK_C_Terminate)
+ (void);
+typedef CK_RV (CK_PTR CK_C_GetInfo)
+ (CK_INFO_PTR pInfo);
+typedef CK_RV (CK_PTR CK_C_GetFunctionList)
+ (CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
+typedef CK_RV (CK_PTR CK_C_GetSlotList)
+ (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
+ CK_ULONG_PTR pusCount);
+typedef CK_RV (CK_PTR CK_C_GetSlotInfo)
+ (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo);
+typedef CK_RV (CK_PTR CK_C_GetTokenInfo)
+ (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo);
+typedef CK_RV (CK_PTR CK_C_GetMechanismList)
+ (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
+ CK_ULONG_PTR pusCount);
+typedef CK_RV (CK_PTR CK_C_GetMechanismInfo)
+ (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR pInfo);
+typedef CK_RV (CK_PTR CK_C_InitToken)
+ (CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG usPinLen,
+ CK_CHAR_PTR pLabel);
+typedef CK_RV (CK_PTR CK_C_InitPIN)
+ (CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin,
+ CK_ULONG usPinLen);
+typedef CK_RV (CK_PTR CK_C_SetPIN)
+ (CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
+ CK_ULONG usOldLen, CK_CHAR_PTR pNewPin,
+ CK_ULONG usNewLen);
+typedef CK_RV (CK_PTR CK_C_OpenSession)
+ (CK_SLOT_ID slotID, CK_FLAGS flags,
+ CK_VOID_PTR pApplication,
+ CK_RV (*Notify) (CK_SESSION_HANDLE hSession,
+ CK_NOTIFICATION event, CK_VOID_PTR pApplication),
+ CK_SESSION_HANDLE_PTR phSession);
+typedef CK_RV (CK_PTR CK_C_CloseSession)
+ (CK_SESSION_HANDLE hSession);
+typedef CK_RV (CK_PTR CK_C_CloseAllSessions)
+ (CK_SLOT_ID slotID);
+typedef CK_RV (CK_PTR CK_C_GetSessionInfo)
+ (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo);
+typedef CK_RV (CK_PTR CK_C_GetOperationState)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
+ CK_ULONG_PTR pulOperationStateLen);
+typedef CK_RV (CK_PTR CK_C_SetOperationState)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
+ CK_ULONG ulOperationStateLen,
+ CK_OBJECT_HANDLE hEncryptionKey,
+ CK_OBJECT_HANDLE hAuthenticationKey);
+typedef CK_RV (CK_PTR CK_C_Login)(CK_SESSION_HANDLE hSession,
+ CK_USER_TYPE userType, CK_CHAR_PTR pPin,
+ CK_ULONG usPinLen);
+typedef CK_RV (CK_PTR CK_C_Logout)(CK_SESSION_HANDLE hSession);
+typedef CK_RV (CK_PTR CK_C_CreateObject)
+ (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject);
+typedef CK_RV (CK_PTR CK_C_CopyObject)
+ (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount,
+ CK_OBJECT_HANDLE_PTR phNewObject);
+typedef CK_RV (CK_PTR CK_C_DestroyObject)
+ (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject);
+typedef CK_RV(CK_PTR CK_C_GetObjectSize)
+ (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+ CK_ULONG_PTR pusSize);
+typedef CK_RV(CK_PTR CK_C_GetAttributeValue)
+ (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount);
+typedef CK_RV(CK_PTR CK_C_SetAttributeValue)
+ (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount);
+typedef CK_RV (CK_PTR CK_C_FindObjectsInit)
+ (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG usCount);
+typedef CK_RV (CK_PTR CK_C_FindObjects)
+ (CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount,
+ CK_ULONG_PTR pusObjectCount);
+typedef CK_RV (CK_PTR CK_C_FindObjectsFinal)
+ (CK_SESSION_HANDLE hSession);
+typedef CK_RV (CK_PTR CK_C_EncryptInit)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_Encrypt)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
+ CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
+ CK_ULONG_PTR pusEncryptedDataLen);
+typedef CK_RV (CK_PTR CK_C_EncryptUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pusEncryptedPartLen);
+typedef CK_RV (CK_PTR CK_C_EncryptFinal)
+ (CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastEncryptedPart,
+ CK_ULONG_PTR pusLastEncryptedPartLen);
+typedef CK_RV (CK_PTR CK_C_DecryptInit)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_Decrypt)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
+ CK_ULONG usEncryptedDataLen, CK_BYTE_PTR pData,
+ CK_ULONG_PTR pusDataLen);
+typedef CK_RV (CK_PTR CK_C_DecryptUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG usEncryptedPartLen, CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pusPartLen);
+typedef CK_RV (CK_PTR CK_C_DecryptFinal)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
+ CK_ULONG_PTR pusLastPartLen);
+typedef CK_RV (CK_PTR CK_C_DigestInit)
+ (CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism);
+typedef CK_RV (CK_PTR CK_C_Digest)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
+ CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pusDigestLen);
+typedef CK_RV (CK_PTR CK_C_DigestUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG usPartLen);
+typedef CK_RV (CK_PTR CK_C_DigestKey)
+ (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_DigestFinal)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pusDigestLen);
+typedef CK_RV (CK_PTR CK_C_SignInit)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_Sign)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
+ CK_ULONG usDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pusSignatureLen);
+typedef CK_RV (CK_PTR CK_C_SignUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG usPartLen);
+typedef CK_RV (CK_PTR CK_C_SignFinal)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pusSignatureLen);
+typedef CK_RV (CK_PTR CK_C_SignRecoverInit)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_SignRecover)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
+ CK_ULONG usDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pusSignatureLen);
+typedef CK_RV (CK_PTR CK_C_VerifyInit)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_Verify)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
+ CK_ULONG usDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG usSignatureLen);
+typedef CK_RV (CK_PTR CK_C_VerifyUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG usPartLen);
+typedef CK_RV (CK_PTR CK_C_VerifyFinal)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+ CK_ULONG usSignatureLen);
+typedef CK_RV (CK_PTR CK_C_VerifyRecoverInit)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey);
+typedef CK_RV (CK_PTR CK_C_VerifyRecover)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+ CK_ULONG usSignatureLen, CK_BYTE_PTR pData,
+ CK_ULONG_PTR pusDataLen);
+typedef CK_RV (CK_PTR CK_C_DigestEncryptUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen);
+typedef CK_RV (CK_PTR CK_C_DecryptDigestUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen);
+typedef CK_RV (CK_PTR CK_C_SignEncryptUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen);
+typedef CK_RV (CK_PTR CK_C_DecryptVerifyUpdate)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen);
+typedef CK_RV (CK_PTR CK_C_GenerateKey)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount,
+ CK_OBJECT_HANDLE_PTR phKey);
+typedef CK_RV (CK_PTR CK_C_GenerateKeyPair)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG usPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG usPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE_PTR phPrivateKey,
+ CK_OBJECT_HANDLE_PTR phPublicKey);
+typedef CK_RV (CK_PTR CK_C_WrapKey)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
+ CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pusWrappedKeyLen);
+typedef CK_RV (CK_PTR CK_C_UnwrapKey)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
+ CK_ULONG usWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
+typedef CK_RV (CK_PTR CK_C_DeriveKey)
+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
+typedef CK_RV (CK_PTR CK_C_SeedRandom)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
+ CK_ULONG usSeedLen);
+typedef CK_RV (CK_PTR CK_C_GenerateRandom)
+ (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
+ CK_ULONG usRandomLen);
+typedef CK_RV (CK_PTR CK_C_GetFunctionStatus)
+ (CK_SESSION_HANDLE hSession);
+typedef CK_RV (CK_PTR CK_C_CancelFunction)
+ (CK_SESSION_HANDLE hSession);
+typedef CK_RV (CK_PTR CK_Notify)
+ (CK_SESSION_HANDLE hSession, CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication);
+typedef CK_RV (CK_PTR CK_C_WaitForSlotEvent)
+ (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
+ CK_VOID_PTR pReserved);
+
+struct CK_FUNCTION_LIST {
+ CK_VERSION version;
+ CK_C_Initialize C_Initialize;
+ CK_C_Finalize C_Finalize;
+ CK_C_GetInfo C_GetInfo;
+ CK_C_GetFunctionList C_GetFunctionList;
+ CK_C_GetSlotList C_GetSlotList;
+ CK_C_GetSlotInfo C_GetSlotInfo;
+ CK_C_GetTokenInfo C_GetTokenInfo;
+ CK_C_GetMechanismList C_GetMechanismList;
+ CK_C_GetMechanismInfo C_GetMechanismInfo;
+ CK_C_InitToken C_InitToken;
+ CK_C_InitPIN C_InitPIN;
+ CK_C_SetPIN C_SetPIN;
+ CK_C_OpenSession C_OpenSession;
+ CK_C_CloseSession C_CloseSession;
+ CK_C_CloseAllSessions C_CloseAllSessions;
+ CK_C_GetSessionInfo C_GetSessionInfo;
+ CK_C_GetOperationState C_GetOperationState;
+ CK_C_SetOperationState C_SetOperationState;
+ CK_C_Login C_Login;
+ CK_C_Logout C_Logout;
+ CK_C_CreateObject C_CreateObject;
+ CK_C_CopyObject C_CopyObject;
+ CK_C_DestroyObject C_DestroyObject;
+ CK_C_GetObjectSize C_GetObjectSize;
+ CK_C_GetAttributeValue C_GetAttributeValue;
+ CK_C_SetAttributeValue C_SetAttributeValue;
+ CK_C_FindObjectsInit C_FindObjectsInit;
+ CK_C_FindObjects C_FindObjects;
+ CK_C_FindObjectsFinal C_FindObjectsFinal;
+ CK_C_EncryptInit C_EncryptInit;
+ CK_C_Encrypt C_Encrypt;
+ CK_C_EncryptUpdate C_EncryptUpdate;
+ CK_C_EncryptFinal C_EncryptFinal;
+ CK_C_DecryptInit C_DecryptInit;
+ CK_C_Decrypt C_Decrypt;
+ CK_C_DecryptUpdate C_DecryptUpdate;
+ CK_C_DecryptFinal C_DecryptFinal;
+ CK_C_DigestInit C_DigestInit;
+ CK_C_Digest C_Digest;
+ CK_C_DigestUpdate C_DigestUpdate;
+ CK_C_DigestKey C_DigestKey;
+ CK_C_DigestFinal C_DigestFinal;
+ CK_C_SignInit C_SignInit;
+ CK_C_Sign C_Sign;
+ CK_C_SignUpdate C_SignUpdate;
+ CK_C_SignFinal C_SignFinal;
+ CK_C_SignRecoverInit C_SignRecoverInit;
+ CK_C_SignRecover C_SignRecover;
+ CK_C_VerifyInit C_VerifyInit;
+ CK_C_Verify C_Verify;
+ CK_C_VerifyUpdate C_VerifyUpdate;
+ CK_C_VerifyFinal C_VerifyFinal;
+ CK_C_VerifyRecoverInit C_VerifyRecoverInit;
+ CK_C_VerifyRecover C_VerifyRecover;
+ CK_C_DigestEncryptUpdate C_DigestEncryptUpdate;
+ CK_C_DecryptDigestUpdate C_DecryptDigestUpdate;
+ CK_C_SignEncryptUpdate C_SignEncryptUpdate;
+ CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate;
+ CK_C_GenerateKey C_GenerateKey;
+ CK_C_GenerateKeyPair C_GenerateKeyPair;
+ CK_C_WrapKey C_WrapKey;
+ CK_C_UnwrapKey C_UnwrapKey;
+ CK_C_DeriveKey C_DeriveKey;
+ CK_C_SeedRandom C_SeedRandom;
+ CK_C_GenerateRandom C_GenerateRandom;
+ CK_C_GetFunctionStatus C_GetFunctionStatus;
+ CK_C_CancelFunction C_CancelFunction;
+ CK_C_WaitForSlotEvent C_WaitForSlotEvent;
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _PKCS11TYPES_H_
diff --git a/contrib/pkcs11-keygen/openssl-0.9.8g-patch b/contrib/pkcs11-keygen/openssl-0.9.8g-patch
deleted file mode 100644
index 6d93c687..00000000
--- a/contrib/pkcs11-keygen/openssl-0.9.8g-patch
+++ /dev/null
@@ -1,8715 +0,0 @@
-diff -r -u -N openssl-0.9.8g/Configure openssl/Configure
---- openssl-0.9.8g/Configure 2007-09-16 14:24:17.000000000 +0200
-+++ openssl/Configure 2007-10-25 01:27:08.000000000 +0200
-@@ -10,7 +10,7 @@
-
- # see INSTALL for instructions.
-
--my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
-+my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
-
- # Options:
- #
-@@ -19,6 +19,9 @@
- # --prefix prefix for the OpenSSL include, lib and bin directories
- # (Default: the OPENSSLDIR directory)
- #
-+# --pk11_libname PKCS#11 library name.
-+# (Default: none)
-+#
- # --install_prefix Additional prefix for package builders (empty by
- # default). This needn't be set in advance, you can
- # just as well use "make INSTALL_PREFIX=/whatever install".
-@@ -560,6 +563,8 @@
- my $idx_ranlib = $idx++;
- my $idx_arflags = $idx++;
-
-+my $pk11_libname="";
-+
- my $prefix="";
- my $openssldir="";
- my $exe_ext="";
-@@ -738,6 +743,10 @@
- {
- $flags.=$_." ";
- }
-+ elsif (/^--pk11-libname=(.*)$/)
-+ {
-+ $pk11_libname=$1;
-+ }
- elsif (/^--prefix=(.*)$/)
- {
- $prefix=$1;
-@@ -861,6 +870,13 @@
- exit 0;
- }
-
-+if (! $pk11_libname)
-+ {
-+ print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
-+ print STDERR "See README.pkcs11 for more information.\n";
-+ exit 1;
-+ }
-+
- if ($target =~ m/^CygWin32(-.*)$/) {
- $target = "Cygwin".$1;
- }
-@@ -986,6 +1002,8 @@
- if ($flags ne "") { $cflags="$flags$cflags"; }
- else { $no_user_cflags=1; }
-
-+$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
-+
- # Kerberos settings. The flavor must be provided from outside, either through
- # the script "config" or manually.
- if (!$no_krb5)
-@@ -1319,6 +1337,7 @@
- s/^VERSION=.*/VERSION=$version/;
- s/^MAJOR=.*/MAJOR=$major/;
- s/^MINOR=.*/MINOR=$minor/;
-+ s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
- s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
- s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
- s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
-diff -r -u -N openssl-0.9.8g/crypto/engine/cryptoki.h openssl/crypto/engine/cryptoki.h
---- openssl-0.9.8g/crypto/engine/cryptoki.h 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/cryptoki.h 2007-10-25 01:27:09.000000000 +0200
-@@ -0,0 +1,103 @@
-+/*
-+ * CDDL HEADER START
-+ *
-+ * The contents of this file are subject to the terms of the
-+ * Common Development and Distribution License, Version 1.0 only
-+ * (the "License"). You may not use this file except in compliance
-+ * with the License.
-+ *
-+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-+ * or http://www.opensolaris.org/os/licensing.
-+ * See the License for the specific language governing permissions
-+ * and limitations under the License.
-+ *
-+ * When distributing Covered Code, include this CDDL HEADER in each
-+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-+ * If applicable, add the following below this CDDL HEADER, with the
-+ * fields enclosed by brackets "[]" replaced with your own identifying
-+ * information: Portions Copyright [yyyy] [name of copyright owner]
-+ *
-+ * CDDL HEADER END
-+ */
-+/*
-+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
-+
-+#ifndef _CRYPTOKI_H
-+#define _CRYPTOKI_H
-+
-+#pragma ident "@(#)cryptoki.h 1.2 05/06/08 SMI"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#ifndef CK_PTR
-+#define CK_PTR *
-+#endif
-+
-+#ifndef CK_DEFINE_FUNCTION
-+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
-+#endif
-+
-+#ifndef CK_DECLARE_FUNCTION
-+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
-+#endif
-+
-+#ifndef CK_DECLARE_FUNCTION_POINTER
-+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
-+#endif
-+
-+#ifndef CK_CALLBACK_FUNCTION
-+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
-+#endif
-+
-+#ifndef NULL_PTR
-+#include <unistd.h> /* For NULL */
-+#define NULL_PTR NULL
-+#endif
-+
-+/*
-+ * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
-+ */
-+#ifndef CK_DISABLE_TRUE_FALSE
-+#define CK_DISABLE_TRUE_FALSE
-+#ifndef TRUE
-+#define TRUE 1
-+#endif /* TRUE */
-+#ifndef FALSE
-+#define FALSE 0
-+#endif /* FALSE */
-+#endif /* CK_DISABLE_TRUE_FALSE */
-+
-+#undef CK_PKCS11_FUNCTION_INFO
-+
-+#include "pkcs11.h"
-+
-+/* Solaris specific functions */
-+
-+#include <stdlib.h>
-+
-+/*
-+ * SUNW_C_GetMechSession will initialize the framework and do all
-+ * the necessary PKCS#11 calls to create a session capable of
-+ * providing operations on the requested mechanism
-+ */
-+CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
-+ CK_SESSION_HANDLE_PTR hSession);
-+
-+/*
-+ * SUNW_C_KeyToObject will create a secret key object for the given
-+ * mechanism from the rawkey data.
-+ */
-+CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
-+ CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
-+ CK_OBJECT_HANDLE_PTR obj);
-+
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _CRYPTOKI_H */
-diff -r -u -N openssl-0.9.8g/crypto/engine/eng_all.c openssl/crypto/engine/eng_all.c
---- openssl-0.9.8g/crypto/engine/eng_all.c 2007-01-04 23:55:25.000000000 +0100
-+++ openssl/crypto/engine/eng_all.c 2007-10-25 01:27:09.000000000 +0200
-@@ -107,6 +107,9 @@
- #if defined(__OpenBSD__) || defined(__FreeBSD__)
- ENGINE_load_cryptodev();
- #endif
-+#ifndef OPENSSL_NO_HW_PKCS11
-+ ENGINE_load_pk11();
-+#endif
- #endif
- }
-
-diff -r -u -N openssl-0.9.8g/crypto/engine/engine.h openssl/crypto/engine/engine.h
---- openssl-0.9.8g/crypto/engine/engine.h 2005-11-06 18:48:59.000000000 +0100
-+++ openssl/crypto/engine/engine.h 2007-10-25 01:27:09.000000000 +0200
-@@ -332,6 +332,7 @@
- void ENGINE_load_ubsec(void);
- #endif
- void ENGINE_load_cryptodev(void);
-+void ENGINE_load_pk11(void);
- void ENGINE_load_padlock(void);
- void ENGINE_load_builtin_engines(void);
-
-diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11.c openssl/crypto/engine/hw_pk11.c
---- openssl-0.9.8g/crypto/engine/hw_pk11.c 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/hw_pk11.c 2007-10-29 23:31:11.000000000 +0100
-@@ -0,0 +1,2153 @@
-+/*
-+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
-+
-+#pragma ident "@(#)hw_pk11.c 1.12 07/07/05 SMI"
-+
-+/* crypto/engine/hw_pk11.c */
-+/* This product includes software developed by the OpenSSL Project for
-+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
-+ *
-+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
-+ * Afchine Madjlessi.
-+ */
-+/* ====================================================================
-+ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ *
-+ * 3. All advertising materials mentioning features or use of this
-+ * software must display the following acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
-+ *
-+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
-+ * endorse or promote products derived from this software without
-+ * prior written permission. For written permission, please contact
-+ * licensing@OpenSSL.org.
-+ *
-+ * 5. Products derived from this software may not be called "OpenSSL"
-+ * nor may "OpenSSL" appear in their names without prior written
-+ * permission of the OpenSSL Project.
-+ *
-+ * 6. Redistributions of any form whatsoever must retain the following
-+ * acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
-+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ * ====================================================================
-+ *
-+ * This product includes cryptographic software written by Eric Young
-+ * (eay@cryptsoft.com). This product includes software written by Tim
-+ * Hudson (tjh@cryptsoft.com).
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <assert.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+
-+#include <openssl/e_os2.h>
-+#include <openssl/engine.h>
-+#include <openssl/dso.h>
-+#include <openssl/err.h>
-+#include <openssl/bn.h>
-+#include <openssl/md5.h>
-+#include <openssl/pem.h>
-+#include <openssl/rsa.h>
-+#include <openssl/rand.h>
-+#include <openssl/objects.h>
-+#include <openssl/x509.h>
-+#include <cryptlib.h>
-+
-+#ifndef OPENSSL_NO_HW
-+#ifndef OPENSSL_NO_HW_PK11
-+
-+#undef DEBUG_SLOT_SELECTION
-+
-+#include "cryptoki.h"
-+#include "pkcs11.h"
-+#include "hw_pk11_err.c"
-+
-+
-+/* The head of the free PK11 session list */
-+static struct PK11_SESSION_st *free_session = NULL;
-+
-+/* Create all secret key objects in a global session so that they are available
-+ * to use for other sessions. These other sessions may be opened or closed
-+ * without losing the secret key objects */
-+static CK_SESSION_HANDLE global_session = CK_INVALID_HANDLE;
-+
-+/* ENGINE level stuff */
-+static int pk11_init(ENGINE *e);
-+static int pk11_library_init(ENGINE *e);
-+static int pk11_finish(ENGINE *e);
-+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
-+static int pk11_destroy(ENGINE *e);
-+
-+/* RAND stuff */
-+static void pk11_rand_seed(const void *buf, int num);
-+static void pk11_rand_add(const void *buf, int num, double add_entropy);
-+static void pk11_rand_cleanup(void);
-+static int pk11_rand_bytes(unsigned char *buf, int num);
-+static int pk11_rand_status(void);
-+
-+/* These functions are also used in other files */
-+PK11_SESSION *pk11_get_session();
-+void pk11_return_session(PK11_SESSION *sp);
-+int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-+int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-+int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-+
-+/* Local helper functions */
-+static int pk11_free_all_sessions();
-+static int pk11_setup_session(PK11_SESSION *sp);
-+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
-+static int pk11_destroy_object(CK_SESSION_HANDLE session,
-+ CK_OBJECT_HANDLE oh);
-+static const char *get_PK11_LIBNAME(void);
-+static void free_PK11_LIBNAME(void);
-+static long set_PK11_LIBNAME(const char *name);
-+
-+/* Symmetric cipher and digest support functions */
-+static int cipher_nid_to_pk11(int nid);
-+static int pk11_usable_ciphers(const int **nids);
-+static int pk11_usable_digests(const int **nids);
-+static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+ const unsigned char *iv, int enc);
-+static int pk11_cipher_final(PK11_SESSION *sp);
-+static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+ const unsigned char *in, unsigned int inl);
-+static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
-+static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+ const int **nids, int nid);
-+static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-+ const int **nids, int nid);
-+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-+ const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
-+static void check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key);
-+static int md_nid_to_pk11(int nid);
-+static int pk11_digest_init(EVP_MD_CTX *ctx);
-+static int pk11_digest_update(EVP_MD_CTX *ctx,const void *data,
-+ size_t count);
-+static int pk11_digest_final(EVP_MD_CTX *ctx,unsigned char *md);
-+static int pk11_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
-+static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
-+
-+static int pk11_choose_slot();
-+static int pk11_count_symmetric_cipher(int slot_id, CK_MECHANISM_TYPE mech,
-+ int *current_slot_n_cipher, int *local_cipher_nids, int id);
-+static int pk11_count_digest(int slot_id, CK_MECHANISM_TYPE mech,
-+ int *current_slot_n_digest, int *local_digest_nids, int id);
-+
-+/* Index for the supported ciphers */
-+#define PK11_DES_CBC 0
-+#define PK11_DES3_CBC 1
-+#define PK11_AES_CBC 2
-+#define PK11_RC4 3
-+
-+/* Index for the supported digests */
-+#define PK11_MD5 0
-+#define PK11_SHA1 1
-+
-+#define PK11_CIPHER_MAX 4 /* Max num of ciphers supported */
-+#define PK11_DIGEST_MAX 2 /* Max num of digests supported */
-+
-+#define PK11_KEY_LEN_MAX 24
-+
-+static int cipher_nids[PK11_CIPHER_MAX];
-+static int digest_nids[PK11_DIGEST_MAX];
-+static int cipher_count = 0;
-+static int digest_count = 0;
-+static CK_BBOOL pk11_have_rsa = CK_FALSE;
-+static CK_BBOOL pk11_have_dsa = CK_FALSE;
-+static CK_BBOOL pk11_have_dh = CK_FALSE;
-+static CK_BBOOL pk11_have_random = CK_FALSE;
-+
-+typedef struct PK11_CIPHER_st
-+ {
-+ int id;
-+ int nid;
-+ int ivmax;
-+ int key_len;
-+ CK_KEY_TYPE key_type;
-+ CK_MECHANISM_TYPE mech_type;
-+ } PK11_CIPHER;
-+
-+static PK11_CIPHER ciphers[] =
-+ {
-+ {PK11_DES_CBC, NID_des_cbc, 8, 8, CKK_DES, CKM_DES_CBC, },
-+ {PK11_DES3_CBC, NID_des_ede3_cbc, 8, 24, CKK_DES3, CKM_DES3_CBC, },
-+ {PK11_AES_CBC, NID_aes_128_cbc, 16, 16, CKK_AES, CKM_AES_CBC, },
-+ {PK11_RC4, NID_rc4, 0, 16, CKK_RC4, CKM_RC4, },
-+ };
-+
-+typedef struct PK11_DIGEST_st
-+ {
-+ int id;
-+ int nid;
-+ CK_MECHANISM_TYPE mech_type;
-+ } PK11_DIGEST;
-+
-+static PK11_DIGEST digests[] =
-+ {
-+ {PK11_MD5, NID_md5, CKM_MD5, },
-+ {PK11_SHA1, NID_sha1, CKM_SHA_1, },
-+ {0, NID_undef, 0xFFFF, },
-+ };
-+
-+/* Structure to be used for the cipher_data/md_data in
-+ * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same
-+ * pk11 session in multiple cipher_update calls
-+ */
-+typedef struct PK11_CIPHER_STATE_st
-+ {
-+ PK11_SESSION *sp;
-+ } PK11_CIPHER_STATE;
-+
-+
-+/* libcrypto EVP stuff - this is how we get wired to EVP so the engine
-+ * gets called when libcrypto requests a cipher NID.
-+ * Note how the PK11_CIPHER_STATE is used here.
-+ */
-+
-+/* DES CBC EVP */
-+static const EVP_CIPHER pk11_des_cbc =
-+ {
-+ NID_des_cbc,
-+ 8, 8, 8,
-+ EVP_CIPH_CBC_MODE,
-+ pk11_cipher_init,
-+ pk11_cipher_do_cipher,
-+ pk11_cipher_cleanup,
-+ sizeof(PK11_CIPHER_STATE),
-+ EVP_CIPHER_set_asn1_iv,
-+ EVP_CIPHER_get_asn1_iv,
-+ NULL
-+ };
-+
-+/* 3DES CBC EVP */
-+static const EVP_CIPHER pk11_3des_cbc =
-+ {
-+ NID_des_ede3_cbc,
-+ 8, 24, 8,
-+ EVP_CIPH_CBC_MODE,
-+ pk11_cipher_init,
-+ pk11_cipher_do_cipher,
-+ pk11_cipher_cleanup,
-+ sizeof(PK11_CIPHER_STATE),
-+ EVP_CIPHER_set_asn1_iv,
-+ EVP_CIPHER_get_asn1_iv,
-+ NULL
-+ };
-+
-+static const EVP_CIPHER pk11_aes_cbc =
-+ {
-+ NID_aes_128_cbc,
-+ 16, 16, 16,
-+ EVP_CIPH_CBC_MODE,
-+ pk11_cipher_init,
-+ pk11_cipher_do_cipher,
-+ pk11_cipher_cleanup,
-+ sizeof(PK11_CIPHER_STATE),
-+ EVP_CIPHER_set_asn1_iv,
-+ EVP_CIPHER_get_asn1_iv,
-+ NULL
-+ };
-+
-+static const EVP_CIPHER pk11_rc4 =
-+ {
-+ NID_rc4,
-+ 1,16,0,
-+ EVP_CIPH_VARIABLE_LENGTH,
-+ pk11_cipher_init,
-+ pk11_cipher_do_cipher,
-+ pk11_cipher_cleanup,
-+ sizeof(PK11_CIPHER_STATE),
-+ NULL,
-+ NULL,
-+ NULL
-+ };
-+
-+static const EVP_MD pk11_md5 =
-+ {
-+ NID_md5,
-+ NID_md5WithRSAEncryption,
-+ MD5_DIGEST_LENGTH,
-+ 0,
-+ pk11_digest_init,
-+ pk11_digest_update,
-+ pk11_digest_final,
-+ pk11_digest_copy,
-+ pk11_digest_cleanup,
-+ EVP_PKEY_RSA_method,
-+ MD5_CBLOCK,
-+ sizeof(PK11_CIPHER_STATE),
-+ };
-+
-+static const EVP_MD pk11_sha1 =
-+ {
-+ NID_sha1,
-+ NID_sha1WithRSAEncryption,
-+ SHA_DIGEST_LENGTH,
-+ 0,
-+ pk11_digest_init,
-+ pk11_digest_update,
-+ pk11_digest_final,
-+ pk11_digest_copy,
-+ pk11_digest_cleanup,
-+ EVP_PKEY_RSA_method,
-+ SHA_CBLOCK,
-+ sizeof(PK11_CIPHER_STATE),
-+ };
-+
-+/* Initialization function. Sets up various pk11 library components.
-+ */
-+/* The definitions for control commands specific to this engine
-+ */
-+#define PK11_CMD_SO_PATH ENGINE_CMD_BASE
-+#define PK11_CMD_PIN (ENGINE_CMD_BASE+1)
-+#define PK11_CMD_SLOT (ENGINE_CMD_BASE+2)
-+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
-+ {
-+ {
-+ PK11_CMD_SO_PATH,
-+ "SO_PATH",
-+ "Specifies the path to the 'pkcs#11' shared library",
-+ ENGINE_CMD_FLAG_STRING
-+ },
-+ {
-+ PK11_CMD_PIN,
-+ "PIN",
-+ "Specifies the pin code",
-+ ENGINE_CMD_FLAG_STRING
-+ },
-+ {
-+ PK11_CMD_SLOT,
-+ "SLOT",
-+ "Specifies the slot (default is auto select)",
-+ ENGINE_CMD_FLAG_NUMERIC,
-+ },
-+ {0, NULL, NULL, 0}
-+ };
-+
-+
-+static RAND_METHOD pk11_random =
-+ {
-+ pk11_rand_seed,
-+ pk11_rand_bytes,
-+ pk11_rand_cleanup,
-+ pk11_rand_add,
-+ pk11_rand_bytes,
-+ pk11_rand_status
-+ };
-+
-+
-+/* Constants used when creating the ENGINE
-+ */
-+static const char *engine_pk11_id = "pkcs11";
-+static const char *engine_pk11_name = "PKCS #11 engine support";
-+
-+CK_FUNCTION_LIST_PTR pFuncList = NULL;
-+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
-+
-+/* Cryptoki library
-+ */
-+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
-+
-+static CK_BBOOL true = TRUE;
-+static CK_BBOOL false = FALSE;
-+static CK_SLOT_ID SLOTID = 0;
-+static int pk11_auto_slot = 1;
-+char *pk11_pin;
-+static int pk11_library_initialized = 0;
-+
-+static DSO *pk11_dso = NULL;
-+
-+/*
-+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
-+ */
-+static int bind_pk11(ENGINE *e)
-+ {
-+ const RSA_METHOD *rsa = NULL;
-+ RSA_METHOD *pk11_rsa = PK11_RSA();
-+
-+ if (!pk11_library_initialized)
-+ pk11_library_init(e);
-+
-+ if(!ENGINE_set_id(e, engine_pk11_id) ||
-+ !ENGINE_set_name(e, engine_pk11_name) ||
-+ !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
-+ !ENGINE_set_digests(e, pk11_engine_digests))
-+ return 0;
-+#ifndef OPENSSL_NO_RSA
-+ if(pk11_have_rsa == CK_TRUE)
-+ {
-+ if(!ENGINE_set_RSA(e, PK11_RSA()) ||
-+ !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
-+ !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
-+ return 0;
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered RSA\n");
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+ if(pk11_have_dsa == CK_TRUE)
-+ {
-+ if (!ENGINE_set_DSA(e, PK11_DSA()))
-+ return 0;
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered DSA\n");
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+#endif
-+#ifndef OPENSSL_NO_DH
-+ if(pk11_have_dh == CK_TRUE)
-+ {
-+ if (!ENGINE_set_DH(e, PK11_DH()))
-+ return 0;
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered DH\n");
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+#endif
-+ if(pk11_have_random)
-+ {
-+ if(!ENGINE_set_RAND(e, &pk11_random))
-+ return 0;
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered random\n");
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+ if(!ENGINE_set_init_function(e, pk11_init) ||
-+ !ENGINE_set_destroy_function(e, pk11_destroy) ||
-+ !ENGINE_set_finish_function(e, pk11_finish) ||
-+ !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
-+ !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
-+ return 0;
-+
-+/* Apache calls OpenSSL function RSA_blinding_on() once during startup
-+ * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
-+ * here, we wire it back to the OpenSSL software implementation.
-+ * Since it is used only once, performance is not a concern. */
-+#ifndef OPENSSL_NO_RSA
-+ rsa = RSA_PKCS1_SSLeay();
-+ pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
-+ pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
-+#endif
-+
-+ /* Ensure the pk11 error handling is set up */
-+ ERR_load_pk11_strings();
-+
-+ return 1;
-+ }
-+
-+/* Dynamic engine support is disabled at a higher level for Solaris
-+ */
-+#ifdef ENGINE_DYNAMIC_SUPPORT
-+static int bind_helper(ENGINE *e, const char *id)
-+ {
-+ if (id && (strcmp(id, engine_pk11_id) != 0))
-+ return 0;
-+
-+ if (!bind_pk11(e))
-+ return 0;
-+
-+ return 1;
-+ }
-+
-+IMPLEMENT_DYNAMIC_CHECK_FN()
-+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
-+
-+#else
-+static ENGINE *engine_pk11(void)
-+ {
-+ ENGINE *ret = ENGINE_new();
-+
-+ if (!ret)
-+ return NULL;
-+
-+ if (!bind_pk11(ret))
-+ {
-+ ENGINE_free(ret);
-+ return NULL;
-+ }
-+
-+ return ret;
-+ }
-+
-+void ENGINE_load_pk11(void)
-+ {
-+ ENGINE *e_pk11 = NULL;
-+
-+ /* Do not use dynamic PKCS#11 library on Solaris due to
-+ * security reasons. We will link it in statically
-+ */
-+ /* Attempt to load PKCS#11 library
-+ */
-+ if (!pk11_dso)
-+ pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
-+
-+ if (pk11_dso == NULL)
-+ {
-+ PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
-+ return;
-+ }
-+
-+ e_pk11 = engine_pk11();
-+ if (!e_pk11)
-+ {
-+ DSO_free(pk11_dso);
-+ pk11_dso = NULL;
-+ return;
-+ }
-+
-+ /* At this point, the pk11 shared library is either dynamically
-+ * loaded or statically linked in. So, initialize the pk11
-+ * library before calling ENGINE_set_default since the latter
-+ * needs cipher and digest algorithm information
-+ */
-+ if (!pk11_library_init(e_pk11))
-+ {
-+ DSO_free(pk11_dso);
-+ pk11_dso = NULL;
-+ ENGINE_free(e_pk11);
-+ return;
-+ }
-+
-+ ENGINE_add(e_pk11);
-+
-+ ENGINE_free(e_pk11);
-+ ERR_clear_error();
-+ }
-+#endif
-+
-+/* These are the static string constants for the DSO file name and
-+ * the function symbol names to bind to.
-+ */
-+static const char *PK11_LIBNAME = NULL;
-+
-+static const char *get_PK11_LIBNAME(void)
-+ {
-+ if (PK11_LIBNAME)
-+ return PK11_LIBNAME;
-+
-+ return def_PK11_LIBNAME;
-+ }
-+
-+static void free_PK11_LIBNAME(void)
-+ {
-+ if (PK11_LIBNAME)
-+ OPENSSL_free((void*)PK11_LIBNAME);
-+
-+ PK11_LIBNAME = NULL;
-+ }
-+
-+static long set_PK11_LIBNAME(const char *name)
-+ {
-+ free_PK11_LIBNAME();
-+
-+ return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
-+ }
-+
-+/* Initialization function for the pk11 engine */
-+static int pk11_init(ENGINE *e)
-+{
-+ return pk11_library_init(e);
-+}
-+
-+/* Initialization function. Sets up various pk11 library components.
-+ * It selects a slot based on predefined critiera. In the process, it also
-+ * count how many ciphers and digests to support. Since the cipher and
-+ * digest information is needed when setting default engine, this function
-+ * needs to be called before calling ENGINE_set_default.
-+ */
-+static int pk11_library_init(ENGINE *e)
-+ {
-+ CK_C_GetFunctionList p;
-+ CK_RV rv = CKR_OK;
-+ CK_INFO info;
-+ CK_ULONG ul_state_len;
-+ char tmp_buf[20];
-+
-+ if (pk11_library_initialized)
-+ return 1;
-+
-+ if (pk11_dso == NULL)
-+ {
-+ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-+ goto err;
-+ }
-+
-+ /* get the C_GetFunctionList function from the loaded library
-+ */
-+ p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
-+ PK11_GET_FUNCTION_LIST);
-+ if ( !p )
-+ {
-+ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-+ goto err;
-+ }
-+
-+ /* get the full function list from the loaded library
-+ */
-+ rv = p(&pFuncList);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_Initialize(NULL_PTR);
-+ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-+ {
-+ PK11err(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_GetInfo(&info);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_LIBRARY_INIT, PK11_R_GETINFO);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (pk11_choose_slot() == 0)
-+ goto err;
-+
-+ if (global_session == CK_INVALID_HANDLE)
-+ {
-+ /* Open the global_session for the new process */
-+ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-+ NULL_PTR, NULL_PTR, &global_session);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_LIBRARY_INIT, PK11_R_OPENSESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ }
-+
-+ /* Disable digest if C_GetOperationState is not supported since
-+ * this function is required by OpenSSL digest copy function */
-+ if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
-+ == CKR_FUNCTION_NOT_SUPPORTED)
-+ digest_count = 0;
-+
-+ pk11_library_initialized = 1;
-+ return 1;
-+
-+err:
-+
-+ return 0;
-+ }
-+
-+/* Destructor (complements the "ENGINE_pk11()" constructor)
-+ */
-+static int pk11_destroy(ENGINE *e)
-+ {
-+ free_PK11_LIBNAME();
-+ ERR_unload_pk11_strings();
-+ if (pk11_pin) {
-+ memset(pk11_pin, 0, strlen(pk11_pin));
-+ OPENSSL_free((void*)pk11_pin);
-+ }
-+ pk11_pin = NULL;
-+ return 1;
-+ }
-+
-+/* Termination function to clean up the session, the token, and
-+ * the pk11 library.
-+ */
-+static int pk11_finish(ENGINE *e)
-+ {
-+
-+ if (pk11_pin) {
-+ memset(pk11_pin, 0, strlen(pk11_pin));
-+ OPENSSL_free((void*)pk11_pin);
-+ }
-+ pk11_pin = NULL;
-+
-+ if (pk11_dso == NULL)
-+ {
-+ PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
-+ goto err;
-+ }
-+
-+ assert(pFuncList != NULL);
-+
-+ if (pk11_free_all_sessions() == 0)
-+ goto err;
-+
-+ pFuncList->C_CloseSession(global_session);
-+
-+ /* Since we are part of a library (libcrypto.so), calling this
-+ * function may have side-effects.
-+ pFuncList->C_Finalize(NULL);
-+ */
-+
-+ if (!DSO_free(pk11_dso))
-+ {
-+ PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
-+ goto err;
-+ }
-+ pk11_dso = NULL;
-+ pFuncList = NULL;
-+ pk11_library_initialized = 0;
-+
-+ return 1;
-+
-+err:
-+ return 0;
-+ }
-+
-+/* Standard engine interface function to set the dynamic library path */
-+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
-+ {
-+ int initialized = ((pk11_dso == NULL) ? 0 : 1);
-+
-+ switch(cmd)
-+ {
-+ case PK11_CMD_SO_PATH:
-+ if (p == NULL)
-+ {
-+ PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-+ return 0;
-+ }
-+
-+ if (initialized)
-+ {
-+ PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
-+ return 0;
-+ }
-+
-+ return set_PK11_LIBNAME((const char*)p);
-+ case PK11_CMD_PIN:
-+ if (pk11_pin) {
-+ memset(pk11_pin, 0, strlen(pk11_pin));
-+ OPENSSL_free((void*)pk11_pin);
-+ }
-+ pk11_pin = NULL;
-+
-+ if (p == NULL)
-+ {
-+ PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-+ return 0;
-+ }
-+
-+ pk11_pin = BUF_strdup(p);
-+ if (pk11_pin == NULL)
-+ {
-+ PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
-+ return 0;
-+ }
-+ return 1;
-+ case PK11_CMD_SLOT:
-+ SLOTID = (CK_SLOT_ID)i;
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: slot set\n");
-+#endif
-+ return 1;
-+ default:
-+ break;
-+ }
-+
-+ PK11err(PK11_F_CTRL,PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
-+
-+ return 0;
-+ }
-+
-+
-+/* Required function by the engine random interface. It does nothing here
-+ */
-+static void pk11_rand_cleanup(void)
-+ {
-+ return;
-+ }
-+
-+static void pk11_rand_add(const void *buf, int num, double add)
-+ {
-+ PK11_SESSION *sp;
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return;
-+
-+ /* Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
-+ * the calling functions do not care anyway
-+ */
-+ pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
-+ pk11_return_session(sp);
-+
-+ return;
-+ }
-+
-+static void pk11_rand_seed(const void *buf, int num)
-+ {
-+ pk11_rand_add(buf, num, 0);
-+ }
-+
-+static int pk11_rand_bytes(unsigned char *buf, int num)
-+ {
-+ CK_RV rv;
-+ PK11_SESSION *sp;
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return 0;
-+
-+ rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return 0;
-+ }
-+
-+ pk11_return_session(sp);
-+ return 1;
-+ }
-+
-+
-+/* Required function by the engine random interface. It does nothing here
-+ */
-+static int pk11_rand_status(void)
-+ {
-+ return 1;
-+ }
-+
-+
-+PK11_SESSION *pk11_get_session()
-+ {
-+ PK11_SESSION *sp, *sp1;
-+ CK_RV rv;
-+ char tmp_buf[20];
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if ((sp = free_session) == NULL)
-+ {
-+ if ((sp = OPENSSL_malloc(sizeof(PK11_SESSION))) == NULL)
-+ {
-+ PK11err(PK11_F_GET_SESSION,
-+ PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ memset(sp, 0, sizeof(PK11_SESSION));
-+ }
-+ else
-+ {
-+ free_session = sp->next;
-+ }
-+
-+ if (sp->pid != 0 && sp->pid != getpid())
-+ {
-+ /* We are a new process and thus need to free any inherated
-+ * PK11_SESSION objects.
-+ */
-+ while ((sp1 = free_session) != NULL)
-+ {
-+ free_session = sp1->next;
-+ OPENSSL_free(sp1);
-+ }
-+
-+ /* Initialize the process */
-+ rv = pFuncList->C_Initialize(NULL_PTR);
-+ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-+ {
-+ PK11err(PK11_F_GET_SESSION, PK11_R_INITIALIZE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ OPENSSL_free(sp);
-+ sp = NULL;
-+ goto err;
-+ }
-+
-+ /* Choose slot here since the slot table is different on
-+ * this process.
-+ */
-+ if (pk11_choose_slot() == 0)
-+ goto err;
-+
-+ /* Open the global_session for the new process */
-+ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-+ NULL_PTR, NULL_PTR, &global_session);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_SESSION, PK11_R_OPENSESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ OPENSSL_free(sp);
-+ sp = NULL;
-+ goto err;
-+ }
-+
-+ /* It is an inherited session and needs re-initialization.
-+ */
-+ if (pk11_setup_session(sp) == 0)
-+ {
-+ OPENSSL_free(sp);
-+ sp = NULL;
-+ }
-+ }
-+ else if (sp->pid == 0)
-+ {
-+ /* It is a new session and needs initialization.
-+ */
-+ if (pk11_setup_session(sp) == 0)
-+ {
-+ OPENSSL_free(sp);
-+ sp = NULL;
-+ }
-+ }
-+
-+err:
-+ if (sp)
-+ sp->next = NULL;
-+
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ return sp;
-+ }
-+
-+
-+void pk11_return_session(PK11_SESSION *sp)
-+ {
-+ if (sp == NULL || sp->pid != getpid())
-+ return;
-+
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ sp->next = free_session;
-+ free_session = sp;
-+
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ }
-+
-+
-+/* Destroy all objects. This function is called when the engine is finished
-+ */
-+static int pk11_free_all_sessions()
-+ {
-+ CK_RV rv;
-+ PK11_SESSION *sp = NULL;
-+ pid_t mypid = getpid();
-+ int ret = 0;
-+
-+ pk11_destroy_rsa_key_objects(NULL);
-+ pk11_destroy_dsa_key_objects(NULL);
-+ pk11_destroy_dh_key_objects(NULL);
-+ pk11_destroy_cipher_key_objects(NULL);
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ while ((sp = free_session) != NULL)
-+ {
-+ if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
-+ {
-+ rv = pFuncList->C_CloseSession(sp->session);
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_FREE_ALL_SESSIONS,
-+ PK11_R_CLOSESESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ }
-+ }
-+ if (sp->session_cipher != CK_INVALID_HANDLE && sp->pid == mypid)
-+ {
-+ rv = pFuncList->C_CloseSession(sp->session_cipher);
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_FREE_ALL_SESSIONS,
-+ PK11_R_CLOSESESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ }
-+ }
-+ free_session = sp->next;
-+ OPENSSL_free(sp);
-+ }
-+ ret = 1;
-+err:
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ return ret;
-+ }
-+
-+
-+static int pk11_setup_session(PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ sp->session = CK_INVALID_HANDLE;
-+ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-+ NULL_PTR, NULL_PTR, &sp->session);
-+ if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
-+ {
-+ /*
-+ * We are probably a child process so force the
-+ * reinitialize of the session
-+ */
-+ pk11_library_initialized = 0;
-+ (void) pk11_library_init(NULL);
-+ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-+ NULL_PTR, NULL_PTR, &sp->session);
-+ }
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return 0;
-+ }
-+
-+ sp->session_cipher = CK_INVALID_HANDLE;
-+ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-+ NULL_PTR, NULL_PTR, &sp->session_cipher);
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+
-+ (void) pFuncList->C_CloseSession(sp->session);
-+ sp->session = CK_INVALID_HANDLE;
-+
-+ PK11err(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return 0;
-+ }
-+
-+ sp->pid = getpid();
-+ sp->rsa_pub_key = CK_INVALID_HANDLE;
-+ sp->rsa_priv_key = CK_INVALID_HANDLE;
-+ sp->dsa_pub_key = CK_INVALID_HANDLE;
-+ sp->dsa_priv_key = CK_INVALID_HANDLE;
-+ sp->dh_key = CK_INVALID_HANDLE;
-+ sp->cipher_key = CK_INVALID_HANDLE;
-+ sp->rsa = NULL;
-+ sp->dsa = NULL;
-+ sp->dh = NULL;
-+ sp->encrypt = -1;
-+
-+ return 1;
-+ }
-+
-+int pk11_destroy_rsa_key_objects(PK11_SESSION *session)
-+ {
-+ int ret = 0;
-+ PK11_SESSION *sp = NULL;
-+ PK11_SESSION *local_free_session;
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if (session)
-+ local_free_session = session;
-+ else
-+ local_free_session = free_session;
-+ while ((sp = local_free_session) != NULL)
-+ {
-+ local_free_session = sp->next;
-+
-+ if (sp->rsa_pub_key != CK_INVALID_HANDLE)
-+ {
-+ if (pk11_destroy_object(sp->session,
-+ sp->rsa_pub_key) == 0)
-+ goto err;
-+ sp->rsa_pub_key = CK_INVALID_HANDLE;
-+ }
-+
-+ if (sp->rsa_priv_key != CK_INVALID_HANDLE)
-+ {
-+ if ((sp->rsa->flags & RSA_FLAG_EXT_PKEY) == 0 &&
-+ pk11_destroy_object(sp->session,
-+ sp->rsa_priv_key) == 0)
-+ goto err;
-+ sp->rsa_priv_key = CK_INVALID_HANDLE;
-+ }
-+
-+ sp->rsa = NULL;
-+ }
-+ ret = 1;
-+err:
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ return ret;
-+ }
-+
-+int pk11_destroy_dsa_key_objects(PK11_SESSION *session)
-+ {
-+ int ret = 0;
-+ PK11_SESSION *sp = NULL;
-+ PK11_SESSION *local_free_session;
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if (session)
-+ local_free_session = session;
-+ else
-+ local_free_session = free_session;
-+ while ((sp = local_free_session) != NULL)
-+ {
-+ local_free_session = sp->next;
-+
-+ if (sp->dsa_pub_key != CK_INVALID_HANDLE)
-+ {
-+ if (pk11_destroy_object(sp->session,
-+ sp->dsa_pub_key) == 0)
-+ goto err;
-+ sp->dsa_pub_key = CK_INVALID_HANDLE;
-+ }
-+
-+ if (sp->dsa_priv_key != CK_INVALID_HANDLE)
-+ {
-+ if (pk11_destroy_object(sp->session,
-+ sp->dsa_priv_key) == 0)
-+ goto err;
-+ sp->dsa_priv_key = CK_INVALID_HANDLE;
-+ }
-+
-+ sp->dsa = NULL;
-+ }
-+ ret = 1;
-+err:
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ return ret;
-+ }
-+
-+int pk11_destroy_dh_key_objects(PK11_SESSION *session)
-+ {
-+ int ret = 0;
-+ PK11_SESSION *sp = NULL;
-+ PK11_SESSION *local_free_session;
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if (session)
-+ local_free_session = session;
-+ else
-+ local_free_session = free_session;
-+ while ((sp = local_free_session) != NULL)
-+ {
-+ local_free_session = sp->next;
-+
-+ if (sp->dh_key != CK_INVALID_HANDLE)
-+ {
-+ if (pk11_destroy_object(sp->session,
-+ sp->dh_key) == 0)
-+ goto err;
-+ sp->dh_key = CK_INVALID_HANDLE;
-+ }
-+
-+ sp->dh = NULL;
-+ }
-+ ret = 1;
-+err:
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ return ret;
-+ }
-+
-+static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh)
-+ {
-+ CK_RV rv;
-+ rv = pFuncList->C_DestroyObject(session, oh);
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X",
-+ tmp_buf);
-+ return 0;
-+ }
-+
-+ return 1;
-+ }
-+
-+
-+/* Symmetric ciphers and digests support functions
-+ */
-+
-+static int
-+cipher_nid_to_pk11(int nid)
-+ {
-+ int i;
-+
-+ for (i = 0; i < PK11_CIPHER_MAX; i++)
-+ if (ciphers[i].nid == nid)
-+ return (ciphers[i].id);
-+ return (-1);
-+ }
-+
-+static int
-+pk11_usable_ciphers(const int **nids)
-+ {
-+ if (cipher_count > 0)
-+ *nids = cipher_nids;
-+ else
-+ *nids = NULL;
-+ return (cipher_count);
-+ }
-+
-+static int
-+pk11_usable_digests(const int **nids)
-+ {
-+ if (digest_count > 0)
-+ *nids = digest_nids;
-+ else
-+ *nids = NULL;
-+ return (digest_count);
-+ }
-+
-+static int
-+pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+ const unsigned char *iv, int enc)
-+ {
-+ CK_RV rv;
-+ CK_MECHANISM mech;
-+ int index;
-+ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-+ PK11_SESSION *sp;
-+ PK11_CIPHER *pcp;
-+ char tmp_buf[20];
-+
-+ state->sp = NULL;
-+
-+ index = cipher_nid_to_pk11(ctx->cipher->nid);
-+ if (index < 0 || index >= PK11_CIPHER_MAX)
-+ return 0;
-+
-+ pcp = &ciphers[index];
-+ if (ctx->cipher->iv_len > pcp->ivmax || ctx->key_len != pcp->key_len)
-+ return 0;
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return 0;
-+
-+ /* if applicable, the mechanism parameter is used for IV */
-+ mech.mechanism = pcp->mech_type;
-+ mech.pParameter = NULL;
-+ mech.ulParameterLen = 0;
-+
-+ /* The key object is destroyed here if it is not the current key
-+ */
-+ check_new_cipher_key(sp, key);
-+
-+ /* If the key is the same and the encryption is also the same,
-+ * then just reuse it
-+ */
-+ if (sp->cipher_key != CK_INVALID_HANDLE && sp->encrypt == ctx->encrypt)
-+ {
-+ state->sp = sp;
-+ return 1;
-+ }
-+
-+ /* Check if the key has been invalidated. If so, a new key object
-+ * needs to be created.
-+ */
-+ if (sp->cipher_key == CK_INVALID_HANDLE)
-+ {
-+ sp->cipher_key = pk11_get_cipher_key(
-+ ctx, key, pcp->key_type, sp);
-+ }
-+
-+ if (sp->encrypt != ctx->encrypt && sp->encrypt != -1)
-+ {
-+ /* The previous encryption/decryption
-+ * is different. Need to terminate the previous
-+ * active encryption/decryption here
-+ */
-+ if (!pk11_cipher_final(sp))
-+ {
-+ pk11_return_session(sp);
-+ return 0;
-+ }
-+ }
-+
-+ if (sp->cipher_key == CK_INVALID_HANDLE)
-+ {
-+ pk11_return_session(sp);
-+ return 0;
-+ }
-+
-+ if (ctx->cipher->iv_len > 0)
-+ {
-+ mech.pParameter = (void *) ctx->iv;
-+ mech.ulParameterLen = ctx->cipher->iv_len;
-+ }
-+
-+ /* If we get here, the encryption needs to be reinitialized */
-+ if (ctx->encrypt)
-+ {
-+ rv = pFuncList->C_EncryptInit(sp->session_cipher, &mech,
-+ sp->cipher_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CIPHER_INIT, PK11_R_ENCRYPTINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return 0;
-+ }
-+ }
-+ else
-+ {
-+ rv = pFuncList->C_DecryptInit(sp->session_cipher, &mech,
-+ sp->cipher_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CIPHER_INIT, PK11_R_DECRYPTINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return 0;
-+ }
-+ }
-+
-+ sp->encrypt = ctx->encrypt;
-+ state->sp = sp;
-+
-+ return 1;
-+ }
-+
-+/* When reusing the same key in an encryption/decryption session for a
-+ * decryption/encryption session, we need to close the active session
-+ * and recreate a new one. Note that the key is in the global session so
-+ * that it needs not be recreated.
-+ *
-+ * It is more appropriate to use C_En/DecryptFinish here. At the time of this
-+ * development, these two functions in the PKCS#11 libraries used return
-+ * unexpected errors when passing in 0 length output. It may be a good
-+ * idea to try them again if performance is a problem here and fix
-+ * C_En/DecryptFinial if there are bugs there causing the problem.
-+ */
-+static int
-+pk11_cipher_final(PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ char tmp_buf[20];
-+
-+ rv = pFuncList->C_CloseSession(sp->session_cipher);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return 0;
-+ }
-+
-+ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-+ NULL_PTR, NULL_PTR, &sp->session_cipher);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return 0;
-+ }
-+
-+ return 1;
-+ }
-+
-+/* An engine interface function. The calling function allocates sufficient
-+ * memory for the output buffer "out" to hold the results */
-+static int
-+pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+ const unsigned char *in, unsigned int inl)
-+ {
-+ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-+ PK11_SESSION *sp;
-+ CK_RV rv;
-+ unsigned long outl = inl;
-+ char tmp_buf[20];
-+
-+ if (state == NULL || state->sp == NULL)
-+ return 0;
-+
-+ sp = (PK11_SESSION *) state->sp;
-+
-+ if (!inl)
-+ return 1;
-+
-+ /* RC4 is the only stream cipher we support */
-+ if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
-+ return 0;
-+
-+ if (ctx->encrypt)
-+ {
-+ rv = pFuncList->C_EncryptUpdate(sp->session_cipher,
-+ (unsigned char *)in, inl, out, &outl);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CIPHER_DO_CIPHER,
-+ PK11_R_ENCRYPTUPDATE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return 0;
-+ }
-+ }
-+ else
-+ {
-+ rv = pFuncList->C_DecryptUpdate(sp->session_cipher,
-+ (unsigned char *)in, inl, out, &outl);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CIPHER_DO_CIPHER,
-+ PK11_R_DECRYPTUPDATE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return 0;
-+ }
-+ }
-+
-+ /* for DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
-+ * the same size of input
-+ * The application has guaranteed to call the block ciphers with
-+ * correctly aligned buffers.
-+ */
-+ if (inl != outl)
-+ return 0;
-+
-+ return 1;
-+ }
-+
-+/* Return the session to the pool. The C_EncryptFinal and C_DecryptFinal are
-+ * not used. Once a secret key is initialized, it is used until destroyed.
-+ */
-+static int
-+pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
-+ {
-+ PK11_CIPHER_STATE *state = ctx->cipher_data;
-+
-+ if (state != NULL && state->sp != NULL)
-+ {
-+ pk11_return_session(state->sp);
-+ state->sp = NULL;
-+ }
-+
-+ return 1;
-+ }
-+
-+/* Registered by the ENGINE when used to find out how to deal with
-+ * a particular NID in the ENGINE. This says what we'll do at the
-+ * top level - note, that list is restricted by what we answer with
-+ */
-+static int
-+pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+ const int **nids, int nid)
-+ {
-+ if (!cipher)
-+ return (pk11_usable_ciphers(nids));
-+
-+ switch (nid)
-+ {
-+ case NID_des_ede3_cbc:
-+ *cipher = &pk11_3des_cbc;
-+ break;
-+ case NID_des_cbc:
-+ *cipher = &pk11_des_cbc;
-+ break;
-+ case NID_aes_128_cbc:
-+ *cipher = &pk11_aes_cbc;
-+ break;
-+ case NID_rc4:
-+ *cipher = &pk11_rc4;
-+ break;
-+ default:
-+ *cipher = NULL;
-+ break;
-+ }
-+ return (*cipher != NULL);
-+ }
-+
-+static int
-+pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-+ const int **nids, int nid)
-+ {
-+ if (!digest)
-+ return (pk11_usable_digests(nids));
-+
-+ switch (nid)
-+ {
-+ case NID_md5:
-+ *digest = &pk11_md5;
-+ break;
-+ case NID_sha1:
-+ *digest = &pk11_sha1;
-+ break;
-+ default:
-+ *digest = NULL;
-+ break;
-+ }
-+ return (*digest != NULL);
-+ }
-+
-+
-+/* Create a secret key object in a PKCS#11 session
-+ */
-+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-+ const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+ CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
-+ CK_ULONG ul_key_attr_count = 6;
-+ char tmp_buf[20];
-+
-+ CK_ATTRIBUTE a_key_template[] =
-+ {
-+ {CKA_CLASS, (void*) NULL, sizeof(CK_OBJECT_CLASS)},
-+ {CKA_KEY_TYPE, (void*) NULL, sizeof(CK_KEY_TYPE)},
-+ {CKA_TOKEN, &false, sizeof(false)},
-+ {CKA_ENCRYPT, &true, sizeof(true)},
-+ {CKA_DECRYPT, &true, sizeof(true)},
-+ {CKA_VALUE, (void*) NULL, 0},
-+ };
-+
-+ /* Create secret key object in global_session. All other sessions
-+ * can use the key handles. Here is why:
-+ * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
-+ * It may then call DecryptInit and DecryptUpdate using the same key.
-+ * To use the same key object, we need to call EncryptFinal with
-+ * a 0 length message. Currently, this does not work for 3DES
-+ * mechanism. To get around this problem, we close the session and
-+ * then create a new session to use the same key object. When a session
-+ * is closed, all the object handles will be invalid. Thus, create key
-+ * objects in a global session, an individual session may be closed to
-+ * terminate the active operation.
-+ */
-+ CK_SESSION_HANDLE session = global_session;
-+ a_key_template[0].pValue = &obj_key;
-+ a_key_template[1].pValue = &key_type;
-+ a_key_template[5].pValue = (void *) key;
-+ a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
-+
-+ rv = pFuncList->C_CreateObject(session,
-+ a_key_template, ul_key_attr_count, &h_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ /* Save the key information used in this session.
-+ * The max can be saved is PK11_KEY_LEN_MAX.
-+ */
-+ sp->key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
-+ PK11_KEY_LEN_MAX : ctx->key_len;
-+ memcpy(sp->key, key, sp->key_len);
-+err:
-+
-+ return h_key;
-+ }
-+
-+static int
-+md_nid_to_pk11(int nid)
-+ {
-+ int i;
-+
-+ for (i = 0; i < PK11_DIGEST_MAX; i++)
-+ if (digests[i].nid == nid)
-+ return (digests[i].id);
-+ return (-1);
-+ }
-+
-+static int
-+pk11_digest_init(EVP_MD_CTX *ctx)
-+ {
-+ CK_RV rv;
-+ CK_MECHANISM mech;
-+ int index;
-+ PK11_SESSION *sp;
-+ PK11_DIGEST *pdp;
-+ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-+
-+ state->sp = NULL;
-+
-+ index = md_nid_to_pk11(ctx->digest->type);
-+ if (index < 0 || index >= PK11_DIGEST_MAX)
-+ return 0;
-+
-+ pdp = &digests[index];
-+ if ((sp = pk11_get_session()) == NULL)
-+ return 0;
-+
-+ /* at present, no parameter is needed for supported digests */
-+ mech.mechanism = pdp->mech_type;
-+ mech.pParameter = NULL;
-+ mech.ulParameterLen = 0;
-+
-+ rv = pFuncList->C_DigestInit(sp->session, &mech);
-+
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return 0;
-+ }
-+
-+ state->sp = sp;
-+
-+ return 1;
-+ }
-+
-+static int
-+pk11_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count)
-+ {
-+ CK_RV rv;
-+ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-+
-+ /* 0 length message will cause a failure in C_DigestFinal */
-+ if (count == 0)
-+ return 1;
-+
-+ if (state == NULL || state->sp == NULL)
-+ return 0;
-+
-+ rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
-+ count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(state->sp);
-+ state->sp = NULL;
-+ return 0;
-+ }
-+
-+ return 1;
-+ }
-+
-+static int
-+pk11_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
-+ {
-+ CK_RV rv;
-+ unsigned long len;
-+ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-+ len = ctx->digest->md_size;
-+
-+ if (state == NULL || state->sp == NULL)
-+ return 0;
-+
-+ rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
-+
-+ if (rv != CKR_OK)
-+ {
-+ char tmp_buf[20];
-+ PK11err(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(state->sp);
-+ state->sp = NULL;
-+ return 0;
-+ }
-+
-+ if (ctx->digest->md_size != len)
-+ return 0;
-+
-+ /* Final is called and digest is returned, so return the session
-+ * to the pool
-+ */
-+ pk11_return_session(state->sp);
-+ state->sp = NULL;
-+
-+ return 1;
-+ }
-+
-+static int
-+pk11_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
-+ {
-+ CK_RV rv;
-+ int ret = 0;
-+ PK11_CIPHER_STATE *state, *state_to;
-+ CK_BYTE_PTR pstate = NULL;
-+ CK_ULONG ul_state_len;
-+ char tmp_buf[20];
-+
-+ /* The copy-from state */
-+ state = (PK11_CIPHER_STATE *) from->md_data;
-+ if (state == NULL || state->sp == NULL)
-+ goto err;
-+
-+ /* Initialize the copy-to state */
-+ if (!pk11_digest_init(to))
-+ goto err;
-+ state_to = (PK11_CIPHER_STATE *) to->md_data;
-+
-+ /* Get the size of the operation state of the copy-from session */
-+ rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
-+ &ul_state_len);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ if (ul_state_len == 0)
-+ {
-+ goto err;
-+ }
-+
-+ pstate = OPENSSL_malloc(ul_state_len);
-+ if (pstate == NULL)
-+ {
-+ RSAerr(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Get the operation state of the copy-from session */
-+ rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
-+ &ul_state_len);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ /* Set the operation state of the copy-to session */
-+ rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
-+ ul_state_len, 0, 0);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DIGEST_COPY, PK11_R_SET_OPERATION_STATE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ ret = 1;
-+err:
-+ if (pstate != NULL)
-+ OPENSSL_free(pstate);
-+
-+ return ret;
-+ }
-+
-+/* Return any pending session state to the pool */
-+static int
-+pk11_digest_cleanup(EVP_MD_CTX *ctx)
-+ {
-+ PK11_CIPHER_STATE *state = ctx->md_data;
-+ unsigned char buf[EVP_MAX_MD_SIZE];
-+
-+ if (state != NULL && state->sp != NULL)
-+ {
-+ /*
-+ * If state->sp is not NULL then pk11_digest_final() has not
-+ * been called yet. We must call it now to free any memory
-+ * that might have been allocated in the token when
-+ * pk11_digest_init() was called.
-+ */
-+ pk11_digest_final(ctx,buf);
-+ pk11_return_session(state->sp);
-+ state->sp = NULL;
-+ }
-+
-+ return 1;
-+ }
-+
-+/* Check if the new key is the same as the key object in the session.
-+ * If the key is the same, no need to create a new key object. Otherwise,
-+ * the old key object needs to be destroyed and a new one will be created
-+ */
-+static void check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key)
-+ {
-+ if (memcmp(sp->key, key, sp->key_len) != 0)
-+ pk11_destroy_cipher_key_objects(sp);
-+ }
-+
-+/* Destroy one or more secret key objects.
-+ */
-+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
-+ {
-+ int ret = 0;
-+ PK11_SESSION *sp = NULL;
-+ PK11_SESSION *local_free_session;
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if (session)
-+ local_free_session = session;
-+ else
-+ local_free_session = free_session;
-+ while ((sp = local_free_session) != NULL)
-+ {
-+ local_free_session = sp->next;
-+
-+ if (sp->cipher_key != CK_INVALID_HANDLE)
-+ {
-+ /* The secret key object is created in the
-+ * global_session. See pk11_get_cipher_key
-+ */
-+ if (pk11_destroy_object(global_session,
-+ sp->cipher_key) == 0)
-+ goto err;
-+ sp->cipher_key = CK_INVALID_HANDLE;
-+ }
-+ }
-+ ret = 1;
-+err:
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ return ret;
-+ }
-+
-+
-+/*
-+ * Required mechanisms
-+ *
-+ * CKM_RSA_X_509
-+ * CKM_RSA_PKCS
-+ * CKM_DSA
-+ *
-+ * As long as these required mechanisms are met, it will return success.
-+ * Otherwise, it will return failure and the engine initialization will fail.
-+ * The application will then decide whether to use another engine or
-+ * no engine.
-+ *
-+ * Symmetric ciphers optionally supported
-+ *
-+ * CKM_DES3_CBC
-+ * CKM_DES_CBC
-+ * CKM_AES_CBC
-+ * CKM_RC4
-+ *
-+ * Digests optionally supported
-+ *
-+ * CKM_MD5
-+ * CKM_SHA_1
-+ */
-+
-+static int
-+pk11_choose_slot()
-+ {
-+ CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-+ CK_ULONG ulSlotCount = 0;
-+ CK_MECHANISM_INFO mech_info;
-+ CK_TOKEN_INFO token_info;
-+ int i;
-+ CK_RV rv;
-+ CK_SLOT_ID best_slot_sofar;
-+ CK_BBOOL found_candidate_slot = CK_FALSE;
-+ int slot_n_cipher = 0;
-+ int slot_n_digest = 0;
-+ CK_SLOT_ID current_slot = 0;
-+ int current_slot_n_cipher = 0;
-+ int current_slot_n_digest = 0;
-+
-+ int local_cipher_nids[PK11_CIPHER_MAX];
-+ int local_digest_nids[PK11_DIGEST_MAX];
-+ char tmp_buf[20];
-+ int retval = 0;
-+
-+ if (!pk11_auto_slot)
-+ return 1;
-+
-+ /* Get slot list for memory alloction */
-+ rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ return retval;
-+ }
-+
-+ if (ulSlotCount == 0)
-+ {
-+ PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST);
-+ return retval;
-+ }
-+
-+ pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-+
-+ if (pSlotList == NULL)
-+ {
-+ RSAerr(PK11_F_CHOOSE_SLOT,PK11_R_MALLOC_FAILURE);
-+ return retval;
-+ }
-+
-+ /* Get the slot list for processing */
-+ rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ OPENSSL_free(pSlotList);
-+ return retval;
-+ }
-+
-+ for (i = 0; i < ulSlotCount; i++)
-+ {
-+ CK_BBOOL slot_has_rsa = CK_FALSE;
-+ CK_BBOOL slot_has_dsa = CK_FALSE;
-+ CK_BBOOL slot_has_dh = CK_FALSE;
-+ current_slot = pSlotList[i];
-+ current_slot_n_cipher = 0;
-+ current_slot_n_digest = 0;
-+ memset(local_cipher_nids, 0, sizeof(local_cipher_nids));
-+ memset(local_digest_nids, 0, sizeof(local_digest_nids));
-+
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: checking slot: %d\n",
-+ current_slot);
-+#endif
-+ /* Check if slot has random support. */
-+ rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-+ if (rv != CKR_OK)
-+ continue;
-+
-+ if (token_info.flags & CKF_RNG)
-+ pk11_have_random = CK_TRUE;
-+
-+ /*
-+ * Check if this slot is capable of signing and
-+ * verifying with CKM_RSA_PKCS.
-+ */
-+ rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
-+ &mech_info);
-+
-+ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-+ (mech_info.flags & CKF_VERIFY)))
-+ {
-+ /*
-+ * Check if this slot is capable of encryption,
-+ * decryption, sign, and verify with CKM_RSA_X_509.
-+ */
-+ rv = pFuncList->C_GetMechanismInfo(current_slot,
-+ CKM_RSA_X_509, &mech_info);
-+
-+ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-+ (mech_info.flags & CKF_VERIFY) &&
-+ (mech_info.flags & CKF_ENCRYPT) &&
-+ (mech_info.flags & CKF_VERIFY_RECOVER) &&
-+ (mech_info.flags & CKF_DECRYPT)))
-+ slot_has_rsa = CK_TRUE;
-+ }
-+
-+ /*
-+ * Check if this slot is capable of signing and
-+ * verifying with CKM_DSA.
-+ */
-+ rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
-+ &mech_info);
-+ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-+ (mech_info.flags & CKF_VERIFY)))
-+ slot_has_dsa = CK_TRUE;
-+
-+ /*
-+ * Check if this slot is capable of DH key generataion and
-+ * derivation.
-+ */
-+ rv = pFuncList->C_GetMechanismInfo(current_slot,
-+ CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
-+
-+ if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
-+ {
-+ rv = pFuncList->C_GetMechanismInfo(current_slot,
-+ CKM_DH_PKCS_DERIVE, &mech_info);
-+ if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
-+ slot_has_dh = CK_TRUE;
-+ }
-+
-+ if (!found_candidate_slot &&
-+ (slot_has_rsa || slot_has_dsa || slot_has_dh))
-+ {
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: potential slot: %d\n",
-+ current_slot);
-+#endif
-+ best_slot_sofar = current_slot;
-+ pk11_have_rsa = slot_has_rsa;
-+ pk11_have_dsa = slot_has_dsa;
-+ pk11_have_dh = slot_has_dh;
-+ found_candidate_slot = CK_TRUE;
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: best so far slot: %d\n",
-+ best_slot_sofar);
-+#endif
-+ }
-+
-+ /* Count symmetric cipher support. */
-+ if (!pk11_count_symmetric_cipher(current_slot, CKM_DES_CBC,
-+ &current_slot_n_cipher, local_cipher_nids,
-+ PK11_DES_CBC))
-+ continue;
-+ if (!pk11_count_symmetric_cipher(current_slot, CKM_DES3_CBC,
-+ &current_slot_n_cipher, local_cipher_nids,
-+ PK11_DES3_CBC))
-+ continue;
-+ if (!pk11_count_symmetric_cipher(current_slot, CKM_AES_CBC,
-+ &current_slot_n_cipher, local_cipher_nids,
-+ PK11_AES_CBC))
-+ continue;
-+ if (!pk11_count_symmetric_cipher(current_slot, CKM_RC4,
-+ &current_slot_n_cipher, local_cipher_nids,
-+ PK11_RC4))
-+ continue;
-+
-+ /* Count digest support */
-+ if (!pk11_count_digest(current_slot, CKM_MD5,
-+ &current_slot_n_digest, local_digest_nids,
-+ PK11_MD5))
-+ continue;
-+ if (!pk11_count_digest(current_slot, CKM_SHA_1,
-+ &current_slot_n_digest, local_digest_nids,
-+ PK11_SHA1))
-+ continue;
-+
-+ /*
-+ * If the current slot supports more ciphers/digests than
-+ * the previous best one we change the current best to this one.
-+ * otherwise leave it where it is.
-+ */
-+ if (((current_slot_n_cipher > slot_n_cipher) &&
-+ (current_slot_n_digest > slot_n_digest)) &&
-+ ((slot_has_rsa == pk11_have_rsa) &&
-+ (slot_has_dsa == pk11_have_dsa) &&
-+ (slot_has_dh == pk11_have_dh)))
-+ {
-+ best_slot_sofar = current_slot;
-+ slot_n_cipher = current_slot_n_cipher;
-+ slot_n_digest = current_slot_n_digest;
-+
-+ memcpy(cipher_nids, local_cipher_nids,
-+ sizeof(local_cipher_nids));
-+ memcpy(digest_nids, local_digest_nids,
-+ sizeof(local_digest_nids));
-+ }
-+
-+ }
-+
-+ if (found_candidate_slot)
-+ {
-+ cipher_count = slot_n_cipher;
-+ digest_count = slot_n_digest;
-+ SLOTID = best_slot_sofar;
-+ retval = 1;
-+ }
-+ else
-+ {
-+ cipher_count = 0;
-+ digest_count = 0;
-+ }
-+
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: choose slot: %d\n", SLOTID);
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: pk11_have_rsa %d\n", pk11_have_rsa);
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: pk11_have_dsa %d\n", pk11_have_dsa);
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: pk11_have_dh %d\n", pk11_have_dh);
-+ fprintf(stderr,
-+ "OPENSSL_PKCS#11_ENGINE: pk11_have_random %d\n", pk11_have_random);
-+#endif /* DEBUG_SLOT_SELECTION */
-+
-+ if (pSlotList)
-+ OPENSSL_free(pSlotList);
-+
-+ return retval;
-+ }
-+
-+static int pk11_count_symmetric_cipher(int slot_id, CK_MECHANISM_TYPE mech,
-+ int *current_slot_n_cipher, int *local_cipher_nids, int id)
-+ {
-+ CK_MECHANISM_INFO mech_info;
-+ CK_RV rv;
-+
-+ rv = pFuncList->C_GetMechanismInfo(slot_id, mech, &mech_info);
-+
-+ if (rv != CKR_OK)
-+ return 0;
-+
-+ if ((mech_info.flags & CKF_ENCRYPT) &&
-+ (mech_info.flags & CKF_DECRYPT))
-+ {
-+ local_cipher_nids[(*current_slot_n_cipher)++] = ciphers[id].nid;
-+ }
-+
-+ return 1;
-+ }
-+
-+
-+static int pk11_count_digest(int slot_id, CK_MECHANISM_TYPE mech,
-+ int *current_slot_n_digest, int *local_digest_nids, int id)
-+ {
-+ CK_MECHANISM_INFO mech_info;
-+ CK_RV rv;
-+
-+ rv = pFuncList->C_GetMechanismInfo(slot_id, mech, &mech_info);
-+
-+ if (rv != CKR_OK)
-+ return 0;
-+
-+ if (mech_info.flags & CKF_DIGEST)
-+ {
-+ local_digest_nids[(*current_slot_n_digest)++] = digests[id].nid;
-+ }
-+
-+ return 1;
-+ }
-+
-+
-+#endif
-+#endif
-+
-diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11_err.c openssl/crypto/engine/hw_pk11_err.c
---- openssl-0.9.8g/crypto/engine/hw_pk11_err.c 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/hw_pk11_err.c 2007-10-25 01:27:09.000000000 +0200
-@@ -0,0 +1,233 @@
-+/*
-+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
-+#pragma ident "@(#)hw_pk11_err.c 1.2 04/06/22 SMI"
-+
-+/* crypto/engine/hw_pk11_err.c */
-+/* This product includes software developed by the OpenSSL Project for
-+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
-+ *
-+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
-+ * Afchine Madjlessi.
-+ */
-+/* ====================================================================
-+ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ *
-+ * 3. All advertising materials mentioning features or use of this
-+ * software must display the following acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
-+ *
-+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
-+ * endorse or promote products derived from this software without
-+ * prior written permission. For written permission, please contact
-+ * licensing@OpenSSL.org.
-+ *
-+ * 5. Products derived from this software may not be called "OpenSSL"
-+ * nor may "OpenSSL" appear in their names without prior written
-+ * permission of the OpenSSL Project.
-+ *
-+ * 6. Redistributions of any form whatsoever must retain the following
-+ * acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
-+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ * ====================================================================
-+ *
-+ * This product includes cryptographic software written by Eric Young
-+ * (eay@cryptsoft.com). This product includes software written by Tim
-+ * Hudson (tjh@cryptsoft.com).
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <openssl/err.h>
-+#include "hw_pk11_err.h"
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+static ERR_STRING_DATA pk11_str_functs[]=
-+{
-+ {ERR_PACK(0,PK11_F_INIT,0), "PK11_INIT"},
-+ {ERR_PACK(0,PK11_F_FINISH,0), "PK11_FINISH"},
-+ {ERR_PACK(0,PK11_F_DESTROY,0), "PK11_DESTROY"},
-+ {ERR_PACK(0,PK11_F_CTRL,0), "PK11_CTRL"},
-+ {ERR_PACK(0,PK11_F_RSA_INIT,0), "PK11_RSA_INIT"},
-+ {ERR_PACK(0,PK11_F_RSA_FINISH,0), "PK11_RSA_FINISH"},
-+ {ERR_PACK(0,PK11_F_GET_PUB_RSA_KEY,0), "PK11_GET_PUB_RSA_KEY"},
-+ {ERR_PACK(0,PK11_F_GET_PRIV_RSA_KEY,0), "PK11_GET_PRIV_RSA_KEY"},
-+ {ERR_PACK(0,PK11_F_RSA_GEN_KEY,0), "PK11_RSA_GEN_KEY"},
-+ {ERR_PACK(0,PK11_F_RSA_PUB_ENC,0), "PK11_RSA_PUB_ENC"},
-+ {ERR_PACK(0,PK11_F_RSA_PRIV_ENC,0), "PK11_RSA_PRIV_ENC"},
-+ {ERR_PACK(0,PK11_F_RSA_PUB_DEC,0), "PK11_RSA_PUB_DEC"},
-+ {ERR_PACK(0,PK11_F_RSA_PRIV_DEC,0), "PK11_RSA_PRIV_DEC"},
-+ {ERR_PACK(0,PK11_F_RSA_SIGN,0), "PK11_RSA_SIGN"},
-+ {ERR_PACK(0,PK11_F_RSA_VERIFY,0), "PK11_RSA_VERIFY"},
-+ {ERR_PACK(0,PK11_F_RAND_ADD,0), "PK11_RAND_ADD"},
-+ {ERR_PACK(0,PK11_F_RAND_BYTES,0), "PK11_RAND_BYTES"},
-+ {ERR_PACK(0,PK11_F_GET_SESSION,0), "PK11_GET_SESSION"},
-+ {ERR_PACK(0,PK11_F_FREE_SESSION,0), "PK11_FREE_SESSION"},
-+ {ERR_PACK(0,PK11_F_LOAD_PUBKEY,0), "PK11_LOAD_PUBKEY"},
-+ {ERR_PACK(0,PK11_F_LOAD_PRIVKEY,0), "PK11_LOAD_PRIV_KEY"},
-+ {ERR_PACK(0,PK11_F_RSA_PUB_ENC_LOW,0), "PK11_RSA_PUB_ENC_LOW"},
-+ {ERR_PACK(0,PK11_F_RSA_PRIV_ENC_LOW,0), "PK11_RSA_PRIV_ENC_LOW"},
-+ {ERR_PACK(0,PK11_F_RSA_PUB_DEC_LOW,0), "PK11_RSA_PUB_DEC_LOW"},
-+ {ERR_PACK(0,PK11_F_RSA_PRIV_DEC_LOW,0), "PK11_RSA_PRIV_DEC_LOW"},
-+ {ERR_PACK(0,PK11_F_DSA_SIGN,0), "PK11_DSA_SIGN"},
-+ {ERR_PACK(0,PK11_F_DSA_VERIFY,0), "PK11_DSA_VERIFY"},
-+ {ERR_PACK(0,PK11_F_DSA_INIT,0), "PK11_DSA_INIT"},
-+ {ERR_PACK(0,PK11_F_DSA_FINISH,0), "PK11_DSA_FINISH"},
-+ {ERR_PACK(0,PK11_F_GET_PUB_DSA_KEY,0), "PK11_GET_PUB_DSA_KEY"},
-+ {ERR_PACK(0,PK11_F_GET_PRIV_DSA_KEY,0), "PK11_GET_PRIV_DSA_KEY"},
-+ {ERR_PACK(0,PK11_F_DH_INIT,0), "PK11_DH_INIT"},
-+ {ERR_PACK(0,PK11_F_DH_FINISH,0), "PK11_DH_FINISH"},
-+ {ERR_PACK(0,PK11_F_MOD_EXP_DH,0), "PK11_MOD_EXP_DH"},
-+ {ERR_PACK(0,PK11_F_GET_DH_KEY,0), "PK11_GET_DH_KEY"},
-+ {ERR_PACK(0,PK11_F_FREE_ALL_SESSIONS,0),"PK11_FREE_ALL_SESSIONS"},
-+ {ERR_PACK(0,PK11_F_SETUP_SESSION,0), "PK11_SETUP_SESSION"},
-+ {ERR_PACK(0,PK11_F_DESTROY_OBJECT,0), "PK11_DESTROY_OBJECT"},
-+ {ERR_PACK(0,PK11_F_CIPHER_INIT,0), "PK11_CIPHER_INIT"},
-+ {ERR_PACK(0,PK11_F_CIPHER_DO_CIPHER,0), "PK11_CIPHER_DO_CIPHER"},
-+ {ERR_PACK(0,PK11_F_GET_CIPHER_KEY,0), "PK11_GET_CIPHER_KEY"},
-+ {ERR_PACK(0,PK11_F_DIGEST_INIT,0), "PK11_DIGEST_INIT"},
-+ {ERR_PACK(0,PK11_F_DIGEST_UPDATE,0), "PK11_DIGEST_UPDATE"},
-+ {ERR_PACK(0,PK11_F_DIGEST_FINAL,0), "PK11_DIGEST_FINAL"},
-+ {ERR_PACK(0,PK11_F_CHOOSE_SLOT,0), "PK11_CHOOSE_SLOT"},
-+ {ERR_PACK(0,PK11_F_CIPHER_FINAL,0), "PK11_CIPHER_FINAL"},
-+ {ERR_PACK(0,PK11_F_LIBRARY_INIT,0), "PK11_LIBRARY_INIT"},
-+ {ERR_PACK(0,PK11_F_LOAD,0), "ENGINE_LOAD_PK11"},
-+ {ERR_PACK(0,PK11_F_DH_GEN_KEY,0), "PK11_DH_GEN_KEY"},
-+ {ERR_PACK(0,PK11_F_DH_COMP_KEY,0), "PK11_DH_COMP_KEY"},
-+ {ERR_PACK(0,PK11_F_DIGEST_COPY,0), "PK11_DIGEST_COPY"},
-+ {0,NULL}
-+};
-+
-+static ERR_STRING_DATA pk11_str_reasons[]=
-+{
-+ {PK11_R_ALREADY_LOADED ,"PKCS#11 DSO already loaded"},
-+ {PK11_R_DSO_FAILURE ,"unable to load PKCS#11 DSO"},
-+ {PK11_R_NOT_LOADED ,"PKCS#11 DSO not loaded"},
-+ {PK11_R_PASSED_NULL_PARAMETER ,"null parameter passed"},
-+ {PK11_R_COMMAND_NOT_IMPLEMENTED ,"command not implemented"},
-+ {PK11_R_INITIALIZE ,"C_Initialize failed"},
-+ {PK11_R_FINALIZE ,"C_Finalize failed"},
-+ {PK11_R_GETINFO ,"C_GetInfo faile"},
-+ {PK11_R_GETSLOTLIST ,"C_GetSlotList failed"},
-+ {PK11_R_NO_MODULUS_OR_NO_EXPONENT ,"no modulus or no exponent"},
-+ {PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID ,"attr sensitive or invalid"},
-+ {PK11_R_GETATTRIBUTVALUE ,"C_GetAttributeValue failed"},
-+ {PK11_R_NO_MODULUS ,"no modulus"},
-+ {PK11_R_NO_EXPONENT ,"no exponent"},
-+ {PK11_R_FINDOBJECTSINIT ,"C_FindObjectsInit failed"},
-+ {PK11_R_FINDOBJECTS ,"C_FindObjects failed"},
-+ {PK11_R_FINDOBJECTSFINAL ,"C_FindObjectsFinal failed"},
-+ {PK11_R_CREATEOBJECT ,"C_CreateObject failed"},
-+ {PK11_R_DESTROYOBJECT ,"C_DestroyObject failed"},
-+ {PK11_R_OPENSESSION ,"C_OpenSession failed"},
-+ {PK11_R_CLOSESESSION ,"C_CloseSession failed"},
-+ {PK11_R_ENCRYPTINIT ,"C_EncryptInit failed"},
-+ {PK11_R_ENCRYPT ,"C_Encrypt failed"},
-+ {PK11_R_SIGNINIT ,"C_SignInit failed"},
-+ {PK11_R_SIGN ,"C_Sign failed"},
-+ {PK11_R_DECRYPTINIT ,"C_DecryptInit failed"},
-+ {PK11_R_DECRYPT ,"C_Decrypt failed"},
-+ {PK11_R_VERIFYINIT ,"C_VerifyRecover failed"},
-+ {PK11_R_VERIFY ,"C_Verify failed "},
-+ {PK11_R_VERIFYRECOVERINIT ,"C_VerifyRecoverInit failed"},
-+ {PK11_R_VERIFYRECOVER ,"C_VerifyRecover failed"},
-+ {PK11_R_GEN_KEY ,"C_GenerateKeyPair failed"},
-+ {PK11_R_SEEDRANDOM ,"C_SeedRandom failed"},
-+ {PK11_R_GENERATERANDOM ,"C_GenerateRandom failed"},
-+ {PK11_R_INVALID_MESSAGE_LENGTH ,"invalid message length"},
-+ {PK11_R_UNKNOWN_ALGORITHM_TYPE ,"unknown algorithm type"},
-+ {PK11_R_UNKNOWN_ASN1_OBJECT_ID ,"unknown asn1 onject id"},
-+ {PK11_R_UNKNOWN_PADDING_TYPE ,"unknown padding type"},
-+ {PK11_R_PADDING_CHECK_FAILED ,"padding check failed"},
-+ {PK11_R_DIGEST_TOO_BIG ,"digest too big"},
-+ {PK11_R_MALLOC_FAILURE ,"malloc failure"},
-+ {PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctl command not implemented"},
-+ {PK11_R_DATA_GREATER_THAN_MOD_LEN ,"data is bigger than mod"},
-+ {PK11_R_DATA_TOO_LARGE_FOR_MODULUS ,"data is too larger for mod"},
-+ {PK11_R_MISSING_KEY_COMPONENT ,"a dsa component is missing"},
-+ {PK11_R_INVALID_SIGNATURE_LENGTH ,"invalid signature length"},
-+ {PK11_R_INVALID_DSA_SIGNATURE_R ,"missing r in dsa verify"},
-+ {PK11_R_INVALID_DSA_SIGNATURE_S ,"missing s in dsa verify"},
-+ {PK11_R_INCONSISTENT_KEY ,"inconsistent key type"},
-+ {PK11_R_ENCRYPTUPDATE ,"C_EncryptUpdate failed"},
-+ {PK11_R_DECRYPTUPDATE ,"C_DecryptUpdate failed"},
-+ {PK11_R_DIGESTINIT ,"C_DigestInit failed"},
-+ {PK11_R_DIGESTUPDATE ,"C_DigestUpdate failed"},
-+ {PK11_R_DIGESTFINAL ,"C_DigestFinal failed"},
-+ {PK11_R_ENCRYPTFINAL ,"C_EncryptFinal failed"},
-+ {PK11_R_DECRYPTFINAL ,"C_DecryptFinal failed"},
-+ {PK11_R_NO_PRNG_SUPPORT ,"Slot does not support PRNG"},
-+ {PK11_R_GETTOKENINFO ,"C_GetTokenInfo failed"},
-+ {PK11_R_DERIVEKEY ,"C_DeriveKey failed"},
-+ {PK11_R_GET_OPERATION_STATE ,"C_GetOperationState failed"},
-+ {PK11_R_SET_OPERATION_STATE ,"C_SetOperationState failed"},
-+ {0,NULL}
-+};
-+
-+#endif
-+
-+static int pk11_lib_error_code=0;
-+static int pk11_error_init=1;
-+
-+static void ERR_load_pk11_strings(void)
-+{
-+ if (pk11_lib_error_code == 0)
-+ pk11_lib_error_code = ERR_get_next_error_library();
-+
-+ if (pk11_error_init)
-+ {
-+ pk11_error_init=0;
-+#ifndef OPENSSL_NO_ERR
-+ ERR_load_strings(pk11_lib_error_code,pk11_str_functs);
-+ ERR_load_strings(pk11_lib_error_code,pk11_str_reasons);
-+#endif
-+ }
-+}
-+
-+static void ERR_unload_pk11_strings(void)
-+{
-+ if (pk11_error_init == 0)
-+ {
-+#ifndef OPENSSL_NO_ERR
-+ ERR_unload_strings(pk11_lib_error_code,pk11_str_functs);
-+ ERR_unload_strings(pk11_lib_error_code,pk11_str_reasons);
-+#endif
-+ pk11_error_init = 1;
-+ }
-+}
-+
-+static void ERR_pk11_error(int function, int reason, char *file, int line)
-+{
-+ if (pk11_lib_error_code == 0)
-+ pk11_lib_error_code=ERR_get_next_error_library();
-+ ERR_PUT_error(pk11_lib_error_code,function,reason,file,line);
-+}
-diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11_err.h openssl/crypto/engine/hw_pk11_err.h
---- openssl-0.9.8g/crypto/engine/hw_pk11_err.h 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/hw_pk11_err.h 2008-01-31 16:14:07.000000000 +0100
-@@ -0,0 +1,247 @@
-+/*
-+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
-+#pragma ident "@(#)hw_pk11_err.h 1.2 04/06/22 SMI"
-+
-+/* crypto/engine/hw_pk11_err.h */
-+/* This product includes software developed by the OpenSSL Project for
-+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
-+ *
-+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
-+ * Afchine Madjlessi.
-+ */
-+/* ====================================================================
-+ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ *
-+ * 3. All advertising materials mentioning features or use of this
-+ * software must display the following acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
-+ *
-+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
-+ * endorse or promote products derived from this software without
-+ * prior written permission. For written permission, please contact
-+ * licensing@OpenSSL.org.
-+ *
-+ * 5. Products derived from this software may not be called "OpenSSL"
-+ * nor may "OpenSSL" appear in their names without prior written
-+ * permission of the OpenSSL Project.
-+ *
-+ * 6. Redistributions of any form whatsoever must retain the following
-+ * acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
-+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ * ====================================================================
-+ *
-+ * This product includes cryptographic software written by Eric Young
-+ * (eay@cryptsoft.com). This product includes software written by Tim
-+ * Hudson (tjh@cryptsoft.com).
-+ *
-+ */
-+
-+#ifndef HW_PK11_ERR_H
-+#define HW_PK11_ERR_H
-+
-+/* CRYPTO_LOCK_RSA is defined in OpenSSL for RSA method. Since this pk11
-+ * engine replaces RSA method, we may reuse this lock here.
-+ */
-+#define CRYPTO_LOCK_PK11_ENGINE CRYPTO_LOCK_RSA
-+
-+static void ERR_load_pk11_strings(void);
-+static void ERR_pk11_error(int function, int reason, char *file, int line);
-+#define PK11err(f,r) ERR_pk11_error((f),(r),__FILE__,__LINE__)
-+
-+/* Error codes for the PK11 functions. */
-+
-+/* Function codes. */
-+
-+#define PK11_F_INIT 100
-+#define PK11_F_FINISH 101
-+#define PK11_F_DESTROY 102
-+#define PK11_F_CTRL 103
-+#define PK11_F_RSA_INIT 104
-+#define PK11_F_RSA_FINISH 105
-+#define PK11_F_GET_PUB_RSA_KEY 106
-+#define PK11_F_GET_PRIV_RSA_KEY 107
-+#define PK11_F_RSA_GEN_KEY 108
-+#define PK11_F_RSA_PUB_ENC 109
-+#define PK11_F_RSA_PRIV_ENC 110
-+#define PK11_F_RSA_PUB_DEC 111
-+#define PK11_F_RSA_PRIV_DEC 112
-+#define PK11_F_RSA_SIGN 113
-+#define PK11_F_RSA_VERIFY 114
-+#define PK11_F_RAND_ADD 115
-+#define PK11_F_RAND_BYTES 116
-+#define PK11_F_GET_SESSION 117
-+#define PK11_F_FREE_SESSION 118
-+#define PK11_F_LOAD_PUBKEY 119
-+#define PK11_F_LOAD_PRIVKEY 120
-+#define PK11_F_RSA_PUB_ENC_LOW 121
-+#define PK11_F_RSA_PRIV_ENC_LOW 122
-+#define PK11_F_RSA_PUB_DEC_LOW 123
-+#define PK11_F_RSA_PRIV_DEC_LOW 124
-+#define PK11_F_DSA_SIGN 125
-+#define PK11_F_DSA_VERIFY 126
-+#define PK11_F_DSA_INIT 127
-+#define PK11_F_DSA_FINISH 128
-+#define PK11_F_GET_PUB_DSA_KEY 129
-+#define PK11_F_GET_PRIV_DSA_KEY 130
-+#define PK11_F_DH_INIT 131
-+#define PK11_F_DH_FINISH 132
-+#define PK11_F_MOD_EXP_DH 133
-+#define PK11_F_GET_DH_KEY 134
-+#define PK11_F_FREE_ALL_SESSIONS 135
-+#define PK11_F_SETUP_SESSION 136
-+#define PK11_F_DESTROY_OBJECT 137
-+#define PK11_F_CIPHER_INIT 138
-+#define PK11_F_CIPHER_DO_CIPHER 139
-+#define PK11_F_GET_CIPHER_KEY 140
-+#define PK11_F_DIGEST_INIT 141
-+#define PK11_F_DIGEST_UPDATE 142
-+#define PK11_F_DIGEST_FINAL 143
-+#define PK11_F_CHOOSE_SLOT 144
-+#define PK11_F_CIPHER_FINAL 145
-+#define PK11_F_LIBRARY_INIT 146
-+#define PK11_F_LOAD 147
-+#define PK11_F_DH_GEN_KEY 148
-+#define PK11_F_DH_COMP_KEY 149
-+#define PK11_F_DIGEST_COPY 150
-+
-+/* Reason codes. */
-+#define PK11_R_ALREADY_LOADED 100
-+#define PK11_R_DSO_FAILURE 101
-+#define PK11_R_NOT_LOADED 102
-+#define PK11_R_PASSED_NULL_PARAMETER 103
-+#define PK11_R_COMMAND_NOT_IMPLEMENTED 104
-+#define PK11_R_INITIALIZE 105
-+#define PK11_R_FINALIZE 106
-+#define PK11_R_GETINFO 107
-+#define PK11_R_GETSLOTLIST 108
-+#define PK11_R_NO_MODULUS_OR_NO_EXPONENT 109
-+#define PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 110
-+#define PK11_R_GETATTRIBUTVALUE 111
-+#define PK11_R_NO_MODULUS 112
-+#define PK11_R_NO_EXPONENT 113
-+#define PK11_R_FINDOBJECTSINIT 114
-+#define PK11_R_FINDOBJECTS 115
-+#define PK11_R_FINDOBJECTSFINAL 116
-+#define PK11_R_CREATEOBJECT 118
-+#define PK11_R_DESTROYOBJECT 119
-+#define PK11_R_OPENSESSION 120
-+#define PK11_R_CLOSESESSION 121
-+#define PK11_R_ENCRYPTINIT 122
-+#define PK11_R_ENCRYPT 123
-+#define PK11_R_SIGNINIT 124
-+#define PK11_R_SIGN 125
-+#define PK11_R_DECRYPTINIT 126
-+#define PK11_R_DECRYPT 127
-+#define PK11_R_VERIFYINIT 128
-+#define PK11_R_VERIFY 129
-+#define PK11_R_VERIFYRECOVERINIT 130
-+#define PK11_R_VERIFYRECOVER 131
-+#define PK11_R_GEN_KEY 132
-+#define PK11_R_SEEDRANDOM 133
-+#define PK11_R_GENERATERANDOM 134
-+#define PK11_R_INVALID_MESSAGE_LENGTH 135
-+#define PK11_R_UNKNOWN_ALGORITHM_TYPE 136
-+#define PK11_R_UNKNOWN_ASN1_OBJECT_ID 137
-+#define PK11_R_UNKNOWN_PADDING_TYPE 138
-+#define PK11_R_PADDING_CHECK_FAILED 139
-+#define PK11_R_DIGEST_TOO_BIG 140
-+#define PK11_R_MALLOC_FAILURE 141
-+#define PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 142
-+#define PK11_R_DATA_GREATER_THAN_MOD_LEN 143
-+#define PK11_R_DATA_TOO_LARGE_FOR_MODULUS 144
-+#define PK11_R_MISSING_KEY_COMPONENT 145
-+#define PK11_R_INVALID_SIGNATURE_LENGTH 146
-+#define PK11_R_INVALID_DSA_SIGNATURE_R 147
-+#define PK11_R_INVALID_DSA_SIGNATURE_S 148
-+#define PK11_R_INCONSISTENT_KEY 149
-+#define PK11_R_ENCRYPTUPDATE 150
-+#define PK11_R_DECRYPTUPDATE 151
-+#define PK11_R_DIGESTINIT 152
-+#define PK11_R_DIGESTUPDATE 153
-+#define PK11_R_DIGESTFINAL 154
-+#define PK11_R_ENCRYPTFINAL 155
-+#define PK11_R_DECRYPTFINAL 156
-+#define PK11_R_NO_PRNG_SUPPORT 157
-+#define PK11_R_GETTOKENINFO 158
-+#define PK11_R_DERIVEKEY 159
-+#define PK11_R_GET_OPERATION_STATE 160
-+#define PK11_R_SET_OPERATION_STATE 161
-+#define PK11_R_INVALID_PIN 162
-+#define PK11_R_TOO_MANY_OBJECTS 163
-+#define PK11_R_OBJECT_NOT_FOUND 164
-+
-+/* This structure encapsulates all reusable information for a PKCS#11
-+ * session. A list of this object is created on behalf of the
-+ * calling application using an on-demand method. When a new request
-+ * comes in, an object will be taken from the list (if there is one)
-+ * or a new one is created to handle the request. Note that not all
-+ * fields are used for every application. For example, an RSA-only
-+ * application only uses the RSA related fields */
-+typedef struct PK11_SESSION_st
-+ {
-+ struct PK11_SESSION_st *next;
-+ CK_SESSION_HANDLE session; /* PK11 session handle */
-+ CK_SESSION_HANDLE session_cipher; /* PK11 sess handle for ciph */
-+ pid_t pid; /* Current process ID */
-+ CK_OBJECT_HANDLE rsa_pub_key; /* RSA key handle in the sess */
-+ CK_OBJECT_HANDLE rsa_priv_key; /* RSA private key handle */
-+ CK_OBJECT_HANDLE dsa_pub_key; /* DSA pub key handle */
-+ CK_OBJECT_HANDLE dsa_priv_key; /* DSA priv key handle */
-+ CK_OBJECT_HANDLE dh_key; /* RSA pub key handle for DH */
-+ CK_OBJECT_HANDLE cipher_key; /* Cipher key handle */
-+ RSA *rsa; /* Address of the RSA struct */
-+ void *dsa; /* Address of the DSA structure */
-+ void *dh; /* Address of the DH */
-+ unsigned char key[24];/* Save the private key here */
-+ int key_len;/* Saved private key length */
-+ int encrypt;/* 1/0 for encrypt/decrypt */
-+ } PK11_SESSION;
-+
-+extern PK11_SESSION *pk11_get_session();
-+extern void pk11_return_session(PK11_SESSION *sp);
-+
-+extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-+extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-+extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-+
-+extern RSA_METHOD *PK11_RSA(void);
-+extern DSA_METHOD *PK11_DSA(void);
-+extern DH_METHOD *PK11_DH(void);
-+
-+extern EVP_PKEY *pk11_load_privkey(ENGINE*, const char* pubkey_file,
-+ UI_METHOD *ui_method, void *callback_data);
-+extern EVP_PKEY *pk11_load_pubkey(ENGINE*, const char* pubkey_file,
-+ UI_METHOD *ui_method, void *callback_data);
-+
-+extern CK_FUNCTION_LIST_PTR pFuncList;
-+
-+#endif /* HW_PK11_ERR_H */
-diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11_pub.c openssl/crypto/engine/hw_pk11_pub.c
---- openssl-0.9.8g/crypto/engine/hw_pk11_pub.c 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/hw_pk11_pub.c 2008-03-17 15:15:49.000000000 +0100
-@@ -0,0 +1,2616 @@
-+/*
-+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
-+#pragma ident "@(#)hw_pk11_pub.c 1.4 07/05/10 SMI"
-+
-+/* crypto/engine/hw_pk11_pub.c */
-+/* This product includes software developed by the OpenSSL Project for
-+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
-+ *
-+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
-+ * Afchine Madjlessi.
-+ */
-+/* ====================================================================
-+ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ *
-+ * 3. All advertising materials mentioning features or use of this
-+ * software must display the following acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
-+ *
-+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
-+ * endorse or promote products derived from this software without
-+ * prior written permission. For written permission, please contact
-+ * licensing@OpenSSL.org.
-+ *
-+ * 5. Products derived from this software may not be called "OpenSSL"
-+ * nor may "OpenSSL" appear in their names without prior written
-+ * permission of the OpenSSL Project.
-+ *
-+ * 6. Redistributions of any form whatsoever must retain the following
-+ * acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
-+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ * ====================================================================
-+ *
-+ * This product includes cryptographic software written by Eric Young
-+ * (eay@cryptsoft.com). This product includes software written by Tim
-+ * Hudson (tjh@cryptsoft.com).
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <assert.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+
-+#include <openssl/e_os2.h>
-+#include <openssl/engine.h>
-+#include <openssl/dso.h>
-+#include <openssl/err.h>
-+#include <openssl/bn.h>
-+#include <openssl/pem.h>
-+#include <openssl/rsa.h>
-+#include <openssl/rand.h>
-+#include <openssl/objects.h>
-+#include <openssl/x509.h>
-+#include <cryptlib.h>
-+
-+#ifndef OPENSSL_NO_HW
-+#ifndef OPENSSL_NO_HW_PK11
-+
-+#include "cryptoki.h"
-+#include "pkcs11.h"
-+#include "hw_pk11_err.c"
-+
-+#ifndef OPENSSL_NO_RSA
-+/* RSA stuff */
-+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding);
-+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding);
-+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding);
-+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding);
-+static int pk11_RSA_init(RSA *rsa);
-+static int pk11_RSA_finish(RSA *rsa);
-+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
-+static int pk11_RSA_verify(int dtype, const unsigned char *m,
-+ unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
-+ const RSA *rsa);
-+EVP_PKEY *pk11_load_privkey(ENGINE*, const char* pubkey_file,
-+ UI_METHOD *ui_method, void *callback_data);
-+EVP_PKEY *pk11_load_pubkey(ENGINE*, const char* pubkey_file,
-+ UI_METHOD *ui_method, void *callback_data);
-+
-+static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa);
-+static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa);
-+static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa);
-+static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa);
-+
-+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp);
-+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa,
-+ PK11_SESSION *sp);
-+#endif
-+
-+/* DSA stuff */
-+#ifndef OPENSSL_NO_DSA
-+static int pk11_DSA_init(DSA *dsa);
-+static int pk11_DSA_finish(DSA *dsa);
-+static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
-+ DSA *dsa);
-+static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
-+ DSA_SIG *sig, DSA *dsa);
-+
-+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
-+ PK11_SESSION *sp);
-+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
-+ PK11_SESSION *sp);
-+#endif
-+
-+/* DH stuff */
-+#ifndef OPENSSL_NO_DH
-+static int pk11_DH_init(DH *dh);
-+static int pk11_DH_finish(DH *dh);
-+static int pk11_DH_generate_key(DH *dh);
-+static int pk11_DH_compute_key(unsigned char *key,
-+ const BIGNUM *pub_key,DH *dh);
-+
-+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, PK11_SESSION *sp);
-+#endif
-+
-+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
-+ CK_ULONG *ulValueLen);
-+static void check_new_rsa_key(PK11_SESSION *sp, void *rsa);
-+static void check_new_dsa_key(PK11_SESSION *sp, void *dsa);
-+static void check_new_dh_key(PK11_SESSION *sp, void *dh);
-+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
-+
-+
-+#ifndef OPENSSL_NO_RSA
-+/* Our internal RSA_METHOD that we provide pointers to */
-+static RSA_METHOD pk11_rsa =
-+ {
-+ "PKCS#11 RSA method",
-+ pk11_RSA_public_encrypt, /* rsa_pub_encrypt */
-+ pk11_RSA_public_decrypt, /* rsa_pub_decrypt */
-+ pk11_RSA_private_encrypt, /* rsa_priv_encrypt */
-+ pk11_RSA_private_decrypt, /* rsa_priv_decrypt */
-+ NULL, /* rsa_mod_exp */
-+ NULL, /* bn_mod_exp */
-+ pk11_RSA_init, /* init */
-+ pk11_RSA_finish, /* finish */
-+ RSA_FLAG_SIGN_VER, /* flags */
-+ NULL, /* app_data */
-+ pk11_RSA_sign, /* rsa_sign */
-+ pk11_RSA_verify/*,*/ /* rsa_verify */
-+ };
-+
-+RSA_METHOD *PK11_RSA(void)
-+ {
-+ return(&pk11_rsa);
-+ }
-+#endif
-+
-+#ifndef OPENSSL_NO_DSA
-+/* Our internal DSA_METHOD that we provide pointers to */
-+static DSA_METHOD pk11_dsa =
-+ {
-+ "PKCS#11 DSA method",
-+ pk11_dsa_do_sign, /* dsa_do_sign */
-+ NULL, /* dsa_sign_setup */
-+ pk11_dsa_do_verify, /* dsa_do_verify */
-+ NULL, /* dsa_mod_exp */
-+ NULL, /* bn_mod_exp */
-+ pk11_DSA_init, /* init */
-+ pk11_DSA_finish, /* finish */
-+ 0, /* flags */
-+ NULL /* app_data */
-+ };
-+
-+DSA_METHOD *PK11_DSA(void)
-+ {
-+ return(&pk11_dsa);
-+ }
-+
-+#endif
-+
-+
-+#ifndef OPENSSL_NO_DH
-+/* Our internal DH_METHOD that we provide pointers to */
-+static DH_METHOD pk11_dh =
-+ {
-+ "PKCS#11 DH method",
-+ pk11_DH_generate_key, /* generate_key */
-+ pk11_DH_compute_key, /* compute_key */
-+ NULL, /* bn_mod_exp */
-+ pk11_DH_init, /* init */
-+ pk11_DH_finish, /* finish */
-+ 0, /* flags */
-+ NULL /* app_data */
-+ };
-+
-+DH_METHOD *PK11_DH(void)
-+ {
-+ return(&pk11_dh);
-+ }
-+#endif
-+
-+/* Size of an SSL signature: MD5+SHA1
-+ */
-+#define SSL_SIG_LENGTH 36
-+
-+/* Lengths of DSA data and signature
-+ */
-+#define DSA_DATA_LEN 20
-+#define DSA_SIGNATURE_LEN 40
-+
-+static CK_BBOOL true = TRUE;
-+static CK_BBOOL false = FALSE;
-+
-+#ifndef OPENSSL_NO_RSA
-+
-+/* Similiar to Openssl to take advantage of the paddings. The goal is to
-+ * support all paddings in this engine although PK11 library does not
-+ * support all the paddings used in OpenSSL.
-+ * The input errors should have been checked in the padding functions
-+ */
-+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding)
-+ {
-+ int i,num=0,r= -1;
-+ unsigned char *buf=NULL;
-+
-+ num=BN_num_bytes(rsa->n);
-+ if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
-+ {
-+ RSAerr(PK11_F_RSA_PUB_ENC,PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ switch (padding)
-+ {
-+ case RSA_PKCS1_PADDING:
-+ i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
-+ break;
-+#ifndef OPENSSL_NO_SHA
-+ case RSA_PKCS1_OAEP_PADDING:
-+ i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
-+ break;
-+#endif
-+ case RSA_SSLV23_PADDING:
-+ i=RSA_padding_add_SSLv23(buf,num,from,flen);
-+ break;
-+ case RSA_NO_PADDING:
-+ i=RSA_padding_add_none(buf,num,from,flen);
-+ break;
-+ default:
-+ RSAerr(PK11_F_RSA_PUB_ENC,PK11_R_UNKNOWN_PADDING_TYPE);
-+ goto err;
-+ }
-+ if (i <= 0) goto err;
-+
-+ /* PK11 functions are called here */
-+ r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
-+err:
-+ if (buf != NULL)
-+ {
-+ OPENSSL_cleanse(buf,num);
-+ OPENSSL_free(buf);
-+ }
-+ return(r);
-+ }
-+
-+
-+/* Similar to Openssl to take advantage of the paddings. The input errors
-+ * should be catched in the padding functions
-+ */
-+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding)
-+ {
-+ int i,num=0,r= -1;
-+ unsigned char *buf=NULL;
-+
-+ num=BN_num_bytes(rsa->n);
-+ if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
-+ {
-+ RSAerr(PK11_F_RSA_PRIV_ENC,PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ switch (padding)
-+ {
-+ case RSA_PKCS1_PADDING:
-+ i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
-+ break;
-+ case RSA_NO_PADDING:
-+ i=RSA_padding_add_none(buf,num,from,flen);
-+ break;
-+ case RSA_SSLV23_PADDING:
-+ default:
-+ RSAerr(PK11_F_RSA_PRIV_ENC,PK11_R_UNKNOWN_PADDING_TYPE);
-+ goto err;
-+ }
-+ if (i <= 0) goto err;
-+
-+ /* PK11 functions are called here */
-+ r=pk11_RSA_private_encrypt_low(num, buf, to, rsa);
-+err:
-+ if (buf != NULL)
-+ {
-+ OPENSSL_cleanse(buf,num);
-+ OPENSSL_free(buf);
-+ }
-+ return(r);
-+ }
-+
-+/* Similar to Openssl. Input errors are also checked here
-+ */
-+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding)
-+ {
-+ BIGNUM f;
-+ int j,num=0,r= -1;
-+ unsigned char *p;
-+ unsigned char *buf=NULL;
-+
-+ BN_init(&f);
-+
-+ num=BN_num_bytes(rsa->n);
-+
-+ if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
-+ {
-+ RSAerr(PK11_F_RSA_PRIV_DEC,PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* This check was for equality but PGP does evil things
-+ * and chops off the top '0' bytes */
-+ if (flen > num)
-+ {
-+ RSAerr(PK11_F_RSA_PRIV_DEC,
-+ PK11_R_DATA_GREATER_THAN_MOD_LEN);
-+ goto err;
-+ }
-+
-+ /* make data into a big number */
-+ if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;
-+
-+ if (BN_ucmp(&f, rsa->n) >= 0)
-+ {
-+ RSAerr(PK11_F_RSA_PRIV_DEC,
-+ PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-+ goto err;
-+ }
-+
-+ /* PK11 functions are called here */
-+ r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
-+
-+ /* PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-+ * Needs to skip these 0's paddings here */
-+ for (j = 0; j < r; j++)
-+ if (buf[j] != 0)
-+ break;
-+
-+ p = buf + j;
-+ j = r - j; /* j is only used with no-padding mode */
-+
-+ switch (padding)
-+ {
-+ case RSA_PKCS1_PADDING:
-+ r=RSA_padding_check_PKCS1_type_2(to,num,p,j,num);
-+ break;
-+#ifndef OPENSSL_NO_SHA
-+ case RSA_PKCS1_OAEP_PADDING:
-+ r=RSA_padding_check_PKCS1_OAEP(to,num,p,j,num,NULL,0);
-+ break;
-+#endif
-+ case RSA_SSLV23_PADDING:
-+ r=RSA_padding_check_SSLv23(to,num,p,j,num);
-+ break;
-+ case RSA_NO_PADDING:
-+ r=RSA_padding_check_none(to,num,p,j,num);
-+ break;
-+ default:
-+ RSAerr(PK11_F_RSA_PRIV_DEC,PK11_R_UNKNOWN_PADDING_TYPE);
-+ goto err;
-+ }
-+ if (r < 0)
-+ RSAerr(PK11_F_RSA_PRIV_DEC,PK11_R_PADDING_CHECK_FAILED);
-+
-+err:
-+ BN_clear_free(&f);
-+ if (buf != NULL)
-+ {
-+ OPENSSL_cleanse(buf,num);
-+ OPENSSL_free(buf);
-+ }
-+ return(r);
-+ }
-+
-+/* Similar to Openssl. Input errors are also checked here
-+ */
-+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding)
-+ {
-+ BIGNUM f;
-+ int i,num=0,r= -1;
-+ unsigned char *p;
-+ unsigned char *buf=NULL;
-+
-+ BN_init(&f);
-+ num=BN_num_bytes(rsa->n);
-+ buf=(unsigned char *)OPENSSL_malloc(num);
-+ if (buf == NULL)
-+ {
-+ RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* This check was for equality but PGP does evil things
-+ * and chops off the top '0' bytes */
-+ if (flen > num)
-+ {
-+ RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_DATA_GREATER_THAN_MOD_LEN);
-+ goto err;
-+ }
-+
-+ if (BN_bin2bn(from,flen,&f) == NULL) goto err;
-+
-+ if (BN_ucmp(&f, rsa->n) >= 0)
-+ {
-+ RSAerr(PK11_F_RSA_PUB_DEC,
-+ PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-+ goto err;
-+ }
-+
-+ /* PK11 functions are called here */
-+ r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
-+
-+ /* PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-+ * Needs to skip these 0's here */
-+ for (i = 0; i < r; i++)
-+ if (buf[i] != 0)
-+ break;
-+
-+ p = buf + i;
-+ i = r - i; /* i is only used with no-padding mode */
-+
-+ switch (padding)
-+ {
-+ case RSA_PKCS1_PADDING:
-+ r=RSA_padding_check_PKCS1_type_1(to,num,p,i,num);
-+ break;
-+ case RSA_NO_PADDING:
-+ r=RSA_padding_check_none(to,num,p,i,num);
-+ break;
-+ default:
-+ RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_UNKNOWN_PADDING_TYPE);
-+ goto err;
-+ }
-+ if (r < 0)
-+ RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_PADDING_CHECK_FAILED);
-+
-+err:
-+ BN_clear_free(&f);
-+ if (buf != NULL)
-+ {
-+ OPENSSL_cleanse(buf,num);
-+ OPENSSL_free(buf);
-+ }
-+ return(r);
-+ }
-+
-+/* This function implements RSA public encryption using C_EncryptInit and
-+ * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
-+ * The calling function allocated sufficient memory in "to" to store results.
-+ */
-+static int pk11_RSA_public_encrypt_low(int flen,
-+ const unsigned char *from, unsigned char *to, RSA *rsa)
-+ {
-+ CK_ULONG bytes_encrypted=flen;
-+ int retval = -1;
-+ CK_RV rv;
-+ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-+ CK_MECHANISM *p_mech = &mech_rsa;
-+ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-+ PK11_SESSION *sp;
-+ char tmp_buf[20];
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return -1;
-+
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_pub_key = sp->rsa_pub_key;
-+ if (h_pub_key == CK_INVALID_HANDLE)
-+ h_pub_key = sp->rsa_pub_key =
-+ pk11_get_public_rsa_key(rsa, sp);
-+
-+ if (h_pub_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_EncryptInit(sp->session, p_mech,
-+ h_pub_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PUB_ENC_LOW,
-+ PK11_R_ENCRYPTINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+
-+ rv = pFuncList->C_Encrypt(sp->session,
-+ (unsigned char *)from, flen, to, &bytes_encrypted);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PUB_ENC_LOW, PK11_R_ENCRYPT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+ retval = bytes_encrypted;
-+ }
-+
-+ pk11_return_session(sp);
-+ return retval;
-+ }
-+
-+
-+/* This function implements RSA private encryption using C_SignInit and
-+ * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
-+ * The calling function allocated sufficient memory in "to" to store results.
-+ */
-+static int pk11_RSA_private_encrypt_low(int flen,
-+ const unsigned char *from, unsigned char *to, RSA *rsa)
-+ {
-+ CK_ULONG ul_sig_len=flen;
-+ int retval = -1;
-+ CK_RV rv;
-+ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-+ CK_MECHANISM *p_mech = &mech_rsa;
-+ CK_OBJECT_HANDLE h_priv_key= CK_INVALID_HANDLE;
-+ PK11_SESSION *sp;
-+ char tmp_buf[20];
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return -1;
-+
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_priv_key = sp->rsa_priv_key;
-+ if (h_priv_key == CK_INVALID_HANDLE)
-+ h_priv_key = sp->rsa_priv_key =
-+ pk11_get_private_rsa_key(rsa, sp);
-+
-+ if (h_priv_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_SignInit(sp->session, p_mech,
-+ h_priv_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGNINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+
-+ rv = pFuncList->C_Sign(sp->session,
-+ (unsigned char *)from, flen, to, &ul_sig_len);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+
-+ retval = ul_sig_len;
-+ }
-+
-+ pk11_return_session(sp);
-+ return retval;
-+ }
-+
-+
-+/* This function implements RSA private decryption using C_DecryptInit and
-+ * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
-+ * The calling function allocated sufficient memory in "to" to store results.
-+ */
-+static int pk11_RSA_private_decrypt_low(int flen,
-+ const unsigned char *from, unsigned char *to, RSA *rsa)
-+ {
-+ CK_ULONG bytes_decrypted = flen;
-+ int retval = -1;
-+ CK_RV rv;
-+ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-+ CK_MECHANISM *p_mech = &mech_rsa;
-+ CK_OBJECT_HANDLE h_priv_key;
-+ PK11_SESSION *sp;
-+ char tmp_buf[20];
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return -1;
-+
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_priv_key = sp->rsa_priv_key;
-+ if (h_priv_key == CK_INVALID_HANDLE)
-+ h_priv_key = sp->rsa_priv_key =
-+ pk11_get_private_rsa_key(rsa, sp);
-+
-+ if (h_priv_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_DecryptInit(sp->session, p_mech,
-+ h_priv_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PRIV_DEC_LOW,
-+ PK11_R_DECRYPTINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+
-+ rv = pFuncList->C_Decrypt(sp->session,
-+ (unsigned char *)from, flen, to, &bytes_decrypted);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PRIV_DEC_LOW, PK11_R_DECRYPT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+ retval = bytes_decrypted;
-+ }
-+
-+ pk11_return_session(sp);
-+ return retval;
-+ }
-+
-+
-+/* This function implements RSA public decryption using C_VerifyRecoverInit
-+ * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
-+ * The calling function allocated sufficient memory in "to" to store results.
-+ */
-+static int pk11_RSA_public_decrypt_low(int flen,
-+ const unsigned char *from, unsigned char *to, RSA *rsa)
-+ {
-+ CK_ULONG bytes_decrypted = flen;
-+ int retval = -1;
-+ CK_RV rv;
-+ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-+ CK_MECHANISM *p_mech = &mech_rsa;
-+ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-+ PK11_SESSION *sp;
-+ char tmp_buf[20];
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return -1;
-+
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_pub_key = sp->rsa_pub_key;
-+ if (h_pub_key == CK_INVALID_HANDLE)
-+ h_pub_key = sp->rsa_pub_key =
-+ pk11_get_public_rsa_key(rsa, sp);
-+
-+ if (h_pub_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_VerifyRecoverInit(sp->session,
-+ p_mech, h_pub_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PUB_DEC_LOW,
-+ PK11_R_VERIFYRECOVERINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+
-+ rv = pFuncList->C_VerifyRecover(sp->session,
-+ (unsigned char *)from, flen, to, &bytes_decrypted);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_PUB_DEC_LOW,
-+ PK11_R_VERIFYRECOVER);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ pk11_return_session(sp);
-+ return -1;
-+ }
-+ retval = bytes_decrypted;
-+ }
-+
-+ pk11_return_session(sp);
-+ return retval;
-+ }
-+
-+
-+static int pk11_RSA_init(RSA *rsa)
-+ {
-+ /* This flag in the RSA_METHOD enables the new rsa_sign,
-+ * rsa_verify functions. See rsa.h for details. */
-+ rsa->flags |= RSA_FLAG_SIGN_VER;
-+
-+ return 1;
-+ }
-+
-+
-+static int pk11_RSA_finish(RSA *rsa)
-+ {
-+ if (rsa->_method_mod_n != NULL)
-+ BN_MONT_CTX_free(rsa->_method_mod_n);
-+ if (rsa->_method_mod_p != NULL)
-+ BN_MONT_CTX_free(rsa->_method_mod_p);
-+ if (rsa->_method_mod_q != NULL)
-+ BN_MONT_CTX_free(rsa->_method_mod_q);
-+
-+ return pk11_destroy_rsa_key_objects(NULL);
-+ }
-+
-+
-+/* Standard engine interface function. Majority codes here are from
-+ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
-+ * See more details in rsa/rsa_sign.c */
-+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
-+ {
-+ X509_SIG sig;
-+ ASN1_TYPE parameter;
-+ int i,j;
-+ unsigned char *p,*s = NULL;
-+ X509_ALGOR algor;
-+ ASN1_OCTET_STRING digest;
-+ CK_RV rv;
-+ CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-+ CK_MECHANISM *p_mech = &mech_rsa;
-+ CK_OBJECT_HANDLE h_priv_key;
-+ PK11_SESSION *sp = NULL;
-+ int ret = 0;
-+ char tmp_buf[20];
-+ unsigned long ulsiglen;
-+
-+ /* Encode the digest */
-+ /* Special case: SSL signature, just check the length */
-+ if (type == NID_md5_sha1)
-+ {
-+ if (m_len != SSL_SIG_LENGTH)
-+ {
-+ PK11err(PK11_F_RSA_SIGN,
-+ PK11_R_INVALID_MESSAGE_LENGTH);
-+ goto err;
-+ }
-+ i = SSL_SIG_LENGTH;
-+ s = (unsigned char *)m;
-+ }
-+ else
-+ {
-+ sig.algor= &algor;
-+ sig.algor->algorithm=OBJ_nid2obj(type);
-+ if (sig.algor->algorithm == NULL)
-+ {
-+ PK11err(PK11_F_RSA_SIGN,
-+ PK11_R_UNKNOWN_ALGORITHM_TYPE);
-+ goto err;
-+ }
-+ if (sig.algor->algorithm->length == 0)
-+ {
-+ PK11err(PK11_F_RSA_SIGN,
-+ PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-+ goto err;
-+ }
-+ parameter.type=V_ASN1_NULL;
-+ parameter.value.ptr=NULL;
-+ sig.algor->parameter= &parameter;
-+
-+ sig.digest= &digest;
-+ sig.digest->data=(unsigned char *)m;
-+ sig.digest->length=m_len;
-+
-+ i=i2d_X509_SIG(&sig,NULL);
-+ }
-+
-+ j=RSA_size(rsa);
-+ if ((i-RSA_PKCS1_PADDING) > j)
-+ {
-+ PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
-+ goto err;
-+ }
-+
-+ if (type != NID_md5_sha1)
-+ {
-+ s=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
-+ if (s == NULL)
-+ {
-+ PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ p=s;
-+ i2d_X509_SIG(&sig,&p);
-+ }
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ goto err;
-+
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_priv_key = sp->rsa_priv_key;
-+ if (h_priv_key == CK_INVALID_HANDLE)
-+ h_priv_key = sp->rsa_priv_key =
-+ pk11_get_private_rsa_key((RSA *)rsa, sp);
-+
-+ if (h_priv_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_SIGN, PK11_R_SIGNINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ ulsiglen = j;
-+ rv = pFuncList->C_Sign(sp->session, s, i, sigret,
-+ (CK_ULONG_PTR) &ulsiglen);
-+ *siglen = ulsiglen;
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_SIGN, PK11_R_SIGN);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ ret = 1;
-+ }
-+
-+err:
-+ if (type != NID_md5_sha1)
-+ {
-+ memset(s,0,(unsigned int)j+1);
-+ OPENSSL_free(s);
-+ }
-+
-+ pk11_return_session(sp);
-+ return ret;
-+ }
-+
-+static int pk11_RSA_verify(int type, const unsigned char *m,
-+ unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
-+ const RSA *rsa)
-+ {
-+ X509_SIG sig;
-+ ASN1_TYPE parameter;
-+ int i,j;
-+ unsigned char *p,*s = NULL;
-+ X509_ALGOR algor;
-+ ASN1_OCTET_STRING digest;
-+ CK_RV rv;
-+ CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-+ CK_MECHANISM *p_mech = &mech_rsa;
-+ CK_OBJECT_HANDLE h_pub_key;
-+ PK11_SESSION *sp = NULL;
-+ int ret = 0;
-+ char tmp_buf[20];
-+
-+ /* Encode the digest */
-+ /* Special case: SSL signature, just check the length */
-+ if (type == NID_md5_sha1)
-+ {
-+ if (m_len != SSL_SIG_LENGTH)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY,
-+ PK11_R_INVALID_MESSAGE_LENGTH);
-+ goto err;
-+ }
-+ i = SSL_SIG_LENGTH;
-+ s = (unsigned char *)m;
-+ }
-+ else
-+ {
-+ sig.algor= &algor;
-+ sig.algor->algorithm=OBJ_nid2obj(type);
-+ if (sig.algor->algorithm == NULL)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY,
-+ PK11_R_UNKNOWN_ALGORITHM_TYPE);
-+ goto err;
-+ }
-+ if (sig.algor->algorithm->length == 0)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY,
-+ PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-+ goto err;
-+ }
-+ parameter.type=V_ASN1_NULL;
-+ parameter.value.ptr=NULL;
-+ sig.algor->parameter= &parameter;
-+ sig.digest= &digest;
-+ sig.digest->data=(unsigned char *)m;
-+ sig.digest->length=m_len;
-+ i=i2d_X509_SIG(&sig,NULL);
-+ }
-+
-+ j=RSA_size(rsa);
-+ if ((i-RSA_PKCS1_PADDING) > j)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
-+ goto err;
-+ }
-+
-+ if (type != NID_md5_sha1)
-+ {
-+ s=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
-+ if (s == NULL)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ p=s;
-+ i2d_X509_SIG(&sig,&p);
-+ }
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ goto err;
-+
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_pub_key = sp->rsa_pub_key;
-+ if (h_pub_key == CK_INVALID_HANDLE)
-+ h_pub_key = sp->rsa_pub_key =
-+ pk11_get_public_rsa_key((RSA *)rsa, sp);
-+
-+ if (h_pub_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-+ h_pub_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ rv = pFuncList->C_Verify(sp->session, s, i, sigbuf,
-+ (CK_ULONG)siglen);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_RSA_VERIFY, PK11_R_VERIFY);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ ret = 1;
-+ }
-+
-+err:
-+ if (type != NID_md5_sha1)
-+ {
-+ memset(s,0,(unsigned int)siglen);
-+ OPENSSL_free(s);
-+ }
-+
-+ pk11_return_session(sp);
-+ return ret;
-+ }
-+
-+static int hndidx_rsa = -1;
-+
-+struct key_info {
-+ CK_OBJECT_HANDLE handle;
-+ CK_SESSION_HANDLE session;
-+};
-+
-+/* Destroy the object when the last reference to it has gone.
-+ */
-+static void hndidx_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
-+ int ind, long argl, void *argp)
-+{
-+ struct key_info *key_info = item;
-+ CK_RV rv;
-+ char tmp_buf[20];
-+
-+ if (key_info != NULL)
-+ {
-+ rv = pFuncList->C_DestroyObject(key_info->session,
-+ key_info->handle);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ }
-+ free(item);
-+ }
-+}
-+
-+EVP_PKEY *pk11_load_privkey(ENGINE* e, const char* privkey_file,
-+ UI_METHOD *ui_method, void *callback_data)
-+ {
-+ EVP_PKEY *pkey=NULL;
-+ FILE *privkey;
-+ CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-+ RSA *rsa;
-+ PK11_SESSION *sp;
-+ /* everything else below needed for key by reference extension */
-+ char tmp_buf[20];
-+ CK_RV rv;
-+ CK_ULONG objcnt = 0;
-+ CK_BBOOL is_token = TRUE;
-+ CK_BYTE attr_data[2][1024];
-+ CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
-+ CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */
-+ struct key_info *key_info = NULL;
-+ extern char *pk11_pin;
-+
-+ /* we look for private keys only */
-+ CK_ATTRIBUTE search_templ[] =
-+ {
-+ {CKA_TOKEN, &is_token, sizeof(is_token)},
-+ {CKA_CLASS, &key_class, sizeof(key_class)},
-+ {CKA_LABEL, NULL, 0}
-+ };
-+
-+ /* these attributes are needed to initialize OpenSSL RSA structure */
-+ CK_ATTRIBUTE get_templ[] =
-+ {
-+ {CKA_MODULUS, (void *)attr_data[0], 1024}, /* n */
-+ {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024}, /* e */
-+ };
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return NULL;
-+
-+ /*
-+ * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
-+ */
-+ if (strstr(privkey_file, "pkcs11:") == privkey_file)
-+ {
-+ search_templ[2].pValue = strstr(privkey_file, ":") + 1;
-+ search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-+
-+ if (pk11_pin == NULL)
-+#ifndef OPENCRYPTOKI
-+ pk11_pin = getpassphrase("Enter PIN: ");
-+#else
-+ pk11_pin = getpass("Enter PIN: ");
-+#endif
-+ if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
-+ strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
-+ {
-+ fprintf(stderr, "C_Login -> %lx\n", rv);
-+ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_INVALID_PIN);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if ((rv = pFuncList->C_FindObjectsInit(sp->session,
-+ search_templ, 3)) != CKR_OK)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
-+ if (rv != CKR_OK)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (objcnt > 1)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_TOO_MANY_OBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lu", objcnt);
-+ ERR_add_error_data(2,
-+ "PK11 too many objects:", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (objcnt != 1)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_OBJECT_NOT_FOUND);
-+ ERR_add_error_data(1, "PK11 object not found");
-+ goto err;
-+ }
-+
-+ (void) pFuncList->C_FindObjectsFinal(sp->session);
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ if (hndidx_rsa == -1)
-+ hndidx_rsa = RSA_get_ex_new_index(0,
-+ "pkcs11 RSA HSM key handle",
-+ NULL, NULL, hndidx_free);
-+
-+ key_info = malloc(sizeof(struct key_info));
-+ if (key_info == NULL)
-+ goto err;
-+
-+ pkey = EVP_PKEY_new();
-+ if (pkey == NULL)
-+ goto err;
-+
-+ rsa = RSA_new();
-+ if (rsa == NULL) {
-+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ goto err;
-+ }
-+ EVP_PKEY_set1_RSA(pkey, rsa);
-+
-+ if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-+ get_templ, 2)) != CKR_OK)
-+ {
-+ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ goto err;
-+ }
-+
-+ /*
-+ * Now we have to initialize an OpenSSL RSA structure,
-+ * everything else is 0 or NULL.
-+ */
-+ rsa->meth = &pk11_rsa;
-+ rsa->engine = e;
-+ rsa->references = 2;
-+ rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
-+ key_info->handle = ks_key;
-+ key_info->session = sp->session;
-+ RSA_set_ex_data(rsa, hndidx_rsa, key_info);
-+ key_info = NULL;
-+ sp->rsa = rsa;
-+ sp->rsa_priv_key = ks_key;
-+
-+ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-+#ifdef OPENCRYPTOKI
-+ /* openCryptoki bug workaround */
-+ if (get_templ[1].ulValueLen == 0) {
-+ get_templ[1].ulValueLen = 1;
-+ attr_data[1][0] = 3;
-+ }
-+#endif
-+ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-+ }
-+ else if ((privkey=fopen(privkey_file,"r")) != NULL)
-+ {
-+ pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
-+ fclose(privkey);
-+ if (pkey)
-+ {
-+ rsa = EVP_PKEY_get1_RSA(pkey);
-+
-+ if (rsa)
-+ {
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_priv_key = pk11_get_private_rsa_key(rsa,
-+ sp);
-+ if (h_priv_key == CK_INVALID_HANDLE)
-+ {
-+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ }
-+ }
-+ else
-+ {
-+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ }
-+ }
-+ }
-+
-+err:
-+ if (key_info != NULL)
-+ free(key_info);
-+ pk11_return_session(sp);
-+ return(pkey);
-+ }
-+
-+EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char* pubkey_file,
-+ UI_METHOD *ui_method, void *callback_data)
-+ {
-+ EVP_PKEY *pkey=NULL;
-+ FILE *pubkey;
-+ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-+ RSA *rsa;
-+ PK11_SESSION *sp;
-+ /* everything else below needed for key by reference extension */
-+ char tmp_buf[20];
-+ CK_RV rv;
-+ CK_ULONG objcnt = 0;
-+ CK_BBOOL is_token = TRUE;
-+ CK_BYTE attr_data[2][1024];
-+ CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
-+ CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */
-+ extern char *pk11_pin;
-+
-+ /* we look for private keys only */
-+ CK_ATTRIBUTE search_templ[] =
-+ {
-+ {CKA_TOKEN, &is_token, sizeof(is_token)},
-+ {CKA_CLASS, &key_class, sizeof(key_class)},
-+ {CKA_LABEL, NULL, 0}
-+ };
-+
-+ /* these attributes are needed to initialize OpenSSL RSA structure */
-+ CK_ATTRIBUTE get_templ[] =
-+ {
-+ {CKA_MODULUS, (void *)attr_data[0], 1024}, /* n */
-+ {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024}, /* e */
-+ };
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ return NULL;
-+
-+ /*
-+ * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
-+ */
-+ if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
-+ {
-+ search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
-+ search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-+
-+#define ALLWAYS_LOGIN
-+#ifdef ALLWAYS_LOGIN
-+ if (pk11_pin == NULL)
-+#ifndef OPENCRYPTOKI
-+ pk11_pin = getpassphrase("Enter PIN: ");
-+#else
-+ pk11_pin = getpass("Enter PIN: ");
-+#endif
-+ if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
-+ strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
-+ {
-+ fprintf(stderr, "C_Login -> %lx\n", rv);
-+ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_INVALID_PIN);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+#endif
-+
-+ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
-+ if (pFuncList->C_FindObjectsInit(sp->session, search_templ, 3) != CKR_OK)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
-+ if (rv != CKR_OK)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (objcnt > 1)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_TOO_MANY_OBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lu", objcnt);
-+ ERR_add_error_data(2,
-+ "PK11 too many objects:", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (objcnt != 1)
-+ {
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_OBJECT_NOT_FOUND);
-+ ERR_add_error_data(1, "PK11 object not found");
-+ goto err;
-+ }
-+
-+ (void) pFuncList->C_FindObjectsFinal(sp->session);
-+ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
-+
-+ sp->rsa_pub_key = ks_key;
-+ pkey = malloc(sizeof(EVP_PKEY));
-+ bzero(pkey, sizeof(EVP_PKEY));
-+ pkey->type = EVP_PKEY_RSA;
-+ pkey->references = 1;
-+
-+ rsa = pkey->pkey.rsa = sp->rsa = malloc(sizeof(RSA));
-+ bzero(rsa, sizeof(RSA));
-+
-+ if (pFuncList->C_GetAttributeValue(sp->session, ks_key,
-+ get_templ, 3) != CKR_OK)
-+ {
-+ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ /*
-+ * Now we have to initialize an OpenSSL RSA structure,
-+ * everything else is 0 or NULL.
-+ */
-+ rsa->meth = &pk11_rsa;
-+ rsa->engine = e;
-+ rsa->references = 2;
-+ rsa->flags = RSA_FLAG_SIGN_VER;
-+
-+ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-+ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-+ }
-+ else if ((pubkey=fopen(pubkey_file,"r")) != NULL)
-+ {
-+ pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
-+ fclose(pubkey);
-+ if (pkey)
-+ {
-+ rsa = EVP_PKEY_get1_RSA(pkey);
-+ if (rsa)
-+ {
-+ check_new_rsa_key(sp, (void *) rsa);
-+
-+ h_pub_key = pk11_get_public_rsa_key(rsa, sp);
-+ if (h_pub_key == CK_INVALID_HANDLE)
-+ {
-+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ }
-+ }
-+ else
-+ {
-+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ }
-+ }
-+ }
-+
-+err:
-+ pk11_return_session(sp);
-+ return(pkey);
-+ }
-+
-+/* Create a public key object in a session from a given rsa structure.
-+ */
-+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+ CK_ULONG found;
-+ CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-+ CK_KEY_TYPE k_type = CKK_RSA;
-+ CK_ULONG ul_key_attr_count = 7;
-+ char tmp_buf[20];
-+
-+ CK_ATTRIBUTE a_key_template[] =
-+ {
-+ {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
-+ {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
-+ {CKA_TOKEN, &false, sizeof(true)},
-+ {CKA_ENCRYPT, &true, sizeof(true)},
-+ {CKA_VERIFY_RECOVER, &true, sizeof(true)},
-+ {CKA_MODULUS, (void *)NULL, 0},
-+ {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
-+ };
-+
-+ int i;
-+ CK_SESSION_HANDLE session = sp->session;
-+
-+ a_key_template[0].pValue = &o_key;
-+ a_key_template[1].pValue = &k_type;
-+
-+ a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
-+ a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-+ (size_t)a_key_template[5].ulValueLen);
-+ if (a_key_template[5].pValue == NULL)
-+ {
-+ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ BN_bn2bin(rsa->n, a_key_template[5].pValue);
-+
-+ a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
-+ a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-+ (size_t)a_key_template[6].ulValueLen);
-+ if (a_key_template[6].pValue == NULL)
-+ {
-+ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ BN_bn2bin(rsa->e, a_key_template[6].pValue);
-+
-+ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-+ ul_key_attr_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsFinal(session);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSFINAL);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (found == 0)
-+ {
-+ rv = pFuncList->C_CreateObject(session,
-+ a_key_template, ul_key_attr_count, &h_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_RSA_KEY,
-+ PK11_R_CREATEOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ }
-+
-+ sp->rsa = rsa;
-+
-+ err:
-+ for (i = 5; i <= 6; i++)
-+ {
-+ if (a_key_template[i].pValue != NULL)
-+ {
-+ OPENSSL_free(a_key_template[i].pValue);
-+ a_key_template[i].pValue = NULL;
-+ }
-+ }
-+
-+ return h_key;
-+
-+ }
-+
-+/* Create a private key object in the session from a given rsa structure
-+ */
-+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+ int i;
-+ CK_ULONG found;
-+ CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-+ CK_KEY_TYPE k_type = CKK_RSA;
-+ CK_ULONG ul_key_attr_count = 14;
-+ char tmp_buf[20];
-+
-+ /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys
-+ */
-+ CK_ATTRIBUTE a_key_template[] =
-+ {
-+ {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
-+ {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
-+ {CKA_TOKEN, &false, sizeof(true)},
-+ {CKA_SENSITIVE, &false, sizeof(true)},
-+ {CKA_DECRYPT, &true, sizeof(true)},
-+ {CKA_SIGN, &true, sizeof(true)},
-+ {CKA_MODULUS, (void *)NULL, 0},
-+ {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
-+ {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
-+ {CKA_PRIME_1, (void *)NULL, 0},
-+ {CKA_PRIME_2, (void *)NULL, 0},
-+ {CKA_EXPONENT_1, (void *)NULL, 0},
-+ {CKA_EXPONENT_2, (void *)NULL, 0},
-+ {CKA_COEFFICIENT, (void *)NULL, 0}
-+ };
-+ CK_SESSION_HANDLE session = sp->session;
-+
-+ if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
-+ sp->rsa = rsa;
-+ return (*(CK_OBJECT_HANDLE_PTR)RSA_get_ex_data(rsa, hndidx_rsa));
-+ }
-+
-+ a_key_template[0].pValue = &o_key;
-+ a_key_template[1].pValue = &k_type;
-+
-+ /* Put the private key components into the template */
-+ if (init_template_value(rsa->n, &a_key_template[6].pValue,
-+ &a_key_template[6].ulValueLen) == 0 ||
-+ init_template_value(rsa->e, &a_key_template[7].pValue,
-+ &a_key_template[7].ulValueLen) == 0 ||
-+ init_template_value(rsa->d, &a_key_template[8].pValue,
-+ &a_key_template[8].ulValueLen) == 0 ||
-+ init_template_value(rsa->p, &a_key_template[9].pValue,
-+ &a_key_template[9].ulValueLen) == 0 ||
-+ init_template_value(rsa->q, &a_key_template[10].pValue,
-+ &a_key_template[10].ulValueLen) == 0 ||
-+ init_template_value(rsa->dmp1, &a_key_template[11].pValue,
-+ &a_key_template[11].ulValueLen) == 0 ||
-+ init_template_value(rsa->dmq1, &a_key_template[12].pValue,
-+ &a_key_template[12].ulValueLen) == 0 ||
-+ init_template_value(rsa->iqmp, &a_key_template[13].pValue,
-+ &a_key_template[13].ulValueLen) == 0)
-+ {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-+ ul_key_attr_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsFinal(session);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_FINDOBJECTSFINAL);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (found == 0)
-+ {
-+ rv = pFuncList->C_CreateObject(session,
-+ a_key_template, ul_key_attr_count, &h_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY,
-+ PK11_R_CREATEOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ }
-+
-+ sp->rsa = rsa;
-+
-+ err:
-+ /* 6 to 13 entries in the key template are key components
-+ * They need to be freed apon exit or error.
-+ */
-+ for (i = 6; i <= 13; i++)
-+ {
-+ if (a_key_template[i].pValue != NULL)
-+ {
-+ memset(a_key_template[i].pValue, 0,
-+ a_key_template[i].ulValueLen);
-+ OPENSSL_free(a_key_template[i].pValue);
-+ a_key_template[i].pValue = NULL;
-+ }
-+ }
-+
-+ return h_key;
-+ }
-+
-+#endif
-+
-+
-+#ifndef OPENSSL_NO_DSA
-+/* The DSA function implementation
-+ */
-+static int pk11_DSA_init(DSA *dsa)
-+ {
-+ return 1;
-+ }
-+
-+
-+static int pk11_DSA_finish(DSA *dsa)
-+ {
-+ return pk11_destroy_dsa_key_objects(NULL);
-+ }
-+
-+
-+static DSA_SIG *
-+pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
-+ {
-+ BIGNUM *r = NULL, *s = NULL;
-+ int i;
-+ DSA_SIG *dsa_sig = NULL;
-+
-+ CK_RV rv;
-+ CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-+ CK_MECHANISM *p_mech = &Mechanism_dsa;
-+ CK_OBJECT_HANDLE h_priv_key;
-+
-+ /* The signature is the concatenation of r and s,
-+ * each is 20 bytes long
-+ */
-+ unsigned char sigret[DSA_SIGNATURE_LEN];
-+ unsigned long siglen = DSA_SIGNATURE_LEN;
-+ unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
-+
-+ PK11_SESSION *sp = NULL;
-+ char tmp_buf[20];
-+
-+ if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
-+ goto ret;
-+ }
-+
-+ i=BN_num_bytes(dsa->q); /* should be 20 */
-+ if (dlen > i)
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
-+ goto ret;
-+ }
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ goto ret;
-+
-+ check_new_dsa_key(sp, (void *) dsa);
-+
-+ h_priv_key = sp->dsa_priv_key;
-+ if (h_priv_key == CK_INVALID_HANDLE)
-+ h_priv_key = sp->dsa_priv_key =
-+ pk11_get_private_dsa_key((DSA *)dsa, sp);
-+
-+ if (h_priv_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_SIGNINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto ret;
-+ }
-+
-+ memset(sigret, 0, siglen);
-+ rv = pFuncList->C_Sign(sp->session,
-+ (unsigned char*) dgst, dlen, sigret,
-+ (CK_ULONG_PTR) &siglen);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_SIGN);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto ret;
-+ }
-+ }
-+
-+
-+ if ((s = BN_new()) == NULL)
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-+ goto ret;
-+ }
-+
-+ if ((r = BN_new()) == NULL)
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-+ goto ret;
-+ }
-+
-+ if ((dsa_sig = DSA_SIG_new()) == NULL)
-+ {
-+ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-+ goto ret;
-+ }
-+
-+ BN_bin2bn(sigret, siglen2, r);
-+ BN_bin2bn(&sigret[siglen2], siglen2, s);
-+
-+ dsa_sig->r = r;
-+ dsa_sig->s = s;
-+
-+ret:
-+ if (dsa_sig == NULL)
-+ {
-+ if (r != NULL)
-+ BN_free(r);
-+ if (s != NULL)
-+ BN_free(s);
-+ }
-+
-+ pk11_return_session(sp);
-+ return (dsa_sig);
-+ }
-+
-+static int
-+pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
-+ DSA *dsa)
-+ {
-+ int i;
-+ CK_RV rv;
-+ int retval = 0;
-+ CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-+ CK_MECHANISM *p_mech = &Mechanism_dsa;
-+ CK_OBJECT_HANDLE h_pub_key;
-+
-+ unsigned char sigbuf[DSA_SIGNATURE_LEN];
-+ unsigned long siglen = DSA_SIGNATURE_LEN;
-+ unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
-+
-+ PK11_SESSION *sp = NULL;
-+ char tmp_buf[20];
-+
-+ if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
-+ {
-+ PK11err(PK11_F_DSA_VERIFY,
-+ PK11_R_INVALID_DSA_SIGNATURE_R);
-+ goto ret;
-+ }
-+
-+ if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
-+ {
-+ PK11err(PK11_F_DSA_VERIFY,
-+ PK11_R_INVALID_DSA_SIGNATURE_S);
-+ goto ret;
-+ }
-+
-+ i = BN_num_bytes(dsa->q); /* should be 20 */
-+
-+ if (dlen > i)
-+ {
-+ PK11err(PK11_F_DSA_VERIFY,
-+ PK11_R_INVALID_SIGNATURE_LENGTH);
-+ goto ret;
-+ }
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ goto ret;
-+
-+ check_new_dsa_key(sp, (void *) dsa);
-+
-+ h_pub_key = sp->dsa_pub_key;
-+ if (h_pub_key == CK_INVALID_HANDLE)
-+ h_pub_key = sp->dsa_pub_key =
-+ pk11_get_public_dsa_key((DSA *)dsa, sp);
-+
-+ if (h_pub_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-+ h_pub_key);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto ret;
-+ }
-+
-+ memset(sigbuf, 0, siglen);
-+ BN_bn2bin(sig->r, sigbuf);
-+ BN_bn2bin(sig->s, &sigbuf[siglen2]);
-+
-+ rv = pFuncList->C_Verify(sp->session,
-+ (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DSA_VERIFY, PK11_R_VERIFY);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto ret;
-+ }
-+ }
-+
-+ retval = 1;
-+ret:
-+
-+ pk11_return_session(sp);
-+ return retval;
-+ }
-+
-+
-+/* Create a public key object in a session from a given dsa structure.
-+ */
-+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+ CK_ULONG found;
-+ CK_KEY_TYPE k_type = CKK_DSA;
-+ CK_ULONG ul_key_attr_count = 8;
-+ int i;
-+ char tmp_buf[20];
-+
-+ CK_ATTRIBUTE a_key_template[] =
-+ {
-+ {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
-+ {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
-+ {CKA_TOKEN, &false, sizeof(true)},
-+ {CKA_VERIFY, &true, sizeof(true)},
-+ {CKA_PRIME, (void *)NULL, 0}, /* p */
-+ {CKA_SUBPRIME, (void *)NULL, 0}, /* q */
-+ {CKA_BASE, (void *)NULL, 0}, /* g */
-+ {CKA_VALUE, (void *)NULL, 0} /* pub_key - y */
-+ };
-+ CK_SESSION_HANDLE session = sp->session;
-+
-+ a_key_template[0].pValue = &o_key;
-+ a_key_template[1].pValue = &k_type;
-+
-+ if (init_template_value(dsa->p, &a_key_template[4].pValue,
-+ &a_key_template[4].ulValueLen) == 0 ||
-+ init_template_value(dsa->q, &a_key_template[5].pValue,
-+ &a_key_template[5].ulValueLen) == 0 ||
-+ init_template_value(dsa->g, &a_key_template[6].pValue,
-+ &a_key_template[6].ulValueLen) == 0 ||
-+ init_template_value(dsa->pub_key, &a_key_template[7].pValue,
-+ &a_key_template[7].ulValueLen) == 0)
-+ {
-+ PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-+ ul_key_attr_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsFinal(session);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSFINAL);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (found == 0)
-+ {
-+ rv = pFuncList->C_CreateObject(session,
-+ a_key_template, ul_key_attr_count, &h_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PUB_DSA_KEY,
-+ PK11_R_CREATEOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ }
-+
-+ sp->dsa = dsa;
-+
-+ err:
-+ for (i = 4; i <= 7; i++)
-+ {
-+ if (a_key_template[i].pValue != NULL)
-+ {
-+ OPENSSL_free(a_key_template[i].pValue);
-+ a_key_template[i].pValue = NULL;
-+ }
-+ }
-+
-+ return h_key;
-+
-+ }
-+
-+/* Create a private key object in the session from a given dsa structure
-+ */
-+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+ CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-+ int i;
-+ char tmp_buf[20];
-+ CK_ULONG found;
-+ CK_KEY_TYPE k_type = CKK_DSA;
-+ CK_ULONG ul_key_attr_count = 9;
-+
-+ /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys
-+ */
-+ CK_ATTRIBUTE a_key_template[] =
-+ {
-+ {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
-+ {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
-+ {CKA_TOKEN, &false, sizeof(true)},
-+ {CKA_SENSITIVE, &false, sizeof(true)},
-+ {CKA_SIGN, &true, sizeof(true)},
-+ {CKA_PRIME, (void *)NULL, 0}, /* p */
-+ {CKA_SUBPRIME, (void *)NULL, 0}, /* q */
-+ {CKA_BASE, (void *)NULL, 0}, /* g */
-+ {CKA_VALUE, (void *)NULL, 0} /* priv_key - x */
-+ };
-+ CK_SESSION_HANDLE session = sp->session;
-+
-+ a_key_template[0].pValue = &o_key;
-+ a_key_template[1].pValue = &k_type;
-+
-+ /* Put the private key components into the template
-+ */
-+ if (init_template_value(dsa->p, &a_key_template[5].pValue,
-+ &a_key_template[5].ulValueLen) == 0 ||
-+ init_template_value(dsa->q, &a_key_template[6].pValue,
-+ &a_key_template[6].ulValueLen) == 0 ||
-+ init_template_value(dsa->g, &a_key_template[7].pValue,
-+ &a_key_template[7].ulValueLen) == 0 ||
-+ init_template_value(dsa->priv_key, &a_key_template[8].pValue,
-+ &a_key_template[8].ulValueLen) == 0)
-+ {
-+ PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-+ ul_key_attr_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsFinal(session);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_FINDOBJECTSFINAL);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (found == 0)
-+ {
-+ rv = pFuncList->C_CreateObject(session,
-+ a_key_template, ul_key_attr_count, &h_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_PRIV_DSA_KEY,
-+ PK11_R_CREATEOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ }
-+
-+ sp->dsa = dsa;
-+
-+err:
-+ /* 5 to 8 entries in the key template are key components
-+ * They need to be freed apon exit or error.
-+ */
-+ for (i = 5; i <= 8; i++)
-+ {
-+ if (a_key_template[i].pValue != NULL)
-+ {
-+ memset(a_key_template[i].pValue, 0,
-+ a_key_template[i].ulValueLen);
-+ OPENSSL_free(a_key_template[i].pValue);
-+ a_key_template[i].pValue = NULL;
-+ }
-+ }
-+
-+ return h_key;
-+
-+ }
-+#endif
-+
-+
-+#ifndef OPENSSL_NO_DH
-+
-+/* The DH function implementation
-+ */
-+static int pk11_DH_init(DH *dh)
-+ {
-+ return 1;
-+ }
-+
-+
-+static int pk11_DH_finish(DH *dh)
-+ {
-+ return pk11_destroy_dh_key_objects(NULL);
-+ }
-+
-+static int pk11_DH_generate_key(DH *dh)
-+ {
-+ CK_ULONG i;
-+ CK_RV rv, rv1;
-+ int ret = 0;
-+ PK11_SESSION *sp = NULL;
-+ char tmp_buf[20];
-+ CK_BYTE_PTR reuse_mem;
-+
-+ CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
-+ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-+ CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-+
-+ CK_ULONG ul_pub_key_attr_count = 3;
-+ CK_ATTRIBUTE pub_key_template[] =
-+ {
-+ {CKA_PRIVATE, &false, sizeof(false)},
-+ {CKA_PRIME, (void *)NULL, 0},
-+ {CKA_BASE, (void *)NULL, 0}
-+ };
-+
-+ CK_ULONG ul_priv_key_attr_count = 3;
-+ CK_ATTRIBUTE priv_key_template[] =
-+ {
-+ {CKA_PRIVATE, &false, sizeof(false)},
-+ {CKA_SENSITIVE, &false, sizeof(false)},
-+ {CKA_DERIVE, &true, sizeof(true)}
-+ };
-+
-+ CK_ULONG pub_key_attr_result_count = 1;
-+ CK_ATTRIBUTE pub_key_result[] =
-+ {
-+ {CKA_VALUE, (void *)NULL, 0}
-+ };
-+
-+ CK_ULONG priv_key_attr_result_count = 1;
-+ CK_ATTRIBUTE priv_key_result[] =
-+ {
-+ {CKA_VALUE, (void *)NULL, 0}
-+ };
-+
-+ pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
-+ if (pub_key_template[1].ulValueLen > 0)
-+ {
-+ pub_key_template[1].pValue =
-+ OPENSSL_malloc(pub_key_template[1].ulValueLen);
-+ if (pub_key_template[1].pValue == NULL)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
-+ }
-+ else
-+ goto err;
-+
-+ pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
-+ if (pub_key_template[2].ulValueLen > 0)
-+ {
-+ pub_key_template[2].pValue =
-+ OPENSSL_malloc(pub_key_template[2].ulValueLen);
-+ if (pub_key_template[2].pValue == NULL)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
-+ }
-+ else
-+ goto err;
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ goto err;
-+
-+ rv = pFuncList->C_GenerateKeyPair(sp->session,
-+ &mechanism,
-+ pub_key_template,
-+ ul_pub_key_attr_count,
-+ priv_key_template,
-+ ul_priv_key_attr_count,
-+ &h_pub_key,
-+ &h_priv_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ /* Reuse the larger memory allocated. We know the larger memory
-+ * is sufficient for reuse */
-+ if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
-+ reuse_mem = pub_key_template[1].pValue;
-+ else
-+ reuse_mem = pub_key_template[2].pValue;
-+
-+ rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-+ pub_key_result, pub_key_attr_result_count);
-+ rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-+ priv_key_result, priv_key_attr_result_count);
-+
-+ if (rv != CKR_OK || rv1 != CKR_OK)
-+ {
-+ rv = (rv != CKR_OK) ? rv : rv1;
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
-+ ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-+ goto err;
-+ }
-+
-+ /* Reuse the memory allocated */
-+ pub_key_result[0].pValue = reuse_mem;
-+
-+ rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-+ pub_key_result, pub_key_attr_result_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (pub_key_result[0].type == CKA_VALUE)
-+ {
-+ if (dh->pub_key == NULL)
-+ dh->pub_key = BN_new();
-+ dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
-+ pub_key_result[0].ulValueLen, dh->pub_key);
-+ }
-+
-+ /* Reuse the memory allocated */
-+ priv_key_result[0].pValue = reuse_mem;
-+
-+ rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-+ priv_key_result, priv_key_attr_result_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (priv_key_result[0].type == CKA_VALUE)
-+ {
-+ if (dh->priv_key == NULL)
-+ dh->priv_key = BN_new();
-+ dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
-+ priv_key_result[0].ulValueLen, dh->priv_key);
-+ }
-+
-+ ret = 1;
-+
-+err:
-+
-+ if (h_pub_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_DESTROYOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ }
-+ }
-+
-+ if (h_priv_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_GEN_KEY, PK11_R_DESTROYOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ }
-+ }
-+
-+ for (i = 1; i <= 2; i++)
-+ {
-+ if (pub_key_template[i].pValue != NULL)
-+ {
-+ OPENSSL_free(pub_key_template[i].pValue);
-+ pub_key_template[i].pValue = NULL;
-+ }
-+ }
-+
-+ pk11_return_session(sp);
-+ return ret;
-+ }
-+
-+static int pk11_DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
-+ {
-+ int i;
-+ CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
-+ CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
-+ CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
-+ CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+
-+ CK_ULONG ul_priv_key_attr_count = 2;
-+ CK_ATTRIBUTE priv_key_template[] =
-+ {
-+ {CKA_CLASS, (void*) NULL, sizeof(key_class)},
-+ {CKA_KEY_TYPE, (void*) NULL, sizeof(key_type)},
-+ };
-+
-+ CK_ULONG priv_key_attr_result_count = 1;
-+ CK_ATTRIBUTE priv_key_result[] =
-+ {
-+ {CKA_VALUE, (void *)NULL, 0}
-+ };
-+
-+ CK_RV rv;
-+ int ret = 0;
-+ PK11_SESSION *sp = NULL;
-+ char tmp_buf[20];
-+
-+ priv_key_template[0].pValue = &key_class;
-+ priv_key_template[1].pValue = &key_type;
-+
-+ if ((sp = pk11_get_session()) == NULL)
-+ goto err;
-+
-+ mechanism.ulParameterLen = BN_num_bytes(pub_key);
-+ mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
-+ if (mechanism.pParameter == NULL)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ BN_bn2bin(pub_key, mechanism.pParameter);
-+
-+ check_new_dh_key(sp, dh);
-+
-+ h_key = sp->dh_key;
-+ if (h_key == CK_INVALID_HANDLE)
-+ h_key = sp->dh_key = pk11_get_dh_key((DH*) dh, sp);
-+
-+ if (h_key == CK_INVALID_HANDLE)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_DeriveKey(sp->session,
-+ &mechanism,
-+ h_key,
-+ priv_key_template,
-+ ul_priv_key_attr_count,
-+ &h_derived_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-+ priv_key_result, priv_key_attr_result_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
-+ goto err;
-+ }
-+ priv_key_result[0].pValue =
-+ OPENSSL_malloc(priv_key_result[0].ulValueLen);
-+ if (!priv_key_result[0].pValue)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-+ priv_key_result, priv_key_attr_result_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ /* OpenSSL allocates the output buffer 'key' which is the same
-+ * length of the public key. It is long enough for the derived key */
-+ if (priv_key_result[0].type == CKA_VALUE)
-+ {
-+ /* CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
-+ * leading zeros from a computed shared secret. However,
-+ * OpenSSL always did it so we must do the same here. The
-+ * vagueness of the spec regarding leading zero bytes was
-+ * finally cleared with TLS 1.1 (RFC 4346) saying that leading
-+ * zeros are stripped before the computed data is used as the
-+ * pre-master secret.
-+ */
-+ for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
-+ {
-+ if (((char *) priv_key_result[0].pValue)[i] != 0)
-+ break;
-+ }
-+
-+ memcpy(key, ((char *) priv_key_result[0].pValue) + i,
-+ priv_key_result[0].ulValueLen - i);
-+ ret = priv_key_result[0].ulValueLen - i;
-+ }
-+
-+err:
-+
-+ if (h_derived_key != CK_INVALID_HANDLE)
-+ {
-+ rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_DH_COMP_KEY, PK11_R_DESTROYOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ }
-+ }
-+ if (priv_key_result[0].pValue)
-+ {
-+ OPENSSL_free(priv_key_result[0].pValue);
-+ priv_key_result[0].pValue = NULL;
-+ }
-+
-+ if (mechanism.pParameter)
-+ {
-+ OPENSSL_free(mechanism.pParameter);
-+ mechanism.pParameter = NULL;
-+ }
-+
-+ pk11_return_session(sp);
-+ return ret;
-+ }
-+
-+
-+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, PK11_SESSION *sp)
-+ {
-+ CK_RV rv;
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+ CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
-+ CK_KEY_TYPE key_type = CKK_DH;
-+ CK_ULONG found;
-+ int i;
-+ char tmp_buf[20];
-+
-+ CK_ULONG ul_key_attr_count = 7;
-+ CK_ATTRIBUTE key_template[] =
-+ {
-+ {CKA_CLASS, (void*) NULL, sizeof(class)},
-+ {CKA_KEY_TYPE, (void*) NULL, sizeof(key_type)},
-+ {CKA_DERIVE, &true, sizeof(true)},
-+ {CKA_PRIVATE, &false, sizeof(false)},
-+ {CKA_PRIME, (void *) NULL, 0},
-+ {CKA_BASE, (void *) NULL, 0},
-+ {CKA_VALUE, (void *) NULL, 0},
-+ };
-+
-+ CK_SESSION_HANDLE session = sp->session;
-+
-+ key_template[0].pValue = &class;
-+ key_template[1].pValue = &key_type;
-+
-+ key_template[4].ulValueLen = BN_num_bytes(dh->p);
-+ key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-+ (size_t)key_template[4].ulValueLen);
-+ if (key_template[4].pValue == NULL)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ BN_bn2bin(dh->p, key_template[4].pValue);
-+
-+ key_template[5].ulValueLen = BN_num_bytes(dh->g);
-+ key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-+ (size_t)key_template[5].ulValueLen);
-+ if (key_template[5].pValue == NULL)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ BN_bn2bin(dh->g, key_template[5].pValue);
-+
-+ key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
-+ key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-+ (size_t)key_template[6].ulValueLen);
-+ if (key_template[6].pValue == NULL)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ BN_bn2bin(dh->priv_key, key_template[6].pValue);
-+
-+ rv = pFuncList->C_FindObjectsInit(session, key_template,
-+ ul_key_attr_count);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ rv = pFuncList->C_FindObjectsFinal(session);
-+
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+
-+ if (found == 0)
-+ {
-+ rv = pFuncList->C_CreateObject(session,
-+ key_template, ul_key_attr_count, &h_key);
-+ if (rv != CKR_OK)
-+ {
-+ PK11err(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT);
-+ snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-+ goto err;
-+ }
-+ }
-+
-+ sp->dh = dh;
-+
-+ err:
-+ for (i = 4; i <= 6; i++)
-+ {
-+ if (key_template[i].pValue != NULL)
-+ {
-+ OPENSSL_free(key_template[i].pValue);
-+ key_template[i].pValue = NULL;
-+ }
-+ }
-+
-+ return h_key;
-+ }
-+
-+#endif
-+
-+/* Local function to simplify key template population
-+ * Return 0 -- error, 1 -- no error
-+ */
-+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
-+ CK_ULONG *ul_value_len)
-+ {
-+ CK_ULONG len = BN_num_bytes(bn);
-+ if (len == 0)
-+ return 1;
-+
-+ *ul_value_len = len;
-+ *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t) *ul_value_len);
-+ if (*p_value == NULL)
-+ return 0;
-+
-+ BN_bn2bin(bn, *p_value);
-+
-+ return 1;
-+ }
-+
-+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
-+ {
-+ if (attr->ulValueLen > 0)
-+ {
-+ *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
-+ }
-+ }
-+
-+static void check_new_rsa_key(PK11_SESSION *sp, void *rsa)
-+ {
-+ if (sp->rsa != rsa)
-+ pk11_destroy_rsa_key_objects(sp);
-+ }
-+
-+static void check_new_dsa_key(PK11_SESSION *sp, void *dsa)
-+ {
-+ if (sp->dsa != dsa)
-+ pk11_destroy_dsa_key_objects(sp);
-+ }
-+
-+static void check_new_dh_key(PK11_SESSION *sp, void *dh)
-+ {
-+ if (sp->dh != dh)
-+ pk11_destroy_dh_key_objects(sp);
-+ }
-+
-+
-+#endif
-+#endif
-diff -r -u -N openssl-0.9.8g/crypto/engine/Makefile openssl/crypto/engine/Makefile
---- openssl-0.9.8g/crypto/engine/Makefile 2005-07-16 13:13:05.000000000 +0200
-+++ openssl/crypto/engine/Makefile 2007-10-25 01:27:09.000000000 +0200
-@@ -21,12 +21,14 @@
- eng_table.c eng_pkey.c eng_fat.c eng_all.c \
- tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
- tb_cipher.c tb_digest.c \
-- eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
-+ eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
-+ hw_pk11.c hw_pk11_pub.c
- LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
- eng_table.o eng_pkey.o eng_fat.o eng_all.o \
- tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
- tb_cipher.o tb_digest.o \
-- eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
-+ eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
-+ hw_pk11.o hw_pk11_pub.o
-
- SRC= $(LIBSRC)
-
-@@ -212,6 +214,54 @@
- eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
- eng_table.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
- eng_table.o: eng_table.c
-+hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-+hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
-+hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
-+hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-+hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
-+hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
-+hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
-+hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
-+hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
-+hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
-+hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
-+hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-+hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
-+hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
-+hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
-+hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
-+hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
-+hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
-+hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
-+hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
-+hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
-+hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
-+hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
-+hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
-+hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-+hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
-+hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
-+hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-+hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
-+hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
-+hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
-+hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
-+hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
-+hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
-+hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
-+hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-+hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
-+hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
-+hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
-+hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
-+hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
-+hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
-+hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
-+hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
-+hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
-+hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
-+hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
-+hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
- tb_cipher.o: ../../e_os.h ../../include/openssl/bio.h
- tb_cipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
- tb_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-diff -r -u -N openssl-0.9.8g/crypto/engine/pkcs11f.h openssl/crypto/engine/pkcs11f.h
---- openssl-0.9.8g/crypto/engine/pkcs11f.h 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/pkcs11f.h 2007-10-25 01:27:09.000000000 +0200
-@@ -0,0 +1,912 @@
-+/* pkcs11f.h include file for PKCS #11. */
-+/* $Revision: 1.2 $ */
-+
-+/* License to copy and use this software is granted provided that it is
-+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-+ * (Cryptoki)" in all material mentioning or referencing this software.
-+
-+ * License is also granted to make and use derivative works provided that
-+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
-+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
-+ * referencing the derived work.
-+
-+ * RSA Security Inc. makes no representations concerning either the
-+ * merchantability of this software or the suitability of this software for
-+ * any particular purpose. It is provided "as is" without express or implied
-+ * warranty of any kind.
-+ */
-+
-+/* This header file contains pretty much everything about all the */
-+/* Cryptoki function prototypes. Because this information is */
-+/* used for more than just declaring function prototypes, the */
-+/* order of the functions appearing herein is important, and */
-+/* should not be altered. */
-+
-+/* General-purpose */
-+
-+/* C_Initialize initializes the Cryptoki library. */
-+CK_PKCS11_FUNCTION_INFO(C_Initialize)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
-+ * cast to CK_C_INITIALIZE_ARGS_PTR
-+ * and dereferenced */
-+);
-+#endif
-+
-+
-+/* C_Finalize indicates that an application is done with the
-+ * Cryptoki library. */
-+CK_PKCS11_FUNCTION_INFO(C_Finalize)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
-+);
-+#endif
-+
-+
-+/* C_GetInfo returns general information about Cryptoki. */
-+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_INFO_PTR pInfo /* location that receives information */
-+);
-+#endif
-+
-+
-+/* C_GetFunctionList returns the function list. */
-+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
-+ * function list */
-+);
-+#endif
-+
-+
-+
-+/* Slot and token management */
-+
-+/* C_GetSlotList obtains a list of slots in the system. */
-+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_BBOOL tokenPresent, /* only slots with tokens? */
-+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
-+ CK_ULONG_PTR pulCount /* receives number of slots */
-+);
-+#endif
-+
-+
-+/* C_GetSlotInfo obtains information about a particular slot in
-+ * the system. */
-+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SLOT_ID slotID, /* the ID of the slot */
-+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
-+);
-+#endif
-+
-+
-+/* C_GetTokenInfo obtains information about a particular token
-+ * in the system. */
-+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SLOT_ID slotID, /* ID of the token's slot */
-+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
-+);
-+#endif
-+
-+
-+/* C_GetMechanismList obtains a list of mechanism types
-+ * supported by a token. */
-+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SLOT_ID slotID, /* ID of token's slot */
-+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
-+ CK_ULONG_PTR pulCount /* gets # of mechs. */
-+);
-+#endif
-+
-+
-+/* C_GetMechanismInfo obtains information about a particular
-+ * mechanism possibly supported by a token. */
-+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SLOT_ID slotID, /* ID of the token's slot */
-+ CK_MECHANISM_TYPE type, /* type of mechanism */
-+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
-+);
-+#endif
-+
-+
-+/* C_InitToken initializes a token. */
-+CK_PKCS11_FUNCTION_INFO(C_InitToken)
-+#ifdef CK_NEED_ARG_LIST
-+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
-+(
-+ CK_SLOT_ID slotID, /* ID of the token's slot */
-+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
-+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
-+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
-+);
-+#endif
-+
-+
-+/* C_InitPIN initializes the normal user's PIN. */
-+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
-+ CK_ULONG ulPinLen /* length in bytes of the PIN */
-+);
-+#endif
-+
-+
-+/* C_SetPIN modifies the PIN of the user who is logged in. */
-+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
-+ CK_ULONG ulOldLen, /* length of the old PIN */
-+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
-+ CK_ULONG ulNewLen /* length of the new PIN */
-+);
-+#endif
-+
-+
-+
-+/* Session management */
-+
-+/* C_OpenSession opens a session between an application and a
-+ * token. */
-+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SLOT_ID slotID, /* the slot's ID */
-+ CK_FLAGS flags, /* from CK_SESSION_INFO */
-+ CK_VOID_PTR pApplication, /* passed to callback */
-+ CK_NOTIFY Notify, /* callback function */
-+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
-+);
-+#endif
-+
-+
-+/* C_CloseSession closes a session between an application and a
-+ * token. */
-+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
-+
-+
-+/* C_CloseAllSessions closes all sessions with a token. */
-+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SLOT_ID slotID /* the token's slot */
-+);
-+#endif
-+
-+
-+/* C_GetSessionInfo obtains information about the session. */
-+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_SESSION_INFO_PTR pInfo /* receives session info */
-+);
-+#endif
-+
-+
-+/* C_GetOperationState obtains the state of the cryptographic operation
-+ * in a session. */
-+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pOperationState, /* gets state */
-+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
-+);
-+#endif
-+
-+
-+/* C_SetOperationState restores the state of the cryptographic
-+ * operation in a session. */
-+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pOperationState, /* holds state */
-+ CK_ULONG ulOperationStateLen, /* holds state length */
-+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
-+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
-+);
-+#endif
-+
-+
-+/* C_Login logs a user into a token. */
-+CK_PKCS11_FUNCTION_INFO(C_Login)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_USER_TYPE userType, /* the user type */
-+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
-+ CK_ULONG ulPinLen /* the length of the PIN */
-+);
-+#endif
-+
-+
-+/* C_Logout logs a user out from a token. */
-+CK_PKCS11_FUNCTION_INFO(C_Logout)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
-+
-+
-+
-+/* Object management */
-+
-+/* C_CreateObject creates a new object. */
-+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
-+ CK_ULONG ulCount, /* attributes in template */
-+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
-+);
-+#endif
-+
-+
-+/* C_CopyObject copies an object, creating a new object for the
-+ * copy. */
-+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_OBJECT_HANDLE hObject, /* the object's handle */
-+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
-+ CK_ULONG ulCount, /* attributes in template */
-+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
-+);
-+#endif
-+
-+
-+/* C_DestroyObject destroys an object. */
-+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_OBJECT_HANDLE hObject /* the object's handle */
-+);
-+#endif
-+
-+
-+/* C_GetObjectSize gets the size of an object in bytes. */
-+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_OBJECT_HANDLE hObject, /* the object's handle */
-+ CK_ULONG_PTR pulSize /* receives size of object */
-+);
-+#endif
-+
-+
-+/* C_GetAttributeValue obtains the value of one or more object
-+ * attributes. */
-+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_OBJECT_HANDLE hObject, /* the object's handle */
-+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
-+ CK_ULONG ulCount /* attributes in template */
-+);
-+#endif
-+
-+
-+/* C_SetAttributeValue modifies the value of one or more object
-+ * attributes */
-+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_OBJECT_HANDLE hObject, /* the object's handle */
-+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
-+ CK_ULONG ulCount /* attributes in template */
-+);
-+#endif
-+
-+
-+/* C_FindObjectsInit initializes a search for token and session
-+ * objects that match a template. */
-+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
-+ CK_ULONG ulCount /* attrs in search template */
-+);
-+#endif
-+
-+
-+/* C_FindObjects continues a search for token and session
-+ * objects that match a template, obtaining additional object
-+ * handles. */
-+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
-+ CK_ULONG ulMaxObjectCount, /* max handles to get */
-+ CK_ULONG_PTR pulObjectCount /* actual # returned */
-+);
-+#endif
-+
-+
-+/* C_FindObjectsFinal finishes a search for token and session
-+ * objects. */
-+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
-+
-+
-+
-+/* Encryption and decryption */
-+
-+/* C_EncryptInit initializes an encryption operation. */
-+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
-+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
-+);
-+#endif
-+
-+
-+/* C_Encrypt encrypts single-part data. */
-+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pData, /* the plaintext data */
-+ CK_ULONG ulDataLen, /* bytes of plaintext */
-+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
-+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
-+);
-+#endif
-+
-+
-+/* C_EncryptUpdate continues a multiple-part encryption
-+ * operation. */
-+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pPart, /* the plaintext data */
-+ CK_ULONG ulPartLen, /* plaintext data len */
-+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
-+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
-+);
-+#endif
-+
-+
-+/* C_EncryptFinal finishes a multiple-part encryption
-+ * operation. */
-+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session handle */
-+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
-+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
-+);
-+#endif
-+
-+
-+/* C_DecryptInit initializes a decryption operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
-+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
-+);
-+#endif
-+
-+
-+/* C_Decrypt decrypts encrypted data in a single part. */
-+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
-+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
-+ CK_BYTE_PTR pData, /* gets plaintext */
-+ CK_ULONG_PTR pulDataLen /* gets p-text size */
-+);
-+#endif
-+
-+
-+/* C_DecryptUpdate continues a multiple-part decryption
-+ * operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
-+ CK_ULONG ulEncryptedPartLen, /* input length */
-+ CK_BYTE_PTR pPart, /* gets plaintext */
-+ CK_ULONG_PTR pulPartLen /* p-text size */
-+);
-+#endif
-+
-+
-+/* C_DecryptFinal finishes a multiple-part decryption
-+ * operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pLastPart, /* gets plaintext */
-+ CK_ULONG_PTR pulLastPartLen /* p-text size */
-+);
-+#endif
-+
-+
-+
-+/* Message digesting */
-+
-+/* C_DigestInit initializes a message-digesting operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
-+);
-+#endif
-+
-+
-+/* C_Digest digests data in a single part. */
-+CK_PKCS11_FUNCTION_INFO(C_Digest)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pData, /* data to be digested */
-+ CK_ULONG ulDataLen, /* bytes of data to digest */
-+ CK_BYTE_PTR pDigest, /* gets the message digest */
-+ CK_ULONG_PTR pulDigestLen /* gets digest length */
-+);
-+#endif
-+
-+
-+/* C_DigestUpdate continues a multiple-part message-digesting
-+ * operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pPart, /* data to be digested */
-+ CK_ULONG ulPartLen /* bytes of data to be digested */
-+);
-+#endif
-+
-+
-+/* C_DigestKey continues a multi-part message-digesting
-+ * operation, by digesting the value of a secret key as part of
-+ * the data already digested. */
-+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_OBJECT_HANDLE hKey /* secret key to digest */
-+);
-+#endif
-+
-+
-+/* C_DigestFinal finishes a multiple-part message-digesting
-+ * operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pDigest, /* gets the message digest */
-+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
-+);
-+#endif
-+
-+
-+
-+/* Signing and MACing */
-+
-+/* C_SignInit initializes a signature (private key encryption)
-+ * operation, where the signature is (will be) an appendix to
-+ * the data, and plaintext cannot be recovered from the
-+ *signature. */
-+CK_PKCS11_FUNCTION_INFO(C_SignInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
-+ CK_OBJECT_HANDLE hKey /* handle of signature key */
-+);
-+#endif
-+
-+
-+/* C_Sign signs (encrypts with private key) data in a single
-+ * part, where the signature is (will be) an appendix to the
-+ * data, and plaintext cannot be recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_Sign)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pData, /* the data to sign */
-+ CK_ULONG ulDataLen, /* count of bytes to sign */
-+ CK_BYTE_PTR pSignature, /* gets the signature */
-+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
-+);
-+#endif
-+
-+
-+/* C_SignUpdate continues a multiple-part signature operation,
-+ * where the signature is (will be) an appendix to the data,
-+ * and plaintext cannot be recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pPart, /* the data to sign */
-+ CK_ULONG ulPartLen /* count of bytes to sign */
-+);
-+#endif
-+
-+
-+/* C_SignFinal finishes a multiple-part signature operation,
-+ * returning the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pSignature, /* gets the signature */
-+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
-+);
-+#endif
-+
-+
-+/* C_SignRecoverInit initializes a signature operation, where
-+ * the data can be recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
-+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
-+);
-+#endif
-+
-+
-+/* C_SignRecover signs data in a single operation, where the
-+ * data can be recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pData, /* the data to sign */
-+ CK_ULONG ulDataLen, /* count of bytes to sign */
-+ CK_BYTE_PTR pSignature, /* gets the signature */
-+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
-+);
-+#endif
-+
-+
-+
-+/* Verifying signatures and MACs */
-+
-+/* C_VerifyInit initializes a verification operation, where the
-+ * signature is an appendix to the data, and plaintext cannot
-+ * cannot be recovered from the signature (e.g. DSA). */
-+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
-+ CK_OBJECT_HANDLE hKey /* verification key */
-+);
-+#endif
-+
-+
-+/* C_Verify verifies a signature in a single-part operation,
-+ * where the signature is an appendix to the data, and plaintext
-+ * cannot be recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_Verify)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pData, /* signed data */
-+ CK_ULONG ulDataLen, /* length of signed data */
-+ CK_BYTE_PTR pSignature, /* signature */
-+ CK_ULONG ulSignatureLen /* signature length*/
-+);
-+#endif
-+
-+
-+/* C_VerifyUpdate continues a multiple-part verification
-+ * operation, where the signature is an appendix to the data,
-+ * and plaintext cannot be recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pPart, /* signed data */
-+ CK_ULONG ulPartLen /* length of signed data */
-+);
-+#endif
-+
-+
-+/* C_VerifyFinal finishes a multiple-part verification
-+ * operation, checking the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pSignature, /* signature to verify */
-+ CK_ULONG ulSignatureLen /* signature length */
-+);
-+#endif
-+
-+
-+/* C_VerifyRecoverInit initializes a signature verification
-+ * operation, where the data is recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
-+ CK_OBJECT_HANDLE hKey /* verification key */
-+);
-+#endif
-+
-+
-+/* C_VerifyRecover verifies a signature in a single-part
-+ * operation, where the data is recovered from the signature. */
-+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pSignature, /* signature to verify */
-+ CK_ULONG ulSignatureLen, /* signature length */
-+ CK_BYTE_PTR pData, /* gets signed data */
-+ CK_ULONG_PTR pulDataLen /* gets signed data len */
-+);
-+#endif
-+
-+
-+
-+/* Dual-function cryptographic operations */
-+
-+/* C_DigestEncryptUpdate continues a multiple-part digesting
-+ * and encryption operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pPart, /* the plaintext data */
-+ CK_ULONG ulPartLen, /* plaintext length */
-+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
-+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-+);
-+#endif
-+
-+
-+/* C_DecryptDigestUpdate continues a multiple-part decryption and
-+ * digesting operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
-+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
-+ CK_BYTE_PTR pPart, /* gets plaintext */
-+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
-+);
-+#endif
-+
-+
-+/* C_SignEncryptUpdate continues a multiple-part signing and
-+ * encryption operation. */
-+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pPart, /* the plaintext data */
-+ CK_ULONG ulPartLen, /* plaintext length */
-+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
-+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-+);
-+#endif
-+
-+
-+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
-+ * verify operation. */
-+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
-+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
-+ CK_BYTE_PTR pPart, /* gets plaintext */
-+ CK_ULONG_PTR pulPartLen /* gets p-text length */
-+);
-+#endif
-+
-+
-+
-+/* Key management */
-+
-+/* C_GenerateKey generates a secret key, creating a new key
-+ * object. */
-+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
-+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
-+ CK_ULONG ulCount, /* # of attrs in template */
-+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
-+);
-+#endif
-+
-+
-+/* C_GenerateKeyPair generates a public-key/private-key pair,
-+ * creating new key objects. */
-+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session
-+ * handle */
-+ CK_MECHANISM_PTR pMechanism, /* key-gen
-+ * mech. */
-+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
-+ * for pub.
-+ * key */
-+ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
-+ * attrs. */
-+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
-+ * for priv.
-+ * key */
-+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
-+ * attrs. */
-+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
-+ * key
-+ * handle */
-+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
-+ * priv. key
-+ * handle */
-+);
-+#endif
-+
-+
-+/* C_WrapKey wraps (i.e., encrypts) a key. */
-+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
-+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
-+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
-+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
-+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
-+);
-+#endif
-+
-+
-+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
-+ * key object. */
-+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
-+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
-+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
-+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
-+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
-+ CK_ULONG ulAttributeCount, /* template length */
-+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-+);
-+#endif
-+
-+
-+/* C_DeriveKey derives a key from a base key, creating a new key
-+ * object. */
-+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
-+ CK_OBJECT_HANDLE hBaseKey, /* base key */
-+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
-+ CK_ULONG ulAttributeCount, /* template length */
-+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-+);
-+#endif
-+
-+
-+
-+/* Random number generation */
-+
-+/* C_SeedRandom mixes additional seed material into the token's
-+ * random number generator. */
-+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pSeed, /* the seed material */
-+ CK_ULONG ulSeedLen /* length of seed material */
-+);
-+#endif
-+
-+
-+/* C_GenerateRandom generates random data. */
-+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR RandomData, /* receives the random data */
-+ CK_ULONG ulRandomLen /* # of bytes to generate */
-+);
-+#endif
-+
-+
-+
-+/* Parallel function management */
-+
-+/* C_GetFunctionStatus is a legacy function; it obtains an
-+ * updated status of a function running in parallel with an
-+ * application. */
-+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
-+
-+
-+/* C_CancelFunction is a legacy function; it cancels a function
-+ * running in parallel. */
-+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
-+
-+
-+
-+/* Functions added in for Cryptoki Version 2.01 or later */
-+
-+/* C_WaitForSlotEvent waits for a slot event (token insertion,
-+ * removal, etc.) to occur. */
-+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_FLAGS flags, /* blocking/nonblocking flag */
-+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
-+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
-+);
-+#endif
-diff -r -u -N openssl-0.9.8g/crypto/engine/pkcs11.h openssl/crypto/engine/pkcs11.h
---- openssl-0.9.8g/crypto/engine/pkcs11.h 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/pkcs11.h 2007-10-25 01:27:09.000000000 +0200
-@@ -0,0 +1,299 @@
-+/* pkcs11.h include file for PKCS #11. */
-+/* $Revision: 1.2 $ */
-+
-+/* License to copy and use this software is granted provided that it is
-+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-+ * (Cryptoki)" in all material mentioning or referencing this software.
-+
-+ * License is also granted to make and use derivative works provided that
-+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
-+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
-+ * referencing the derived work.
-+
-+ * RSA Security Inc. makes no representations concerning either the
-+ * merchantability of this software or the suitability of this software for
-+ * any particular purpose. It is provided "as is" without express or implied
-+ * warranty of any kind.
-+ */
-+
-+#ifndef _PKCS11_H_
-+#define _PKCS11_H_ 1
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* Before including this file (pkcs11.h) (or pkcs11t.h by
-+ * itself), 6 platform-specific macros must be defined. These
-+ * macros are described below, and typical definitions for them
-+ * are also given. Be advised that these definitions can depend
-+ * on both the platform and the compiler used (and possibly also
-+ * on whether a Cryptoki library is linked statically or
-+ * dynamically).
-+ *
-+ * In addition to defining these 6 macros, the packing convention
-+ * for Cryptoki structures should be set. The Cryptoki
-+ * convention on packing is that structures should be 1-byte
-+ * aligned.
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to produce
-+ * Win32 stuff, this might be done by using the following
-+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
-+ *
-+ * #pragma pack(push, cryptoki, 1)
-+ *
-+ * and using the following preprocessor directive after including
-+ * pkcs11.h or pkcs11t.h:
-+ *
-+ * #pragma pack(pop, cryptoki)
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to produce Win16 stuff, this might be done by using
-+ * the following preprocessor directive before including
-+ * pkcs11.h or pkcs11t.h:
-+ *
-+ * #pragma pack(1)
-+ *
-+ * In a UNIX environment, you're on your own for this. You might
-+ * not need to do (or be able to do!) anything.
-+ *
-+ *
-+ * Now for the macros:
-+ *
-+ *
-+ * 1. CK_PTR: The indirection string for making a pointer to an
-+ * object. It can be used like this:
-+ *
-+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to produce
-+ * Win32 stuff, it might be defined by:
-+ *
-+ * #define CK_PTR *
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to produce Win16 stuff, it might be defined by:
-+ *
-+ * #define CK_PTR far *
-+ *
-+ * In a typical UNIX environment, it might be defined by:
-+ *
-+ * #define CK_PTR *
-+ *
-+ *
-+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
-+ * an exportable Cryptoki library function definition out of a
-+ * return type and a function name. It should be used in the
-+ * following fashion to define the exposed Cryptoki functions in
-+ * a Cryptoki library:
-+ *
-+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
-+ * CK_VOID_PTR pReserved
-+ * )
-+ * {
-+ * ...
-+ * }
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to define a
-+ * function in a Win32 Cryptoki .dll, it might be defined by:
-+ *
-+ * #define CK_DEFINE_FUNCTION(returnType, name) \
-+ * returnType __declspec(dllexport) name
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to define a function in a Win16 Cryptoki .dll, it
-+ * might be defined by:
-+ *
-+ * #define CK_DEFINE_FUNCTION(returnType, name) \
-+ * returnType __export _far _pascal name
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_DEFINE_FUNCTION(returnType, name) \
-+ * returnType name
-+ *
-+ *
-+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
-+ * an importable Cryptoki library function declaration out of a
-+ * return type and a function name. It should be used in the
-+ * following fashion:
-+ *
-+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
-+ * CK_VOID_PTR pReserved
-+ * );
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to declare a
-+ * function in a Win32 Cryptoki .dll, it might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION(returnType, name) \
-+ * returnType __declspec(dllimport) name
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to declare a function in a Win16 Cryptoki .dll, it
-+ * might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION(returnType, name) \
-+ * returnType __export _far _pascal name
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION(returnType, name) \
-+ * returnType name
-+ *
-+ *
-+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
-+ * which makes a Cryptoki API function pointer declaration or
-+ * function pointer type declaration out of a return type and a
-+ * function name. It should be used in the following fashion:
-+ *
-+ * // Define funcPtr to be a pointer to a Cryptoki API function
-+ * // taking arguments args and returning CK_RV.
-+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
-+ *
-+ * or
-+ *
-+ * // Define funcPtrType to be the type of a pointer to a
-+ * // Cryptoki API function taking arguments args and returning
-+ * // CK_RV, and then define funcPtr to be a variable of type
-+ * // funcPtrType.
-+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
-+ * funcPtrType funcPtr;
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to access
-+ * functions in a Win32 Cryptoki .dll, in might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ * returnType __declspec(dllimport) (* name)
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to access functions in a Win16 Cryptoki .dll, it might
-+ * be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ * returnType __export _far _pascal (* name)
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ * returnType (* name)
-+ *
-+ *
-+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
-+ * a function pointer type for an application callback out of
-+ * a return type for the callback and a name for the callback.
-+ * It should be used in the following fashion:
-+ *
-+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
-+ *
-+ * to declare a function pointer, myCallback, to a callback
-+ * which takes arguments args and returns a CK_RV. It can also
-+ * be used like this:
-+ *
-+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
-+ * myCallbackType myCallback;
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to do Win32
-+ * Cryptoki development, it might be defined by:
-+ *
-+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
-+ * returnType (* name)
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to do Win16 development, it might be defined by:
-+ *
-+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
-+ * returnType _far _pascal (* name)
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
-+ * returnType (* name)
-+ *
-+ *
-+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
-+ *
-+ * In any ANSI/ISO C environment (and in many others as well),
-+ * this should best be defined by
-+ *
-+ * #ifndef NULL_PTR
-+ * #define NULL_PTR 0
-+ * #endif
-+ */
-+
-+
-+/* All the various Cryptoki types and #define'd values are in the
-+ * file pkcs11t.h. */
-+#include "pkcs11t.h"
-+
-+#define __PASTE(x,y) x##y
-+
-+
-+/* ==============================================================
-+ * Define the "extern" form of all the entry points.
-+ * ==============================================================
-+ */
-+
-+#define CK_NEED_ARG_LIST 1
-+#define CK_PKCS11_FUNCTION_INFO(name) \
-+ extern CK_DECLARE_FUNCTION(CK_RV, name)
-+
-+/* pkcs11f.h has all the information about the Cryptoki
-+ * function prototypes. */
-+#include "pkcs11f.h"
-+
-+#undef CK_NEED_ARG_LIST
-+#undef CK_PKCS11_FUNCTION_INFO
-+
-+
-+/* ==============================================================
-+ * Define the typedef form of all the entry points. That is, for
-+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
-+ * a pointer to that kind of function.
-+ * ==============================================================
-+ */
-+
-+#define CK_NEED_ARG_LIST 1
-+#define CK_PKCS11_FUNCTION_INFO(name) \
-+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-+
-+/* pkcs11f.h has all the information about the Cryptoki
-+ * function prototypes. */
-+#include "pkcs11f.h"
-+
-+#undef CK_NEED_ARG_LIST
-+#undef CK_PKCS11_FUNCTION_INFO
-+
-+
-+/* ==============================================================
-+ * Define structed vector of entry points. A CK_FUNCTION_LIST
-+ * contains a CK_VERSION indicating a library's Cryptoki version
-+ * and then a whole slew of function pointers to the routines in
-+ * the library. This type was declared, but not defined, in
-+ * pkcs11t.h.
-+ * ==============================================================
-+ */
-+
-+#define CK_PKCS11_FUNCTION_INFO(name) \
-+ __PASTE(CK_,name) name;
-+
-+struct CK_FUNCTION_LIST {
-+
-+ CK_VERSION version; /* Cryptoki version */
-+
-+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-+/* pkcs11f.h has all the information about the Cryptoki
-+ * function prototypes. */
-+#include "pkcs11f.h"
-+
-+};
-+
-+#undef CK_PKCS11_FUNCTION_INFO
-+
-+
-+#undef __PASTE
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-diff -r -u -N openssl-0.9.8g/crypto/engine/pkcs11t.h openssl/crypto/engine/pkcs11t.h
---- openssl-0.9.8g/crypto/engine/pkcs11t.h 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/crypto/engine/pkcs11t.h 2007-10-25 01:27:09.000000000 +0200
-@@ -0,0 +1,1685 @@
-+/* pkcs11t.h include file for PKCS #11. */
-+/* $Revision: 1.2 $ */
-+
-+/* License to copy and use this software is granted provided that it is
-+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-+ * (Cryptoki)" in all material mentioning or referencing this software.
-+
-+ * License is also granted to make and use derivative works provided that
-+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
-+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
-+ * referencing the derived work.
-+
-+ * RSA Security Inc. makes no representations concerning either the
-+ * merchantability of this software or the suitability of this software for
-+ * any particular purpose. It is provided "as is" without express or implied
-+ * warranty of any kind.
-+ */
-+
-+/* See top of pkcs11.h for information about the macros that
-+ * must be defined and the structure-packing conventions that
-+ * must be set before including this file. */
-+
-+#ifndef _PKCS11T_H_
-+#define _PKCS11T_H_ 1
-+
-+#define CK_TRUE 1
-+#define CK_FALSE 0
-+
-+#ifndef CK_DISABLE_TRUE_FALSE
-+#ifndef FALSE
-+#define FALSE CK_FALSE
-+#endif
-+
-+#ifndef TRUE
-+#define TRUE CK_TRUE
-+#endif
-+#endif
-+
-+/* an unsigned 8-bit value */
-+typedef unsigned char CK_BYTE;
-+
-+/* an unsigned 8-bit character */
-+typedef CK_BYTE CK_CHAR;
-+
-+/* an 8-bit UTF-8 character */
-+typedef CK_BYTE CK_UTF8CHAR;
-+
-+/* a BYTE-sized Boolean flag */
-+typedef CK_BYTE CK_BBOOL;
-+
-+/* an unsigned value, at least 32 bits long */
-+typedef unsigned long int CK_ULONG;
-+
-+/* a signed value, the same size as a CK_ULONG */
-+/* CK_LONG is new for v2.0 */
-+typedef long int CK_LONG;
-+
-+/* at least 32 bits; each bit is a Boolean flag */
-+typedef CK_ULONG CK_FLAGS;
-+
-+
-+/* some special values for certain CK_ULONG variables */
-+#define CK_UNAVAILABLE_INFORMATION (~0UL)
-+#define CK_EFFECTIVELY_INFINITE 0
-+
-+
-+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
-+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
-+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
-+typedef void CK_PTR CK_VOID_PTR;
-+
-+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-+
-+
-+/* The following value is always invalid if used as a session */
-+/* handle or object handle */
-+#define CK_INVALID_HANDLE 0
-+
-+
-+typedef struct CK_VERSION {
-+ CK_BYTE major; /* integer portion of version number */
-+ CK_BYTE minor; /* 1/100ths portion of version number */
-+} CK_VERSION;
-+
-+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-+
-+
-+typedef struct CK_INFO {
-+ /* manufacturerID and libraryDecription have been changed from
-+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
-+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
-+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
-+ CK_FLAGS flags; /* must be zero */
-+
-+ /* libraryDescription and libraryVersion are new for v2.0 */
-+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
-+ CK_VERSION libraryVersion; /* version of library */
-+} CK_INFO;
-+
-+typedef CK_INFO CK_PTR CK_INFO_PTR;
-+
-+
-+/* CK_NOTIFICATION enumerates the types of notifications that
-+ * Cryptoki provides to an application */
-+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
-+ * for v2.0 */
-+typedef CK_ULONG CK_NOTIFICATION;
-+#define CKN_SURRENDER 0
-+
-+
-+typedef CK_ULONG CK_SLOT_ID;
-+
-+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-+
-+
-+/* CK_SLOT_INFO provides information about a slot */
-+typedef struct CK_SLOT_INFO {
-+ /* slotDescription and manufacturerID have been changed from
-+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
-+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
-+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
-+ CK_FLAGS flags;
-+
-+ /* hardwareVersion and firmwareVersion are new for v2.0 */
-+ CK_VERSION hardwareVersion; /* version of hardware */
-+ CK_VERSION firmwareVersion; /* version of firmware */
-+} CK_SLOT_INFO;
-+
-+/* flags: bit flags that provide capabilities of the slot
-+ * Bit Flag Mask Meaning
-+ */
-+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
-+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
-+#define CKF_HW_SLOT 0x00000004 /* hardware slot */
-+
-+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-+
-+
-+/* CK_TOKEN_INFO provides information about a token */
-+typedef struct CK_TOKEN_INFO {
-+ /* label, manufacturerID, and model have been changed from
-+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
-+ CK_UTF8CHAR label[32]; /* blank padded */
-+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
-+ CK_UTF8CHAR model[16]; /* blank padded */
-+ CK_CHAR serialNumber[16]; /* blank padded */
-+ CK_FLAGS flags; /* see below */
-+
-+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
-+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
-+ * changed from CK_USHORT to CK_ULONG for v2.0 */
-+ CK_ULONG ulMaxSessionCount; /* max open sessions */
-+ CK_ULONG ulSessionCount; /* sess. now open */
-+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
-+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
-+ CK_ULONG ulMaxPinLen; /* in bytes */
-+ CK_ULONG ulMinPinLen; /* in bytes */
-+ CK_ULONG ulTotalPublicMemory; /* in bytes */
-+ CK_ULONG ulFreePublicMemory; /* in bytes */
-+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
-+ CK_ULONG ulFreePrivateMemory; /* in bytes */
-+
-+ /* hardwareVersion, firmwareVersion, and time are new for
-+ * v2.0 */
-+ CK_VERSION hardwareVersion; /* version of hardware */
-+ CK_VERSION firmwareVersion; /* version of firmware */
-+ CK_CHAR utcTime[16]; /* time */
-+} CK_TOKEN_INFO;
-+
-+/* The flags parameter is defined as follows:
-+ * Bit Flag Mask Meaning
-+ */
-+#define CKF_RNG 0x00000001 /* has random #
-+ * generator */
-+#define CKF_WRITE_PROTECTED 0x00000002 /* token is
-+ * write-
-+ * protected */
-+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
-+ * login */
-+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
-+ * PIN is set */
-+
-+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
-+ * that means that *every* time the state of cryptographic
-+ * operations of a session is successfully saved, all keys
-+ * needed to continue those operations are stored in the state */
-+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
-+
-+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
-+ * that the token has some sort of clock. The time on that
-+ * clock is returned in the token info structure */
-+#define CKF_CLOCK_ON_TOKEN 0x00000040
-+
-+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
-+ * set, that means that there is some way for the user to login
-+ * without sending a PIN through the Cryptoki library itself */
-+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-+
-+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
-+ * that means that a single session with the token can perform
-+ * dual simultaneous cryptographic operations (digest and
-+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
-+ * and sign) */
-+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
-+
-+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
-+ * token has been initialized using C_InitializeToken or an
-+ * equivalent mechanism outside the scope of PKCS #11.
-+ * Calling C_InitializeToken when this flag is set will cause
-+ * the token to be reinitialized. */
-+#define CKF_TOKEN_INITIALIZED 0x00000400
-+
-+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
-+ * true, the token supports secondary authentication for
-+ * private key objects. This flag is deprecated in v2.11 and
-+ onwards. */
-+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
-+
-+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
-+ * incorrect user login PIN has been entered at least once
-+ * since the last successful authentication. */
-+#define CKF_USER_PIN_COUNT_LOW 0x00010000
-+
-+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
-+ * supplying an incorrect user PIN will it to become locked. */
-+#define CKF_USER_PIN_FINAL_TRY 0x00020000
-+
-+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
-+ * user PIN has been locked. User login to the token is not
-+ * possible. */
-+#define CKF_USER_PIN_LOCKED 0x00040000
-+
-+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
-+ * the user PIN value is the default value set by token
-+ * initialization or manufacturing, or the PIN has been
-+ * expired by the card. */
-+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
-+
-+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
-+ * incorrect SO login PIN has been entered at least once since
-+ * the last successful authentication. */
-+#define CKF_SO_PIN_COUNT_LOW 0x00100000
-+
-+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
-+ * supplying an incorrect SO PIN will it to become locked. */
-+#define CKF_SO_PIN_FINAL_TRY 0x00200000
-+
-+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
-+ * PIN has been locked. SO login to the token is not possible.
-+ */
-+#define CKF_SO_PIN_LOCKED 0x00400000
-+
-+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
-+ * the SO PIN value is the default value set by token
-+ * initialization or manufacturing, or the PIN has been
-+ * expired by the card. */
-+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
-+
-+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-+
-+
-+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
-+ * identifies a session */
-+typedef CK_ULONG CK_SESSION_HANDLE;
-+
-+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-+
-+
-+/* CK_USER_TYPE enumerates the types of Cryptoki users */
-+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
-+ * v2.0 */
-+typedef CK_ULONG CK_USER_TYPE;
-+/* Security Officer */
-+#define CKU_SO 0
-+/* Normal user */
-+#define CKU_USER 1
-+/* Context specific (added in v2.20) */
-+#define CKU_CONTEXT_SPECIFIC 2
-+
-+/* CK_STATE enumerates the session states */
-+/* CK_STATE has been changed from an enum to a CK_ULONG for
-+ * v2.0 */
-+typedef CK_ULONG CK_STATE;
-+#define CKS_RO_PUBLIC_SESSION 0
-+#define CKS_RO_USER_FUNCTIONS 1
-+#define CKS_RW_PUBLIC_SESSION 2
-+#define CKS_RW_USER_FUNCTIONS 3
-+#define CKS_RW_SO_FUNCTIONS 4
-+
-+
-+/* CK_SESSION_INFO provides information about a session */
-+typedef struct CK_SESSION_INFO {
-+ CK_SLOT_ID slotID;
-+ CK_STATE state;
-+ CK_FLAGS flags; /* see below */
-+
-+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+ CK_ULONG ulDeviceError; /* device-dependent error code */
-+} CK_SESSION_INFO;
-+
-+/* The flags are defined in the following table:
-+ * Bit Flag Mask Meaning
-+ */
-+#define CKF_RW_SESSION 0x00000002 /* session is r/w */
-+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
-+
-+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-+
-+
-+/* CK_OBJECT_HANDLE is a token-specific identifier for an
-+ * object */
-+typedef CK_ULONG CK_OBJECT_HANDLE;
-+
-+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-+
-+
-+/* CK_OBJECT_CLASS is a value that identifies the classes (or
-+ * types) of objects that Cryptoki recognizes. It is defined
-+ * as follows: */
-+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+typedef CK_ULONG CK_OBJECT_CLASS;
-+
-+/* The following classes of objects are defined: */
-+/* CKO_HW_FEATURE is new for v2.10 */
-+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-+/* CKO_MECHANISM is new for v2.20 */
-+#define CKO_DATA 0x00000000
-+#define CKO_CERTIFICATE 0x00000001
-+#define CKO_PUBLIC_KEY 0x00000002
-+#define CKO_PRIVATE_KEY 0x00000003
-+#define CKO_SECRET_KEY 0x00000004
-+#define CKO_HW_FEATURE 0x00000005
-+#define CKO_DOMAIN_PARAMETERS 0x00000006
-+#define CKO_MECHANISM 0x00000007
-+#define CKO_VENDOR_DEFINED 0x80000000
-+
-+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-+
-+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
-+ * value that identifies the hardware feature type of an object
-+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
-+typedef CK_ULONG CK_HW_FEATURE_TYPE;
-+
-+/* The following hardware feature types are defined */
-+/* CKH_USER_INTERFACE is new for v2.20 */
-+#define CKH_MONOTONIC_COUNTER 0x00000001
-+#define CKH_CLOCK 0x00000002
-+#define CKH_USER_INTERFACE 0x00000003
-+#define CKH_VENDOR_DEFINED 0x80000000
-+
-+/* CK_KEY_TYPE is a value that identifies a key type */
-+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-+typedef CK_ULONG CK_KEY_TYPE;
-+
-+/* the following key types are defined: */
-+#define CKK_RSA 0x00000000
-+#define CKK_DSA 0x00000001
-+#define CKK_DH 0x00000002
-+
-+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-+#define CKK_ECDSA 0x00000003
-+#define CKK_EC 0x00000003
-+#define CKK_X9_42_DH 0x00000004
-+#define CKK_KEA 0x00000005
-+
-+#define CKK_GENERIC_SECRET 0x00000010
-+#define CKK_RC2 0x00000011
-+#define CKK_RC4 0x00000012
-+#define CKK_DES 0x00000013
-+#define CKK_DES2 0x00000014
-+#define CKK_DES3 0x00000015
-+
-+/* all these key types are new for v2.0 */
-+#define CKK_CAST 0x00000016
-+#define CKK_CAST3 0x00000017
-+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-+#define CKK_CAST5 0x00000018
-+#define CKK_CAST128 0x00000018
-+#define CKK_RC5 0x00000019
-+#define CKK_IDEA 0x0000001A
-+#define CKK_SKIPJACK 0x0000001B
-+#define CKK_BATON 0x0000001C
-+#define CKK_JUNIPER 0x0000001D
-+#define CKK_CDMF 0x0000001E
-+#define CKK_AES 0x0000001F
-+
-+/* BlowFish and TwoFish are new for v2.20 */
-+#define CKK_BLOWFISH 0x00000020
-+#define CKK_TWOFISH 0x00000021
-+
-+#define CKK_VENDOR_DEFINED 0x80000000
-+
-+
-+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
-+ * type */
-+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
-+ * for v2.0 */
-+typedef CK_ULONG CK_CERTIFICATE_TYPE;
-+
-+/* The following certificate types are defined: */
-+/* CKC_X_509_ATTR_CERT is new for v2.10 */
-+/* CKC_WTLS is new for v2.20 */
-+#define CKC_X_509 0x00000000
-+#define CKC_X_509_ATTR_CERT 0x00000001
-+#define CKC_WTLS 0x00000002
-+#define CKC_VENDOR_DEFINED 0x80000000
-+
-+
-+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
-+ * type */
-+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
-+
-+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
-+ consists of an array of values. */
-+#define CKF_ARRAY_ATTRIBUTE 0x40000000
-+
-+/* The following attribute types are defined: */
-+#define CKA_CLASS 0x00000000
-+#define CKA_TOKEN 0x00000001
-+#define CKA_PRIVATE 0x00000002
-+#define CKA_LABEL 0x00000003
-+#define CKA_APPLICATION 0x00000010
-+#define CKA_VALUE 0x00000011
-+
-+/* CKA_OBJECT_ID is new for v2.10 */
-+#define CKA_OBJECT_ID 0x00000012
-+
-+#define CKA_CERTIFICATE_TYPE 0x00000080
-+#define CKA_ISSUER 0x00000081
-+#define CKA_SERIAL_NUMBER 0x00000082
-+
-+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
-+ * for v2.10 */
-+#define CKA_AC_ISSUER 0x00000083
-+#define CKA_OWNER 0x00000084
-+#define CKA_ATTR_TYPES 0x00000085
-+
-+/* CKA_TRUSTED is new for v2.11 */
-+#define CKA_TRUSTED 0x00000086
-+
-+/* CKA_CERTIFICATE_CATEGORY ...
-+ * CKA_CHECK_VALUE are new for v2.20 */
-+#define CKA_CERTIFICATE_CATEGORY 0x00000087
-+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
-+#define CKA_URL 0x00000089
-+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
-+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
-+#define CKA_CHECK_VALUE 0x00000090
-+
-+#define CKA_KEY_TYPE 0x00000100
-+#define CKA_SUBJECT 0x00000101
-+#define CKA_ID 0x00000102
-+#define CKA_SENSITIVE 0x00000103
-+#define CKA_ENCRYPT 0x00000104
-+#define CKA_DECRYPT 0x00000105
-+#define CKA_WRAP 0x00000106
-+#define CKA_UNWRAP 0x00000107
-+#define CKA_SIGN 0x00000108
-+#define CKA_SIGN_RECOVER 0x00000109
-+#define CKA_VERIFY 0x0000010A
-+#define CKA_VERIFY_RECOVER 0x0000010B
-+#define CKA_DERIVE 0x0000010C
-+#define CKA_START_DATE 0x00000110
-+#define CKA_END_DATE 0x00000111
-+#define CKA_MODULUS 0x00000120
-+#define CKA_MODULUS_BITS 0x00000121
-+#define CKA_PUBLIC_EXPONENT 0x00000122
-+#define CKA_PRIVATE_EXPONENT 0x00000123
-+#define CKA_PRIME_1 0x00000124
-+#define CKA_PRIME_2 0x00000125
-+#define CKA_EXPONENT_1 0x00000126
-+#define CKA_EXPONENT_2 0x00000127
-+#define CKA_COEFFICIENT 0x00000128
-+#define CKA_PRIME 0x00000130
-+#define CKA_SUBPRIME 0x00000131
-+#define CKA_BASE 0x00000132
-+
-+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-+#define CKA_PRIME_BITS 0x00000133
-+#define CKA_SUBPRIME_BITS 0x00000134
-+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
-+/* (To retain backwards-compatibility) */
-+
-+#define CKA_VALUE_BITS 0x00000160
-+#define CKA_VALUE_LEN 0x00000161
-+
-+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
-+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
-+ * and CKA_EC_POINT are new for v2.0 */
-+#define CKA_EXTRACTABLE 0x00000162
-+#define CKA_LOCAL 0x00000163
-+#define CKA_NEVER_EXTRACTABLE 0x00000164
-+#define CKA_ALWAYS_SENSITIVE 0x00000165
-+
-+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-+#define CKA_KEY_GEN_MECHANISM 0x00000166
-+
-+#define CKA_MODIFIABLE 0x00000170
-+
-+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
-+ * CKA_EC_PARAMS is preferred. */
-+#define CKA_ECDSA_PARAMS 0x00000180
-+#define CKA_EC_PARAMS 0x00000180
-+
-+#define CKA_EC_POINT 0x00000181
-+
-+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
-+ * are new for v2.10. Deprecated in v2.11 and onwards. */
-+#define CKA_SECONDARY_AUTH 0x00000200
-+#define CKA_AUTH_PIN_FLAGS 0x00000201
-+
-+/* CKA_ALWAYS_AUTHENTICATE ...
-+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
-+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
-+
-+#define CKA_WRAP_WITH_TRUSTED 0x00000210
-+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
-+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
-+
-+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
-+ * are new for v2.10 */
-+#define CKA_HW_FEATURE_TYPE 0x00000300
-+#define CKA_RESET_ON_INIT 0x00000301
-+#define CKA_HAS_RESET 0x00000302
-+
-+/* The following attributes are new for v2.20 */
-+#define CKA_PIXEL_X 0x00000400
-+#define CKA_PIXEL_Y 0x00000401
-+#define CKA_RESOLUTION 0x00000402
-+#define CKA_CHAR_ROWS 0x00000403
-+#define CKA_CHAR_COLUMNS 0x00000404
-+#define CKA_COLOR 0x00000405
-+#define CKA_BITS_PER_PIXEL 0x00000406
-+#define CKA_CHAR_SETS 0x00000480
-+#define CKA_ENCODING_METHODS 0x00000481
-+#define CKA_MIME_TYPES 0x00000482
-+#define CKA_MECHANISM_TYPE 0x00000500
-+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
-+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
-+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
-+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
-+
-+#define CKA_VENDOR_DEFINED 0x80000000
-+
-+
-+/* CK_ATTRIBUTE is a structure that includes the type, length
-+ * and value of an attribute */
-+typedef struct CK_ATTRIBUTE {
-+ CK_ATTRIBUTE_TYPE type;
-+ CK_VOID_PTR pValue;
-+
-+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
-+ CK_ULONG ulValueLen; /* in bytes */
-+} CK_ATTRIBUTE;
-+
-+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-+
-+
-+/* CK_DATE is a structure that defines a date */
-+typedef struct CK_DATE{
-+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
-+ CK_CHAR month[2]; /* the month ("01" - "12") */
-+ CK_CHAR day[2]; /* the day ("01" - "31") */
-+} CK_DATE;
-+
-+
-+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
-+ * type */
-+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+typedef CK_ULONG CK_MECHANISM_TYPE;
-+
-+/* the following mechanism types are defined: */
-+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
-+#define CKM_RSA_PKCS 0x00000001
-+#define CKM_RSA_9796 0x00000002
-+#define CKM_RSA_X_509 0x00000003
-+
-+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
-+ * are new for v2.0. They are mechanisms which hash and sign */
-+#define CKM_MD2_RSA_PKCS 0x00000004
-+#define CKM_MD5_RSA_PKCS 0x00000005
-+#define CKM_SHA1_RSA_PKCS 0x00000006
-+
-+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
-+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
-+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
-+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
-+#define CKM_RSA_PKCS_OAEP 0x00000009
-+
-+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
-+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
-+#define CKM_RSA_X9_31 0x0000000B
-+#define CKM_SHA1_RSA_X9_31 0x0000000C
-+#define CKM_RSA_PKCS_PSS 0x0000000D
-+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
-+
-+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
-+#define CKM_DSA 0x00000011
-+#define CKM_DSA_SHA1 0x00000012
-+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
-+#define CKM_DH_PKCS_DERIVE 0x00000021
-+
-+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
-+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
-+ * v2.11 */
-+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
-+#define CKM_X9_42_DH_DERIVE 0x00000031
-+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
-+#define CKM_X9_42_MQV_DERIVE 0x00000033
-+
-+/* CKM_SHA256/384/512 are new for v2.20 */
-+#define CKM_SHA256_RSA_PKCS 0x00000040
-+#define CKM_SHA384_RSA_PKCS 0x00000041
-+#define CKM_SHA512_RSA_PKCS 0x00000042
-+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
-+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
-+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
-+
-+#define CKM_RC2_KEY_GEN 0x00000100
-+#define CKM_RC2_ECB 0x00000101
-+#define CKM_RC2_CBC 0x00000102
-+#define CKM_RC2_MAC 0x00000103
-+
-+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-+#define CKM_RC2_MAC_GENERAL 0x00000104
-+#define CKM_RC2_CBC_PAD 0x00000105
-+
-+#define CKM_RC4_KEY_GEN 0x00000110
-+#define CKM_RC4 0x00000111
-+#define CKM_DES_KEY_GEN 0x00000120
-+#define CKM_DES_ECB 0x00000121
-+#define CKM_DES_CBC 0x00000122
-+#define CKM_DES_MAC 0x00000123
-+
-+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-+#define CKM_DES_MAC_GENERAL 0x00000124
-+#define CKM_DES_CBC_PAD 0x00000125
-+
-+#define CKM_DES2_KEY_GEN 0x00000130
-+#define CKM_DES3_KEY_GEN 0x00000131
-+#define CKM_DES3_ECB 0x00000132
-+#define CKM_DES3_CBC 0x00000133
-+#define CKM_DES3_MAC 0x00000134
-+
-+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
-+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
-+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-+#define CKM_DES3_MAC_GENERAL 0x00000135
-+#define CKM_DES3_CBC_PAD 0x00000136
-+#define CKM_CDMF_KEY_GEN 0x00000140
-+#define CKM_CDMF_ECB 0x00000141
-+#define CKM_CDMF_CBC 0x00000142
-+#define CKM_CDMF_MAC 0x00000143
-+#define CKM_CDMF_MAC_GENERAL 0x00000144
-+#define CKM_CDMF_CBC_PAD 0x00000145
-+
-+/* the following four DES mechanisms are new for v2.20 */
-+#define CKM_DES_OFB64 0x00000150
-+#define CKM_DES_OFB8 0x00000151
-+#define CKM_DES_CFB64 0x00000152
-+#define CKM_DES_CFB8 0x00000153
-+
-+#define CKM_MD2 0x00000200
-+
-+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-+#define CKM_MD2_HMAC 0x00000201
-+#define CKM_MD2_HMAC_GENERAL 0x00000202
-+
-+#define CKM_MD5 0x00000210
-+
-+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-+#define CKM_MD5_HMAC 0x00000211
-+#define CKM_MD5_HMAC_GENERAL 0x00000212
-+
-+#define CKM_SHA_1 0x00000220
-+
-+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-+#define CKM_SHA_1_HMAC 0x00000221
-+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
-+
-+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
-+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
-+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-+#define CKM_RIPEMD128 0x00000230
-+#define CKM_RIPEMD128_HMAC 0x00000231
-+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
-+#define CKM_RIPEMD160 0x00000240
-+#define CKM_RIPEMD160_HMAC 0x00000241
-+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
-+
-+/* CKM_SHA256/384/512 are new for v2.20 */
-+#define CKM_SHA256 0x00000250
-+#define CKM_SHA256_HMAC 0x00000251
-+#define CKM_SHA256_HMAC_GENERAL 0x00000252
-+#define CKM_SHA384 0x00000260
-+#define CKM_SHA384_HMAC 0x00000261
-+#define CKM_SHA384_HMAC_GENERAL 0x00000262
-+#define CKM_SHA512 0x00000270
-+#define CKM_SHA512_HMAC 0x00000271
-+#define CKM_SHA512_HMAC_GENERAL 0x00000272
-+
-+/* All of the following mechanisms are new for v2.0 */
-+/* Note that CAST128 and CAST5 are the same algorithm */
-+#define CKM_CAST_KEY_GEN 0x00000300
-+#define CKM_CAST_ECB 0x00000301
-+#define CKM_CAST_CBC 0x00000302
-+#define CKM_CAST_MAC 0x00000303
-+#define CKM_CAST_MAC_GENERAL 0x00000304
-+#define CKM_CAST_CBC_PAD 0x00000305
-+#define CKM_CAST3_KEY_GEN 0x00000310
-+#define CKM_CAST3_ECB 0x00000311
-+#define CKM_CAST3_CBC 0x00000312
-+#define CKM_CAST3_MAC 0x00000313
-+#define CKM_CAST3_MAC_GENERAL 0x00000314
-+#define CKM_CAST3_CBC_PAD 0x00000315
-+#define CKM_CAST5_KEY_GEN 0x00000320
-+#define CKM_CAST128_KEY_GEN 0x00000320
-+#define CKM_CAST5_ECB 0x00000321
-+#define CKM_CAST128_ECB 0x00000321
-+#define CKM_CAST5_CBC 0x00000322
-+#define CKM_CAST128_CBC 0x00000322
-+#define CKM_CAST5_MAC 0x00000323
-+#define CKM_CAST128_MAC 0x00000323
-+#define CKM_CAST5_MAC_GENERAL 0x00000324
-+#define CKM_CAST128_MAC_GENERAL 0x00000324
-+#define CKM_CAST5_CBC_PAD 0x00000325
-+#define CKM_CAST128_CBC_PAD 0x00000325
-+#define CKM_RC5_KEY_GEN 0x00000330
-+#define CKM_RC5_ECB 0x00000331
-+#define CKM_RC5_CBC 0x00000332
-+#define CKM_RC5_MAC 0x00000333
-+#define CKM_RC5_MAC_GENERAL 0x00000334
-+#define CKM_RC5_CBC_PAD 0x00000335
-+#define CKM_IDEA_KEY_GEN 0x00000340
-+#define CKM_IDEA_ECB 0x00000341
-+#define CKM_IDEA_CBC 0x00000342
-+#define CKM_IDEA_MAC 0x00000343
-+#define CKM_IDEA_MAC_GENERAL 0x00000344
-+#define CKM_IDEA_CBC_PAD 0x00000345
-+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
-+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
-+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
-+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
-+#define CKM_XOR_BASE_AND_DATA 0x00000364
-+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
-+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
-+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
-+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
-+
-+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
-+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
-+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
-+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
-+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
-+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
-+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
-+
-+/* CKM_TLS_PRF is new for v2.20 */
-+#define CKM_TLS_PRF 0x00000378
-+
-+#define CKM_SSL3_MD5_MAC 0x00000380
-+#define CKM_SSL3_SHA1_MAC 0x00000381
-+#define CKM_MD5_KEY_DERIVATION 0x00000390
-+#define CKM_MD2_KEY_DERIVATION 0x00000391
-+#define CKM_SHA1_KEY_DERIVATION 0x00000392
-+
-+/* CKM_SHA256/384/512 are new for v2.20 */
-+#define CKM_SHA256_KEY_DERIVATION 0x00000393
-+#define CKM_SHA384_KEY_DERIVATION 0x00000394
-+#define CKM_SHA512_KEY_DERIVATION 0x00000395
-+
-+#define CKM_PBE_MD2_DES_CBC 0x000003A0
-+#define CKM_PBE_MD5_DES_CBC 0x000003A1
-+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
-+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
-+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
-+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
-+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
-+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
-+#define CKM_PBE_SHA1_RC4_128 0x000003A6
-+#define CKM_PBE_SHA1_RC4_40 0x000003A7
-+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
-+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
-+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
-+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
-+
-+/* CKM_PKCS5_PBKD2 is new for v2.10 */
-+#define CKM_PKCS5_PBKD2 0x000003B0
-+
-+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
-+
-+/* WTLS mechanisms are new for v2.20 */
-+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
-+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
-+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
-+#define CKM_WTLS_PRF 0x000003D3
-+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
-+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
-+
-+#define CKM_KEY_WRAP_LYNKS 0x00000400
-+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
-+
-+/* CKM_CMS_SIG is new for v2.20 */
-+#define CKM_CMS_SIG 0x00000500
-+
-+/* Fortezza mechanisms */
-+#define CKM_SKIPJACK_KEY_GEN 0x00001000
-+#define CKM_SKIPJACK_ECB64 0x00001001
-+#define CKM_SKIPJACK_CBC64 0x00001002
-+#define CKM_SKIPJACK_OFB64 0x00001003
-+#define CKM_SKIPJACK_CFB64 0x00001004
-+#define CKM_SKIPJACK_CFB32 0x00001005
-+#define CKM_SKIPJACK_CFB16 0x00001006
-+#define CKM_SKIPJACK_CFB8 0x00001007
-+#define CKM_SKIPJACK_WRAP 0x00001008
-+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
-+#define CKM_SKIPJACK_RELAYX 0x0000100a
-+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
-+#define CKM_KEA_KEY_DERIVE 0x00001011
-+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
-+#define CKM_BATON_KEY_GEN 0x00001030
-+#define CKM_BATON_ECB128 0x00001031
-+#define CKM_BATON_ECB96 0x00001032
-+#define CKM_BATON_CBC128 0x00001033
-+#define CKM_BATON_COUNTER 0x00001034
-+#define CKM_BATON_SHUFFLE 0x00001035
-+#define CKM_BATON_WRAP 0x00001036
-+
-+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
-+ * CKM_EC_KEY_PAIR_GEN is preferred */
-+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
-+#define CKM_EC_KEY_PAIR_GEN 0x00001040
-+
-+#define CKM_ECDSA 0x00001041
-+#define CKM_ECDSA_SHA1 0x00001042
-+
-+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
-+ * are new for v2.11 */
-+#define CKM_ECDH1_DERIVE 0x00001050
-+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
-+#define CKM_ECMQV_DERIVE 0x00001052
-+
-+#define CKM_JUNIPER_KEY_GEN 0x00001060
-+#define CKM_JUNIPER_ECB128 0x00001061
-+#define CKM_JUNIPER_CBC128 0x00001062
-+#define CKM_JUNIPER_COUNTER 0x00001063
-+#define CKM_JUNIPER_SHUFFLE 0x00001064
-+#define CKM_JUNIPER_WRAP 0x00001065
-+#define CKM_FASTHASH 0x00001070
-+
-+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
-+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
-+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
-+ * new for v2.11 */
-+#define CKM_AES_KEY_GEN 0x00001080
-+#define CKM_AES_ECB 0x00001081
-+#define CKM_AES_CBC 0x00001082
-+#define CKM_AES_MAC 0x00001083
-+#define CKM_AES_MAC_GENERAL 0x00001084
-+#define CKM_AES_CBC_PAD 0x00001085
-+
-+/* BlowFish and TwoFish are new for v2.20 */
-+#define CKM_BLOWFISH_KEY_GEN 0x00001090
-+#define CKM_BLOWFISH_CBC 0x00001091
-+#define CKM_TWOFISH_KEY_GEN 0x00001092
-+#define CKM_TWOFISH_CBC 0x00001093
-+
-+
-+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
-+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
-+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
-+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
-+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
-+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
-+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
-+
-+#define CKM_DSA_PARAMETER_GEN 0x00002000
-+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
-+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
-+
-+#define CKM_VENDOR_DEFINED 0x80000000
-+
-+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-+
-+
-+/* CK_MECHANISM is a structure that specifies a particular
-+ * mechanism */
-+typedef struct CK_MECHANISM {
-+ CK_MECHANISM_TYPE mechanism;
-+ CK_VOID_PTR pParameter;
-+
-+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+ CK_ULONG ulParameterLen; /* in bytes */
-+} CK_MECHANISM;
-+
-+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-+
-+
-+/* CK_MECHANISM_INFO provides information about a particular
-+ * mechanism */
-+typedef struct CK_MECHANISM_INFO {
-+ CK_ULONG ulMinKeySize;
-+ CK_ULONG ulMaxKeySize;
-+ CK_FLAGS flags;
-+} CK_MECHANISM_INFO;
-+
-+/* The flags are defined as follows:
-+ * Bit Flag Mask Meaning */
-+#define CKF_HW 0x00000001 /* performed by HW */
-+
-+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
-+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
-+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
-+ * and CKF_DERIVE are new for v2.0. They specify whether or not
-+ * a mechanism can be used for a particular task */
-+#define CKF_ENCRYPT 0x00000100
-+#define CKF_DECRYPT 0x00000200
-+#define CKF_DIGEST 0x00000400
-+#define CKF_SIGN 0x00000800
-+#define CKF_SIGN_RECOVER 0x00001000
-+#define CKF_VERIFY 0x00002000
-+#define CKF_VERIFY_RECOVER 0x00004000
-+#define CKF_GENERATE 0x00008000
-+#define CKF_GENERATE_KEY_PAIR 0x00010000
-+#define CKF_WRAP 0x00020000
-+#define CKF_UNWRAP 0x00040000
-+#define CKF_DERIVE 0x00080000
-+
-+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
-+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
-+ * describe a token's EC capabilities not available in mechanism
-+ * information. */
-+#define CKF_EC_F_P 0x00100000
-+#define CKF_EC_F_2M 0x00200000
-+#define CKF_EC_ECPARAMETERS 0x00400000
-+#define CKF_EC_NAMEDCURVE 0x00800000
-+#define CKF_EC_UNCOMPRESS 0x01000000
-+#define CKF_EC_COMPRESS 0x02000000
-+
-+#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
-+
-+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-+
-+
-+/* CK_RV is a value that identifies the return value of a
-+ * Cryptoki function */
-+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-+typedef CK_ULONG CK_RV;
-+
-+#define CKR_OK 0x00000000
-+#define CKR_CANCEL 0x00000001
-+#define CKR_HOST_MEMORY 0x00000002
-+#define CKR_SLOT_ID_INVALID 0x00000003
-+
-+/* CKR_FLAGS_INVALID was removed for v2.0 */
-+
-+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-+#define CKR_GENERAL_ERROR 0x00000005
-+#define CKR_FUNCTION_FAILED 0x00000006
-+
-+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
-+ * and CKR_CANT_LOCK are new for v2.01 */
-+#define CKR_ARGUMENTS_BAD 0x00000007
-+#define CKR_NO_EVENT 0x00000008
-+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
-+#define CKR_CANT_LOCK 0x0000000A
-+
-+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
-+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
-+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
-+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
-+#define CKR_DATA_INVALID 0x00000020
-+#define CKR_DATA_LEN_RANGE 0x00000021
-+#define CKR_DEVICE_ERROR 0x00000030
-+#define CKR_DEVICE_MEMORY 0x00000031
-+#define CKR_DEVICE_REMOVED 0x00000032
-+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
-+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
-+#define CKR_FUNCTION_CANCELED 0x00000050
-+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
-+
-+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
-+
-+#define CKR_KEY_HANDLE_INVALID 0x00000060
-+
-+/* CKR_KEY_SENSITIVE was removed for v2.0 */
-+
-+#define CKR_KEY_SIZE_RANGE 0x00000062
-+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
-+
-+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
-+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
-+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
-+ * v2.0 */
-+#define CKR_KEY_NOT_NEEDED 0x00000064
-+#define CKR_KEY_CHANGED 0x00000065
-+#define CKR_KEY_NEEDED 0x00000066
-+#define CKR_KEY_INDIGESTIBLE 0x00000067
-+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
-+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
-+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
-+
-+#define CKR_MECHANISM_INVALID 0x00000070
-+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
-+
-+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
-+ * were removed for v2.0 */
-+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
-+#define CKR_OPERATION_ACTIVE 0x00000090
-+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
-+#define CKR_PIN_INCORRECT 0x000000A0
-+#define CKR_PIN_INVALID 0x000000A1
-+#define CKR_PIN_LEN_RANGE 0x000000A2
-+
-+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-+#define CKR_PIN_EXPIRED 0x000000A3
-+#define CKR_PIN_LOCKED 0x000000A4
-+
-+#define CKR_SESSION_CLOSED 0x000000B0
-+#define CKR_SESSION_COUNT 0x000000B1
-+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
-+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
-+#define CKR_SESSION_READ_ONLY 0x000000B5
-+#define CKR_SESSION_EXISTS 0x000000B6
-+
-+/* CKR_SESSION_READ_ONLY_EXISTS and
-+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
-+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
-+
-+#define CKR_SIGNATURE_INVALID 0x000000C0
-+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
-+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
-+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
-+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
-+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
-+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
-+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
-+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
-+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
-+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
-+#define CKR_USER_NOT_LOGGED_IN 0x00000101
-+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
-+#define CKR_USER_TYPE_INVALID 0x00000103
-+
-+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
-+ * are new to v2.01 */
-+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
-+#define CKR_USER_TOO_MANY_TYPES 0x00000105
-+
-+#define CKR_WRAPPED_KEY_INVALID 0x00000110
-+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
-+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
-+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
-+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
-+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-+
-+/* These are new to v2.0 */
-+#define CKR_RANDOM_NO_RNG 0x00000121
-+
-+/* These are new to v2.11 */
-+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
-+
-+/* These are new to v2.0 */
-+#define CKR_BUFFER_TOO_SMALL 0x00000150
-+#define CKR_SAVED_STATE_INVALID 0x00000160
-+#define CKR_INFORMATION_SENSITIVE 0x00000170
-+#define CKR_STATE_UNSAVEABLE 0x00000180
-+
-+/* These are new to v2.01 */
-+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
-+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
-+#define CKR_MUTEX_BAD 0x000001A0
-+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
-+
-+/* This is new to v2.20 */
-+#define CKR_FUNCTION_REJECTED 0x00000200
-+
-+#define CKR_VENDOR_DEFINED 0x80000000
-+
-+
-+/* CK_NOTIFY is an application callback that processes events */
-+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_NOTIFICATION event,
-+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
-+);
-+
-+
-+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
-+ * version and pointers of appropriate types to all the
-+ * Cryptoki functions */
-+/* CK_FUNCTION_LIST is new for v2.0 */
-+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-+
-+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-+
-+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-+
-+
-+/* CK_CREATEMUTEX is an application callback for creating a
-+ * mutex object */
-+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
-+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
-+);
-+
-+
-+/* CK_DESTROYMUTEX is an application callback for destroying a
-+ * mutex object */
-+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
-+ CK_VOID_PTR pMutex /* pointer to mutex */
-+);
-+
-+
-+/* CK_LOCKMUTEX is an application callback for locking a mutex */
-+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
-+ CK_VOID_PTR pMutex /* pointer to mutex */
-+);
-+
-+
-+/* CK_UNLOCKMUTEX is an application callback for unlocking a
-+ * mutex */
-+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
-+ CK_VOID_PTR pMutex /* pointer to mutex */
-+);
-+
-+
-+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
-+ * C_Initialize */
-+typedef struct CK_C_INITIALIZE_ARGS {
-+ CK_CREATEMUTEX CreateMutex;
-+ CK_DESTROYMUTEX DestroyMutex;
-+ CK_LOCKMUTEX LockMutex;
-+ CK_UNLOCKMUTEX UnlockMutex;
-+ CK_FLAGS flags;
-+ CK_VOID_PTR pReserved;
-+} CK_C_INITIALIZE_ARGS;
-+
-+/* flags: bit flags that provide capabilities of the slot
-+ * Bit Flag Mask Meaning
-+ */
-+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-+#define CKF_OS_LOCKING_OK 0x00000002
-+
-+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-+
-+
-+/* additional flags for parameters to functions */
-+
-+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-+#define CKF_DONT_BLOCK 1
-+
-+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
-+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
-+ * Generation Function (MGF) applied to a message block when
-+ * formatting a message block for the PKCS #1 OAEP encryption
-+ * scheme. */
-+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-+
-+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
-+
-+/* The following MGFs are defined */
-+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
-+ * are new for v2.20 */
-+#define CKG_MGF1_SHA1 0x00000001
-+#define CKG_MGF1_SHA256 0x00000002
-+#define CKG_MGF1_SHA384 0x00000003
-+#define CKG_MGF1_SHA512 0x00000004
-+
-+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
-+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
-+ * of the encoding parameter when formatting a message block
-+ * for the PKCS #1 OAEP encryption scheme. */
-+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
-+
-+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
-+
-+/* The following encoding parameter sources are defined */
-+#define CKZ_DATA_SPECIFIED 0x00000001
-+
-+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
-+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
-+ * CKM_RSA_PKCS_OAEP mechanism. */
-+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
-+ CK_MECHANISM_TYPE hashAlg;
-+ CK_RSA_PKCS_MGF_TYPE mgf;
-+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
-+ CK_VOID_PTR pSourceData;
-+ CK_ULONG ulSourceDataLen;
-+} CK_RSA_PKCS_OAEP_PARAMS;
-+
-+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
-+
-+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
-+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
-+ * CKM_RSA_PKCS_PSS mechanism(s). */
-+typedef struct CK_RSA_PKCS_PSS_PARAMS {
-+ CK_MECHANISM_TYPE hashAlg;
-+ CK_RSA_PKCS_MGF_TYPE mgf;
-+ CK_ULONG sLen;
-+} CK_RSA_PKCS_PSS_PARAMS;
-+
-+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
-+
-+/* CK_EC_KDF_TYPE is new for v2.11. */
-+typedef CK_ULONG CK_EC_KDF_TYPE;
-+
-+/* The following EC Key Derivation Functions are defined */
-+#define CKD_NULL 0x00000001
-+#define CKD_SHA1_KDF 0x00000002
-+
-+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
-+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
-+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
-+ * where each party contributes one key pair.
-+ */
-+typedef struct CK_ECDH1_DERIVE_PARAMS {
-+ CK_EC_KDF_TYPE kdf;
-+ CK_ULONG ulSharedDataLen;
-+ CK_BYTE_PTR pSharedData;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+} CK_ECDH1_DERIVE_PARAMS;
-+
-+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-+
-+
-+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
-+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
-+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
-+typedef struct CK_ECDH2_DERIVE_PARAMS {
-+ CK_EC_KDF_TYPE kdf;
-+ CK_ULONG ulSharedDataLen;
-+ CK_BYTE_PTR pSharedData;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+ CK_ULONG ulPrivateDataLen;
-+ CK_OBJECT_HANDLE hPrivateData;
-+ CK_ULONG ulPublicDataLen2;
-+ CK_BYTE_PTR pPublicData2;
-+} CK_ECDH2_DERIVE_PARAMS;
-+
-+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
-+
-+typedef struct CK_ECMQV_DERIVE_PARAMS {
-+ CK_EC_KDF_TYPE kdf;
-+ CK_ULONG ulSharedDataLen;
-+ CK_BYTE_PTR pSharedData;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+ CK_ULONG ulPrivateDataLen;
-+ CK_OBJECT_HANDLE hPrivateData;
-+ CK_ULONG ulPublicDataLen2;
-+ CK_BYTE_PTR pPublicData2;
-+ CK_OBJECT_HANDLE publicKey;
-+} CK_ECMQV_DERIVE_PARAMS;
-+
-+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
-+
-+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
-+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
-+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
-+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
-+
-+/* The following X9.42 DH key derivation functions are defined
-+ (besides CKD_NULL already defined : */
-+#define CKD_SHA1_KDF_ASN1 0x00000003
-+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
-+
-+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
-+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
-+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
-+ * contributes one key pair */
-+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
-+ CK_X9_42_DH_KDF_TYPE kdf;
-+ CK_ULONG ulOtherInfoLen;
-+ CK_BYTE_PTR pOtherInfo;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+} CK_X9_42_DH1_DERIVE_PARAMS;
-+
-+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
-+
-+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
-+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
-+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
-+ * mechanisms, where each party contributes two key pairs */
-+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
-+ CK_X9_42_DH_KDF_TYPE kdf;
-+ CK_ULONG ulOtherInfoLen;
-+ CK_BYTE_PTR pOtherInfo;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+ CK_ULONG ulPrivateDataLen;
-+ CK_OBJECT_HANDLE hPrivateData;
-+ CK_ULONG ulPublicDataLen2;
-+ CK_BYTE_PTR pPublicData2;
-+} CK_X9_42_DH2_DERIVE_PARAMS;
-+
-+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
-+
-+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
-+ CK_X9_42_DH_KDF_TYPE kdf;
-+ CK_ULONG ulOtherInfoLen;
-+ CK_BYTE_PTR pOtherInfo;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+ CK_ULONG ulPrivateDataLen;
-+ CK_OBJECT_HANDLE hPrivateData;
-+ CK_ULONG ulPublicDataLen2;
-+ CK_BYTE_PTR pPublicData2;
-+ CK_OBJECT_HANDLE publicKey;
-+} CK_X9_42_MQV_DERIVE_PARAMS;
-+
-+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
-+
-+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
-+ * CKM_KEA_DERIVE mechanism */
-+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-+typedef struct CK_KEA_DERIVE_PARAMS {
-+ CK_BBOOL isSender;
-+ CK_ULONG ulRandomLen;
-+ CK_BYTE_PTR pRandomA;
-+ CK_BYTE_PTR pRandomB;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+} CK_KEA_DERIVE_PARAMS;
-+
-+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-+
-+
-+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
-+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
-+ * holds the effective keysize */
-+typedef CK_ULONG CK_RC2_PARAMS;
-+
-+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-+
-+
-+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
-+ * mechanism */
-+typedef struct CK_RC2_CBC_PARAMS {
-+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-+
-+ CK_BYTE iv[8]; /* IV for CBC mode */
-+} CK_RC2_CBC_PARAMS;
-+
-+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-+
-+
-+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
-+ * CKM_RC2_MAC_GENERAL mechanism */
-+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
-+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
-+} CK_RC2_MAC_GENERAL_PARAMS;
-+
-+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
-+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
-+
-+
-+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
-+ * CKM_RC5_MAC mechanisms */
-+/* CK_RC5_PARAMS is new for v2.0 */
-+typedef struct CK_RC5_PARAMS {
-+ CK_ULONG ulWordsize; /* wordsize in bits */
-+ CK_ULONG ulRounds; /* number of rounds */
-+} CK_RC5_PARAMS;
-+
-+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-+
-+
-+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
-+ * mechanism */
-+/* CK_RC5_CBC_PARAMS is new for v2.0 */
-+typedef struct CK_RC5_CBC_PARAMS {
-+ CK_ULONG ulWordsize; /* wordsize in bits */
-+ CK_ULONG ulRounds; /* number of rounds */
-+ CK_BYTE_PTR pIv; /* pointer to IV */
-+ CK_ULONG ulIvLen; /* length of IV in bytes */
-+} CK_RC5_CBC_PARAMS;
-+
-+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-+
-+
-+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
-+ * CKM_RC5_MAC_GENERAL mechanism */
-+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
-+ CK_ULONG ulWordsize; /* wordsize in bits */
-+ CK_ULONG ulRounds; /* number of rounds */
-+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
-+} CK_RC5_MAC_GENERAL_PARAMS;
-+
-+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
-+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
-+
-+
-+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
-+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
-+ * the MAC */
-+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
-+
-+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-+
-+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
-+ CK_BYTE iv[8];
-+ CK_BYTE_PTR pData;
-+ CK_ULONG length;
-+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
-+
-+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-+
-+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
-+ CK_BYTE iv[16];
-+ CK_BYTE_PTR pData;
-+ CK_ULONG length;
-+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
-+
-+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-+
-+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
-+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
-+ CK_ULONG ulPasswordLen;
-+ CK_BYTE_PTR pPassword;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+ CK_ULONG ulPAndGLen;
-+ CK_ULONG ulQLen;
-+ CK_ULONG ulRandomLen;
-+ CK_BYTE_PTR pRandomA;
-+ CK_BYTE_PTR pPrimeP;
-+ CK_BYTE_PTR pBaseG;
-+ CK_BYTE_PTR pSubprimeQ;
-+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-+
-+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
-+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
-+
-+
-+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
-+ * CKM_SKIPJACK_RELAYX mechanism */
-+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
-+ CK_ULONG ulOldWrappedXLen;
-+ CK_BYTE_PTR pOldWrappedX;
-+ CK_ULONG ulOldPasswordLen;
-+ CK_BYTE_PTR pOldPassword;
-+ CK_ULONG ulOldPublicDataLen;
-+ CK_BYTE_PTR pOldPublicData;
-+ CK_ULONG ulOldRandomLen;
-+ CK_BYTE_PTR pOldRandomA;
-+ CK_ULONG ulNewPasswordLen;
-+ CK_BYTE_PTR pNewPassword;
-+ CK_ULONG ulNewPublicDataLen;
-+ CK_BYTE_PTR pNewPublicData;
-+ CK_ULONG ulNewRandomLen;
-+ CK_BYTE_PTR pNewRandomA;
-+} CK_SKIPJACK_RELAYX_PARAMS;
-+
-+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
-+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
-+
-+
-+typedef struct CK_PBE_PARAMS {
-+ CK_BYTE_PTR pInitVector;
-+ CK_UTF8CHAR_PTR pPassword;
-+ CK_ULONG ulPasswordLen;
-+ CK_BYTE_PTR pSalt;
-+ CK_ULONG ulSaltLen;
-+ CK_ULONG ulIteration;
-+} CK_PBE_PARAMS;
-+
-+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-+
-+
-+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
-+ * CKM_KEY_WRAP_SET_OAEP mechanism */
-+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
-+ CK_BYTE bBC; /* block contents byte */
-+ CK_BYTE_PTR pX; /* extra data */
-+ CK_ULONG ulXLen; /* length of extra data in bytes */
-+} CK_KEY_WRAP_SET_OAEP_PARAMS;
-+
-+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
-+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-+
-+
-+typedef struct CK_SSL3_RANDOM_DATA {
-+ CK_BYTE_PTR pClientRandom;
-+ CK_ULONG ulClientRandomLen;
-+ CK_BYTE_PTR pServerRandom;
-+ CK_ULONG ulServerRandomLen;
-+} CK_SSL3_RANDOM_DATA;
-+
-+
-+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
-+ CK_SSL3_RANDOM_DATA RandomInfo;
-+ CK_VERSION_PTR pVersion;
-+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-+
-+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-+
-+
-+typedef struct CK_SSL3_KEY_MAT_OUT {
-+ CK_OBJECT_HANDLE hClientMacSecret;
-+ CK_OBJECT_HANDLE hServerMacSecret;
-+ CK_OBJECT_HANDLE hClientKey;
-+ CK_OBJECT_HANDLE hServerKey;
-+ CK_BYTE_PTR pIVClient;
-+ CK_BYTE_PTR pIVServer;
-+} CK_SSL3_KEY_MAT_OUT;
-+
-+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-+
-+
-+typedef struct CK_SSL3_KEY_MAT_PARAMS {
-+ CK_ULONG ulMacSizeInBits;
-+ CK_ULONG ulKeySizeInBits;
-+ CK_ULONG ulIVSizeInBits;
-+ CK_BBOOL bIsExport;
-+ CK_SSL3_RANDOM_DATA RandomInfo;
-+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-+} CK_SSL3_KEY_MAT_PARAMS;
-+
-+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-+
-+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-+typedef struct CK_TLS_PRF_PARAMS {
-+ CK_BYTE_PTR pSeed;
-+ CK_ULONG ulSeedLen;
-+ CK_BYTE_PTR pLabel;
-+ CK_ULONG ulLabelLen;
-+ CK_BYTE_PTR pOutput;
-+ CK_ULONG_PTR pulOutputLen;
-+} CK_TLS_PRF_PARAMS;
-+
-+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
-+
-+/* WTLS is new for version 2.20 */
-+typedef struct CK_WTLS_RANDOM_DATA {
-+ CK_BYTE_PTR pClientRandom;
-+ CK_ULONG ulClientRandomLen;
-+ CK_BYTE_PTR pServerRandom;
-+ CK_ULONG ulServerRandomLen;
-+} CK_WTLS_RANDOM_DATA;
-+
-+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
-+
-+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
-+ CK_MECHANISM_TYPE DigestMechanism;
-+ CK_WTLS_RANDOM_DATA RandomInfo;
-+ CK_BYTE_PTR pVersion;
-+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
-+
-+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
-+
-+typedef struct CK_WTLS_PRF_PARAMS {
-+ CK_MECHANISM_TYPE DigestMechanism;
-+ CK_BYTE_PTR pSeed;
-+ CK_ULONG ulSeedLen;
-+ CK_BYTE_PTR pLabel;
-+ CK_ULONG ulLabelLen;
-+ CK_BYTE_PTR pOutput;
-+ CK_ULONG_PTR pulOutputLen;
-+} CK_WTLS_PRF_PARAMS;
-+
-+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
-+
-+typedef struct CK_WTLS_KEY_MAT_OUT {
-+ CK_OBJECT_HANDLE hMacSecret;
-+ CK_OBJECT_HANDLE hKey;
-+ CK_BYTE_PTR pIV;
-+} CK_WTLS_KEY_MAT_OUT;
-+
-+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
-+
-+typedef struct CK_WTLS_KEY_MAT_PARAMS {
-+ CK_MECHANISM_TYPE DigestMechanism;
-+ CK_ULONG ulMacSizeInBits;
-+ CK_ULONG ulKeySizeInBits;
-+ CK_ULONG ulIVSizeInBits;
-+ CK_ULONG ulSequenceNumber;
-+ CK_BBOOL bIsExport;
-+ CK_WTLS_RANDOM_DATA RandomInfo;
-+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-+} CK_WTLS_KEY_MAT_PARAMS;
-+
-+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
-+
-+/* CMS is new for version 2.20 */
-+typedef struct CK_CMS_SIG_PARAMS {
-+ CK_OBJECT_HANDLE certificateHandle;
-+ CK_MECHANISM_PTR pSigningMechanism;
-+ CK_MECHANISM_PTR pDigestMechanism;
-+ CK_UTF8CHAR_PTR pContentType;
-+ CK_BYTE_PTR pRequestedAttributes;
-+ CK_ULONG ulRequestedAttributesLen;
-+ CK_BYTE_PTR pRequiredAttributes;
-+ CK_ULONG ulRequiredAttributesLen;
-+} CK_CMS_SIG_PARAMS;
-+
-+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
-+
-+typedef struct CK_KEY_DERIVATION_STRING_DATA {
-+ CK_BYTE_PTR pData;
-+ CK_ULONG ulLen;
-+} CK_KEY_DERIVATION_STRING_DATA;
-+
-+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
-+ CK_KEY_DERIVATION_STRING_DATA_PTR;
-+
-+
-+/* The CK_EXTRACT_PARAMS is used for the
-+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
-+ * of the base key should be used as the first bit of the
-+ * derived key */
-+/* CK_EXTRACT_PARAMS is new for v2.0 */
-+typedef CK_ULONG CK_EXTRACT_PARAMS;
-+
-+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-+
-+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
-+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
-+ * indicate the Pseudo-Random Function (PRF) used to generate
-+ * key bits using PKCS #5 PBKDF2. */
-+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
-+
-+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
-+
-+/* The following PRFs are defined in PKCS #5 v2.0. */
-+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-+
-+
-+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
-+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
-+ * source of the salt value when deriving a key using PKCS #5
-+ * PBKDF2. */
-+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
-+
-+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
-+
-+/* The following salt value sources are defined in PKCS #5 v2.0. */
-+#define CKZ_SALT_SPECIFIED 0x00000001
-+
-+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
-+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
-+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-+typedef struct CK_PKCS5_PBKD2_PARAMS {
-+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
-+ CK_VOID_PTR pSaltSourceData;
-+ CK_ULONG ulSaltSourceDataLen;
-+ CK_ULONG iterations;
-+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-+ CK_VOID_PTR pPrfData;
-+ CK_ULONG ulPrfDataLen;
-+ CK_UTF8CHAR_PTR pPassword;
-+ CK_ULONG_PTR ulPasswordLen;
-+} CK_PKCS5_PBKD2_PARAMS;
-+
-+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-+
-+#endif
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/cacerts.pem openssl/demos/easy_tls/cacerts.pem
---- openssl-0.9.8g/demos/easy_tls/cacerts.pem 2001-09-17 21:06:57.000000000 +0200
-+++ openssl/demos/easy_tls/cacerts.pem 2007-10-25 01:27:09.000000000 +0200
-@@ -1,4 +1,4 @@
--$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-+$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-
- issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
- subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/cert.pem openssl/demos/easy_tls/cert.pem
---- openssl-0.9.8g/demos/easy_tls/cert.pem 2001-09-17 21:06:57.000000000 +0200
-+++ openssl/demos/easy_tls/cert.pem 2007-10-25 01:27:09.000000000 +0200
-@@ -1,4 +1,4 @@
--$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-+$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-
- Example certificate and key.
-
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/easy-tls.c openssl/demos/easy_tls/easy-tls.c
---- openssl-0.9.8g/demos/easy_tls/easy-tls.c 2002-03-05 10:07:16.000000000 +0100
-+++ openssl/demos/easy_tls/easy-tls.c 2007-10-25 01:27:09.000000000 +0200
-@@ -1,7 +1,7 @@
- /* -*- Mode: C; c-file-style: "bsd" -*- */
- /*
- * easy-tls.c -- generic TLS proxy.
-- * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-+ * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
- */
- /*
- (c) Copyright 1999 Bodo Moeller. All rights reserved.
-@@ -73,7 +73,7 @@
- */
-
- static char const rcsid[] =
--"$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $";
-+"$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $";
-
- #include <assert.h>
- #include <errno.h>
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/easy-tls.h openssl/demos/easy_tls/easy-tls.h
---- openssl-0.9.8g/demos/easy_tls/easy-tls.h 2001-09-17 21:06:59.000000000 +0200
-+++ openssl/demos/easy_tls/easy-tls.h 2007-10-25 01:27:09.000000000 +0200
-@@ -1,7 +1,7 @@
- /* -*- Mode: C; c-file-style: "bsd" -*- */
- /*
- * easy-tls.h -- generic TLS proxy.
-- * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-+ * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
- */
- /*
- * (c) Copyright 1999 Bodo Moeller. All rights reserved.
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/Makefile openssl/demos/easy_tls/Makefile
---- openssl-0.9.8g/demos/easy_tls/Makefile 2001-09-18 11:15:40.000000000 +0200
-+++ openssl/demos/easy_tls/Makefile 2007-10-25 01:27:09.000000000 +0200
-@@ -1,5 +1,5 @@
- # Makefile for easy-tls example application (rudimentary client and server)
--# $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-+# $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-
- SOLARIS_CFLAGS=-Wall -pedantic -g -O2
- SOLARIS_LIBS=-lxnet
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/test.c openssl/demos/easy_tls/test.c
---- openssl-0.9.8g/demos/easy_tls/test.c 2001-09-17 21:06:59.000000000 +0200
-+++ openssl/demos/easy_tls/test.c 2007-10-25 01:27:09.000000000 +0200
-@@ -1,5 +1,5 @@
- /* test.c */
--/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
-+/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
-
- #define L_PORT 9999
- #define C_PORT 443
-diff -r -u -N openssl-0.9.8g/demos/easy_tls/test.h openssl/demos/easy_tls/test.h
---- openssl-0.9.8g/demos/easy_tls/test.h 2001-09-17 21:07:00.000000000 +0200
-+++ openssl/demos/easy_tls/test.h 2007-10-25 01:27:09.000000000 +0200
-@@ -1,5 +1,5 @@
- /* test.h */
--/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
-+/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
-
-
- void test_process_init(int fd, int client_p, void *apparg);
-diff -r -u -N openssl-0.9.8g/engines/vendor_defns/hwcryptohook.h openssl/engines/vendor_defns/hwcryptohook.h
---- openssl-0.9.8g/engines/vendor_defns/hwcryptohook.h 2002-10-11 19:10:59.000000000 +0200
-+++ openssl/engines/vendor_defns/hwcryptohook.h 2007-10-25 01:27:09.000000000 +0200
-@@ -65,7 +65,7 @@
- * please contact nCipher.
- *
- *
-- * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
-+ * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
- */
-
- #ifndef HWCRYPTOHOOK_H
-diff -r -u -N openssl-0.9.8g/Makefile.org openssl/Makefile.org
---- openssl-0.9.8g/Makefile.org 2007-04-24 01:49:54.000000000 +0200
-+++ openssl/Makefile.org 2007-10-25 01:27:08.000000000 +0200
-@@ -26,6 +26,9 @@
- INSTALL_PREFIX=
- INSTALLTOP=/usr/local/ssl
-
-+# You must set this through --pk11-libname configure option.
-+PK11_LIB_LOCATION=
-+
- # Do not edit this manually. Use Configure --openssldir=DIR do change this!
- OPENSSLDIR=/usr/local/ssl
-
-diff -r -u -N openssl-0.9.8g/README.pkcs11 openssl/README.pkcs11
---- openssl-0.9.8g/README.pkcs11 1970-01-01 01:00:00.000000000 +0100
-+++ openssl/README.pkcs11 2008-01-31 15:24:32.000000000 +0100
-@@ -0,0 +1,153 @@
-+PKCS#11 engine support for OpenSSL 0.9.8g
-+=========================================
-+
-+[Nov 21, 2007]
-+
-+This patch containing code available in OpenSolaris adds support for PKCS#11
-+engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
-+OpenSSL 0.9.8g. Your system must provide PKCS#11 backend otherwise the patch
-+is useless.
-+
-+Patch can be applied like this:
-+
-+ tar xfzv openssl-0.9.8g.tar.gz
-+ cd openssl-0.9.8g
-+ patch -p1 < ../pkcs11_engine-0.9.8g.patch.2007-11-21
-+
-+It is designed to support pure acceleration for RSA, DSA, DH and all the
-+symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
-+except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
-+
-+It also contains experimental code for accessing RSA keys stored in pkcs#11 key
-+stores by reference. See below for more information.
-+
-+You must provide the location of PKCS#11 library in your system to the
-+configure script, eg. if you use libraries from openCryptoki project on Linux
-+AMD64 box, run configure like this:
-+
-+ ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
-+
-+To check whether newly built openssl really supports PKCS#11 it's enough to
-+run "apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in
-+the output.
-+
-+This patch was tested on Solaris against PKCS#11 engine available from Solaris
-+Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using
-+PKCS#11 libraries from openCryptoki project (see openCryptoki website
-+http://sourceforge.net/projects/opencryptoki for more information). Some Linux
-+distributions even ship those libraries with the system. The patch should work
-+on any system that is supported by OpenSSL itself and has functional PKCS#11
-+library.
-+
-+The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-+(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
-+copyrighted by RSA Security Inc., see pkcs11.h for more information.
-+
-+Other added/modified code in this patch is copyrighted by Sun Microsystems,
-+Inc. and is released under the OpenSSL license (see LICENSE file for more
-+information).
-+
-+Revisions of patch for 0.9.8 branch
-+===================================
-+
-+2007-11-21
-+- update for 0.9.8g version
-+- fixes in the draft code for "6607670 teach pkcs#11 engine how to use keys
-+ be reference" so that it doesn't coredump when the referenced key is not
-+ present
-+
-+2007-10-15
-+- update for 0.9.8f version
-+- update for "6607670 teach pkcs#11 engine how to use keys be reference"
-+
-+2007-10-02
-+- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
-+- draft for "6607307 pkcs#11 engine can't read RSA private keys"
-+
-+2007-09-26
-+- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
-+ significant performance drop
-+- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
-+
-+2007-05-25
-+- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
-+
-+2007-05-19
-+- initial patch for 0.9.8e using latest OpenSolaris code
-+
-+Notes
-+=====
-+
-+This patch version contains not very well tested code for referencing RSA keys
-+in keystores by labels. That code might and might not end up in OpenSolaris
-+code base in the future. If you use this particular functionality with this
-+patch I would be very grateful to get any feedback from you (please see my
-+contact in the bottom).
-+
-+Issues
-+------
-+- can't reference public keys inside of certificates using certificate label
-+- can't reference symetric keys
-+- simple references in form of "pkcs11:LABEL" only are supported now. This is
-+ supposed to be changed according to discussion on pkcs11 mailing list; comma
-+ separated list of attributes is planned to be used.
-+- getpassphrase(3c) is used for entering the PIN. This should be changed to a
-+ more general approach; to check if the process has allocated tty and use
-+ other means of entering the PIN if not.
-+
-+Usage
-+-----
-+See examples below using Solaris's pktool(1):
-+
-+# list private keys (note "mycert" label. Basically, we can't generate a
-+# pub/priv key pair with pktool(1) without creating a certificate. This should
-+# be changed in the future).
-+$ pktool list objtype=private
-+Enter PIN for Sun Software PKCS#11 softtoken :
-+Found 1 keys.
-+Key #1 - RSA private key: mycert
-+
-+# this file is going to be signed
-+$ cat test
-+hello
-+
-+# sign it, note "pkcs11:mycert" private key's label
-+$ openssl rsautl -inkey pkcs11:mycert -out test2 -in test -sign -keyform e -engine pkcs11
-+engine "pkcs11" set.
-+Enter PIN:
-+
-+# export the certificate out of the keyring
-+$ pktool export keystore=pkcs11 label=mycert outfile=mycert.cert outformat=pem
-+Warning: file "mycert.cert" exists, will be overwritten.
-+Continue with export? y
-+
-+# verify using OpenSSL without pkcs#11 engine and with the certificate in the
-+# file. This is proof of concept that a file signed with key by reference is
-+# successfully verified when stock OpenSSL is used (I didn't have public key
-+# in the keystore, only the certificate. There is no way to reference a public
-+# key inside of the certificate).
-+$ openssl rsautl -verify -inkey mycert.cert -certin -in test2
-+hello
-+
-+API
-+---
-+You can use ENGINE_load_public_key() and ENGINE_load_private_key() functions
-+only. The 2nd parameter of those calls is the one to use for "pkcs11:LABEL"
-+filename overloading. If used that way, both functions will look for the key
-+in the available keystores. Only one such key must be present. The private key
-+is never extracted from the keystore. See OpenSSL's engine(3) or header file
-+openssl/engine.h for more information.
-+
-+Note that those functions return a pointer to EVP_PKEY structure that contains
-+all necessary information for accesing the key by label then. The pointer can be
-+used in other functions that work with RSA keys - X509_sign() for example. See
-+source code in apps/ subdirectory for reference.
-+
-+Feedback
-+========
-+
-+Please send feedback to security-discuss@opensolaris.org. The patch was
-+created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
-+
-+Latest version should be always available on http://blogs.sun.com/janp.
-+
diff --git a/contrib/pkcs11-keygen/openssl-0.9.8i-patch b/contrib/pkcs11-keygen/openssl-0.9.8i-patch
new file mode 100644
index 00000000..0ea5beec
--- /dev/null
+++ b/contrib/pkcs11-keygen/openssl-0.9.8i-patch
@@ -0,0 +1,14000 @@
+Index: openssl/Configure
+diff -u openssl/Configure:1.1.2.1 openssl/Configure:1.5
+--- openssl/Configure:1.1.2.1 Fri Sep 12 14:47:00 2008
++++ openssl/Configure Tue Dec 16 14:12:43 2008
+@@ -10,7 +10,7 @@
+
+ # see INSTALL for instructions.
+
+-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
++my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
+
+ # Options:
+ #
+@@ -19,6 +19,9 @@
+ # --prefix prefix for the OpenSSL include, lib and bin directories
+ # (Default: the OPENSSLDIR directory)
+ #
++# --pk11-libname PKCS#11 library name.
++# (Default: none)
++#
+ # --install_prefix Additional prefix for package builders (empty by
+ # default). This needn't be set in advance, you can
+ # just as well use "make INSTALL_PREFIX=/whatever install".
+@@ -322,7 +325,7 @@
+ "linux-ppc", "gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL::linux_ppc32.o::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+ #### IA-32 targets...
+ "linux-ia32-icc", "icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+-"linux-elf", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
++"linux-elf", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+ "linux-aout", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}",
+ ####
+ "linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+@@ -573,6 +576,9 @@
+ my $idx_ranlib = $idx++;
+ my $idx_arflags = $idx++;
+
++# PKCS#11 engine patch
++my $pk11_libname="";
++
+ my $prefix="";
+ my $openssldir="";
+ my $exe_ext="";
+@@ -755,6 +761,10 @@
+ {
+ $flags.=$_." ";
+ }
++ elsif (/^--pk11-libname=(.*)$/)
++ {
++ $pk11_libname=$1;
++ }
+ elsif (/^--prefix=(.*)$/)
+ {
+ $prefix=$1;
+@@ -878,6 +888,13 @@
+ exit 0;
+ }
+
++if (! $pk11_libname)
++ {
++ print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
++ print STDERR "See README.pkcs11 for more information.\n";
++ exit 1;
++ }
++
+ if ($target =~ m/^CygWin32(-.*)$/) {
+ $target = "Cygwin".$1;
+ }
+@@ -1006,6 +1023,8 @@
+ if ($flags ne "") { $cflags="$flags$cflags"; }
+ else { $no_user_cflags=1; }
+
++$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
++
+ # Kerberos settings. The flavor must be provided from outside, either through
+ # the script "config" or manually.
+ if (!$no_krb5)
+@@ -1348,6 +1367,7 @@
+ s/^VERSION=.*/VERSION=$version/;
+ s/^MAJOR=.*/MAJOR=$major/;
+ s/^MINOR=.*/MINOR=$minor/;
++ s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
+ s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
+ s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
+ s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
+Index: openssl/Makefile.org
+diff -u openssl/Makefile.org:1.1.2.1 openssl/Makefile.org:1.2
+--- openssl/Makefile.org:1.1.2.1 Thu Apr 3 23:03:39 2008
++++ openssl/Makefile.org Fri Aug 29 16:19:02 2008
+@@ -26,6 +26,9 @@
+ INSTALL_PREFIX=
+ INSTALLTOP=/usr/local/ssl
+
++# You must set this through --pk11-libname configure option.
++PK11_LIB_LOCATION=
++
+ # Do not edit this manually. Use Configure --openssldir=DIR do change this!
+ OPENSSLDIR=/usr/local/ssl
+
+Index: openssl/README.pkcs11
+diff -u /dev/null openssl/README.pkcs11:1.4
+--- /dev/null Wed Sep 2 11:37:22 2009
++++ openssl/README.pkcs11 Mon Dec 15 12:59:11 2008
+@@ -0,0 +1,218 @@
++PKCS#11 engine support for OpenSSL 0.9.8i
++=========================================
++
++[December 2, 2008]
++
++Contents:
++
++Overview
++Revisions of patch for 0.9.8 branch
++FAQs
++Feedback
++
++Overview
++========
++
++This patch containing code available in OpenSolaris adds support for PKCS#11
++engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
++OpenSSL 0.9.8i source code distribution as shipped by OpenSSL.Org. Your system
++must provide PKCS#11 backend otherwise the patch is useless. You provide the
++PKCS#11 library name during the build configuration phase, see below.
++
++Patch can be applied like this:
++
++ # NOTE: use gtar if on Solaris
++ tar xfzv openssl-0.9.8i.tar.gz
++ # now download the patch to the current directory
++ # ...
++ cd openssl-0.9.8i
++ # NOTE: use gpatch if on Solaris
++ patch -p1 < ../pkcs11_engine-0.9.8i.patch.2008-12-02
++
++It is designed to support pure acceleration for RSA, DSA, DH and all the
++symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
++except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
++
++According to the PKCS#11 providers installed on your machine, it can support
++following mechanisms:
++
++ RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
++ AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
++ AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
++ SHA256, SHA384, SHA512
++
++Note that for AES counter mode the application must provide their own EVP
++functions since OpenSSL doesn't support counter mode through EVP yet. You may
++see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
++example of code that uses the PKCS#11 engine and deals with the fork-safety
++problem (see engine.c and packet.c files if interested).
++
+++------------------------------------------------------------------------------+
++| NOTE: this patch version does NOT contain experimental code for accessing |
++| RSA keys stored in PKCS#11 key stores by reference. Some problems were found |
++| (thanks to all who wrote me!) and due to my ENOTIME problem I may address |
++| those issues in the next version of the patch that will have that code back, |
++| hopefully fixed. |
+++------------------------------------------------------------------------------+
++
++You must provide the location of PKCS#11 library in your system to the
++configure script. You will be instructed to do that when you try to run the
++config script:
++
++ $ ./config
++ Operating system: i86pc-whatever-solaris2
++ Configuring for solaris-x86-cc
++ You must set --pk11-libname for PKCS#11 library.
++ See README.pkcs11 for more information.
++
++Taking openCryptoki project on Linux AMD64 box as an example, you would run
++configure script like this:
++
++ ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
++
++To check whether newly built openssl really supports PKCS#11 it's enough to run
++"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
++output. If you see no PKCS#11 engine support check that the built openssl binary
++and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
++
++This patch was tested on Solaris against PKCS#11 engine available from Solaris
++Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using
++PKCS#11 libraries from openCryptoki project (see openCryptoki website
++http://sourceforge.net/projects/opencryptoki for more information). Some Linux
++distributions even ship those libraries with the system. The patch should work
++on any system that is supported by OpenSSL itself and has functional PKCS#11
++library.
++
++The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
++(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
++copyrighted by RSA Security Inc., see pkcs11.h for more information.
++
++Other added/modified code in this patch is copyrighted by Sun Microsystems,
++Inc. and is released under the OpenSSL license (see LICENSE file for more
++information).
++
++Revisions of patch for 0.9.8 branch
++===================================
++
++2008-12-02
++- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
++
++ 6723504 more granular locking in PKCS#11 engine
++ 6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
++ 6710420 PKCS#11 engine source should be lint clean
++ 6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
++ it seriously
++ 6746712 PKCS#11 engine source code should be cstyle clean
++ 6731380 return codes of several functions are not checked in the PKCS#11
++ engine code
++ 6746735 PKCS#11 engine should use extended FILE space API
++ 6734038 Apache SSL web server using the pkcs11 engine fails to start if
++ meta slot is disabled
++
++2008-08-01
++- fixed bug
++
++ 6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
++ and digests
++
++- Solaris specific code for slot selection made automatic
++
++2008-07-29
++- update the patch to OpenSSL 0.9.8h version
++- pkcs11t.h updated to the latest version:
++
++ 6545665 make CKM_AES_CTR available to non-kernel users
++
++- fixed bugs in the engine code:
++
++ 6602801 PK11_SESSION cache has to employ reference counting scheme for
++ asymmetric key operations
++ 6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
++ atomically
++ 6607307 pkcs#11 engine can't read RSA private keys
++ 6652362 pk11_RSA_finish() is cutting corners
++ 6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
++ suboptimal way
++ 6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
++ resilient to destroy failures
++ 6667273 OpenSSL engine should not use free() but OPENSSL_free()
++ 6670363 PKCS#11 engine fails to reuse existing symmetric keys
++ 6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
++ 6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
++ of big numbers leading to failures
++ 6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
++ -1
++ 6706622 pk11_load_{pub,priv}key create corrupted RSA key references
++ 6707129 return values from BN_new() in pk11_DH_generate_key() are not
++ checked
++ 6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
++ structure reuse
++ 6707782 OpenSSL PKCS#11 engine pretends to be aware of
++ OPENSSL_NO_{RSA,DSA,DH}
++ defines but fails miserably
++ 6709966 make check_new_*() to return values to indicate cache hit/miss
++ 6705200 pk11_dh struct initialization in PKCS#11 engine is missing
++ generate_params parameter
++ 6709513 PKCS#11 engine sets IV length even for ECB modes
++ 6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
++ PKCS#11 engine
++ 6728871 PKCS#11 engine must reset global_session in pk11_finish()
++
++- new features and enhancements:
++
++ 6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
++ 6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
++ 6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
++ ciphers and digests
++
++2007-10-15
++- update for 0.9.8f version
++- update for "6607670 teach pkcs#11 engine how to use keys be reference"
++
++2007-10-02
++- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
++- draft for "6607307 pkcs#11 engine can't read RSA private keys"
++
++2007-09-26
++- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
++ significant performance drop
++- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
++
++2007-05-25
++- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
++
++2007-05-19
++- initial patch for 0.9.8e using latest OpenSolaris code
++
++FAQs
++====
++
++(1) my build failed on Linux distro with this error:
++
++../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
++hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
++
++ - don't use "no-threads" when configuring
++ - if you didn't then OpenSSL failed to create a threaded library by
++ default. You may manually edit Configure and try again. Look for the
++ architecture that Configure printed, for example:
++
++Configured for linux-elf.
++
++ - then edit Configure, find string "linux-elf" (inluding the quotes),
++ and add flags to support threads to the 4th column of the 2nd string.
++ If you build with GCC then adding "-pthread" should be enough. With
++ "linux-elf" as an example, you would add " -pthread" right after
++ "-D_REENTRANT", like this:
++
++....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
++
++
++Feedback
++========
++
++Please send feedback to security-discuss@opensolaris.org. The patch was
++created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
++
++Latest version should be always available on http://blogs.sun.com/janp.
++
+Index: openssl/crypto/opensslconf.h
+diff -u openssl/crypto/opensslconf.h:1.1.2.1 openssl/crypto/opensslconf.h:1.4
+--- openssl/crypto/opensslconf.h:1.1.2.1 Mon Sep 15 15:27:21 2008
++++ openssl/crypto/opensslconf.h Mon Dec 15 13:00:52 2008
+@@ -36,6 +36,9 @@
+ #endif
+
+ #endif /* OPENSSL_DOING_MAKEDEPEND */
++#ifndef OPENSSL_THREADS
++# define OPENSSL_THREADS
++#endif
+ #ifndef OPENSSL_NO_DYNAMIC_ENGINE
+ # define OPENSSL_NO_DYNAMIC_ENGINE
+ #endif
+@@ -77,6 +80,8 @@
+ # endif
+ #endif
+
++#define OPENSSL_CPUID_OBJ
++
+ /* crypto/opensslconf.h.in */
+
+ /* Generate 80386 code? */
+@@ -123,7 +128,7 @@
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+-#undef RC4_CHUNK
++#define RC4_CHUNK unsigned long
+ #endif
+ #endif
+
+@@ -131,7 +136,7 @@
+ /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+ #ifndef DES_LONG
+-#define DES_LONG unsigned long
++#define DES_LONG unsigned int
+ #endif
+ #endif
+
+@@ -145,9 +150,9 @@
+ /* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+-#undef SIXTY_FOUR_BIT_LONG
++#define SIXTY_FOUR_BIT_LONG
+ #undef SIXTY_FOUR_BIT
+-#define THIRTY_TWO_BIT
++#undef THIRTY_TWO_BIT
+ #undef SIXTEEN_BIT
+ #undef EIGHT_BIT
+ #endif
+@@ -161,7 +166,7 @@
+
+ #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+ #define CONFIG_HEADER_BF_LOCL_H
+-#undef BF_PTR
++#define BF_PTR2
+ #endif /* HEADER_BF_LOCL_H */
+
+ #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+@@ -191,7 +196,7 @@
+ /* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+ #ifndef DES_UNROLL
+-#undef DES_UNROLL
++#define DES_UNROLL
+ #endif
+
+ /* These default values were supplied by
+Index: openssl/crypto/engine/Makefile
+diff -u openssl/crypto/engine/Makefile:1.1.2.1 openssl/crypto/engine/Makefile:1.3
+--- openssl/crypto/engine/Makefile:1.1.2.1 Sun Sep 14 16:43:34 2008
++++ openssl/crypto/engine/Makefile Wed Oct 15 21:03:29 2008
+@@ -21,12 +21,14 @@
+ eng_table.c eng_pkey.c eng_fat.c eng_all.c \
+ tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
+ tb_cipher.c tb_digest.c \
+- eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
++ eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
++ hw_pk11.c hw_pk11_pub.c
+ LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
+ eng_table.o eng_pkey.o eng_fat.o eng_all.o \
+ tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
+ tb_cipher.o tb_digest.o \
+- eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
++ eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
++ hw_pk11.o hw_pk11_pub.o
+
+ SRC= $(LIBSRC)
+
+@@ -279,6 +281,54 @@
+ eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
+ eng_table.o: eng_table.c
++hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
++hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
++hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
++hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
++hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
++hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
++hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
++hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
++hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
++hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
++hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
++hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
++hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
++hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
++hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
++hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
++hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
++hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
++hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
++hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
++hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
++hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
++hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
++hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
++hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
++hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
++hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
++hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
++hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
++hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
++hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
++hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
++hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
++hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
++hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
++hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
++hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
++hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
++hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
++hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
++hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
++hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
++hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
++hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
++hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
++hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
++hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
++hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
+ tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
+ tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+Index: openssl/crypto/engine/cryptoki.h
+diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/cryptoki.h Thu Dec 18 00:14:12 2008
+@@ -0,0 +1,103 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License, Version 1.0 only
++ * (the "License"). You may not use this file except in compliance
++ * with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++/*
++ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++#ifndef _CRYPTOKI_H
++#define _CRYPTOKI_H
++
++/* ident "@(#)cryptoki.h 1.2 05/06/08 SMI" */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#ifndef CK_PTR
++#define CK_PTR *
++#endif
++
++#ifndef CK_DEFINE_FUNCTION
++#define CK_DEFINE_FUNCTION(returnType, name) returnType name
++#endif
++
++#ifndef CK_DECLARE_FUNCTION
++#define CK_DECLARE_FUNCTION(returnType, name) returnType name
++#endif
++
++#ifndef CK_DECLARE_FUNCTION_POINTER
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
++#endif
++
++#ifndef CK_CALLBACK_FUNCTION
++#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
++#endif
++
++#ifndef NULL_PTR
++#include <unistd.h> /* For NULL */
++#define NULL_PTR NULL
++#endif
++
++/*
++ * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
++ */
++#ifndef CK_DISABLE_TRUE_FALSE
++#define CK_DISABLE_TRUE_FALSE
++#ifndef TRUE
++#define TRUE 1
++#endif /* TRUE */
++#ifndef FALSE
++#define FALSE 0
++#endif /* FALSE */
++#endif /* CK_DISABLE_TRUE_FALSE */
++
++#undef CK_PKCS11_FUNCTION_INFO
++
++#include "pkcs11.h"
++
++/* Solaris specific functions */
++
++#include <stdlib.h>
++
++/*
++ * SUNW_C_GetMechSession will initialize the framework and do all
++ * the necessary PKCS#11 calls to create a session capable of
++ * providing operations on the requested mechanism
++ */
++CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
++ CK_SESSION_HANDLE_PTR hSession);
++
++/*
++ * SUNW_C_KeyToObject will create a secret key object for the given
++ * mechanism from the rawkey data.
++ */
++CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
++ CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
++ CK_OBJECT_HANDLE_PTR obj);
++
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _CRYPTOKI_H */
+Index: openssl/crypto/engine/eng_all.c
+diff -u openssl/crypto/engine/eng_all.c:1.1.2.1 openssl/crypto/engine/eng_all.c:1.2
+--- openssl/crypto/engine/eng_all.c:1.1.2.1 Wed Jun 4 18:01:39 2008
++++ openssl/crypto/engine/eng_all.c Wed Oct 15 15:39:48 2008
+@@ -110,6 +110,9 @@
+ #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+ ENGINE_load_capi();
+ #endif
++#ifndef OPENSSL_NO_HW_PKCS11
++ ENGINE_load_pk11();
++#endif
+ #endif
+ }
+
+Index: openssl/crypto/engine/engine.h
+diff -u openssl/crypto/engine/engine.h:1.1.2.1 openssl/crypto/engine/engine.h:1.2
+--- openssl/crypto/engine/engine.h:1.1.2.1 Wed Jun 4 18:01:40 2008
++++ openssl/crypto/engine/engine.h Wed Oct 15 15:39:48 2008
+@@ -337,6 +337,7 @@
+ void ENGINE_load_ubsec(void);
+ #endif
+ void ENGINE_load_cryptodev(void);
++void ENGINE_load_pk11(void);
+ void ENGINE_load_padlock(void);
+ void ENGINE_load_builtin_engines(void);
+ #ifndef OPENSSL_NO_CAPIENG
+Index: openssl/crypto/engine/hw_pk11-kp.c
+diff -u /dev/null openssl/crypto/engine/hw_pk11-kp.c:1.20
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/hw_pk11-kp.c Tue Sep 1 06:02:18 2009
+@@ -0,0 +1,1611 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_pk11.c */
++/*
++ * This product includes software developed by the OpenSSL Project for
++ * use in the OpenSSL Toolkit (http://www.openssl.org/).
++ *
++ * This project also referenced hw_pkcs11-0.9.7b.patch written by
++ * Afchine Madjlessi.
++ */
++/*
++ * ====================================================================
++ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ * software must display the following acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
++ *
++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
++ * endorse or promote products derived from this software without
++ * prior written permission. For written permission, please contact
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
++
++/* Modified to keep only RNG and RSA Sign */
++
++#ifdef OPENSSL_NO_RSA
++#error RSA is disabled
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++
++#include <openssl/e_os2.h>
++#include <openssl/crypto.h>
++#include <cryptlib.h>
++#include <openssl/engine.h>
++#include <openssl/dso.h>
++#include <openssl/err.h>
++#include <openssl/bn.h>
++#include <openssl/md5.h>
++#include <openssl/pem.h>
++#include <openssl/rsa.h>
++#include <openssl/rand.h>
++#include <openssl/objects.h>
++#include <openssl/x509.h>
++
++#ifdef OPENSSL_SYS_WIN32
++typedef int pid_t;
++#define getpid() GetCurrentProcessId()
++#define NOPTHREADS
++#ifndef NULL_PTR
++#define NULL_PTR NULL
++#endif
++#define CK_DEFINE_FUNCTION(returnType, name) \
++ returnType __declspec(dllexport) name
++#define CK_DECLARE_FUNCTION(returnType, name) \
++ returnType __declspec(dllimport) name
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ returnType __declspec(dllimport) (* name)
++#else
++#include <signal.h>
++#include <unistd.h>
++#include <dlfcn.h>
++#endif
++
++#ifndef NOPTHREADS
++#include <pthread.h>
++#endif
++
++#ifndef OPENSSL_NO_HW
++#ifndef OPENSSL_NO_HW_PK11
++
++/* label for debug messages printed on stderr */
++#define PK11_DBG "PKCS#11 ENGINE DEBUG"
++/* prints a lot of debug messages on stderr about slot selection process */
++#undef DEBUG_SLOT_SELECTION
++
++#ifndef OPENSSL_NO_DSA
++#define OPENSSL_NO_DSA
++#endif
++#ifndef OPENSSL_NO_DH
++#define OPENSSL_NO_DH
++#endif
++
++#ifdef OPENSSL_SYS_WIN32
++#pragma pack(push, cryptoki, 1)
++#include "cryptoki.h"
++#include "pkcs11.h"
++#pragma pack(pop, cryptoki)
++#else
++#include "cryptoki.h"
++#include "pkcs11.h"
++#endif
++#include "hw_pk11_err.c"
++
++/* PKCS#11 session caches and their locks for all operation types */
++static PK11_CACHE session_cache[OP_MAX];
++
++/*
++ * As stated in v2.20, 11.7 Object Management Function, in section for
++ * C_FindObjectsInit(), at most one search operation may be active at a given
++ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
++ * grouped together to form one atomic search operation. This is already
++ * ensured by the property of unique PKCS#11 session handle used for each
++ * PK11_SESSION object.
++ *
++ * This is however not the biggest concern - maintaining consistency of the
++ * underlying object store is more important. The same section of the spec also
++ * says that one thread can be in the middle of a search operation while another
++ * thread destroys the object matching the search template which would result in
++ * invalid handle returned from the search operation.
++ *
++ * Hence, the following locks are used for both protection of the object stores.
++ * They are also used for active list protection.
++ */
++#ifndef NOPTHREADS
++pthread_mutex_t *find_lock[OP_MAX] = { NULL };
++#endif
++
++/*
++ * lists of asymmetric key handles which are active (referenced by at least one
++ * PK11_SESSION structure, either held by a thread or present in free_session
++ * list) for given algorithm type
++ */
++PK11_active *active_list[OP_MAX] = { NULL };
++
++/*
++ * Create all secret key objects in a global session so that they are available
++ * to use for other sessions. These other sessions may be opened or closed
++ * without losing the secret key objects.
++ */
++static CK_SESSION_HANDLE global_session = CK_INVALID_HANDLE;
++
++/* ENGINE level stuff */
++static int pk11_init(ENGINE *e);
++static int pk11_library_init(ENGINE *e);
++static int pk11_finish(ENGINE *e);
++static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
++static int pk11_destroy(ENGINE *e);
++
++/* RAND stuff */
++static void pk11_rand_seed(const void *buf, int num);
++static void pk11_rand_add(const void *buf, int num, double add_entropy);
++static void pk11_rand_cleanup(void);
++static int pk11_rand_bytes(unsigned char *buf, int num);
++static int pk11_rand_status(void);
++
++/* These functions are also used in other files */
++PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
++void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
++
++/* active list manipulation functions used in this file */
++extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
++extern void pk11_free_active_list(PK11_OPTYPE type);
++
++int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
++int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
++int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
++
++/* Local helper functions */
++static int pk11_free_all_sessions(void);
++static int pk11_free_session_list(PK11_OPTYPE optype);
++static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
++static int pk11_destroy_object(CK_SESSION_HANDLE session,
++ CK_OBJECT_HANDLE oh);
++static const char *get_PK11_LIBNAME(void);
++static void free_PK11_LIBNAME(void);
++static long set_PK11_LIBNAME(const char *name);
++
++static int pk11_choose_slots(int *any_slot_found);
++
++static int pk11_init_all_locks(void);
++static void pk11_free_all_locks(void);
++
++#define TRY_OBJ_DESTROY(sess_hdl, obj_hdl, retval, uselock, alg_type) \
++ { \
++ if (uselock) \
++ LOCK_OBJSTORE(alg_type); \
++ if (pk11_active_delete(obj_hdl, alg_type) == 1) \
++ { \
++ retval = pk11_destroy_object(sess_hdl, obj_hdl); \
++ } \
++ if (uselock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ }
++
++#define TRY_OBJ_DELETE(sess_hdl, obj_hdl, retval, uselock, alg_type) \
++ { \
++ if (uselock) \
++ LOCK_OBJSTORE(alg_type); \
++ (void) pk11_active_delete(obj_hdl, alg_type); \
++ if (uselock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ }
++
++static CK_BBOOL pk11_have_rsa = CK_FALSE;
++static CK_BBOOL pk11_have_random = CK_FALSE;
++
++/*
++ * Initialization function. Sets up various PKCS#11 library components.
++ * The definitions for control commands specific to this engine
++ */
++#define PK11_CMD_SO_PATH ENGINE_CMD_BASE
++#define PK11_CMD_PIN (ENGINE_CMD_BASE+1)
++#define PK11_CMD_SLOT (ENGINE_CMD_BASE+2)
++static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
++ {
++ {
++ PK11_CMD_SO_PATH,
++ "SO_PATH",
++ "Specifies the path to the 'pkcs#11' shared library",
++ ENGINE_CMD_FLAG_STRING
++ },
++ {
++ PK11_CMD_PIN,
++ "PIN",
++ "Specifies the pin code",
++ ENGINE_CMD_FLAG_STRING
++ },
++ {
++ PK11_CMD_SLOT,
++ "SLOT",
++ "Specifies the slot (default is auto select)",
++ ENGINE_CMD_FLAG_NUMERIC,
++ },
++ {0, NULL, NULL, 0}
++ };
++
++
++static RAND_METHOD pk11_random =
++ {
++ pk11_rand_seed,
++ pk11_rand_bytes,
++ pk11_rand_cleanup,
++ pk11_rand_add,
++ pk11_rand_bytes,
++ pk11_rand_status
++ };
++
++
++/* Constants used when creating the ENGINE */
++static const char *engine_pk11_id = "pkcs11";
++static const char *engine_pk11_name = "PKCS #11 engine support";
++
++CK_FUNCTION_LIST_PTR pFuncList = NULL;
++static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
++
++/*
++ * These is the static string constant for the DSO file name and the function
++ * symbol names to bind to.
++ */
++static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
++
++static CK_SLOT_ID pubkey_SLOTID = 0;
++static CK_SLOT_ID rand_SLOTID = 0;
++static CK_SLOT_ID SLOTID = 0;
++char *pk11_pin = NULL;
++static CK_BBOOL pk11_library_initialized = FALSE;
++static CK_BBOOL pk11_atfork_initialized = FALSE;
++static int pk11_pid = 0;
++
++static DSO *pk11_dso = NULL;
++
++/* allocate and initialize all locks used by the engine itself */
++static int pk11_init_all_locks(void)
++ {
++#ifndef NOPTHREADS
++ int type;
++
++ find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
++ if (find_lock[OP_RSA] == NULL)
++ goto malloc_err;
++ (void) pthread_mutex_init(find_lock[OP_RSA], NULL);
++
++ for (type = 0; type < OP_MAX; type++)
++ {
++ session_cache[type].lock =
++ OPENSSL_malloc(sizeof (pthread_mutex_t));
++ if (session_cache[type].lock == NULL)
++ goto malloc_err;
++ (void) pthread_mutex_init(session_cache[type].lock, NULL);
++ }
++
++ return (1);
++
++malloc_err:
++ pk11_free_all_locks();
++ PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
++ return (0);
++#else
++ return (1);
++#endif
++ }
++
++static void pk11_free_all_locks(void)
++ {
++#ifndef NOPTHREADS
++ int type;
++
++ if (find_lock[OP_RSA] != NULL)
++ {
++ (void) pthread_mutex_destroy(find_lock[OP_RSA]);
++ OPENSSL_free(find_lock[OP_RSA]);
++ find_lock[OP_RSA] = NULL;
++ }
++
++ for (type = 0; type < OP_MAX; type++)
++ {
++ if (session_cache[type].lock != NULL)
++ {
++ (void) pthread_mutex_destroy(session_cache[type].lock);
++ OPENSSL_free(session_cache[type].lock);
++ session_cache[type].lock = NULL;
++ }
++ }
++#endif
++ }
++
++/*
++ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
++ */
++static int bind_pk11(ENGINE *e)
++ {
++ if (!pk11_library_initialized)
++ if (!pk11_library_init(e))
++ return (0);
++
++ if (!ENGINE_set_id(e, engine_pk11_id) ||
++ !ENGINE_set_name(e, engine_pk11_name))
++ return (0);
++
++ if (pk11_have_rsa == CK_TRUE)
++ {
++ if (!ENGINE_set_RSA(e, PK11_RSA()) ||
++ !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
++ !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++
++ if (pk11_have_random)
++ {
++ if (!ENGINE_set_RAND(e, &pk11_random))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered random\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++ if (!ENGINE_set_init_function(e, pk11_init) ||
++ !ENGINE_set_destroy_function(e, pk11_destroy) ||
++ !ENGINE_set_finish_function(e, pk11_finish) ||
++ !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
++ !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
++ return (0);
++
++ /* Ensure the pk11 error handling is set up */
++ ERR_load_pk11_strings();
++
++ return (1);
++ }
++
++/* Dynamic engine support is disabled at a higher level for Solaris */
++#ifdef ENGINE_DYNAMIC_SUPPORT
++static int bind_helper(ENGINE *e, const char *id)
++ {
++ if (id && (strcmp(id, engine_pk11_id) != 0))
++ return (0);
++
++ if (!bind_pk11(e))
++ return (0);
++
++ return (1);
++ }
++
++IMPLEMENT_DYNAMIC_CHECK_FN()
++IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
++
++#else
++static ENGINE *engine_pk11(void)
++ {
++ ENGINE *ret = ENGINE_new();
++
++ if (!ret)
++ return (NULL);
++
++ if (!bind_pk11(ret))
++ {
++ ENGINE_free(ret);
++ return (NULL);
++ }
++
++ return (ret);
++ }
++
++void
++ENGINE_load_pk11(void)
++ {
++ ENGINE *e_pk11 = NULL;
++
++ /*
++ * Do not use dynamic PKCS#11 library on Solaris due to
++ * security reasons. We will link it in statically.
++ */
++ /* Attempt to load PKCS#11 library */
++ if (!pk11_dso)
++ pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
++
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
++ return;
++ }
++
++ e_pk11 = engine_pk11();
++ if (!e_pk11)
++ {
++ DSO_free(pk11_dso);
++ pk11_dso = NULL;
++ return;
++ }
++
++ /*
++ * At this point, the pk11 shared library is either dynamically
++ * loaded or statically linked in. So, initialize the pk11
++ * library before calling ENGINE_set_default since the latter
++ * needs cipher and digest algorithm information
++ */
++ if (!pk11_library_init(e_pk11))
++ {
++ DSO_free(pk11_dso);
++ pk11_dso = NULL;
++ ENGINE_free(e_pk11);
++ return;
++ }
++
++ ENGINE_add(e_pk11);
++
++ ENGINE_free(e_pk11);
++ ERR_clear_error();
++ }
++#endif /* ENGINE_DYNAMIC_SUPPORT */
++
++/*
++ * These are the static string constants for the DSO file name and
++ * the function symbol names to bind to.
++ */
++static const char *PK11_LIBNAME = NULL;
++
++static const char *get_PK11_LIBNAME(void)
++ {
++ if (PK11_LIBNAME)
++ return (PK11_LIBNAME);
++
++ return (def_PK11_LIBNAME);
++ }
++
++static void free_PK11_LIBNAME(void)
++ {
++ if (PK11_LIBNAME)
++ OPENSSL_free((void*)PK11_LIBNAME);
++
++ PK11_LIBNAME = NULL;
++ }
++
++static long set_PK11_LIBNAME(const char *name)
++ {
++ free_PK11_LIBNAME();
++
++ return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
++ }
++
++/* acquire all engine specific mutexes before fork */
++static void pk11_fork_prepare(void)
++ {
++#ifndef NOPTHREADS
++ int i;
++
++ if (!pk11_library_initialized)
++ return;
++
++ LOCK_OBJSTORE(OP_RSA);
++ for (i = 0; i < OP_MAX; i++)
++ {
++ (void) pthread_mutex_lock(session_cache[i].lock);
++ }
++#endif
++ }
++
++/* release all engine specific mutexes */
++static void pk11_fork_parent(void)
++ {
++#ifndef NOPTHREADS
++ int i;
++
++ if (!pk11_library_initialized)
++ return;
++
++ for (i = OP_MAX - 1; i >= 0; i--)
++ {
++ (void) pthread_mutex_unlock(session_cache[i].lock);
++ }
++ UNLOCK_OBJSTORE(OP_RSA);
++#endif
++ }
++
++/*
++ * same situation as in parent - we need to unlock all locks to make them
++ * accessible to all threads.
++ */
++static void pk11_fork_child(void)
++ {
++#ifndef NOPTHREADS
++ int i;
++
++ if (!pk11_library_initialized)
++ return;
++
++ for (i = OP_MAX - 1; i >= 0; i--)
++ {
++ (void) pthread_mutex_unlock(session_cache[i].lock);
++ }
++ UNLOCK_OBJSTORE(OP_RSA);
++#endif
++ }
++
++/* Initialization function for the pk11 engine */
++static int pk11_init(ENGINE *e)
++{
++ return (pk11_library_init(e));
++}
++
++/*
++ * Initialization function. Sets up various PKCS#11 library components.
++ * It selects a slot based on predefined critiera. In the process, it also
++ * count how many ciphers and digests to support. Since the cipher and
++ * digest information is needed when setting default engine, this function
++ * needs to be called before calling ENGINE_set_default.
++ */
++/* ARGSUSED */
++static int pk11_library_init(ENGINE *e)
++ {
++ CK_C_GetFunctionList p;
++ CK_RV rv = CKR_OK;
++ CK_INFO info;
++ int any_slot_found;
++ int i;
++#ifndef OPENSSL_SYS_WIN32
++ struct sigaction sigint_act, sigterm_act, sighup_act;
++#endif
++
++ /*
++ * pk11_library_initialized is set to 0 in pk11_finish() which is called
++ * from ENGINE_finish(). However, if there is still at least one
++ * existing functional reference to the engine (see engine(3) for more
++ * information), pk11_finish() is skipped. For example, this can happen
++ * if an application forgets to clear one cipher context. In case of a
++ * fork() when the application is finishing the engine so that it can be
++ * reinitialized in the child, forgotten functional reference causes
++ * pk11_library_initialized to stay 1. In that case we need the PID
++ * check so that we properly initialize the engine again.
++ */
++ if (pk11_library_initialized)
++ {
++ if (pk11_pid == getpid())
++ {
++ return (1);
++ }
++ else
++ {
++ global_session = CK_INVALID_HANDLE;
++ /*
++ * free the locks first to prevent memory leak in case
++ * the application calls fork() without finishing the
++ * engine first.
++ */
++ pk11_free_all_locks();
++ }
++ }
++
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++ /* get the C_GetFunctionList function from the loaded library */
++ p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
++ PK11_GET_FUNCTION_LIST);
++ if (!p)
++ {
++ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++ /* get the full function list from the loaded library */
++ rv = p(&pFuncList);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
++ goto err;
++ }
++
++#ifndef OPENSSL_SYS_WIN32
++ /* Not all PKCS#11 library are signal safe! */
++
++ (void) memset(&sigint_act, 0, sizeof(sigint_act));
++ (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
++ (void) memset(&sighup_act, 0, sizeof(sighup_act));
++ (void) sigaction(SIGINT, NULL, &sigint_act);
++ (void) sigaction(SIGTERM, NULL, &sigterm_act);
++ (void) sigaction(SIGHUP, NULL, &sighup_act);
++#endif
++ rv = pFuncList->C_Initialize(NULL_PTR);
++#ifndef OPENSSL_SYS_WIN32
++ (void) sigaction(SIGINT, &sigint_act, NULL);
++ (void) sigaction(SIGTERM, &sigterm_act, NULL);
++ (void) sigaction(SIGHUP, &sighup_act, NULL);
++#endif
++ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_GetInfo(&info);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
++ goto err;
++ }
++
++ if (pk11_choose_slots(&any_slot_found) == 0)
++ goto err;
++
++ /*
++ * The library we use, set in def_PK11_LIBNAME, may not offer any
++ * slot(s). In that case, we must not proceed but we must not return an
++ * error. The reason is that applications that try to set up the PKCS#11
++ * engine don't exit on error during the engine initialization just
++ * because no slot was present.
++ */
++ if (any_slot_found == 0)
++ return (1);
++
++ if (global_session == CK_INVALID_HANDLE)
++ {
++ /* Open the global_session for the new process */
++ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &global_session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT,
++ PK11_R_OPENSESSION, rv);
++ goto err;
++ }
++ }
++
++ pk11_library_initialized = TRUE;
++ pk11_pid = getpid();
++ /*
++ * if initialization of the locks fails pk11_init_all_locks()
++ * will do the cleanup.
++ */
++ if (!pk11_init_all_locks())
++ goto err;
++ for (i = 0; i < OP_MAX; i++)
++ session_cache[i].head = NULL;
++ /*
++ * initialize active lists. We only use active lists
++ * for asymmetric ciphers.
++ */
++ for (i = 0; i < OP_MAX; i++)
++ active_list[i] = NULL;
++
++#ifndef NOPTHREADS
++ if (!pk11_atfork_initialized)
++ {
++ if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
++ pk11_fork_child) != 0)
++ {
++ PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
++ goto err;
++ }
++ pk11_atfork_initialized = TRUE;
++ }
++#endif
++
++ return (1);
++
++err:
++ return (0);
++ }
++
++/* Destructor (complements the "ENGINE_pk11()" constructor) */
++/* ARGSUSED */
++static int pk11_destroy(ENGINE *e)
++ {
++ free_PK11_LIBNAME();
++ ERR_unload_pk11_strings();
++ if (pk11_pin) {
++ memset(pk11_pin, 0, strlen(pk11_pin));
++ OPENSSL_free((void*)pk11_pin);
++ }
++ pk11_pin = NULL;
++ return (1);
++ }
++
++/*
++ * Termination function to clean up the session, the token, and the pk11
++ * library.
++ */
++/* ARGSUSED */
++static int pk11_finish(ENGINE *e)
++ {
++ int i;
++
++ if (pk11_pin) {
++ memset(pk11_pin, 0, strlen(pk11_pin));
++ OPENSSL_free((void*)pk11_pin);
++ }
++ pk11_pin = NULL;
++
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
++ goto err;
++ }
++
++ OPENSSL_assert(pFuncList != NULL);
++
++ if (pk11_free_all_sessions() == 0)
++ goto err;
++
++ /* free all active lists */
++ for (i = 0; i < OP_MAX; i++)
++ pk11_free_active_list(i);
++
++ pFuncList->C_CloseSession(global_session);
++ global_session = CK_INVALID_HANDLE;
++
++ /*
++ * Since we are part of a library (libcrypto.so), calling this function
++ * may have side-effects.
++ */
++#if 0
++ pFuncList->C_Finalize(NULL);
++#endif
++
++ if (!DSO_free(pk11_dso))
++ {
++ PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++ pk11_dso = NULL;
++ pFuncList = NULL;
++ pk11_library_initialized = FALSE;
++ pk11_pid = 0;
++ /*
++ * There is no way how to unregister atfork handlers (other than
++ * unloading the library) so we just free the locks. For this reason
++ * the atfork handlers check if the engine is initialized and bail out
++ * immediately if not. This is necessary in case a process finishes
++ * the engine before calling fork().
++ */
++ pk11_free_all_locks();
++
++ return (1);
++
++err:
++ return (0);
++ }
++
++/* Standard engine interface function to set the dynamic library path */
++/* ARGSUSED */
++static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
++ {
++ int initialized = ((pk11_dso == NULL) ? 0 : 1);
++
++ switch (cmd)
++ {
++ case PK11_CMD_SO_PATH:
++ if (p == NULL)
++ {
++ PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
++ return (0);
++ }
++
++ if (initialized)
++ {
++ PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
++ return (0);
++ }
++
++ return (set_PK11_LIBNAME((const char *)p));
++ case PK11_CMD_PIN:
++ if (pk11_pin) {
++ memset(pk11_pin, 0, strlen(pk11_pin));
++ OPENSSL_free((void*)pk11_pin);
++ }
++ pk11_pin = NULL;
++
++ if (p == NULL)
++ {
++ PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
++ return (0);
++ }
++
++ pk11_pin = BUF_strdup(p);
++ if (pk11_pin == NULL)
++ {
++ PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
++ return (0);
++ }
++ return (1);
++ case PK11_CMD_SLOT:
++ SLOTID = (CK_SLOT_ID)i;
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: slot set\n", PK11_DBG);
++#endif
++ return (1);
++ default:
++ break;
++ }
++
++ PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
++
++ return (0);
++ }
++
++
++/* Required function by the engine random interface. It does nothing here */
++static void pk11_rand_cleanup(void)
++ {
++ return;
++ }
++
++/* ARGSUSED */
++static void pk11_rand_add(const void *buf, int num, double add)
++ {
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RAND)) == NULL)
++ return;
++
++ /*
++ * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
++ * the calling functions do not care anyway
++ */
++ pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
++ pk11_return_session(sp, OP_RAND);
++
++ return;
++ }
++
++static void pk11_rand_seed(const void *buf, int num)
++ {
++ pk11_rand_add(buf, num, 0);
++ }
++
++static int pk11_rand_bytes(unsigned char *buf, int num)
++ {
++ CK_RV rv;
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RAND)) == NULL)
++ return (0);
++
++ rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
++ pk11_return_session(sp, OP_RAND);
++ return (0);
++ }
++
++ pk11_return_session(sp, OP_RAND);
++ return (1);
++ }
++
++/* Required function by the engine random interface. It does nothing here */
++static int pk11_rand_status(void)
++ {
++ return (1);
++ }
++
++/* Free all BIGNUM structures from PK11_SESSION. */
++static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
++ {
++ switch (optype)
++ {
++ case OP_RSA:
++ if (sp->opdata_rsa_n_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_n_num);
++ sp->opdata_rsa_n_num = NULL;
++ }
++ if (sp->opdata_rsa_e_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_e_num);
++ sp->opdata_rsa_e_num = NULL;
++ }
++ if (sp->opdata_rsa_d_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_d_num);
++ sp->opdata_rsa_d_num = NULL;
++ }
++ break;
++ default:
++ break;
++ }
++ }
++
++/*
++ * Get new PK11_SESSION structure ready for use. Every process must have
++ * its own freelist of PK11_SESSION structures so handle fork() here
++ * by destroying the old and creating new freelist.
++ * The returned PK11_SESSION structure is disconnected from the freelist.
++ */
++PK11_SESSION *
++pk11_get_session(PK11_OPTYPE optype)
++ {
++ PK11_SESSION *sp = NULL, *sp1, *freelist;
++#ifndef NOPTHREADS
++ pthread_mutex_t *freelist_lock = NULL;
++#endif
++ CK_RV rv;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ case OP_RAND:
++ case OP_DIGEST:
++ case OP_CIPHER:
++#ifndef NOPTHREADS
++ freelist_lock = session_cache[optype].lock;
++#endif
++ break;
++ default:
++ PK11err(PK11_F_GET_SESSION,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return (NULL);
++ }
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(freelist_lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ freelist = session_cache[optype].head;
++ sp = freelist;
++
++ /*
++ * If the free list is empty, allocate new unitialized (filled
++ * with zeroes) PK11_SESSION structure otherwise return first
++ * structure from the freelist.
++ */
++ if (sp == NULL)
++ {
++ if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
++ {
++ PK11err(PK11_F_GET_SESSION,
++ PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ (void) memset(sp, 0, sizeof (PK11_SESSION));
++ }
++ else
++ {
++ freelist = sp->next;
++ }
++
++ if (sp->pid != 0 && sp->pid != getpid())
++ {
++ /*
++ * We are a new process and thus need to free any inherited
++ * PK11_SESSION objects.
++ */
++ while ((sp1 = freelist) != NULL)
++ {
++ freelist = sp1->next;
++ /*
++ * NOTE: we do not want to call pk11_free_all_sessions()
++ * here because it would close underlying PKCS#11
++ * sessions and destroy all objects.
++ */
++ pk11_free_nums(sp1, optype);
++ OPENSSL_free(sp1);
++ }
++
++ /* we have to free the active list as well. */
++ pk11_free_active_list(optype);
++
++ /* Initialize the process */
++ rv = pFuncList->C_Initialize(NULL_PTR);
++ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
++ {
++ PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
++ rv);
++ OPENSSL_free(sp);
++ sp = NULL;
++ goto err;
++ }
++
++ /*
++ * Choose slot here since the slot table is different on this
++ * process. If we are here then we must have found at least one
++ * usable slot before so we don't need to check any_slot_found.
++ * See pk11_library_init()'s usage of this function for more
++ * information.
++ */
++ if (pk11_choose_slots(NULL) == 0)
++ goto err;
++
++ /* Open the global_session for the new process */
++ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &global_session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
++ rv);
++ OPENSSL_free(sp);
++ sp = NULL;
++ goto err;
++ }
++
++ /* It is an inherited session and needs re-initialization. */
++ if (pk11_setup_session(sp, optype) == 0)
++ {
++ OPENSSL_free(sp);
++ sp = NULL;
++ }
++ }
++ if (sp->pid == 0)
++ {
++ /* It is a new session and needs initialization. */
++ if (pk11_setup_session(sp, optype) == 0)
++ {
++ OPENSSL_free(sp);
++ sp = NULL;
++ }
++ }
++
++ /* set new head for the list of PK11_SESSION objects */
++ session_cache[optype].head = freelist;
++
++err:
++ if (sp != NULL)
++ sp->next = NULL;
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_unlock(freelist_lock);
++#else
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (sp);
++ }
++
++
++void
++pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
++ {
++#ifndef NOPTHREADS
++ pthread_mutex_t *freelist_lock;
++#endif
++ PK11_SESSION *freelist;
++
++ if (sp == NULL || sp->pid != getpid())
++ return;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ case OP_RAND:
++ case OP_DIGEST:
++ case OP_CIPHER:
++#ifndef NOPTHREADS
++ freelist_lock = session_cache[optype].lock;
++#endif
++ break;
++ default:
++ PK11err(PK11_F_RETURN_SESSION,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return;
++ }
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(freelist_lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ freelist = session_cache[optype].head;
++ sp->next = freelist;
++ session_cache[optype].head = sp;
++#ifndef NOPTHREADS
++ (void) pthread_mutex_unlock(freelist_lock);
++#else
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ }
++
++
++/* Destroy all objects. This function is called when the engine is finished */
++static int pk11_free_all_sessions()
++ {
++ int ret = 1;
++ int type;
++
++ (void) pk11_destroy_rsa_key_objects(NULL);
++
++ /*
++ * We try to release as much as we can but any error means that we will
++ * return 0 on exit.
++ */
++ for (type = 0; type < OP_MAX; type++)
++ {
++ if (pk11_free_session_list(type) == 0)
++ ret = 0;
++ }
++
++ return (ret);
++ }
++
++/*
++ * Destroy session structures from the linked list specified. Free as many
++ * sessions as possible but any failure in C_CloseSession() means that we
++ * return an error on return.
++ */
++static int pk11_free_session_list(PK11_OPTYPE optype)
++ {
++ CK_RV rv;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *freelist = NULL;
++ pid_t mypid = getpid();
++#ifndef NOPTHREADS
++ pthread_mutex_t *freelist_lock;
++#endif
++ int ret = 1;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ case OP_RAND:
++ case OP_DIGEST:
++ case OP_CIPHER:
++#ifndef NOPTHREADS
++ freelist_lock = session_cache[optype].lock;
++#endif
++ break;
++ default:
++ PK11err(PK11_F_FREE_ALL_SESSIONS,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return (0);
++ }
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(freelist_lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ freelist = session_cache[optype].head;
++ while ((sp = freelist) != NULL)
++ {
++ if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
++ {
++ rv = pFuncList->C_CloseSession(sp->session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
++ PK11_R_CLOSESESSION, rv);
++ ret = 0;
++ }
++ }
++ freelist = sp->next;
++ pk11_free_nums(sp, optype);
++ OPENSSL_free(sp);
++ }
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_unlock(freelist_lock);
++#else
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ return (ret);
++ }
++
++
++static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
++ {
++ CK_RV rv;
++ CK_SLOT_ID myslot;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ myslot = pubkey_SLOTID;
++ break;
++ case OP_RAND:
++ myslot = rand_SLOTID;
++ break;
++ default:
++ PK11err(PK11_F_SETUP_SESSION,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return (0);
++ }
++
++ sp->session = CK_INVALID_HANDLE;
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
++#endif /* DEBUG_SLOT_SELECTION */
++ rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &sp->session);
++ if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
++ {
++ /*
++ * We are probably a child process so force the
++ * reinitialize of the session
++ */
++ pk11_library_initialized = FALSE;
++ if (!pk11_library_init(NULL))
++ return (0);
++ rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &sp->session);
++ }
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
++ return (0);
++ }
++
++ sp->pid = getpid();
++
++ if (optype == OP_RSA)
++ {
++ sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_pub = NULL;
++ sp->opdata_rsa_n_num = NULL;
++ sp->opdata_rsa_e_num = NULL;
++ sp->opdata_rsa_priv = NULL;
++ sp->opdata_rsa_d_num = NULL;
++ }
++
++ return (1);
++ }
++
++/* Destroy RSA public key from single session. */
++int
++pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
++ {
++ TRY_OBJ_DESTROY(sp->session, sp->opdata_rsa_pub_key,
++ ret, uselock, OP_RSA);
++ sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_pub = NULL;
++ if (sp->opdata_rsa_n_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_n_num);
++ sp->opdata_rsa_n_num = NULL;
++ }
++ if (sp->opdata_rsa_e_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_e_num);
++ sp->opdata_rsa_e_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/* Destroy RSA private key from single session. */
++int
++pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
++ {
++ TRY_OBJ_DELETE(sp->session,
++ sp->opdata_rsa_priv_key,
++ ret, uselock, OP_RSA);
++ sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_priv = NULL;
++ if (sp->opdata_rsa_d_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_d_num);
++ sp->opdata_rsa_d_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/*
++ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
++ * objects in the free list.
++ */
++int
++pk11_destroy_rsa_key_objects(PK11_SESSION *session)
++ {
++ int ret = 1;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *local_free_session;
++ CK_BBOOL uselock = TRUE;
++
++ if (session != NULL)
++ local_free_session = session;
++ else
++ {
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(session_cache[OP_RSA].lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ local_free_session = session_cache[OP_RSA].head;
++ uselock = FALSE;
++ }
++
++ /*
++ * go through the list of sessions and delete key objects
++ */
++ while ((sp = local_free_session) != NULL)
++ {
++ local_free_session = sp->next;
++
++ /*
++ * Do not terminate list traversal if one of the
++ * destroy operations fails.
++ */
++ if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ }
++
++#ifndef NOPTHREADS
++ if (session == NULL)
++ (void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
++#else
++ if (session == NULL)
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (ret);
++ }
++
++static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh)
++ {
++ CK_RV rv;
++ rv = pFuncList->C_DestroyObject(session, oh);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
++ rv);
++ return (0);
++ }
++
++ return (1);
++ }
++
++
++/*
++ * Public key mechanisms optionally supported
++ *
++ * CKM_RSA_X_509
++ * CKM_RSA_PKCS
++ *
++ * The first slot that supports at least one of those mechanisms is chosen as a
++ * public key slot.
++ *
++ * The output of this function is a set of global variables indicating which
++ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
++ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
++ * variables carry information about which slot was chosen for (a) public key
++ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
++ */
++static int
++pk11_choose_slots(int *any_slot_found)
++ {
++ CK_SLOT_ID_PTR pSlotList = NULL_PTR;
++ CK_ULONG ulSlotCount = 0;
++ CK_MECHANISM_INFO mech_info;
++ CK_TOKEN_INFO token_info;
++ unsigned int i;
++ CK_RV rv;
++ CK_SLOT_ID best_slot_sofar = 0;
++ CK_BBOOL found_candidate_slot = CK_FALSE;
++ CK_SLOT_ID current_slot = 0;
++
++ /* let's initialize the output parameter */
++ if (any_slot_found != NULL)
++ *any_slot_found = 0;
++
++ /* Get slot list for memory allocation */
++ rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
++ return (0);
++ }
++
++ /* it's not an error if we didn't find any providers */
++ if (ulSlotCount == 0)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ return (1);
++ }
++
++ pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
++
++ if (pSlotList == NULL)
++ {
++ PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
++ return (0);
++ }
++
++ /* Get the slot list for processing */
++ rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
++ OPENSSL_free(pSlotList);
++ return (0);
++ }
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
++ fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
++
++ fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ for (i = 0; i < ulSlotCount; i++)
++ {
++ current_slot = pSlotList[i];
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
++#endif /* DEBUG_SLOT_SELECTION */
++ /* Check if slot has random support. */
++ rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
++ if (rv != CKR_OK)
++ continue;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ if (token_info.flags & CKF_RNG)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ pk11_have_random = CK_TRUE;
++ rand_SLOTID = current_slot;
++ break;
++ }
++ }
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ pubkey_SLOTID = pSlotList[0];
++ for (i = 0; i < ulSlotCount; i++)
++ {
++ CK_BBOOL slot_has_rsa = CK_FALSE;
++ current_slot = pSlotList[i];
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
++#endif /* DEBUG_SLOT_SELECTION */
++ rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
++ if (rv != CKR_OK)
++ continue;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ /*
++ * Check if this slot is capable of signing with CKM_RSA_PKCS.
++ */
++ rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
++ &mech_info);
++
++ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
++ {
++ slot_has_rsa = CK_TRUE;
++ }
++
++ if (!found_candidate_slot && slot_has_rsa)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: potential slot: %d\n", PK11_DBG, current_slot);
++#endif /* DEBUG_SLOT_SELECTION */
++ best_slot_sofar = current_slot;
++ pk11_have_rsa = slot_has_rsa;
++ found_candidate_slot = CK_TRUE;
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: setting found_candidate_slot to CK_TRUE\n",
++ PK11_DBG);
++ fprintf(stderr,
++ "%s: best so far slot: %d\n", PK11_DBG,
++ best_slot_sofar);
++ }
++ else
++ {
++ fprintf(stderr,
++ "%s: no rsa\n", PK11_DBG);
++ }
++#else
++ } /* if */
++#endif /* DEBUG_SLOT_SELECTION */
++ } /* for */
++
++ if (found_candidate_slot)
++ {
++ pubkey_SLOTID = best_slot_sofar;
++ }
++
++ /*SLOTID = pSlotList[0];*/
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
++ fprintf(stderr,
++ "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
++ fprintf(stderr,
++ "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
++ fprintf(stderr,
++ "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ if (pSlotList != NULL)
++ OPENSSL_free(pSlotList);
++
++ if (any_slot_found != NULL)
++ *any_slot_found = 1;
++ return (1);
++ }
++
++#endif /* OPENSSL_NO_HW_PK11 */
++#endif /* OPENSSL_NO_HW */
+Index: openssl/crypto/engine/hw_pk11.c
+diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.24
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/hw_pk11.c Fri Aug 28 06:31:09 2009
+@@ -0,0 +1,3916 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_pk11.c */
++/*
++ * This product includes software developed by the OpenSSL Project for
++ * use in the OpenSSL Toolkit (http://www.openssl.org/).
++ *
++ * This project also referenced hw_pkcs11-0.9.7b.patch written by
++ * Afchine Madjlessi.
++ */
++/*
++ * ====================================================================
++ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ * software must display the following acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
++ *
++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
++ * endorse or promote products derived from this software without
++ * prior written permission. For written permission, please contact
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++
++#include <openssl/e_os2.h>
++#include <openssl/crypto.h>
++#include <cryptlib.h>
++#include <openssl/engine.h>
++#include <openssl/dso.h>
++#include <openssl/err.h>
++#include <openssl/bn.h>
++#include <openssl/md5.h>
++#include <openssl/pem.h>
++#ifndef OPENSSL_NO_RSA
++#include <openssl/rsa.h>
++#endif
++#ifndef OPENSSL_NO_DSA
++#include <openssl/dsa.h>
++#endif
++#ifndef OPENSSL_NO_DH
++#include <openssl/dh.h>
++#endif
++#include <openssl/rand.h>
++#include <openssl/objects.h>
++#include <openssl/x509.h>
++#include <openssl/aes.h>
++
++#ifdef OPENSSL_SYS_WIN32
++typedef int pid_t;
++#define getpid() GetCurrentProcessId()
++#define NOPTHREADS
++#ifndef NULL_PTR
++#define NULL_PTR NULL
++#endif
++#define CK_DEFINE_FUNCTION(returnType, name) \
++ returnType __declspec(dllexport) name
++#define CK_DECLARE_FUNCTION(returnType, name) \
++ returnType __declspec(dllimport) name
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ returnType __declspec(dllimport) (* name)
++#else
++#include <signal.h>
++#include <unistd.h>
++#include <dlfcn.h>
++#endif
++
++#ifndef NOPTHREADS
++#include <pthread.h>
++#endif
++
++#ifndef OPENSSL_NO_HW
++#ifndef OPENSSL_NO_HW_PK11
++
++/* label for debug messages printed on stderr */
++#define PK11_DBG "PKCS#11 ENGINE DEBUG"
++/* prints a lot of debug messages on stderr about slot selection process */
++#undef DEBUG_SLOT_SELECTION
++/*
++ * Solaris specific code. See comment at check_hw_mechanisms() for more
++ * information.
++ */
++#if defined (__SVR4) && defined (__sun)
++#undef SOLARIS_HW_SLOT_SELECTION
++#endif
++
++/*
++ * AES counter mode is not supported in the OpenSSL EVP API yet and neither
++ * there are official OIDs for mechanisms based on this mode. With our changes,
++ * an application can define its own EVP calls for AES counter mode and then
++ * it can make use of hardware acceleration through this engine. However, it's
++ * better if we keep AES CTR support code under ifdef's.
++ */
++#define SOLARIS_AES_CTR
++
++#ifdef OPENSSL_SYS_WIN32
++#pragma pack(push, cryptoki, 1)
++#include "cryptoki.h"
++#include "pkcs11.h"
++#pragma pack(pop, cryptoki)
++#else
++#include "cryptoki.h"
++#include "pkcs11.h"
++#endif
++#include "hw_pk11_err.c"
++
++#ifdef SOLARIS_AES_CTR
++/*
++ * NIDs for AES counter mode that will be defined during the engine
++ * initialization.
++ */
++int NID_aes_128_ctr = NID_undef;
++int NID_aes_192_ctr = NID_undef;
++int NID_aes_256_ctr = NID_undef;
++#endif /* SOLARIS_AES_CTR */
++
++#ifdef SOLARIS_HW_SLOT_SELECTION
++/*
++ * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
++ * library. See comment at check_hw_mechanisms() for more information.
++ */
++int *hw_cnids;
++int *hw_dnids;
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++
++/* PKCS#11 session caches and their locks for all operation types */
++static PK11_CACHE session_cache[OP_MAX];
++
++/*
++ * As stated in v2.20, 11.7 Object Management Function, in section for
++ * C_FindObjectsInit(), at most one search operation may be active at a given
++ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
++ * grouped together to form one atomic search operation. This is already
++ * ensured by the property of unique PKCS#11 session handle used for each
++ * PK11_SESSION object.
++ *
++ * This is however not the biggest concern - maintaining consistency of the
++ * underlying object store is more important. The same section of the spec also
++ * says that one thread can be in the middle of a search operation while another
++ * thread destroys the object matching the search template which would result in
++ * invalid handle returned from the search operation.
++ *
++ * Hence, the following locks are used for both protection of the object stores.
++ * They are also used for active list protection.
++ */
++#ifndef NOPTHREADS
++pthread_mutex_t *find_lock[OP_MAX] = { NULL };
++#endif
++
++/*
++ * lists of asymmetric key handles which are active (referenced by at least one
++ * PK11_SESSION structure, either held by a thread or present in free_session
++ * list) for given algorithm type
++ */
++PK11_active *active_list[OP_MAX] = { NULL };
++
++/*
++ * Create all secret key objects in a global session so that they are available
++ * to use for other sessions. These other sessions may be opened or closed
++ * without losing the secret key objects.
++ */
++static CK_SESSION_HANDLE global_session = CK_INVALID_HANDLE;
++
++/* ENGINE level stuff */
++static int pk11_init(ENGINE *e);
++static int pk11_library_init(ENGINE *e);
++static int pk11_finish(ENGINE *e);
++static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
++static int pk11_destroy(ENGINE *e);
++
++/* RAND stuff */
++static void pk11_rand_seed(const void *buf, int num);
++static void pk11_rand_add(const void *buf, int num, double add_entropy);
++static void pk11_rand_cleanup(void);
++static int pk11_rand_bytes(unsigned char *buf, int num);
++static int pk11_rand_status(void);
++
++/* These functions are also used in other files */
++PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
++void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
++
++/* active list manipulation functions used in this file */
++extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
++extern void pk11_free_active_list(PK11_OPTYPE type);
++
++#ifndef OPENSSL_NO_RSA
++int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
++int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
++int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
++#endif
++#ifndef OPENSSL_NO_DSA
++int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
++int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
++int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
++#endif
++#ifndef OPENSSL_NO_DH
++int pk11_destroy_dh_key_objects(PK11_SESSION *session);
++int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
++#endif
++
++/* Local helper functions */
++static int pk11_free_all_sessions(void);
++static int pk11_free_session_list(PK11_OPTYPE optype);
++static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
++static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
++static int pk11_destroy_object(CK_SESSION_HANDLE session,
++ CK_OBJECT_HANDLE oh);
++static const char *get_PK11_LIBNAME(void);
++static void free_PK11_LIBNAME(void);
++static long set_PK11_LIBNAME(const char *name);
++
++/* Symmetric cipher and digest support functions */
++static int cipher_nid_to_pk11(int nid);
++#ifdef SOLARIS_AES_CTR
++static int pk11_add_NID(char *sn, char *ln);
++static int pk11_add_aes_ctr_NIDs(void);
++#endif /* SOLARIS_AES_CTR */
++static int pk11_usable_ciphers(const int **nids);
++static int pk11_usable_digests(const int **nids);
++static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
++ const unsigned char *iv, int enc);
++static int pk11_cipher_final(PK11_SESSION *sp);
++static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
++ const unsigned char *in, unsigned int inl);
++static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
++static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
++ const int **nids, int nid);
++static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
++ const int **nids, int nid);
++static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
++ const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
++static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
++ int key_len);
++static int md_nid_to_pk11(int nid);
++static int pk11_digest_init(EVP_MD_CTX *ctx);
++static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
++ size_t count);
++static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
++static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
++static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
++
++static int pk11_choose_slots(int *any_slot_found);
++static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
++ CK_SLOT_ID current_slot, int *current_slot_n_cipher,
++ int *local_cipher_nids);
++static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
++ CK_SLOT_ID current_slot, int *current_slot_n_digest,
++ int *local_digest_nids);
++static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
++ CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
++ int id);
++static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
++ CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
++ int id);
++
++static int pk11_init_all_locks(void);
++static void pk11_free_all_locks(void);
++
++#ifdef SOLARIS_HW_SLOT_SELECTION
++static int check_hw_mechanisms(void);
++static int nid_in_table(int nid, int *nid_table);
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++
++/* Index for the supported ciphers */
++enum pk11_cipher_id {
++ PK11_DES_CBC,
++ PK11_DES3_CBC,
++ PK11_DES_ECB,
++ PK11_DES3_ECB,
++ PK11_RC4,
++ PK11_AES_128_CBC,
++ PK11_AES_192_CBC,
++ PK11_AES_256_CBC,
++ PK11_AES_128_ECB,
++ PK11_AES_192_ECB,
++ PK11_AES_256_ECB,
++ PK11_BLOWFISH_CBC,
++#ifdef SOLARIS_AES_CTR
++ PK11_AES_128_CTR,
++ PK11_AES_192_CTR,
++ PK11_AES_256_CTR,
++#endif /* SOLARIS_AES_CTR */
++ PK11_CIPHER_MAX
++};
++
++/* Index for the supported digests */
++enum pk11_digest_id {
++ PK11_MD5,
++ PK11_SHA1,
++ PK11_SHA224,
++ PK11_SHA256,
++ PK11_SHA384,
++ PK11_SHA512,
++ PK11_DIGEST_MAX
++};
++
++#define TRY_OBJ_DESTROY(sess_hdl, obj_hdl, retval, uselock, alg_type) \
++ { \
++ if (uselock) \
++ LOCK_OBJSTORE(alg_type); \
++ if (pk11_active_delete(obj_hdl, alg_type) == 1) \
++ { \
++ retval = pk11_destroy_object(sess_hdl, obj_hdl); \
++ } \
++ if (uselock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ }
++
++#define TRY_OBJ_DELETE(sess_hdl, obj_hdl, retval, uselock, alg_type) \
++ { \
++ if (uselock) \
++ LOCK_OBJSTORE(alg_type); \
++ (void) pk11_active_delete(obj_hdl, alg_type); \
++ if (uselock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ }
++
++static int cipher_nids[PK11_CIPHER_MAX];
++static int digest_nids[PK11_DIGEST_MAX];
++static int cipher_count = 0;
++static int digest_count = 0;
++static CK_BBOOL pk11_have_rsa = CK_FALSE;
++static CK_BBOOL pk11_have_recover = CK_FALSE;
++static CK_BBOOL pk11_have_dsa = CK_FALSE;
++static CK_BBOOL pk11_have_dh = CK_FALSE;
++static CK_BBOOL pk11_have_random = CK_FALSE;
++
++typedef struct PK11_CIPHER_st
++ {
++ enum pk11_cipher_id id;
++ int nid;
++ int iv_len;
++ int key_len;
++ CK_KEY_TYPE key_type;
++ CK_MECHANISM_TYPE mech_type;
++ } PK11_CIPHER;
++
++static PK11_CIPHER ciphers[] =
++ {
++ { PK11_DES_CBC, NID_des_cbc, 8, 8,
++ CKK_DES, CKM_DES_CBC, },
++ { PK11_DES3_CBC, NID_des_ede3_cbc, 8, 24,
++ CKK_DES3, CKM_DES3_CBC, },
++ { PK11_DES_ECB, NID_des_ecb, 0, 8,
++ CKK_DES, CKM_DES_ECB, },
++ { PK11_DES3_ECB, NID_des_ede3_ecb, 0, 24,
++ CKK_DES3, CKM_DES3_ECB, },
++ { PK11_RC4, NID_rc4, 0, 16,
++ CKK_RC4, CKM_RC4, },
++ { PK11_AES_128_CBC, NID_aes_128_cbc, 16, 16,
++ CKK_AES, CKM_AES_CBC, },
++ { PK11_AES_192_CBC, NID_aes_192_cbc, 16, 24,
++ CKK_AES, CKM_AES_CBC, },
++ { PK11_AES_256_CBC, NID_aes_256_cbc, 16, 32,
++ CKK_AES, CKM_AES_CBC, },
++ { PK11_AES_128_ECB, NID_aes_128_ecb, 0, 16,
++ CKK_AES, CKM_AES_ECB, },
++ { PK11_AES_192_ECB, NID_aes_192_ecb, 0, 24,
++ CKK_AES, CKM_AES_ECB, },
++ { PK11_AES_256_ECB, NID_aes_256_ecb, 0, 32,
++ CKK_AES, CKM_AES_ECB, },
++ { PK11_BLOWFISH_CBC, NID_bf_cbc, 8, 16,
++ CKK_BLOWFISH, CKM_BLOWFISH_CBC, },
++#ifdef SOLARIS_AES_CTR
++ /* we don't know the correct NIDs until the engine is initialized */
++ { PK11_AES_128_CTR, NID_undef, 16, 16,
++ CKK_AES, CKM_AES_CTR, },
++ { PK11_AES_192_CTR, NID_undef, 16, 24,
++ CKK_AES, CKM_AES_CTR, },
++ { PK11_AES_256_CTR, NID_undef, 16, 32,
++ CKK_AES, CKM_AES_CTR, },
++#endif /* SOLARIS_AES_CTR */
++ };
++
++typedef struct PK11_DIGEST_st
++ {
++ enum pk11_digest_id id;
++ int nid;
++ CK_MECHANISM_TYPE mech_type;
++ } PK11_DIGEST;
++
++static PK11_DIGEST digests[] =
++ {
++ {PK11_MD5, NID_md5, CKM_MD5, },
++ {PK11_SHA1, NID_sha1, CKM_SHA_1, },
++ {PK11_SHA224, NID_sha224, CKM_SHA224, },
++ {PK11_SHA256, NID_sha256, CKM_SHA256, },
++ {PK11_SHA384, NID_sha384, CKM_SHA384, },
++ {PK11_SHA512, NID_sha512, CKM_SHA512, },
++ {0, NID_undef, 0xFFFF, },
++ };
++
++/*
++ * Structure to be used for the cipher_data/md_data in
++ * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
++ * session in multiple cipher_update calls
++ */
++typedef struct PK11_CIPHER_STATE_st
++ {
++ PK11_SESSION *sp;
++ } PK11_CIPHER_STATE;
++
++
++/*
++ * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
++ * called when libcrypto requests a cipher NID.
++ *
++ * Note how the PK11_CIPHER_STATE is used here.
++ */
++
++/* DES CBC EVP */
++static const EVP_CIPHER pk11_des_cbc =
++ {
++ NID_des_cbc,
++ 8, 8, 8,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++/* 3DES CBC EVP */
++static const EVP_CIPHER pk11_3des_cbc =
++ {
++ NID_des_ede3_cbc,
++ 8, 24, 8,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++/*
++ * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
++ * get_asn1_parameters fields are set to NULL.
++ */
++static const EVP_CIPHER pk11_des_ecb =
++ {
++ NID_des_ecb,
++ 8, 8, 8,
++ EVP_CIPH_ECB_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ NULL,
++ NULL,
++ NULL
++ };
++
++static const EVP_CIPHER pk11_3des_ecb =
++ {
++ NID_des_ede3_ecb,
++ 8, 24, 8,
++ EVP_CIPH_ECB_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ NULL,
++ NULL,
++ NULL
++ };
++
++
++static const EVP_CIPHER pk11_aes_128_cbc =
++ {
++ NID_aes_128_cbc,
++ 16, 16, 16,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++static const EVP_CIPHER pk11_aes_192_cbc =
++ {
++ NID_aes_192_cbc,
++ 16, 24, 16,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++static const EVP_CIPHER pk11_aes_256_cbc =
++ {
++ NID_aes_256_cbc,
++ 16, 32, 16,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++/*
++ * ECB modes don't use IV so that's why set_asn1_parameters and
++ * get_asn1_parameters are set to NULL.
++ */
++static const EVP_CIPHER pk11_aes_128_ecb =
++ {
++ NID_aes_128_ecb,
++ 16, 16, 0,
++ EVP_CIPH_ECB_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ NULL,
++ NULL,
++ NULL
++ };
++
++static const EVP_CIPHER pk11_aes_192_ecb =
++ {
++ NID_aes_192_ecb,
++ 16, 24, 0,
++ EVP_CIPH_ECB_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ NULL,
++ NULL,
++ NULL
++ };
++
++static const EVP_CIPHER pk11_aes_256_ecb =
++ {
++ NID_aes_256_ecb,
++ 16, 32, 0,
++ EVP_CIPH_ECB_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ NULL,
++ NULL,
++ NULL
++ };
++
++#ifdef SOLARIS_AES_CTR
++/*
++ * NID_undef's will be changed to the AES counter mode NIDs as soon they are
++ * created in pk11_library_init(). Note that the need to change these structures
++ * is the reason why we don't define them with the const keyword.
++ */
++static EVP_CIPHER pk11_aes_128_ctr =
++ {
++ NID_undef,
++ 16, 16, 16,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++static EVP_CIPHER pk11_aes_192_ctr =
++ {
++ NID_undef,
++ 16, 24, 16,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++static EVP_CIPHER pk11_aes_256_ctr =
++ {
++ NID_undef,
++ 16, 32, 16,
++ EVP_CIPH_CBC_MODE,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++#endif /* SOLARIS_AES_CTR */
++
++static const EVP_CIPHER pk11_bf_cbc =
++ {
++ NID_bf_cbc,
++ 8, 16, 8,
++ EVP_CIPH_VARIABLE_LENGTH,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ EVP_CIPHER_set_asn1_iv,
++ EVP_CIPHER_get_asn1_iv,
++ NULL
++ };
++
++static const EVP_CIPHER pk11_rc4 =
++ {
++ NID_rc4,
++ 1, 16, 0,
++ EVP_CIPH_VARIABLE_LENGTH,
++ pk11_cipher_init,
++ pk11_cipher_do_cipher,
++ pk11_cipher_cleanup,
++ sizeof (PK11_CIPHER_STATE),
++ NULL,
++ NULL,
++ NULL
++ };
++
++static const EVP_MD pk11_md5 =
++ {
++ NID_md5,
++ NID_md5WithRSAEncryption,
++ MD5_DIGEST_LENGTH,
++ 0,
++ pk11_digest_init,
++ pk11_digest_update,
++ pk11_digest_final,
++ pk11_digest_copy,
++ pk11_digest_cleanup,
++ EVP_PKEY_RSA_method,
++ MD5_CBLOCK,
++ sizeof (PK11_CIPHER_STATE),
++ };
++
++static const EVP_MD pk11_sha1 =
++ {
++ NID_sha1,
++ NID_sha1WithRSAEncryption,
++ SHA_DIGEST_LENGTH,
++ 0,
++ pk11_digest_init,
++ pk11_digest_update,
++ pk11_digest_final,
++ pk11_digest_copy,
++ pk11_digest_cleanup,
++ EVP_PKEY_RSA_method,
++ SHA_CBLOCK,
++ sizeof (PK11_CIPHER_STATE),
++ };
++
++static const EVP_MD pk11_sha224 =
++ {
++ NID_sha224,
++ NID_sha224WithRSAEncryption,
++ SHA224_DIGEST_LENGTH,
++ 0,
++ pk11_digest_init,
++ pk11_digest_update,
++ pk11_digest_final,
++ pk11_digest_copy,
++ pk11_digest_cleanup,
++ EVP_PKEY_RSA_method,
++ /* SHA-224 uses the same cblock size as SHA-256 */
++ SHA256_CBLOCK,
++ sizeof (PK11_CIPHER_STATE),
++ };
++
++static const EVP_MD pk11_sha256 =
++ {
++ NID_sha256,
++ NID_sha256WithRSAEncryption,
++ SHA256_DIGEST_LENGTH,
++ 0,
++ pk11_digest_init,
++ pk11_digest_update,
++ pk11_digest_final,
++ pk11_digest_copy,
++ pk11_digest_cleanup,
++ EVP_PKEY_RSA_method,
++ SHA256_CBLOCK,
++ sizeof (PK11_CIPHER_STATE),
++ };
++
++static const EVP_MD pk11_sha384 =
++ {
++ NID_sha384,
++ NID_sha384WithRSAEncryption,
++ SHA384_DIGEST_LENGTH,
++ 0,
++ pk11_digest_init,
++ pk11_digest_update,
++ pk11_digest_final,
++ pk11_digest_copy,
++ pk11_digest_cleanup,
++ EVP_PKEY_RSA_method,
++ /* SHA-384 uses the same cblock size as SHA-512 */
++ SHA512_CBLOCK,
++ sizeof (PK11_CIPHER_STATE),
++ };
++
++static const EVP_MD pk11_sha512 =
++ {
++ NID_sha512,
++ NID_sha512WithRSAEncryption,
++ SHA512_DIGEST_LENGTH,
++ 0,
++ pk11_digest_init,
++ pk11_digest_update,
++ pk11_digest_final,
++ pk11_digest_copy,
++ pk11_digest_cleanup,
++ EVP_PKEY_RSA_method,
++ SHA512_CBLOCK,
++ sizeof (PK11_CIPHER_STATE),
++ };
++
++/*
++ * Initialization function. Sets up various PKCS#11 library components.
++ * The definitions for control commands specific to this engine
++ */
++#define PK11_CMD_SO_PATH ENGINE_CMD_BASE
++#define PK11_CMD_PIN (ENGINE_CMD_BASE+1)
++#define PK11_CMD_SLOT (ENGINE_CMD_BASE+2)
++static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
++ {
++ {
++ PK11_CMD_SO_PATH,
++ "SO_PATH",
++ "Specifies the path to the 'pkcs#11' shared library",
++ ENGINE_CMD_FLAG_STRING
++ },
++ {
++ PK11_CMD_PIN,
++ "PIN",
++ "Specifies the pin code",
++ ENGINE_CMD_FLAG_STRING
++ },
++ {
++ PK11_CMD_SLOT,
++ "SLOT",
++ "Specifies the slot (default is auto select)",
++ ENGINE_CMD_FLAG_NUMERIC,
++ },
++ {0, NULL, NULL, 0}
++ };
++
++
++static RAND_METHOD pk11_random =
++ {
++ pk11_rand_seed,
++ pk11_rand_bytes,
++ pk11_rand_cleanup,
++ pk11_rand_add,
++ pk11_rand_bytes,
++ pk11_rand_status
++ };
++
++
++/* Constants used when creating the ENGINE */
++static const char *engine_pk11_id = "pkcs11";
++static const char *engine_pk11_name = "PKCS #11 engine support";
++
++CK_FUNCTION_LIST_PTR pFuncList = NULL;
++static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
++
++/*
++ * These is the static string constant for the DSO file name and the function
++ * symbol names to bind to.
++ */
++static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
++
++static CK_BBOOL true = TRUE;
++static CK_BBOOL false = FALSE;
++static CK_SLOT_ID pubkey_SLOTID = 0;
++static CK_SLOT_ID rand_SLOTID = 0;
++static CK_SLOT_ID SLOTID = 0;
++char *pk11_pin = NULL;
++static CK_BBOOL pk11_library_initialized = FALSE;
++static CK_BBOOL pk11_atfork_initialized = FALSE;
++static int pk11_pid = 0;
++
++static DSO *pk11_dso = NULL;
++
++/* allocate and initialize all locks used by the engine itself */
++static int pk11_init_all_locks(void)
++ {
++#ifndef NOPTHREADS
++ int type;
++
++#ifndef OPENSSL_NO_RSA
++ find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
++ if (find_lock[OP_RSA] == NULL)
++ goto malloc_err;
++ (void) pthread_mutex_init(find_lock[OP_RSA], NULL);
++#endif /* OPENSSL_NO_RSA */
++
++#ifndef OPENSSL_NO_DSA
++ find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
++ if (find_lock[OP_DSA] == NULL)
++ goto malloc_err;
++ (void) pthread_mutex_init(find_lock[OP_DSA], NULL);
++#endif /* OPENSSL_NO_DSA */
++
++#ifndef OPENSSL_NO_DH
++ find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
++ if (find_lock[OP_DH] == NULL)
++ goto malloc_err;
++ (void) pthread_mutex_init(find_lock[OP_DH], NULL);
++#endif /* OPENSSL_NO_DH */
++
++ for (type = 0; type < OP_MAX; type++)
++ {
++ session_cache[type].lock =
++ OPENSSL_malloc(sizeof (pthread_mutex_t));
++ if (session_cache[type].lock == NULL)
++ goto malloc_err;
++ (void) pthread_mutex_init(session_cache[type].lock, NULL);
++ }
++
++ return (1);
++
++malloc_err:
++ pk11_free_all_locks();
++ PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
++ return (0);
++#else
++ return (1);
++#endif
++ }
++
++static void pk11_free_all_locks(void)
++ {
++#ifndef NOPTHREADS
++ int type;
++
++#ifndef OPENSSL_NO_RSA
++ if (find_lock[OP_RSA] != NULL)
++ {
++ (void) pthread_mutex_destroy(find_lock[OP_RSA]);
++ OPENSSL_free(find_lock[OP_RSA]);
++ find_lock[OP_RSA] = NULL;
++ }
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++ if (find_lock[OP_DSA] != NULL)
++ {
++ (void) pthread_mutex_destroy(find_lock[OP_DSA]);
++ OPENSSL_free(find_lock[OP_DSA]);
++ find_lock[OP_DSA] = NULL;
++ }
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++ if (find_lock[OP_DH] != NULL)
++ {
++ (void) pthread_mutex_destroy(find_lock[OP_DH]);
++ OPENSSL_free(find_lock[OP_DH]);
++ find_lock[OP_DH] = NULL;
++ }
++#endif /* OPENSSL_NO_DH */
++
++ for (type = 0; type < OP_MAX; type++)
++ {
++ if (session_cache[type].lock != NULL)
++ {
++ (void) pthread_mutex_destroy(session_cache[type].lock);
++ OPENSSL_free(session_cache[type].lock);
++ session_cache[type].lock = NULL;
++ }
++ }
++#endif
++ }
++
++/*
++ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
++ */
++static int bind_pk11(ENGINE *e)
++ {
++#ifndef OPENSSL_NO_RSA
++ const RSA_METHOD *rsa = NULL;
++ RSA_METHOD *pk11_rsa = PK11_RSA();
++#endif /* OPENSSL_NO_RSA */
++ if (!pk11_library_initialized)
++ if (!pk11_library_init(e))
++ return (0);
++
++ if (!ENGINE_set_id(e, engine_pk11_id) ||
++ !ENGINE_set_name(e, engine_pk11_name) ||
++ !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
++ !ENGINE_set_digests(e, pk11_engine_digests))
++ return (0);
++#ifndef OPENSSL_NO_RSA
++ if (pk11_have_rsa == CK_TRUE)
++ {
++ if (!ENGINE_set_RSA(e, PK11_RSA()) ||
++ !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
++ !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++ if (pk11_have_dsa == CK_TRUE)
++ {
++ if (!ENGINE_set_DSA(e, PK11_DSA()))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++ if (pk11_have_dh == CK_TRUE)
++ {
++ if (!ENGINE_set_DH(e, PK11_DH()))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered DH\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++#endif /* OPENSSL_NO_DH */
++ if (pk11_have_random)
++ {
++ if (!ENGINE_set_RAND(e, &pk11_random))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered random\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++ if (!ENGINE_set_init_function(e, pk11_init) ||
++ !ENGINE_set_destroy_function(e, pk11_destroy) ||
++ !ENGINE_set_finish_function(e, pk11_finish) ||
++ !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
++ !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
++ return (0);
++
++/*
++ * Apache calls OpenSSL function RSA_blinding_on() once during startup
++ * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
++ * here, we wire it back to the OpenSSL software implementation.
++ * Since it is used only once, performance is not a concern.
++ */
++#ifndef OPENSSL_NO_RSA
++ rsa = RSA_PKCS1_SSLeay();
++ pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
++ pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
++ if (pk11_have_recover != CK_TRUE)
++ pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
++#endif /* OPENSSL_NO_RSA */
++
++ /* Ensure the pk11 error handling is set up */
++ ERR_load_pk11_strings();
++
++ return (1);
++ }
++
++/* Dynamic engine support is disabled at a higher level for Solaris */
++#ifdef ENGINE_DYNAMIC_SUPPORT
++static int bind_helper(ENGINE *e, const char *id)
++ {
++ if (id && (strcmp(id, engine_pk11_id) != 0))
++ return (0);
++
++ if (!bind_pk11(e))
++ return (0);
++
++ return (1);
++ }
++
++IMPLEMENT_DYNAMIC_CHECK_FN()
++IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
++
++#else
++static ENGINE *engine_pk11(void)
++ {
++ ENGINE *ret = ENGINE_new();
++
++ if (!ret)
++ return (NULL);
++
++ if (!bind_pk11(ret))
++ {
++ ENGINE_free(ret);
++ return (NULL);
++ }
++
++ return (ret);
++ }
++
++void
++ENGINE_load_pk11(void)
++ {
++ ENGINE *e_pk11 = NULL;
++
++ /*
++ * Do not use dynamic PKCS#11 library on Solaris due to
++ * security reasons. We will link it in statically.
++ */
++ /* Attempt to load PKCS#11 library */
++ if (!pk11_dso)
++ pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
++
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
++ return;
++ }
++
++ e_pk11 = engine_pk11();
++ if (!e_pk11)
++ {
++ DSO_free(pk11_dso);
++ pk11_dso = NULL;
++ return;
++ }
++
++ /*
++ * At this point, the pk11 shared library is either dynamically
++ * loaded or statically linked in. So, initialize the pk11
++ * library before calling ENGINE_set_default since the latter
++ * needs cipher and digest algorithm information
++ */
++ if (!pk11_library_init(e_pk11))
++ {
++ DSO_free(pk11_dso);
++ pk11_dso = NULL;
++ ENGINE_free(e_pk11);
++ return;
++ }
++
++ ENGINE_add(e_pk11);
++
++ ENGINE_free(e_pk11);
++ ERR_clear_error();
++ }
++#endif /* ENGINE_DYNAMIC_SUPPORT */
++
++/*
++ * These are the static string constants for the DSO file name and
++ * the function symbol names to bind to.
++ */
++static const char *PK11_LIBNAME = NULL;
++
++static const char *get_PK11_LIBNAME(void)
++ {
++ if (PK11_LIBNAME)
++ return (PK11_LIBNAME);
++
++ return (def_PK11_LIBNAME);
++ }
++
++static void free_PK11_LIBNAME(void)
++ {
++ if (PK11_LIBNAME)
++ OPENSSL_free((void*)PK11_LIBNAME);
++
++ PK11_LIBNAME = NULL;
++ }
++
++static long set_PK11_LIBNAME(const char *name)
++ {
++ free_PK11_LIBNAME();
++
++ return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
++ }
++
++/* acquire all engine specific mutexes before fork */
++static void pk11_fork_prepare(void)
++ {
++#ifndef NOPTHREADS
++ int i;
++
++ if (!pk11_library_initialized)
++ return;
++
++ LOCK_OBJSTORE(OP_RSA);
++ LOCK_OBJSTORE(OP_DSA);
++ LOCK_OBJSTORE(OP_DH);
++ for (i = 0; i < OP_MAX; i++)
++ {
++ (void) pthread_mutex_lock(session_cache[i].lock);
++ }
++#endif
++ }
++
++/* release all engine specific mutexes */
++static void pk11_fork_parent(void)
++ {
++#ifndef NOPTHREADS
++ int i;
++
++ if (!pk11_library_initialized)
++ return;
++
++ for (i = OP_MAX - 1; i >= 0; i--)
++ {
++ (void) pthread_mutex_unlock(session_cache[i].lock);
++ }
++ UNLOCK_OBJSTORE(OP_DH);
++ UNLOCK_OBJSTORE(OP_DSA);
++ UNLOCK_OBJSTORE(OP_RSA);
++#endif
++ }
++
++/*
++ * same situation as in parent - we need to unlock all locks to make them
++ * accessible to all threads.
++ */
++static void pk11_fork_child(void)
++ {
++#ifndef NOPTHREADS
++ int i;
++
++ if (!pk11_library_initialized)
++ return;
++
++ for (i = OP_MAX - 1; i >= 0; i--)
++ {
++ (void) pthread_mutex_unlock(session_cache[i].lock);
++ }
++ UNLOCK_OBJSTORE(OP_DH);
++ UNLOCK_OBJSTORE(OP_DSA);
++ UNLOCK_OBJSTORE(OP_RSA);
++#endif
++ }
++
++/* Initialization function for the pk11 engine */
++static int pk11_init(ENGINE *e)
++{
++ return (pk11_library_init(e));
++}
++
++/*
++ * Initialization function. Sets up various PKCS#11 library components.
++ * It selects a slot based on predefined critiera. In the process, it also
++ * count how many ciphers and digests to support. Since the cipher and
++ * digest information is needed when setting default engine, this function
++ * needs to be called before calling ENGINE_set_default.
++ */
++/* ARGSUSED */
++static int pk11_library_init(ENGINE *e)
++ {
++ CK_C_GetFunctionList p;
++ CK_RV rv = CKR_OK;
++ CK_INFO info;
++ CK_ULONG ul_state_len;
++ int any_slot_found;
++ int i;
++#ifndef OPENSSL_SYS_WIN32
++ struct sigaction sigint_act, sigterm_act, sighup_act;
++#endif
++
++ /*
++ * pk11_library_initialized is set to 0 in pk11_finish() which is called
++ * from ENGINE_finish(). However, if there is still at least one
++ * existing functional reference to the engine (see engine(3) for more
++ * information), pk11_finish() is skipped. For example, this can happen
++ * if an application forgets to clear one cipher context. In case of a
++ * fork() when the application is finishing the engine so that it can be
++ * reinitialized in the child, forgotten functional reference causes
++ * pk11_library_initialized to stay 1. In that case we need the PID
++ * check so that we properly initialize the engine again.
++ */
++ if (pk11_library_initialized)
++ {
++ if (pk11_pid == getpid())
++ {
++ return (1);
++ }
++ else
++ {
++ global_session = CK_INVALID_HANDLE;
++ /*
++ * free the locks first to prevent memory leak in case
++ * the application calls fork() without finishing the
++ * engine first.
++ */
++ pk11_free_all_locks();
++ }
++ }
++
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++#ifdef SOLARIS_AES_CTR
++ /*
++ * We must do this before we start working with slots since we need all
++ * NIDs there.
++ */
++ if (pk11_add_aes_ctr_NIDs() == 0)
++ goto err;
++#endif /* SOLARIS_AES_CTR */
++
++#ifdef SOLARIS_HW_SLOT_SELECTION
++ if (check_hw_mechanisms() == 0)
++ goto err;
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++
++ /* get the C_GetFunctionList function from the loaded library */
++ p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
++ PK11_GET_FUNCTION_LIST);
++ if (!p)
++ {
++ PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++ /* get the full function list from the loaded library */
++ rv = p(&pFuncList);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
++ goto err;
++ }
++
++#ifndef OPENSSL_SYS_WIN32
++ /* Not all PKCS#11 library are signal safe! */
++
++ (void) memset(&sigint_act, 0, sizeof(sigint_act));
++ (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
++ (void) memset(&sighup_act, 0, sizeof(sighup_act));
++ (void) sigaction(SIGINT, NULL, &sigint_act);
++ (void) sigaction(SIGTERM, NULL, &sigterm_act);
++ (void) sigaction(SIGHUP, NULL, &sighup_act);
++#endif
++ rv = pFuncList->C_Initialize(NULL_PTR);
++#ifndef OPENSSL_SYS_WIN32
++ (void) sigaction(SIGINT, &sigint_act, NULL);
++ (void) sigaction(SIGTERM, &sigterm_act, NULL);
++ (void) sigaction(SIGHUP, &sighup_act, NULL);
++#endif
++ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_GetInfo(&info);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
++ goto err;
++ }
++
++ if (pk11_choose_slots(&any_slot_found) == 0)
++ goto err;
++
++ /*
++ * The library we use, set in def_PK11_LIBNAME, may not offer any
++ * slot(s). In that case, we must not proceed but we must not return an
++ * error. The reason is that applications that try to set up the PKCS#11
++ * engine don't exit on error during the engine initialization just
++ * because no slot was present.
++ */
++ if (any_slot_found == 0)
++ return (1);
++
++ if (global_session == CK_INVALID_HANDLE)
++ {
++ /* Open the global_session for the new process */
++ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &global_session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LIBRARY_INIT,
++ PK11_R_OPENSESSION, rv);
++ goto err;
++ }
++ }
++
++ /*
++ * Disable digest if C_GetOperationState is not supported since
++ * this function is required by OpenSSL digest copy function
++ */
++ /* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
++ if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
++ != CKR_OK) {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: C_GetOperationState() not supported, "
++ "setting digest_count to 0\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ digest_count = 0;
++ }
++
++ pk11_library_initialized = TRUE;
++ pk11_pid = getpid();
++ /*
++ * if initialization of the locks fails pk11_init_all_locks()
++ * will do the cleanup.
++ */
++ if (!pk11_init_all_locks())
++ goto err;
++ for (i = 0; i < OP_MAX; i++)
++ session_cache[i].head = NULL;
++ /*
++ * initialize active lists. We only use active lists
++ * for asymmetric ciphers.
++ */
++ for (i = 0; i < OP_MAX; i++)
++ active_list[i] = NULL;
++
++#ifndef NOPTHREADS
++ if (!pk11_atfork_initialized)
++ {
++ if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
++ pk11_fork_child) != 0)
++ {
++ PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
++ goto err;
++ }
++ pk11_atfork_initialized = TRUE;
++ }
++#endif
++
++ return (1);
++
++err:
++ return (0);
++ }
++
++/* Destructor (complements the "ENGINE_pk11()" constructor) */
++/* ARGSUSED */
++static int pk11_destroy(ENGINE *e)
++ {
++ free_PK11_LIBNAME();
++ ERR_unload_pk11_strings();
++ if (pk11_pin) {
++ memset(pk11_pin, 0, strlen(pk11_pin));
++ OPENSSL_free((void*)pk11_pin);
++ }
++ pk11_pin = NULL;
++ return (1);
++ }
++
++/*
++ * Termination function to clean up the session, the token, and the pk11
++ * library.
++ */
++/* ARGSUSED */
++static int pk11_finish(ENGINE *e)
++ {
++ int i;
++
++ if (pk11_pin) {
++ memset(pk11_pin, 0, strlen(pk11_pin));
++ OPENSSL_free((void*)pk11_pin);
++ }
++ pk11_pin = NULL;
++
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
++ goto err;
++ }
++
++ OPENSSL_assert(pFuncList != NULL);
++
++ if (pk11_free_all_sessions() == 0)
++ goto err;
++
++ /* free all active lists */
++ for (i = 0; i < OP_MAX; i++)
++ pk11_free_active_list(i);
++
++ pFuncList->C_CloseSession(global_session);
++ global_session = CK_INVALID_HANDLE;
++
++ /*
++ * Since we are part of a library (libcrypto.so), calling this function
++ * may have side-effects.
++ */
++#if 0
++ pFuncList->C_Finalize(NULL);
++#endif
++
++ if (!DSO_free(pk11_dso))
++ {
++ PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++ pk11_dso = NULL;
++ pFuncList = NULL;
++ pk11_library_initialized = FALSE;
++ pk11_pid = 0;
++ /*
++ * There is no way how to unregister atfork handlers (other than
++ * unloading the library) so we just free the locks. For this reason
++ * the atfork handlers check if the engine is initialized and bail out
++ * immediately if not. This is necessary in case a process finishes
++ * the engine before calling fork().
++ */
++ pk11_free_all_locks();
++
++ return (1);
++
++err:
++ return (0);
++ }
++
++/* Standard engine interface function to set the dynamic library path */
++/* ARGSUSED */
++static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
++ {
++ int initialized = ((pk11_dso == NULL) ? 0 : 1);
++
++ switch (cmd)
++ {
++ case PK11_CMD_SO_PATH:
++ if (p == NULL)
++ {
++ PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
++ return (0);
++ }
++
++ if (initialized)
++ {
++ PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
++ return (0);
++ }
++
++ return (set_PK11_LIBNAME((const char *)p));
++ case PK11_CMD_PIN:
++ if (pk11_pin) {
++ memset(pk11_pin, 0, strlen(pk11_pin));
++ OPENSSL_free((void*)pk11_pin);
++ }
++ pk11_pin = NULL;
++
++ if (p == NULL)
++ {
++ PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
++ return (0);
++ }
++
++ pk11_pin = BUF_strdup(p);
++ if (pk11_pin == NULL)
++ {
++ PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
++ return (0);
++ }
++ return (1);
++ case PK11_CMD_SLOT:
++ SLOTID = (CK_SLOT_ID)i;
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: slot set\n", PK11_DBG);
++#endif
++ return (1);
++ default:
++ break;
++ }
++
++ PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
++
++ return (0);
++ }
++
++
++/* Required function by the engine random interface. It does nothing here */
++static void pk11_rand_cleanup(void)
++ {
++ return;
++ }
++
++/* ARGSUSED */
++static void pk11_rand_add(const void *buf, int num, double add)
++ {
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RAND)) == NULL)
++ return;
++
++ /*
++ * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
++ * the calling functions do not care anyway
++ */
++ pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
++ pk11_return_session(sp, OP_RAND);
++
++ return;
++ }
++
++static void pk11_rand_seed(const void *buf, int num)
++ {
++ pk11_rand_add(buf, num, 0);
++ }
++
++static int pk11_rand_bytes(unsigned char *buf, int num)
++ {
++ CK_RV rv;
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RAND)) == NULL)
++ return (0);
++
++ rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
++ pk11_return_session(sp, OP_RAND);
++ return (0);
++ }
++
++ pk11_return_session(sp, OP_RAND);
++ return (1);
++ }
++
++/* Required function by the engine random interface. It does nothing here */
++static int pk11_rand_status(void)
++ {
++ return (1);
++ }
++
++/* Free all BIGNUM structures from PK11_SESSION. */
++static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
++ {
++ switch (optype)
++ {
++#ifndef OPENSSL_NO_RSA
++ case OP_RSA:
++ if (sp->opdata_rsa_n_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_n_num);
++ sp->opdata_rsa_n_num = NULL;
++ }
++ if (sp->opdata_rsa_e_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_e_num);
++ sp->opdata_rsa_e_num = NULL;
++ }
++ if (sp->opdata_rsa_d_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_d_num);
++ sp->opdata_rsa_d_num = NULL;
++ }
++ break;
++#endif
++#ifndef OPENSSL_NO_DSA
++ case OP_DSA:
++ if (sp->opdata_dsa_pub_num != NULL)
++ {
++ BN_free(sp->opdata_dsa_pub_num);
++ sp->opdata_dsa_pub_num = NULL;
++ }
++ if (sp->opdata_dsa_priv_num != NULL)
++ {
++ BN_free(sp->opdata_dsa_priv_num);
++ sp->opdata_dsa_priv_num = NULL;
++ }
++ break;
++#endif
++#ifndef OPENSSL_NO_DH
++ case OP_DH:
++ if (sp->opdata_dh_priv_num != NULL)
++ {
++ BN_free(sp->opdata_dh_priv_num);
++ sp->opdata_dh_priv_num = NULL;
++ }
++ break;
++#endif
++ default:
++ break;
++ }
++ }
++
++/*
++ * Get new PK11_SESSION structure ready for use. Every process must have
++ * its own freelist of PK11_SESSION structures so handle fork() here
++ * by destroying the old and creating new freelist.
++ * The returned PK11_SESSION structure is disconnected from the freelist.
++ */
++PK11_SESSION *
++pk11_get_session(PK11_OPTYPE optype)
++ {
++ PK11_SESSION *sp = NULL, *sp1, *freelist;
++#ifndef NOPTHREADS
++ pthread_mutex_t *freelist_lock = NULL;
++#endif
++ CK_RV rv;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ case OP_RAND:
++ case OP_DIGEST:
++ case OP_CIPHER:
++#ifndef NOPTHREADS
++ freelist_lock = session_cache[optype].lock;
++#endif
++ break;
++ default:
++ PK11err(PK11_F_GET_SESSION,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return (NULL);
++ }
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(freelist_lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ freelist = session_cache[optype].head;
++ sp = freelist;
++
++ /*
++ * If the free list is empty, allocate new unitialized (filled
++ * with zeroes) PK11_SESSION structure otherwise return first
++ * structure from the freelist.
++ */
++ if (sp == NULL)
++ {
++ if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
++ {
++ PK11err(PK11_F_GET_SESSION,
++ PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ (void) memset(sp, 0, sizeof (PK11_SESSION));
++ }
++ else
++ {
++ freelist = sp->next;
++ }
++
++ if (sp->pid != 0 && sp->pid != getpid())
++ {
++ /*
++ * We are a new process and thus need to free any inherited
++ * PK11_SESSION objects.
++ */
++ while ((sp1 = freelist) != NULL)
++ {
++ freelist = sp1->next;
++ /*
++ * NOTE: we do not want to call pk11_free_all_sessions()
++ * here because it would close underlying PKCS#11
++ * sessions and destroy all objects.
++ */
++ pk11_free_nums(sp1, optype);
++ OPENSSL_free(sp1);
++ }
++
++ /* we have to free the active list as well. */
++ pk11_free_active_list(optype);
++
++ /* Initialize the process */
++ rv = pFuncList->C_Initialize(NULL_PTR);
++ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
++ {
++ PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
++ rv);
++ OPENSSL_free(sp);
++ sp = NULL;
++ goto err;
++ }
++
++ /*
++ * Choose slot here since the slot table is different on this
++ * process. If we are here then we must have found at least one
++ * usable slot before so we don't need to check any_slot_found.
++ * See pk11_library_init()'s usage of this function for more
++ * information.
++ */
++#ifdef SOLARIS_HW_SLOT_SELECTION
++ if (check_hw_mechanisms() == 0)
++ goto err;
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++ if (pk11_choose_slots(NULL) == 0)
++ goto err;
++
++ /* Open the global_session for the new process */
++ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &global_session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
++ rv);
++ OPENSSL_free(sp);
++ sp = NULL;
++ goto err;
++ }
++
++ /* It is an inherited session and needs re-initialization. */
++ if (pk11_setup_session(sp, optype) == 0)
++ {
++ OPENSSL_free(sp);
++ sp = NULL;
++ }
++ }
++ if (sp->pid == 0)
++ {
++ /* It is a new session and needs initialization. */
++ if (pk11_setup_session(sp, optype) == 0)
++ {
++ OPENSSL_free(sp);
++ sp = NULL;
++ }
++ }
++
++ /* set new head for the list of PK11_SESSION objects */
++ session_cache[optype].head = freelist;
++
++err:
++ if (sp != NULL)
++ sp->next = NULL;
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_unlock(freelist_lock);
++#else
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (sp);
++ }
++
++
++void
++pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
++ {
++#ifndef NOPTHREADS
++ pthread_mutex_t *freelist_lock;
++#endif
++ PK11_SESSION *freelist;
++
++ if (sp == NULL || sp->pid != getpid())
++ return;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ case OP_RAND:
++ case OP_DIGEST:
++ case OP_CIPHER:
++#ifndef NOPTHREADS
++ freelist_lock = session_cache[optype].lock;
++#endif
++ break;
++ default:
++ PK11err(PK11_F_RETURN_SESSION,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return;
++ }
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(freelist_lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ freelist = session_cache[optype].head;
++ sp->next = freelist;
++ session_cache[optype].head = sp;
++#ifndef NOPTHREADS
++ (void) pthread_mutex_unlock(freelist_lock);
++#else
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ }
++
++
++/* Destroy all objects. This function is called when the engine is finished */
++static int pk11_free_all_sessions()
++ {
++ int ret = 1;
++ int type;
++
++#ifndef OPENSSL_NO_RSA
++ (void) pk11_destroy_rsa_key_objects(NULL);
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++ (void) pk11_destroy_dsa_key_objects(NULL);
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++ (void) pk11_destroy_dh_key_objects(NULL);
++#endif /* OPENSSL_NO_DH */
++ (void) pk11_destroy_cipher_key_objects(NULL);
++
++ /*
++ * We try to release as much as we can but any error means that we will
++ * return 0 on exit.
++ */
++ for (type = 0; type < OP_MAX; type++)
++ {
++ if (pk11_free_session_list(type) == 0)
++ ret = 0;
++ }
++
++ return (ret);
++ }
++
++/*
++ * Destroy session structures from the linked list specified. Free as many
++ * sessions as possible but any failure in C_CloseSession() means that we
++ * return an error on return.
++ */
++static int pk11_free_session_list(PK11_OPTYPE optype)
++ {
++ CK_RV rv;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *freelist = NULL;
++ pid_t mypid = getpid();
++#ifndef NOPTHREADS
++ pthread_mutex_t *freelist_lock;
++#endif
++ int ret = 1;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ case OP_RAND:
++ case OP_DIGEST:
++ case OP_CIPHER:
++#ifndef NOPTHREADS
++ freelist_lock = session_cache[optype].lock;
++#endif
++ break;
++ default:
++ PK11err(PK11_F_FREE_ALL_SESSIONS,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return (0);
++ }
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(freelist_lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ freelist = session_cache[optype].head;
++ while ((sp = freelist) != NULL)
++ {
++ if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
++ {
++ rv = pFuncList->C_CloseSession(sp->session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
++ PK11_R_CLOSESESSION, rv);
++ ret = 0;
++ }
++ }
++ freelist = sp->next;
++ pk11_free_nums(sp, optype);
++ OPENSSL_free(sp);
++ }
++
++#ifndef NOPTHREADS
++ (void) pthread_mutex_unlock(freelist_lock);
++#else
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ return (ret);
++ }
++
++
++static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
++ {
++ CK_RV rv;
++ CK_SLOT_ID myslot;
++
++ switch (optype)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ myslot = pubkey_SLOTID;
++ break;
++ case OP_RAND:
++ myslot = rand_SLOTID;
++ break;
++ case OP_DIGEST:
++ case OP_CIPHER:
++ myslot = SLOTID;
++ break;
++ default:
++ PK11err(PK11_F_SETUP_SESSION,
++ PK11_R_INVALID_OPERATION_TYPE);
++ return (0);
++ }
++
++ sp->session = CK_INVALID_HANDLE;
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
++#endif /* DEBUG_SLOT_SELECTION */
++ rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &sp->session);
++ if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
++ {
++ /*
++ * We are probably a child process so force the
++ * reinitialize of the session
++ */
++ pk11_library_initialized = FALSE;
++ if (!pk11_library_init(NULL))
++ return (0);
++ rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &sp->session);
++ }
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
++ return (0);
++ }
++
++ sp->pid = getpid();
++
++ switch (optype)
++ {
++#ifndef OPENSSL_NO_RSA
++ case OP_RSA:
++ sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_pub = NULL;
++ sp->opdata_rsa_n_num = NULL;
++ sp->opdata_rsa_e_num = NULL;
++ sp->opdata_rsa_priv = NULL;
++ sp->opdata_rsa_d_num = NULL;
++ break;
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++ case OP_DSA:
++ sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
++ sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
++ sp->opdata_dsa_pub = NULL;
++ sp->opdata_dsa_pub_num = NULL;
++ sp->opdata_dsa_priv = NULL;
++ sp->opdata_dsa_priv_num = NULL;
++ break;
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++ case OP_DH:
++ sp->opdata_dh_key = CK_INVALID_HANDLE;
++ sp->opdata_dh = NULL;
++ sp->opdata_dh_priv_num = NULL;
++ break;
++#endif /* OPENSSL_NO_DH */
++ case OP_CIPHER:
++ sp->opdata_cipher_key = CK_INVALID_HANDLE;
++ sp->opdata_encrypt = -1;
++ break;
++ default:
++ break;
++ }
++
++ return (1);
++ }
++
++#ifndef OPENSSL_NO_RSA
++/* Destroy RSA public key from single session. */
++int
++pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
++ {
++ TRY_OBJ_DESTROY(sp->session, sp->opdata_rsa_pub_key,
++ ret, uselock, OP_RSA);
++ sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_pub = NULL;
++ if (sp->opdata_rsa_n_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_n_num);
++ sp->opdata_rsa_n_num = NULL;
++ }
++ if (sp->opdata_rsa_e_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_e_num);
++ sp->opdata_rsa_e_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/* Destroy RSA private key from single session. */
++int
++pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
++ {
++ if ((sp->opdata_rsa_priv->flags & RSA_FLAG_EXT_PKEY) != 0)
++ {
++ TRY_OBJ_DELETE(sp->session,
++ sp->opdata_rsa_priv_key,
++ ret, uselock, OP_RSA);
++ }
++ else
++ {
++ TRY_OBJ_DESTROY(sp->session,
++ sp->opdata_rsa_priv_key,
++ ret, uselock, OP_RSA);
++ }
++ sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
++ sp->opdata_rsa_priv = NULL;
++ if (sp->opdata_rsa_d_num != NULL)
++ {
++ BN_free(sp->opdata_rsa_d_num);
++ sp->opdata_rsa_d_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/*
++ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
++ * objects in the free list.
++ */
++int
++pk11_destroy_rsa_key_objects(PK11_SESSION *session)
++ {
++ int ret = 1;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *local_free_session;
++ CK_BBOOL uselock = TRUE;
++
++ if (session != NULL)
++ local_free_session = session;
++ else
++ {
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(session_cache[OP_RSA].lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ local_free_session = session_cache[OP_RSA].head;
++ uselock = FALSE;
++ }
++
++ /*
++ * go through the list of sessions and delete key objects
++ */
++ while ((sp = local_free_session) != NULL)
++ {
++ local_free_session = sp->next;
++
++ /*
++ * Do not terminate list traversal if one of the
++ * destroy operations fails.
++ */
++ if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ }
++
++#ifndef NOPTHREADS
++ if (session == NULL)
++ (void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
++#else
++ if (session == NULL)
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (ret);
++ }
++#endif /* OPENSSL_NO_RSA */
++
++#ifndef OPENSSL_NO_DSA
++/* Destroy DSA public key from single session. */
++int
++pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
++ {
++ TRY_OBJ_DESTROY(sp->session, sp->opdata_dsa_pub_key,
++ ret, uselock, OP_DSA);
++ sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
++ sp->opdata_dsa_pub = NULL;
++ if (sp->opdata_dsa_pub_num != NULL)
++ {
++ BN_free(sp->opdata_dsa_pub_num);
++ sp->opdata_dsa_pub_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/* Destroy DSA private key from single session. */
++int
++pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
++ {
++ TRY_OBJ_DESTROY(sp->session, sp->opdata_dsa_priv_key,
++ ret, uselock, OP_DSA);
++ sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
++ sp->opdata_dsa_priv = NULL;
++ if (sp->opdata_dsa_priv_num != NULL)
++ {
++ BN_free(sp->opdata_dsa_priv_num);
++ sp->opdata_dsa_priv_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/*
++ * Destroy DSA key object wrapper. If session is NULL, try to destroy all
++ * objects in the free list.
++ */
++int
++pk11_destroy_dsa_key_objects(PK11_SESSION *session)
++ {
++ int ret = 1;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *local_free_session;
++ CK_BBOOL uselock = TRUE;
++
++ if (session != NULL)
++ local_free_session = session;
++ else
++ {
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(session_cache[OP_DSA].lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ local_free_session = session_cache[OP_DSA].head;
++ uselock = FALSE;
++ }
++
++ /*
++ * go through the list of sessions and delete key objects
++ */
++ while ((sp = local_free_session) != NULL)
++ {
++ local_free_session = sp->next;
++
++ /*
++ * Do not terminate list traversal if one of the
++ * destroy operations fails.
++ */
++ if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ }
++
++#ifndef NOPTHREADS
++ if (session == NULL)
++ (void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
++#else
++ if (session == NULL)
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (ret);
++ }
++#endif /* OPENSSL_NO_DSA */
++
++#ifndef OPENSSL_NO_DH
++/* Destroy DH key from single session. */
++int
++pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
++ {
++ int ret = 0;
++
++ if (sp->opdata_dh_key != CK_INVALID_HANDLE)
++ {
++ TRY_OBJ_DESTROY(sp->session, sp->opdata_dh_key,
++ ret, uselock, OP_DH);
++ sp->opdata_dh_key = CK_INVALID_HANDLE;
++ sp->opdata_dh = NULL;
++ if (sp->opdata_dh_priv_num != NULL)
++ {
++ BN_free(sp->opdata_dh_priv_num);
++ sp->opdata_dh_priv_num = NULL;
++ }
++ }
++
++ return (ret);
++ }
++
++/*
++ * Destroy DH key object wrapper.
++ *
++ * arg0: pointer to PKCS#11 engine session structure
++ * if session is NULL, try to destroy all objects in the free list
++ */
++int
++pk11_destroy_dh_key_objects(PK11_SESSION *session)
++ {
++ int ret = 1;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *local_free_session;
++ CK_BBOOL uselock = TRUE;
++
++ if (session != NULL)
++ local_free_session = session;
++ else
++ {
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(session_cache[OP_DH].lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ local_free_session = session_cache[OP_DH].head;
++ uselock = FALSE;
++ }
++
++ while ((sp = local_free_session) != NULL)
++ {
++ local_free_session = sp->next;
++
++ /*
++ * Do not terminate list traversal if one of the
++ * destroy operations fails.
++ */
++ if (pk11_destroy_dh_object(sp, uselock) == 0)
++ {
++ ret = 0;
++ continue;
++ }
++ }
++
++#ifndef NOPTHREADS
++ if (session == NULL)
++ (void) pthread_mutex_unlock(session_cache[OP_DH].lock);
++#else
++ if (session == NULL)
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (ret);
++ }
++#endif /* OPENSSL_NO_DH */
++
++static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh)
++ {
++ CK_RV rv;
++ rv = pFuncList->C_DestroyObject(session, oh);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
++ rv);
++ return (0);
++ }
++
++ return (1);
++ }
++
++
++/* Symmetric ciphers and digests support functions */
++
++static int
++cipher_nid_to_pk11(int nid)
++ {
++ int i;
++
++ for (i = 0; i < PK11_CIPHER_MAX; i++)
++ if (ciphers[i].nid == nid)
++ return (ciphers[i].id);
++ return (-1);
++ }
++
++static int
++pk11_usable_ciphers(const int **nids)
++ {
++ if (cipher_count > 0)
++ *nids = cipher_nids;
++ else
++ *nids = NULL;
++ return (cipher_count);
++ }
++
++static int
++pk11_usable_digests(const int **nids)
++ {
++ if (digest_count > 0)
++ *nids = digest_nids;
++ else
++ *nids = NULL;
++ return (digest_count);
++ }
++
++/*
++ * Init context for encryption or decryption using a symmetric key.
++ */
++static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
++ PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
++ {
++ CK_RV rv;
++#ifdef SOLARIS_AES_CTR
++ CK_AES_CTR_PARAMS ctr_params;
++#endif /* SOLARIS_AES_CTR */
++
++ /*
++ * We expect pmech->mechanism to be already set and
++ * pParameter/ulParameterLen initialized to NULL/0 before
++ * pk11_init_symetric() is called.
++ */
++ OPENSSL_assert(pmech->mechanism != 0);
++ OPENSSL_assert(pmech->pParameter == NULL);
++ OPENSSL_assert(pmech->ulParameterLen == 0);
++
++#ifdef SOLARIS_AES_CTR
++ if (ctx->cipher->nid == NID_aes_128_ctr ||
++ ctx->cipher->nid == NID_aes_192_ctr ||
++ ctx->cipher->nid == NID_aes_256_ctr)
++ {
++ pmech->pParameter = (void *)(&ctr_params);
++ pmech->ulParameterLen = sizeof (ctr_params);
++ /*
++ * For now, we are limited to the fixed length of the counter,
++ * it covers the whole counter block. That's what RFC 4344
++ * needs. For more information on internal structure of the
++ * counter block, see RFC 3686. If needed in the future, we can
++ * add code so that the counter length can be set via
++ * ENGINE_ctrl() function.
++ */
++ ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
++ OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
++ (void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
++ }
++ else
++#endif /* SOLARIS_AES_CTR */
++ {
++ if (pcipher->iv_len > 0)
++ {
++ pmech->pParameter = (void *)ctx->iv;
++ pmech->ulParameterLen = pcipher->iv_len;
++ }
++ }
++
++ /* if we get here, the encryption needs to be reinitialized */
++ if (ctx->encrypt)
++ rv = pFuncList->C_EncryptInit(sp->session, pmech,
++ sp->opdata_cipher_key);
++ else
++ rv = pFuncList->C_DecryptInit(sp->session, pmech,
++ sp->opdata_cipher_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
++ PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
++ pk11_return_session(sp, OP_CIPHER);
++ return (0);
++ }
++
++ return (1);
++ }
++
++/* ARGSUSED */
++static int
++pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
++ const unsigned char *iv, int enc)
++ {
++ CK_MECHANISM mech;
++ int index;
++ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
++ PK11_SESSION *sp;
++ PK11_CIPHER *p_ciph_table_row;
++
++ state->sp = NULL;
++
++ index = cipher_nid_to_pk11(ctx->cipher->nid);
++ if (index < 0 || index >= PK11_CIPHER_MAX)
++ return (0);
++
++ p_ciph_table_row = &ciphers[index];
++ /*
++ * iv_len in the ctx->cipher structure is the maximum IV length for the
++ * current cipher and it must be less or equal to the IV length in our
++ * ciphers table. The key length must match precisely. Every application
++ * can define its own EVP functions so this code serves as a sanity
++ * check.
++ *
++ * Note that the reason why the IV length in ctx->cipher might be
++ * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
++ * macro to define functions that return EVP structures for all DES
++ * modes. So, even ECB modes get 8 byte IV.
++ */
++ if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
++ ctx->key_len != p_ciph_table_row->key_len)
++ {
++ PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
++ return (0);
++ }
++
++ if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
++ return (0);
++
++ /* if applicable, the mechanism parameter is used for IV */
++ mech.mechanism = p_ciph_table_row->mech_type;
++ mech.pParameter = NULL;
++ mech.ulParameterLen = 0;
++
++ /* The key object is destroyed here if it is not the current key. */
++ (void) check_new_cipher_key(sp, key, p_ciph_table_row->key_len);
++
++ /*
++ * If the key is the same and the encryption is also the same, then
++ * just reuse it. However, we must not forget to reinitialize the
++ * context that was finalized in pk11_cipher_cleanup().
++ */
++ if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
++ sp->opdata_encrypt == ctx->encrypt)
++ {
++ state->sp = sp;
++ if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
++ return (0);
++
++ return (1);
++ }
++
++ /*
++ * Check if the key has been invalidated. If so, a new key object
++ * needs to be created.
++ */
++ if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
++ {
++ sp->opdata_cipher_key = pk11_get_cipher_key(
++ ctx, key, p_ciph_table_row->key_type, sp);
++ }
++
++ if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
++ {
++ /*
++ * The previous encryption/decryption is different. Need to
++ * terminate the previous * active encryption/decryption here.
++ */
++ if (!pk11_cipher_final(sp))
++ {
++ pk11_return_session(sp, OP_CIPHER);
++ return (0);
++ }
++ }
++
++ if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
++ {
++ pk11_return_session(sp, OP_CIPHER);
++ return (0);
++ }
++
++ /* now initialize the context with a new key */
++ if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
++ return (0);
++
++ sp->opdata_encrypt = ctx->encrypt;
++ state->sp = sp;
++
++ return (1);
++ }
++
++/*
++ * When reusing the same key in an encryption/decryption session for a
++ * decryption/encryption session, we need to close the active session
++ * and recreate a new one. Note that the key is in the global session so
++ * that it needs not be recreated.
++ *
++ * It is more appropriate to use C_En/DecryptFinish here. At the time of this
++ * development, these two functions in the PKCS#11 libraries used return
++ * unexpected errors when passing in 0 length output. It may be a good
++ * idea to try them again if performance is a problem here and fix
++ * C_En/DecryptFinial if there are bugs there causing the problem.
++ */
++static int
++pk11_cipher_final(PK11_SESSION *sp)
++ {
++ CK_RV rv;
++
++ rv = pFuncList->C_CloseSession(sp->session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
++ return (0);
++ }
++
++ rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
++ NULL_PTR, NULL_PTR, &sp->session);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
++ return (0);
++ }
++
++ return (1);
++ }
++
++/*
++ * An engine interface function. The calling function allocates sufficient
++ * memory for the output buffer "out" to hold the results.
++ */
++static int
++pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
++ const unsigned char *in, unsigned int inl)
++ {
++ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
++ PK11_SESSION *sp;
++ CK_RV rv;
++ unsigned long outl = inl;
++
++ if (state == NULL || state->sp == NULL)
++ return (0);
++
++ sp = (PK11_SESSION *) state->sp;
++
++ if (!inl)
++ return (1);
++
++ /* RC4 is the only stream cipher we support */
++ if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
++ return (0);
++
++ if (ctx->encrypt)
++ {
++ rv = pFuncList->C_EncryptUpdate(sp->session,
++ (unsigned char *)in, inl, out, &outl);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
++ PK11_R_ENCRYPTUPDATE, rv);
++ return (0);
++ }
++ }
++ else
++ {
++ rv = pFuncList->C_DecryptUpdate(sp->session,
++ (unsigned char *)in, inl, out, &outl);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
++ PK11_R_DECRYPTUPDATE, rv);
++ return (0);
++ }
++ }
++
++ /*
++ * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
++ * the same size of input.
++ * The application has guaranteed to call the block ciphers with
++ * correctly aligned buffers.
++ */
++ if (inl != outl)
++ return (0);
++
++ return (1);
++ }
++
++/*
++ * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
++ * here is the right thing because in EVP_DecryptFinal_ex(), engine's
++ * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
++ * the engine can't find out that it's the finalizing call. We wouldn't
++ * necessarily have to finalize the context here since reinitializing it with
++ * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
++ * let's do it. Some implementations might leak memory if the previously used
++ * context is initialized without finalizing it first.
++ */
++static int
++pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
++ {
++ CK_RV rv;
++ CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
++ CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
++ PK11_CIPHER_STATE *state = ctx->cipher_data;
++
++ if (state != NULL && state->sp != NULL)
++ {
++ /*
++ * We are not interested in the data here, we just need to get
++ * rid of the context.
++ */
++ if (ctx->encrypt)
++ rv = pFuncList->C_EncryptFinal(
++ state->sp->session, buf, &len);
++ else
++ rv = pFuncList->C_DecryptFinal(
++ state->sp->session, buf, &len);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
++ PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
++ pk11_return_session(state->sp, OP_CIPHER);
++ return (0);
++ }
++
++ pk11_return_session(state->sp, OP_CIPHER);
++ state->sp = NULL;
++ }
++
++ return (1);
++ }
++
++/*
++ * Registered by the ENGINE when used to find out how to deal with
++ * a particular NID in the ENGINE. This says what we'll do at the
++ * top level - note, that list is restricted by what we answer with
++ */
++/* ARGSUSED */
++static int
++pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
++ const int **nids, int nid)
++ {
++ if (!cipher)
++ return (pk11_usable_ciphers(nids));
++
++ switch (nid)
++ {
++ case NID_des_ede3_cbc:
++ *cipher = &pk11_3des_cbc;
++ break;
++ case NID_des_cbc:
++ *cipher = &pk11_des_cbc;
++ break;
++ case NID_des_ede3_ecb:
++ *cipher = &pk11_3des_ecb;
++ break;
++ case NID_des_ecb:
++ *cipher = &pk11_des_ecb;
++ break;
++ case NID_aes_128_cbc:
++ *cipher = &pk11_aes_128_cbc;
++ break;
++ case NID_aes_192_cbc:
++ *cipher = &pk11_aes_192_cbc;
++ break;
++ case NID_aes_256_cbc:
++ *cipher = &pk11_aes_256_cbc;
++ break;
++ case NID_aes_128_ecb:
++ *cipher = &pk11_aes_128_ecb;
++ break;
++ case NID_aes_192_ecb:
++ *cipher = &pk11_aes_192_ecb;
++ break;
++ case NID_aes_256_ecb:
++ *cipher = &pk11_aes_256_ecb;
++ break;
++ case NID_bf_cbc:
++ *cipher = &pk11_bf_cbc;
++ break;
++ case NID_rc4:
++ *cipher = &pk11_rc4;
++ break;
++ default:
++#ifdef SOLARIS_AES_CTR
++ /*
++ * These can't be in separated cases because the NIDs
++ * here are not constants.
++ */
++ if (nid == NID_aes_128_ctr)
++ *cipher = &pk11_aes_128_ctr;
++ else if (nid == NID_aes_192_ctr)
++ *cipher = &pk11_aes_192_ctr;
++ else if (nid == NID_aes_256_ctr)
++ *cipher = &pk11_aes_256_ctr;
++ else
++#endif /* SOLARIS_AES_CTR */
++ *cipher = NULL;
++ break;
++ }
++ return (*cipher != NULL);
++ }
++
++/* ARGSUSED */
++static int
++pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
++ const int **nids, int nid)
++ {
++ if (!digest)
++ return (pk11_usable_digests(nids));
++
++ switch (nid)
++ {
++ case NID_md5:
++ *digest = &pk11_md5;
++ break;
++ case NID_sha1:
++ *digest = &pk11_sha1;
++ break;
++ case NID_sha224:
++ *digest = &pk11_sha224;
++ break;
++ case NID_sha256:
++ *digest = &pk11_sha256;
++ break;
++ case NID_sha384:
++ *digest = &pk11_sha384;
++ break;
++ case NID_sha512:
++ *digest = &pk11_sha512;
++ break;
++ default:
++ *digest = NULL;
++ break;
++ }
++ return (*digest != NULL);
++ }
++
++
++/* Create a secret key object in a PKCS#11 session */
++static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
++ const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
++ {
++ CK_RV rv;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++ CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
++ CK_ULONG ul_key_attr_count = 6;
++
++ CK_ATTRIBUTE a_key_template[] =
++ {
++ {CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
++ {CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
++ {CKA_TOKEN, &false, sizeof (false)},
++ {CKA_ENCRYPT, &true, sizeof (true)},
++ {CKA_DECRYPT, &true, sizeof (true)},
++ {CKA_VALUE, (void*) NULL, 0},
++ };
++
++ /*
++ * Create secret key object in global_session. All other sessions
++ * can use the key handles. Here is why:
++ * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
++ * It may then call DecryptInit and DecryptUpdate using the same key.
++ * To use the same key object, we need to call EncryptFinal with
++ * a 0 length message. Currently, this does not work for 3DES
++ * mechanism. To get around this problem, we close the session and
++ * then create a new session to use the same key object. When a session
++ * is closed, all the object handles will be invalid. Thus, create key
++ * objects in a global session, an individual session may be closed to
++ * terminate the active operation.
++ */
++ CK_SESSION_HANDLE session = global_session;
++ a_key_template[0].pValue = &obj_key;
++ a_key_template[1].pValue = &key_type;
++ a_key_template[5].pValue = (void *) key;
++ a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
++
++ rv = pFuncList->C_CreateObject(session,
++ a_key_template, ul_key_attr_count, &h_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
++ rv);
++ goto err;
++ }
++
++ /*
++ * Save the key information used in this session.
++ * The max can be saved is PK11_KEY_LEN_MAX.
++ */
++ sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
++ PK11_KEY_LEN_MAX : ctx->key_len;
++ (void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
++err:
++
++ return (h_key);
++ }
++
++static int
++md_nid_to_pk11(int nid)
++ {
++ int i;
++
++ for (i = 0; i < PK11_DIGEST_MAX; i++)
++ if (digests[i].nid == nid)
++ return (digests[i].id);
++ return (-1);
++ }
++
++static int
++pk11_digest_init(EVP_MD_CTX *ctx)
++ {
++ CK_RV rv;
++ CK_MECHANISM mech;
++ int index;
++ PK11_SESSION *sp;
++ PK11_DIGEST *pdp;
++ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
++
++ state->sp = NULL;
++
++ index = md_nid_to_pk11(ctx->digest->type);
++ if (index < 0 || index >= PK11_DIGEST_MAX)
++ return (0);
++
++ pdp = &digests[index];
++ if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
++ return (0);
++
++ /* at present, no parameter is needed for supported digests */
++ mech.mechanism = pdp->mech_type;
++ mech.pParameter = NULL;
++ mech.ulParameterLen = 0;
++
++ rv = pFuncList->C_DigestInit(sp->session, &mech);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
++ pk11_return_session(sp, OP_DIGEST);
++ return (0);
++ }
++
++ state->sp = sp;
++
++ return (1);
++ }
++
++static int
++pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
++ {
++ CK_RV rv;
++ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
++
++ /* 0 length message will cause a failure in C_DigestFinal */
++ if (count == 0)
++ return (1);
++
++ if (state == NULL || state->sp == NULL)
++ return (0);
++
++ rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
++ count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
++ pk11_return_session(state->sp, OP_DIGEST);
++ state->sp = NULL;
++ return (0);
++ }
++
++ return (1);
++ }
++
++static int
++pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
++ {
++ CK_RV rv;
++ unsigned long len;
++ PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
++ len = ctx->digest->md_size;
++
++ if (state == NULL || state->sp == NULL)
++ return (0);
++
++ rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
++ pk11_return_session(state->sp, OP_DIGEST);
++ state->sp = NULL;
++ return (0);
++ }
++
++ if (ctx->digest->md_size != len)
++ return (0);
++
++ /*
++ * Final is called and digest is returned, so return the session
++ * to the pool
++ */
++ pk11_return_session(state->sp, OP_DIGEST);
++ state->sp = NULL;
++
++ return (1);
++ }
++
++static int
++pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
++ {
++ CK_RV rv;
++ int ret = 0;
++ PK11_CIPHER_STATE *state, *state_to;
++ CK_BYTE_PTR pstate = NULL;
++ CK_ULONG ul_state_len;
++
++ /* The copy-from state */
++ state = (PK11_CIPHER_STATE *) from->md_data;
++ if (state == NULL || state->sp == NULL)
++ goto err;
++
++ /* Initialize the copy-to state */
++ if (!pk11_digest_init(to))
++ goto err;
++ state_to = (PK11_CIPHER_STATE *) to->md_data;
++
++ /* Get the size of the operation state of the copy-from session */
++ rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
++ &ul_state_len);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
++ rv);
++ goto err;
++ }
++ if (ul_state_len == 0)
++ {
++ goto err;
++ }
++
++ pstate = OPENSSL_malloc(ul_state_len);
++ if (pstate == NULL)
++ {
++ PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ /* Get the operation state of the copy-from session */
++ rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
++ &ul_state_len);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
++ rv);
++ goto err;
++ }
++
++ /* Set the operation state of the copy-to session */
++ rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
++ ul_state_len, 0, 0);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DIGEST_COPY,
++ PK11_R_SET_OPERATION_STATE, rv);
++ goto err;
++ }
++
++ ret = 1;
++err:
++ if (pstate != NULL)
++ OPENSSL_free(pstate);
++
++ return (ret);
++ }
++
++/* Return any pending session state to the pool */
++static int
++pk11_digest_cleanup(EVP_MD_CTX *ctx)
++ {
++ PK11_CIPHER_STATE *state = ctx->md_data;
++ unsigned char buf[EVP_MAX_MD_SIZE];
++
++ if (state != NULL && state->sp != NULL)
++ {
++ /*
++ * If state->sp is not NULL then pk11_digest_final() has not
++ * been called yet. We must call it now to free any memory
++ * that might have been allocated in the token when
++ * pk11_digest_init() was called. pk11_digest_final()
++ * will return the session to the cache.
++ */
++ if (!pk11_digest_final(ctx, buf))
++ return (0);
++ }
++
++ return (1);
++ }
++
++/*
++ * Check if the new key is the same as the key object in the session. If the key
++ * is the same, no need to create a new key object. Otherwise, the old key
++ * object needs to be destroyed and a new one will be created. Return 1 for
++ * cache hit, 0 for cache miss. Note that we must check the key length first
++ * otherwise we could end up reusing a different, longer key with the same
++ * prefix.
++ */
++static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
++ int key_len)
++ {
++ if (sp->opdata_key_len != key_len ||
++ memcmp(sp->opdata_key, key, key_len) != 0)
++ {
++ (void) pk11_destroy_cipher_key_objects(sp);
++ return (0);
++ }
++ return (1);
++ }
++
++/* Destroy one or more secret key objects. */
++static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
++ {
++ int ret = 0;
++ PK11_SESSION *sp = NULL;
++ PK11_SESSION *local_free_session;
++
++ if (session != NULL)
++ local_free_session = session;
++ else
++ {
++#ifndef NOPTHREADS
++ (void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
++#else
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++ local_free_session = session_cache[OP_CIPHER].head;
++ }
++
++ while ((sp = local_free_session) != NULL)
++ {
++ local_free_session = sp->next;
++
++ if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
++ {
++ /*
++ * The secret key object is created in the
++ * global_session. See pk11_get_cipher_key
++ */
++ if (pk11_destroy_object(global_session,
++ sp->opdata_cipher_key) == 0)
++ goto err;
++ sp->opdata_cipher_key = CK_INVALID_HANDLE;
++ }
++ }
++ ret = 1;
++err:
++
++#ifndef NOPTHREADS
++ if (session == NULL)
++ (void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
++#else
++ if (session == NULL)
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
++#endif
++
++ return (ret);
++ }
++
++
++/*
++ * Public key mechanisms optionally supported
++ *
++ * CKM_RSA_X_509
++ * CKM_RSA_PKCS
++ * CKM_DSA
++ *
++ * The first slot that supports at least one of those mechanisms is chosen as a
++ * public key slot.
++ *
++ * Symmetric ciphers optionally supported
++ *
++ * CKM_DES3_CBC
++ * CKM_DES_CBC
++ * CKM_AES_CBC
++ * CKM_DES3_ECB
++ * CKM_DES_ECB
++ * CKM_AES_ECB
++ * CKM_AES_CTR
++ * CKM_RC4
++ * CKM_BLOWFISH_CBC
++ *
++ * Digests optionally supported
++ *
++ * CKM_MD5
++ * CKM_SHA_1
++ * CKM_SHA224
++ * CKM_SHA256
++ * CKM_SHA384
++ * CKM_SHA512
++ *
++ * The output of this function is a set of global variables indicating which
++ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
++ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
++ * variables carry information about which slot was chosen for (a) public key
++ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
++ */
++static int
++pk11_choose_slots(int *any_slot_found)
++ {
++ CK_SLOT_ID_PTR pSlotList = NULL_PTR;
++ CK_ULONG ulSlotCount = 0;
++ CK_MECHANISM_INFO mech_info;
++ CK_TOKEN_INFO token_info;
++ unsigned int i;
++ CK_RV rv;
++ CK_SLOT_ID best_slot_sofar = 0;
++ CK_BBOOL found_candidate_slot = CK_FALSE;
++ int slot_n_cipher = 0;
++ int slot_n_digest = 0;
++ CK_SLOT_ID current_slot = 0;
++ int current_slot_n_cipher = 0;
++ int current_slot_n_digest = 0;
++
++ int local_cipher_nids[PK11_CIPHER_MAX];
++ int local_digest_nids[PK11_DIGEST_MAX];
++
++ /* let's initialize the output parameter */
++ if (any_slot_found != NULL)
++ *any_slot_found = 0;
++
++ /* Get slot list for memory allocation */
++ rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
++ return (0);
++ }
++
++ /* it's not an error if we didn't find any providers */
++ if (ulSlotCount == 0)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ return (1);
++ }
++
++ pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
++
++ if (pSlotList == NULL)
++ {
++ PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
++ return (0);
++ }
++
++ /* Get the slot list for processing */
++ rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
++ OPENSSL_free(pSlotList);
++ return (0);
++ }
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
++ fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
++
++ fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ for (i = 0; i < ulSlotCount; i++)
++ {
++ current_slot = pSlotList[i];
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
++#endif /* DEBUG_SLOT_SELECTION */
++ /* Check if slot has random support. */
++ rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
++ if (rv != CKR_OK)
++ continue;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ if (token_info.flags & CKF_RNG)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ pk11_have_random = CK_TRUE;
++ rand_SLOTID = current_slot;
++ break;
++ }
++ }
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ pubkey_SLOTID = pSlotList[0];
++ for (i = 0; i < ulSlotCount; i++)
++ {
++ CK_BBOOL slot_has_rsa = CK_FALSE;
++ CK_BBOOL slot_has_recover = CK_FALSE;
++ CK_BBOOL slot_has_dsa = CK_FALSE;
++ CK_BBOOL slot_has_dh = CK_FALSE;
++ current_slot = pSlotList[i];
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
++#endif /* DEBUG_SLOT_SELECTION */
++ rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
++ if (rv != CKR_OK)
++ continue;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
++#endif /* DEBUG_SLOT_SELECTION */
++
++#ifndef OPENSSL_NO_RSA
++ /*
++ * Check if this slot is capable of signing and
++ * verifying with CKM_RSA_PKCS.
++ */
++ rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
++ &mech_info);
++
++ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
++ (mech_info.flags & CKF_VERIFY)))
++ {
++ /*
++ * Check if this slot is capable of encryption,
++ * decryption, sign, and verify with CKM_RSA_X_509.
++ */
++ rv = pFuncList->C_GetMechanismInfo(current_slot,
++ CKM_RSA_X_509, &mech_info);
++
++ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
++ (mech_info.flags & CKF_VERIFY) &&
++ (mech_info.flags & CKF_ENCRYPT) &&
++ (mech_info.flags & CKF_DECRYPT)))
++ {
++ slot_has_rsa = CK_TRUE;
++ if (mech_info.flags & CKF_VERIFY_RECOVER)
++ {
++ slot_has_recover = CK_TRUE;
++ }
++ }
++ }
++#endif /* OPENSSL_NO_RSA */
++
++#ifndef OPENSSL_NO_DSA
++ /*
++ * Check if this slot is capable of signing and
++ * verifying with CKM_DSA.
++ */
++ rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
++ &mech_info);
++ if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
++ (mech_info.flags & CKF_VERIFY)))
++ {
++ slot_has_dsa = CK_TRUE;
++ }
++
++#endif /* OPENSSL_NO_DSA */
++
++#ifndef OPENSSL_NO_DH
++ /*
++ * Check if this slot is capable of DH key generataion and
++ * derivation.
++ */
++ rv = pFuncList->C_GetMechanismInfo(current_slot,
++ CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
++
++ if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
++ {
++ rv = pFuncList->C_GetMechanismInfo(current_slot,
++ CKM_DH_PKCS_DERIVE, &mech_info);
++ if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
++ {
++ slot_has_dh = CK_TRUE;
++ }
++ }
++#endif /* OPENSSL_NO_DH */
++
++ if (!found_candidate_slot &&
++ (slot_has_rsa || slot_has_dsa || slot_has_dh))
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: potential slot: %d\n", PK11_DBG, current_slot);
++#endif /* DEBUG_SLOT_SELECTION */
++ best_slot_sofar = current_slot;
++ pk11_have_rsa = slot_has_rsa;
++ pk11_have_recover = slot_has_recover;
++ pk11_have_dsa = slot_has_dsa;
++ pk11_have_dh = slot_has_dh;
++ found_candidate_slot = CK_TRUE;
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: setting found_candidate_slot to CK_TRUE\n",
++ PK11_DBG);
++ fprintf(stderr,
++ "%s: best so far slot: %d\n", PK11_DBG,
++ best_slot_sofar);
++ }
++ else
++ {
++ fprintf(stderr,
++ "%s: no rsa/dsa/dh\n", PK11_DBG);
++ }
++#else
++ } /* if */
++#endif /* DEBUG_SLOT_SELECTION */
++ } /* for */
++
++ if (found_candidate_slot)
++ {
++ pubkey_SLOTID = best_slot_sofar;
++ }
++
++ found_candidate_slot = CK_FALSE;
++ best_slot_sofar = 0;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ SLOTID = pSlotList[0];
++ for (i = 0; i < ulSlotCount; i++)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ current_slot = pSlotList[i];
++ current_slot_n_cipher = 0;
++ current_slot_n_digest = 0;
++ (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
++ (void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
++
++ pk11_find_symmetric_ciphers(pFuncList, current_slot,
++ &current_slot_n_cipher, local_cipher_nids);
++
++ pk11_find_digests(pFuncList, current_slot,
++ &current_slot_n_digest, local_digest_nids);
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
++ current_slot_n_cipher);
++ fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
++ current_slot_n_digest);
++ fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
++ PK11_DBG, best_slot_sofar);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ /*
++ * If the current slot supports more ciphers/digests than
++ * the previous best one we change the current best to this one,
++ * otherwise leave it where it is.
++ */
++ if ((current_slot_n_cipher + current_slot_n_digest) >
++ (slot_n_cipher + slot_n_digest))
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: changing best so far slot to %d\n",
++ PK11_DBG, current_slot);
++#endif /* DEBUG_SLOT_SELECTION */
++ best_slot_sofar = SLOTID = current_slot;
++ cipher_count = slot_n_cipher = current_slot_n_cipher;
++ digest_count = slot_n_digest = current_slot_n_digest;
++ (void) memcpy(cipher_nids, local_cipher_nids,
++ sizeof (local_cipher_nids));
++ (void) memcpy(digest_nids, local_digest_nids,
++ sizeof (local_digest_nids));
++ }
++ }
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr,
++ "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
++ fprintf(stderr,
++ "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
++ fprintf(stderr,
++ "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
++ fprintf(stderr,
++ "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
++ fprintf(stderr,
++ "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
++ fprintf(stderr,
++ "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
++ fprintf(stderr,
++ "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
++ fprintf(stderr,
++ "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
++ fprintf(stderr,
++ "%s: cipher_count %d\n", PK11_DBG, cipher_count);
++ fprintf(stderr,
++ "%s: digest_count %d\n", PK11_DBG, digest_count);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ if (pSlotList != NULL)
++ OPENSSL_free(pSlotList);
++
++#ifdef SOLARIS_HW_SLOT_SELECTION
++ OPENSSL_free(hw_cnids);
++ OPENSSL_free(hw_dnids);
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++
++ if (any_slot_found != NULL)
++ *any_slot_found = 1;
++ return (1);
++ }
++
++static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
++ int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
++ int *local_cipher_nids, int id)
++ {
++ CK_MECHANISM_INFO mech_info;
++ CK_RV rv;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
++#endif /* DEBUG_SLOT_SELECTION */
++ rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
++
++ if (rv != CKR_OK)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, " not found\n");
++#endif /* DEBUG_SLOT_SELECTION */
++ return;
++ }
++
++ if ((mech_info.flags & CKF_ENCRYPT) &&
++ (mech_info.flags & CKF_DECRYPT))
++ {
++#ifdef SOLARIS_HW_SLOT_SELECTION
++ if (nid_in_table(ciphers[id].nid, hw_cnids))
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, " usable\n");
++#endif /* DEBUG_SLOT_SELECTION */
++ local_cipher_nids[(*current_slot_n_cipher)++] =
++ ciphers[id].nid;
++ }
++#ifdef SOLARIS_HW_SLOT_SELECTION
++#ifdef DEBUG_SLOT_SELECTION
++ else
++ {
++ fprintf(stderr, " rejected, software implementation only\n");
++ }
++#endif /* DEBUG_SLOT_SELECTION */
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++ }
++#ifdef DEBUG_SLOT_SELECTION
++ else
++ {
++ fprintf(stderr, " unusable\n");
++ }
++#endif /* DEBUG_SLOT_SELECTION */
++
++ return;
++ }
++
++static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
++ CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
++ int id)
++ {
++ CK_MECHANISM_INFO mech_info;
++ CK_RV rv;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
++#endif /* DEBUG_SLOT_SELECTION */
++ rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
++
++ if (rv != CKR_OK)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, " not found\n");
++#endif /* DEBUG_SLOT_SELECTION */
++ return;
++ }
++
++ if (mech_info.flags & CKF_DIGEST)
++ {
++#ifdef SOLARIS_HW_SLOT_SELECTION
++ if (nid_in_table(digests[id].nid, hw_dnids))
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, " usable\n");
++#endif /* DEBUG_SLOT_SELECTION */
++ local_digest_nids[(*current_slot_n_digest)++] =
++ digests[id].nid;
++ }
++#ifdef SOLARIS_HW_SLOT_SELECTION
++#ifdef DEBUG_SLOT_SELECTION
++ else
++ {
++ fprintf(stderr, " rejected, software implementation only\n");
++ }
++#endif /* DEBUG_SLOT_SELECTION */
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++ }
++#ifdef DEBUG_SLOT_SELECTION
++ else
++ {
++ fprintf(stderr, " unusable\n");
++ }
++#endif /* DEBUG_SLOT_SELECTION */
++
++ return;
++ }
++
++#ifdef SOLARIS_AES_CTR
++/* create a new NID when we have no OID for that mechanism */
++static int pk11_add_NID(char *sn, char *ln)
++ {
++ ASN1_OBJECT *o;
++ int nid;
++
++ if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
++ 1, sn, ln)) == NULL)
++ {
++ return (0);
++ }
++
++ /* will return NID_undef on error */
++ nid = OBJ_add_object(o);
++ ASN1_OBJECT_free(o);
++
++ return (nid);
++ }
++
++/*
++ * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
++ * have to help ourselves here.
++ */
++static int pk11_add_aes_ctr_NIDs(void)
++ {
++ /* are we already set? */
++ if (NID_aes_256_ctr != NID_undef)
++ return (1);
++
++ /*
++ * There are no official names for AES counter modes yet so we just
++ * follow the format of those that exist.
++ */
++ if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
++ NID_undef)
++ goto err;
++ ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
++ if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
++ NID_undef)
++ goto err;
++ ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
++ if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
++ NID_undef)
++ goto err;
++ ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
++ return (1);
++
++err:
++ PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
++ return (0);
++ }
++#endif /* SOLARIS_AES_CTR */
++
++/* Find what symmetric ciphers this slot supports. */
++static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
++ CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
++ {
++ int i;
++
++ for (i = 0; i < PK11_CIPHER_MAX; ++i)
++ {
++ pk11_get_symmetric_cipher(pflist, current_slot,
++ ciphers[i].mech_type, current_slot_n_cipher,
++ local_cipher_nids, ciphers[i].id);
++ }
++ }
++
++/* Find what digest algorithms this slot supports. */
++static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
++ CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
++ {
++ int i;
++
++ for (i = 0; i < PK11_DIGEST_MAX; ++i)
++ {
++ pk11_get_digest(pflist, current_slot, digests[i].mech_type,
++ current_slot_n_digest, local_digest_nids, digests[i].id);
++ }
++ }
++
++#ifdef SOLARIS_HW_SLOT_SELECTION
++/*
++ * It would be great if we could use pkcs11_kernel directly since this library
++ * offers hardware slots only. That's the easiest way to achieve the situation
++ * where we use the hardware accelerators when present and OpenSSL native code
++ * otherwise. That presumes the fact that OpenSSL native code is faster than the
++ * code in the soft token. It's a logical assumption - Crypto Framework has some
++ * inherent overhead so going there for the software implementation of a
++ * mechanism should be logically slower in contrast to the OpenSSL native code,
++ * presuming that both implementations are of similar speed. For example, the
++ * soft token for AES is roughly three times slower than OpenSSL for 64 byte
++ * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
++ * that use the PKCS#11 engine by default, we must somehow avoid that regression
++ * on machines without hardware acceleration. That's why switching to the
++ * pkcs11_kernel library seems like a very good idea.
++ *
++ * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
++ * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
++ * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
++ * library, we would have had a performance regression on machines without
++ * hardware acceleration for asymmetric operations for all applications that use
++ * the PKCS#11 engine. There is one such application - Apache web server since
++ * it's shipped configured to use the PKCS#11 engine by default. Having said
++ * that, we can't switch to the pkcs11_kernel library now and have to come with
++ * a solution that, on non-accelerated machines, uses the OpenSSL native code
++ * for all symmetric ciphers and digests while it uses the soft token for
++ * asymmetric operations.
++ *
++ * This is the idea: dlopen() pkcs11_kernel directly and find out what
++ * mechanisms are there. We don't care about duplications (more slots can
++ * support the same mechanism), we just want to know what mechanisms can be
++ * possibly supported in hardware on that particular machine. As said before,
++ * pkcs11_kernel will show you hardware providers only.
++ *
++ * Then, we rely on the fact that since we use libpkcs11 library we will find
++ * the metaslot. When we go through the metaslot's mechanisms for symmetric
++ * ciphers and digests, we check that any found mechanism is in the table
++ * created using the pkcs11_kernel library. So, as a result we have two arrays
++ * of mechanisms that were advertised as supported in hardware which was the
++ * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
++ * code for symmetric ciphers and digests. See pk11_choose_slots() for more
++ * information.
++ *
++ * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
++ * the code won't be used.
++ */
++#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
++static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
++#else
++static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
++#endif
++
++/*
++ * Check hardware capabilities of the machines. The output are two lists,
++ * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
++ * providers together. They are not sorted and may contain duplicate mechanisms.
++ */
++static int check_hw_mechanisms(void)
++ {
++ int i;
++ CK_RV rv;
++ void *handle;
++ CK_C_GetFunctionList p;
++ CK_TOKEN_INFO token_info;
++ CK_ULONG ulSlotCount = 0;
++ int n_cipher = 0, n_digest = 0;
++ CK_FUNCTION_LIST_PTR pflist = NULL;
++ CK_SLOT_ID_PTR pSlotList = NULL_PTR;
++ int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
++ int hw_ctable_size, hw_dtable_size;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
++ PK11_DBG);
++#endif
++ if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++ if ((p = (CK_C_GetFunctionList)dlsym(handle,
++ PK11_GET_FUNCTION_LIST)) == NULL)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++ /* get the full function list from the loaded library */
++ if (p(&pflist) != CKR_OK)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
++ goto err;
++ }
++
++ rv = pflist->C_Initialize(NULL_PTR);
++ if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
++ {
++ PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
++ PK11_R_INITIALIZE, rv);
++ goto err;
++ }
++
++ if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
++ goto err;
++ }
++
++ /* no slots, set the hw mechanism tables as empty */
++ if (ulSlotCount == 0)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
++#endif
++ hw_cnids = OPENSSL_malloc(sizeof (int));
++ hw_dnids = OPENSSL_malloc(sizeof (int));
++ if (hw_cnids == NULL || hw_dnids == NULL)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS,
++ PK11_R_MALLOC_FAILURE);
++ return (0);
++ }
++ /* this means empty tables */
++ hw_cnids[0] = NID_undef;
++ hw_dnids[0] = NID_undef;
++ return (1);
++ }
++
++ pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
++ if (pSlotList == NULL)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ /* Get the slot list for processing */
++ if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
++ goto err;
++ }
++
++ /*
++ * We don't care about duplicit mechanisms in multiple slots and also
++ * reserve one slot for the terminal NID_undef which we use to stop the
++ * search.
++ */
++ hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
++ hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
++ tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
++ tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
++ if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
++ {
++ PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ /*
++ * Do not use memset since we should not rely on the fact that NID_undef
++ * is zero now.
++ */
++ for (i = 0; i < hw_ctable_size; ++i)
++ tmp_hw_cnids[i] = NID_undef;
++ for (i = 0; i < hw_dtable_size; ++i)
++ tmp_hw_dnids[i] = NID_undef;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
++ fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
++ fprintf(stderr, "%s: now looking for mechs supported in hw\n",
++ PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ for (i = 0; i < ulSlotCount; i++)
++ {
++ if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
++ continue;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
++#endif /* DEBUG_SLOT_SELECTION */
++
++ /*
++ * We are filling the hw mech tables here. Global tables are
++ * still NULL so all mechanisms are put into tmp tables.
++ */
++ pk11_find_symmetric_ciphers(pflist, pSlotList[i],
++ &n_cipher, tmp_hw_cnids);
++ pk11_find_digests(pflist, pSlotList[i],
++ &n_digest, tmp_hw_dnids);
++ }
++
++ /*
++ * Since we are part of a library (libcrypto.so), calling this function
++ * may have side-effects. Also, C_Finalize() is triggered by
++ * dlclose(3C).
++ */
++#if 0
++ pflist->C_Finalize(NULL);
++#endif
++ OPENSSL_free(pSlotList);
++ (void) dlclose(handle);
++ hw_cnids = tmp_hw_cnids;
++ hw_dnids = tmp_hw_dnids;
++
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ return (1);
++
++err:
++ if (pSlotList != NULL)
++ OPENSSL_free(pSlotList);
++ if (tmp_hw_cnids != NULL)
++ OPENSSL_free(tmp_hw_cnids);
++ if (tmp_hw_dnids != NULL)
++ OPENSSL_free(tmp_hw_dnids);
++
++ return (0);
++ }
++
++/*
++ * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
++ * non-existent).
++ */
++static int nid_in_table(int nid, int *nid_table)
++ {
++ int i = 0;
++
++ /*
++ * a special case. NULL means that we are initializing a new
++ * table.
++ */
++ if (nid_table == NULL)
++ return (1);
++
++ /*
++ * the table is never full, there is always at least one
++ * NID_undef.
++ */
++ while (nid_table[i] != NID_undef)
++ {
++ if (nid_table[i++] == nid)
++ {
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
++#endif /* DEBUG_SLOT_SELECTION */
++ return (1);
++ }
++ }
++
++ return (0);
++ }
++#endif /* SOLARIS_HW_SLOT_SELECTION */
++
++#endif /* OPENSSL_NO_HW_PK11 */
++#endif /* OPENSSL_NO_HW */
+Index: openssl/crypto/engine/hw_pk11_err.c
+diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.4
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/hw_pk11_err.c Wed Dec 17 16:14:26 2008
+@@ -0,0 +1,259 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_pk11_err.c */
++/*
++ * This product includes software developed by the OpenSSL Project for
++ * use in the OpenSSL Toolkit (http://www.openssl.org/).
++ *
++ * This project also referenced hw_pkcs11-0.9.7b.patch written by
++ * Afchine Madjlessi.
++ */
++/*
++ * ====================================================================
++ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ * software must display the following acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
++ *
++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
++ * endorse or promote products derived from this software without
++ * prior written permission. For written permission, please contact
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
++
++#include <stdio.h>
++#include <openssl/err.h>
++#include "hw_pk11_err.h"
++
++/* BEGIN ERROR CODES */
++#ifndef OPENSSL_NO_ERR
++static ERR_STRING_DATA pk11_str_functs[]=
++{
++{ ERR_PACK(0, PK11_F_INIT, 0), "PK11_INIT"},
++{ ERR_PACK(0, PK11_F_FINISH, 0), "PK11_FINISH"},
++{ ERR_PACK(0, PK11_F_DESTROY, 0), "PK11_DESTROY"},
++{ ERR_PACK(0, PK11_F_CTRL, 0), "PK11_CTRL"},
++{ ERR_PACK(0, PK11_F_RSA_INIT, 0), "PK11_RSA_INIT"},
++{ ERR_PACK(0, PK11_F_RSA_FINISH, 0), "PK11_RSA_FINISH"},
++{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0), "PK11_GET_PUB_RSA_KEY"},
++{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0), "PK11_GET_PRIV_RSA_KEY"},
++{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0), "PK11_RSA_GEN_KEY"},
++{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0), "PK11_RSA_PUB_ENC"},
++{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0), "PK11_RSA_PRIV_ENC"},
++{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0), "PK11_RSA_PUB_DEC"},
++{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0), "PK11_RSA_PRIV_DEC"},
++{ ERR_PACK(0, PK11_F_RSA_SIGN, 0), "PK11_RSA_SIGN"},
++{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0), "PK11_RSA_VERIFY"},
++{ ERR_PACK(0, PK11_F_RAND_ADD, 0), "PK11_RAND_ADD"},
++{ ERR_PACK(0, PK11_F_RAND_BYTES, 0), "PK11_RAND_BYTES"},
++{ ERR_PACK(0, PK11_F_GET_SESSION, 0), "PK11_GET_SESSION"},
++{ ERR_PACK(0, PK11_F_FREE_SESSION, 0), "PK11_FREE_SESSION"},
++{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0), "PK11_LOAD_PUBKEY"},
++{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0), "PK11_LOAD_PRIV_KEY"},
++{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0), "PK11_RSA_PUB_ENC_LOW"},
++{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0), "PK11_RSA_PRIV_ENC_LOW"},
++{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0), "PK11_RSA_PUB_DEC_LOW"},
++{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0), "PK11_RSA_PRIV_DEC_LOW"},
++{ ERR_PACK(0, PK11_F_DSA_SIGN, 0), "PK11_DSA_SIGN"},
++{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0), "PK11_DSA_VERIFY"},
++{ ERR_PACK(0, PK11_F_DSA_INIT, 0), "PK11_DSA_INIT"},
++{ ERR_PACK(0, PK11_F_DSA_FINISH, 0), "PK11_DSA_FINISH"},
++{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0), "PK11_GET_PUB_DSA_KEY"},
++{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0), "PK11_GET_PRIV_DSA_KEY"},
++{ ERR_PACK(0, PK11_F_DH_INIT, 0), "PK11_DH_INIT"},
++{ ERR_PACK(0, PK11_F_DH_FINISH, 0), "PK11_DH_FINISH"},
++{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0), "PK11_MOD_EXP_DH"},
++{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0), "PK11_GET_DH_KEY"},
++{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0), "PK11_FREE_ALL_SESSIONS"},
++{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0), "PK11_SETUP_SESSION"},
++{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0), "PK11_DESTROY_OBJECT"},
++{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0), "PK11_CIPHER_INIT"},
++{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0), "PK11_CIPHER_DO_CIPHER"},
++{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0), "PK11_GET_CIPHER_KEY"},
++{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0), "PK11_DIGEST_INIT"},
++{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0), "PK11_DIGEST_UPDATE"},
++{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0), "PK11_DIGEST_FINAL"},
++{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0), "PK11_CHOOSE_SLOT"},
++{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0), "PK11_CIPHER_FINAL"},
++{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0), "PK11_LIBRARY_INIT"},
++{ ERR_PACK(0, PK11_F_LOAD, 0), "ENGINE_LOAD_PK11"},
++{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0), "PK11_DH_GEN_KEY"},
++{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0), "PK11_DH_COMP_KEY"},
++{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0), "PK11_DIGEST_COPY"},
++{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0), "PK11_CIPHER_CLEANUP"},
++{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0), "PK11_ACTIVE_ADD"},
++{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0), "PK11_ACTIVE_DELETE"},
++{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0), "PK11_CHECK_HW_MECHANISMS"},
++{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0), "PK11_INIT_SYMMETRIC"},
++{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0), "PK11_ADD_AES_CTR_NIDS"},
++{ 0, NULL}
++};
++
++static ERR_STRING_DATA pk11_str_reasons[]=
++{
++{ PK11_R_ALREADY_LOADED, "PKCS#11 DSO already loaded"},
++{ PK11_R_DSO_FAILURE, "unable to load PKCS#11 DSO"},
++{ PK11_R_NOT_LOADED, "PKCS#11 DSO not loaded"},
++{ PK11_R_PASSED_NULL_PARAMETER, "null parameter passed"},
++{ PK11_R_COMMAND_NOT_IMPLEMENTED, "command not implemented"},
++{ PK11_R_INITIALIZE, "C_Initialize failed"},
++{ PK11_R_FINALIZE, "C_Finalize failed"},
++{ PK11_R_GETINFO, "C_GetInfo faile"},
++{ PK11_R_GETSLOTLIST, "C_GetSlotList failed"},
++{ PK11_R_NO_MODULUS_OR_NO_EXPONENT, "no modulus or no exponent"},
++{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID, "attr sensitive or invalid"},
++{ PK11_R_GETATTRIBUTVALUE, "C_GetAttributeValue failed"},
++{ PK11_R_NO_MODULUS, "no modulus"},
++{ PK11_R_NO_EXPONENT, "no exponent"},
++{ PK11_R_FINDOBJECTSINIT, "C_FindObjectsInit failed"},
++{ PK11_R_FINDOBJECTS, "C_FindObjects failed"},
++{ PK11_R_FINDOBJECTSFINAL, "C_FindObjectsFinal failed"},
++{ PK11_R_CREATEOBJECT, "C_CreateObject failed"},
++{ PK11_R_DESTROYOBJECT, "C_DestroyObject failed"},
++{ PK11_R_OPENSESSION, "C_OpenSession failed"},
++{ PK11_R_CLOSESESSION, "C_CloseSession failed"},
++{ PK11_R_ENCRYPTINIT, "C_EncryptInit failed"},
++{ PK11_R_ENCRYPT, "C_Encrypt failed"},
++{ PK11_R_SIGNINIT, "C_SignInit failed"},
++{ PK11_R_SIGN, "C_Sign failed"},
++{ PK11_R_DECRYPTINIT, "C_DecryptInit failed"},
++{ PK11_R_DECRYPT, "C_Decrypt failed"},
++{ PK11_R_VERIFYINIT, "C_VerifyRecover failed"},
++{ PK11_R_VERIFY, "C_Verify failed"},
++{ PK11_R_VERIFYRECOVERINIT, "C_VerifyRecoverInit failed"},
++{ PK11_R_VERIFYRECOVER, "C_VerifyRecover failed"},
++{ PK11_R_GEN_KEY, "C_GenerateKeyPair failed"},
++{ PK11_R_SEEDRANDOM, "C_SeedRandom failed"},
++{ PK11_R_GENERATERANDOM, "C_GenerateRandom failed"},
++{ PK11_R_INVALID_MESSAGE_LENGTH, "invalid message length"},
++{ PK11_R_UNKNOWN_ALGORITHM_TYPE, "unknown algorithm type"},
++{ PK11_R_UNKNOWN_ASN1_OBJECT_ID, "unknown asn1 onject id"},
++{ PK11_R_UNKNOWN_PADDING_TYPE, "unknown padding type"},
++{ PK11_R_PADDING_CHECK_FAILED, "padding check failed"},
++{ PK11_R_DIGEST_TOO_BIG, "digest too big"},
++{ PK11_R_MALLOC_FAILURE, "malloc failure"},
++{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctl command not implemented"},
++{ PK11_R_DATA_GREATER_THAN_MOD_LEN, "data is bigger than mod"},
++{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS, "data is too larger for mod"},
++{ PK11_R_MISSING_KEY_COMPONENT, "a dsa component is missing"},
++{ PK11_R_INVALID_SIGNATURE_LENGTH, "invalid signature length"},
++{ PK11_R_INVALID_DSA_SIGNATURE_R, "missing r in dsa verify"},
++{ PK11_R_INVALID_DSA_SIGNATURE_S, "missing s in dsa verify"},
++{ PK11_R_INCONSISTENT_KEY, "inconsistent key type"},
++{ PK11_R_ENCRYPTUPDATE, "C_EncryptUpdate failed"},
++{ PK11_R_DECRYPTUPDATE, "C_DecryptUpdate failed"},
++{ PK11_R_DIGESTINIT, "C_DigestInit failed"},
++{ PK11_R_DIGESTUPDATE, "C_DigestUpdate failed"},
++{ PK11_R_DIGESTFINAL, "C_DigestFinal failed"},
++{ PK11_R_ENCRYPTFINAL, "C_EncryptFinal failed"},
++{ PK11_R_DECRYPTFINAL, "C_DecryptFinal failed"},
++{ PK11_R_NO_PRNG_SUPPORT, "Slot does not support PRNG"},
++{ PK11_R_GETTOKENINFO, "C_GetTokenInfo failed"},
++{ PK11_R_DERIVEKEY, "C_DeriveKey failed"},
++{ PK11_R_GET_OPERATION_STATE, "C_GetOperationState failed"},
++{ PK11_R_SET_OPERATION_STATE, "C_SetOperationState failed"},
++{ PK11_R_INVALID_PIN, "invalid PIN"},
++{ PK11_R_TOO_MANY_OBJECTS, "too many objects"},
++{ PK11_R_OBJECT_NOT_FOUND, "object not found"},
++{ PK11_R_INVALID_HANDLE, "invalid PKCS#11 object handle"},
++{ PK11_R_KEY_OR_IV_LEN_PROBLEM, "IV or key length incorrect"},
++{ PK11_R_INVALID_OPERATION_TYPE, "invalid operation type"},
++{ PK11_R_ADD_NID_FAILED, "failed to add NID" },
++{ 0, NULL}
++};
++#endif /* OPENSSL_NO_ERR */
++
++static int pk11_lib_error_code = 0;
++static int pk11_error_init = 1;
++
++static void
++ERR_load_pk11_strings(void)
++ {
++ if (pk11_lib_error_code == 0)
++ pk11_lib_error_code = ERR_get_next_error_library();
++
++ if (pk11_error_init)
++ {
++ pk11_error_init = 0;
++#ifndef OPENSSL_NO_ERR
++ ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
++ ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
++#endif
++ }
++}
++
++static void
++ERR_unload_pk11_strings(void)
++ {
++ if (pk11_error_init == 0)
++ {
++#ifndef OPENSSL_NO_ERR
++ ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
++ ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
++#endif
++ pk11_error_init = 1;
++ }
++}
++
++void
++ERR_pk11_error(int function, int reason, char *file, int line)
++{
++ if (pk11_lib_error_code == 0)
++ pk11_lib_error_code = ERR_get_next_error_library();
++ ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
++}
++
++void
++PK11err_add_data(int function, int reason, CK_RV rv)
++{
++ char tmp_buf[20];
++
++ PK11err(function, reason);
++ (void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
++ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
++}
+Index: openssl/crypto/engine/hw_pk11_err.h
+diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.9
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/hw_pk11_err.h Wed Dec 17 15:01:45 2008
+@@ -0,0 +1,402 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_pk11_err.h */
++/*
++ * This product includes software developed by the OpenSSL Project for
++ * use in the OpenSSL Toolkit (http://www.openssl.org/).
++ *
++ * This project also referenced hw_pkcs11-0.9.7b.patch written by
++ * Afchine Madjlessi.
++ */
++/*
++ * ====================================================================
++ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ * software must display the following acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
++ *
++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
++ * endorse or promote products derived from this software without
++ * prior written permission. For written permission, please contact
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
++
++#ifndef HW_PK11_ERR_H
++#define HW_PK11_ERR_H
++
++void ERR_pk11_error(int function, int reason, char *file, int line);
++void PK11err_add_data(int function, int reason, CK_RV rv);
++#define PK11err(f, r) ERR_pk11_error((f), (r), __FILE__, __LINE__)
++
++/* Error codes for the PK11 functions. */
++
++/* Function codes. */
++
++#define PK11_F_INIT 100
++#define PK11_F_FINISH 101
++#define PK11_F_DESTROY 102
++#define PK11_F_CTRL 103
++#define PK11_F_RSA_INIT 104
++#define PK11_F_RSA_FINISH 105
++#define PK11_F_GET_PUB_RSA_KEY 106
++#define PK11_F_GET_PRIV_RSA_KEY 107
++#define PK11_F_RSA_GEN_KEY 108
++#define PK11_F_RSA_PUB_ENC 109
++#define PK11_F_RSA_PRIV_ENC 110
++#define PK11_F_RSA_PUB_DEC 111
++#define PK11_F_RSA_PRIV_DEC 112
++#define PK11_F_RSA_SIGN 113
++#define PK11_F_RSA_VERIFY 114
++#define PK11_F_RAND_ADD 115
++#define PK11_F_RAND_BYTES 116
++#define PK11_F_GET_SESSION 117
++#define PK11_F_FREE_SESSION 118
++#define PK11_F_LOAD_PUBKEY 119
++#define PK11_F_LOAD_PRIVKEY 120
++#define PK11_F_RSA_PUB_ENC_LOW 121
++#define PK11_F_RSA_PRIV_ENC_LOW 122
++#define PK11_F_RSA_PUB_DEC_LOW 123
++#define PK11_F_RSA_PRIV_DEC_LOW 124
++#define PK11_F_DSA_SIGN 125
++#define PK11_F_DSA_VERIFY 126
++#define PK11_F_DSA_INIT 127
++#define PK11_F_DSA_FINISH 128
++#define PK11_F_GET_PUB_DSA_KEY 129
++#define PK11_F_GET_PRIV_DSA_KEY 130
++#define PK11_F_DH_INIT 131
++#define PK11_F_DH_FINISH 132
++#define PK11_F_MOD_EXP_DH 133
++#define PK11_F_GET_DH_KEY 134
++#define PK11_F_FREE_ALL_SESSIONS 135
++#define PK11_F_SETUP_SESSION 136
++#define PK11_F_DESTROY_OBJECT 137
++#define PK11_F_CIPHER_INIT 138
++#define PK11_F_CIPHER_DO_CIPHER 139
++#define PK11_F_GET_CIPHER_KEY 140
++#define PK11_F_DIGEST_INIT 141
++#define PK11_F_DIGEST_UPDATE 142
++#define PK11_F_DIGEST_FINAL 143
++#define PK11_F_CHOOSE_SLOT 144
++#define PK11_F_CIPHER_FINAL 145
++#define PK11_F_LIBRARY_INIT 146
++#define PK11_F_LOAD 147
++#define PK11_F_DH_GEN_KEY 148
++#define PK11_F_DH_COMP_KEY 149
++#define PK11_F_DIGEST_COPY 150
++#define PK11_F_CIPHER_CLEANUP 151
++#define PK11_F_ACTIVE_ADD 152
++#define PK11_F_ACTIVE_DELETE 153
++#define PK11_F_CHECK_HW_MECHANISMS 154
++#define PK11_F_INIT_SYMMETRIC 155
++#define PK11_F_ADD_AES_CTR_NIDS 156
++#define PK11_F_INIT_ALL_LOCKS 157
++#define PK11_F_RETURN_SESSION 158
++
++/* Reason codes. */
++#define PK11_R_ALREADY_LOADED 100
++#define PK11_R_DSO_FAILURE 101
++#define PK11_R_NOT_LOADED 102
++#define PK11_R_PASSED_NULL_PARAMETER 103
++#define PK11_R_COMMAND_NOT_IMPLEMENTED 104
++#define PK11_R_INITIALIZE 105
++#define PK11_R_FINALIZE 106
++#define PK11_R_GETINFO 107
++#define PK11_R_GETSLOTLIST 108
++#define PK11_R_NO_MODULUS_OR_NO_EXPONENT 109
++#define PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 110
++#define PK11_R_GETATTRIBUTVALUE 111
++#define PK11_R_NO_MODULUS 112
++#define PK11_R_NO_EXPONENT 113
++#define PK11_R_FINDOBJECTSINIT 114
++#define PK11_R_FINDOBJECTS 115
++#define PK11_R_FINDOBJECTSFINAL 116
++#define PK11_R_CREATEOBJECT 118
++#define PK11_R_DESTROYOBJECT 119
++#define PK11_R_OPENSESSION 120
++#define PK11_R_CLOSESESSION 121
++#define PK11_R_ENCRYPTINIT 122
++#define PK11_R_ENCRYPT 123
++#define PK11_R_SIGNINIT 124
++#define PK11_R_SIGN 125
++#define PK11_R_DECRYPTINIT 126
++#define PK11_R_DECRYPT 127
++#define PK11_R_VERIFYINIT 128
++#define PK11_R_VERIFY 129
++#define PK11_R_VERIFYRECOVERINIT 130
++#define PK11_R_VERIFYRECOVER 131
++#define PK11_R_GEN_KEY 132
++#define PK11_R_SEEDRANDOM 133
++#define PK11_R_GENERATERANDOM 134
++#define PK11_R_INVALID_MESSAGE_LENGTH 135
++#define PK11_R_UNKNOWN_ALGORITHM_TYPE 136
++#define PK11_R_UNKNOWN_ASN1_OBJECT_ID 137
++#define PK11_R_UNKNOWN_PADDING_TYPE 138
++#define PK11_R_PADDING_CHECK_FAILED 139
++#define PK11_R_DIGEST_TOO_BIG 140
++#define PK11_R_MALLOC_FAILURE 141
++#define PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 142
++#define PK11_R_DATA_GREATER_THAN_MOD_LEN 143
++#define PK11_R_DATA_TOO_LARGE_FOR_MODULUS 144
++#define PK11_R_MISSING_KEY_COMPONENT 145
++#define PK11_R_INVALID_SIGNATURE_LENGTH 146
++#define PK11_R_INVALID_DSA_SIGNATURE_R 147
++#define PK11_R_INVALID_DSA_SIGNATURE_S 148
++#define PK11_R_INCONSISTENT_KEY 149
++#define PK11_R_ENCRYPTUPDATE 150
++#define PK11_R_DECRYPTUPDATE 151
++#define PK11_R_DIGESTINIT 152
++#define PK11_R_DIGESTUPDATE 153
++#define PK11_R_DIGESTFINAL 154
++#define PK11_R_ENCRYPTFINAL 155
++#define PK11_R_DECRYPTFINAL 156
++#define PK11_R_NO_PRNG_SUPPORT 157
++#define PK11_R_GETTOKENINFO 158
++#define PK11_R_DERIVEKEY 159
++#define PK11_R_GET_OPERATION_STATE 160
++#define PK11_R_SET_OPERATION_STATE 161
++#define PK11_R_INVALID_HANDLE 162
++#define PK11_R_KEY_OR_IV_LEN_PROBLEM 163
++#define PK11_R_INVALID_OPERATION_TYPE 164
++#define PK11_R_ADD_NID_FAILED 165
++#define PK11_R_ATFORK_FAILED 166
++#define PK11_R_INVALID_PIN 167
++#define PK11_R_TOO_MANY_OBJECTS 168
++#define PK11_R_OBJECT_NOT_FOUND 169
++
++/* max byte length of a symetric key we support */
++#define PK11_KEY_LEN_MAX 32
++
++#ifdef NOPTHREADS
++/*
++ * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
++ * free_session list and active_list but generally serves as a global
++ * per-process lock for the whole engine.
++ *
++ * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
++ * the global engine lock. This is not optimal w.r.t. performance but
++ * it's safe.
++ */
++#define CRYPTO_LOCK_PK11_ENGINE CRYPTO_LOCK_EC
++#endif
++
++/*
++ * This structure encapsulates all reusable information for a PKCS#11
++ * session. A list of these objects is created on behalf of the
++ * calling application using an on-demand method. Each operation
++ * type (see PK11_OPTYPE below) has its own per-process list.
++ * Each of the lists is basically a cache for faster PKCS#11 object
++ * access to avoid expensive C_Find{,Init,Final}Object() calls.
++ *
++ * When a new request comes in, an object will be taken from the list
++ * (if there is one) or a new one is created to handle the request
++ * (if the list is empty). See pk11_get_session() on how it is done.
++ */
++typedef struct PK11_st_SESSION
++ {
++ struct PK11_st_SESSION *next;
++ CK_SESSION_HANDLE session; /* PK11 session handle */
++ pid_t pid; /* Current process ID */
++ union
++ {
++#ifndef OPENSSL_NO_RSA
++ struct
++ {
++ CK_OBJECT_HANDLE rsa_pub_key; /* pub handle */
++ CK_OBJECT_HANDLE rsa_priv_key; /* priv handle */
++ RSA *rsa_pub; /* pub key addr */
++ BIGNUM *rsa_n_num; /* pub modulus */
++ BIGNUM *rsa_e_num; /* pub exponent */
++ RSA *rsa_priv; /* priv key addr */
++ BIGNUM *rsa_d_num; /* priv exponent */
++ } u_RSA;
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++ struct
++ {
++ CK_OBJECT_HANDLE dsa_pub_key; /* pub handle */
++ CK_OBJECT_HANDLE dsa_priv_key; /* priv handle */
++ DSA *dsa_pub; /* pub key addr */
++ BIGNUM *dsa_pub_num; /* pub key */
++ DSA *dsa_priv; /* priv key addr */
++ BIGNUM *dsa_priv_num; /* priv key */
++ } u_DSA;
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++ struct
++ {
++ CK_OBJECT_HANDLE dh_key; /* key handle */
++ DH *dh; /* dh key addr */
++ BIGNUM *dh_priv_num; /* priv dh key */
++ } u_DH;
++#endif /* OPENSSL_NO_DH */
++ struct
++ {
++ CK_OBJECT_HANDLE cipher_key; /* key handle */
++ unsigned char key[PK11_KEY_LEN_MAX];
++ int key_len; /* priv key len */
++ int encrypt; /* 1/0 enc/decr */
++ } u_cipher;
++ } opdata_u;
++ } PK11_SESSION;
++
++#define opdata_rsa_pub_key opdata_u.u_RSA.rsa_pub_key
++#define opdata_rsa_priv_key opdata_u.u_RSA.rsa_priv_key
++#define opdata_rsa_pub opdata_u.u_RSA.rsa_pub
++#define opdata_rsa_priv opdata_u.u_RSA.rsa_priv
++#define opdata_rsa_n_num opdata_u.u_RSA.rsa_n_num
++#define opdata_rsa_e_num opdata_u.u_RSA.rsa_e_num
++#define opdata_rsa_d_num opdata_u.u_RSA.rsa_d_num
++#define opdata_dsa_pub_key opdata_u.u_DSA.dsa_pub_key
++#define opdata_dsa_priv_key opdata_u.u_DSA.dsa_priv_key
++#define opdata_dsa_pub opdata_u.u_DSA.dsa_pub
++#define opdata_dsa_pub_num opdata_u.u_DSA.dsa_pub_num
++#define opdata_dsa_priv opdata_u.u_DSA.dsa_priv
++#define opdata_dsa_priv_num opdata_u.u_DSA.dsa_priv_num
++#define opdata_dh_key opdata_u.u_DH.dh_key
++#define opdata_dh opdata_u.u_DH.dh
++#define opdata_dh_priv_num opdata_u.u_DH.dh_priv_num
++#define opdata_cipher_key opdata_u.u_cipher.cipher_key
++#define opdata_key opdata_u.u_cipher.key
++#define opdata_key_len opdata_u.u_cipher.key_len
++#define opdata_encrypt opdata_u.u_cipher.encrypt
++
++/*
++ * We have 3 different groups of operation types:
++ * 1) asymmetric operations
++ * 2) random operations
++ * 3) symmetric and digest operations
++ *
++ * This division into groups stems from the fact that it's common that hardware
++ * providers may support operations from one group only. For example, hardware
++ * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
++ * only a single group of operations.
++ *
++ * For every group a different slot can be chosen. That means that we must have
++ * at least 3 different lists of cached PKCS#11 sessions since sessions from
++ * different groups may be initialized in different slots.
++ *
++ * To provide locking granularity in multithreaded environment, the groups are
++ * further splitted into types with each type having a separate session cache.
++ */
++typedef enum PK11_OPTYPE_ENUM
++ {
++ OP_RAND,
++ OP_RSA,
++ OP_DSA,
++ OP_DH,
++ OP_CIPHER,
++ OP_DIGEST,
++ OP_MAX
++ } PK11_OPTYPE;
++
++/*
++ * This structure contains the heads of the lists forming the object caches
++ * and locks associated with the lists.
++ */
++typedef struct PK11_st_CACHE
++ {
++ PK11_SESSION *head;
++#ifndef NOPTHREADS
++ pthread_mutex_t *lock;
++#endif
++ } PK11_CACHE;
++
++/* structure for tracking handles of asymmetric key objects */
++typedef struct PK11_active_st
++ {
++ CK_OBJECT_HANDLE h;
++ unsigned int refcnt;
++ struct PK11_active_st *prev;
++ struct PK11_active_st *next;
++ } PK11_active;
++
++#ifndef NOPTHREADS
++extern pthread_mutex_t *find_lock[];
++#endif
++extern PK11_active *active_list[];
++
++#ifndef NOPTHREADS
++#define LOCK_OBJSTORE(alg_type) \
++ (void) pthread_mutex_lock(find_lock[alg_type])
++#define UNLOCK_OBJSTORE(alg_type) \
++ (void) pthread_mutex_unlock(find_lock[alg_type])
++#else
++#define LOCK_OBJSTORE(alg_type) \
++ CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
++#define UNLOCK_OBJSTORE(alg_type) \
++ CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
++#endif
++
++extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
++extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
++
++#ifndef OPENSSL_NO_RSA
++extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
++extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
++extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
++extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data);
++extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data);
++extern RSA_METHOD *PK11_RSA(void);
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
++extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
++extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
++extern DSA_METHOD *PK11_DSA(void);
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
++extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
++extern DH_METHOD *PK11_DH(void);
++#endif /* OPENSSL_NO_DH */
++
++extern CK_FUNCTION_LIST_PTR pFuncList;
++
++#endif /* HW_PK11_ERR_H */
+Index: openssl/crypto/engine/hw_pk11_pub-kp.c
+diff -u /dev/null openssl/crypto/engine/hw_pk11_pub-kp.c:1.21
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/hw_pk11_pub-kp.c Tue Sep 1 06:02:18 2009
+@@ -0,0 +1,896 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_pk11_pub.c */
++/*
++ * This product includes software developed by the OpenSSL Project for
++ * use in the OpenSSL Toolkit (http://www.openssl.org/).
++ *
++ * This project also referenced hw_pkcs11-0.9.7b.patch written by
++ * Afchine Madjlessi.
++ */
++/*
++ * ====================================================================
++ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ * software must display the following acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
++ *
++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
++ * endorse or promote products derived from this software without
++ * prior written permission. For written permission, please contact
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
++
++/* Modified to keep only RNG and RSA Sign */
++
++#ifdef OPENSSL_NO_RSA
++#error RSA is disabled
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++
++#include <openssl/e_os2.h>
++#include <openssl/crypto.h>
++#include <cryptlib.h>
++#include <openssl/engine.h>
++#include <openssl/dso.h>
++#include <openssl/err.h>
++#include <openssl/bn.h>
++#include <openssl/pem.h>
++#include <openssl/rsa.h>
++#include <openssl/rand.h>
++#include <openssl/objects.h>
++#include <openssl/x509.h>
++
++#ifdef OPENSSL_SYS_WIN32
++#define NOPTHREADS
++typedef int pid_t;
++#define HAVE_GETPASSPHRASE
++static char *getpassphrase(const char *prompt);
++#ifndef NULL_PTR
++#define NULL_PTR NULL
++#endif
++#define CK_DEFINE_FUNCTION(returnType, name) \
++ returnType __declspec(dllexport) name
++#define CK_DECLARE_FUNCTION(returnType, name) \
++ returnType __declspec(dllimport) name
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ returnType __declspec(dllimport) (* name)
++#else
++#include <unistd.h>
++#endif
++
++#ifndef NOPTHREADS
++#include <pthread.h>
++#endif
++
++#ifndef OPENSSL_NO_HW
++#ifndef OPENSSL_NO_HW_PK11
++
++#ifndef OPENSSL_NO_DSA
++#define OPENSSL_NO_DSA
++#endif
++#ifndef OPENSSL_NO_DH
++#define OPENSSL_NO_DH
++#endif
++
++#ifdef OPENSSL_SYS_WIN32
++#pragma pack(push, cryptoki, 1)
++#include "cryptoki.h"
++#include "pkcs11.h"
++#pragma pack(pop, cryptoki)
++#else
++#include "cryptoki.h"
++#include "pkcs11.h"
++#endif
++#include "hw_pk11_err.h"
++
++#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
++#define getpassphrase(x) getpass(x)
++#endif
++
++/* RSA stuff */
++static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
++ unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
++EVP_PKEY *pk11_load_privkey(ENGINE*, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data);
++EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data);
++
++static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
++ BIGNUM **rsa_d_num, CK_SESSION_HANDLE session);
++
++static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
++static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
++
++static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
++
++/* Read mode string to be used for fopen() */
++#if SOLARIS_OPENSSL
++static char *read_mode_flags = "rF";
++#else
++static char *read_mode_flags = "r";
++#endif
++
++/*
++ * increment/create reference for an asymmetric key handle via active list
++ * manipulation. If active list operation fails, unlock (if locked), set error
++ * variable and jump to the specified label.
++ */
++#define KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label) \
++ { \
++ if (pk11_active_add(key_handle, alg_type) < 0) \
++ { \
++ var = TRUE; \
++ if (unlock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ goto label; \
++ } \
++ }
++
++/*
++ * Find active list entry according to object handle and return pointer to the
++ * entry otherwise return NULL.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
++ {
++ PK11_active *entry;
++
++ for (entry = active_list[type]; entry != NULL; entry = entry->next)
++ if (entry->h == h)
++ return (entry);
++
++ return (NULL);
++ }
++
++/*
++ * Search for an entry in the active list using PKCS#11 object handle as a
++ * search key and return refcnt of the found/created entry or -1 in case of
++ * failure.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++int
++pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
++ {
++ PK11_active *entry = NULL;
++
++ if (h == CK_INVALID_HANDLE)
++ {
++ PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
++ return (-1);
++ }
++
++ /* search for entry in the active list */
++ if ((entry = pk11_active_find(h, type)) != NULL)
++ entry->refcnt++;
++ else
++ {
++ /* not found, create new entry and add it to the list */
++ entry = OPENSSL_malloc(sizeof (PK11_active));
++ if (entry == NULL)
++ {
++ PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
++ return (-1);
++ }
++ entry->h = h;
++ entry->refcnt = 1;
++ entry->prev = NULL;
++ entry->next = NULL;
++ /* connect the newly created entry to the list */
++ if (active_list[type] == NULL)
++ active_list[type] = entry;
++ else /* make the entry first in the list */
++ {
++ entry->next = active_list[type];
++ active_list[type]->prev = entry;
++ active_list[type] = entry;
++ }
++ }
++
++ return (entry->refcnt);
++ }
++
++/*
++ * Remove active list entry from the list and free it.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++void
++pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
++ {
++ PK11_active *prev_entry;
++
++ /* remove the entry from the list and free it */
++ if ((prev_entry = entry->prev) != NULL)
++ {
++ prev_entry->next = entry->next;
++ if (entry->next != NULL)
++ entry->next->prev = prev_entry;
++ }
++ else
++ {
++ active_list[type] = entry->next;
++ /* we were the first but not the only one */
++ if (entry->next != NULL)
++ entry->next->prev = NULL;
++ }
++
++ /* sanitization */
++ entry->h = CK_INVALID_HANDLE;
++ entry->prev = NULL;
++ entry->next = NULL;
++ OPENSSL_free(entry);
++ }
++
++/* Free all entries from the active list. */
++void
++pk11_free_active_list(PK11_OPTYPE type)
++ {
++ PK11_active *entry;
++
++ /* only for asymmetric types since only they have C_Find* locks. */
++ switch (type)
++ {
++ case OP_RSA:
++ break;
++ default:
++ return;
++ }
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(type);
++ while ((entry = active_list[type]) != NULL)
++ pk11_active_remove(entry, type);
++ UNLOCK_OBJSTORE(type);
++ }
++
++/*
++ * Search for active list entry associated with given PKCS#11 object handle,
++ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
++ *
++ * Return 1 if the PKCS#11 object associated with the entry has no references,
++ * return 0 if there is at least one reference, -1 on error.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++int
++pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
++ {
++ PK11_active *entry = NULL;
++
++ if ((entry = pk11_active_find(h, type)) == NULL)
++ {
++ PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
++ return (-1);
++ }
++
++ OPENSSL_assert(entry->refcnt > 0);
++ entry->refcnt--;
++ if (entry->refcnt == 0)
++ {
++ pk11_active_remove(entry, type);
++ return (1);
++ }
++
++ return (0);
++ }
++
++/* Our internal RSA_METHOD that we provide pointers to */
++static RSA_METHOD pk11_rsa;
++
++RSA_METHOD *
++PK11_RSA(void)
++ {
++ const RSA_METHOD *rsa;
++
++ if (pk11_rsa.name == NULL)
++ {
++ rsa = RSA_PKCS1_SSLeay();
++ memcpy(&pk11_rsa, rsa, sizeof(*rsa));
++ pk11_rsa.name = "PKCS#11 RSA method";
++ pk11_rsa.rsa_sign = pk11_RSA_sign;
++ }
++ return (&pk11_rsa);
++ }
++
++/* Size of an SSL signature: MD5+SHA1 */
++#define SSL_SIG_LENGTH 36
++
++/*
++ * Standard engine interface function. Majority codes here are from
++ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
++ * See more details in rsa/rsa_sign.c
++ */
++static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
++ unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
++ {
++ X509_SIG sig;
++ ASN1_TYPE parameter;
++ int i, j = 0;
++ unsigned char *p, *s = NULL;
++ X509_ALGOR algor;
++ ASN1_OCTET_STRING digest;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_priv_key;
++ PK11_SESSION *sp = NULL;
++ int ret = 0;
++ unsigned long ulsiglen;
++
++ /* Encode the digest */
++ /* Special case: SSL signature, just check the length */
++ if (type == NID_md5_sha1)
++ {
++ if (m_len != SSL_SIG_LENGTH)
++ {
++ PK11err(PK11_F_RSA_SIGN,
++ PK11_R_INVALID_MESSAGE_LENGTH);
++ goto err;
++ }
++ i = SSL_SIG_LENGTH;
++ s = (unsigned char *)m;
++ }
++ else
++ {
++ sig.algor = &algor;
++ sig.algor->algorithm = OBJ_nid2obj(type);
++ if (sig.algor->algorithm == NULL)
++ {
++ PK11err(PK11_F_RSA_SIGN,
++ PK11_R_UNKNOWN_ALGORITHM_TYPE);
++ goto err;
++ }
++ if (sig.algor->algorithm->length == 0)
++ {
++ PK11err(PK11_F_RSA_SIGN,
++ PK11_R_UNKNOWN_ASN1_OBJECT_ID);
++ goto err;
++ }
++ parameter.type = V_ASN1_NULL;
++ parameter.value.ptr = NULL;
++ sig.algor->parameter = &parameter;
++
++ sig.digest = &digest;
++ sig.digest->data = (unsigned char *)m;
++ sig.digest->length = m_len;
++
++ i = i2d_X509_SIG(&sig, NULL);
++ }
++
++ j = RSA_size(rsa);
++ if ((i - RSA_PKCS1_PADDING) > j)
++ {
++ PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
++ goto err;
++ }
++
++ if (type != NID_md5_sha1)
++ {
++ s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
++ if (s == NULL)
++ {
++ PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ p = s;
++ (void) i2d_X509_SIG(&sig, &p);
++ }
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ goto err;
++
++ (void) check_new_rsa_key_priv(sp, rsa);
++
++ h_priv_key = sp->opdata_rsa_priv_key;
++ if (h_priv_key == CK_INVALID_HANDLE)
++ h_priv_key = sp->opdata_rsa_priv_key =
++ pk11_get_private_rsa_key((RSA *)rsa,
++ &sp->opdata_rsa_priv,
++ &sp->opdata_rsa_d_num, sp->session);
++
++ if (h_priv_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
++ goto err;
++ }
++
++ ulsiglen = j;
++ rv = pFuncList->C_Sign(sp->session, s, i, sigret,
++ (CK_ULONG_PTR) &ulsiglen);
++ *siglen = ulsiglen;
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
++ goto err;
++ }
++ ret = 1;
++ }
++
++err:
++ if ((type != NID_md5_sha1) && (s != NULL))
++ {
++ (void) memset(s, 0, (unsigned int)(j + 1));
++ OPENSSL_free(s);
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (ret);
++ }
++
++static int hndidx_rsa = -1;
++
++/* load RSA private key from a file */
++/* ARGSUSED */
++EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
++ UI_METHOD *ui_method, void *callback_data)
++ {
++ EVP_PKEY *pkey = NULL;
++ FILE *privkey;
++ RSA *rsa;
++ PK11_SESSION *sp = NULL;
++ /* everything else below needed for key by reference extension */
++ CK_RV rv;
++ CK_ULONG objcnt = 0;
++ CK_BBOOL is_token = TRUE;
++ CK_BYTE attr_data[2][1024];
++ CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
++ CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */
++ extern char *pk11_pin;
++
++ /* we look for private keys only */
++ CK_ATTRIBUTE search_templ[] =
++ {
++ {CKA_TOKEN, &is_token, sizeof(is_token)},
++ {CKA_CLASS, &key_class, sizeof(key_class)},
++ {CKA_LABEL, NULL, 0}
++ };
++
++ /* these attributes are needed to initialize OpenSSL RSA structure */
++ CK_ATTRIBUTE get_templ[] =
++ {
++ {CKA_MODULUS, (void *)attr_data[0], 1024}, /* n */
++ {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024}, /* e */
++ };
++
++ /*
++ * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
++ */
++ if (strstr(privkey_file, "pkcs11:") == privkey_file)
++ {
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (NULL);
++
++ search_templ[2].pValue = strstr(privkey_file, ":") + 1;
++ search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
++
++ if (pk11_pin == NULL)
++ {
++ pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
++
++ if (pk11_pin == NULL)
++ {
++ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ }
++ if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
++ strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
++ {
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_INVALID_PIN, rv);
++ goto err;
++ }
++
++ LOCK_OBJSTORE(OP_RSA);
++ if ((rv = pFuncList->C_FindObjectsInit(sp->session,
++ search_templ, 3)) != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
++ if (rv != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ if (objcnt > 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_TOO_MANY_OBJECTS);
++ goto err;
++ }
++
++ if (objcnt != 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_OBJECT_NOT_FOUND);
++ goto err;
++ }
++
++ (void) pFuncList->C_FindObjectsFinal(sp->session);
++ UNLOCK_OBJSTORE(OP_RSA);
++
++ if (hndidx_rsa == -1)
++ hndidx_rsa = RSA_get_ex_new_index(0,
++ "pkcs11 RSA HSM key handle",
++ NULL, NULL, NULL);
++
++ pkey = EVP_PKEY_new();
++ if (pkey == NULL)
++ goto err;
++
++ rsa = RSA_new_method(e);
++ if (rsa == NULL) {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ goto err;
++ }
++ EVP_PKEY_set1_RSA(pkey, rsa);
++
++ if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
++ get_templ, 2)) != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ goto err;
++ }
++
++ /* Note: these flags are critical! */
++ rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
++ RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
++ (void) check_new_rsa_key_priv(sp, rsa);
++ sp->opdata_rsa_priv = rsa;
++ sp->opdata_rsa_priv_key = ks_key;
++
++ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
++ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
++ }
++ else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
++ {
++ pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
++ (void) fclose(privkey);
++ }
++
++err:
++ if (sp != NULL)
++ pk11_return_session(sp, OP_RSA);
++ return (pkey);
++ }
++
++/* load RSA public key from a file */
++/* ARGSUSED */
++EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data)
++ {
++ EVP_PKEY *pkey = NULL;
++ FILE *pubkey;
++ RSA *rsa;
++ PK11_SESSION *sp = NULL;
++ /* everything else below needed for key by reference extension */
++ CK_RV rv;
++ CK_ULONG objcnt = 0;
++ CK_BBOOL is_token = TRUE;
++ CK_BYTE attr_data[2][1024];
++ CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
++ CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */
++ extern char *pk11_pin;
++
++ /* we look for public keys only */
++ CK_ATTRIBUTE search_templ[] =
++ {
++ {CKA_TOKEN, &is_token, sizeof(is_token)},
++ {CKA_CLASS, &key_class, sizeof(key_class)},
++ {CKA_LABEL, NULL, 0}
++ };
++
++ /* these attributes are needed to initialize OpenSSL RSA structure */
++ CK_ATTRIBUTE get_templ[] =
++ {
++ {CKA_MODULUS, (void *)attr_data[0], 1024}, /* n */
++ {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024}, /* e */
++ };
++
++ /*
++ * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
++ */
++ if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
++ {
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (NULL);
++
++ search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
++ search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
++
++#define ALLWAYS_LOGIN
++#ifdef ALLWAYS_LOGIN
++ if (pk11_pin == NULL)
++ {
++ pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
++
++ if (pk11_pin == NULL)
++ {
++ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ }
++ if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
++ strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
++ {
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_INVALID_PIN, rv);
++ goto err;
++ }
++#endif
++
++ LOCK_OBJSTORE(OP_RSA);
++ if (pFuncList->C_FindObjectsInit(sp->session, search_templ, 3) != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++ rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
++ if (rv != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ if (objcnt > 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_TOO_MANY_OBJECTS);
++ goto err;
++ }
++
++ if (objcnt != 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_OBJECT_NOT_FOUND);
++ goto err;
++ }
++
++ (void) pFuncList->C_FindObjectsFinal(sp->session);
++ UNLOCK_OBJSTORE(OP_RSA);
++
++ sp->opdata_rsa_pub_key = ks_key;
++ pkey = EVP_PKEY_new();
++ if (pkey == NULL)
++ goto err;
++
++ rsa = RSA_new_method(e);
++ if (rsa == NULL) {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ goto err;
++ }
++ EVP_PKEY_set1_RSA(pkey, rsa);
++
++ if (pFuncList->C_GetAttributeValue(sp->session, ks_key,
++ get_templ, 2) != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ goto err;
++ }
++
++ (void) check_new_rsa_key_pub(sp, rsa);
++ sp->opdata_rsa_pub = rsa;
++
++ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
++ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
++ }
++ else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
++ {
++ pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
++ (void) fclose(pubkey);
++ }
++
++err:
++ if (sp != NULL)
++ pk11_return_session(sp, OP_RSA);
++ return (pkey);
++ }
++
++/*
++ * Create a private key object in the session from a given rsa structure.
++ * The *rsa_d_num pointer is non-NULL for RSA private keys.
++ */
++static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA *rsa,
++ RSA **key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
++ {
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++
++ if ((rsa->flags & RSA_FLAG_EXT_PKEY) == 0) {
++ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_INCONSISTENT_KEY);
++ return (h_key);
++ }
++
++ h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
++ (void) pk11_active_add(h_key, OP_RSA);
++ if (key_ptr != NULL)
++ *key_ptr = rsa;
++ if (rsa_d_num != NULL)
++ {
++ if (rsa->d == NULL)
++ *rsa_d_num = NULL;
++ else if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
++ {
++ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ return (h_key);
++ }
++ }
++ return (h_key);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ */
++static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
++ {
++ /*
++ * Provide protection against RSA structure reuse by making the
++ * check for cache hit stronger. Only public components of RSA
++ * key matter here so it is sufficient to compare them with values
++ * cached in PK11_SESSION structure.
++ */
++ if ((sp->opdata_rsa_pub != rsa) ||
++ (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
++ (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_rsa_object_pub(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ */
++static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
++ {
++ /*
++ * Provide protection against RSA structure reuse by making the
++ * check for cache hit stronger. Comparing private exponent of RSA
++ * key with value cached in PK11_SESSION structure should
++ * be sufficient.
++ */
++ if ((sp->opdata_rsa_priv != rsa) ||
++ (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0) ||
++ ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_rsa_object_priv(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++
++static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
++ {
++ if (attr->ulValueLen > 0)
++ {
++ *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
++ }
++ }
++
++#ifdef OPENSSL_SYS_WIN32
++char *getpassphrase(const char *prompt)
++ {
++ static char buf[128];
++ HANDLE h;
++ DWORD cc, mode;
++ int cnt;
++
++ h = GetStdHandle(STD_INPUT_HANDLE);
++ fputs(prompt, stderr);
++ fflush(stderr);
++ fflush(stdout);
++ FlushConsoleInputBuffer(h);
++ GetConsoleMode(h, &mode);
++ SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
++
++ for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
++ {
++ ReadFile(h, buf + cnt, 1, &cc, NULL);
++ if (buf[cnt] == '\r')
++ break;
++ fputc('*', stdout);
++ fflush(stderr);
++ fflush(stdout);
++ }
++
++ SetConsoleMode(h, mode);
++ buf[cnt] = '\0';
++ fputs("\n", stderr);
++ return buf;
++ }
++#endif /* OPENSSL_SYS_WIN32 */
++#endif /* OPENSSL_NO_HW_PK11 */
++#endif /* OPENSSL_NO_HW */
+Index: openssl/crypto/engine/hw_pk11_pub.c
+diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.31
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/hw_pk11_pub.c Fri Aug 28 06:31:09 2009
+@@ -0,0 +1,3137 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_pk11_pub.c */
++/*
++ * This product includes software developed by the OpenSSL Project for
++ * use in the OpenSSL Toolkit (http://www.openssl.org/).
++ *
++ * This project also referenced hw_pkcs11-0.9.7b.patch written by
++ * Afchine Madjlessi.
++ */
++/*
++ * ====================================================================
++ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ * software must display the following acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
++ *
++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
++ * endorse or promote products derived from this software without
++ * prior written permission. For written permission, please contact
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++
++#include <openssl/e_os2.h>
++#include <openssl/crypto.h>
++#include <cryptlib.h>
++#include <openssl/engine.h>
++#include <openssl/dso.h>
++#include <openssl/err.h>
++#include <openssl/bn.h>
++#include <openssl/pem.h>
++#ifndef OPENSSL_NO_RSA
++#include <openssl/rsa.h>
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++#include <openssl/dsa.h>
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++#include <openssl/dh.h>
++#endif /* OPENSSL_NO_DH */
++#include <openssl/rand.h>
++#include <openssl/objects.h>
++#include <openssl/x509.h>
++
++#ifdef OPENSSL_SYS_WIN32
++#define NOPTHREADS
++typedef int pid_t;
++#define HAVE_GETPASSPHRASE
++static char *getpassphrase(const char *prompt);
++#ifndef NULL_PTR
++#define NULL_PTR NULL
++#endif
++#define CK_DEFINE_FUNCTION(returnType, name) \
++ returnType __declspec(dllexport) name
++#define CK_DECLARE_FUNCTION(returnType, name) \
++ returnType __declspec(dllimport) name
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ returnType __declspec(dllimport) (* name)
++#else
++#include <unistd.h>
++#endif
++
++#ifndef NOPTHREADS
++#include <pthread.h>
++#endif
++
++#ifndef OPENSSL_NO_HW
++#ifndef OPENSSL_NO_HW_PK11
++
++#ifdef OPENSSL_SYS_WIN32
++#pragma pack(push, cryptoki, 1)
++#include "cryptoki.h"
++#include "pkcs11.h"
++#pragma pack(pop, cryptoki)
++#else
++#include "cryptoki.h"
++#include "pkcs11.h"
++#endif
++#include "hw_pk11_err.h"
++
++#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
++#define getpassphrase(x) getpass(x)
++#endif
++
++#ifndef OPENSSL_NO_RSA
++/* RSA stuff */
++static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding);
++static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding);
++static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding);
++static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding);
++static int pk11_RSA_init(RSA *rsa);
++static int pk11_RSA_finish(RSA *rsa);
++static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
++ unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
++static int pk11_RSA_verify(int dtype, const unsigned char *m,
++ unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
++ const RSA *rsa);
++EVP_PKEY *pk11_load_privkey(ENGINE*, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data);
++EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data);
++
++static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa);
++static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa);
++static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa);
++static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa);
++
++static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
++ BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
++static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
++ BIGNUM **rsa_d_num, CK_SESSION_HANDLE session);
++
++static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
++static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
++#endif
++
++/* DSA stuff */
++#ifndef OPENSSL_NO_DSA
++static int pk11_DSA_init(DSA *dsa);
++static int pk11_DSA_finish(DSA *dsa);
++static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
++ DSA *dsa);
++static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
++ DSA_SIG *sig, DSA *dsa);
++
++static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
++ BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
++static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
++ BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
++
++static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
++static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
++#endif
++
++/* DH stuff */
++#ifndef OPENSSL_NO_DH
++static int pk11_DH_init(DH *dh);
++static int pk11_DH_finish(DH *dh);
++static int pk11_DH_generate_key(DH *dh);
++static int pk11_DH_compute_key(unsigned char *key,
++ const BIGNUM *pub_key, DH *dh);
++
++static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
++ BIGNUM **priv_key, CK_SESSION_HANDLE session);
++
++static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
++#endif
++
++static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
++ CK_ULONG *ulValueLen);
++static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
++
++/* Read mode string to be used for fopen() */
++#if SOLARIS_OPENSSL
++static char *read_mode_flags = "rF";
++#else
++static char *read_mode_flags = "r";
++#endif
++
++/*
++ * increment/create reference for an asymmetric key handle via active list
++ * manipulation. If active list operation fails, unlock (if locked), set error
++ * variable and jump to the specified label.
++ */
++#define KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label) \
++ { \
++ if (pk11_active_add(key_handle, alg_type) < 0) \
++ { \
++ var = TRUE; \
++ if (unlock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ goto label; \
++ } \
++ }
++
++/*
++ * Find active list entry according to object handle and return pointer to the
++ * entry otherwise return NULL.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
++ {
++ PK11_active *entry;
++
++ for (entry = active_list[type]; entry != NULL; entry = entry->next)
++ if (entry->h == h)
++ return (entry);
++
++ return (NULL);
++ }
++
++/*
++ * Search for an entry in the active list using PKCS#11 object handle as a
++ * search key and return refcnt of the found/created entry or -1 in case of
++ * failure.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++int
++pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
++ {
++ PK11_active *entry = NULL;
++
++ if (h == CK_INVALID_HANDLE)
++ {
++ PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
++ return (-1);
++ }
++
++ /* search for entry in the active list */
++ if ((entry = pk11_active_find(h, type)) != NULL)
++ entry->refcnt++;
++ else
++ {
++ /* not found, create new entry and add it to the list */
++ entry = OPENSSL_malloc(sizeof (PK11_active));
++ if (entry == NULL)
++ {
++ PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
++ return (-1);
++ }
++ entry->h = h;
++ entry->refcnt = 1;
++ entry->prev = NULL;
++ entry->next = NULL;
++ /* connect the newly created entry to the list */
++ if (active_list[type] == NULL)
++ active_list[type] = entry;
++ else /* make the entry first in the list */
++ {
++ entry->next = active_list[type];
++ active_list[type]->prev = entry;
++ active_list[type] = entry;
++ }
++ }
++
++ return (entry->refcnt);
++ }
++
++/*
++ * Remove active list entry from the list and free it.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++void
++pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
++ {
++ PK11_active *prev_entry;
++
++ /* remove the entry from the list and free it */
++ if ((prev_entry = entry->prev) != NULL)
++ {
++ prev_entry->next = entry->next;
++ if (entry->next != NULL)
++ entry->next->prev = prev_entry;
++ }
++ else
++ {
++ active_list[type] = entry->next;
++ /* we were the first but not the only one */
++ if (entry->next != NULL)
++ entry->next->prev = NULL;
++ }
++
++ /* sanitization */
++ entry->h = CK_INVALID_HANDLE;
++ entry->prev = NULL;
++ entry->next = NULL;
++ OPENSSL_free(entry);
++ }
++
++/* Free all entries from the active list. */
++void
++pk11_free_active_list(PK11_OPTYPE type)
++ {
++ PK11_active *entry;
++
++ /* only for asymmetric types since only they have C_Find* locks. */
++ switch (type)
++ {
++ case OP_RSA:
++ case OP_DSA:
++ case OP_DH:
++ break;
++ default:
++ return;
++ }
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(type);
++ while ((entry = active_list[type]) != NULL)
++ pk11_active_remove(entry, type);
++ UNLOCK_OBJSTORE(type);
++ }
++
++/*
++ * Search for active list entry associated with given PKCS#11 object handle,
++ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
++ *
++ * Return 1 if the PKCS#11 object associated with the entry has no references,
++ * return 0 if there is at least one reference, -1 on error.
++ *
++ * This function presumes it is called with lock protecting the active list
++ * held.
++ */
++int
++pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
++ {
++ PK11_active *entry = NULL;
++
++ if ((entry = pk11_active_find(h, type)) == NULL)
++ {
++ PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
++ return (-1);
++ }
++
++ OPENSSL_assert(entry->refcnt > 0);
++ entry->refcnt--;
++ if (entry->refcnt == 0)
++ {
++ pk11_active_remove(entry, type);
++ return (1);
++ }
++
++ return (0);
++ }
++
++#ifndef OPENSSL_NO_RSA
++/* Our internal RSA_METHOD that we provide pointers to */
++static RSA_METHOD pk11_rsa =
++ {
++ "PKCS#11 RSA method",
++ pk11_RSA_public_encrypt, /* rsa_pub_encrypt */
++ pk11_RSA_public_decrypt, /* rsa_pub_decrypt */
++ pk11_RSA_private_encrypt, /* rsa_priv_encrypt */
++ pk11_RSA_private_decrypt, /* rsa_priv_decrypt */
++ NULL, /* rsa_mod_exp */
++ NULL, /* bn_mod_exp */
++ pk11_RSA_init, /* init */
++ pk11_RSA_finish, /* finish */
++ RSA_FLAG_SIGN_VER, /* flags */
++ NULL, /* app_data */
++ pk11_RSA_sign, /* rsa_sign */
++ pk11_RSA_verify /* rsa_verify */
++ };
++
++RSA_METHOD *
++PK11_RSA(void)
++ {
++ return (&pk11_rsa);
++ }
++#endif
++
++#ifndef OPENSSL_NO_DSA
++/* Our internal DSA_METHOD that we provide pointers to */
++static DSA_METHOD pk11_dsa =
++ {
++ "PKCS#11 DSA method",
++ pk11_dsa_do_sign, /* dsa_do_sign */
++ NULL, /* dsa_sign_setup */
++ pk11_dsa_do_verify, /* dsa_do_verify */
++ NULL, /* dsa_mod_exp */
++ NULL, /* bn_mod_exp */
++ pk11_DSA_init, /* init */
++ pk11_DSA_finish, /* finish */
++ 0, /* flags */
++ NULL /* app_data */
++ };
++
++DSA_METHOD *
++PK11_DSA(void)
++ {
++ return (&pk11_dsa);
++ }
++#endif
++
++#ifndef OPENSSL_NO_DH
++/*
++ * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
++ * output buffer may somewhat exceed the precise number of bytes needed, but
++ * should not exceed it by a large amount. That may be caused, for example, by
++ * rounding it up to multiple of X in the underlying bignum library. 8 should be
++ * enough.
++ */
++#define DH_BUF_RESERVE 8
++
++/* Our internal DH_METHOD that we provide pointers to */
++static DH_METHOD pk11_dh =
++ {
++ "PKCS#11 DH method",
++ pk11_DH_generate_key, /* generate_key */
++ pk11_DH_compute_key, /* compute_key */
++ NULL, /* bn_mod_exp */
++ pk11_DH_init, /* init */
++ pk11_DH_finish, /* finish */
++ 0, /* flags */
++ NULL, /* app_data */
++ NULL /* generate_params */
++ };
++
++DH_METHOD *
++PK11_DH(void)
++ {
++ return (&pk11_dh);
++ }
++#endif
++
++/* Size of an SSL signature: MD5+SHA1 */
++#define SSL_SIG_LENGTH 36
++
++/* Lengths of DSA data and signature */
++#define DSA_DATA_LEN 20
++#define DSA_SIGNATURE_LEN 40
++
++static CK_BBOOL true = TRUE;
++static CK_BBOOL false = FALSE;
++
++#ifndef OPENSSL_NO_RSA
++/*
++ * Similiar to OpenSSL to take advantage of the paddings. The goal is to
++ * support all paddings in this engine although PK11 library does not
++ * support all the paddings used in OpenSSL.
++ * The input errors should have been checked in the padding functions.
++ */
++static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding)
++ {
++ int i, num = 0, r = -1;
++ unsigned char *buf = NULL;
++
++ num = BN_num_bytes(rsa->n);
++ if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
++ {
++ RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ switch (padding)
++ {
++ case RSA_PKCS1_PADDING:
++ i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
++ break;
++#ifndef OPENSSL_NO_SHA
++ case RSA_PKCS1_OAEP_PADDING:
++ i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
++ break;
++#endif
++ case RSA_SSLV23_PADDING:
++ i = RSA_padding_add_SSLv23(buf, num, from, flen);
++ break;
++ case RSA_NO_PADDING:
++ i = RSA_padding_add_none(buf, num, from, flen);
++ break;
++ default:
++ RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
++ goto err;
++ }
++ if (i <= 0) goto err;
++
++ /* PK11 functions are called here */
++ r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
++err:
++ if (buf != NULL)
++ {
++ OPENSSL_cleanse(buf, num);
++ OPENSSL_free(buf);
++ }
++ return (r);
++ }
++
++
++/*
++ * Similar to Openssl to take advantage of the paddings. The input errors
++ * should be catched in the padding functions
++ */
++static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding)
++ {
++ int i, num = 0, r = -1;
++ unsigned char *buf = NULL;
++
++ num = BN_num_bytes(rsa->n);
++ if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
++ {
++ RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ switch (padding)
++ {
++ case RSA_PKCS1_PADDING:
++ i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
++ break;
++ case RSA_NO_PADDING:
++ i = RSA_padding_add_none(buf, num, from, flen);
++ break;
++ case RSA_SSLV23_PADDING:
++ default:
++ RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
++ goto err;
++ }
++ if (i <= 0) goto err;
++
++ /* PK11 functions are called here */
++ r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
++err:
++ if (buf != NULL)
++ {
++ OPENSSL_cleanse(buf, num);
++ OPENSSL_free(buf);
++ }
++ return (r);
++ }
++
++/* Similar to OpenSSL code. Input errors are also checked here */
++static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding)
++ {
++ BIGNUM f;
++ int j, num = 0, r = -1;
++ unsigned char *p;
++ unsigned char *buf = NULL;
++
++ BN_init(&f);
++
++ num = BN_num_bytes(rsa->n);
++
++ if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
++ {
++ RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ /*
++ * This check was for equality but PGP does evil things
++ * and chops off the top '0' bytes
++ */
++ if (flen > num)
++ {
++ RSAerr(PK11_F_RSA_PRIV_DEC,
++ PK11_R_DATA_GREATER_THAN_MOD_LEN);
++ goto err;
++ }
++
++ /* make data into a big number */
++ if (BN_bin2bn(from, (int)flen, &f) == NULL)
++ goto err;
++
++ if (BN_ucmp(&f, rsa->n) >= 0)
++ {
++ RSAerr(PK11_F_RSA_PRIV_DEC,
++ PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
++ goto err;
++ }
++
++ /* PK11 functions are called here */
++ r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
++
++ /*
++ * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
++ * Needs to skip these 0's paddings here.
++ */
++ for (j = 0; j < r; j++)
++ if (buf[j] != 0)
++ break;
++
++ p = buf + j;
++ j = r - j; /* j is only used with no-padding mode */
++
++ switch (padding)
++ {
++ case RSA_PKCS1_PADDING:
++ r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
++ break;
++#ifndef OPENSSL_NO_SHA
++ case RSA_PKCS1_OAEP_PADDING:
++ r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
++ break;
++#endif
++ case RSA_SSLV23_PADDING:
++ r = RSA_padding_check_SSLv23(to, num, p, j, num);
++ break;
++ case RSA_NO_PADDING:
++ r = RSA_padding_check_none(to, num, p, j, num);
++ break;
++ default:
++ RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
++ goto err;
++ }
++ if (r < 0)
++ RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
++
++err:
++ BN_clear_free(&f);
++ if (buf != NULL)
++ {
++ OPENSSL_cleanse(buf, num);
++ OPENSSL_free(buf);
++ }
++ return (r);
++ }
++
++/* Similar to OpenSSL code. Input errors are also checked here */
++static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
++ unsigned char *to, RSA *rsa, int padding)
++ {
++ BIGNUM f;
++ int i, num = 0, r = -1;
++ unsigned char *p;
++ unsigned char *buf = NULL;
++
++ BN_init(&f);
++ num = BN_num_bytes(rsa->n);
++ buf = (unsigned char *)OPENSSL_malloc(num);
++ if (buf == NULL)
++ {
++ RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ /*
++ * This check was for equality but PGP does evil things
++ * and chops off the top '0' bytes
++ */
++ if (flen > num)
++ {
++ RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
++ goto err;
++ }
++
++ if (BN_bin2bn(from, flen, &f) == NULL)
++ goto err;
++
++ if (BN_ucmp(&f, rsa->n) >= 0)
++ {
++ RSAerr(PK11_F_RSA_PUB_DEC,
++ PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
++ goto err;
++ }
++
++ /* PK11 functions are called here */
++ r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
++
++ /*
++ * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
++ * Needs to skip these 0's here
++ */
++ for (i = 0; i < r; i++)
++ if (buf[i] != 0)
++ break;
++
++ p = buf + i;
++ i = r - i; /* i is only used with no-padding mode */
++
++ switch (padding)
++ {
++ case RSA_PKCS1_PADDING:
++ r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
++ break;
++ case RSA_NO_PADDING:
++ r = RSA_padding_check_none(to, num, p, i, num);
++ break;
++ default:
++ RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
++ goto err;
++ }
++ if (r < 0)
++ RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
++
++err:
++ BN_clear_free(&f);
++ if (buf != NULL)
++ {
++ OPENSSL_cleanse(buf, num);
++ OPENSSL_free(buf);
++ }
++ return (r);
++ }
++
++/*
++ * This function implements RSA public encryption using C_EncryptInit and
++ * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
++ * The calling function allocated sufficient memory in "to" to store results.
++ */
++static int pk11_RSA_public_encrypt_low(int flen,
++ const unsigned char *from, unsigned char *to, RSA *rsa)
++ {
++ CK_ULONG bytes_encrypted = flen;
++ int retval = -1;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (-1);
++
++ (void) check_new_rsa_key_pub(sp, rsa);
++
++ h_pub_key = sp->opdata_rsa_pub_key;
++ if (h_pub_key == CK_INVALID_HANDLE)
++ h_pub_key = sp->opdata_rsa_pub_key =
++ pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
++ &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
++ sp->session);
++
++ if (h_pub_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_EncryptInit(sp->session, p_mech,
++ h_pub_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
++ PK11_R_ENCRYPTINIT, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++
++ rv = pFuncList->C_Encrypt(sp->session,
++ (unsigned char *)from, flen, to, &bytes_encrypted);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
++ PK11_R_ENCRYPT, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++ retval = bytes_encrypted;
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (retval);
++ }
++
++
++/*
++ * This function implements RSA private encryption using C_SignInit and
++ * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
++ * The calling function allocated sufficient memory in "to" to store results.
++ */
++static int pk11_RSA_private_encrypt_low(int flen,
++ const unsigned char *from, unsigned char *to, RSA *rsa)
++ {
++ CK_ULONG ul_sig_len = flen;
++ int retval = -1;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (-1);
++
++ (void) check_new_rsa_key_priv(sp, rsa);
++
++ h_priv_key = sp->opdata_rsa_priv_key;
++ if (h_priv_key == CK_INVALID_HANDLE)
++ h_priv_key = sp->opdata_rsa_priv_key =
++ pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
++ &sp->opdata_rsa_d_num, sp->session);
++
++ if (h_priv_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_SignInit(sp->session, p_mech,
++ h_priv_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
++ PK11_R_SIGNINIT, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++
++ rv = pFuncList->C_Sign(sp->session,
++ (unsigned char *)from, flen, to, &ul_sig_len);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
++ rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++
++ retval = ul_sig_len;
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (retval);
++ }
++
++
++/*
++ * This function implements RSA private decryption using C_DecryptInit and
++ * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
++ * The calling function allocated sufficient memory in "to" to store results.
++ */
++static int pk11_RSA_private_decrypt_low(int flen,
++ const unsigned char *from, unsigned char *to, RSA *rsa)
++ {
++ CK_ULONG bytes_decrypted = flen;
++ int retval = -1;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_priv_key;
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (-1);
++
++ (void) check_new_rsa_key_priv(sp, rsa);
++
++ h_priv_key = sp->opdata_rsa_priv_key;
++ if (h_priv_key == CK_INVALID_HANDLE)
++ h_priv_key = sp->opdata_rsa_priv_key =
++ pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
++ &sp->opdata_rsa_d_num, sp->session);
++
++ if (h_priv_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_DecryptInit(sp->session, p_mech,
++ h_priv_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
++ PK11_R_DECRYPTINIT, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++
++ rv = pFuncList->C_Decrypt(sp->session,
++ (unsigned char *)from, flen, to, &bytes_decrypted);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
++ PK11_R_DECRYPT, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++ retval = bytes_decrypted;
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (retval);
++ }
++
++
++/*
++ * This function implements RSA public decryption using C_VerifyRecoverInit
++ * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
++ * The calling function allocated sufficient memory in "to" to store results.
++ */
++static int pk11_RSA_public_decrypt_low(int flen,
++ const unsigned char *from, unsigned char *to, RSA *rsa)
++ {
++ CK_ULONG bytes_decrypted = flen;
++ int retval = -1;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
++ PK11_SESSION *sp;
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (-1);
++
++ (void) check_new_rsa_key_pub(sp, rsa);
++
++ h_pub_key = sp->opdata_rsa_pub_key;
++ if (h_pub_key == CK_INVALID_HANDLE)
++ h_pub_key = sp->opdata_rsa_pub_key =
++ pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
++ &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
++ sp->session);
++
++ if (h_pub_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_VerifyRecoverInit(sp->session,
++ p_mech, h_pub_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
++ PK11_R_VERIFYRECOVERINIT, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++
++ rv = pFuncList->C_VerifyRecover(sp->session,
++ (unsigned char *)from, flen, to, &bytes_decrypted);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
++ PK11_R_VERIFYRECOVER, rv);
++ pk11_return_session(sp, OP_RSA);
++ return (-1);
++ }
++ retval = bytes_decrypted;
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (retval);
++ }
++
++static int pk11_RSA_init(RSA *rsa)
++ {
++ /*
++ * This flag in the RSA_METHOD enables the new rsa_sign,
++ * rsa_verify functions. See rsa.h for details.
++ */
++ rsa->flags |= RSA_FLAG_SIGN_VER;
++
++ return (1);
++ }
++
++static int pk11_RSA_finish(RSA *rsa)
++ {
++ /*
++ * Since we are overloading OpenSSL's native RSA_eay_finish() we need
++ * to do the same as in the original function, i.e. to free bignum
++ * structures.
++ */
++ if (rsa->_method_mod_n != NULL)
++ BN_MONT_CTX_free(rsa->_method_mod_n);
++ if (rsa->_method_mod_p != NULL)
++ BN_MONT_CTX_free(rsa->_method_mod_p);
++ if (rsa->_method_mod_q != NULL)
++ BN_MONT_CTX_free(rsa->_method_mod_q);
++
++ return (1);
++ }
++
++/*
++ * Standard engine interface function. Majority codes here are from
++ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
++ * See more details in rsa/rsa_sign.c
++ */
++static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
++ unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
++ {
++ X509_SIG sig;
++ ASN1_TYPE parameter;
++ int i, j = 0;
++ unsigned char *p, *s = NULL;
++ X509_ALGOR algor;
++ ASN1_OCTET_STRING digest;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_priv_key;
++ PK11_SESSION *sp = NULL;
++ int ret = 0;
++ unsigned long ulsiglen;
++
++ /* Encode the digest */
++ /* Special case: SSL signature, just check the length */
++ if (type == NID_md5_sha1)
++ {
++ if (m_len != SSL_SIG_LENGTH)
++ {
++ PK11err(PK11_F_RSA_SIGN,
++ PK11_R_INVALID_MESSAGE_LENGTH);
++ goto err;
++ }
++ i = SSL_SIG_LENGTH;
++ s = (unsigned char *)m;
++ }
++ else
++ {
++ sig.algor = &algor;
++ sig.algor->algorithm = OBJ_nid2obj(type);
++ if (sig.algor->algorithm == NULL)
++ {
++ PK11err(PK11_F_RSA_SIGN,
++ PK11_R_UNKNOWN_ALGORITHM_TYPE);
++ goto err;
++ }
++ if (sig.algor->algorithm->length == 0)
++ {
++ PK11err(PK11_F_RSA_SIGN,
++ PK11_R_UNKNOWN_ASN1_OBJECT_ID);
++ goto err;
++ }
++ parameter.type = V_ASN1_NULL;
++ parameter.value.ptr = NULL;
++ sig.algor->parameter = &parameter;
++
++ sig.digest = &digest;
++ sig.digest->data = (unsigned char *)m;
++ sig.digest->length = m_len;
++
++ i = i2d_X509_SIG(&sig, NULL);
++ }
++
++ j = RSA_size(rsa);
++ if ((i - RSA_PKCS1_PADDING) > j)
++ {
++ PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
++ goto err;
++ }
++
++ if (type != NID_md5_sha1)
++ {
++ s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
++ if (s == NULL)
++ {
++ PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ p = s;
++ (void) i2d_X509_SIG(&sig, &p);
++ }
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ goto err;
++
++ (void) check_new_rsa_key_priv(sp, rsa);
++
++ h_priv_key = sp->opdata_rsa_priv_key;
++ if (h_priv_key == CK_INVALID_HANDLE)
++ h_priv_key = sp->opdata_rsa_priv_key =
++ pk11_get_private_rsa_key((RSA *)rsa,
++ &sp->opdata_rsa_priv,
++ &sp->opdata_rsa_d_num, sp->session);
++
++ if (h_priv_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
++ goto err;
++ }
++
++ ulsiglen = j;
++ rv = pFuncList->C_Sign(sp->session, s, i, sigret,
++ (CK_ULONG_PTR) &ulsiglen);
++ *siglen = ulsiglen;
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
++ goto err;
++ }
++ ret = 1;
++ }
++
++err:
++ if ((type != NID_md5_sha1) && (s != NULL))
++ {
++ (void) memset(s, 0, (unsigned int)(j + 1));
++ OPENSSL_free(s);
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (ret);
++ }
++
++static int pk11_RSA_verify(int type, const unsigned char *m,
++ unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
++ const RSA *rsa)
++ {
++ X509_SIG sig;
++ ASN1_TYPE parameter;
++ int i, j = 0;
++ unsigned char *p, *s = NULL;
++ X509_ALGOR algor;
++ ASN1_OCTET_STRING digest;
++ CK_RV rv;
++ CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
++ CK_MECHANISM *p_mech = &mech_rsa;
++ CK_OBJECT_HANDLE h_pub_key;
++ PK11_SESSION *sp = NULL;
++ int ret = 0;
++
++ /* Encode the digest */
++ /* Special case: SSL signature, just check the length */
++ if (type == NID_md5_sha1)
++ {
++ if (m_len != SSL_SIG_LENGTH)
++ {
++ PK11err(PK11_F_RSA_VERIFY,
++ PK11_R_INVALID_MESSAGE_LENGTH);
++ goto err;
++ }
++ i = SSL_SIG_LENGTH;
++ s = (unsigned char *)m;
++ }
++ else
++ {
++ sig.algor = &algor;
++ sig.algor->algorithm = OBJ_nid2obj(type);
++ if (sig.algor->algorithm == NULL)
++ {
++ PK11err(PK11_F_RSA_VERIFY,
++ PK11_R_UNKNOWN_ALGORITHM_TYPE);
++ goto err;
++ }
++ if (sig.algor->algorithm->length == 0)
++ {
++ PK11err(PK11_F_RSA_VERIFY,
++ PK11_R_UNKNOWN_ASN1_OBJECT_ID);
++ goto err;
++ }
++ parameter.type = V_ASN1_NULL;
++ parameter.value.ptr = NULL;
++ sig.algor->parameter = &parameter;
++ sig.digest = &digest;
++ sig.digest->data = (unsigned char *)m;
++ sig.digest->length = m_len;
++ i = i2d_X509_SIG(&sig, NULL);
++ }
++
++ j = RSA_size(rsa);
++ if ((i - RSA_PKCS1_PADDING) > j)
++ {
++ PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
++ goto err;
++ }
++
++ if (type != NID_md5_sha1)
++ {
++ s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
++ if (s == NULL)
++ {
++ PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ p = s;
++ (void) i2d_X509_SIG(&sig, &p);
++ }
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ goto err;
++
++ (void) check_new_rsa_key_pub(sp, rsa);
++
++ h_pub_key = sp->opdata_rsa_pub_key;
++ if (h_pub_key == CK_INVALID_HANDLE)
++ h_pub_key = sp->opdata_rsa_pub_key =
++ pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
++ &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
++ sp->session);
++
++ if (h_pub_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_VerifyInit(sp->session, p_mech,
++ h_pub_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
++ rv);
++ goto err;
++ }
++ rv = pFuncList->C_Verify(sp->session, s, i, sigbuf,
++ (CK_ULONG)siglen);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
++ goto err;
++ }
++ ret = 1;
++ }
++
++err:
++ if ((type != NID_md5_sha1) && (s != NULL))
++ {
++ (void) memset(s, 0, (unsigned int)(j + 1));
++ OPENSSL_free(s);
++ }
++
++ pk11_return_session(sp, OP_RSA);
++ return (ret);
++ }
++
++static int hndidx_rsa = -1;
++
++/* load RSA private key from a file */
++/* ARGSUSED */
++EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
++ UI_METHOD *ui_method, void *callback_data)
++ {
++ EVP_PKEY *pkey = NULL;
++ FILE *privkey;
++ CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
++ RSA *rsa;
++ PK11_SESSION *sp;
++ /* everything else below needed for key by reference extension */
++ CK_RV rv;
++ CK_ULONG objcnt = 0;
++ CK_BBOOL is_token = TRUE;
++ CK_BYTE attr_data[2][1024];
++ CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
++ CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */
++ extern char *pk11_pin;
++
++ /* we look for private keys only */
++ CK_ATTRIBUTE search_templ[] =
++ {
++ {CKA_TOKEN, &is_token, sizeof(is_token)},
++ {CKA_CLASS, &key_class, sizeof(key_class)},
++ {CKA_LABEL, NULL, 0}
++ };
++
++ /* these attributes are needed to initialize OpenSSL RSA structure */
++ CK_ATTRIBUTE get_templ[] =
++ {
++ {CKA_MODULUS, (void *)attr_data[0], 1024}, /* n */
++ {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024}, /* e */
++ };
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (NULL);
++
++ /*
++ * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
++ */
++ if (strstr(privkey_file, "pkcs11:") == privkey_file)
++ {
++ search_templ[2].pValue = strstr(privkey_file, ":") + 1;
++ search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
++
++ if (pk11_pin == NULL)
++ {
++ pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
++
++ if (pk11_pin == NULL)
++ {
++ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ }
++ if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
++ strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
++ {
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_INVALID_PIN, rv);
++ goto err;
++ }
++
++ LOCK_OBJSTORE(OP_RSA);
++ if ((rv = pFuncList->C_FindObjectsInit(sp->session,
++ search_templ, 3)) != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
++ if (rv != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ if (objcnt > 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_TOO_MANY_OBJECTS);
++ goto err;
++ }
++
++ if (objcnt != 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_OBJECT_NOT_FOUND);
++ goto err;
++ }
++
++ (void) pFuncList->C_FindObjectsFinal(sp->session);
++ UNLOCK_OBJSTORE(OP_RSA);
++
++ if (hndidx_rsa == -1)
++ hndidx_rsa = RSA_get_ex_new_index(0,
++ "pkcs11 RSA HSM key handle",
++ NULL, NULL, NULL);
++
++ pkey = EVP_PKEY_new();
++ if (pkey == NULL)
++ goto err;
++
++ rsa = RSA_new_method(e);
++ if (rsa == NULL) {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ goto err;
++ }
++ EVP_PKEY_set1_RSA(pkey, rsa);
++
++ if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
++ get_templ, 2)) != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LOAD_PRIVKEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ goto err;
++ }
++
++ /*
++ * Now we have to initialize an OpenSSL RSA structure,
++ * everything else is 0 or NULL.
++ */
++ rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
++ RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
++ (void) check_new_rsa_key_priv(sp, rsa);
++ sp->opdata_rsa_priv = rsa;
++ sp->opdata_rsa_priv_key = ks_key;
++
++ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
++ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
++ }
++ else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
++ {
++ pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
++ (void) fclose(privkey);
++ if (pkey != NULL)
++ {
++ rsa = EVP_PKEY_get1_RSA(pkey);
++ if (rsa != NULL)
++ {
++ (void) check_new_rsa_key_priv(sp, rsa);
++
++ h_priv_key = sp->opdata_rsa_priv_key =
++ pk11_get_private_rsa_key(rsa,
++ &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
++ sp->session);
++ if (h_priv_key == CK_INVALID_HANDLE)
++ {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ }
++ }
++ else
++ {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ }
++ }
++ }
++
++err:
++ pk11_return_session(sp, OP_RSA);
++ return (pkey);
++ }
++
++/* load RSA public key from a file */
++/* ARGSUSED */
++EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
++ UI_METHOD *ui_method, void *callback_data)
++ {
++ EVP_PKEY *pkey = NULL;
++ FILE *pubkey;
++ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
++ RSA *rsa;
++ PK11_SESSION *sp;
++ /* everything else below needed for key by reference extension */
++ CK_RV rv;
++ CK_ULONG objcnt = 0;
++ CK_BBOOL is_token = TRUE;
++ CK_BYTE attr_data[2][1024];
++ CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
++ CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */
++ extern char *pk11_pin;
++
++ /* we look for public keys only */
++ CK_ATTRIBUTE search_templ[] =
++ {
++ {CKA_TOKEN, &is_token, sizeof(is_token)},
++ {CKA_CLASS, &key_class, sizeof(key_class)},
++ {CKA_LABEL, NULL, 0}
++ };
++
++ /* these attributes are needed to initialize OpenSSL RSA structure */
++ CK_ATTRIBUTE get_templ[] =
++ {
++ {CKA_MODULUS, (void *)attr_data[0], 1024}, /* n */
++ {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024}, /* e */
++ };
++
++ if ((sp = pk11_get_session(OP_RSA)) == NULL)
++ return (NULL);
++
++ /*
++ * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
++ */
++ if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
++ {
++ search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
++ search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
++
++#define ALLWAYS_LOGIN
++#ifdef ALLWAYS_LOGIN
++ if (pk11_pin == NULL)
++ {
++ pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
++
++ if (pk11_pin == NULL)
++ {
++ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ }
++ if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
++ strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
++ {
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_INVALID_PIN, rv);
++ goto err;
++ }
++#endif
++
++ LOCK_OBJSTORE(OP_RSA);
++ if (pFuncList->C_FindObjectsInit(sp->session, search_templ, 3) != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++ rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
++ if (rv != CKR_OK)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ if (objcnt > 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_TOO_MANY_OBJECTS);
++ goto err;
++ }
++
++ if (objcnt != 1)
++ {
++ UNLOCK_OBJSTORE(OP_RSA);
++ PK11err(PK11_F_LOAD_PUBKEY, PK11_R_OBJECT_NOT_FOUND);
++ goto err;
++ }
++
++ (void) pFuncList->C_FindObjectsFinal(sp->session);
++ UNLOCK_OBJSTORE(OP_RSA);
++
++ sp->opdata_rsa_pub_key = ks_key;
++ pkey = EVP_PKEY_new();
++ if (pkey == NULL)
++ goto err;
++
++ rsa = RSA_new_method(e);
++ if (rsa == NULL) {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ goto err;
++ }
++ EVP_PKEY_set1_RSA(pkey, rsa);
++
++ if (pFuncList->C_GetAttributeValue(sp->session, ks_key,
++ get_templ, 2) != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_LOAD_PUBKEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ goto err;
++ }
++
++ /*
++ * Now we have to initialize an OpenSSL RSA structure,
++ * everything else is 0 or NULL.
++ */
++ rsa->flags = RSA_FLAG_SIGN_VER;
++ (void) check_new_rsa_key_pub(sp, rsa);
++ sp->opdata_rsa_pub = rsa;
++
++ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
++ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
++ }
++ else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
++ {
++ pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
++ (void) fclose(pubkey);
++ if (pkey != NULL)
++ {
++ rsa = EVP_PKEY_get1_RSA(pkey);
++ if (rsa != NULL)
++ {
++ (void) check_new_rsa_key_pub(sp, rsa);
++
++ h_pub_key = sp->opdata_rsa_pub_key =
++ pk11_get_public_rsa_key(rsa,
++ &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
++ &sp->opdata_rsa_e_num, sp->session);
++ if (h_pub_key == CK_INVALID_HANDLE)
++ {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ }
++ }
++ else
++ {
++ EVP_PKEY_free(pkey);
++ pkey = NULL;
++ }
++ }
++ }
++
++err:
++ pk11_return_session(sp, OP_RSA);
++ return (pkey);
++ }
++
++/*
++ * Create a public key object in a session from a given rsa structure.
++ * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
++ */
++static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
++ RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
++ CK_SESSION_HANDLE session)
++ {
++ CK_RV rv;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++ CK_ULONG found;
++ CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
++ CK_KEY_TYPE k_type = CKK_RSA;
++ CK_ULONG ul_key_attr_count = 8;
++ CK_BBOOL rollback = FALSE;
++
++ CK_ATTRIBUTE a_key_template[] =
++ {
++ {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
++ {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
++ {CKA_TOKEN, &false, sizeof (true)},
++ {CKA_ENCRYPT, &true, sizeof (true)},
++ {CKA_VERIFY, &true, sizeof (true)},
++ {CKA_VERIFY_RECOVER, &true, sizeof (true)},
++ {CKA_MODULUS, (void *)NULL, 0},
++ {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
++ };
++
++ int i;
++
++ a_key_template[0].pValue = &o_key;
++ a_key_template[1].pValue = &k_type;
++
++ a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
++ a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
++ (size_t)a_key_template[6].ulValueLen);
++ if (a_key_template[6].pValue == NULL)
++ {
++ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ BN_bn2bin(rsa->n, a_key_template[6].pValue);
++
++ a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
++ a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
++ (size_t)a_key_template[7].ulValueLen);
++ if (a_key_template[7].pValue == NULL)
++ {
++ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ BN_bn2bin(rsa->e, a_key_template[7].pValue);
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(OP_RSA);
++ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
++ ul_key_attr_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSINIT,
++ rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjectsFinal(session);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
++ PK11_R_FINDOBJECTSFINAL, rv);
++ goto err;
++ }
++
++ if (found == 0)
++ {
++ rv = pFuncList->C_CreateObject(session,
++ a_key_template, ul_key_attr_count, &h_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
++ PK11_R_CREATEOBJECT, rv);
++ goto err;
++ }
++ }
++
++ if (rsa_n_num != NULL)
++ if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
++ {
++ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ rollback = TRUE;
++ goto err;
++ }
++ if (rsa_e_num != NULL)
++ if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
++ {
++ PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ BN_free(*rsa_n_num);
++ *rsa_n_num = NULL;
++ rollback = TRUE;
++ goto err;
++ }
++
++ /* LINTED: E_CONSTANT_CONDITION */
++ KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
++ if (key_ptr != NULL)
++ *key_ptr = rsa;
++
++err:
++ if (rollback)
++ {
++ /*
++ * We do not care about the return value from C_DestroyObject()
++ * since we are doing rollback.
++ */
++ if (found == 0)
++ (void) pFuncList->C_DestroyObject(session, h_key);
++ h_key = CK_INVALID_HANDLE;
++ }
++
++ UNLOCK_OBJSTORE(OP_RSA);
++
++malloc_err:
++ for (i = 6; i <= 7; i++)
++ {
++ if (a_key_template[i].pValue != NULL)
++ {
++ OPENSSL_free(a_key_template[i].pValue);
++ a_key_template[i].pValue = NULL;
++ }
++ }
++
++ return (h_key);
++ }
++
++/*
++ * Create a private key object in the session from a given rsa structure.
++ * The *rsa_d_num pointer is non-NULL for RSA private keys.
++ */
++static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA *rsa,
++ RSA **key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
++ {
++ CK_RV rv;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++ int i;
++ CK_ULONG found;
++ CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
++ CK_KEY_TYPE k_type = CKK_RSA;
++ CK_ULONG ul_key_attr_count = 14;
++ CK_BBOOL rollback = FALSE;
++
++ /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
++ CK_ATTRIBUTE a_key_template[] =
++ {
++ {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
++ {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
++ {CKA_TOKEN, &false, sizeof (true)},
++ {CKA_SENSITIVE, &false, sizeof (true)},
++ {CKA_DECRYPT, &true, sizeof (true)},
++ {CKA_SIGN, &true, sizeof (true)},
++ {CKA_MODULUS, (void *)NULL, 0},
++ {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
++ {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
++ {CKA_PRIME_1, (void *)NULL, 0},
++ {CKA_PRIME_2, (void *)NULL, 0},
++ {CKA_EXPONENT_1, (void *)NULL, 0},
++ {CKA_EXPONENT_2, (void *)NULL, 0},
++ {CKA_COEFFICIENT, (void *)NULL, 0}
++ };
++
++ if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
++ h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
++ LOCK_OBJSTORE(OP_RSA);
++ goto set;
++ }
++
++ a_key_template[0].pValue = &o_key;
++ a_key_template[1].pValue = &k_type;
++
++ /* Put the private key components into the template */
++ if (init_template_value(rsa->n, &a_key_template[6].pValue,
++ &a_key_template[6].ulValueLen) == 0 ||
++ init_template_value(rsa->e, &a_key_template[7].pValue,
++ &a_key_template[7].ulValueLen) == 0 ||
++ init_template_value(rsa->d, &a_key_template[8].pValue,
++ &a_key_template[8].ulValueLen) == 0 ||
++ init_template_value(rsa->p, &a_key_template[9].pValue,
++ &a_key_template[9].ulValueLen) == 0 ||
++ init_template_value(rsa->q, &a_key_template[10].pValue,
++ &a_key_template[10].ulValueLen) == 0 ||
++ init_template_value(rsa->dmp1, &a_key_template[11].pValue,
++ &a_key_template[11].ulValueLen) == 0 ||
++ init_template_value(rsa->dmq1, &a_key_template[12].pValue,
++ &a_key_template[12].ulValueLen) == 0 ||
++ init_template_value(rsa->iqmp, &a_key_template[13].pValue,
++ &a_key_template[13].ulValueLen) == 0)
++ {
++ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(OP_RSA);
++ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
++ ul_key_attr_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
++ PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjectsFinal(session);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
++ PK11_R_FINDOBJECTSFINAL, rv);
++ goto err;
++ }
++
++ if (found == 0)
++ {
++ rv = pFuncList->C_CreateObject(session,
++ a_key_template, ul_key_attr_count, &h_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
++ PK11_R_CREATEOBJECT, rv);
++ goto err;
++ }
++ }
++
++set:
++ if (rsa_d_num != NULL)
++ {
++ if (rsa->d == NULL)
++ *rsa_d_num = NULL;
++ else if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
++ {
++ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ rollback = TRUE;
++ goto err;
++ }
++ }
++
++ /* LINTED: E_CONSTANT_CONDITION */
++ KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
++ if (key_ptr != NULL)
++ *key_ptr = rsa;
++
++err:
++ if (rollback)
++ {
++ /*
++ * We do not care about the return value from C_DestroyObject()
++ * since we are doing rollback.
++ */
++ if (found == 0 &&
++ (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
++ (void) pFuncList->C_DestroyObject(session, h_key);
++ h_key = CK_INVALID_HANDLE;
++ }
++
++ UNLOCK_OBJSTORE(OP_RSA);
++
++malloc_err:
++ /*
++ * 6 to 13 entries in the key template are key components.
++ * They need to be freed apon exit or error.
++ */
++ for (i = 6; i <= 13; i++)
++ {
++ if (a_key_template[i].pValue != NULL)
++ {
++ (void) memset(a_key_template[i].pValue, 0,
++ a_key_template[i].ulValueLen);
++ OPENSSL_free(a_key_template[i].pValue);
++ a_key_template[i].pValue = NULL;
++ }
++ }
++
++ return (h_key);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ */
++static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
++ {
++ /*
++ * Provide protection against RSA structure reuse by making the
++ * check for cache hit stronger. Only public components of RSA
++ * key matter here so it is sufficient to compare them with values
++ * cached in PK11_SESSION structure.
++ */
++ if ((sp->opdata_rsa_pub != rsa) ||
++ (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
++ (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_rsa_object_pub(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ */
++static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
++ {
++ /*
++ * Provide protection against RSA structure reuse by making the
++ * check for cache hit stronger. Comparing private exponent of RSA
++ * key with value cached in PK11_SESSION structure should
++ * be sufficient.
++ */
++ if ((sp->opdata_rsa_priv != rsa) ||
++ (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0) ||
++ ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_rsa_object_priv(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++#endif
++
++#ifndef OPENSSL_NO_DSA
++/* The DSA function implementation */
++/* ARGSUSED */
++static int pk11_DSA_init(DSA *dsa)
++ {
++ return (1);
++ }
++
++/* ARGSUSED */
++static int pk11_DSA_finish(DSA *dsa)
++ {
++ return (1);
++ }
++
++
++static DSA_SIG *
++pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
++ {
++ BIGNUM *r = NULL, *s = NULL;
++ int i;
++ DSA_SIG *dsa_sig = NULL;
++
++ CK_RV rv;
++ CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
++ CK_MECHANISM *p_mech = &Mechanism_dsa;
++ CK_OBJECT_HANDLE h_priv_key;
++
++ /*
++ * The signature is the concatenation of r and s,
++ * each is 20 bytes long
++ */
++ unsigned char sigret[DSA_SIGNATURE_LEN];
++ unsigned long siglen = DSA_SIGNATURE_LEN;
++ unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
++
++ PK11_SESSION *sp = NULL;
++
++ if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
++ {
++ PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
++ goto ret;
++ }
++
++ i = BN_num_bytes(dsa->q); /* should be 20 */
++ if (dlen > i)
++ {
++ PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
++ goto ret;
++ }
++
++ if ((sp = pk11_get_session(OP_DSA)) == NULL)
++ goto ret;
++
++ (void) check_new_dsa_key_priv(sp, dsa);
++
++ h_priv_key = sp->opdata_dsa_priv_key;
++ if (h_priv_key == CK_INVALID_HANDLE)
++ h_priv_key = sp->opdata_dsa_priv_key =
++ pk11_get_private_dsa_key((DSA *)dsa,
++ &sp->opdata_dsa_priv,
++ &sp->opdata_dsa_priv_num, sp->session);
++
++ if (h_priv_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
++ goto ret;
++ }
++
++ (void) memset(sigret, 0, siglen);
++ rv = pFuncList->C_Sign(sp->session,
++ (unsigned char*) dgst, dlen, sigret,
++ (CK_ULONG_PTR) &siglen);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
++ goto ret;
++ }
++ }
++
++
++ if ((s = BN_new()) == NULL)
++ {
++ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
++ goto ret;
++ }
++
++ if ((r = BN_new()) == NULL)
++ {
++ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
++ goto ret;
++ }
++
++ if ((dsa_sig = DSA_SIG_new()) == NULL)
++ {
++ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
++ goto ret;
++ }
++
++ if (BN_bin2bn(sigret, siglen2, r) == NULL ||
++ BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
++ {
++ PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
++ goto ret;
++ }
++
++ dsa_sig->r = r;
++ dsa_sig->s = s;
++
++ret:
++ if (dsa_sig == NULL)
++ {
++ if (r != NULL)
++ BN_free(r);
++ if (s != NULL)
++ BN_free(s);
++ }
++
++ pk11_return_session(sp, OP_DSA);
++ return (dsa_sig);
++ }
++
++static int
++pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
++ DSA *dsa)
++ {
++ int i;
++ CK_RV rv;
++ int retval = 0;
++ CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
++ CK_MECHANISM *p_mech = &Mechanism_dsa;
++ CK_OBJECT_HANDLE h_pub_key;
++
++ unsigned char sigbuf[DSA_SIGNATURE_LEN];
++ unsigned long siglen = DSA_SIGNATURE_LEN;
++ unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
++
++ PK11_SESSION *sp = NULL;
++
++ if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
++ {
++ PK11err(PK11_F_DSA_VERIFY,
++ PK11_R_INVALID_DSA_SIGNATURE_R);
++ goto ret;
++ }
++
++ if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
++ {
++ PK11err(PK11_F_DSA_VERIFY,
++ PK11_R_INVALID_DSA_SIGNATURE_S);
++ goto ret;
++ }
++
++ i = BN_num_bytes(dsa->q); /* should be 20 */
++
++ if (dlen > i)
++ {
++ PK11err(PK11_F_DSA_VERIFY,
++ PK11_R_INVALID_SIGNATURE_LENGTH);
++ goto ret;
++ }
++
++ if ((sp = pk11_get_session(OP_DSA)) == NULL)
++ goto ret;
++
++ (void) check_new_dsa_key_pub(sp, dsa);
++
++ h_pub_key = sp->opdata_dsa_pub_key;
++ if (h_pub_key == CK_INVALID_HANDLE)
++ h_pub_key = sp->opdata_dsa_pub_key =
++ pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
++ &sp->opdata_dsa_pub_num, sp->session);
++
++ if (h_pub_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_VerifyInit(sp->session, p_mech,
++ h_pub_key);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
++ rv);
++ goto ret;
++ }
++
++ /*
++ * The representation of each of the two big numbers could
++ * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
++ * to act accordingly and shift if necessary.
++ */
++ (void) memset(sigbuf, 0, siglen);
++ BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
++ BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
++ BN_num_bytes(sig->s));
++
++ rv = pFuncList->C_Verify(sp->session,
++ (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
++ goto ret;
++ }
++ }
++
++ retval = 1;
++ret:
++
++ pk11_return_session(sp, OP_DSA);
++ return (retval);
++ }
++
++
++/*
++ * Create a public key object in a session from a given dsa structure.
++ * The *dsa_pub_num pointer is non-NULL for DSA public keys.
++ */
++static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
++ DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
++ {
++ CK_RV rv;
++ CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++ CK_ULONG found;
++ CK_KEY_TYPE k_type = CKK_DSA;
++ CK_ULONG ul_key_attr_count = 8;
++ CK_BBOOL rollback = FALSE;
++ int i;
++
++ CK_ATTRIBUTE a_key_template[] =
++ {
++ {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
++ {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
++ {CKA_TOKEN, &false, sizeof (true)},
++ {CKA_VERIFY, &true, sizeof (true)},
++ {CKA_PRIME, (void *)NULL, 0}, /* p */
++ {CKA_SUBPRIME, (void *)NULL, 0}, /* q */
++ {CKA_BASE, (void *)NULL, 0}, /* g */
++ {CKA_VALUE, (void *)NULL, 0} /* pub_key - y */
++ };
++
++ a_key_template[0].pValue = &o_key;
++ a_key_template[1].pValue = &k_type;
++
++ if (init_template_value(dsa->p, &a_key_template[4].pValue,
++ &a_key_template[4].ulValueLen) == 0 ||
++ init_template_value(dsa->q, &a_key_template[5].pValue,
++ &a_key_template[5].ulValueLen) == 0 ||
++ init_template_value(dsa->g, &a_key_template[6].pValue,
++ &a_key_template[6].ulValueLen) == 0 ||
++ init_template_value(dsa->pub_key, &a_key_template[7].pValue,
++ &a_key_template[7].ulValueLen) == 0)
++ {
++ PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(OP_DSA);
++ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
++ ul_key_attr_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSINIT,
++ rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjectsFinal(session);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
++ PK11_R_FINDOBJECTSFINAL, rv);
++ goto err;
++ }
++
++ if (found == 0)
++ {
++ rv = pFuncList->C_CreateObject(session,
++ a_key_template, ul_key_attr_count, &h_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
++ PK11_R_CREATEOBJECT, rv);
++ goto err;
++ }
++ }
++
++ if (dsa_pub_num != NULL)
++ if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
++ {
++ PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
++ rollback = TRUE;
++ goto err;
++ }
++
++ /* LINTED: E_CONSTANT_CONDITION */
++ KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
++ if (key_ptr != NULL)
++ *key_ptr = dsa;
++
++err:
++ if (rollback)
++ {
++ /*
++ * We do not care about the return value from C_DestroyObject()
++ * since we are doing rollback.
++ */
++ if (found == 0)
++ (void) pFuncList->C_DestroyObject(session, h_key);
++ h_key = CK_INVALID_HANDLE;
++ }
++
++ UNLOCK_OBJSTORE(OP_DSA);
++
++malloc_err:
++ for (i = 4; i <= 7; i++)
++ {
++ if (a_key_template[i].pValue != NULL)
++ {
++ OPENSSL_free(a_key_template[i].pValue);
++ a_key_template[i].pValue = NULL;
++ }
++ }
++
++ return (h_key);
++ }
++
++/*
++ * Create a private key object in the session from a given dsa structure
++ * The *dsa_priv_num pointer is non-NULL for DSA private keys.
++ */
++static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
++ DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
++ {
++ CK_RV rv;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++ CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
++ int i;
++ CK_ULONG found;
++ CK_KEY_TYPE k_type = CKK_DSA;
++ CK_ULONG ul_key_attr_count = 9;
++ CK_BBOOL rollback = FALSE;
++
++ /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
++ CK_ATTRIBUTE a_key_template[] =
++ {
++ {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
++ {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
++ {CKA_TOKEN, &false, sizeof (true)},
++ {CKA_SENSITIVE, &false, sizeof (true)},
++ {CKA_SIGN, &true, sizeof (true)},
++ {CKA_PRIME, (void *)NULL, 0}, /* p */
++ {CKA_SUBPRIME, (void *)NULL, 0}, /* q */
++ {CKA_BASE, (void *)NULL, 0}, /* g */
++ {CKA_VALUE, (void *)NULL, 0} /* priv_key - x */
++ };
++
++ a_key_template[0].pValue = &o_key;
++ a_key_template[1].pValue = &k_type;
++
++ /* Put the private key components into the template */
++ if (init_template_value(dsa->p, &a_key_template[5].pValue,
++ &a_key_template[5].ulValueLen) == 0 ||
++ init_template_value(dsa->q, &a_key_template[6].pValue,
++ &a_key_template[6].ulValueLen) == 0 ||
++ init_template_value(dsa->g, &a_key_template[7].pValue,
++ &a_key_template[7].ulValueLen) == 0 ||
++ init_template_value(dsa->priv_key, &a_key_template[8].pValue,
++ &a_key_template[8].ulValueLen) == 0)
++ {
++ PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(OP_DSA);
++ rv = pFuncList->C_FindObjectsInit(session, a_key_template,
++ ul_key_attr_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
++ PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
++ PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjectsFinal(session);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
++ PK11_R_FINDOBJECTSFINAL, rv);
++ goto err;
++ }
++
++ if (found == 0)
++ {
++ rv = pFuncList->C_CreateObject(session,
++ a_key_template, ul_key_attr_count, &h_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
++ PK11_R_CREATEOBJECT, rv);
++ goto err;
++ }
++ }
++
++ if (dsa_priv_num != NULL)
++ if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
++ {
++ PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
++ rollback = TRUE;
++ goto err;
++ }
++
++ /* LINTED: E_CONSTANT_CONDITION */
++ KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
++ if (key_ptr != NULL)
++ *key_ptr = dsa;
++
++err:
++ if (rollback)
++ {
++ /*
++ * We do not care about the return value from C_DestroyObject()
++ * since we are doing rollback.
++ */
++ if (found == 0)
++ (void) pFuncList->C_DestroyObject(session, h_key);
++ h_key = CK_INVALID_HANDLE;
++ }
++
++ UNLOCK_OBJSTORE(OP_DSA);
++
++malloc_err:
++ /*
++ * 5 to 8 entries in the key template are key components.
++ * They need to be freed apon exit or error.
++ */
++ for (i = 5; i <= 8; i++)
++ {
++ if (a_key_template[i].pValue != NULL)
++ {
++ (void) memset(a_key_template[i].pValue, 0,
++ a_key_template[i].ulValueLen);
++ OPENSSL_free(a_key_template[i].pValue);
++ a_key_template[i].pValue = NULL;
++ }
++ }
++
++ return (h_key);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ */
++static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
++ {
++ /*
++ * Provide protection against DSA structure reuse by making the
++ * check for cache hit stronger. Only public key component of DSA
++ * key matters here so it is sufficient to compare it with value
++ * cached in PK11_SESSION structure.
++ */
++ if ((sp->opdata_dsa_pub != dsa) ||
++ (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_dsa_object_pub(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ */
++static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
++ {
++ /*
++ * Provide protection against DSA structure reuse by making the
++ * check for cache hit stronger. Only private key component of DSA
++ * key matters here so it is sufficient to compare it with value
++ * cached in PK11_SESSION structure.
++ */
++ if ((sp->opdata_dsa_priv != dsa) ||
++ (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_dsa_object_priv(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++#endif
++
++
++#ifndef OPENSSL_NO_DH
++/* The DH function implementation */
++/* ARGSUSED */
++static int pk11_DH_init(DH *dh)
++ {
++ return (1);
++ }
++
++/* ARGSUSED */
++static int pk11_DH_finish(DH *dh)
++ {
++ return (1);
++ }
++
++/*
++ * Generate DH key-pair.
++ *
++ * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
++ * and override it even if it is set. OpenSSL does not touch dh->priv_key
++ * if set and just computes dh->pub_key. It looks like PKCS#11 standard
++ * is not capable of providing this functionality. This could be a problem
++ * for applications relying on OpenSSL's semantics.
++ */
++static int pk11_DH_generate_key(DH *dh)
++ {
++ CK_ULONG i;
++ CK_RV rv, rv1;
++ int reuse_mem_len = 0, ret = 0;
++ PK11_SESSION *sp = NULL;
++ CK_BYTE_PTR reuse_mem;
++
++ CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
++ CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
++ CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
++
++ CK_ULONG ul_pub_key_attr_count = 3;
++ CK_ATTRIBUTE pub_key_template[] =
++ {
++ {CKA_PRIVATE, &false, sizeof (false)},
++ {CKA_PRIME, (void *)NULL, 0},
++ {CKA_BASE, (void *)NULL, 0}
++ };
++
++ CK_ULONG ul_priv_key_attr_count = 3;
++ CK_ATTRIBUTE priv_key_template[] =
++ {
++ {CKA_PRIVATE, &false, sizeof (false)},
++ {CKA_SENSITIVE, &false, sizeof (false)},
++ {CKA_DERIVE, &true, sizeof (true)}
++ };
++
++ CK_ULONG pub_key_attr_result_count = 1;
++ CK_ATTRIBUTE pub_key_result[] =
++ {
++ {CKA_VALUE, (void *)NULL, 0}
++ };
++
++ CK_ULONG priv_key_attr_result_count = 1;
++ CK_ATTRIBUTE priv_key_result[] =
++ {
++ {CKA_VALUE, (void *)NULL, 0}
++ };
++
++ pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
++ if (pub_key_template[1].ulValueLen > 0)
++ {
++ /*
++ * We must not increase ulValueLen by DH_BUF_RESERVE since that
++ * could cause the same rounding problem. See definition of
++ * DH_BUF_RESERVE above.
++ */
++ pub_key_template[1].pValue =
++ OPENSSL_malloc(pub_key_template[1].ulValueLen +
++ DH_BUF_RESERVE);
++ if (pub_key_template[1].pValue == NULL)
++ {
++ PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
++ }
++ else
++ goto err;
++
++ pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
++ if (pub_key_template[2].ulValueLen > 0)
++ {
++ pub_key_template[2].pValue =
++ OPENSSL_malloc(pub_key_template[2].ulValueLen +
++ DH_BUF_RESERVE);
++ if (pub_key_template[2].pValue == NULL)
++ {
++ PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
++ }
++ else
++ goto err;
++
++ /*
++ * Note: we are only using PK11_SESSION structure for getting
++ * a session handle. The objects created in this function are
++ * destroyed before return and thus not cached.
++ */
++ if ((sp = pk11_get_session(OP_DH)) == NULL)
++ goto err;
++
++ rv = pFuncList->C_GenerateKeyPair(sp->session,
++ &mechanism,
++ pub_key_template,
++ ul_pub_key_attr_count,
++ priv_key_template,
++ ul_priv_key_attr_count,
++ &h_pub_key,
++ &h_priv_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
++ goto err;
++ }
++
++ /*
++ * Reuse the larger memory allocated. We know the larger memory
++ * should be sufficient for reuse.
++ */
++ if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
++ {
++ reuse_mem = pub_key_template[1].pValue;
++ reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
++ }
++ else
++ {
++ reuse_mem = pub_key_template[2].pValue;
++ reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
++ }
++
++ rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
++ pub_key_result, pub_key_attr_result_count);
++ rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
++ priv_key_result, priv_key_attr_result_count);
++
++ if (rv != CKR_OK || rv1 != CKR_OK)
++ {
++ rv = (rv != CKR_OK) ? rv : rv1;
++ PK11err_add_data(PK11_F_DH_GEN_KEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ goto err;
++ }
++
++ if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
++ ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
++ {
++ PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
++ goto err;
++ }
++
++ /* Reuse the memory allocated */
++ pub_key_result[0].pValue = reuse_mem;
++ pub_key_result[0].ulValueLen = reuse_mem_len;
++
++ rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
++ pub_key_result, pub_key_attr_result_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_GEN_KEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ goto err;
++ }
++
++ if (pub_key_result[0].type == CKA_VALUE)
++ {
++ if (dh->pub_key == NULL)
++ if ((dh->pub_key = BN_new()) == NULL)
++ {
++ PK11err(PK11_F_DH_GEN_KEY,
++ PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
++ pub_key_result[0].ulValueLen, dh->pub_key);
++ if (dh->pub_key == NULL)
++ {
++ PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ }
++
++ /* Reuse the memory allocated */
++ priv_key_result[0].pValue = reuse_mem;
++ priv_key_result[0].ulValueLen = reuse_mem_len;
++
++ rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
++ priv_key_result, priv_key_attr_result_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_GEN_KEY,
++ PK11_R_GETATTRIBUTVALUE, rv);
++ goto err;
++ }
++
++ if (priv_key_result[0].type == CKA_VALUE)
++ {
++ if (dh->priv_key == NULL)
++ if ((dh->priv_key = BN_new()) == NULL)
++ {
++ PK11err(PK11_F_DH_GEN_KEY,
++ PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
++ priv_key_result[0].ulValueLen, dh->priv_key);
++ if (dh->priv_key == NULL)
++ {
++ PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ }
++
++ ret = 1;
++
++err:
++
++ if (h_pub_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_GEN_KEY,
++ PK11_R_DESTROYOBJECT, rv);
++ }
++ }
++
++ if (h_priv_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_GEN_KEY,
++ PK11_R_DESTROYOBJECT, rv);
++ }
++ }
++
++ for (i = 1; i <= 2; i++)
++ {
++ if (pub_key_template[i].pValue != NULL)
++ {
++ OPENSSL_free(pub_key_template[i].pValue);
++ pub_key_template[i].pValue = NULL;
++ }
++ }
++
++ pk11_return_session(sp, OP_DH);
++ return (ret);
++ }
++
++static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
++ DH *dh)
++ {
++ unsigned int i;
++ CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
++ CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
++ CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
++ CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++
++ CK_ULONG ul_priv_key_attr_count = 2;
++ CK_ATTRIBUTE priv_key_template[] =
++ {
++ {CKA_CLASS, (void*) NULL, sizeof (key_class)},
++ {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
++ };
++
++ CK_ULONG priv_key_attr_result_count = 1;
++ CK_ATTRIBUTE priv_key_result[] =
++ {
++ {CKA_VALUE, (void *)NULL, 0}
++ };
++
++ CK_RV rv;
++ int ret = -1;
++ PK11_SESSION *sp = NULL;
++
++ if (dh->priv_key == NULL)
++ goto err;
++
++ priv_key_template[0].pValue = &key_class;
++ priv_key_template[1].pValue = &key_type;
++
++ if ((sp = pk11_get_session(OP_DH)) == NULL)
++ goto err;
++
++ mechanism.ulParameterLen = BN_num_bytes(pub_key);
++ mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
++ if (mechanism.pParameter == NULL)
++ {
++ PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++ BN_bn2bin(pub_key, mechanism.pParameter);
++
++ (void) check_new_dh_key(sp, dh);
++
++ h_key = sp->opdata_dh_key;
++ if (h_key == CK_INVALID_HANDLE)
++ h_key = sp->opdata_dh_key =
++ pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
++ &sp->opdata_dh_priv_num, sp->session);
++
++ if (h_key == CK_INVALID_HANDLE)
++ {
++ PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
++ goto err;
++ }
++
++ rv = pFuncList->C_DeriveKey(sp->session,
++ &mechanism,
++ h_key,
++ priv_key_template,
++ ul_priv_key_attr_count,
++ &h_derived_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
++ priv_key_result, priv_key_attr_result_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
++ rv);
++ goto err;
++ }
++
++ if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
++ {
++ PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
++ goto err;
++ }
++ priv_key_result[0].pValue =
++ OPENSSL_malloc(priv_key_result[0].ulValueLen);
++ if (!priv_key_result[0].pValue)
++ {
++ PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
++ priv_key_result, priv_key_attr_result_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
++ rv);
++ goto err;
++ }
++
++ /*
++ * OpenSSL allocates the output buffer 'key' which is the same
++ * length of the public key. It is long enough for the derived key
++ */
++ if (priv_key_result[0].type == CKA_VALUE)
++ {
++ /*
++ * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
++ * leading zeros from a computed shared secret. However,
++ * OpenSSL always did it so we must do the same here. The
++ * vagueness of the spec regarding leading zero bytes was
++ * finally cleared with TLS 1.1 (RFC 4346) saying that leading
++ * zeros are stripped before the computed data is used as the
++ * pre-master secret.
++ */
++ for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
++ {
++ if (((char *)priv_key_result[0].pValue)[i] != 0)
++ break;
++ }
++
++ (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
++ priv_key_result[0].ulValueLen - i);
++ ret = priv_key_result[0].ulValueLen - i;
++ }
++
++err:
++
++ if (h_derived_key != CK_INVALID_HANDLE)
++ {
++ rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_DH_COMP_KEY,
++ PK11_R_DESTROYOBJECT, rv);
++ }
++ }
++ if (priv_key_result[0].pValue)
++ {
++ OPENSSL_free(priv_key_result[0].pValue);
++ priv_key_result[0].pValue = NULL;
++ }
++
++ if (mechanism.pParameter)
++ {
++ OPENSSL_free(mechanism.pParameter);
++ mechanism.pParameter = NULL;
++ }
++
++ pk11_return_session(sp, OP_DH);
++ return (ret);
++ }
++
++
++static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
++ DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
++ {
++ CK_RV rv;
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
++ CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
++ CK_KEY_TYPE key_type = CKK_DH;
++ CK_ULONG found;
++ CK_BBOOL rollback = FALSE;
++ int i;
++
++ CK_ULONG ul_key_attr_count = 7;
++ CK_ATTRIBUTE key_template[] =
++ {
++ {CKA_CLASS, (void*) NULL, sizeof (class)},
++ {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
++ {CKA_DERIVE, &true, sizeof (true)},
++ {CKA_PRIVATE, &false, sizeof (false)},
++ {CKA_PRIME, (void *) NULL, 0},
++ {CKA_BASE, (void *) NULL, 0},
++ {CKA_VALUE, (void *) NULL, 0},
++ };
++
++ key_template[0].pValue = &class;
++ key_template[1].pValue = &key_type;
++
++ key_template[4].ulValueLen = BN_num_bytes(dh->p);
++ key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
++ (size_t)key_template[4].ulValueLen);
++ if (key_template[4].pValue == NULL)
++ {
++ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ BN_bn2bin(dh->p, key_template[4].pValue);
++
++ key_template[5].ulValueLen = BN_num_bytes(dh->g);
++ key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
++ (size_t)key_template[5].ulValueLen);
++ if (key_template[5].pValue == NULL)
++ {
++ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ BN_bn2bin(dh->g, key_template[5].pValue);
++
++ key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
++ key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
++ (size_t)key_template[6].ulValueLen);
++ if (key_template[6].pValue == NULL)
++ {
++ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
++ goto malloc_err;
++ }
++
++ BN_bn2bin(dh->priv_key, key_template[6].pValue);
++
++ /* see find_lock array definition for more info on object locking */
++ LOCK_OBJSTORE(OP_DH);
++ rv = pFuncList->C_FindObjectsInit(session, key_template,
++ ul_key_attr_count);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
++ goto err;
++ }
++
++ rv = pFuncList->C_FindObjectsFinal(session);
++
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
++ rv);
++ goto err;
++ }
++
++ if (found == 0)
++ {
++ rv = pFuncList->C_CreateObject(session,
++ key_template, ul_key_attr_count, &h_key);
++ if (rv != CKR_OK)
++ {
++ PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
++ rv);
++ goto err;
++ }
++ }
++
++ if (dh_priv_num != NULL)
++ if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
++ {
++ PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
++ rollback = TRUE;
++ goto err;
++ }
++
++ /* LINTED: E_CONSTANT_CONDITION */
++ KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
++ if (key_ptr != NULL)
++ *key_ptr = dh;
++
++err:
++ if (rollback)
++ {
++ /*
++ * We do not care about the return value from C_DestroyObject()
++ * since we are doing rollback.
++ */
++ if (found == 0)
++ (void) pFuncList->C_DestroyObject(session, h_key);
++ h_key = CK_INVALID_HANDLE;
++ }
++
++ UNLOCK_OBJSTORE(OP_DH);
++
++malloc_err:
++ for (i = 4; i <= 6; i++)
++ {
++ if (key_template[i].pValue != NULL)
++ {
++ OPENSSL_free(key_template[i].pValue);
++ key_template[i].pValue = NULL;
++ }
++ }
++
++ return (h_key);
++ }
++
++/*
++ * Check for cache miss and clean the object pointer and handle
++ * in such case. Return 1 for cache hit, 0 for cache miss.
++ *
++ * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
++ * to CK_INVALID_HANDLE even when it fails to destroy the object.
++ */
++static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
++ {
++ /*
++ * Provide protection against DH structure reuse by making the
++ * check for cache hit stronger. Private key component of DH key
++ * is unique so it is sufficient to compare it with value cached
++ * in PK11_SESSION structure.
++ */
++ if ((sp->opdata_dh != dh) ||
++ (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
++ {
++ /*
++ * We do not check the return value because even in case of
++ * failure the sp structure will have both key pointer
++ * and object handle cleaned and pk11_destroy_object()
++ * reports the failure to the OpenSSL error message buffer.
++ */
++ (void) pk11_destroy_dh_object(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
++#endif
++
++/*
++ * Local function to simplify key template population
++ * Return 0 -- error, 1 -- no error
++ */
++static int init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
++ CK_ULONG *ul_value_len)
++ {
++ CK_ULONG len = BN_num_bytes(bn);
++ if (len == 0)
++ return (1);
++
++ *ul_value_len = len;
++ *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
++ if (*p_value == NULL)
++ return (0);
++
++ BN_bn2bin(bn, *p_value);
++
++ return (1);
++ }
++
++static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
++ {
++ if (attr->ulValueLen > 0)
++ {
++ *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
++ }
++ }
++#ifdef OPENSSL_SYS_WIN32
++char *getpassphrase(const char *prompt)
++ {
++ static char buf[128];
++ HANDLE h;
++ DWORD cc, mode;
++ int cnt;
++
++ h = GetStdHandle(STD_INPUT_HANDLE);
++ fputs(prompt, stderr);
++ fflush(stderr);
++ fflush(stdout);
++ FlushConsoleInputBuffer(h);
++ GetConsoleMode(h, &mode);
++ SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
++
++ for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
++ {
++ ReadFile(h, buf + cnt, 1, &cc, NULL);
++ if (buf[cnt] == '\r')
++ break;
++ fputc('*', stdout);
++ fflush(stderr);
++ fflush(stdout);
++ }
++
++ SetConsoleMode(h, mode);
++ buf[cnt] = '\0';
++ fputs("\n", stderr);
++ return buf;
++ }
++#endif /* OPENSSL_SYS_WIN32 */
++#endif /* OPENSSL_NO_HW_PK11 */
++#endif /* OPENSSL_NO_HW */
+Index: openssl/crypto/engine/pkcs11.h
+diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/pkcs11.h Wed Oct 24 23:27:09 2007
+@@ -0,0 +1,299 @@
++/* pkcs11.h include file for PKCS #11. */
++/* $Revision: 1.4 $ */
++
++/* License to copy and use this software is granted provided that it is
++ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
++ * (Cryptoki)" in all material mentioning or referencing this software.
++
++ * License is also granted to make and use derivative works provided that
++ * such works are identified as "derived from the RSA Security Inc. PKCS #11
++ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
++ * referencing the derived work.
++
++ * RSA Security Inc. makes no representations concerning either the
++ * merchantability of this software or the suitability of this software for
++ * any particular purpose. It is provided "as is" without express or implied
++ * warranty of any kind.
++ */
++
++#ifndef _PKCS11_H_
++#define _PKCS11_H_ 1
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Before including this file (pkcs11.h) (or pkcs11t.h by
++ * itself), 6 platform-specific macros must be defined. These
++ * macros are described below, and typical definitions for them
++ * are also given. Be advised that these definitions can depend
++ * on both the platform and the compiler used (and possibly also
++ * on whether a Cryptoki library is linked statically or
++ * dynamically).
++ *
++ * In addition to defining these 6 macros, the packing convention
++ * for Cryptoki structures should be set. The Cryptoki
++ * convention on packing is that structures should be 1-byte
++ * aligned.
++ *
++ * If you're using Microsoft Developer Studio 5.0 to produce
++ * Win32 stuff, this might be done by using the following
++ * preprocessor directive before including pkcs11.h or pkcs11t.h:
++ *
++ * #pragma pack(push, cryptoki, 1)
++ *
++ * and using the following preprocessor directive after including
++ * pkcs11.h or pkcs11t.h:
++ *
++ * #pragma pack(pop, cryptoki)
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to produce Win16 stuff, this might be done by using
++ * the following preprocessor directive before including
++ * pkcs11.h or pkcs11t.h:
++ *
++ * #pragma pack(1)
++ *
++ * In a UNIX environment, you're on your own for this. You might
++ * not need to do (or be able to do!) anything.
++ *
++ *
++ * Now for the macros:
++ *
++ *
++ * 1. CK_PTR: The indirection string for making a pointer to an
++ * object. It can be used like this:
++ *
++ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
++ *
++ * If you're using Microsoft Developer Studio 5.0 to produce
++ * Win32 stuff, it might be defined by:
++ *
++ * #define CK_PTR *
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to produce Win16 stuff, it might be defined by:
++ *
++ * #define CK_PTR far *
++ *
++ * In a typical UNIX environment, it might be defined by:
++ *
++ * #define CK_PTR *
++ *
++ *
++ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
++ * an exportable Cryptoki library function definition out of a
++ * return type and a function name. It should be used in the
++ * following fashion to define the exposed Cryptoki functions in
++ * a Cryptoki library:
++ *
++ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
++ * CK_VOID_PTR pReserved
++ * )
++ * {
++ * ...
++ * }
++ *
++ * If you're using Microsoft Developer Studio 5.0 to define a
++ * function in a Win32 Cryptoki .dll, it might be defined by:
++ *
++ * #define CK_DEFINE_FUNCTION(returnType, name) \
++ * returnType __declspec(dllexport) name
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to define a function in a Win16 Cryptoki .dll, it
++ * might be defined by:
++ *
++ * #define CK_DEFINE_FUNCTION(returnType, name) \
++ * returnType __export _far _pascal name
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_DEFINE_FUNCTION(returnType, name) \
++ * returnType name
++ *
++ *
++ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
++ * an importable Cryptoki library function declaration out of a
++ * return type and a function name. It should be used in the
++ * following fashion:
++ *
++ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
++ * CK_VOID_PTR pReserved
++ * );
++ *
++ * If you're using Microsoft Developer Studio 5.0 to declare a
++ * function in a Win32 Cryptoki .dll, it might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION(returnType, name) \
++ * returnType __declspec(dllimport) name
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to declare a function in a Win16 Cryptoki .dll, it
++ * might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION(returnType, name) \
++ * returnType __export _far _pascal name
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION(returnType, name) \
++ * returnType name
++ *
++ *
++ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
++ * which makes a Cryptoki API function pointer declaration or
++ * function pointer type declaration out of a return type and a
++ * function name. It should be used in the following fashion:
++ *
++ * // Define funcPtr to be a pointer to a Cryptoki API function
++ * // taking arguments args and returning CK_RV.
++ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
++ *
++ * or
++ *
++ * // Define funcPtrType to be the type of a pointer to a
++ * // Cryptoki API function taking arguments args and returning
++ * // CK_RV, and then define funcPtr to be a variable of type
++ * // funcPtrType.
++ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
++ * funcPtrType funcPtr;
++ *
++ * If you're using Microsoft Developer Studio 5.0 to access
++ * functions in a Win32 Cryptoki .dll, in might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ * returnType __declspec(dllimport) (* name)
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to access functions in a Win16 Cryptoki .dll, it might
++ * be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ * returnType __export _far _pascal (* name)
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ * returnType (* name)
++ *
++ *
++ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
++ * a function pointer type for an application callback out of
++ * a return type for the callback and a name for the callback.
++ * It should be used in the following fashion:
++ *
++ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
++ *
++ * to declare a function pointer, myCallback, to a callback
++ * which takes arguments args and returns a CK_RV. It can also
++ * be used like this:
++ *
++ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
++ * myCallbackType myCallback;
++ *
++ * If you're using Microsoft Developer Studio 5.0 to do Win32
++ * Cryptoki development, it might be defined by:
++ *
++ * #define CK_CALLBACK_FUNCTION(returnType, name) \
++ * returnType (* name)
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to do Win16 development, it might be defined by:
++ *
++ * #define CK_CALLBACK_FUNCTION(returnType, name) \
++ * returnType _far _pascal (* name)
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_CALLBACK_FUNCTION(returnType, name) \
++ * returnType (* name)
++ *
++ *
++ * 6. NULL_PTR: This macro is the value of a NULL pointer.
++ *
++ * In any ANSI/ISO C environment (and in many others as well),
++ * this should best be defined by
++ *
++ * #ifndef NULL_PTR
++ * #define NULL_PTR 0
++ * #endif
++ */
++
++
++/* All the various Cryptoki types and #define'd values are in the
++ * file pkcs11t.h. */
++#include "pkcs11t.h"
++
++#define __PASTE(x,y) x##y
++
++
++/* ==============================================================
++ * Define the "extern" form of all the entry points.
++ * ==============================================================
++ */
++
++#define CK_NEED_ARG_LIST 1
++#define CK_PKCS11_FUNCTION_INFO(name) \
++ extern CK_DECLARE_FUNCTION(CK_RV, name)
++
++/* pkcs11f.h has all the information about the Cryptoki
++ * function prototypes. */
++#include "pkcs11f.h"
++
++#undef CK_NEED_ARG_LIST
++#undef CK_PKCS11_FUNCTION_INFO
++
++
++/* ==============================================================
++ * Define the typedef form of all the entry points. That is, for
++ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
++ * a pointer to that kind of function.
++ * ==============================================================
++ */
++
++#define CK_NEED_ARG_LIST 1
++#define CK_PKCS11_FUNCTION_INFO(name) \
++ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
++
++/* pkcs11f.h has all the information about the Cryptoki
++ * function prototypes. */
++#include "pkcs11f.h"
++
++#undef CK_NEED_ARG_LIST
++#undef CK_PKCS11_FUNCTION_INFO
++
++
++/* ==============================================================
++ * Define structed vector of entry points. A CK_FUNCTION_LIST
++ * contains a CK_VERSION indicating a library's Cryptoki version
++ * and then a whole slew of function pointers to the routines in
++ * the library. This type was declared, but not defined, in
++ * pkcs11t.h.
++ * ==============================================================
++ */
++
++#define CK_PKCS11_FUNCTION_INFO(name) \
++ __PASTE(CK_,name) name;
++
++struct CK_FUNCTION_LIST {
++
++ CK_VERSION version; /* Cryptoki version */
++
++/* Pile all the function pointers into the CK_FUNCTION_LIST. */
++/* pkcs11f.h has all the information about the Cryptoki
++ * function prototypes. */
++#include "pkcs11f.h"
++
++};
++
++#undef CK_PKCS11_FUNCTION_INFO
++
++
++#undef __PASTE
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+Index: openssl/crypto/engine/pkcs11f.h
+diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/pkcs11f.h Wed Oct 24 23:27:09 2007
+@@ -0,0 +1,912 @@
++/* pkcs11f.h include file for PKCS #11. */
++/* $Revision: 1.4 $ */
++
++/* License to copy and use this software is granted provided that it is
++ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
++ * (Cryptoki)" in all material mentioning or referencing this software.
++
++ * License is also granted to make and use derivative works provided that
++ * such works are identified as "derived from the RSA Security Inc. PKCS #11
++ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
++ * referencing the derived work.
++
++ * RSA Security Inc. makes no representations concerning either the
++ * merchantability of this software or the suitability of this software for
++ * any particular purpose. It is provided "as is" without express or implied
++ * warranty of any kind.
++ */
++
++/* This header file contains pretty much everything about all the */
++/* Cryptoki function prototypes. Because this information is */
++/* used for more than just declaring function prototypes, the */
++/* order of the functions appearing herein is important, and */
++/* should not be altered. */
++
++/* General-purpose */
++
++/* C_Initialize initializes the Cryptoki library. */
++CK_PKCS11_FUNCTION_INFO(C_Initialize)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
++ * cast to CK_C_INITIALIZE_ARGS_PTR
++ * and dereferenced */
++);
++#endif
++
++
++/* C_Finalize indicates that an application is done with the
++ * Cryptoki library. */
++CK_PKCS11_FUNCTION_INFO(C_Finalize)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
++);
++#endif
++
++
++/* C_GetInfo returns general information about Cryptoki. */
++CK_PKCS11_FUNCTION_INFO(C_GetInfo)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_INFO_PTR pInfo /* location that receives information */
++);
++#endif
++
++
++/* C_GetFunctionList returns the function list. */
++CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
++ * function list */
++);
++#endif
++
++
++
++/* Slot and token management */
++
++/* C_GetSlotList obtains a list of slots in the system. */
++CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_BBOOL tokenPresent, /* only slots with tokens? */
++ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
++ CK_ULONG_PTR pulCount /* receives number of slots */
++);
++#endif
++
++
++/* C_GetSlotInfo obtains information about a particular slot in
++ * the system. */
++CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SLOT_ID slotID, /* the ID of the slot */
++ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
++);
++#endif
++
++
++/* C_GetTokenInfo obtains information about a particular token
++ * in the system. */
++CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SLOT_ID slotID, /* ID of the token's slot */
++ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
++);
++#endif
++
++
++/* C_GetMechanismList obtains a list of mechanism types
++ * supported by a token. */
++CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SLOT_ID slotID, /* ID of token's slot */
++ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
++ CK_ULONG_PTR pulCount /* gets # of mechs. */
++);
++#endif
++
++
++/* C_GetMechanismInfo obtains information about a particular
++ * mechanism possibly supported by a token. */
++CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SLOT_ID slotID, /* ID of the token's slot */
++ CK_MECHANISM_TYPE type, /* type of mechanism */
++ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
++);
++#endif
++
++
++/* C_InitToken initializes a token. */
++CK_PKCS11_FUNCTION_INFO(C_InitToken)
++#ifdef CK_NEED_ARG_LIST
++/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
++(
++ CK_SLOT_ID slotID, /* ID of the token's slot */
++ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
++ CK_ULONG ulPinLen, /* length in bytes of the PIN */
++ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
++);
++#endif
++
++
++/* C_InitPIN initializes the normal user's PIN. */
++CK_PKCS11_FUNCTION_INFO(C_InitPIN)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
++ CK_ULONG ulPinLen /* length in bytes of the PIN */
++);
++#endif
++
++
++/* C_SetPIN modifies the PIN of the user who is logged in. */
++CK_PKCS11_FUNCTION_INFO(C_SetPIN)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
++ CK_ULONG ulOldLen, /* length of the old PIN */
++ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
++ CK_ULONG ulNewLen /* length of the new PIN */
++);
++#endif
++
++
++
++/* Session management */
++
++/* C_OpenSession opens a session between an application and a
++ * token. */
++CK_PKCS11_FUNCTION_INFO(C_OpenSession)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SLOT_ID slotID, /* the slot's ID */
++ CK_FLAGS flags, /* from CK_SESSION_INFO */
++ CK_VOID_PTR pApplication, /* passed to callback */
++ CK_NOTIFY Notify, /* callback function */
++ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
++);
++#endif
++
++
++/* C_CloseSession closes a session between an application and a
++ * token. */
++CK_PKCS11_FUNCTION_INFO(C_CloseSession)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++/* C_CloseAllSessions closes all sessions with a token. */
++CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SLOT_ID slotID /* the token's slot */
++);
++#endif
++
++
++/* C_GetSessionInfo obtains information about the session. */
++CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_SESSION_INFO_PTR pInfo /* receives session info */
++);
++#endif
++
++
++/* C_GetOperationState obtains the state of the cryptographic operation
++ * in a session. */
++CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pOperationState, /* gets state */
++ CK_ULONG_PTR pulOperationStateLen /* gets state length */
++);
++#endif
++
++
++/* C_SetOperationState restores the state of the cryptographic
++ * operation in a session. */
++CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pOperationState, /* holds state */
++ CK_ULONG ulOperationStateLen, /* holds state length */
++ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
++ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
++);
++#endif
++
++
++/* C_Login logs a user into a token. */
++CK_PKCS11_FUNCTION_INFO(C_Login)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_USER_TYPE userType, /* the user type */
++ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
++ CK_ULONG ulPinLen /* the length of the PIN */
++);
++#endif
++
++
++/* C_Logout logs a user out from a token. */
++CK_PKCS11_FUNCTION_INFO(C_Logout)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++
++/* Object management */
++
++/* C_CreateObject creates a new object. */
++CK_PKCS11_FUNCTION_INFO(C_CreateObject)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
++ CK_ULONG ulCount, /* attributes in template */
++ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
++);
++#endif
++
++
++/* C_CopyObject copies an object, creating a new object for the
++ * copy. */
++CK_PKCS11_FUNCTION_INFO(C_CopyObject)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_OBJECT_HANDLE hObject, /* the object's handle */
++ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
++ CK_ULONG ulCount, /* attributes in template */
++ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
++);
++#endif
++
++
++/* C_DestroyObject destroys an object. */
++CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_OBJECT_HANDLE hObject /* the object's handle */
++);
++#endif
++
++
++/* C_GetObjectSize gets the size of an object in bytes. */
++CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_OBJECT_HANDLE hObject, /* the object's handle */
++ CK_ULONG_PTR pulSize /* receives size of object */
++);
++#endif
++
++
++/* C_GetAttributeValue obtains the value of one or more object
++ * attributes. */
++CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_OBJECT_HANDLE hObject, /* the object's handle */
++ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
++ CK_ULONG ulCount /* attributes in template */
++);
++#endif
++
++
++/* C_SetAttributeValue modifies the value of one or more object
++ * attributes */
++CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_OBJECT_HANDLE hObject, /* the object's handle */
++ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
++ CK_ULONG ulCount /* attributes in template */
++);
++#endif
++
++
++/* C_FindObjectsInit initializes a search for token and session
++ * objects that match a template. */
++CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
++ CK_ULONG ulCount /* attrs in search template */
++);
++#endif
++
++
++/* C_FindObjects continues a search for token and session
++ * objects that match a template, obtaining additional object
++ * handles. */
++CK_PKCS11_FUNCTION_INFO(C_FindObjects)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
++ CK_ULONG ulMaxObjectCount, /* max handles to get */
++ CK_ULONG_PTR pulObjectCount /* actual # returned */
++);
++#endif
++
++
++/* C_FindObjectsFinal finishes a search for token and session
++ * objects. */
++CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++
++/* Encryption and decryption */
++
++/* C_EncryptInit initializes an encryption operation. */
++CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
++ CK_OBJECT_HANDLE hKey /* handle of encryption key */
++);
++#endif
++
++
++/* C_Encrypt encrypts single-part data. */
++CK_PKCS11_FUNCTION_INFO(C_Encrypt)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pData, /* the plaintext data */
++ CK_ULONG ulDataLen, /* bytes of plaintext */
++ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
++ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
++);
++#endif
++
++
++/* C_EncryptUpdate continues a multiple-part encryption
++ * operation. */
++CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pPart, /* the plaintext data */
++ CK_ULONG ulPartLen, /* plaintext data len */
++ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
++ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
++);
++#endif
++
++
++/* C_EncryptFinal finishes a multiple-part encryption
++ * operation. */
++CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session handle */
++ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
++ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
++);
++#endif
++
++
++/* C_DecryptInit initializes a decryption operation. */
++CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
++ CK_OBJECT_HANDLE hKey /* handle of decryption key */
++);
++#endif
++
++
++/* C_Decrypt decrypts encrypted data in a single part. */
++CK_PKCS11_FUNCTION_INFO(C_Decrypt)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pEncryptedData, /* ciphertext */
++ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
++ CK_BYTE_PTR pData, /* gets plaintext */
++ CK_ULONG_PTR pulDataLen /* gets p-text size */
++);
++#endif
++
++
++/* C_DecryptUpdate continues a multiple-part decryption
++ * operation. */
++CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
++ CK_ULONG ulEncryptedPartLen, /* input length */
++ CK_BYTE_PTR pPart, /* gets plaintext */
++ CK_ULONG_PTR pulPartLen /* p-text size */
++);
++#endif
++
++
++/* C_DecryptFinal finishes a multiple-part decryption
++ * operation. */
++CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pLastPart, /* gets plaintext */
++ CK_ULONG_PTR pulLastPartLen /* p-text size */
++);
++#endif
++
++
++
++/* Message digesting */
++
++/* C_DigestInit initializes a message-digesting operation. */
++CK_PKCS11_FUNCTION_INFO(C_DigestInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
++);
++#endif
++
++
++/* C_Digest digests data in a single part. */
++CK_PKCS11_FUNCTION_INFO(C_Digest)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pData, /* data to be digested */
++ CK_ULONG ulDataLen, /* bytes of data to digest */
++ CK_BYTE_PTR pDigest, /* gets the message digest */
++ CK_ULONG_PTR pulDigestLen /* gets digest length */
++);
++#endif
++
++
++/* C_DigestUpdate continues a multiple-part message-digesting
++ * operation. */
++CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pPart, /* data to be digested */
++ CK_ULONG ulPartLen /* bytes of data to be digested */
++);
++#endif
++
++
++/* C_DigestKey continues a multi-part message-digesting
++ * operation, by digesting the value of a secret key as part of
++ * the data already digested. */
++CK_PKCS11_FUNCTION_INFO(C_DigestKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_OBJECT_HANDLE hKey /* secret key to digest */
++);
++#endif
++
++
++/* C_DigestFinal finishes a multiple-part message-digesting
++ * operation. */
++CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pDigest, /* gets the message digest */
++ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
++);
++#endif
++
++
++
++/* Signing and MACing */
++
++/* C_SignInit initializes a signature (private key encryption)
++ * operation, where the signature is (will be) an appendix to
++ * the data, and plaintext cannot be recovered from the
++ *signature. */
++CK_PKCS11_FUNCTION_INFO(C_SignInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
++ CK_OBJECT_HANDLE hKey /* handle of signature key */
++);
++#endif
++
++
++/* C_Sign signs (encrypts with private key) data in a single
++ * part, where the signature is (will be) an appendix to the
++ * data, and plaintext cannot be recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_Sign)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pData, /* the data to sign */
++ CK_ULONG ulDataLen, /* count of bytes to sign */
++ CK_BYTE_PTR pSignature, /* gets the signature */
++ CK_ULONG_PTR pulSignatureLen /* gets signature length */
++);
++#endif
++
++
++/* C_SignUpdate continues a multiple-part signature operation,
++ * where the signature is (will be) an appendix to the data,
++ * and plaintext cannot be recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pPart, /* the data to sign */
++ CK_ULONG ulPartLen /* count of bytes to sign */
++);
++#endif
++
++
++/* C_SignFinal finishes a multiple-part signature operation,
++ * returning the signature. */
++CK_PKCS11_FUNCTION_INFO(C_SignFinal)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pSignature, /* gets the signature */
++ CK_ULONG_PTR pulSignatureLen /* gets signature length */
++);
++#endif
++
++
++/* C_SignRecoverInit initializes a signature operation, where
++ * the data can be recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
++ CK_OBJECT_HANDLE hKey /* handle of the signature key */
++);
++#endif
++
++
++/* C_SignRecover signs data in a single operation, where the
++ * data can be recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_SignRecover)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pData, /* the data to sign */
++ CK_ULONG ulDataLen, /* count of bytes to sign */
++ CK_BYTE_PTR pSignature, /* gets the signature */
++ CK_ULONG_PTR pulSignatureLen /* gets signature length */
++);
++#endif
++
++
++
++/* Verifying signatures and MACs */
++
++/* C_VerifyInit initializes a verification operation, where the
++ * signature is an appendix to the data, and plaintext cannot
++ * cannot be recovered from the signature (e.g. DSA). */
++CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
++ CK_OBJECT_HANDLE hKey /* verification key */
++);
++#endif
++
++
++/* C_Verify verifies a signature in a single-part operation,
++ * where the signature is an appendix to the data, and plaintext
++ * cannot be recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_Verify)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pData, /* signed data */
++ CK_ULONG ulDataLen, /* length of signed data */
++ CK_BYTE_PTR pSignature, /* signature */
++ CK_ULONG ulSignatureLen /* signature length*/
++);
++#endif
++
++
++/* C_VerifyUpdate continues a multiple-part verification
++ * operation, where the signature is an appendix to the data,
++ * and plaintext cannot be recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pPart, /* signed data */
++ CK_ULONG ulPartLen /* length of signed data */
++);
++#endif
++
++
++/* C_VerifyFinal finishes a multiple-part verification
++ * operation, checking the signature. */
++CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pSignature, /* signature to verify */
++ CK_ULONG ulSignatureLen /* signature length */
++);
++#endif
++
++
++/* C_VerifyRecoverInit initializes a signature verification
++ * operation, where the data is recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
++ CK_OBJECT_HANDLE hKey /* verification key */
++);
++#endif
++
++
++/* C_VerifyRecover verifies a signature in a single-part
++ * operation, where the data is recovered from the signature. */
++CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pSignature, /* signature to verify */
++ CK_ULONG ulSignatureLen, /* signature length */
++ CK_BYTE_PTR pData, /* gets signed data */
++ CK_ULONG_PTR pulDataLen /* gets signed data len */
++);
++#endif
++
++
++
++/* Dual-function cryptographic operations */
++
++/* C_DigestEncryptUpdate continues a multiple-part digesting
++ * and encryption operation. */
++CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pPart, /* the plaintext data */
++ CK_ULONG ulPartLen, /* plaintext length */
++ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
++ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
++);
++#endif
++
++
++/* C_DecryptDigestUpdate continues a multiple-part decryption and
++ * digesting operation. */
++CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
++ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
++ CK_BYTE_PTR pPart, /* gets plaintext */
++ CK_ULONG_PTR pulPartLen /* gets plaintext len */
++);
++#endif
++
++
++/* C_SignEncryptUpdate continues a multiple-part signing and
++ * encryption operation. */
++CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pPart, /* the plaintext data */
++ CK_ULONG ulPartLen, /* plaintext length */
++ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
++ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
++);
++#endif
++
++
++/* C_DecryptVerifyUpdate continues a multiple-part decryption and
++ * verify operation. */
++CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
++ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
++ CK_BYTE_PTR pPart, /* gets plaintext */
++ CK_ULONG_PTR pulPartLen /* gets p-text length */
++);
++#endif
++
++
++
++/* Key management */
++
++/* C_GenerateKey generates a secret key, creating a new key
++ * object. */
++CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
++ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
++ CK_ULONG ulCount, /* # of attrs in template */
++ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
++);
++#endif
++
++
++/* C_GenerateKeyPair generates a public-key/private-key pair,
++ * creating new key objects. */
++CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session
++ * handle */
++ CK_MECHANISM_PTR pMechanism, /* key-gen
++ * mech. */
++ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
++ * for pub.
++ * key */
++ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
++ * attrs. */
++ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
++ * for priv.
++ * key */
++ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
++ * attrs. */
++ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
++ * key
++ * handle */
++ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
++ * priv. key
++ * handle */
++);
++#endif
++
++
++/* C_WrapKey wraps (i.e., encrypts) a key. */
++CK_PKCS11_FUNCTION_INFO(C_WrapKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
++ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
++ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
++ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
++ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
++);
++#endif
++
++
++/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
++ * key object. */
++CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
++ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
++ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
++ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
++ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
++ CK_ULONG ulAttributeCount, /* template length */
++ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
++);
++#endif
++
++
++/* C_DeriveKey derives a key from a base key, creating a new key
++ * object. */
++CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
++ CK_OBJECT_HANDLE hBaseKey, /* base key */
++ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
++ CK_ULONG ulAttributeCount, /* template length */
++ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
++);
++#endif
++
++
++
++/* Random number generation */
++
++/* C_SeedRandom mixes additional seed material into the token's
++ * random number generator. */
++CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pSeed, /* the seed material */
++ CK_ULONG ulSeedLen /* length of seed material */
++);
++#endif
++
++
++/* C_GenerateRandom generates random data. */
++CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR RandomData, /* receives the random data */
++ CK_ULONG ulRandomLen /* # of bytes to generate */
++);
++#endif
++
++
++
++/* Parallel function management */
++
++/* C_GetFunctionStatus is a legacy function; it obtains an
++ * updated status of a function running in parallel with an
++ * application. */
++CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++/* C_CancelFunction is a legacy function; it cancels a function
++ * running in parallel. */
++CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++
++/* Functions added in for Cryptoki Version 2.01 or later */
++
++/* C_WaitForSlotEvent waits for a slot event (token insertion,
++ * removal, etc.) to occur. */
++CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_FLAGS flags, /* blocking/nonblocking flag */
++ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
++ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
++);
++#endif
+Index: openssl/crypto/engine/pkcs11t.h
+diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
+--- /dev/null Wed Sep 2 11:37:23 2009
++++ openssl/crypto/engine/pkcs11t.h Sat Aug 30 11:58:07 2008
+@@ -0,0 +1,1885 @@
++/* pkcs11t.h include file for PKCS #11. */
++/* $Revision: 1.4 $ */
++
++/* License to copy and use this software is granted provided that it is
++ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
++ * (Cryptoki)" in all material mentioning or referencing this software.
++
++ * License is also granted to make and use derivative works provided that
++ * such works are identified as "derived from the RSA Security Inc. PKCS #11
++ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
++ * referencing the derived work.
++
++ * RSA Security Inc. makes no representations concerning either the
++ * merchantability of this software or the suitability of this software for
++ * any particular purpose. It is provided "as is" without express or implied
++ * warranty of any kind.
++ */
++
++/* See top of pkcs11.h for information about the macros that
++ * must be defined and the structure-packing conventions that
++ * must be set before including this file. */
++
++#ifndef _PKCS11T_H_
++#define _PKCS11T_H_ 1
++
++#define CRYPTOKI_VERSION_MAJOR 2
++#define CRYPTOKI_VERSION_MINOR 20
++#define CRYPTOKI_VERSION_AMENDMENT 3
++
++#define CK_TRUE 1
++#define CK_FALSE 0
++
++#ifndef CK_DISABLE_TRUE_FALSE
++#ifndef FALSE
++#define FALSE CK_FALSE
++#endif
++
++#ifndef TRUE
++#define TRUE CK_TRUE
++#endif
++#endif
++
++/* an unsigned 8-bit value */
++typedef unsigned char CK_BYTE;
++
++/* an unsigned 8-bit character */
++typedef CK_BYTE CK_CHAR;
++
++/* an 8-bit UTF-8 character */
++typedef CK_BYTE CK_UTF8CHAR;
++
++/* a BYTE-sized Boolean flag */
++typedef CK_BYTE CK_BBOOL;
++
++/* an unsigned value, at least 32 bits long */
++typedef unsigned long int CK_ULONG;
++
++/* a signed value, the same size as a CK_ULONG */
++/* CK_LONG is new for v2.0 */
++typedef long int CK_LONG;
++
++/* at least 32 bits; each bit is a Boolean flag */
++typedef CK_ULONG CK_FLAGS;
++
++
++/* some special values for certain CK_ULONG variables */
++#define CK_UNAVAILABLE_INFORMATION (~0UL)
++#define CK_EFFECTIVELY_INFINITE 0
++
++
++typedef CK_BYTE CK_PTR CK_BYTE_PTR;
++typedef CK_CHAR CK_PTR CK_CHAR_PTR;
++typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
++typedef CK_ULONG CK_PTR CK_ULONG_PTR;
++typedef void CK_PTR CK_VOID_PTR;
++
++/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
++typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
++
++
++/* The following value is always invalid if used as a session */
++/* handle or object handle */
++#define CK_INVALID_HANDLE 0
++
++
++typedef struct CK_VERSION {
++ CK_BYTE major; /* integer portion of version number */
++ CK_BYTE minor; /* 1/100ths portion of version number */
++} CK_VERSION;
++
++typedef CK_VERSION CK_PTR CK_VERSION_PTR;
++
++
++typedef struct CK_INFO {
++ /* manufacturerID and libraryDecription have been changed from
++ * CK_CHAR to CK_UTF8CHAR for v2.10 */
++ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
++ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
++ CK_FLAGS flags; /* must be zero */
++
++ /* libraryDescription and libraryVersion are new for v2.0 */
++ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
++ CK_VERSION libraryVersion; /* version of library */
++} CK_INFO;
++
++typedef CK_INFO CK_PTR CK_INFO_PTR;
++
++
++/* CK_NOTIFICATION enumerates the types of notifications that
++ * Cryptoki provides to an application */
++/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
++ * for v2.0 */
++typedef CK_ULONG CK_NOTIFICATION;
++#define CKN_SURRENDER 0
++
++/* The following notification is new for PKCS #11 v2.20 amendment 3 */
++#define CKN_OTP_CHANGED 1
++
++
++typedef CK_ULONG CK_SLOT_ID;
++
++typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
++
++
++/* CK_SLOT_INFO provides information about a slot */
++typedef struct CK_SLOT_INFO {
++ /* slotDescription and manufacturerID have been changed from
++ * CK_CHAR to CK_UTF8CHAR for v2.10 */
++ CK_UTF8CHAR slotDescription[64]; /* blank padded */
++ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
++ CK_FLAGS flags;
++
++ /* hardwareVersion and firmwareVersion are new for v2.0 */
++ CK_VERSION hardwareVersion; /* version of hardware */
++ CK_VERSION firmwareVersion; /* version of firmware */
++} CK_SLOT_INFO;
++
++/* flags: bit flags that provide capabilities of the slot
++ * Bit Flag Mask Meaning
++ */
++#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
++#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
++#define CKF_HW_SLOT 0x00000004 /* hardware slot */
++
++typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
++
++
++/* CK_TOKEN_INFO provides information about a token */
++typedef struct CK_TOKEN_INFO {
++ /* label, manufacturerID, and model have been changed from
++ * CK_CHAR to CK_UTF8CHAR for v2.10 */
++ CK_UTF8CHAR label[32]; /* blank padded */
++ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
++ CK_UTF8CHAR model[16]; /* blank padded */
++ CK_CHAR serialNumber[16]; /* blank padded */
++ CK_FLAGS flags; /* see below */
++
++ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
++ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
++ * changed from CK_USHORT to CK_ULONG for v2.0 */
++ CK_ULONG ulMaxSessionCount; /* max open sessions */
++ CK_ULONG ulSessionCount; /* sess. now open */
++ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
++ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
++ CK_ULONG ulMaxPinLen; /* in bytes */
++ CK_ULONG ulMinPinLen; /* in bytes */
++ CK_ULONG ulTotalPublicMemory; /* in bytes */
++ CK_ULONG ulFreePublicMemory; /* in bytes */
++ CK_ULONG ulTotalPrivateMemory; /* in bytes */
++ CK_ULONG ulFreePrivateMemory; /* in bytes */
++
++ /* hardwareVersion, firmwareVersion, and time are new for
++ * v2.0 */
++ CK_VERSION hardwareVersion; /* version of hardware */
++ CK_VERSION firmwareVersion; /* version of firmware */
++ CK_CHAR utcTime[16]; /* time */
++} CK_TOKEN_INFO;
++
++/* The flags parameter is defined as follows:
++ * Bit Flag Mask Meaning
++ */
++#define CKF_RNG 0x00000001 /* has random #
++ * generator */
++#define CKF_WRITE_PROTECTED 0x00000002 /* token is
++ * write-
++ * protected */
++#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
++ * login */
++#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
++ * PIN is set */
++
++/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
++ * that means that *every* time the state of cryptographic
++ * operations of a session is successfully saved, all keys
++ * needed to continue those operations are stored in the state */
++#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
++
++/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
++ * that the token has some sort of clock. The time on that
++ * clock is returned in the token info structure */
++#define CKF_CLOCK_ON_TOKEN 0x00000040
++
++/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
++ * set, that means that there is some way for the user to login
++ * without sending a PIN through the Cryptoki library itself */
++#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
++
++/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
++ * that means that a single session with the token can perform
++ * dual simultaneous cryptographic operations (digest and
++ * encrypt; decrypt and digest; sign and encrypt; and decrypt
++ * and sign) */
++#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
++
++/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
++ * token has been initialized using C_InitializeToken or an
++ * equivalent mechanism outside the scope of PKCS #11.
++ * Calling C_InitializeToken when this flag is set will cause
++ * the token to be reinitialized. */
++#define CKF_TOKEN_INITIALIZED 0x00000400
++
++/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
++ * true, the token supports secondary authentication for
++ * private key objects. This flag is deprecated in v2.11 and
++ onwards. */
++#define CKF_SECONDARY_AUTHENTICATION 0x00000800
++
++/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
++ * incorrect user login PIN has been entered at least once
++ * since the last successful authentication. */
++#define CKF_USER_PIN_COUNT_LOW 0x00010000
++
++/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
++ * supplying an incorrect user PIN will it to become locked. */
++#define CKF_USER_PIN_FINAL_TRY 0x00020000
++
++/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
++ * user PIN has been locked. User login to the token is not
++ * possible. */
++#define CKF_USER_PIN_LOCKED 0x00040000
++
++/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
++ * the user PIN value is the default value set by token
++ * initialization or manufacturing, or the PIN has been
++ * expired by the card. */
++#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
++
++/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
++ * incorrect SO login PIN has been entered at least once since
++ * the last successful authentication. */
++#define CKF_SO_PIN_COUNT_LOW 0x00100000
++
++/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
++ * supplying an incorrect SO PIN will it to become locked. */
++#define CKF_SO_PIN_FINAL_TRY 0x00200000
++
++/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
++ * PIN has been locked. SO login to the token is not possible.
++ */
++#define CKF_SO_PIN_LOCKED 0x00400000
++
++/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
++ * the SO PIN value is the default value set by token
++ * initialization or manufacturing, or the PIN has been
++ * expired by the card. */
++#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
++
++typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
++
++
++/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
++ * identifies a session */
++typedef CK_ULONG CK_SESSION_HANDLE;
++
++typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
++
++
++/* CK_USER_TYPE enumerates the types of Cryptoki users */
++/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
++ * v2.0 */
++typedef CK_ULONG CK_USER_TYPE;
++/* Security Officer */
++#define CKU_SO 0
++/* Normal user */
++#define CKU_USER 1
++/* Context specific (added in v2.20) */
++#define CKU_CONTEXT_SPECIFIC 2
++
++/* CK_STATE enumerates the session states */
++/* CK_STATE has been changed from an enum to a CK_ULONG for
++ * v2.0 */
++typedef CK_ULONG CK_STATE;
++#define CKS_RO_PUBLIC_SESSION 0
++#define CKS_RO_USER_FUNCTIONS 1
++#define CKS_RW_PUBLIC_SESSION 2
++#define CKS_RW_USER_FUNCTIONS 3
++#define CKS_RW_SO_FUNCTIONS 4
++
++
++/* CK_SESSION_INFO provides information about a session */
++typedef struct CK_SESSION_INFO {
++ CK_SLOT_ID slotID;
++ CK_STATE state;
++ CK_FLAGS flags; /* see below */
++
++ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++ CK_ULONG ulDeviceError; /* device-dependent error code */
++} CK_SESSION_INFO;
++
++/* The flags are defined in the following table:
++ * Bit Flag Mask Meaning
++ */
++#define CKF_RW_SESSION 0x00000002 /* session is r/w */
++#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
++
++typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
++
++
++/* CK_OBJECT_HANDLE is a token-specific identifier for an
++ * object */
++typedef CK_ULONG CK_OBJECT_HANDLE;
++
++typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
++
++
++/* CK_OBJECT_CLASS is a value that identifies the classes (or
++ * types) of objects that Cryptoki recognizes. It is defined
++ * as follows: */
++/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++typedef CK_ULONG CK_OBJECT_CLASS;
++
++/* The following classes of objects are defined: */
++/* CKO_HW_FEATURE is new for v2.10 */
++/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
++/* CKO_MECHANISM is new for v2.20 */
++#define CKO_DATA 0x00000000
++#define CKO_CERTIFICATE 0x00000001
++#define CKO_PUBLIC_KEY 0x00000002
++#define CKO_PRIVATE_KEY 0x00000003
++#define CKO_SECRET_KEY 0x00000004
++#define CKO_HW_FEATURE 0x00000005
++#define CKO_DOMAIN_PARAMETERS 0x00000006
++#define CKO_MECHANISM 0x00000007
++
++/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
++#define CKO_OTP_KEY 0x00000008
++
++#define CKO_VENDOR_DEFINED 0x80000000
++
++typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
++
++/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
++ * value that identifies the hardware feature type of an object
++ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
++typedef CK_ULONG CK_HW_FEATURE_TYPE;
++
++/* The following hardware feature types are defined */
++/* CKH_USER_INTERFACE is new for v2.20 */
++#define CKH_MONOTONIC_COUNTER 0x00000001
++#define CKH_CLOCK 0x00000002
++#define CKH_USER_INTERFACE 0x00000003
++#define CKH_VENDOR_DEFINED 0x80000000
++
++/* CK_KEY_TYPE is a value that identifies a key type */
++/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
++typedef CK_ULONG CK_KEY_TYPE;
++
++/* the following key types are defined: */
++#define CKK_RSA 0x00000000
++#define CKK_DSA 0x00000001
++#define CKK_DH 0x00000002
++
++/* CKK_ECDSA and CKK_KEA are new for v2.0 */
++/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
++#define CKK_ECDSA 0x00000003
++#define CKK_EC 0x00000003
++#define CKK_X9_42_DH 0x00000004
++#define CKK_KEA 0x00000005
++
++#define CKK_GENERIC_SECRET 0x00000010
++#define CKK_RC2 0x00000011
++#define CKK_RC4 0x00000012
++#define CKK_DES 0x00000013
++#define CKK_DES2 0x00000014
++#define CKK_DES3 0x00000015
++
++/* all these key types are new for v2.0 */
++#define CKK_CAST 0x00000016
++#define CKK_CAST3 0x00000017
++/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
++#define CKK_CAST5 0x00000018
++#define CKK_CAST128 0x00000018
++#define CKK_RC5 0x00000019
++#define CKK_IDEA 0x0000001A
++#define CKK_SKIPJACK 0x0000001B
++#define CKK_BATON 0x0000001C
++#define CKK_JUNIPER 0x0000001D
++#define CKK_CDMF 0x0000001E
++#define CKK_AES 0x0000001F
++
++/* BlowFish and TwoFish are new for v2.20 */
++#define CKK_BLOWFISH 0x00000020
++#define CKK_TWOFISH 0x00000021
++
++/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
++#define CKK_SECURID 0x00000022
++#define CKK_HOTP 0x00000023
++#define CKK_ACTI 0x00000024
++
++/* Camellia is new for PKCS #11 v2.20 amendment 3 */
++#define CKK_CAMELLIA 0x00000025
++/* ARIA is new for PKCS #11 v2.20 amendment 3 */
++#define CKK_ARIA 0x00000026
++
++
++#define CKK_VENDOR_DEFINED 0x80000000
++
++
++/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
++ * type */
++/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
++ * for v2.0 */
++typedef CK_ULONG CK_CERTIFICATE_TYPE;
++
++/* The following certificate types are defined: */
++/* CKC_X_509_ATTR_CERT is new for v2.10 */
++/* CKC_WTLS is new for v2.20 */
++#define CKC_X_509 0x00000000
++#define CKC_X_509_ATTR_CERT 0x00000001
++#define CKC_WTLS 0x00000002
++#define CKC_VENDOR_DEFINED 0x80000000
++
++
++/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
++ * type */
++/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++typedef CK_ULONG CK_ATTRIBUTE_TYPE;
++
++/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
++ consists of an array of values. */
++#define CKF_ARRAY_ATTRIBUTE 0x40000000
++
++/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
++ and relates to the CKA_OTP_FORMAT attribute */
++#define CK_OTP_FORMAT_DECIMAL 0
++#define CK_OTP_FORMAT_HEXADECIMAL 1
++#define CK_OTP_FORMAT_ALPHANUMERIC 2
++#define CK_OTP_FORMAT_BINARY 3
++
++/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
++ and relates to the CKA_OTP_..._REQUIREMENT attributes */
++#define CK_OTP_PARAM_IGNORED 0
++#define CK_OTP_PARAM_OPTIONAL 1
++#define CK_OTP_PARAM_MANDATORY 2
++
++/* The following attribute types are defined: */
++#define CKA_CLASS 0x00000000
++#define CKA_TOKEN 0x00000001
++#define CKA_PRIVATE 0x00000002
++#define CKA_LABEL 0x00000003
++#define CKA_APPLICATION 0x00000010
++#define CKA_VALUE 0x00000011
++
++/* CKA_OBJECT_ID is new for v2.10 */
++#define CKA_OBJECT_ID 0x00000012
++
++#define CKA_CERTIFICATE_TYPE 0x00000080
++#define CKA_ISSUER 0x00000081
++#define CKA_SERIAL_NUMBER 0x00000082
++
++/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
++ * for v2.10 */
++#define CKA_AC_ISSUER 0x00000083
++#define CKA_OWNER 0x00000084
++#define CKA_ATTR_TYPES 0x00000085
++
++/* CKA_TRUSTED is new for v2.11 */
++#define CKA_TRUSTED 0x00000086
++
++/* CKA_CERTIFICATE_CATEGORY ...
++ * CKA_CHECK_VALUE are new for v2.20 */
++#define CKA_CERTIFICATE_CATEGORY 0x00000087
++#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
++#define CKA_URL 0x00000089
++#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
++#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
++#define CKA_CHECK_VALUE 0x00000090
++
++#define CKA_KEY_TYPE 0x00000100
++#define CKA_SUBJECT 0x00000101
++#define CKA_ID 0x00000102
++#define CKA_SENSITIVE 0x00000103
++#define CKA_ENCRYPT 0x00000104
++#define CKA_DECRYPT 0x00000105
++#define CKA_WRAP 0x00000106
++#define CKA_UNWRAP 0x00000107
++#define CKA_SIGN 0x00000108
++#define CKA_SIGN_RECOVER 0x00000109
++#define CKA_VERIFY 0x0000010A
++#define CKA_VERIFY_RECOVER 0x0000010B
++#define CKA_DERIVE 0x0000010C
++#define CKA_START_DATE 0x00000110
++#define CKA_END_DATE 0x00000111
++#define CKA_MODULUS 0x00000120
++#define CKA_MODULUS_BITS 0x00000121
++#define CKA_PUBLIC_EXPONENT 0x00000122
++#define CKA_PRIVATE_EXPONENT 0x00000123
++#define CKA_PRIME_1 0x00000124
++#define CKA_PRIME_2 0x00000125
++#define CKA_EXPONENT_1 0x00000126
++#define CKA_EXPONENT_2 0x00000127
++#define CKA_COEFFICIENT 0x00000128
++#define CKA_PRIME 0x00000130
++#define CKA_SUBPRIME 0x00000131
++#define CKA_BASE 0x00000132
++
++/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
++#define CKA_PRIME_BITS 0x00000133
++#define CKA_SUBPRIME_BITS 0x00000134
++#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
++/* (To retain backwards-compatibility) */
++
++#define CKA_VALUE_BITS 0x00000160
++#define CKA_VALUE_LEN 0x00000161
++
++/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
++ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
++ * and CKA_EC_POINT are new for v2.0 */
++#define CKA_EXTRACTABLE 0x00000162
++#define CKA_LOCAL 0x00000163
++#define CKA_NEVER_EXTRACTABLE 0x00000164
++#define CKA_ALWAYS_SENSITIVE 0x00000165
++
++/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
++#define CKA_KEY_GEN_MECHANISM 0x00000166
++
++#define CKA_MODIFIABLE 0x00000170
++
++/* CKA_ECDSA_PARAMS is deprecated in v2.11,
++ * CKA_EC_PARAMS is preferred. */
++#define CKA_ECDSA_PARAMS 0x00000180
++#define CKA_EC_PARAMS 0x00000180
++
++#define CKA_EC_POINT 0x00000181
++
++/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
++ * are new for v2.10. Deprecated in v2.11 and onwards. */
++#define CKA_SECONDARY_AUTH 0x00000200
++#define CKA_AUTH_PIN_FLAGS 0x00000201
++
++/* CKA_ALWAYS_AUTHENTICATE ...
++ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
++#define CKA_ALWAYS_AUTHENTICATE 0x00000202
++
++#define CKA_WRAP_WITH_TRUSTED 0x00000210
++#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
++#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
++
++/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
++#define CKA_OTP_FORMAT 0x00000220
++#define CKA_OTP_LENGTH 0x00000221
++#define CKA_OTP_TIME_INTERVAL 0x00000222
++#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223
++#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
++#define CKA_OTP_TIME_REQUIREMENT 0x00000225
++#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226
++#define CKA_OTP_PIN_REQUIREMENT 0x00000227
++#define CKA_OTP_COUNTER 0x0000022E
++#define CKA_OTP_TIME 0x0000022F
++#define CKA_OTP_USER_IDENTIFIER 0x0000022A
++#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022B
++#define CKA_OTP_SERVICE_LOGO 0x0000022C
++#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022D
++
++
++/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
++ * are new for v2.10 */
++#define CKA_HW_FEATURE_TYPE 0x00000300
++#define CKA_RESET_ON_INIT 0x00000301
++#define CKA_HAS_RESET 0x00000302
++
++/* The following attributes are new for v2.20 */
++#define CKA_PIXEL_X 0x00000400
++#define CKA_PIXEL_Y 0x00000401
++#define CKA_RESOLUTION 0x00000402
++#define CKA_CHAR_ROWS 0x00000403
++#define CKA_CHAR_COLUMNS 0x00000404
++#define CKA_COLOR 0x00000405
++#define CKA_BITS_PER_PIXEL 0x00000406
++#define CKA_CHAR_SETS 0x00000480
++#define CKA_ENCODING_METHODS 0x00000481
++#define CKA_MIME_TYPES 0x00000482
++#define CKA_MECHANISM_TYPE 0x00000500
++#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
++#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
++#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
++#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
++
++#define CKA_VENDOR_DEFINED 0x80000000
++
++/* CK_ATTRIBUTE is a structure that includes the type, length
++ * and value of an attribute */
++typedef struct CK_ATTRIBUTE {
++ CK_ATTRIBUTE_TYPE type;
++ CK_VOID_PTR pValue;
++
++ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
++ CK_ULONG ulValueLen; /* in bytes */
++} CK_ATTRIBUTE;
++
++typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
++
++
++/* CK_DATE is a structure that defines a date */
++typedef struct CK_DATE{
++ CK_CHAR year[4]; /* the year ("1900" - "9999") */
++ CK_CHAR month[2]; /* the month ("01" - "12") */
++ CK_CHAR day[2]; /* the day ("01" - "31") */
++} CK_DATE;
++
++
++/* CK_MECHANISM_TYPE is a value that identifies a mechanism
++ * type */
++/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++typedef CK_ULONG CK_MECHANISM_TYPE;
++
++/* the following mechanism types are defined: */
++#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
++#define CKM_RSA_PKCS 0x00000001
++#define CKM_RSA_9796 0x00000002
++#define CKM_RSA_X_509 0x00000003
++
++/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
++ * are new for v2.0. They are mechanisms which hash and sign */
++#define CKM_MD2_RSA_PKCS 0x00000004
++#define CKM_MD5_RSA_PKCS 0x00000005
++#define CKM_SHA1_RSA_PKCS 0x00000006
++
++/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
++ * CKM_RSA_PKCS_OAEP are new for v2.10 */
++#define CKM_RIPEMD128_RSA_PKCS 0x00000007
++#define CKM_RIPEMD160_RSA_PKCS 0x00000008
++#define CKM_RSA_PKCS_OAEP 0x00000009
++
++/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
++ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
++#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
++#define CKM_RSA_X9_31 0x0000000B
++#define CKM_SHA1_RSA_X9_31 0x0000000C
++#define CKM_RSA_PKCS_PSS 0x0000000D
++#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
++
++#define CKM_DSA_KEY_PAIR_GEN 0x00000010
++#define CKM_DSA 0x00000011
++#define CKM_DSA_SHA1 0x00000012
++#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
++#define CKM_DH_PKCS_DERIVE 0x00000021
++
++/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
++ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
++ * v2.11 */
++#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
++#define CKM_X9_42_DH_DERIVE 0x00000031
++#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
++#define CKM_X9_42_MQV_DERIVE 0x00000033
++
++/* CKM_SHA256/384/512 are new for v2.20 */
++#define CKM_SHA256_RSA_PKCS 0x00000040
++#define CKM_SHA384_RSA_PKCS 0x00000041
++#define CKM_SHA512_RSA_PKCS 0x00000042
++#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
++#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
++#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
++
++/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
++#define CKM_SHA224_RSA_PKCS 0x00000046
++#define CKM_SHA224_RSA_PKCS_PSS 0x00000047
++
++#define CKM_RC2_KEY_GEN 0x00000100
++#define CKM_RC2_ECB 0x00000101
++#define CKM_RC2_CBC 0x00000102
++#define CKM_RC2_MAC 0x00000103
++
++/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
++#define CKM_RC2_MAC_GENERAL 0x00000104
++#define CKM_RC2_CBC_PAD 0x00000105
++
++#define CKM_RC4_KEY_GEN 0x00000110
++#define CKM_RC4 0x00000111
++#define CKM_DES_KEY_GEN 0x00000120
++#define CKM_DES_ECB 0x00000121
++#define CKM_DES_CBC 0x00000122
++#define CKM_DES_MAC 0x00000123
++
++/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
++#define CKM_DES_MAC_GENERAL 0x00000124
++#define CKM_DES_CBC_PAD 0x00000125
++
++#define CKM_DES2_KEY_GEN 0x00000130
++#define CKM_DES3_KEY_GEN 0x00000131
++#define CKM_DES3_ECB 0x00000132
++#define CKM_DES3_CBC 0x00000133
++#define CKM_DES3_MAC 0x00000134
++
++/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
++ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
++ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
++#define CKM_DES3_MAC_GENERAL 0x00000135
++#define CKM_DES3_CBC_PAD 0x00000136
++#define CKM_CDMF_KEY_GEN 0x00000140
++#define CKM_CDMF_ECB 0x00000141
++#define CKM_CDMF_CBC 0x00000142
++#define CKM_CDMF_MAC 0x00000143
++#define CKM_CDMF_MAC_GENERAL 0x00000144
++#define CKM_CDMF_CBC_PAD 0x00000145
++
++/* the following four DES mechanisms are new for v2.20 */
++#define CKM_DES_OFB64 0x00000150
++#define CKM_DES_OFB8 0x00000151
++#define CKM_DES_CFB64 0x00000152
++#define CKM_DES_CFB8 0x00000153
++
++#define CKM_MD2 0x00000200
++
++/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
++#define CKM_MD2_HMAC 0x00000201
++#define CKM_MD2_HMAC_GENERAL 0x00000202
++
++#define CKM_MD5 0x00000210
++
++/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
++#define CKM_MD5_HMAC 0x00000211
++#define CKM_MD5_HMAC_GENERAL 0x00000212
++
++#define CKM_SHA_1 0x00000220
++
++/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
++#define CKM_SHA_1_HMAC 0x00000221
++#define CKM_SHA_1_HMAC_GENERAL 0x00000222
++
++/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
++ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
++ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
++#define CKM_RIPEMD128 0x00000230
++#define CKM_RIPEMD128_HMAC 0x00000231
++#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
++#define CKM_RIPEMD160 0x00000240
++#define CKM_RIPEMD160_HMAC 0x00000241
++#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
++
++/* CKM_SHA256/384/512 are new for v2.20 */
++#define CKM_SHA256 0x00000250
++#define CKM_SHA256_HMAC 0x00000251
++#define CKM_SHA256_HMAC_GENERAL 0x00000252
++
++/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
++#define CKM_SHA224 0x00000255
++#define CKM_SHA224_HMAC 0x00000256
++#define CKM_SHA224_HMAC_GENERAL 0x00000257
++
++#define CKM_SHA384 0x00000260
++#define CKM_SHA384_HMAC 0x00000261
++#define CKM_SHA384_HMAC_GENERAL 0x00000262
++#define CKM_SHA512 0x00000270
++#define CKM_SHA512_HMAC 0x00000271
++#define CKM_SHA512_HMAC_GENERAL 0x00000272
++
++/* SecurID is new for PKCS #11 v2.20 amendment 1 */
++#define CKM_SECURID_KEY_GEN 0x00000280
++#define CKM_SECURID 0x00000282
++
++/* HOTP is new for PKCS #11 v2.20 amendment 1 */
++#define CKM_HOTP_KEY_GEN 0x00000290
++#define CKM_HOTP 0x00000291
++
++/* ACTI is new for PKCS #11 v2.20 amendment 1 */
++#define CKM_ACTI 0x000002A0
++#define CKM_ACTI_KEY_GEN 0x000002A1
++
++/* All of the following mechanisms are new for v2.0 */
++/* Note that CAST128 and CAST5 are the same algorithm */
++#define CKM_CAST_KEY_GEN 0x00000300
++#define CKM_CAST_ECB 0x00000301
++#define CKM_CAST_CBC 0x00000302
++#define CKM_CAST_MAC 0x00000303
++#define CKM_CAST_MAC_GENERAL 0x00000304
++#define CKM_CAST_CBC_PAD 0x00000305
++#define CKM_CAST3_KEY_GEN 0x00000310
++#define CKM_CAST3_ECB 0x00000311
++#define CKM_CAST3_CBC 0x00000312
++#define CKM_CAST3_MAC 0x00000313
++#define CKM_CAST3_MAC_GENERAL 0x00000314
++#define CKM_CAST3_CBC_PAD 0x00000315
++#define CKM_CAST5_KEY_GEN 0x00000320
++#define CKM_CAST128_KEY_GEN 0x00000320
++#define CKM_CAST5_ECB 0x00000321
++#define CKM_CAST128_ECB 0x00000321
++#define CKM_CAST5_CBC 0x00000322
++#define CKM_CAST128_CBC 0x00000322
++#define CKM_CAST5_MAC 0x00000323
++#define CKM_CAST128_MAC 0x00000323
++#define CKM_CAST5_MAC_GENERAL 0x00000324
++#define CKM_CAST128_MAC_GENERAL 0x00000324
++#define CKM_CAST5_CBC_PAD 0x00000325
++#define CKM_CAST128_CBC_PAD 0x00000325
++#define CKM_RC5_KEY_GEN 0x00000330
++#define CKM_RC5_ECB 0x00000331
++#define CKM_RC5_CBC 0x00000332
++#define CKM_RC5_MAC 0x00000333
++#define CKM_RC5_MAC_GENERAL 0x00000334
++#define CKM_RC5_CBC_PAD 0x00000335
++#define CKM_IDEA_KEY_GEN 0x00000340
++#define CKM_IDEA_ECB 0x00000341
++#define CKM_IDEA_CBC 0x00000342
++#define CKM_IDEA_MAC 0x00000343
++#define CKM_IDEA_MAC_GENERAL 0x00000344
++#define CKM_IDEA_CBC_PAD 0x00000345
++#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
++#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
++#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
++#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
++#define CKM_XOR_BASE_AND_DATA 0x00000364
++#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
++#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
++#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
++#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
++
++/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
++ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
++ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
++#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
++#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
++#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
++#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
++#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
++
++/* CKM_TLS_PRF is new for v2.20 */
++#define CKM_TLS_PRF 0x00000378
++
++#define CKM_SSL3_MD5_MAC 0x00000380
++#define CKM_SSL3_SHA1_MAC 0x00000381
++#define CKM_MD5_KEY_DERIVATION 0x00000390
++#define CKM_MD2_KEY_DERIVATION 0x00000391
++#define CKM_SHA1_KEY_DERIVATION 0x00000392
++
++/* CKM_SHA256/384/512 are new for v2.20 */
++#define CKM_SHA256_KEY_DERIVATION 0x00000393
++#define CKM_SHA384_KEY_DERIVATION 0x00000394
++#define CKM_SHA512_KEY_DERIVATION 0x00000395
++
++/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
++#define CKM_SHA224_KEY_DERIVATION 0x00000396
++
++#define CKM_PBE_MD2_DES_CBC 0x000003A0
++#define CKM_PBE_MD5_DES_CBC 0x000003A1
++#define CKM_PBE_MD5_CAST_CBC 0x000003A2
++#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
++#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
++#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
++#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
++#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
++#define CKM_PBE_SHA1_RC4_128 0x000003A6
++#define CKM_PBE_SHA1_RC4_40 0x000003A7
++#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
++#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
++#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
++#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
++
++/* CKM_PKCS5_PBKD2 is new for v2.10 */
++#define CKM_PKCS5_PBKD2 0x000003B0
++
++#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
++
++/* WTLS mechanisms are new for v2.20 */
++#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
++#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
++#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
++#define CKM_WTLS_PRF 0x000003D3
++#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
++#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
++
++#define CKM_KEY_WRAP_LYNKS 0x00000400
++#define CKM_KEY_WRAP_SET_OAEP 0x00000401
++
++/* CKM_CMS_SIG is new for v2.20 */
++#define CKM_CMS_SIG 0x00000500
++
++/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
++#define CKM_KIP_DERIVE 0x00000510
++#define CKM_KIP_WRAP 0x00000511
++#define CKM_KIP_MAC 0x00000512
++
++/* Camellia is new for PKCS #11 v2.20 amendment 3 */
++#define CKM_CAMELLIA_KEY_GEN 0x00000550
++#define CKM_CAMELLIA_ECB 0x00000551
++#define CKM_CAMELLIA_CBC 0x00000552
++#define CKM_CAMELLIA_MAC 0x00000553
++#define CKM_CAMELLIA_MAC_GENERAL 0x00000554
++#define CKM_CAMELLIA_CBC_PAD 0x00000555
++#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556
++#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557
++#define CKM_CAMELLIA_CTR 0x00000558
++
++/* ARIA is new for PKCS #11 v2.20 amendment 3 */
++#define CKM_ARIA_KEY_GEN 0x00000560
++#define CKM_ARIA_ECB 0x00000561
++#define CKM_ARIA_CBC 0x00000562
++#define CKM_ARIA_MAC 0x00000563
++#define CKM_ARIA_MAC_GENERAL 0x00000564
++#define CKM_ARIA_CBC_PAD 0x00000565
++#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566
++#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567
++
++/* Fortezza mechanisms */
++#define CKM_SKIPJACK_KEY_GEN 0x00001000
++#define CKM_SKIPJACK_ECB64 0x00001001
++#define CKM_SKIPJACK_CBC64 0x00001002
++#define CKM_SKIPJACK_OFB64 0x00001003
++#define CKM_SKIPJACK_CFB64 0x00001004
++#define CKM_SKIPJACK_CFB32 0x00001005
++#define CKM_SKIPJACK_CFB16 0x00001006
++#define CKM_SKIPJACK_CFB8 0x00001007
++#define CKM_SKIPJACK_WRAP 0x00001008
++#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
++#define CKM_SKIPJACK_RELAYX 0x0000100a
++#define CKM_KEA_KEY_PAIR_GEN 0x00001010
++#define CKM_KEA_KEY_DERIVE 0x00001011
++#define CKM_FORTEZZA_TIMESTAMP 0x00001020
++#define CKM_BATON_KEY_GEN 0x00001030
++#define CKM_BATON_ECB128 0x00001031
++#define CKM_BATON_ECB96 0x00001032
++#define CKM_BATON_CBC128 0x00001033
++#define CKM_BATON_COUNTER 0x00001034
++#define CKM_BATON_SHUFFLE 0x00001035
++#define CKM_BATON_WRAP 0x00001036
++
++/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
++ * CKM_EC_KEY_PAIR_GEN is preferred */
++#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
++#define CKM_EC_KEY_PAIR_GEN 0x00001040
++
++#define CKM_ECDSA 0x00001041
++#define CKM_ECDSA_SHA1 0x00001042
++
++/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
++ * are new for v2.11 */
++#define CKM_ECDH1_DERIVE 0x00001050
++#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
++#define CKM_ECMQV_DERIVE 0x00001052
++
++#define CKM_JUNIPER_KEY_GEN 0x00001060
++#define CKM_JUNIPER_ECB128 0x00001061
++#define CKM_JUNIPER_CBC128 0x00001062
++#define CKM_JUNIPER_COUNTER 0x00001063
++#define CKM_JUNIPER_SHUFFLE 0x00001064
++#define CKM_JUNIPER_WRAP 0x00001065
++#define CKM_FASTHASH 0x00001070
++
++/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
++ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
++ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
++ * new for v2.11 */
++#define CKM_AES_KEY_GEN 0x00001080
++#define CKM_AES_ECB 0x00001081
++#define CKM_AES_CBC 0x00001082
++#define CKM_AES_MAC 0x00001083
++#define CKM_AES_MAC_GENERAL 0x00001084
++#define CKM_AES_CBC_PAD 0x00001085
++
++/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
++#define CKM_AES_CTR 0x00001086
++
++/* BlowFish and TwoFish are new for v2.20 */
++#define CKM_BLOWFISH_KEY_GEN 0x00001090
++#define CKM_BLOWFISH_CBC 0x00001091
++#define CKM_TWOFISH_KEY_GEN 0x00001092
++#define CKM_TWOFISH_CBC 0x00001093
++
++
++/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
++#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
++#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
++#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
++#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
++#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
++#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
++
++#define CKM_DSA_PARAMETER_GEN 0x00002000
++#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
++#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
++
++#define CKM_VENDOR_DEFINED 0x80000000
++
++typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
++
++
++/* CK_MECHANISM is a structure that specifies a particular
++ * mechanism */
++typedef struct CK_MECHANISM {
++ CK_MECHANISM_TYPE mechanism;
++ CK_VOID_PTR pParameter;
++
++ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++ CK_ULONG ulParameterLen; /* in bytes */
++} CK_MECHANISM;
++
++typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
++
++
++/* CK_MECHANISM_INFO provides information about a particular
++ * mechanism */
++typedef struct CK_MECHANISM_INFO {
++ CK_ULONG ulMinKeySize;
++ CK_ULONG ulMaxKeySize;
++ CK_FLAGS flags;
++} CK_MECHANISM_INFO;
++
++/* The flags are defined as follows:
++ * Bit Flag Mask Meaning */
++#define CKF_HW 0x00000001 /* performed by HW */
++
++/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
++ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
++ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
++ * and CKF_DERIVE are new for v2.0. They specify whether or not
++ * a mechanism can be used for a particular task */
++#define CKF_ENCRYPT 0x00000100
++#define CKF_DECRYPT 0x00000200
++#define CKF_DIGEST 0x00000400
++#define CKF_SIGN 0x00000800
++#define CKF_SIGN_RECOVER 0x00001000
++#define CKF_VERIFY 0x00002000
++#define CKF_VERIFY_RECOVER 0x00004000
++#define CKF_GENERATE 0x00008000
++#define CKF_GENERATE_KEY_PAIR 0x00010000
++#define CKF_WRAP 0x00020000
++#define CKF_UNWRAP 0x00040000
++#define CKF_DERIVE 0x00080000
++
++/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
++ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
++ * describe a token's EC capabilities not available in mechanism
++ * information. */
++#define CKF_EC_F_P 0x00100000
++#define CKF_EC_F_2M 0x00200000
++#define CKF_EC_ECPARAMETERS 0x00400000
++#define CKF_EC_NAMEDCURVE 0x00800000
++#define CKF_EC_UNCOMPRESS 0x01000000
++#define CKF_EC_COMPRESS 0x02000000
++
++#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
++
++typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
++
++
++/* CK_RV is a value that identifies the return value of a
++ * Cryptoki function */
++/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
++typedef CK_ULONG CK_RV;
++
++#define CKR_OK 0x00000000
++#define CKR_CANCEL 0x00000001
++#define CKR_HOST_MEMORY 0x00000002
++#define CKR_SLOT_ID_INVALID 0x00000003
++
++/* CKR_FLAGS_INVALID was removed for v2.0 */
++
++/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
++#define CKR_GENERAL_ERROR 0x00000005
++#define CKR_FUNCTION_FAILED 0x00000006
++
++/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
++ * and CKR_CANT_LOCK are new for v2.01 */
++#define CKR_ARGUMENTS_BAD 0x00000007
++#define CKR_NO_EVENT 0x00000008
++#define CKR_NEED_TO_CREATE_THREADS 0x00000009
++#define CKR_CANT_LOCK 0x0000000A
++
++#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
++#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
++#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
++#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
++#define CKR_DATA_INVALID 0x00000020
++#define CKR_DATA_LEN_RANGE 0x00000021
++#define CKR_DEVICE_ERROR 0x00000030
++#define CKR_DEVICE_MEMORY 0x00000031
++#define CKR_DEVICE_REMOVED 0x00000032
++#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
++#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
++#define CKR_FUNCTION_CANCELED 0x00000050
++#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
++
++/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
++#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
++
++#define CKR_KEY_HANDLE_INVALID 0x00000060
++
++/* CKR_KEY_SENSITIVE was removed for v2.0 */
++
++#define CKR_KEY_SIZE_RANGE 0x00000062
++#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
++
++/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
++ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
++ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
++ * v2.0 */
++#define CKR_KEY_NOT_NEEDED 0x00000064
++#define CKR_KEY_CHANGED 0x00000065
++#define CKR_KEY_NEEDED 0x00000066
++#define CKR_KEY_INDIGESTIBLE 0x00000067
++#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
++#define CKR_KEY_NOT_WRAPPABLE 0x00000069
++#define CKR_KEY_UNEXTRACTABLE 0x0000006A
++
++#define CKR_MECHANISM_INVALID 0x00000070
++#define CKR_MECHANISM_PARAM_INVALID 0x00000071
++
++/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
++ * were removed for v2.0 */
++#define CKR_OBJECT_HANDLE_INVALID 0x00000082
++#define CKR_OPERATION_ACTIVE 0x00000090
++#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
++#define CKR_PIN_INCORRECT 0x000000A0
++#define CKR_PIN_INVALID 0x000000A1
++#define CKR_PIN_LEN_RANGE 0x000000A2
++
++/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
++#define CKR_PIN_EXPIRED 0x000000A3
++#define CKR_PIN_LOCKED 0x000000A4
++
++#define CKR_SESSION_CLOSED 0x000000B0
++#define CKR_SESSION_COUNT 0x000000B1
++#define CKR_SESSION_HANDLE_INVALID 0x000000B3
++#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
++#define CKR_SESSION_READ_ONLY 0x000000B5
++#define CKR_SESSION_EXISTS 0x000000B6
++
++/* CKR_SESSION_READ_ONLY_EXISTS and
++ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
++#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
++#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
++
++#define CKR_SIGNATURE_INVALID 0x000000C0
++#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
++#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
++#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
++#define CKR_TOKEN_NOT_PRESENT 0x000000E0
++#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
++#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
++#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
++#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
++#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
++#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
++#define CKR_USER_NOT_LOGGED_IN 0x00000101
++#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
++#define CKR_USER_TYPE_INVALID 0x00000103
++
++/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
++ * are new to v2.01 */
++#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
++#define CKR_USER_TOO_MANY_TYPES 0x00000105
++
++#define CKR_WRAPPED_KEY_INVALID 0x00000110
++#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
++#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
++#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
++#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
++#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
++
++/* These are new to v2.0 */
++#define CKR_RANDOM_NO_RNG 0x00000121
++
++/* These are new to v2.11 */
++#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
++
++/* These are new to v2.0 */
++#define CKR_BUFFER_TOO_SMALL 0x00000150
++#define CKR_SAVED_STATE_INVALID 0x00000160
++#define CKR_INFORMATION_SENSITIVE 0x00000170
++#define CKR_STATE_UNSAVEABLE 0x00000180
++
++/* These are new to v2.01 */
++#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
++#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
++#define CKR_MUTEX_BAD 0x000001A0
++#define CKR_MUTEX_NOT_LOCKED 0x000001A1
++
++/* The following return values are new for PKCS #11 v2.20 amendment 3 */
++#define CKR_NEW_PIN_MODE 0x000001B0
++#define CKR_NEXT_OTP 0x000001B1
++
++/* This is new to v2.20 */
++#define CKR_FUNCTION_REJECTED 0x00000200
++
++#define CKR_VENDOR_DEFINED 0x80000000
++
++
++/* CK_NOTIFY is an application callback that processes events */
++typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_NOTIFICATION event,
++ CK_VOID_PTR pApplication /* passed to C_OpenSession */
++);
++
++
++/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
++ * version and pointers of appropriate types to all the
++ * Cryptoki functions */
++/* CK_FUNCTION_LIST is new for v2.0 */
++typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
++
++typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
++
++typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
++
++
++/* CK_CREATEMUTEX is an application callback for creating a
++ * mutex object */
++typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
++ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
++);
++
++
++/* CK_DESTROYMUTEX is an application callback for destroying a
++ * mutex object */
++typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
++ CK_VOID_PTR pMutex /* pointer to mutex */
++);
++
++
++/* CK_LOCKMUTEX is an application callback for locking a mutex */
++typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
++ CK_VOID_PTR pMutex /* pointer to mutex */
++);
++
++
++/* CK_UNLOCKMUTEX is an application callback for unlocking a
++ * mutex */
++typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
++ CK_VOID_PTR pMutex /* pointer to mutex */
++);
++
++
++/* CK_C_INITIALIZE_ARGS provides the optional arguments to
++ * C_Initialize */
++typedef struct CK_C_INITIALIZE_ARGS {
++ CK_CREATEMUTEX CreateMutex;
++ CK_DESTROYMUTEX DestroyMutex;
++ CK_LOCKMUTEX LockMutex;
++ CK_UNLOCKMUTEX UnlockMutex;
++ CK_FLAGS flags;
++ CK_VOID_PTR pReserved;
++} CK_C_INITIALIZE_ARGS;
++
++/* flags: bit flags that provide capabilities of the slot
++ * Bit Flag Mask Meaning
++ */
++#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
++#define CKF_OS_LOCKING_OK 0x00000002
++
++typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
++
++
++/* additional flags for parameters to functions */
++
++/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
++#define CKF_DONT_BLOCK 1
++
++/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
++ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
++ * Generation Function (MGF) applied to a message block when
++ * formatting a message block for the PKCS #1 OAEP encryption
++ * scheme. */
++typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
++
++typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
++
++/* The following MGFs are defined */
++/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
++ * are new for v2.20 */
++#define CKG_MGF1_SHA1 0x00000001
++#define CKG_MGF1_SHA256 0x00000002
++#define CKG_MGF1_SHA384 0x00000003
++#define CKG_MGF1_SHA512 0x00000004
++/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
++#define CKG_MGF1_SHA224 0x00000005
++
++/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
++ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
++ * of the encoding parameter when formatting a message block
++ * for the PKCS #1 OAEP encryption scheme. */
++typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
++
++typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
++
++/* The following encoding parameter sources are defined */
++#define CKZ_DATA_SPECIFIED 0x00000001
++
++/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
++ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
++ * CKM_RSA_PKCS_OAEP mechanism. */
++typedef struct CK_RSA_PKCS_OAEP_PARAMS {
++ CK_MECHANISM_TYPE hashAlg;
++ CK_RSA_PKCS_MGF_TYPE mgf;
++ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
++ CK_VOID_PTR pSourceData;
++ CK_ULONG ulSourceDataLen;
++} CK_RSA_PKCS_OAEP_PARAMS;
++
++typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
++
++/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
++ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
++ * CKM_RSA_PKCS_PSS mechanism(s). */
++typedef struct CK_RSA_PKCS_PSS_PARAMS {
++ CK_MECHANISM_TYPE hashAlg;
++ CK_RSA_PKCS_MGF_TYPE mgf;
++ CK_ULONG sLen;
++} CK_RSA_PKCS_PSS_PARAMS;
++
++typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
++
++/* CK_EC_KDF_TYPE is new for v2.11. */
++typedef CK_ULONG CK_EC_KDF_TYPE;
++
++/* The following EC Key Derivation Functions are defined */
++#define CKD_NULL 0x00000001
++#define CKD_SHA1_KDF 0x00000002
++
++/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
++ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
++ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
++ * where each party contributes one key pair.
++ */
++typedef struct CK_ECDH1_DERIVE_PARAMS {
++ CK_EC_KDF_TYPE kdf;
++ CK_ULONG ulSharedDataLen;
++ CK_BYTE_PTR pSharedData;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++} CK_ECDH1_DERIVE_PARAMS;
++
++typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
++
++
++/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
++ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
++ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
++typedef struct CK_ECDH2_DERIVE_PARAMS {
++ CK_EC_KDF_TYPE kdf;
++ CK_ULONG ulSharedDataLen;
++ CK_BYTE_PTR pSharedData;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++ CK_ULONG ulPrivateDataLen;
++ CK_OBJECT_HANDLE hPrivateData;
++ CK_ULONG ulPublicDataLen2;
++ CK_BYTE_PTR pPublicData2;
++} CK_ECDH2_DERIVE_PARAMS;
++
++typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
++
++typedef struct CK_ECMQV_DERIVE_PARAMS {
++ CK_EC_KDF_TYPE kdf;
++ CK_ULONG ulSharedDataLen;
++ CK_BYTE_PTR pSharedData;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++ CK_ULONG ulPrivateDataLen;
++ CK_OBJECT_HANDLE hPrivateData;
++ CK_ULONG ulPublicDataLen2;
++ CK_BYTE_PTR pPublicData2;
++ CK_OBJECT_HANDLE publicKey;
++} CK_ECMQV_DERIVE_PARAMS;
++
++typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
++
++/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
++ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
++typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
++typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
++
++/* The following X9.42 DH key derivation functions are defined
++ (besides CKD_NULL already defined : */
++#define CKD_SHA1_KDF_ASN1 0x00000003
++#define CKD_SHA1_KDF_CONCATENATE 0x00000004
++
++/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
++ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
++ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
++ * contributes one key pair */
++typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
++ CK_X9_42_DH_KDF_TYPE kdf;
++ CK_ULONG ulOtherInfoLen;
++ CK_BYTE_PTR pOtherInfo;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++} CK_X9_42_DH1_DERIVE_PARAMS;
++
++typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
++
++/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
++ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
++ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
++ * mechanisms, where each party contributes two key pairs */
++typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
++ CK_X9_42_DH_KDF_TYPE kdf;
++ CK_ULONG ulOtherInfoLen;
++ CK_BYTE_PTR pOtherInfo;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++ CK_ULONG ulPrivateDataLen;
++ CK_OBJECT_HANDLE hPrivateData;
++ CK_ULONG ulPublicDataLen2;
++ CK_BYTE_PTR pPublicData2;
++} CK_X9_42_DH2_DERIVE_PARAMS;
++
++typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
++
++typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
++ CK_X9_42_DH_KDF_TYPE kdf;
++ CK_ULONG ulOtherInfoLen;
++ CK_BYTE_PTR pOtherInfo;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++ CK_ULONG ulPrivateDataLen;
++ CK_OBJECT_HANDLE hPrivateData;
++ CK_ULONG ulPublicDataLen2;
++ CK_BYTE_PTR pPublicData2;
++ CK_OBJECT_HANDLE publicKey;
++} CK_X9_42_MQV_DERIVE_PARAMS;
++
++typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
++
++/* CK_KEA_DERIVE_PARAMS provides the parameters to the
++ * CKM_KEA_DERIVE mechanism */
++/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
++typedef struct CK_KEA_DERIVE_PARAMS {
++ CK_BBOOL isSender;
++ CK_ULONG ulRandomLen;
++ CK_BYTE_PTR pRandomA;
++ CK_BYTE_PTR pRandomB;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++} CK_KEA_DERIVE_PARAMS;
++
++typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
++
++
++/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
++ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
++ * holds the effective keysize */
++typedef CK_ULONG CK_RC2_PARAMS;
++
++typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
++
++
++/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
++ * mechanism */
++typedef struct CK_RC2_CBC_PARAMS {
++ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
++
++ CK_BYTE iv[8]; /* IV for CBC mode */
++} CK_RC2_CBC_PARAMS;
++
++typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
++
++
++/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
++ * CKM_RC2_MAC_GENERAL mechanism */
++/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
++typedef struct CK_RC2_MAC_GENERAL_PARAMS {
++ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
++ CK_ULONG ulMacLength; /* Length of MAC in bytes */
++} CK_RC2_MAC_GENERAL_PARAMS;
++
++typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
++ CK_RC2_MAC_GENERAL_PARAMS_PTR;
++
++
++/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
++ * CKM_RC5_MAC mechanisms */
++/* CK_RC5_PARAMS is new for v2.0 */
++typedef struct CK_RC5_PARAMS {
++ CK_ULONG ulWordsize; /* wordsize in bits */
++ CK_ULONG ulRounds; /* number of rounds */
++} CK_RC5_PARAMS;
++
++typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
++
++
++/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
++ * mechanism */
++/* CK_RC5_CBC_PARAMS is new for v2.0 */
++typedef struct CK_RC5_CBC_PARAMS {
++ CK_ULONG ulWordsize; /* wordsize in bits */
++ CK_ULONG ulRounds; /* number of rounds */
++ CK_BYTE_PTR pIv; /* pointer to IV */
++ CK_ULONG ulIvLen; /* length of IV in bytes */
++} CK_RC5_CBC_PARAMS;
++
++typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
++
++
++/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
++ * CKM_RC5_MAC_GENERAL mechanism */
++/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
++typedef struct CK_RC5_MAC_GENERAL_PARAMS {
++ CK_ULONG ulWordsize; /* wordsize in bits */
++ CK_ULONG ulRounds; /* number of rounds */
++ CK_ULONG ulMacLength; /* Length of MAC in bytes */
++} CK_RC5_MAC_GENERAL_PARAMS;
++
++typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
++ CK_RC5_MAC_GENERAL_PARAMS_PTR;
++
++
++/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
++ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
++ * the MAC */
++/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
++typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
++
++typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
++
++/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
++typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[8];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
++
++typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
++
++typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[16];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
++
++typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
++
++/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
++ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
++/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
++typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
++ CK_ULONG ulPasswordLen;
++ CK_BYTE_PTR pPassword;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++ CK_ULONG ulPAndGLen;
++ CK_ULONG ulQLen;
++ CK_ULONG ulRandomLen;
++ CK_BYTE_PTR pRandomA;
++ CK_BYTE_PTR pPrimeP;
++ CK_BYTE_PTR pBaseG;
++ CK_BYTE_PTR pSubprimeQ;
++} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
++
++typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
++ CK_SKIPJACK_PRIVATE_WRAP_PTR;
++
++
++/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
++ * CKM_SKIPJACK_RELAYX mechanism */
++/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
++typedef struct CK_SKIPJACK_RELAYX_PARAMS {
++ CK_ULONG ulOldWrappedXLen;
++ CK_BYTE_PTR pOldWrappedX;
++ CK_ULONG ulOldPasswordLen;
++ CK_BYTE_PTR pOldPassword;
++ CK_ULONG ulOldPublicDataLen;
++ CK_BYTE_PTR pOldPublicData;
++ CK_ULONG ulOldRandomLen;
++ CK_BYTE_PTR pOldRandomA;
++ CK_ULONG ulNewPasswordLen;
++ CK_BYTE_PTR pNewPassword;
++ CK_ULONG ulNewPublicDataLen;
++ CK_BYTE_PTR pNewPublicData;
++ CK_ULONG ulNewRandomLen;
++ CK_BYTE_PTR pNewRandomA;
++} CK_SKIPJACK_RELAYX_PARAMS;
++
++typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
++ CK_SKIPJACK_RELAYX_PARAMS_PTR;
++
++
++typedef struct CK_PBE_PARAMS {
++ CK_BYTE_PTR pInitVector;
++ CK_UTF8CHAR_PTR pPassword;
++ CK_ULONG ulPasswordLen;
++ CK_BYTE_PTR pSalt;
++ CK_ULONG ulSaltLen;
++ CK_ULONG ulIteration;
++} CK_PBE_PARAMS;
++
++typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
++
++
++/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
++ * CKM_KEY_WRAP_SET_OAEP mechanism */
++/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
++typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
++ CK_BYTE bBC; /* block contents byte */
++ CK_BYTE_PTR pX; /* extra data */
++ CK_ULONG ulXLen; /* length of extra data in bytes */
++} CK_KEY_WRAP_SET_OAEP_PARAMS;
++
++typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
++ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
++
++
++typedef struct CK_SSL3_RANDOM_DATA {
++ CK_BYTE_PTR pClientRandom;
++ CK_ULONG ulClientRandomLen;
++ CK_BYTE_PTR pServerRandom;
++ CK_ULONG ulServerRandomLen;
++} CK_SSL3_RANDOM_DATA;
++
++
++typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
++ CK_SSL3_RANDOM_DATA RandomInfo;
++ CK_VERSION_PTR pVersion;
++} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
++
++typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
++ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
++
++
++typedef struct CK_SSL3_KEY_MAT_OUT {
++ CK_OBJECT_HANDLE hClientMacSecret;
++ CK_OBJECT_HANDLE hServerMacSecret;
++ CK_OBJECT_HANDLE hClientKey;
++ CK_OBJECT_HANDLE hServerKey;
++ CK_BYTE_PTR pIVClient;
++ CK_BYTE_PTR pIVServer;
++} CK_SSL3_KEY_MAT_OUT;
++
++typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
++
++
++typedef struct CK_SSL3_KEY_MAT_PARAMS {
++ CK_ULONG ulMacSizeInBits;
++ CK_ULONG ulKeySizeInBits;
++ CK_ULONG ulIVSizeInBits;
++ CK_BBOOL bIsExport;
++ CK_SSL3_RANDOM_DATA RandomInfo;
++ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
++} CK_SSL3_KEY_MAT_PARAMS;
++
++typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
++
++/* CK_TLS_PRF_PARAMS is new for version 2.20 */
++typedef struct CK_TLS_PRF_PARAMS {
++ CK_BYTE_PTR pSeed;
++ CK_ULONG ulSeedLen;
++ CK_BYTE_PTR pLabel;
++ CK_ULONG ulLabelLen;
++ CK_BYTE_PTR pOutput;
++ CK_ULONG_PTR pulOutputLen;
++} CK_TLS_PRF_PARAMS;
++
++typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
++
++/* WTLS is new for version 2.20 */
++typedef struct CK_WTLS_RANDOM_DATA {
++ CK_BYTE_PTR pClientRandom;
++ CK_ULONG ulClientRandomLen;
++ CK_BYTE_PTR pServerRandom;
++ CK_ULONG ulServerRandomLen;
++} CK_WTLS_RANDOM_DATA;
++
++typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
++
++typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
++ CK_MECHANISM_TYPE DigestMechanism;
++ CK_WTLS_RANDOM_DATA RandomInfo;
++ CK_BYTE_PTR pVersion;
++} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
++
++typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
++ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
++
++typedef struct CK_WTLS_PRF_PARAMS {
++ CK_MECHANISM_TYPE DigestMechanism;
++ CK_BYTE_PTR pSeed;
++ CK_ULONG ulSeedLen;
++ CK_BYTE_PTR pLabel;
++ CK_ULONG ulLabelLen;
++ CK_BYTE_PTR pOutput;
++ CK_ULONG_PTR pulOutputLen;
++} CK_WTLS_PRF_PARAMS;
++
++typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
++
++typedef struct CK_WTLS_KEY_MAT_OUT {
++ CK_OBJECT_HANDLE hMacSecret;
++ CK_OBJECT_HANDLE hKey;
++ CK_BYTE_PTR pIV;
++} CK_WTLS_KEY_MAT_OUT;
++
++typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
++
++typedef struct CK_WTLS_KEY_MAT_PARAMS {
++ CK_MECHANISM_TYPE DigestMechanism;
++ CK_ULONG ulMacSizeInBits;
++ CK_ULONG ulKeySizeInBits;
++ CK_ULONG ulIVSizeInBits;
++ CK_ULONG ulSequenceNumber;
++ CK_BBOOL bIsExport;
++ CK_WTLS_RANDOM_DATA RandomInfo;
++ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
++} CK_WTLS_KEY_MAT_PARAMS;
++
++typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
++
++/* CMS is new for version 2.20 */
++typedef struct CK_CMS_SIG_PARAMS {
++ CK_OBJECT_HANDLE certificateHandle;
++ CK_MECHANISM_PTR pSigningMechanism;
++ CK_MECHANISM_PTR pDigestMechanism;
++ CK_UTF8CHAR_PTR pContentType;
++ CK_BYTE_PTR pRequestedAttributes;
++ CK_ULONG ulRequestedAttributesLen;
++ CK_BYTE_PTR pRequiredAttributes;
++ CK_ULONG ulRequiredAttributesLen;
++} CK_CMS_SIG_PARAMS;
++
++typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
++
++typedef struct CK_KEY_DERIVATION_STRING_DATA {
++ CK_BYTE_PTR pData;
++ CK_ULONG ulLen;
++} CK_KEY_DERIVATION_STRING_DATA;
++
++typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
++ CK_KEY_DERIVATION_STRING_DATA_PTR;
++
++
++/* The CK_EXTRACT_PARAMS is used for the
++ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
++ * of the base key should be used as the first bit of the
++ * derived key */
++/* CK_EXTRACT_PARAMS is new for v2.0 */
++typedef CK_ULONG CK_EXTRACT_PARAMS;
++
++typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
++
++/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
++ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
++ * indicate the Pseudo-Random Function (PRF) used to generate
++ * key bits using PKCS #5 PBKDF2. */
++typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
++
++typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
++
++/* The following PRFs are defined in PKCS #5 v2.0. */
++#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
++
++
++/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
++ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
++ * source of the salt value when deriving a key using PKCS #5
++ * PBKDF2. */
++typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
++
++typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
++
++/* The following salt value sources are defined in PKCS #5 v2.0. */
++#define CKZ_SALT_SPECIFIED 0x00000001
++
++/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
++ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
++ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
++typedef struct CK_PKCS5_PBKD2_PARAMS {
++ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
++ CK_VOID_PTR pSaltSourceData;
++ CK_ULONG ulSaltSourceDataLen;
++ CK_ULONG iterations;
++ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
++ CK_VOID_PTR pPrfData;
++ CK_ULONG ulPrfDataLen;
++ CK_UTF8CHAR_PTR pPassword;
++ CK_ULONG_PTR ulPasswordLen;
++} CK_PKCS5_PBKD2_PARAMS;
++
++typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
++
++/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
++
++typedef CK_ULONG CK_OTP_PARAM_TYPE;
++typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
++
++typedef struct CK_OTP_PARAM {
++ CK_OTP_PARAM_TYPE type;
++ CK_VOID_PTR pValue;
++ CK_ULONG ulValueLen;
++} CK_OTP_PARAM;
++
++typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
++
++typedef struct CK_OTP_PARAMS {
++ CK_OTP_PARAM_PTR pParams;
++ CK_ULONG ulCount;
++} CK_OTP_PARAMS;
++
++typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
++
++typedef struct CK_OTP_SIGNATURE_INFO {
++ CK_OTP_PARAM_PTR pParams;
++ CK_ULONG ulCount;
++} CK_OTP_SIGNATURE_INFO;
++
++typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
++
++/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
++#define CK_OTP_VALUE 0
++#define CK_OTP_PIN 1
++#define CK_OTP_CHALLENGE 2
++#define CK_OTP_TIME 3
++#define CK_OTP_COUNTER 4
++#define CK_OTP_FLAGS 5
++#define CK_OTP_OUTPUT_LENGTH 6
++#define CK_OTP_OUTPUT_FORMAT 7
++
++/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
++#define CKF_NEXT_OTP 0x00000001
++#define CKF_EXCLUDE_TIME 0x00000002
++#define CKF_EXCLUDE_COUNTER 0x00000004
++#define CKF_EXCLUDE_CHALLENGE 0x00000008
++#define CKF_EXCLUDE_PIN 0x00000010
++#define CKF_USER_FRIENDLY_OTP 0x00000020
++
++/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
++typedef struct CK_KIP_PARAMS {
++ CK_MECHANISM_PTR pMechanism;
++ CK_OBJECT_HANDLE hKey;
++ CK_BYTE_PTR pSeed;
++ CK_ULONG ulSeedLen;
++} CK_KIP_PARAMS;
++
++typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
++
++/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_AES_CTR_PARAMS {
++ CK_ULONG ulCounterBits;
++ CK_BYTE cb[16];
++} CK_AES_CTR_PARAMS;
++
++typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
++
++/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_CAMELLIA_CTR_PARAMS {
++ CK_ULONG ulCounterBits;
++ CK_BYTE cb[16];
++} CK_CAMELLIA_CTR_PARAMS;
++
++typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
++
++/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[16];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
++
++typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
++
++/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[16];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
++
++typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
++
++#endif
+Index: openssl/util/libeay.num
+diff -u openssl/util/libeay.num:1.1.2.1 openssl/util/libeay.num:1.4
+--- openssl/util/libeay.num:1.1.2.1 Sun Jun 22 01:10:04 2008
++++ openssl/util/libeay.num Wed Dec 17 14:54:59 2008
+@@ -3700,3 +3700,4 @@
+ FIPS_dsa_sig_encode 4089 NOEXIST::FUNCTION:
+ CRYPTO_dbg_remove_all_info 4090 NOEXIST::FUNCTION:
+ OPENSSL_init 4091 NOEXIST::FUNCTION:
++ENGINE_load_pk11 4092 EXIST::FUNCTION:ENGINE
+Index: openssl/util/mk1mf.pl
+diff -u openssl/util/mk1mf.pl:1.1.2.1 openssl/util/mk1mf.pl:1.5
+--- openssl/util/mk1mf.pl:1.1.2.1 Thu Jun 5 15:09:40 2008
++++ openssl/util/mk1mf.pl Wed Dec 17 16:56:20 2008
+@@ -299,6 +299,9 @@
+ if ($key eq "ZLIB_INCLUDE")
+ { $cflags .= " $val" if $val ne "";}
+
++ if ($key eq "PK11_LIB_LOCATION")
++ { $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
++
+ if ($key eq "LIBZLIB")
+ { $zlib_lib = "$val" if $val ne "";}
+
+Index: openssl/util/pl/VC-32.pl
+diff -u openssl/util/pl/VC-32.pl:1.1.2.1 openssl/util/pl/VC-32.pl:1.4
+--- openssl/util/pl/VC-32.pl:1.1.2.1 Fri Jun 6 20:48:57 2008
++++ openssl/util/pl/VC-32.pl Thu Jan 1 14:38:50 2009
+@@ -99,7 +99,7 @@
+ my $f = $shlib?' /MD':' /MT';
+ $lib_cflag='/Zl' if (!$shlib); # remove /DEFAULTLIBs from static lib
+ $opt_cflags=$f.' /Ox /O2 /Ob2';
+- $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
++ $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
+ $lflags="/nologo /subsystem:console /opt:ref";
+ }
+ $mlflags='';
diff --git a/contrib/pkcs11-keygen/readkey.c b/contrib/pkcs11-keygen/readkey.c
index 869717c7..ced0fa9c 100644
--- a/contrib/pkcs11-keygen/readkey.c
+++ b/contrib/pkcs11-keygen/readkey.c
@@ -7,12 +7,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
-#ifndef OPENCRYPTOKI
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#else
#include <opencryptoki/pkcs11.h>
-#endif
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
@@ -117,7 +112,7 @@ main(int argc, char *argv[])
/* Login to the Token (Keystore) */
if (!pin)
-#ifndef OPENCRYPTOKI
+#ifndef HAVE_GETPASS
pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
#else
pin = (CK_UTF8CHAR *)getpass("Enter Pin: ");
diff --git a/contrib/pkcs11-keygen/set_key_id.c b/contrib/pkcs11-keygen/set_key_id.c
index 5c3a3c40..3cb1cd3a 100644
--- a/contrib/pkcs11-keygen/set_key_id.c
+++ b/contrib/pkcs11-keygen/set_key_id.c
@@ -7,12 +7,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
-#ifndef OPENCRYPTOKI
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#else
#include <opencryptoki/pkcs11.h>
-#endif
int
main(int argc, char *argv[])
@@ -101,7 +96,7 @@ main(int argc, char *argv[])
/* Login to the Token (Keystore) */
if (!pin)
-#ifndef OPENCRYPTOKI
+#ifndef HAVE_GETPASS
pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
#else
pin = (CK_UTF8CHAR *)getpass("Enter Pin: ");
diff --git a/contrib/pkcs11-keygen/writekey.c b/contrib/pkcs11-keygen/writekey.c
index 3d1ba99d..b532963d 100644
--- a/contrib/pkcs11-keygen/writekey.c
+++ b/contrib/pkcs11-keygen/writekey.c
@@ -7,12 +7,7 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
-#ifndef OPENCRYPTOKI
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#else
#include <opencryptoki/pkcs11.h>
-#endif
#include <openssl/conf.h>
#include <openssl/engine.h>
#include <openssl/err.h>
@@ -139,7 +134,7 @@ main(int argc, char *argv[])
/* Login to the Token (Keystore) */
if (!pin)
-#ifndef OPENCRYPTOKI
+#ifndef HAVE_GETPASS
pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
#else
pin = (CK_UTF8CHAR *)getpass("Enter Pin: ");
diff --git a/contrib/sdb/bdb/zone2bdb.c b/contrib/sdb/bdb/zone2bdb.c
index 36326afe..e7118531 100644
--- a/contrib/sdb/bdb/zone2bdb.c
+++ b/contrib/sdb/bdb/zone2bdb.c
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone2bdb.c,v 1.2 2008/09/24 02:46:21 marka Exp $ */
+/* $Id: zone2bdb.c,v 1.3 2009/09/01 00:22:26 jinmei Exp $ */
#include <stdio.h>
@@ -137,7 +137,7 @@ main(int argc, char *argv[])
dns_fixedname_init(&origin);
REQUIRE(dns_name_fromtext(dns_fixedname_name(&origin), &b, dns_rootname,
- ISC_FALSE, NULL) == ISC_R_SUCCESS);
+ 0, NULL) == ISC_R_SUCCESS);
REQUIRE(dns_db_create(mctx, "rbt", dns_fixedname_name(&origin),
dns_dbtype_zone, dns_rdataclass_in, 0, NULL,
&db) == ISC_R_SUCCESS);
diff --git a/contrib/sdb/ldap/zone2ldap.c b/contrib/sdb/ldap/zone2ldap.c
index c2820fdc..e06f4f95 100644
--- a/contrib/sdb/ldap/zone2ldap.c
+++ b/contrib/sdb/ldap/zone2ldap.c
@@ -201,7 +201,7 @@ main (int *argc, char **argv)
isc_buffer_add (&buff, strlen (argzone));
dns_fixedname_init (&fixedzone);
zone = dns_fixedname_name (&fixedzone);
- result = dns_name_fromtext (zone, &buff, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext (zone, &buff, dns_rootname, 0, NULL);
isc_result_check (result, "dns_name_fromtext");
result = dns_db_create (mctx, "rbt", zone, dns_dbtype_zone,
diff --git a/contrib/sdb/pgsql/zonetodb.c b/contrib/sdb/pgsql/zonetodb.c
index 61ec2644..a26d72d4 100644
--- a/contrib/sdb/pgsql/zonetodb.c
+++ b/contrib/sdb/pgsql/zonetodb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zonetodb.c,v 1.21 2008/11/27 06:14:22 marka Exp $ */
+/* $Id: zonetodb.c,v 1.23 2009/09/02 23:48:01 tbox Exp $ */
#include <stdlib.h>
#include <string.h>
@@ -174,7 +174,7 @@ main(int argc, char **argv) {
isc_buffer_add(&b, strlen(porigin));
dns_fixedname_init(&forigin);
origin = dns_fixedname_name(&forigin);
- result = dns_name_fromtext(origin, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
db = NULL;
diff --git a/contrib/sdb/sqlite/zone2sqlite.c b/contrib/sdb/sqlite/zone2sqlite.c
index abaf52bf..2ba63cc5 100644
--- a/contrib/sdb/sqlite/zone2sqlite.c
+++ b/contrib/sdb/sqlite/zone2sqlite.c
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone2sqlite.c,v 1.2 2008/09/24 02:46:21 marka Exp $ */
+/* $Id: zone2sqlite.c,v 1.3 2009/09/01 00:22:26 jinmei Exp $ */
#include <stdlib.h>
#include <string.h>
@@ -181,7 +181,7 @@ main(int argc, char *argv[])
isc_buffer_add(&b, strlen(porigin));
dns_fixedname_init(&forigin);
origin = dns_fixedname_name(&forigin);
- result = dns_name_fromtext(origin, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
db = NULL;
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index 13137cac..1e55d84b 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $Id: Bv9ARM-book.xml,v 1.424 2009/07/27 00:43:13 each Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.428 2009/09/02 21:24:24 jreed Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@@ -2486,7 +2486,8 @@ allow-update { key host1-host2. ;};
<command>dnssec-validation</command> options must both be
set to yes (the default setting in <acronym>BIND</acronym> 9.5
and later), and at least one trust anchor must be configured
- with a <command>trusted-keys</command> statement in
+ with a <command>trusted-keys</command> or
+ <command>managed-keys</command> statement in
<filename>named.conf</filename>.
</para>
@@ -2500,7 +2501,14 @@ allow-update { key host1-host2. ;};
</para>
<para>
- <command>trusted-keys</command> are described in more detail
+ <command>managed-keys</command> are trusted keys which are
+ automatically kept up to date via RFC 5011 trust anchor
+ maintenance.
+ </para>
+
+ <para>
+ <command>trusted-keys</command> and
+ <command>managed-keys</command> are described in more detail
later in this document.
</para>
@@ -2517,54 +2525,55 @@ allow-update { key host1-host2. ;};
more public keys for the root. This allows answers from
outside the organization to be validated. It will also
have several keys for parts of the namespace the organization
- controls. These are here to ensure that <command>named</command> is immune
- to compromises in the DNSSEC components of the security
- of parent zones.
+ controls. These are here to ensure that <command>named</command>
+ is immune to compromises in the DNSSEC components of the security
+ of parent zones.
</para>
<programlisting>
-trusted-keys {
-
+managed-keys {
/* Root Key */
-"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
- JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
- aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
- 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
- hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
- 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
- g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
- 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
- 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
- dgxbcDTClU0CRBdiieyLMNzXG3";
-
-/* Key for our organization's forward zone */
-example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
- 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
- GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
- 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
- kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
- g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
- TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
- FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
- F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
- /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
- 1OTQ09A0=";
-
-/* Key for our reverse zone. */
-2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
- xOdNax071L18QqZnQQQAVVr+i
- LhGTnNGp3HoWQLUIzKrJVZ3zg
- gy3WwNT6kZo6c0tszYqbtvchm
- gQC8CzKojM/W16i6MG/eafGU3
- siaOdS0yOI6BgPsw+YZdzlYMa
- IJGf4M4dyoKIhzdZyQ2bYQrjy
- Q4LB0lC7aOnsMyYKHHYeRvPxj
- IQXmdqgOJGq+vsevG06zW+1xg
- YJh9rCIfnm1GX/KMgxLPG2vXT
- D/RnLX+D3T3UL7HJYHJhAZD5L
- 59VvjSPsZJHeDCUyWYrvPZesZ
- DIRvhDD52SKvbheeTJUm6Ehkz
- ytNN2SN96QRk8j/iI8ib";
+ "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
+ JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
+ aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
+ 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
+ hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
+ 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
+ g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
+ 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
+ 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
+ dgxbcDTClU0CRBdiieyLMNzXG3";
+};
+
+trusted-keys {
+ /* Key for our organization's forward zone */
+ example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
+ 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
+ GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
+ 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
+ kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
+ g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
+ TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
+ FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
+ F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
+ /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
+ 1OTQ09A0=";
+
+ /* Key for our reverse zone. */
+ 2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
+ xOdNax071L18QqZnQQQAVVr+i
+ LhGTnNGp3HoWQLUIzKrJVZ3zg
+ gy3WwNT6kZo6c0tszYqbtvchm
+ gQC8CzKojM/W16i6MG/eafGU3
+ siaOdS0yOI6BgPsw+YZdzlYMa
+ IJGf4M4dyoKIhzdZyQ2bYQrjy
+ Q4LB0lC7aOnsMyYKHHYeRvPxj
+ IQXmdqgOJGq+vsevG06zW+1xg
+ YJh9rCIfnm1GX/KMgxLPG2vXT
+ D/RnLX+D3T3UL7HJYHJhAZD5L
+ 59VvjSPsZJHeDCUyWYrvPZesZ
+ DIRvhDD52SKvbheeTJUm6Ehkz
+ ytNN2SN96QRk8j/iI8ib";
};
options {
@@ -3496,6 +3505,17 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
</row>
<row rowsep="0">
<entry colname="1">
+ <para><command>managed-keys</command></para>
+ </entry>
+ <entry colname="2">
+ <para>
+ lists DNSSEC keys to be kept up to date
+ using RFC 5011 trust anchor maintenance.
+ </para>
+ </entry>
+ </row>
+ <row rowsep="0">
+ <entry colname="1">
<para><command>view</command></para>
</entry>
<entry colname="2">
@@ -5118,11 +5138,14 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<listitem>
<para>
When performing dynamic update of secure zones, the
- directory where the public and private key files should be
- found,
- if different than the current working directory. The
- directory specified
- must be an absolute path.
+ directory where the public and private DNSSEC key files
+ should be found, if different than the current working
+ directory. The directory specified must be an absolute
+ path. (Note that this option has no effect on the paths
+ for files containing non-DNSSEC keys such as
+ <filename>bind.keys</filename>,
+ <filename>rndc.key</filename> or
+ <filename>session.key</filename>.)
</para>
</listitem>
</varlistentry>
@@ -5492,7 +5515,8 @@ options {
they are secure. If <userinput>no</userinput>, then normal
DNSSEC validation applies allowing for insecure answers to
be accepted. The specified domain must be under a
- <command>trusted-key</command> or
+ <command>trusted-keys</command> or
+ <command>managed-keys</command> statement, or
<command>dnssec-lookaside</command> must be active.
</para>
</listitem>
@@ -9014,11 +9038,112 @@ deny-answer-aliases { "example.net"; };
level are inherited by all views, but keys defined in a view
are only used within that view.
</para>
+ </sect2>
+
+ <sect2>
+ <title><command>managed-keys</command> Statement Grammar</title>
+
+<programlisting><command>managed-keys</command> {
+ <replaceable>string</replaceable> initial-key <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ;
+ <optional> <replaceable>string</replaceable> initial-key <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ; <optional>...</optional></optional>
+};
+</programlisting>
+
+ </sect2>
+ <sect2>
+ <title><command>managed-keys</command> Statement Definition
+ and Usage</title>
+ <para>
+ The <command>managed-keys</command> statement, like
+ <command>trusted-keys</command>, defines DNSSEC
+ security roots. The difference is that
+ <command>managed-keys</command> can be kept up to date
+ automatically, without intervention from the resolver
+ operator.
+ </para>
+ <para>
+ Suppose, for example, that a zone's key-signing
+ key was compromised, and the zone owner had to revoke and
+ replace the key. A resolver which had the old key in a
+ <command>trusted-keys</command> statement would be
+ unable to validate this zone any longer; it would
+ reply with a SERVFAIL response code. This would
+ continue until the resolver operator had updated the
+ <command>trusted-keys</command> statement with the new key.
+ </para>
+ <para>
+ If, however, the zone were listed in a
+ <command>managed-keys</command> statement instead, then the
+ zone owner could add a "stand-by" key to the zone in advance.
+ <command>named</command> would store the stand-by key, and
+ when the original key was revoked, <command>named</command>
+ would be able to transition smoothly to the new key. It would
+ also recognize that the old key had been revoked, and cease
+ using that key to validate answers, minimizing the damage that
+ the compromised key could do.
+ </para>
+ <para>
+ A <command>managed-keys</command> statement contains a list of
+ the keys to be managed, along with information about how the
+ keys are to be initialized for the first time. The only
+ initialization method currently supported (as of
+ <acronym>BIND</acronym> 9.7.0) is <literal>initial-key</literal>.
+ This means the <command>managed-keys</command> statement must
+ contain a copy of the initializing key. (Future releases may
+ allow keys to be initialized by other methods, eliminating this
+ requirement.)
+ </para>
+ <para>
+ Consequently, a <command>managed-keys</command> statement
+ appears similar to a <command>trusted-keys</command>, differing
+ in the presence of the second field, containing the keyword
+ <literal>initial-key</literal>. The difference is, whereas the
+ keys listed in a <command>trusted-keys</command> continue to be
+ trusted until they are removed from
+ <filename>named.conf</filename>, an initializing key listed
+ in a <command>managed-keys</command> statement is only trusted
+ <emphasis>once</emphasis>: for as long as it takes to load the
+ managed key database and start the RFC 5011 key maintenance
+ process.
+ </para>
+ <para>
+ The first time <command>named</command> runs with a managed key
+ configured in <filename>named.conf</filename>, it fetches the
+ DNSKEY RRset directly from the zone apex, and validates it
+ using the key specified in the <command>managed-keys</command>
+ statement. If the DNSKEY RRset is validly signed, then it is
+ used as the basis for a new managed keys database.
+ </para>
+ <para>
+ From that point on, whenever <command>named</command> runs, it
+ sees the <command>managed-keys</command> statement, checks to
+ make sure RFC 5011 key maintenance has already been initialized
+ for the specified domain, and if so, it simply moves on. The
+ key specified in the <command>managed-keys</command> is not
+ used to validate answers; it has been superseded by the key or
+ keys stored in the managed keys database.
+ </para>
+ <para>
+ The next time <command>named</command> runs after a name
+ has been <emphasis>removed</emphasis> from the
+ <command>managed-keys</command> statement, the corresponding
+ zone will be removed from the managed keys database,
+ and RFC 5011 key maintenance will no longer be used for that
+ domain.
+ </para>
+ <para>
+ <command>named</command> only maintains a single managed keys
+ database; consequently, unlike <command>trusted-keys</command>,
+ <command>managed-keys</command> may only be set at the top
+ level of <filename>named.conf</filename>, not within a view.
+ </para>
<para>
- In addition to keys specified in
- <command>trusted-keys</command> statements, if the
- <command>dnssec-lookaside</command> option is set to "auto",
- named will also load a built-in trusted key for dlv.isc.org.
+ If the <command>dnssec-lookaside</command> option is set to
+ "auto", <command>named</command> will automatically initialize
+ a managed key for the zone <literal>dlv.isc.org</literal>. The
+ key that is used to initialize the key maintenance process is
+ built into <command>named</command>, and can be overridden
+ from <command>bindkeys-file</command>.
</para>
</sect2>
diff --git a/doc/arm/Bv9ARM.ch04.html b/doc/arm/Bv9ARM.ch04.html
index 2e264d02..c58535f3 100644
--- a/doc/arm/Bv9ARM.ch04.html
+++ b/doc/arm/Bv9ARM.ch04.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch04.html,v 1.99 2009/07/15 01:13:11 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch04.html,v 1.100 2009/09/03 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -68,10 +68,10 @@
<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571813">Signing the Zone</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571894">Configuring Servers</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572064">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572076">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572262">Address Lookups Using AAAA Records</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572283">Address to Name Lookups Using Nibble Format</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564083">Address Lookups Using AAAA Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564104">Address to Name Lookups Using Nibble Format</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -884,7 +884,8 @@ allow-update { key host1-host2. ;};
<span><strong class="command">dnssec-validation</strong></span> options must both be
set to yes (the default setting in <acronym class="acronym">BIND</acronym> 9.5
and later), and at least one trust anchor must be configured
- with a <span><strong class="command">trusted-keys</strong></span> statement in
+ with a <span><strong class="command">trusted-keys</strong></span> or
+ <span><strong class="command">managed-keys</strong></span> statement in
<code class="filename">named.conf</code>.
</p>
<p>
@@ -896,7 +897,13 @@ allow-update { key host1-host2. ;};
to validated the DNSKEY RRset that they are from.
</p>
<p>
- <span><strong class="command">trusted-keys</strong></span> are described in more detail
+ <span><strong class="command">managed-keys</strong></span> are trusted keys which are
+ automatically kept up to date via RFC 5011 trust anchor
+ maintenance.
+ </p>
+<p>
+ <span><strong class="command">trusted-keys</strong></span> and
+ <span><strong class="command">managed-keys</strong></span> are described in more detail
later in this document.
</p>
<p>
@@ -911,53 +918,54 @@ allow-update { key host1-host2. ;};
more public keys for the root. This allows answers from
outside the organization to be validated. It will also
have several keys for parts of the namespace the organization
- controls. These are here to ensure that <span><strong class="command">named</strong></span> is immune
- to compromises in the DNSSEC components of the security
+ controls. These are here to ensure that <span><strong class="command">named</strong></span>
+ is immune to compromises in the DNSSEC components of the security
of parent zones.
</p>
<pre class="programlisting">
-trusted-keys {
-
+managed-keys {
/* Root Key */
-"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
- JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
- aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
- 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
- hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
- 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
- g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
- 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
- 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
- dgxbcDTClU0CRBdiieyLMNzXG3";
+ "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
+ JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
+ aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
+ 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
+ hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
+ 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
+ g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
+ 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
+ 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
+ dgxbcDTClU0CRBdiieyLMNzXG3";
+};
-/* Key for our organization's forward zone */
-example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
- 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
- GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
- 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
- kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
- g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
- TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
- FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
- F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
- /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
- 1OTQ09A0=";
+trusted-keys {
+ /* Key for our organization's forward zone */
+ example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
+ 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
+ GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
+ 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
+ kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
+ g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
+ TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
+ FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
+ F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
+ /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
+ 1OTQ09A0=";
-/* Key for our reverse zone. */
-2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
- xOdNax071L18QqZnQQQAVVr+i
- LhGTnNGp3HoWQLUIzKrJVZ3zg
- gy3WwNT6kZo6c0tszYqbtvchm
- gQC8CzKojM/W16i6MG/eafGU3
- siaOdS0yOI6BgPsw+YZdzlYMa
- IJGf4M4dyoKIhzdZyQ2bYQrjy
- Q4LB0lC7aOnsMyYKHHYeRvPxj
- IQXmdqgOJGq+vsevG06zW+1xg
- YJh9rCIfnm1GX/KMgxLPG2vXT
- D/RnLX+D3T3UL7HJYHJhAZD5L
- 59VvjSPsZJHeDCUyWYrvPZesZ
- DIRvhDD52SKvbheeTJUm6Ehkz
- ytNN2SN96QRk8j/iI8ib";
+ /* Key for our reverse zone. */
+ 2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
+ xOdNax071L18QqZnQQQAVVr+i
+ LhGTnNGp3HoWQLUIzKrJVZ3zg
+ gy3WwNT6kZo6c0tszYqbtvchm
+ gQC8CzKojM/W16i6MG/eafGU3
+ siaOdS0yOI6BgPsw+YZdzlYMa
+ IJGf4M4dyoKIhzdZyQ2bYQrjy
+ Q4LB0lC7aOnsMyYKHHYeRvPxj
+ IQXmdqgOJGq+vsevG06zW+1xg
+ YJh9rCIfnm1GX/KMgxLPG2vXT
+ D/RnLX+D3T3UL7HJYHJhAZD5L
+ 59VvjSPsZJHeDCUyWYrvPZesZ
+ DIRvhDD52SKvbheeTJUm6Ehkz
+ ytNN2SN96QRk8j/iI8ib";
};
options {
@@ -1009,7 +1017,7 @@ options {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2572064"></a>IPv6 Support in <acronym class="acronym">BIND</acronym> 9</h2></div></div></div>
+<a name="id2572076"></a>IPv6 Support in <acronym class="acronym">BIND</acronym> 9</h2></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> 9 fully supports all currently
defined forms of IPv6 name to address and address to name
@@ -1047,7 +1055,7 @@ options {
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572262"></a>Address Lookups Using AAAA Records</h3></div></div></div>
+<a name="id2564083"></a>Address Lookups Using AAAA Records</h3></div></div></div>
<p>
The IPv6 AAAA record is a parallel to the IPv4 A record,
and, unlike the deprecated A6 record, specifies the entire
@@ -1066,7 +1074,7 @@ host 3600 IN AAAA 2001:db8::1
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572283"></a>Address to Name Lookups Using Nibble Format</h3></div></div></div>
+<a name="id2564104"></a>Address to Name Lookups Using Nibble Format</h3></div></div></div>
<p>
When looking up an address in nibble format, the address
components are simply reversed, just as in IPv4, and
diff --git a/doc/arm/Bv9ARM.ch05.html b/doc/arm/Bv9ARM.ch05.html
index 56bc69d6..c5ceb50d 100644
--- a/doc/arm/Bv9ARM.ch05.html
+++ b/doc/arm/Bv9ARM.ch05.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch05.html,v 1.80 2009/07/15 01:13:11 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch05.html,v 1.81 2009/09/03 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,13 +45,13 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572316">The Lightweight Resolver Library</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2564137">The Lightweight Resolver Library</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch05.html#lwresd">Running a Resolver Daemon</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2572316"></a>The Lightweight Resolver Library</h2></div></div></div>
+<a name="id2564137"></a>The Lightweight Resolver Library</h2></div></div></div>
<p>
Traditionally applications have been linked with a stub resolver
library that sends recursive DNS queries to a local caching name
diff --git a/doc/arm/Bv9ARM.ch06.html b/doc/arm/Bv9ARM.ch06.html
index 6f0db4c0..68543607 100644
--- a/doc/arm/Bv9ARM.ch06.html
+++ b/doc/arm/Bv9ARM.ch06.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch06.html,v 1.229 2009/07/27 01:13:17 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch06.html,v 1.231 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -48,55 +48,58 @@
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#configuration_file_elements">Configuration File Elements</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#address_match_lists">Address Match Lists</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573863">Comment Syntax</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573876">Comment Syntax</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#Configuration_File_Grammar">Configuration File Grammar</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574562"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574598"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#acl"><span><strong class="command">acl</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574752"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574788"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#controls_statement_definition_and_usage"><span><strong class="command">controls</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575179"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575196"><span><strong class="command">include</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575216"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575233"><span><strong class="command">include</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575220"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575243"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575334"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575460"><span><strong class="command">logging</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575256"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575280"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575370"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575496"><span><strong class="command">logging</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577527"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577601"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577665"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577708"><span><strong class="command">masters</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577495"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577569"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577633"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577676"><span><strong class="command">masters</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577723"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577691"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#options"><span><strong class="command">options</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_grammar"><span><strong class="command">server</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_definition_and_usage"><span><strong class="command">server</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#statschannels"><span><strong class="command">statistics-channels</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587578"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587559"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587733"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587784"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587645"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587765"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+ and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587812"><span><strong class="command">managed-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587931"><span><strong class="command">managed-keys</strong></span> Statement Definition
and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#view_statement_grammar"><span><strong class="command">view</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588025"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588149"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zone_statement_grammar"><span><strong class="command">zone</strong></span>
Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589433"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589693"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2592136">Zone File</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2592396">Zone File</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#types_of_resource_records_and_when_to_use_them">Types of Resource Records and When to Use Them</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594366">Discussion of MX Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594627">Discussion of MX Records</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#Setting_TTLs">Setting TTLs</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594914">Inverse Mapping in IPv4</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595109">Other Zone File Directives</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595450"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595174">Inverse Mapping in IPv4</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595301">Other Zone File Directives</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595574"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zonefile_format">Additional File Formats</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#statistics">BIND9 Statistics</a></span></dt>
@@ -474,7 +477,7 @@
<a name="address_match_lists"></a>Address Match Lists</h3></div></div></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573698"></a>Syntax</h4></div></div></div>
+<a name="id2573710"></a>Syntax</h4></div></div></div>
<pre class="programlisting"><code class="varname">address_match_list</code> = address_match_list_element ;
[<span class="optional"> address_match_list_element; ... </span>]
<code class="varname">address_match_list_element</code> = [<span class="optional"> ! </span>] (ip_address [<span class="optional">/length</span>] |
@@ -483,7 +486,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573725"></a>Definition and Usage</h4></div></div></div>
+<a name="id2573738"></a>Definition and Usage</h4></div></div></div>
<p>
Address match lists are primarily used to determine access
control for various server operations. They are also used in
@@ -567,7 +570,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2573863"></a>Comment Syntax</h3></div></div></div>
+<a name="id2573876"></a>Comment Syntax</h3></div></div></div>
<p>
The <acronym class="acronym">BIND</acronym> 9 comment syntax allows for
comments to appear
@@ -577,7 +580,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573878"></a>Syntax</h4></div></div></div>
+<a name="id2573891"></a>Syntax</h4></div></div></div>
<p>
</p>
<pre class="programlisting">/* This is a <acronym class="acronym">BIND</acronym> comment as in C */</pre>
@@ -593,7 +596,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573908"></a>Definition and Usage</h4></div></div></div>
+<a name="id2573921"></a>Definition and Usage</h4></div></div></div>
<p>
Comments may appear anywhere that whitespace may appear in
a <acronym class="acronym">BIND</acronym> configuration file.
@@ -806,6 +809,17 @@
</tr>
<tr>
<td>
+ <p><span><strong class="command">managed-keys</strong></span></p>
+ </td>
+<td>
+ <p>
+ lists DNSSEC keys to be kept up to date
+ using RFC 5011 trust anchor maintenance.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
<p><span><strong class="command">view</strong></span></p>
</td>
<td>
@@ -834,7 +848,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574562"></a><span><strong class="command">acl</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574598"></a><span><strong class="command">acl</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">acl</strong></span> acl-name {
address_match_list
};
@@ -916,7 +930,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574752"></a><span><strong class="command">controls</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574788"></a><span><strong class="command">controls</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">controls</strong></span> {
[ inet ( ip_addr | * ) [ port ip_port ]
allow { <em class="replaceable"><code> address_match_list </code></em> }
@@ -1040,12 +1054,12 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575179"></a><span><strong class="command">include</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575216"></a><span><strong class="command">include</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">include</strong></span> <em class="replaceable"><code>filename</code></em>;</pre>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575196"></a><span><strong class="command">include</strong></span> Statement Definition and
+<a name="id2575233"></a><span><strong class="command">include</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">include</strong></span> statement inserts the
@@ -1060,7 +1074,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575220"></a><span><strong class="command">key</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575256"></a><span><strong class="command">key</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">key</strong></span> <em class="replaceable"><code>key_id</code></em> {
algorithm <em class="replaceable"><code>string</code></em>;
secret <em class="replaceable"><code>string</code></em>;
@@ -1069,7 +1083,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575243"></a><span><strong class="command">key</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2575280"></a><span><strong class="command">key</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">key</strong></span> statement defines a shared
secret key for use with TSIG (see <a href="Bv9ARM.ch04.html#tsig" title="TSIG">the section called &#8220;TSIG&#8221;</a>)
@@ -1116,7 +1130,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575334"></a><span><strong class="command">logging</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575370"></a><span><strong class="command">logging</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">logging</strong></span> {
[ <span><strong class="command">channel</strong></span> <em class="replaceable"><code>channel_name</code></em> {
( <span><strong class="command">file</strong></span> <em class="replaceable"><code>path_name</code></em>
@@ -1140,7 +1154,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575460"></a><span><strong class="command">logging</strong></span> Statement Definition and
+<a name="id2575496"></a><span><strong class="command">logging</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">logging</strong></span> statement configures a
@@ -1174,7 +1188,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2575512"></a>The <span><strong class="command">channel</strong></span> Phrase</h4></div></div></div>
+<a name="id2575548"></a>The <span><strong class="command">channel</strong></span> Phrase</h4></div></div></div>
<p>
All log output goes to one or more <span class="emphasis"><em>channels</em></span>;
you can make as many of them as you want.
@@ -1738,7 +1752,7 @@ category notify { null; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2577008"></a>The <span><strong class="command">query-errors</strong></span> Category</h4></div></div></div>
+<a name="id2576976"></a>The <span><strong class="command">query-errors</strong></span> Category</h4></div></div></div>
<p>
The <span><strong class="command">query-errors</strong></span> category is
specifically intended for debugging purposes: To identify
@@ -1966,7 +1980,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577527"></a><span><strong class="command">lwres</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577495"></a><span><strong class="command">lwres</strong></span> Statement Grammar</h3></div></div></div>
<p>
This is the grammar of the <span><strong class="command">lwres</strong></span>
statement in the <code class="filename">named.conf</code> file:
@@ -1982,7 +1996,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577601"></a><span><strong class="command">lwres</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2577569"></a><span><strong class="command">lwres</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">lwres</strong></span> statement configures the
name
@@ -2033,7 +2047,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577665"></a><span><strong class="command">masters</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577633"></a><span><strong class="command">masters</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting">
<span><strong class="command">masters</strong></span> <em class="replaceable"><code>name</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> |
<em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] };
@@ -2041,7 +2055,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577708"></a><span><strong class="command">masters</strong></span> Statement Definition and
+<a name="id2577676"></a><span><strong class="command">masters</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p><span><strong class="command">masters</strong></span>
lists allow for a common set of masters to be easily used by
@@ -2050,7 +2064,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577723"></a><span><strong class="command">options</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577691"></a><span><strong class="command">options</strong></span> Statement Grammar</h3></div></div></div>
<p>
This is the grammar of the <span><strong class="command">options</strong></span>
statement in the <code class="filename">named.conf</code> file:
@@ -2345,11 +2359,14 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<dt><span class="term"><span><strong class="command">key-directory</strong></span></span></dt>
<dd><p>
When performing dynamic update of secure zones, the
- directory where the public and private key files should be
- found,
- if different than the current working directory. The
- directory specified
- must be an absolute path.
+ directory where the public and private DNSSEC key files
+ should be found, if different than the current working
+ directory. The directory specified must be an absolute
+ path. (Note that this option has no effect on the paths
+ for files containing non-DNSSEC keys such as
+ <code class="filename">bind.keys</code>,
+ <code class="filename">rndc.key</code> or
+ <code class="filename">session.key</code>.)
</p></dd>
<dt><span class="term"><span><strong class="command">named-xfer</strong></span></span></dt>
<dd><p>
@@ -2613,7 +2630,8 @@ options {
they are secure. If <strong class="userinput"><code>no</code></strong>, then normal
DNSSEC validation applies allowing for insecure answers to
be accepted. The specified domain must be under a
- <span><strong class="command">trusted-key</strong></span> or
+ <span><strong class="command">trusted-keys</strong></span> or
+ <span><strong class="command">managed-keys</strong></span> statement, or
<span><strong class="command">dnssec-lookaside</strong></span> must be active.
</p></dd>
</dl></div>
@@ -3344,7 +3362,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2582292"></a>Forwarding</h4></div></div></div>
+<a name="id2582273"></a>Forwarding</h4></div></div></div>
<p>
The forwarding facility can be used to create a large site-wide
cache on a few servers, reducing traffic over links to external
@@ -3388,7 +3406,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2582350"></a>Dual-stack Servers</h4></div></div></div>
+<a name="id2582468"></a>Dual-stack Servers</h4></div></div></div>
<p>
Dual-stack servers are used as servers of last resort to work
around
@@ -3585,7 +3603,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2582924"></a>Interfaces</h4></div></div></div>
+<a name="id2582973"></a>Interfaces</h4></div></div></div>
<p>
The interfaces and ports that the server will answer queries
from may be specified using the <span><strong class="command">listen-on</strong></span> option. <span><strong class="command">listen-on</strong></span> takes
@@ -4037,7 +4055,7 @@ avoid-v6-udp-ports {};
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2584128"></a>UDP Port Lists</h4></div></div></div>
+<a name="id2584177"></a>UDP Port Lists</h4></div></div></div>
<p>
<span><strong class="command">use-v4-udp-ports</strong></span>,
<span><strong class="command">avoid-v4-udp-ports</strong></span>,
@@ -4079,7 +4097,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2584187"></a>Operating System Resource Limits</h4></div></div></div>
+<a name="id2584305"></a>Operating System Resource Limits</h4></div></div></div>
<p>
The server's usage of many system resources can be limited.
Scaled values are allowed when specifying resource limits. For
@@ -4241,7 +4259,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2584678"></a>Periodic Task Intervals</h4></div></div></div>
+<a name="id2584727"></a>Periodic Task Intervals</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">cleaning-interval</strong></span></span></dt>
<dd><p>
@@ -5037,7 +5055,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2586690"></a>Content Filtering</h4></div></div></div>
+<a name="id2586807"></a>Content Filtering</h4></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> 9 provides the ability to filter
out DNS responses from external DNS servers containing
@@ -5367,7 +5385,7 @@ deny-answer-aliases { "example.net"; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587578"></a><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<a name="id2587559"></a><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">statistics-channels</strong></span> statement
@@ -5418,7 +5436,7 @@ deny-answer-aliases { "example.net"; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587733"></a><span><strong class="command">trusted-keys</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2587645"></a><span><strong class="command">trusted-keys</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">trusted-keys</strong></span> {
<em class="replaceable"><code>string</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ;
[<span class="optional"> <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ; [<span class="optional">...</span>]</span>]
@@ -5427,7 +5445,7 @@ deny-answer-aliases { "example.net"; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587784"></a><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<a name="id2587765"></a><span><strong class="command">trusted-keys</strong></span> Statement Definition
and Usage</h3></div></div></div>
<p>
The <span><strong class="command">trusted-keys</strong></span> statement defines
@@ -5464,11 +5482,111 @@ deny-answer-aliases { "example.net"; };
level are inherited by all views, but keys defined in a view
are only used within that view.
</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2587812"></a><span><strong class="command">managed-keys</strong></span> Statement Grammar</h3></div></div></div>
+<pre class="programlisting"><span><strong class="command">managed-keys</strong></span> {
+ <em class="replaceable"><code>string</code></em> initial-key <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ;
+ [<span class="optional"> <em class="replaceable"><code>string</code></em> initial-key <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ; [<span class="optional">...</span>]</span>]
+};
+</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2587931"></a><span><strong class="command">managed-keys</strong></span> Statement Definition
+ and Usage</h3></div></div></div>
<p>
- In addition to keys specified in
- <span><strong class="command">trusted-keys</strong></span> statements, if the
- <span><strong class="command">dnssec-lookaside</strong></span> option is set to "auto",
- named will also load a built-in trusted key for dlv.isc.org.
+ The <span><strong class="command">managed-keys</strong></span> statement, like
+ <span><strong class="command">trusted-keys</strong></span>, defines DNSSEC
+ security roots. The difference is that
+ <span><strong class="command">managed-keys</strong></span> can be kept up to date
+ automatically, without intervention from the resolver
+ operator.
+ </p>
+<p>
+ Suppose, for example, that a zone's key-signing
+ key was compromised, and the zone owner had to revoke and
+ replace the key. A resolver which had the old key in a
+ <span><strong class="command">trusted-keys</strong></span> statement would be
+ unable to validate this zone any longer; it would
+ reply with a SERVFAIL response code. This would
+ continue until the resolver operator had updated the
+ <span><strong class="command">trusted-keys</strong></span> statement with the new key.
+ </p>
+<p>
+ If, however, the zone were listed in a
+ <span><strong class="command">managed-keys</strong></span> statement instead, then the
+ zone owner could add a "stand-by" key to the zone in advance.
+ <span><strong class="command">named</strong></span> would store the stand-by key, and
+ when the original key was revoked, <span><strong class="command">named</strong></span>
+ would be able to transition smoothly to the new key. It would
+ also recognize that the old key had been revoked, and cease
+ using that key to validate answers, minimizing the damage that
+ the compromised key could do.
+ </p>
+<p>
+ A <span><strong class="command">managed-keys</strong></span> statement contains a list of
+ the keys to be managed, along with information about how the
+ keys are to be initialized for the first time. The only
+ initialization method currently supported (as of
+ <acronym class="acronym">BIND</acronym> 9.7.0) is <code class="literal">initial-key</code>.
+ This means the <span><strong class="command">managed-keys</strong></span> statement must
+ contain a copy of the initializing key. (Future releases may
+ allow keys to be initialized by other methods, eliminating this
+ requirement.)
+ </p>
+<p>
+ Consequently, a <span><strong class="command">managed-keys</strong></span> statement
+ appears similar to a <span><strong class="command">trusted-keys</strong></span>, differing
+ in the presence of the second field, containing the keyword
+ <code class="literal">initial-key</code>. The difference is, whereas the
+ keys listed in a <span><strong class="command">trusted-keys</strong></span> continue to be
+ trusted until they are removed from
+ <code class="filename">named.conf</code>, an initializing key listed
+ in a <span><strong class="command">managed-keys</strong></span> statement is only trusted
+ <span class="emphasis"><em>once</em></span>: for as long as it takes to load the
+ managed key database and start the RFC 5011 key maintenance
+ process.
+ </p>
+<p>
+ The first time <span><strong class="command">named</strong></span> runs with a managed key
+ configured in <code class="filename">named.conf</code>, it fetches the
+ DNSKEY RRset directly from the zone apex, and validates it
+ using the key specified in the <span><strong class="command">managed-keys</strong></span>
+ statement. If the DNSKEY RRset is validly signed, then it is
+ used as the basis for a new managed keys database.
+ </p>
+<p>
+ From that point on, whenever <span><strong class="command">named</strong></span> runs, it
+ sees the <span><strong class="command">managed-keys</strong></span> statement, checks to
+ make sure RFC 5011 key maintenance has already been initialized
+ for the specified domain, and if so, it simply moves on. The
+ key specified in the <span><strong class="command">managed-keys</strong></span> is not
+ used to validate answers; it has been superseded by the key or
+ keys stored in the managed keys database.
+ </p>
+<p>
+ The next time <span><strong class="command">named</strong></span> runs after a name
+ has been <span class="emphasis"><em>removed</em></span> from the
+ <span><strong class="command">managed-keys</strong></span> statement, the corresponding
+ zone will be removed from the managed keys database,
+ and RFC 5011 key maintenance will no longer be used for that
+ domain.
+ </p>
+<p>
+ <span><strong class="command">named</strong></span> only maintains a single managed keys
+ database; consequently, unlike <span><strong class="command">trusted-keys</strong></span>,
+ <span><strong class="command">managed-keys</strong></span> may only be set at the top
+ level of <code class="filename">named.conf</code>, not within a view.
+ </p>
+<p>
+ If the <span><strong class="command">dnssec-lookaside</strong></span> option is set to
+ "auto", <span><strong class="command">named</strong></span> will automatically initialize
+ a managed key for the zone <code class="literal">dlv.isc.org</code>. The
+ key that is used to initialize the key maintenance process is
+ built into <span><strong class="command">named</strong></span>, and can be overridden
+ from <span><strong class="command">bindkeys-file</strong></span>.
</p>
</div>
<div class="sect2" lang="en">
@@ -5486,7 +5604,7 @@ deny-answer-aliases { "example.net"; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2588025"></a><span><strong class="command">view</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2588149"></a><span><strong class="command">view</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">view</strong></span> statement is a powerful
feature
@@ -5763,10 +5881,10 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2589433"></a><span><strong class="command">zone</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2589693"></a><span><strong class="command">zone</strong></span> Statement Definition and Usage</h3></div></div></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2589441"></a>Zone Types</h4></div></div></div>
+<a name="id2589769"></a>Zone Types</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -5977,7 +6095,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2590005"></a>Class</h4></div></div></div>
+<a name="id2590129"></a>Class</h4></div></div></div>
<p>
The zone's name may optionally be followed by a class. If
a class is not specified, class <code class="literal">IN</code> (for <code class="varname">Internet</code>),
@@ -5999,7 +6117,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2590038"></a>Zone Options</h4></div></div></div>
+<a name="id2590162"></a>Zone Options</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">allow-notify</strong></span></span></dt>
<dd><p>
@@ -6629,7 +6747,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2592136"></a>Zone File</h2></div></div></div>
+<a name="id2592396"></a>Zone File</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="types_of_resource_records_and_when_to_use_them"></a>Types of Resource Records and When to Use Them</h3></div></div></div>
@@ -6642,7 +6760,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2592154"></a>Resource Records</h4></div></div></div>
+<a name="id2592414"></a>Resource Records</h4></div></div></div>
<p>
A domain name identifies a node. Each node has a set of
resource information, which may be empty. The set of resource
@@ -7379,7 +7497,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2593709"></a>Textual expression of RRs</h4></div></div></div>
+<a name="id2594106"></a>Textual expression of RRs</h4></div></div></div>
<p>
RRs are represented in binary form in the packets of the DNS
protocol, and are usually represented in highly encoded form
@@ -7582,7 +7700,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2594366"></a>Discussion of MX Records</h3></div></div></div>
+<a name="id2594627"></a>Discussion of MX Records</h3></div></div></div>
<p>
As described above, domain servers store information as a
series of resource records, each of which contains a particular
@@ -7838,7 +7956,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2594914"></a>Inverse Mapping in IPv4</h3></div></div></div>
+<a name="id2595174"></a>Inverse Mapping in IPv4</h3></div></div></div>
<p>
Reverse name resolution (that is, translation from IP address
to name) is achieved by means of the <span class="emphasis"><em>in-addr.arpa</em></span> domain
@@ -7899,7 +8017,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2595109"></a>Other Zone File Directives</h3></div></div></div>
+<a name="id2595301"></a>Other Zone File Directives</h3></div></div></div>
<p>
The Master File Format was initially defined in RFC 1035 and
has subsequently been extended. While the Master File Format
@@ -7914,7 +8032,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2595131"></a>The <span><strong class="command">@</strong></span> (at-sign)</h4></div></div></div>
+<a name="id2595323"></a>The <span><strong class="command">@</strong></span> (at-sign)</h4></div></div></div>
<p>
When used in the label (or name) field, the asperand or
at-sign (@) symbol represents the current origin.
@@ -7925,7 +8043,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2595147"></a>The <span><strong class="command">$ORIGIN</strong></span> Directive</h4></div></div></div>
+<a name="id2595339"></a>The <span><strong class="command">$ORIGIN</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$ORIGIN</strong></span>
<em class="replaceable"><code>domain-name</code></em>
@@ -7954,7 +8072,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2595345"></a>The <span><strong class="command">$INCLUDE</strong></span> Directive</h4></div></div></div>
+<a name="id2595468"></a>The <span><strong class="command">$INCLUDE</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$INCLUDE</strong></span>
<em class="replaceable"><code>filename</code></em>
@@ -7990,7 +8108,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2595414"></a>The <span><strong class="command">$TTL</strong></span> Directive</h4></div></div></div>
+<a name="id2595538"></a>The <span><strong class="command">$TTL</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$TTL</strong></span>
<em class="replaceable"><code>default-ttl</code></em>
@@ -8009,7 +8127,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2595450"></a><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</h3></div></div></div>
+<a name="id2595574"></a><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</h3></div></div></div>
<p>
Syntax: <span><strong class="command">$GENERATE</strong></span>
<em class="replaceable"><code>range</code></em>
@@ -8433,7 +8551,7 @@ HOST-127.EXAMPLE. MX 0 .
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2596472"></a>Name Server Statistics Counters</h4></div></div></div>
+<a name="id2596732"></a>Name Server Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -8990,7 +9108,7 @@ HOST-127.EXAMPLE. MX 0 .
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2597945"></a>Zone Maintenance Statistics Counters</h4></div></div></div>
+<a name="id2598205"></a>Zone Maintenance Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -9144,7 +9262,7 @@ HOST-127.EXAMPLE. MX 0 .
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2598328"></a>Resolver Statistics Counters</h4></div></div></div>
+<a name="id2598588"></a>Resolver Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -9527,7 +9645,7 @@ HOST-127.EXAMPLE. MX 0 .
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2599486"></a>Socket I/O Statistics Counters</h4></div></div></div>
+<a name="id2599610"></a>Socket I/O Statistics Counters</h4></div></div></div>
<p>
Socket I/O statistics counters are defined per socket
types, which are
@@ -9682,7 +9800,7 @@ HOST-127.EXAMPLE. MX 0 .
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2599860"></a>Compatibility with <span class="emphasis"><em>BIND</em></span> 8 Counters</h4></div></div></div>
+<a name="id2600052"></a>Compatibility with <span class="emphasis"><em>BIND</em></span> 8 Counters</h4></div></div></div>
<p>
Most statistics counters that were available
in <span><strong class="command">BIND</strong></span> 8 are also supported in
diff --git a/doc/arm/Bv9ARM.ch07.html b/doc/arm/Bv9ARM.ch07.html
index 5c4323bc..531c63c1 100644
--- a/doc/arm/Bv9ARM.ch07.html
+++ b/doc/arm/Bv9ARM.ch07.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch07.html,v 1.202 2009/07/15 01:13:11 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch07.html,v 1.204 2009/09/03 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -46,10 +46,10 @@
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#Access_Control_Lists">Access Control Lists</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2600034"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2600294"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600115">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600174">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600375">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600435">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#dynamic_update_security">Dynamic Update Security</a></span></dt>
</dl>
@@ -122,7 +122,7 @@ zone "example.com" {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2600034"></a><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span>
+<a name="id2600294"></a><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span>
</h2></div></div></div>
<p>
On UNIX servers, it is possible to run <acronym class="acronym">BIND</acronym>
@@ -148,7 +148,7 @@ zone "example.com" {
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2600115"></a>The <span><strong class="command">chroot</strong></span> Environment</h3></div></div></div>
+<a name="id2600375"></a>The <span><strong class="command">chroot</strong></span> Environment</h3></div></div></div>
<p>
In order for a <span><strong class="command">chroot</strong></span> environment
to
@@ -176,7 +176,7 @@ zone "example.com" {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2600174"></a>Using the <span><strong class="command">setuid</strong></span> Function</h3></div></div></div>
+<a name="id2600435"></a>Using the <span><strong class="command">setuid</strong></span> Function</h3></div></div></div>
<p>
Prior to running the <span><strong class="command">named</strong></span> daemon,
use
diff --git a/doc/arm/Bv9ARM.ch08.html b/doc/arm/Bv9ARM.ch08.html
index 1139185e..d15cd3db 100644
--- a/doc/arm/Bv9ARM.ch08.html
+++ b/doc/arm/Bv9ARM.ch08.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch08.html,v 1.201 2009/07/15 01:13:10 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch08.html,v 1.203 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,18 +45,18 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600323">Common Problems</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2600328">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600340">Incrementing and Changing the Serial Number</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600493">Where Can I Get Help?</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600583">Common Problems</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2600588">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600600">Incrementing and Changing the Serial Number</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600617">Where Can I Get Help?</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2600323"></a>Common Problems</h2></div></div></div>
+<a name="id2600583"></a>Common Problems</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2600328"></a>It's not working; how can I figure out what's wrong?</h3></div></div></div>
+<a name="id2600588"></a>It's not working; how can I figure out what's wrong?</h3></div></div></div>
<p>
The best solution to solving installation and
configuration issues is to take preventative measures by setting
@@ -68,7 +68,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2600340"></a>Incrementing and Changing the Serial Number</h2></div></div></div>
+<a name="id2600600"></a>Incrementing and Changing the Serial Number</h2></div></div></div>
<p>
Zone serial numbers are just numbers &#8212; they aren't
date related. A lot of people set them to a number that
@@ -95,7 +95,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2600493"></a>Where Can I Get Help?</h2></div></div></div>
+<a name="id2600617"></a>Where Can I Get Help?</h2></div></div></div>
<p>
The Internet Systems Consortium
(<acronym class="acronym">ISC</acronym>) offers a wide range
diff --git a/doc/arm/Bv9ARM.ch09.html b/doc/arm/Bv9ARM.ch09.html
index 3bb57609..81d1791e 100644
--- a/doc/arm/Bv9ARM.ch09.html
+++ b/doc/arm/Bv9ARM.ch09.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch09.html,v 1.203 2009/07/15 01:13:11 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch09.html,v 1.205 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,21 +45,21 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600555">Acknowledgments</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600747">Acknowledgments</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#historical_dns_information">A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600659">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600987">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#ipv6addresses">IPv6 addresses (AAAA)</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bibliography">Bibliography (and Suggested Reading)</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#rfcs">Request for Comments (RFCs)</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#internet_drafts">Internet Drafts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2604007">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2604267">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
</dl></dd>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2600555"></a>Acknowledgments</h2></div></div></div>
+<a name="id2600747"></a>Acknowledgments</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="historical_dns_information"></a>A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym>
@@ -162,7 +162,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2600659"></a>General <acronym class="acronym">DNS</acronym> Reference Information</h2></div></div></div>
+<a name="id2600987"></a>General <acronym class="acronym">DNS</acronym> Reference Information</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="ipv6addresses"></a>IPv6 addresses (AAAA)</h3></div></div></div>
@@ -250,17 +250,17 @@
</p>
<div class="bibliography">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2601051"></a>Bibliography</h4></div></div></div>
+<a name="id2601175"></a>Bibliography</h4></div></div></div>
<div class="bibliodiv">
<h3 class="title">Standards</h3>
<div class="biblioentry">
-<a name="id2601062"></a><p>[<abbr class="abbrev">RFC974</abbr>] <span class="author"><span class="firstname">C.</span> <span class="surname">Partridge</span>. </span><span class="title"><i>Mail Routing and the Domain System</i>. </span><span class="pubdate">January 1986. </span></p>
+<a name="id2601186"></a><p>[<abbr class="abbrev">RFC974</abbr>] <span class="author"><span class="firstname">C.</span> <span class="surname">Partridge</span>. </span><span class="title"><i>Mail Routing and the Domain System</i>. </span><span class="pubdate">January 1986. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601085"></a><p>[<abbr class="abbrev">RFC1034</abbr>] <span class="author"><span class="firstname">P.V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Concepts and Facilities</i>. </span><span class="pubdate">November 1987. </span></p>
+<a name="id2601209"></a><p>[<abbr class="abbrev">RFC1034</abbr>] <span class="author"><span class="firstname">P.V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Concepts and Facilities</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601109"></a><p>[<abbr class="abbrev">RFC1035</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Implementation and
+<a name="id2601233"></a><p>[<abbr class="abbrev">RFC1035</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Implementation and
Specification</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
</div>
@@ -268,42 +268,42 @@
<h3 class="title">
<a name="proposed_standards"></a>Proposed Standards</h3>
<div class="biblioentry">
-<a name="id2601145"></a><p>[<abbr class="abbrev">RFC2181</abbr>] <span class="author"><span class="firstname">R., R. Bush</span> <span class="surname">Elz</span>. </span><span class="title"><i>Clarifications to the <acronym class="acronym">DNS</acronym>
+<a name="id2601269"></a><p>[<abbr class="abbrev">RFC2181</abbr>] <span class="author"><span class="firstname">R., R. Bush</span> <span class="surname">Elz</span>. </span><span class="title"><i>Clarifications to the <acronym class="acronym">DNS</acronym>
Specification</i>. </span><span class="pubdate">July 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601172"></a><p>[<abbr class="abbrev">RFC2308</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Andrews</span>. </span><span class="title"><i>Negative Caching of <acronym class="acronym">DNS</acronym>
+<a name="id2601296"></a><p>[<abbr class="abbrev">RFC2308</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Andrews</span>. </span><span class="title"><i>Negative Caching of <acronym class="acronym">DNS</acronym>
Queries</i>. </span><span class="pubdate">March 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601197"></a><p>[<abbr class="abbrev">RFC1995</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Ohta</span>. </span><span class="title"><i>Incremental Zone Transfer in <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2601321"></a><p>[<abbr class="abbrev">RFC1995</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Ohta</span>. </span><span class="title"><i>Incremental Zone Transfer in <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601222"></a><p>[<abbr class="abbrev">RFC1996</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A Mechanism for Prompt Notification of Zone Changes</i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2601346"></a><p>[<abbr class="abbrev">RFC1996</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A Mechanism for Prompt Notification of Zone Changes</i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601245"></a><p>[<abbr class="abbrev">RFC2136</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">Y.</span> <span class="surname">Rekhter</span>, and <span class="firstname">J.</span> <span class="surname">Bound</span>. </span><span class="title"><i>Dynamic Updates in the Domain Name System</i>. </span><span class="pubdate">April 1997. </span></p>
+<a name="id2601369"></a><p>[<abbr class="abbrev">RFC2136</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">Y.</span> <span class="surname">Rekhter</span>, and <span class="firstname">J.</span> <span class="surname">Bound</span>. </span><span class="title"><i>Dynamic Updates in the Domain Name System</i>. </span><span class="pubdate">April 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601301"></a><p>[<abbr class="abbrev">RFC2671</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Extension Mechanisms for DNS (EDNS0)</i>. </span><span class="pubdate">August 1997. </span></p>
+<a name="id2601425"></a><p>[<abbr class="abbrev">RFC2671</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Extension Mechanisms for DNS (EDNS0)</i>. </span><span class="pubdate">August 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601328"></a><p>[<abbr class="abbrev">RFC2672</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Non-Terminal DNS Name Redirection</i>. </span><span class="pubdate">August 1999. </span></p>
+<a name="id2601520"></a><p>[<abbr class="abbrev">RFC2672</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Non-Terminal DNS Name Redirection</i>. </span><span class="pubdate">August 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601354"></a><p>[<abbr class="abbrev">RFC2845</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>, <span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, and <span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secret Key Transaction Authentication for <acronym class="acronym">DNS</acronym> (TSIG)</i>. </span><span class="pubdate">May 2000. </span></p>
+<a name="id2601546"></a><p>[<abbr class="abbrev">RFC2845</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>, <span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, and <span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secret Key Transaction Authentication for <acronym class="acronym">DNS</acronym> (TSIG)</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601416"></a><p>[<abbr class="abbrev">RFC2930</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secret Key Establishment for DNS (TKEY RR)</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2601608"></a><p>[<abbr class="abbrev">RFC2930</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secret Key Establishment for DNS (TKEY RR)</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601446"></a><p>[<abbr class="abbrev">RFC2931</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DNS Request and Transaction Signatures (SIG(0)s)</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2601638"></a><p>[<abbr class="abbrev">RFC2931</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DNS Request and Transaction Signatures (SIG(0)s)</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601476"></a><p>[<abbr class="abbrev">RFC3007</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secure Domain Name System (DNS) Dynamic Update</i>. </span><span class="pubdate">November 2000. </span></p>
+<a name="id2601668"></a><p>[<abbr class="abbrev">RFC3007</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secure Domain Name System (DNS) Dynamic Update</i>. </span><span class="pubdate">November 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601502"></a><p>[<abbr class="abbrev">RFC3645</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Kwan</span>, <span class="firstname">P.</span> <span class="surname">Garg</span>, <span class="firstname">J.</span> <span class="surname">Gilroy</span>, <span class="firstname">L.</span> <span class="surname">Esibov</span>, <span class="firstname">J.</span> <span class="surname">Westhead</span>, and <span class="firstname">R.</span> <span class="surname">Hall</span>. </span><span class="title"><i>Generic Security Service Algorithm for Secret
+<a name="id2601694"></a><p>[<abbr class="abbrev">RFC3645</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Kwan</span>, <span class="firstname">P.</span> <span class="surname">Garg</span>, <span class="firstname">J.</span> <span class="surname">Gilroy</span>, <span class="firstname">L.</span> <span class="surname">Esibov</span>, <span class="firstname">J.</span> <span class="surname">Westhead</span>, and <span class="firstname">R.</span> <span class="surname">Hall</span>. </span><span class="title"><i>Generic Security Service Algorithm for Secret
Key Transaction Authentication for DNS
(GSS-TSIG)</i>. </span><span class="pubdate">October 2003. </span></p>
</div>
@@ -312,19 +312,19 @@
<h3 class="title">
<acronym class="acronym">DNS</acronym> Security Proposed Standards</h3>
<div class="biblioentry">
-<a name="id2601585"></a><p>[<abbr class="abbrev">RFC3225</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Conrad</span>. </span><span class="title"><i>Indicating Resolver Support of DNSSEC</i>. </span><span class="pubdate">December 2001. </span></p>
+<a name="id2601777"></a><p>[<abbr class="abbrev">RFC3225</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Conrad</span>. </span><span class="title"><i>Indicating Resolver Support of DNSSEC</i>. </span><span class="pubdate">December 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601611"></a><p>[<abbr class="abbrev">RFC3833</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Atkins</span> and <span class="firstname">R.</span> <span class="surname">Austein</span>. </span><span class="title"><i>Threat Analysis of the Domain Name System (DNS)</i>. </span><span class="pubdate">August 2004. </span></p>
+<a name="id2601803"></a><p>[<abbr class="abbrev">RFC3833</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Atkins</span> and <span class="firstname">R.</span> <span class="surname">Austein</span>. </span><span class="title"><i>Threat Analysis of the Domain Name System (DNS)</i>. </span><span class="pubdate">August 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601648"></a><p>[<abbr class="abbrev">RFC4033</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>DNS Security Introduction and Requirements</i>. </span><span class="pubdate">March 2005. </span></p>
+<a name="id2601840"></a><p>[<abbr class="abbrev">RFC4033</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>DNS Security Introduction and Requirements</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601713"></a><p>[<abbr class="abbrev">RFC4034</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Resource Records for the DNS Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
+<a name="id2601905"></a><p>[<abbr class="abbrev">RFC4034</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Resource Records for the DNS Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601778"></a><p>[<abbr class="abbrev">RFC4035</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Protocol Modifications for the DNS
+<a name="id2601970"></a><p>[<abbr class="abbrev">RFC4035</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Protocol Modifications for the DNS
Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
</div>
@@ -332,146 +332,146 @@
<h3 class="title">Other Important RFCs About <acronym class="acronym">DNS</acronym>
Implementation</h3>
<div class="biblioentry">
-<a name="id2601851"></a><p>[<abbr class="abbrev">RFC1535</abbr>] <span class="author"><span class="firstname">E.</span> <span class="surname">Gavron</span>. </span><span class="title"><i>A Security Problem and Proposed Correction With Widely
+<a name="id2602043"></a><p>[<abbr class="abbrev">RFC1535</abbr>] <span class="author"><span class="firstname">E.</span> <span class="surname">Gavron</span>. </span><span class="title"><i>A Security Problem and Proposed Correction With Widely
Deployed <acronym class="acronym">DNS</acronym> Software.</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601877"></a><p>[<abbr class="abbrev">RFC1536</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Kumar</span>, <span class="firstname">J.</span> <span class="surname">Postel</span>, <span class="firstname">C.</span> <span class="surname">Neuman</span>, <span class="firstname">P.</span> <span class="surname">Danzig</span>, and <span class="firstname">S.</span> <span class="surname">Miller</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Implementation
+<a name="id2602069"></a><p>[<abbr class="abbrev">RFC1536</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Kumar</span>, <span class="firstname">J.</span> <span class="surname">Postel</span>, <span class="firstname">C.</span> <span class="surname">Neuman</span>, <span class="firstname">P.</span> <span class="surname">Danzig</span>, and <span class="firstname">S.</span> <span class="surname">Miller</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Implementation
Errors and Suggested Fixes</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601945"></a><p>[<abbr class="abbrev">RFC1982</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Elz</span> and <span class="firstname">R.</span> <span class="surname">Bush</span>. </span><span class="title"><i>Serial Number Arithmetic</i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2602137"></a><p>[<abbr class="abbrev">RFC1982</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Elz</span> and <span class="firstname">R.</span> <span class="surname">Bush</span>. </span><span class="title"><i>Serial Number Arithmetic</i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601980"></a><p>[<abbr class="abbrev">RFC4074</abbr>] <span class="authorgroup"><span class="firstname">Y.</span> <span class="surname">Morishita</span> and <span class="firstname">T.</span> <span class="surname">Jinmei</span>. </span><span class="title"><i>Common Misbehaviour Against <acronym class="acronym">DNS</acronym>
+<a name="id2602172"></a><p>[<abbr class="abbrev">RFC4074</abbr>] <span class="authorgroup"><span class="firstname">Y.</span> <span class="surname">Morishita</span> and <span class="firstname">T.</span> <span class="surname">Jinmei</span>. </span><span class="title"><i>Common Misbehaviour Against <acronym class="acronym">DNS</acronym>
Queries for IPv6 Addresses</i>. </span><span class="pubdate">May 2005. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Resource Record Types</h3>
<div class="biblioentry">
-<a name="id2602094"></a><p>[<abbr class="abbrev">RFC1183</abbr>] <span class="authorgroup"><span class="firstname">C.F.</span> <span class="surname">Everhart</span>, <span class="firstname">L. A.</span> <span class="surname">Mamakos</span>, <span class="firstname">R.</span> <span class="surname">Ullmann</span>, and <span class="firstname">P.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>New <acronym class="acronym">DNS</acronym> RR Definitions</i>. </span><span class="pubdate">October 1990. </span></p>
+<a name="id2602218"></a><p>[<abbr class="abbrev">RFC1183</abbr>] <span class="authorgroup"><span class="firstname">C.F.</span> <span class="surname">Everhart</span>, <span class="firstname">L. A.</span> <span class="surname">Mamakos</span>, <span class="firstname">R.</span> <span class="surname">Ullmann</span>, and <span class="firstname">P.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>New <acronym class="acronym">DNS</acronym> RR Definitions</i>. </span><span class="pubdate">October 1990. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602152"></a><p>[<abbr class="abbrev">RFC1706</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">R.</span> <span class="surname">Colella</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> NSAP Resource Records</i>. </span><span class="pubdate">October 1994. </span></p>
+<a name="id2602276"></a><p>[<abbr class="abbrev">RFC1706</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">R.</span> <span class="surname">Colella</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> NSAP Resource Records</i>. </span><span class="pubdate">October 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602189"></a><p>[<abbr class="abbrev">RFC2168</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Daniel</span> and <span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="title"><i>Resolution of Uniform Resource Identifiers using
+<a name="id2602313"></a><p>[<abbr class="abbrev">RFC2168</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Daniel</span> and <span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="title"><i>Resolution of Uniform Resource Identifiers using
the Domain Name System</i>. </span><span class="pubdate">June 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602225"></a><p>[<abbr class="abbrev">RFC1876</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Davis</span>, <span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">T.</span>, and <span class="firstname">I.</span> <span class="surname">Dickinson</span>. </span><span class="title"><i>A Means for Expressing Location Information in the
+<a name="id2602348"></a><p>[<abbr class="abbrev">RFC1876</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Davis</span>, <span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">T.</span>, and <span class="firstname">I.</span> <span class="surname">Dickinson</span>. </span><span class="title"><i>A Means for Expressing Location Information in the
Domain
Name System</i>. </span><span class="pubdate">January 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602279"></a><p>[<abbr class="abbrev">RFC2052</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A <acronym class="acronym">DNS</acronym> RR for Specifying the
+<a name="id2602403"></a><p>[<abbr class="abbrev">RFC2052</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A <acronym class="acronym">DNS</acronym> RR for Specifying the
Location of
Services.</i>. </span><span class="pubdate">October 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602317"></a><p>[<abbr class="abbrev">RFC2163</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Allocchio</span>. </span><span class="title"><i>Using the Internet <acronym class="acronym">DNS</acronym> to
+<a name="id2602441"></a><p>[<abbr class="abbrev">RFC2163</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Allocchio</span>. </span><span class="title"><i>Using the Internet <acronym class="acronym">DNS</acronym> to
Distribute MIXER
Conformant Global Address Mapping</i>. </span><span class="pubdate">January 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602343"></a><p>[<abbr class="abbrev">RFC2230</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Atkinson</span>. </span><span class="title"><i>Key Exchange Delegation Record for the <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">October 1997. </span></p>
+<a name="id2602467"></a><p>[<abbr class="abbrev">RFC2230</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Atkinson</span>. </span><span class="title"><i>Key Exchange Delegation Record for the <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">October 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602369"></a><p>[<abbr class="abbrev">RFC2536</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DSA KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2602492"></a><p>[<abbr class="abbrev">RFC2536</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DSA KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602395"></a><p>[<abbr class="abbrev">RFC2537</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2602519"></a><p>[<abbr class="abbrev">RFC2537</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602422"></a><p>[<abbr class="abbrev">RFC2538</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Storing Certificates in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2602546"></a><p>[<abbr class="abbrev">RFC2538</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Storing Certificates in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602461"></a><p>[<abbr class="abbrev">RFC2539</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Storage of Diffie-Hellman Keys in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2602585"></a><p>[<abbr class="abbrev">RFC2539</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Storage of Diffie-Hellman Keys in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602491"></a><p>[<abbr class="abbrev">RFC2540</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Detached Domain Name System (DNS) Information</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2602615"></a><p>[<abbr class="abbrev">RFC2540</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Detached Domain Name System (DNS) Information</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602521"></a><p>[<abbr class="abbrev">RFC2782</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span>. </span><span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="author"><span class="firstname">L.</span> <span class="surname">Esibov</span>. </span><span class="title"><i>A DNS RR for specifying the location of services (DNS SRV)</i>. </span><span class="pubdate">February 2000. </span></p>
+<a name="id2602645"></a><p>[<abbr class="abbrev">RFC2782</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span>. </span><span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="author"><span class="firstname">L.</span> <span class="surname">Esibov</span>. </span><span class="title"><i>A DNS RR for specifying the location of services (DNS SRV)</i>. </span><span class="pubdate">February 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602564"></a><p>[<abbr class="abbrev">RFC2915</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="author"><span class="firstname">R.</span> <span class="surname">Daniel</span>. </span><span class="title"><i>The Naming Authority Pointer (NAPTR) DNS Resource Record</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2602688"></a><p>[<abbr class="abbrev">RFC2915</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="author"><span class="firstname">R.</span> <span class="surname">Daniel</span>. </span><span class="title"><i>The Naming Authority Pointer (NAPTR) DNS Resource Record</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602597"></a><p>[<abbr class="abbrev">RFC3110</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</i>. </span><span class="pubdate">May 2001. </span></p>
+<a name="id2602721"></a><p>[<abbr class="abbrev">RFC3110</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</i>. </span><span class="pubdate">May 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602624"></a><p>[<abbr class="abbrev">RFC3123</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Koch</span>. </span><span class="title"><i>A DNS RR Type for Lists of Address Prefixes (APL RR)</i>. </span><span class="pubdate">June 2001. </span></p>
+<a name="id2602747"></a><p>[<abbr class="abbrev">RFC3123</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Koch</span>. </span><span class="title"><i>A DNS RR Type for Lists of Address Prefixes (APL RR)</i>. </span><span class="pubdate">June 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602647"></a><p>[<abbr class="abbrev">RFC3596</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">C.</span> <span class="surname">Huitema</span>, <span class="firstname">V.</span> <span class="surname">Ksinant</span>, and <span class="firstname">M.</span> <span class="surname">Souissi</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Extensions to support IP
+<a name="id2602771"></a><p>[<abbr class="abbrev">RFC3596</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">C.</span> <span class="surname">Huitema</span>, <span class="firstname">V.</span> <span class="surname">Ksinant</span>, and <span class="firstname">M.</span> <span class="surname">Souissi</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Extensions to support IP
version 6</i>. </span><span class="pubdate">October 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602705"></a><p>[<abbr class="abbrev">RFC3597</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gustafsson</span>. </span><span class="title"><i>Handling of Unknown DNS Resource Record (RR) Types</i>. </span><span class="pubdate">September 2003. </span></p>
+<a name="id2602828"></a><p>[<abbr class="abbrev">RFC3597</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gustafsson</span>. </span><span class="title"><i>Handling of Unknown DNS Resource Record (RR) Types</i>. </span><span class="pubdate">September 2003. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">
<acronym class="acronym">DNS</acronym> and the Internet</h3>
<div class="biblioentry">
-<a name="id2602737"></a><p>[<abbr class="abbrev">RFC1101</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Network Names
+<a name="id2602860"></a><p>[<abbr class="abbrev">RFC1101</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Network Names
and Other Types</i>. </span><span class="pubdate">April 1989. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602762"></a><p>[<abbr class="abbrev">RFC1123</abbr>] <span class="author"><span class="surname">Braden</span>. </span><span class="title"><i>Requirements for Internet Hosts - Application and
+<a name="id2602886"></a><p>[<abbr class="abbrev">RFC1123</abbr>] <span class="author"><span class="surname">Braden</span>. </span><span class="title"><i>Requirements for Internet Hosts - Application and
Support</i>. </span><span class="pubdate">October 1989. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602785"></a><p>[<abbr class="abbrev">RFC1591</abbr>] <span class="author"><span class="firstname">J.</span> <span class="surname">Postel</span>. </span><span class="title"><i>Domain Name System Structure and Delegation</i>. </span><span class="pubdate">March 1994. </span></p>
+<a name="id2602908"></a><p>[<abbr class="abbrev">RFC1591</abbr>] <span class="author"><span class="firstname">J.</span> <span class="surname">Postel</span>. </span><span class="title"><i>Domain Name System Structure and Delegation</i>. </span><span class="pubdate">March 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602808"></a><p>[<abbr class="abbrev">RFC2317</abbr>] <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Eidnes</span>, <span class="firstname">G.</span> <span class="surname">de Groot</span>, and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Classless IN-ADDR.ARPA Delegation</i>. </span><span class="pubdate">March 1998. </span></p>
+<a name="id2602932"></a><p>[<abbr class="abbrev">RFC2317</abbr>] <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Eidnes</span>, <span class="firstname">G.</span> <span class="surname">de Groot</span>, and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Classless IN-ADDR.ARPA Delegation</i>. </span><span class="pubdate">March 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602854"></a><p>[<abbr class="abbrev">RFC2826</abbr>] <span class="authorgroup"><span class="surname">Internet Architecture Board</span>. </span><span class="title"><i>IAB Technical Comment on the Unique DNS Root</i>. </span><span class="pubdate">May 2000. </span></p>
+<a name="id2603046"></a><p>[<abbr class="abbrev">RFC2826</abbr>] <span class="authorgroup"><span class="surname">Internet Architecture Board</span>. </span><span class="title"><i>IAB Technical Comment on the Unique DNS Root</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602877"></a><p>[<abbr class="abbrev">RFC2929</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, <span class="firstname">E.</span> <span class="surname">Brunner-Williams</span>, and <span class="firstname">B.</span> <span class="surname">Manning</span>. </span><span class="title"><i>Domain Name System (DNS) IANA Considerations</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2603069"></a><p>[<abbr class="abbrev">RFC2929</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, <span class="firstname">E.</span> <span class="surname">Brunner-Williams</span>, and <span class="firstname">B.</span> <span class="surname">Manning</span>. </span><span class="title"><i>Domain Name System (DNS) IANA Considerations</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">
<acronym class="acronym">DNS</acronym> Operations</h3>
<div class="biblioentry">
-<a name="id2602935"></a><p>[<abbr class="abbrev">RFC1033</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Lottor</span>. </span><span class="title"><i>Domain administrators operations guide.</i>. </span><span class="pubdate">November 1987. </span></p>
+<a name="id2603127"></a><p>[<abbr class="abbrev">RFC1033</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Lottor</span>. </span><span class="title"><i>Domain administrators operations guide.</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602958"></a><p>[<abbr class="abbrev">RFC1537</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Beertema</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Data File
+<a name="id2603150"></a><p>[<abbr class="abbrev">RFC1537</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Beertema</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Data File
Configuration Errors</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602985"></a><p>[<abbr class="abbrev">RFC1912</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Barr</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Operational and
+<a name="id2603177"></a><p>[<abbr class="abbrev">RFC1912</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Barr</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Operational and
Configuration Errors</i>. </span><span class="pubdate">February 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603012"></a><p>[<abbr class="abbrev">RFC2010</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Operational Criteria for Root Name Servers.</i>. </span><span class="pubdate">October 1996. </span></p>
+<a name="id2603204"></a><p>[<abbr class="abbrev">RFC2010</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Operational Criteria for Root Name Servers.</i>. </span><span class="pubdate">October 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603048"></a><p>[<abbr class="abbrev">RFC2219</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Hamilton</span> and <span class="firstname">R.</span> <span class="surname">Wright</span>. </span><span class="title"><i>Use of <acronym class="acronym">DNS</acronym> Aliases for
+<a name="id2603240"></a><p>[<abbr class="abbrev">RFC2219</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Hamilton</span> and <span class="firstname">R.</span> <span class="surname">Wright</span>. </span><span class="title"><i>Use of <acronym class="acronym">DNS</acronym> Aliases for
Network Services.</i>. </span><span class="pubdate">October 1997. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Internationalized Domain Names</h3>
<div class="biblioentry">
-<a name="id2603094"></a><p>[<abbr class="abbrev">RFC2825</abbr>] <span class="authorgroup"><span class="surname">IAB</span> and <span class="firstname">R.</span> <span class="surname">Daigle</span>. </span><span class="title"><i>A Tangled Web: Issues of I18N, Domain Names,
+<a name="id2603286"></a><p>[<abbr class="abbrev">RFC2825</abbr>] <span class="authorgroup"><span class="surname">IAB</span> and <span class="firstname">R.</span> <span class="surname">Daigle</span>. </span><span class="title"><i>A Tangled Web: Issues of I18N, Domain Names,
and the Other Internet protocols</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603126"></a><p>[<abbr class="abbrev">RFC3490</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Faltstrom</span>, <span class="firstname">P.</span> <span class="surname">Hoffman</span>, and <span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Internationalizing Domain Names in Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
+<a name="id2603318"></a><p>[<abbr class="abbrev">RFC3490</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Faltstrom</span>, <span class="firstname">P.</span> <span class="surname">Hoffman</span>, and <span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Internationalizing Domain Names in Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603172"></a><p>[<abbr class="abbrev">RFC3491</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Hoffman</span> and <span class="firstname">M.</span> <span class="surname">Blanchet</span>. </span><span class="title"><i>Nameprep: A Stringprep Profile for Internationalized Domain Names</i>. </span><span class="pubdate">March 2003. </span></p>
+<a name="id2603364"></a><p>[<abbr class="abbrev">RFC3491</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Hoffman</span> and <span class="firstname">M.</span> <span class="surname">Blanchet</span>. </span><span class="title"><i>Nameprep: A Stringprep Profile for Internationalized Domain Names</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603207"></a><p>[<abbr class="abbrev">RFC3492</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Punycode: A Bootstring encoding of Unicode
+<a name="id2603399"></a><p>[<abbr class="abbrev">RFC3492</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Punycode: A Bootstring encoding of Unicode
for Internationalized Domain Names in
Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
@@ -487,47 +487,47 @@
</p>
</div>
<div class="biblioentry">
-<a name="id2603252"></a><p>[<abbr class="abbrev">RFC1464</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Rosenbaum</span>. </span><span class="title"><i>Using the Domain Name System To Store Arbitrary String
+<a name="id2603444"></a><p>[<abbr class="abbrev">RFC1464</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Rosenbaum</span>. </span><span class="title"><i>Using the Domain Name System To Store Arbitrary String
Attributes</i>. </span><span class="pubdate">May 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603274"></a><p>[<abbr class="abbrev">RFC1713</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Romao</span>. </span><span class="title"><i>Tools for <acronym class="acronym">DNS</acronym> Debugging</i>. </span><span class="pubdate">November 1994. </span></p>
+<a name="id2603466"></a><p>[<abbr class="abbrev">RFC1713</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Romao</span>. </span><span class="title"><i>Tools for <acronym class="acronym">DNS</acronym> Debugging</i>. </span><span class="pubdate">November 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603300"></a><p>[<abbr class="abbrev">RFC1794</abbr>] <span class="author"><span class="firstname">T.</span> <span class="surname">Brisco</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Support for Load
+<a name="id2603492"></a><p>[<abbr class="abbrev">RFC1794</abbr>] <span class="author"><span class="firstname">T.</span> <span class="surname">Brisco</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Support for Load
Balancing</i>. </span><span class="pubdate">April 1995. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603325"></a><p>[<abbr class="abbrev">RFC2240</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Legal Basis for Domain Name Allocation</i>. </span><span class="pubdate">November 1997. </span></p>
+<a name="id2603517"></a><p>[<abbr class="abbrev">RFC2240</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Legal Basis for Domain Name Allocation</i>. </span><span class="pubdate">November 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603349"></a><p>[<abbr class="abbrev">RFC2345</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>, <span class="firstname">T.</span> <span class="surname">Wolf</span>, and <span class="firstname">G.</span> <span class="surname">Oglesby</span>. </span><span class="title"><i>Domain Names and Company Name Retrieval</i>. </span><span class="pubdate">May 1998. </span></p>
+<a name="id2603541"></a><p>[<abbr class="abbrev">RFC2345</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>, <span class="firstname">T.</span> <span class="surname">Wolf</span>, and <span class="firstname">G.</span> <span class="surname">Oglesby</span>. </span><span class="title"><i>Domain Names and Company Name Retrieval</i>. </span><span class="pubdate">May 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603395"></a><p>[<abbr class="abbrev">RFC2352</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Convention For Using Legal Names as Domain Names</i>. </span><span class="pubdate">May 1998. </span></p>
+<a name="id2603587"></a><p>[<abbr class="abbrev">RFC2352</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Convention For Using Legal Names as Domain Names</i>. </span><span class="pubdate">May 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603418"></a><p>[<abbr class="abbrev">RFC3071</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>. </span><span class="title"><i>Reflections on the DNS, RFC 1591, and Categories of Domains</i>. </span><span class="pubdate">February 2001. </span></p>
+<a name="id2603610"></a><p>[<abbr class="abbrev">RFC3071</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>. </span><span class="title"><i>Reflections on the DNS, RFC 1591, and Categories of Domains</i>. </span><span class="pubdate">February 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603445"></a><p>[<abbr class="abbrev">RFC3258</abbr>] <span class="authorgroup"><span class="firstname">T.</span> <span class="surname">Hardie</span>. </span><span class="title"><i>Distributing Authoritative Name Servers via
+<a name="id2603637"></a><p>[<abbr class="abbrev">RFC3258</abbr>] <span class="authorgroup"><span class="firstname">T.</span> <span class="surname">Hardie</span>. </span><span class="title"><i>Distributing Authoritative Name Servers via
Shared Unicast Addresses</i>. </span><span class="pubdate">April 2002. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603470"></a><p>[<abbr class="abbrev">RFC3901</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Durand</span> and <span class="firstname">J.</span> <span class="surname">Ihren</span>. </span><span class="title"><i>DNS IPv6 Transport Operational Guidelines</i>. </span><span class="pubdate">September 2004. </span></p>
+<a name="id2603662"></a><p>[<abbr class="abbrev">RFC3901</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Durand</span> and <span class="firstname">J.</span> <span class="surname">Ihren</span>. </span><span class="title"><i>DNS IPv6 Transport Operational Guidelines</i>. </span><span class="pubdate">September 2004. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Obsolete and Unimplemented Experimental RFC</h3>
<div class="biblioentry">
-<a name="id2603514"></a><p>[<abbr class="abbrev">RFC1712</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Farrell</span>, <span class="firstname">M.</span> <span class="surname">Schulze</span>, <span class="firstname">S.</span> <span class="surname">Pleitner</span>, and <span class="firstname">D.</span> <span class="surname">Baldoni</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Geographical
+<a name="id2603706"></a><p>[<abbr class="abbrev">RFC1712</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Farrell</span>, <span class="firstname">M.</span> <span class="surname">Schulze</span>, <span class="firstname">S.</span> <span class="surname">Pleitner</span>, and <span class="firstname">D.</span> <span class="surname">Baldoni</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Geographical
Location</i>. </span><span class="pubdate">November 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603572"></a><p>[<abbr class="abbrev">RFC2673</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Binary Labels in the Domain Name System</i>. </span><span class="pubdate">August 1999. </span></p>
+<a name="id2603764"></a><p>[<abbr class="abbrev">RFC2673</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Binary Labels in the Domain Name System</i>. </span><span class="pubdate">August 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603598"></a><p>[<abbr class="abbrev">RFC2874</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span> and <span class="firstname">C.</span> <span class="surname">Huitema</span>. </span><span class="title"><i>DNS Extensions to Support IPv6 Address Aggregation
+<a name="id2603790"></a><p>[<abbr class="abbrev">RFC2874</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span> and <span class="firstname">C.</span> <span class="surname">Huitema</span>. </span><span class="title"><i>DNS Extensions to Support IPv6 Address Aggregation
and Renumbering</i>. </span><span class="pubdate">July 2000. </span></p>
</div>
</div>
@@ -541,39 +541,39 @@
</p>
</div>
<div class="biblioentry">
-<a name="id2603646"></a><p>[<abbr class="abbrev">RFC2065</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">C.</span> <span class="surname">Kaufman</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">January 1997. </span></p>
+<a name="id2603907"></a><p>[<abbr class="abbrev">RFC2065</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">C.</span> <span class="surname">Kaufman</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">January 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603686"></a><p>[<abbr class="abbrev">RFC2137</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secure Domain Name System Dynamic Update</i>. </span><span class="pubdate">April 1997. </span></p>
+<a name="id2603946"></a><p>[<abbr class="abbrev">RFC2137</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secure Domain Name System Dynamic Update</i>. </span><span class="pubdate">April 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603713"></a><p>[<abbr class="abbrev">RFC2535</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2603973"></a><p>[<abbr class="abbrev">RFC2535</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603742"></a><p>[<abbr class="abbrev">RFC3008</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Domain Name System Security (DNSSEC)
+<a name="id2604003"></a><p>[<abbr class="abbrev">RFC3008</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Domain Name System Security (DNSSEC)
Signing Authority</i>. </span><span class="pubdate">November 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603768"></a><p>[<abbr class="abbrev">RFC3090</abbr>] <span class="authorgroup"><span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>DNS Security Extension Clarification on Zone Status</i>. </span><span class="pubdate">March 2001. </span></p>
+<a name="id2604028"></a><p>[<abbr class="abbrev">RFC3090</abbr>] <span class="authorgroup"><span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>DNS Security Extension Clarification on Zone Status</i>. </span><span class="pubdate">March 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603795"></a><p>[<abbr class="abbrev">RFC3445</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Massey</span> and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Limiting the Scope of the KEY Resource Record (RR)</i>. </span><span class="pubdate">December 2002. </span></p>
+<a name="id2604055"></a><p>[<abbr class="abbrev">RFC3445</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Massey</span> and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Limiting the Scope of the KEY Resource Record (RR)</i>. </span><span class="pubdate">December 2002. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603831"></a><p>[<abbr class="abbrev">RFC3655</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Redefinition of DNS Authenticated Data (AD) bit</i>. </span><span class="pubdate">November 2003. </span></p>
+<a name="id2604091"></a><p>[<abbr class="abbrev">RFC3655</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Redefinition of DNS Authenticated Data (AD) bit</i>. </span><span class="pubdate">November 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603867"></a><p>[<abbr class="abbrev">RFC3658</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Delegation Signer (DS) Resource Record (RR)</i>. </span><span class="pubdate">December 2003. </span></p>
+<a name="id2604128"></a><p>[<abbr class="abbrev">RFC3658</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Delegation Signer (DS) Resource Record (RR)</i>. </span><span class="pubdate">December 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603894"></a><p>[<abbr class="abbrev">RFC3755</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Weiler</span>. </span><span class="title"><i>Legacy Resolver Compatibility for Delegation Signer (DS)</i>. </span><span class="pubdate">May 2004. </span></p>
+<a name="id2604154"></a><p>[<abbr class="abbrev">RFC3755</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Weiler</span>. </span><span class="title"><i>Legacy Resolver Compatibility for Delegation Signer (DS)</i>. </span><span class="pubdate">May 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603921"></a><p>[<abbr class="abbrev">RFC3757</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Kolkman</span>, <span class="firstname">J.</span> <span class="surname">Schlyter</span>, and <span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>Domain Name System KEY (DNSKEY) Resource Record
+<a name="id2604181"></a><p>[<abbr class="abbrev">RFC3757</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Kolkman</span>, <span class="firstname">J.</span> <span class="surname">Schlyter</span>, and <span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>Domain Name System KEY (DNSKEY) Resource Record
(RR) Secure Entry Point (SEP) Flag</i>. </span><span class="pubdate">April 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603965"></a><p>[<abbr class="abbrev">RFC3845</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Schlyter</span>. </span><span class="title"><i>DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format</i>. </span><span class="pubdate">August 2004. </span></p>
+<a name="id2604226"></a><p>[<abbr class="abbrev">RFC3845</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Schlyter</span>. </span><span class="title"><i>DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format</i>. </span><span class="pubdate">August 2004. </span></p>
</div>
</div>
</div>
@@ -594,14 +594,14 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2604007"></a>Other Documents About <acronym class="acronym">BIND</acronym>
+<a name="id2604267"></a>Other Documents About <acronym class="acronym">BIND</acronym>
</h3></div></div></div>
<p></p>
<div class="bibliography">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2604017"></a>Bibliography</h4></div></div></div>
+<a name="id2604277"></a>Bibliography</h4></div></div></div>
<div class="biblioentry">
-<a name="id2604019"></a><p><span class="authorgroup"><span class="firstname">Paul</span> <span class="surname">Albitz</span> and <span class="firstname">Cricket</span> <span class="surname">Liu</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></i>. </span><span class="copyright">Copyright © 1998 Sebastopol, CA: O'Reilly and Associates. </span></p>
+<a name="id2604279"></a><p><span class="authorgroup"><span class="firstname">Paul</span> <span class="surname">Albitz</span> and <span class="firstname">Cricket</span> <span class="surname">Liu</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></i>. </span><span class="copyright">Copyright © 1998 Sebastopol, CA: O'Reilly and Associates. </span></p>
</div>
</div>
</div>
diff --git a/doc/arm/Bv9ARM.html b/doc/arm/Bv9ARM.html
index 7f3d40e9..65c51472 100644
--- a/doc/arm/Bv9ARM.html
+++ b/doc/arm/Bv9ARM.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.html,v 1.220 2009/07/19 04:27:55 tbox Exp $ -->
+<!-- $Id: Bv9ARM.html,v 1.222 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -111,15 +111,15 @@
<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571813">Signing the Zone</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571894">Configuring Servers</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572064">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572076">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572262">Address Lookups Using AAAA Records</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572283">Address to Name Lookups Using Nibble Format</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564083">Address Lookups Using AAAA Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564104">Address to Name Lookups Using Nibble Format</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch05.html">5. The <acronym class="acronym">BIND</acronym> 9 Lightweight Resolver</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572316">The Lightweight Resolver Library</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2564137">The Lightweight Resolver Library</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch05.html#lwresd">Running a Resolver Daemon</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch06.html">6. <acronym class="acronym">BIND</acronym> 9 Configuration Reference</a></span></dt>
@@ -127,55 +127,58 @@
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#configuration_file_elements">Configuration File Elements</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#address_match_lists">Address Match Lists</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573863">Comment Syntax</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573876">Comment Syntax</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#Configuration_File_Grammar">Configuration File Grammar</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574562"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574598"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#acl"><span><strong class="command">acl</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574752"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574788"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#controls_statement_definition_and_usage"><span><strong class="command">controls</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575179"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575196"><span><strong class="command">include</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575216"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575233"><span><strong class="command">include</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575220"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575243"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575334"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575460"><span><strong class="command">logging</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575256"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575280"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575370"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575496"><span><strong class="command">logging</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577527"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577601"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577665"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577708"><span><strong class="command">masters</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577495"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577569"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577633"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577676"><span><strong class="command">masters</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577723"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577691"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#options"><span><strong class="command">options</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_grammar"><span><strong class="command">server</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_definition_and_usage"><span><strong class="command">server</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#statschannels"><span><strong class="command">statistics-channels</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587578"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587559"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587733"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587784"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587645"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587765"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+ and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587812"><span><strong class="command">managed-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587931"><span><strong class="command">managed-keys</strong></span> Statement Definition
and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#view_statement_grammar"><span><strong class="command">view</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588025"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588149"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zone_statement_grammar"><span><strong class="command">zone</strong></span>
Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589433"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589693"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2592136">Zone File</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2592396">Zone File</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#types_of_resource_records_and_when_to_use_them">Types of Resource Records and When to Use Them</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594366">Discussion of MX Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594627">Discussion of MX Records</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#Setting_TTLs">Setting TTLs</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594914">Inverse Mapping in IPv4</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595109">Other Zone File Directives</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595450"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595174">Inverse Mapping in IPv4</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595301">Other Zone File Directives</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2595574"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zonefile_format">Additional File Formats</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#statistics">BIND9 Statistics</a></span></dt>
@@ -184,31 +187,31 @@
<dt><span class="chapter"><a href="Bv9ARM.ch07.html">7. <acronym class="acronym">BIND</acronym> 9 Security Considerations</a></span></dt>
<dd><dl>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#Access_Control_Lists">Access Control Lists</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2600034"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2600294"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600115">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600174">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600375">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2600435">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#dynamic_update_security">Dynamic Update Security</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch08.html">8. Troubleshooting</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600323">Common Problems</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2600328">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600340">Incrementing and Changing the Serial Number</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600493">Where Can I Get Help?</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600583">Common Problems</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2600588">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600600">Incrementing and Changing the Serial Number</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2600617">Where Can I Get Help?</a></span></dt>
</dl></dd>
<dt><span class="appendix"><a href="Bv9ARM.ch09.html">A. Appendices</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600555">Acknowledgments</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600747">Acknowledgments</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#historical_dns_information">A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600659">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2600987">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#ipv6addresses">IPv6 addresses (AAAA)</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bibliography">Bibliography (and Suggested Reading)</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#rfcs">Request for Comments (RFCs)</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#internet_drafts">Internet Drafts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2604007">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2604267">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="reference"><a href="Bv9ARM.ch10.html">I. Manual pages</a></span></dt>
diff --git a/doc/arm/man.ddns-confgen.html b/doc/arm/man.ddns-confgen.html
index 2daff74c..f25b277d 100644
--- a/doc/arm/man.ddns-confgen.html
+++ b/doc/arm/man.ddns-confgen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.ddns-confgen.html,v 1.13 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.ddns-confgen.html,v 1.18 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -48,7 +48,7 @@
<div class="cmdsynopsis"><p><code class="command">ddns-confgen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [<code class="option">-s name | -z zone</code>] [<code class="option">-q</code>] [name]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2634677"></a><h2>DESCRIPTION</h2>
+<a name="id2637892"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">ddns-confgen</strong></span>
generates a key for use by <span><strong class="command">nsupdate</strong></span>
and <span><strong class="command">named</strong></span>. It simplifies configuration
@@ -75,7 +75,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2634764"></a><h2>OPTIONS</h2>
+<a name="id2637979"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd><p>
@@ -142,7 +142,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2635033"></a><h2>SEE ALSO</h2>
+<a name="id2638248"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">nsupdate</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -150,7 +150,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2635072"></a><h2>AUTHOR</h2>
+<a name="id2638286"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dig.html b/doc/arm/man.dig.html
index d4f981c8..807c025f 100644
--- a/doc/arm/man.dig.html
+++ b/doc/arm/man.dig.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dig.html,v 1.120 2009/07/19 04:27:56 tbox Exp $ -->
+<!-- $Id: man.dig.html,v 1.122 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -52,7 +52,7 @@
<div class="cmdsynopsis"><p><code class="command">dig</code> [global-queryopt...] [query...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2563941"></a><h2>DESCRIPTION</h2>
+<a name="id2563928"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dig</strong></span>
(domain information groper) is a flexible tool
for interrogating DNS name servers. It performs DNS lookups and
@@ -98,7 +98,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2573184"></a><h2>SIMPLE USAGE</h2>
+<a name="id2572147"></a><h2>SIMPLE USAGE</h2>
<p>
A typical invocation of <span><strong class="command">dig</strong></span> looks like:
</p>
@@ -144,7 +144,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2573294"></a><h2>OPTIONS</h2>
+<a name="id2572326"></a><h2>OPTIONS</h2>
<p>
The <code class="option">-b</code> option sets the source IP address of the query
to <em class="parameter"><code>address</code></em>. This must be a valid
@@ -248,7 +248,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631322"></a><h2>QUERY OPTIONS</h2>
+<a name="id2631446"></a><h2>QUERY OPTIONS</h2>
<p><span><strong class="command">dig</strong></span>
provides a number of query options which affect
the way in which lookups are made and the results displayed. Some of
@@ -573,7 +573,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2632391"></a><h2>MULTIPLE QUERIES</h2>
+<a name="id2632378"></a><h2>MULTIPLE QUERIES</h2>
<p>
The BIND 9 implementation of <span><strong class="command">dig </strong></span>
supports
@@ -619,7 +619,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2632476"></a><h2>IDN SUPPORT</h2>
+<a name="id2632532"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">dig</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -633,14 +633,14 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2632505"></a><h2>FILES</h2>
+<a name="id2632561"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
<p><code class="filename">${HOME}/.digrc</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2632526"></a><h2>SEE ALSO</h2>
+<a name="id2632650"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">host</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
@@ -648,7 +648,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2632564"></a><h2>BUGS</h2>
+<a name="id2632688"></a><h2>BUGS</h2>
<p>
There are probably too many query options.
</p>
diff --git a/doc/arm/man.dnssec-dsfromkey.html b/doc/arm/man.dnssec-dsfromkey.html
index c6621d4a..b56ca825 100644
--- a/doc/arm/man.dnssec-dsfromkey.html
+++ b/doc/arm/man.dnssec-dsfromkey.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-dsfromkey.html,v 1.32 2009/07/19 04:27:55 tbox Exp $ -->
+<!-- $Id: man.dnssec-dsfromkey.html,v 1.35 2009/09/03 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,18 +47,18 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] {keyfile}</p></div>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] {keyfile}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2605187"></a><h2>DESCRIPTION</h2>
+<a name="id2605501"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-dsfromkey</strong></span>
outputs the Delegation Signer (DS) resource record (RR), as defined in
RFC 3658 and RFC 4509, for the given key(s).
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605201"></a><h2>OPTIONS</h2>
+<a name="id2605515"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-1</span></dt>
<dd><p>
@@ -99,6 +99,8 @@
Generate a DLV set instead of a DS set. The specified
<code class="option">domain</code> is appended to the name for each
record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</p></dd>
<dt><span class="term">-s</span></dt>
<dd><p>
@@ -117,7 +119,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2605526"></a><h2>EXAMPLE</h2>
+<a name="id2605909"></a><h2>EXAMPLE</h2>
<p>
To build the SHA-256 DS RR from the
<strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
@@ -132,7 +134,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605562"></a><h2>FILES</h2>
+<a name="id2605945"></a><h2>FILES</h2>
<p>
The keyfile can be designed by the key identification
<code class="filename">Knnnn.+aaa+iiiii</code> or the full file name
@@ -146,22 +148,23 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605604"></a><h2>CAVEAT</h2>
+<a name="id2605987"></a><h2>CAVEAT</h2>
<p>
A keyfile error can give a "file not found" even if the file exists.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605613"></a><h2>SEE ALSO</h2>
+<a name="id2605996"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 3658</em>,
+ <em class="citetitle">RFC 4431</em>.
<em class="citetitle">RFC 4509</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605650"></a><h2>AUTHOR</h2>
+<a name="id2606036"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-keyfromlabel.html b/doc/arm/man.dnssec-keyfromlabel.html
index cf9ce003..d177445b 100644
--- a/doc/arm/man.dnssec-keyfromlabel.html
+++ b/doc/arm/man.dnssec-keyfromlabel.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-keyfromlabel.html,v 1.58 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.dnssec-keyfromlabel.html,v 1.62 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,25 +47,30 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-U <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2605858"></a><h2>DESCRIPTION</h2>
+<a name="id2606265"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605872"></a><h2>OPTIONS</h2>
+<a name="id2606285"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5 (RSA)
- or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5 (RSA),
+ RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
These values are case insensitive.
</p>
<p>
@@ -88,8 +93,17 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keyfromlabel</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
@@ -99,12 +113,12 @@
<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
<dd><p>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
</p></dd>
<dt><span class="term">-h</span></dt>
<dd><p>
Prints a short summary of the options and arguments to
- <span><strong class="command">dnssec-keygen</strong></span>.
+ <span><strong class="command">dnssec-keyfromlabel</strong></span>.
</p></dd>
<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
@@ -116,7 +130,7 @@
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -135,7 +149,54 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2606221"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2607204"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included and the zone and used to sign
+ it.
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-U <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be unpublished. After that
+ date, the key will no longer be included in the zone, but it
+ may remain in the key repository.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key can be removed from the key repository.
+ NOTE: Keys are not currently deleted automatically; this field
+ is included for informational purposes and for future
+ development.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2609077"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -147,8 +208,7 @@
<li><p><code class="filename">nnnn</code> is the key name.
</p></li>
<li><p><code class="filename">aaa</code> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</p></li>
<li><p><code class="filename">iiiii</code> is the key identifier (or
footprint).
@@ -159,8 +219,7 @@
on the printed string. <code class="filename">Knnnn.+aaa+iiiii.key</code>
contains the public key, and
<code class="filename">Knnnn.+aaa+iiiii.private</code> contains the
- private
- key.
+ private key.
</p>
<p>
The <code class="filename">.key</code> file contains a DNS KEY record
@@ -169,14 +228,14 @@
statement).
</p>
<p>
- The <code class="filename">.private</code> file contains algorithm
- specific
+ The <code class="filename">.private</code> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2606452"></a><h2>SEE ALSO</h2>
+<a name="id2609171"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -186,7 +245,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2606560"></a><h2>AUTHOR</h2>
+<a name="id2609210"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-keygen.html b/doc/arm/man.dnssec-keygen.html
index 0f90985c..fefeaa78 100644
--- a/doc/arm/man.dnssec-keygen.html
+++ b/doc/arm/man.dnssec-keygen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-keygen.html,v 1.125 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.dnssec-keygen.html,v 1.130 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,16 +50,21 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-3</code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-C</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k</code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-U <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2607382"></a><h2>DESCRIPTION</h2>
+<a name="id2607937"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keygen</strong></span>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
(Transaction Key) as defined in RFC 2930.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. For DNSSEC keys, this must match the name of the zone for
+ which the key is being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2607396"></a><h2>OPTIONS</h2>
+<a name="id2607957"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
@@ -221,14 +226,16 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610500"></a><h2>TIMING OPTIONS</h2>
+<a name="id2659667"></a><h2>TIMING OPTIONS</h2>
<p>
Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
If the argument begins with a '+' or '-', it is interpreted as
- an offset from the present time. If such an offset is followed
- by one of the characters 'y', 'm', 'w', 'd', or 'h', then the
- offset is computed in years, months, weeks, days, or hours,
- respectively; otherwise it is computed in seconds.
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
</p>
<div class="variablelist"><dl>
<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
@@ -266,7 +273,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2659409"></a><h2>GENERATED KEYS</h2>
+<a name="id2659765"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -312,7 +319,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659516"></a><h2>EXAMPLE</h2>
+<a name="id2659873"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -333,7 +340,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659573"></a><h2>SEE ALSO</h2>
+<a name="id2659997"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
@@ -342,7 +349,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659672"></a><h2>AUTHOR</h2>
+<a name="id2660028"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-revoke.html b/doc/arm/man.dnssec-revoke.html
index d2f8c780..4020c1a0 100644
--- a/doc/arm/man.dnssec-revoke.html
+++ b/doc/arm/man.dnssec-revoke.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-revoke.html,v 1.9 2009/07/21 07:02:09 tbox Exp $ -->
+<!-- $Id: man.dnssec-revoke.html,v 1.14 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-revoke</code> [<code class="option">-hr</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-f</code>] {keyfile}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608416"></a><h2>DESCRIPTION</h2>
+<a name="id2608697"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-revoke</strong></span>
reads a DNSSEC key file, sets the REVOKED bit on the key as defined
in RFC 5011, and creates a new pair of key files containing the
@@ -58,7 +58,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608429"></a><h2>OPTIONS</h2>
+<a name="id2608711"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-h</span></dt>
<dd><p>
@@ -86,14 +86,14 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608520"></a><h2>SEE ALSO</h2>
+<a name="id2608802"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 5011</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608545"></a><h2>AUTHOR</h2>
+<a name="id2608826"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-settime.html b/doc/arm/man.dnssec-settime.html
index 7f91c320..c02f1d8e 100644
--- a/doc/arm/man.dnssec-settime.html
+++ b/doc/arm/man.dnssec-settime.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-settime.html,v 1.3 2009/07/21 07:02:09 tbox Exp $ -->
+<!-- $Id: man.dnssec-settime.html,v 1.8 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-settime</code> [<code class="option">-fr</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-U <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-h</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {keyfile}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608948"></a><h2>DESCRIPTION</h2>
+<a name="id2609514"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-settime</strong></span>
reads a DNSSEC private key file and sets the key timing metadata
as specified by the <code class="option">-P</code>, <code class="option">-A</code>,
@@ -75,7 +75,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2609006"></a><h2>OPTIONS</h2>
+<a name="id2609641"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-f</span></dt>
<dd><p>
@@ -101,14 +101,16 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2609083"></a><h2>TIMING OPTIONS</h2>
+<a name="id2609718"></a><h2>TIMING OPTIONS</h2>
<p>
Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
If the argument begins with a '+' or '-', it is interpreted as
- an offset from the present time. If such an offset is followed
- by one of the characters 'y', 'm', 'w', 'd', or 'h', then the
- offset is computed in years, months, weeks, days, or hours,
- respectively; otherwise it is computed in seconds.
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
</p>
<div class="variablelist"><dl>
<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
@@ -146,7 +148,33 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2609181"></a><h2>SEE ALSO</h2>
+<a name="id2609816"></a><h2>PRINTING OPTIONS</h2>
+<p>
+ <span><strong class="command">dnssec-settime</strong></span> can also be used to print the
+ timing metadata associated with a key.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Print times in UNIX epoch format.
+ </p></dd>
+<dt><span class="term">-p <em class="replaceable"><code>C/P/A/R/U/D/all</code></em></span></dt>
+<dd><p>
+ Print a specific metadata value or set of metadata values.
+ The <code class="option">-p</code> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <code class="option">C</code> for the creation date,
+ <code class="option">P</code> for the publication date,
+ <code class="option">A</code> for the activation date,
+ <code class="option">R</code> for the revokation date,
+ <code class="option">U</code> for the unpublication date, or
+ <code class="option">D</code> for the deletion date.
+ To print all of the metadata, use <code class="option">-p all</code>.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2609896"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -154,7 +182,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2609214"></a><h2>AUTHOR</h2>
+<a name="id2609929"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-signzone.html b/doc/arm/man.dnssec-signzone.html
index ce90b1e3..3e52b6a5 100644
--- a/doc/arm/man.dnssec-signzone.html
+++ b/doc/arm/man.dnssec-signzone.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-signzone.html,v 1.124 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.dnssec-signzone.html,v 1.129 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S</code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-T <em class="replaceable"><code>ttl</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610791"></a><h2>DESCRIPTION</h2>
+<a name="id2611403"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-signzone</strong></span>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
@@ -61,7 +61,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2610810"></a><h2>OPTIONS</h2>
+<a name="id2611422"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -71,6 +71,15 @@
<dd><p>
Specifies the DNS class of the zone.
</p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: Generate a
+ <code class="filename">keyset-<em class="replaceable"><code>zonename</code></em></code>
+ file in addition to
+ <code class="filename">dsset-<em class="replaceable"><code>zonename</code></em></code>
+ when signing a zone, for use by older versions of
+ <span><strong class="command">dnssec-signzone</strong></span>.
+ </p></dd>
<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
Look for <code class="filename">dsset-</code> or
@@ -117,6 +126,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <code class="option">end-time</code> is
specified, 30 days from the start time is used as a default.
+ <code class="option">end-time</code> must be later than
+ <code class="option">start-time</code>.
</p></dd>
<dt><span class="term">-f <em class="replaceable"><code>output-file</code></em></span></dt>
<dd><p>
@@ -297,8 +308,15 @@
</dd>
<dt><span class="term">-T <em class="replaceable"><code>ttl</code></em></span></dt>
<dd><p>
- Specifies the TTL of new DNSKEY records imported to the zone
- from the key repository. Only useful with the -S option.
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <code class="option">-S</code>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
</p></dd>
<dt><span class="term">-t</span></dt>
<dd><p>
@@ -344,7 +362,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2660500"></a><h2>EXAMPLE</h2>
+<a name="id2660612"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
@@ -373,14 +391,14 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2660641"></a><h2>SEE ALSO</h2>
+<a name="id2660753"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 4033</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2660665"></a><h2>AUTHOR</h2>
+<a name="id2660777"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.host.html b/doc/arm/man.host.html
index afbcc463..f8343f2c 100644
--- a/doc/arm/man.host.html
+++ b/doc/arm/man.host.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.host.html,v 1.118 2009/07/19 04:27:56 tbox Exp $ -->
+<!-- $Id: man.host.html,v 1.120 2009/09/03 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">host</code> [<code class="option">-aCdlnrsTwv</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-N <em class="replaceable"><code>ndots</code></em></code>] [<code class="option">-R <em class="replaceable"><code>number</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-W <em class="replaceable"><code>wait</code></em></code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-4</code>] [<code class="option">-6</code>] {name} [server]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604423"></a><h2>DESCRIPTION</h2>
+<a name="id2604615"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">host</strong></span>
is a simple utility for performing DNS lookups.
It is normally used to convert names to IP addresses and vice versa.
@@ -202,7 +202,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605005"></a><h2>IDN SUPPORT</h2>
+<a name="id2605197"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">host</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -216,12 +216,12 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605034"></a><h2>FILES</h2>
+<a name="id2605226"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605048"></a><h2>SEE ALSO</h2>
+<a name="id2605240"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dig</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>.
</p>
diff --git a/doc/arm/man.named-checkconf.html b/doc/arm/man.named-checkconf.html
index 06f5cebc..3f166f03 100644
--- a/doc/arm/man.named-checkconf.html
+++ b/doc/arm/man.named-checkconf.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named-checkconf.html,v 1.121 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.named-checkconf.html,v 1.126 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,14 +50,14 @@
<div class="cmdsynopsis"><p><code class="command">named-checkconf</code> [<code class="option">-h</code>] [<code class="option">-v</code>] [<code class="option">-j</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] {filename} [<code class="option">-p</code>] [<code class="option">-z</code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610537"></a><h2>DESCRIPTION</h2>
+<a name="id2611764"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkconf</strong></span>
checks the syntax, but not the semantics, of a named
configuration file.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2610551"></a><h2>OPTIONS</h2>
+<a name="id2611778"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-h</span></dt>
<dd><p>
@@ -96,21 +96,21 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610685"></a><h2>RETURN VALUES</h2>
+<a name="id2611912"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkconf</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2610699"></a><h2>SEE ALSO</h2>
+<a name="id2611926"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611070"></a><h2>AUTHOR</h2>
+<a name="id2611956"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.named-checkzone.html b/doc/arm/man.named-checkzone.html
index 699121b0..e9a0fe97 100644
--- a/doc/arm/man.named-checkzone.html
+++ b/doc/arm/man.named-checkzone.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named-checkzone.html,v 1.128 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.named-checkzone.html,v 1.133 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -51,7 +51,7 @@
<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2611719"></a><h2>DESCRIPTION</h2>
+<a name="id2613355"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkzone</strong></span>
checks the syntax and integrity of a zone file. It performs the
same checks as <span><strong class="command">named</strong></span> does when loading a
@@ -71,7 +71,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611769"></a><h2>OPTIONS</h2>
+<a name="id2613405"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-d</span></dt>
<dd><p>
@@ -257,14 +257,14 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2661386"></a><h2>RETURN VALUES</h2>
+<a name="id2663569"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkzone</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2661400"></a><h2>SEE ALSO</h2>
+<a name="id2663582"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<em class="citetitle">RFC 1035</em>,
@@ -272,7 +272,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2661433"></a><h2>AUTHOR</h2>
+<a name="id2663616"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.named.html b/doc/arm/man.named.html
index 1ef55447..57a0af06 100644
--- a/doc/arm/man.named.html
+++ b/doc/arm/man.named.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named.html,v 1.130 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.named.html,v 1.135 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2612203"></a><h2>DESCRIPTION</h2>
+<a name="id2613771"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named</strong></span>
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -65,7 +65,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612576"></a><h2>OPTIONS</h2>
+<a name="id2613802"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-4</span></dt>
<dd><p>
@@ -238,7 +238,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2613038"></a><h2>SIGNALS</h2>
+<a name="id2635086"></a><h2>SIGNALS</h2>
<p>
In routine operation, signals should not be used to control
the nameserver; <span><strong class="command">rndc</strong></span> should be used
@@ -259,7 +259,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2614454"></a><h2>CONFIGURATION</h2>
+<a name="id2635137"></a><h2>CONFIGURATION</h2>
<p>
The <span><strong class="command">named</strong></span> configuration file is too complex
to describe in detail here. A complete description is provided
@@ -276,7 +276,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2615049"></a><h2>FILES</h2>
+<a name="id2635186"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt>
<dd><p>
@@ -289,7 +289,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2654892"></a><h2>SEE ALSO</h2>
+<a name="id2663697"></a><h2>SEE ALSO</h2>
<p><em class="citetitle">RFC 1033</em>,
<em class="citetitle">RFC 1034</em>,
<em class="citetitle">RFC 1035</em>,
@@ -302,7 +302,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2654963"></a><h2>AUTHOR</h2>
+<a name="id2663767"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.nsupdate.html b/doc/arm/man.nsupdate.html
index 7016c263..5eb06851 100644
--- a/doc/arm/man.nsupdate.html
+++ b/doc/arm/man.nsupdate.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.nsupdate.html,v 1.54 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.nsupdate.html,v 1.59 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,10 +47,10 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
+<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-l</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2613313"></a><h2>DESCRIPTION</h2>
+<a name="id2626844"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">nsupdate</strong></span>
is used to submit Dynamic DNS Update requests as defined in RFC2136
to a name server.
@@ -205,7 +205,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2613843"></a><h2>INPUT FORMAT</h2>
+<a name="id2629081"></a><h2>INPUT FORMAT</h2>
<p><span><strong class="command">nsupdate</strong></span>
reads input from
<em class="parameter"><code>filename</code></em>
@@ -469,7 +469,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2664505"></a><h2>EXAMPLES</h2>
+<a name="id2664861"></a><h2>EXAMPLES</h2>
<p>
The examples below show how
<span><strong class="command">nsupdate</strong></span>
@@ -523,7 +523,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2664555"></a><h2>FILES</h2>
+<a name="id2664912"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="constant">/etc/resolv.conf</code></span></dt>
<dd><p>
@@ -546,7 +546,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2664638"></a><h2>SEE ALSO</h2>
+<a name="id2665063"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">RFC2136</span></span>,
<span class="citerefentry"><span class="refentrytitle">RFC3007</span></span>,
<span class="citerefentry"><span class="refentrytitle">RFC2104</span></span>,
@@ -560,7 +560,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2664717"></a><h2>BUGS</h2>
+<a name="id2665142"></a><h2>BUGS</h2>
<p>
The TSIG key is redundantly stored in two separate files.
This is a consequence of nsupdate using the DST library
diff --git a/doc/arm/man.rndc-confgen.html b/doc/arm/man.rndc-confgen.html
index 765c78da..6f33554f 100644
--- a/doc/arm/man.rndc-confgen.html
+++ b/doc/arm/man.rndc-confgen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc-confgen.html,v 1.134 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.rndc-confgen.html,v 1.139 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc-confgen</code> [<code class="option">-a</code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-c <em class="replaceable"><code>keyfile</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [<code class="option">-s <em class="replaceable"><code>address</code></em></code>] [<code class="option">-t <em class="replaceable"><code>chrootdir</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2627573"></a><h2>DESCRIPTION</h2>
+<a name="id2637137"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc-confgen</strong></span>
generates configuration files
for <span><strong class="command">rndc</strong></span>. It can be used as a
@@ -66,7 +66,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2627639"></a><h2>OPTIONS</h2>
+<a name="id2637203"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd>
@@ -173,7 +173,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2628844"></a><h2>EXAMPLES</h2>
+<a name="id2637794"></a><h2>EXAMPLES</h2>
<p>
To allow <span><strong class="command">rndc</strong></span> to be used with
no manual configuration, run
@@ -190,7 +190,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2636410"></a><h2>SEE ALSO</h2>
+<a name="id2639011"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -198,7 +198,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2636449"></a><h2>AUTHOR</h2>
+<a name="id2639049"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.rndc.conf.html b/doc/arm/man.rndc.conf.html
index 99959268..b940710f 100644
--- a/doc/arm/man.rndc.conf.html
+++ b/doc/arm/man.rndc.conf.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc.conf.html,v 1.135 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.rndc.conf.html,v 1.140 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc.conf</code> </p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608789"></a><h2>DESCRIPTION</h2>
+<a name="id2610161"></a><h2>DESCRIPTION</h2>
<p><code class="filename">rndc.conf</code> is the configuration file
for <span><strong class="command">rndc</strong></span>, the BIND 9 name server control
utility. This file has a similar structure and syntax to
@@ -135,7 +135,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2623160"></a><h2>EXAMPLE</h2>
+<a name="id2636137"></a><h2>EXAMPLE</h2>
<pre class="programlisting">
options {
default-server localhost;
@@ -209,7 +209,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2625534"></a><h2>NAME SERVER CONFIGURATION</h2>
+<a name="id2636259"></a><h2>NAME SERVER CONFIGURATION</h2>
<p>
The name server must be configured to accept rndc connections and
to recognize the key specified in the <code class="filename">rndc.conf</code>
@@ -219,7 +219,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2625560"></a><h2>SEE ALSO</h2>
+<a name="id2636284"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">mmencode</span>(1)</span>,
@@ -227,7 +227,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2625598"></a><h2>AUTHOR</h2>
+<a name="id2636323"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.rndc.html b/doc/arm/man.rndc.html
index 1fa2708a..a4537a92 100644
--- a/doc/arm/man.rndc.html
+++ b/doc/arm/man.rndc.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc.html,v 1.133 2009/07/20 01:13:18 tbox Exp $ -->
+<!-- $Id: man.rndc.html,v 1.138 2009/09/08 01:14:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc</code> [<code class="option">-b <em class="replaceable"><code>source-address</code></em></code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-k <em class="replaceable"><code>key-file</code></em></code>] [<code class="option">-s <em class="replaceable"><code>server</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-V</code>] [<code class="option">-y <em class="replaceable"><code>key_id</code></em></code>] {command}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2614016"></a><h2>DESCRIPTION</h2>
+<a name="id2627470"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc</strong></span>
controls the operation of a name
server. It supersedes the <span><strong class="command">ndc</strong></span> utility
@@ -79,7 +79,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2614066"></a><h2>OPTIONS</h2>
+<a name="id2627521"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-b <em class="replaceable"><code>source-address</code></em></span></dt>
<dd><p>
@@ -151,7 +151,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2616066"></a><h2>LIMITATIONS</h2>
+<a name="id2635733"></a><h2>LIMITATIONS</h2>
<p><span><strong class="command">rndc</strong></span>
does not yet support all the commands of
the BIND 8 <span><strong class="command">ndc</strong></span> utility.
@@ -165,7 +165,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2616097"></a><h2>SEE ALSO</h2>
+<a name="id2635764"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -175,7 +175,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2616152"></a><h2>AUTHOR</h2>
+<a name="id2635819"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-08.txt b/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-09.txt
index dc108cbf..0953e28b 100644
--- a/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-08.txt
+++ b/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-09.txt
@@ -5,12 +5,12 @@ Network Working Group S. Weiler
Internet-Draft SPARTA, Inc.
Updates: 4033, 4034, 4035, 5155 D. Blacka
(if approved) VeriSign, Inc.
-Intended status: Standards Track January 14, 2009
-Expires: July 18, 2009
+Intended status: Standards Track September 5, 2009
+Expires: March 9, 2010
Clarifications and Implementation Notes for DNSSECbis
- draft-ietf-dnsext-dnssec-bis-updates-08
+ draft-ietf-dnsext-dnssec-bis-updates-09
Status of this Memo
@@ -33,7 +33,7 @@ Status of this Memo
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
- This Internet-Draft will expire on July 18, 2009.
+ This Internet-Draft will expire on March 9, 2010.
Copyright Notice
@@ -41,25 +41,22 @@ Copyright Notice
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
- Provisions Relating to IETF Documents
- (http://trustee.ietf.org/license-info) in effect on the date of
- publication of this document. Please review these documents
- carefully, as they describe your rights and restrictions with respect
- to this document.
-
+ Provisions Relating to IETF Documents in effect on the date of
+ publication of this document (http://trustee.ietf.org/license-info).
+ Please review these documents carefully, as they describe your rights
+ and restrictions with respect to this document.
+Abstract
+ This document is a collection of technical clarifications to the
-Weiler & Blacka Expires July 18, 2009 [Page 1]
+Weiler & Blacka Expires March 9, 2010 [Page 1]
-Internet-Draft DNSSECbis Implementation Notes January 2009
+Internet-Draft DNSSECbis Implementation Notes September 2009
-Abstract
-
- This document is a collection of technical clarifications to the
DNSSECbis document set. It is meant to serve as a resource to
implementors as well as a repository of DNSSECbis errata.
@@ -72,24 +69,24 @@ Table of Contents
2. Important Additions to DNSSSECbis . . . . . . . . . . . . . . 3
2.1. NSEC3 Support . . . . . . . . . . . . . . . . . . . . . . 3
2.2. SHA-256 Support . . . . . . . . . . . . . . . . . . . . . 3
- 3. Significant Concerns . . . . . . . . . . . . . . . . . . . . . 4
+ 3. Security Concerns . . . . . . . . . . . . . . . . . . . . . . 4
3.1. Clarifications on Non-Existence Proofs . . . . . . . . . . 4
3.2. Validating Responses to an ANY Query . . . . . . . . . . . 4
3.3. Check for CNAME . . . . . . . . . . . . . . . . . . . . . 5
3.4. Insecure Delegation Proofs . . . . . . . . . . . . . . . . 5
- 3.5. Errors in Canonical Form Type Code List . . . . . . . . . 5
4. Interoperability Concerns . . . . . . . . . . . . . . . . . . 5
- 4.1. Unknown DS Message Digest Algorithms . . . . . . . . . . . 5
- 4.2. Private Algorithms . . . . . . . . . . . . . . . . . . . . 6
- 4.3. Caution About Local Policy and Multiple RRSIGs . . . . . . 6
- 4.4. Key Tag Calculation . . . . . . . . . . . . . . . . . . . 7
- 4.5. Setting the DO Bit on Replies . . . . . . . . . . . . . . 7
- 4.6. Setting the AD bit on Replies . . . . . . . . . . . . . . 7
- 4.7. Setting the CD bit on Requests . . . . . . . . . . . . . . 8
- 4.8. Nested Trust Anchors . . . . . . . . . . . . . . . . . . . 8
+ 4.1. Errors in Canonical Form Type Code List . . . . . . . . . 5
+ 4.2. Unknown DS Message Digest Algorithms . . . . . . . . . . . 5
+ 4.3. Private Algorithms . . . . . . . . . . . . . . . . . . . . 6
+ 4.4. Caution About Local Policy and Multiple RRSIGs . . . . . . 7
+ 4.5. Key Tag Calculation . . . . . . . . . . . . . . . . . . . 7
+ 4.6. Setting the DO Bit on Replies . . . . . . . . . . . . . . 7
+ 4.7. Setting the AD bit on Replies . . . . . . . . . . . . . . 7
+ 4.8. Setting the CD bit on Requests . . . . . . . . . . . . . . 8
+ 4.9. Nested Trust Anchors . . . . . . . . . . . . . . . . . . . 8
5. Minor Corrections and Clarifications . . . . . . . . . . . . . 8
5.1. Finding Zone Cuts . . . . . . . . . . . . . . . . . . . . 8
- 5.2. Clarifications on DNSKEY Usage . . . . . . . . . . . . . . 8
+ 5.2. Clarifications on DNSKEY Usage . . . . . . . . . . . . . . 9
5.3. Errors in Examples . . . . . . . . . . . . . . . . . . . . 9
5.4. Errors in RFC 5155 . . . . . . . . . . . . . . . . . . . . 9
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10
@@ -108,15 +105,19 @@ Table of Contents
-Weiler & Blacka Expires July 18, 2009 [Page 2]
+
+
+
+Weiler & Blacka Expires March 9, 2010 [Page 2]
-Internet-Draft DNSSECbis Implementation Notes January 2009
+Internet-Draft DNSSECbis Implementation Notes September 2009
1. Introduction and Terminology
- This document lists some clarifications and corrections to DNSSECbis,
- as described in [RFC4033], [RFC4034], and [RFC4035].
+ This document lists some additions, clarifications and corrections to
+ the core DNSSECbis specification, as originally described in
+ [RFC4033], [RFC4034], and [RFC4035].
It is intended to serve as a resource for implementors and as a
repository of items that need to be addressed when advancing the
@@ -126,8 +127,8 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
The clarifications to DNSSECbis are sorted according to their
importance, starting with ones which could, if ignored, lead to
- security and stability problems and progressing down to
- clarifications that are expected to have little operational impact.
+ security problems and progressing down to clarifications that are
+ expected to have little operational impact.
1.2. Terminology
@@ -138,16 +139,17 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
2. Important Additions to DNSSSECbis
- This section provides
+ This section updates the set of core DNSSEC protocol documents
+ originally specified in Section 10 of [RFC4033].
2.1. NSEC3 Support
[RFC5155] describes the use and behavior of the NSEC3 and NSEC3PARAM
records for hashed denial of existence. Validator implementations
- are strongly encouraged to include support for NSEC3 as a number of
- highly visible zones are expected to use it. Validators that do not
- support validation of responses using NSEC3 will likely be hampered
- in validating large portions of the DNS space.
+ are strongly encouraged to include support for NSEC3 because a number
+ of highly visible zones are expected to use it. Validators that do
+ not support validation of responses using NSEC3 will likely be
+ hampered in validating large portions of the DNS space.
[RFC5155] should be considered part of the DNS Security Document
Family as described by [RFC4033], Section 10.
@@ -156,35 +158,33 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
[RFC4509] describes the use of SHA-256 as a digest algorithm for use
with Delegation Signer (DS) RRs. [I-D.ietf-dnsext-dnssec-rsasha256]
- describes the use of the RSASHA256 algorthim for use in DNSKEY and
+ describes the use of the RSASHA256 algorithm for use in DNSKEY and
RRSIG RRs. Validator implementations are strongly encouraged to
include support for this algorithm for DS, DNSKEY, and RRSIG records.
- Both [RFC4509] and [I-D.ietf-dnsext-dnssec-rsasha256] should also be
-
-Weiler & Blacka Expires July 18, 2009 [Page 3]
+Weiler & Blacka Expires March 9, 2010 [Page 3]
-Internet-Draft DNSSECbis Implementation Notes January 2009
+Internet-Draft DNSSECbis Implementation Notes September 2009
+ Both [RFC4509] and [I-D.ietf-dnsext-dnssec-rsasha256] should also be
considered part of the DNS Security Document Family as described by
[RFC4033], Section 10.
-3. Significant Concerns
+3. Security Concerns
This section provides clarifications that, if overlooked, could lead
- to security issues or major interoperability problems.
+ to security issues.
3.1. Clarifications on Non-Existence Proofs
- [RFC4035] Section 5.4 underspecifies the algorithm for checking non-
+ [RFC4035] Section 5.4 under-specifies the algorithm for checking non-
existence proofs. In particular, the algorithm as presented would
incorrectly allow an NSEC or NSEC3 RR from an ancestor zone to prove
- the non-existence of other RRs at that name in the child zone or
- other names in the child zone.
+ the non-existence of RRs in the child zone.
An "ancestor delegation" NSEC RR (or NSEC3 RR) is one with:
@@ -209,43 +209,51 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
[RFC4035] does not address how to validate responses when QTYPE=*.
As described in Section 6.2.2 of [RFC1034], a proper response to
- QTYPE=* may include a subset of the RRsets at a given name -- it is
- not necessary to include all RRsets at the QNAME in the response.
+ QTYPE=* may include a subset of the RRsets at a given name. That is,
+ it is not necessary to include all RRsets at the QNAME in the
+ response.
- When validating a response to QTYPE=*, validate all received RRsets
- that match QNAME and QCLASS. If any of those RRsets fail validation,
- treat the answer as Bogus. If there are no RRsets matching QNAME and
- QCLASS, validate that fact using the rules in [RFC4035] Section 5.4
- (as clarified in this document). To be clear, a validator must not
+ When validating a response to QTYPE=*, all received RRsets that match
+ QNAME and QCLASS MUST be validated. If any of those RRsets fail
+ validation, the answer is considered Bogus. If there are no RRsets
+ matching QNAME and QCLASS, that fact MUST be validated according to
-Weiler & Blacka Expires July 18, 2009 [Page 4]
+Weiler & Blacka Expires March 9, 2010 [Page 4]
-Internet-Draft DNSSECbis Implementation Notes January 2009
+Internet-Draft DNSSECbis Implementation Notes September 2009
- expect to receive all records at the QNAME in response to QTYPE=*.
+ the rules in [RFC4035] Section 5.4 (as clarified in this document).
+ To be clear, a validator must not expect to receive all records at
+ the QNAME in response to QTYPE=*.
3.3. Check for CNAME
Section 5 of [RFC4035] says little about validating responses based
on (or that should be based on) CNAMEs. When validating a NOERROR/
NODATA response, validators MUST check the CNAME bit in the matching
- NSEC or NSEC3 RR's type bitmap. If the CNAME bit is set, the
- validator MUST validate the CNAME RR and follow it, as appropriate.
+ NSEC or NSEC3 RR's type bitmap in addition to the bit for the query
+ type. Without this check, an attacker could successfully transform a
+ positive CNAME response into a NOERROR/NODATA response.
3.4. Insecure Delegation Proofs
[RFC4035] Section 5.2 specifies that a validator, when proving a
delegation is not secure, needs to check for the absence of the DS
and SOA bits in the NSEC (or NSEC3) type bitmap. The validator also
- needs to check for the presence of the NS bit in the NSEC (or NSEC3)
- RR (proving that there is, indeed, a delegation). If this is not
- checked, spoofed unsigned delegations might be used to claim that an
- existing signed record is not signed.
+ needs to check for the presence of the NS bit in the matching NSEC
+ (or NSEC3) RR (proving that there is, indeed, a delegation), or
+ alternately make sure that the delegation is covered by an NSEC3 RR
+ with the Opt-Out flag set. If this is not checked, spoofed unsigned
+ delegations might be used to claim that an existing signed record is
+ not signed.
-3.5. Errors in Canonical Form Type Code List
+
+4. Interoperability Concerns
+
+4.1. Errors in Canonical Form Type Code List
When canonicalizing DNS names, DNS names in the RDATA section of NSEC
and RRSIG resource records are not downcased.
@@ -260,26 +268,24 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
Since HINFO records contain no domain names, they are not subject to
downcasing.
-
-4. Interoperability Concerns
-
-4.1. Unknown DS Message Digest Algorithms
+4.2. Unknown DS Message Digest Algorithms
Section 5.2 of [RFC4035] includes rules for how to handle delegations
- to zones that are signed with entirely unsupported algorithms, as
- indicated by the algorithms shown in those zone's DS RRsets. It does
- not explicitly address how to handle DS records that use unsupported
- message digest algorithms. In brief, DS records using unknown or
- unsupported message digest algorithms MUST be treated the same way as
- DS records referring to DNSKEY RRs of unknown or unsupported
- algorithms.
+ to zones that are signed with entirely unsupported public key
+ algorithms, as indicated by the key algorithms shown in those zone's
-Weiler & Blacka Expires July 18, 2009 [Page 5]
+Weiler & Blacka Expires March 9, 2010 [Page 5]
-Internet-Draft DNSSECbis Implementation Notes January 2009
+Internet-Draft DNSSECbis Implementation Notes September 2009
+
+ DS RRsets. It does not explicitly address how to handle DS records
+ that use unsupported message digest algorithms. In brief, DS records
+ using unknown or unsupported message digest algorithms MUST be
+ treated the same way as DS records referring to DNSKEY RRs of unknown
+ or unsupported public key algorithms.
The existing text says:
@@ -291,15 +297,15 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
described above.
To paraphrase the above, when determining the security status of a
- zone, a validator discards (for this purpose only) any DS records
- listing unknown or unsupported algorithms. If none are left, the
- zone is treated as if it were unsigned.
+ zone, a validator disregards any DS records listing unknown or
+ unsupported algorithms. If none are left, the zone is treated as if
+ it were unsigned.
Modified to consider DS message digest algorithms, a validator also
- discards any DS records using unknown or unsupported message digest
+ disregards any DS records using unknown or unsupported message digest
algorithms.
-4.2. Private Algorithms
+4.3. Private Algorithms
As discussed above, section 5.2 of [RFC4035] requires that validators
make decisions about the security status of zones based on the public
@@ -313,30 +319,30 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
needed. In the remaining cases, the security status of the zone
depends on whether or not the resolver supports any of the private
algorithms in use (provided that these DS records use supported hash
- functions, as discussed in Section 4.1). In these cases, the
+ functions, as discussed in Section 4.2). In these cases, the
resolver MUST retrieve the corresponding DNSKEY for each private
algorithm DS record and examine the public key field to determine the
algorithm in use. The security-aware resolver MUST ensure that the
hash of the DNSKEY RR's owner name and RDATA matches the digest in
the DS RR. If they do not match, and no other DS establishes that
- the zone is secure, the referral should be considered BAD data, as
+ the zone is secure, the referral should be considered Bogus data, as
discussed in [RFC4035].
This clarification facilitates the broader use of private algorithms,
- as suggested by [RFC4955].
-4.3. Caution About Local Policy and Multiple RRSIGs
- When multiple RRSIGs cover a given RRset, [RFC4035] Section 5.3.3
- suggests that "the local resolver security policy determines whether
+Weiler & Blacka Expires March 9, 2010 [Page 6]
+
+Internet-Draft DNSSECbis Implementation Notes September 2009
-Weiler & Blacka Expires July 18, 2009 [Page 6]
-
-Internet-Draft DNSSECbis Implementation Notes January 2009
+ as suggested by [RFC4955].
+4.4. Caution About Local Policy and Multiple RRSIGs
+ When multiple RRSIGs cover a given RRset, [RFC4035] Section 5.3.3
+ suggests that "the local resolver security policy determines whether
the resolver also has to test these RRSIG RRs and how to resolve
conflicts if these RRSIG RRs lead to differing results." In most
cases, a resolver would be well advised to accept any valid RRSIG as
@@ -352,7 +358,7 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
method described in section 4.2.1.2 of [RFC4641] might not work
reliably.
-4.4. Key Tag Calculation
+4.5. Key Tag Calculation
[RFC4034] Appendix B.1 incorrectly defines the Key Tag field
calculation for algorithm 1. It correctly says that the Key Tag is
@@ -361,7 +367,7 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
say that this is 4th to last and 3rd to last octets of the public key
modulus. It is, in fact, the 3rd to last and 2nd to last octets.
-4.5. Setting the DO Bit on Replies
+4.6. Setting the DO Bit on Replies
[RFC4035] does not provide any instructions to servers as to how to
set the DO bit. Some authoritative server implementations have
@@ -370,7 +376,7 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
responses. Either behavior is permitted. To be clear, in replies to
queries with the DO-bit set servers may or may not set the DO bit.
-4.6. Setting the AD bit on Replies
+4.7. Setting the AD bit on Replies
Section 3.2.3 of [RFC4035] describes under which conditions a
validating resolver should set or clear the AD bit in a response. In
@@ -379,6 +385,14 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
conditions listed in RFC 4035, section 3.2.3, and the request
contained either a set DO bit or a set AD bit.
+
+
+
+Weiler & Blacka Expires March 9, 2010 [Page 7]
+
+Internet-Draft DNSSECbis Implementation Notes September 2009
+
+
Note that the use of the AD bit in the query was previously
undefined. This document defines it as a signal indicating that the
requester understands and is interested in the value of the AD bit in
@@ -386,23 +400,16 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
understands the AD bit without also requesting DNSSEC data via the DO
bit.
-
-
-Weiler & Blacka Expires July 18, 2009 [Page 7]
-
-Internet-Draft DNSSECbis Implementation Notes January 2009
-
-
-4.7. Setting the CD bit on Requests
+4.8. Setting the CD bit on Requests
When processing a request with the CD bit set, the resolver MUST set
the CD bit on its upstream queries.
-4.8. Nested Trust Anchors
+4.9. Nested Trust Anchors
A DNSSEC validator may be configured such that, for a given response,
more than one trust anchor could be used to validate the chain of
- trust to the response zone. For example, imagine a validor
+ trust to the response zone. For example, imagine a validator
configured with trust anchors for "example." and "zone.example."
When the validator is asked to validate a response to
"www.sub.zone.example.", either trust anchor could apply.
@@ -431,6 +438,17 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
does not already have the parent's NS RRset. Section 4.2 of
[RFC4035] specifies a mechanism for doing that.
+
+
+
+
+
+
+Weiler & Blacka Expires March 9, 2010 [Page 8]
+
+Internet-Draft DNSSECbis Implementation Notes September 2009
+
+
5.2. Clarifications on DNSKEY Usage
Questions of the form "can I use a different DNSKEY for signing this
@@ -441,14 +459,6 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
the size of the DNSKEY RRset. However, be aware that there is no way
to tell resolvers what a particularly DNSKEY is supposed to be used
for -- any DNSKEY in the zone's signed DNSKEY RRset may be used to
-
-
-
-Weiler & Blacka Expires July 18, 2009 [Page 8]
-
-Internet-Draft DNSSECbis Implementation Notes January 2009
-
-
authenticate any RRset in the zone. For example, if a weaker or less
trusted DNSKEY is being used to authenticate NSEC RRsets or all
dynamically updated records, that same DNSKEY can also be used to
@@ -480,14 +490,21 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
5.4. Errors in RFC 5155
- A NSEC3 record, that matches an Empty Non-Terminal, effectively has
- no type associated with it. This NSEC3 record has an empty type bit
+ A NSEC3 record that matches an Empty Non-Terminal effectively has no
+ type associated with it. This NSEC3 record has an empty type bit
map. Section 3.2.1 of [RFC5155] contains the statement:
Blocks with no types present MUST NOT be included.
However, the same section contains a regular expression:
+
+
+Weiler & Blacka Expires March 9, 2010 [Page 9]
+
+Internet-Draft DNSSECbis Implementation Notes September 2009
+
+
Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+
The plus sign in the regular expression indicates that there is one
@@ -496,15 +513,6 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
contradicts with the first statement. Therefore, the correct text in
RFC 5155 3.2.1 should be:
-
-
-
-
-Weiler & Blacka Expires July 18, 2009 [Page 9]
-
-Internet-Draft DNSSECbis Implementation Notes January 2009
-
-
Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )*
@@ -515,16 +523,15 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
7. Security Considerations
- This document does not make fundamental changes to the DNSSEC
- protocol, as it was generally understood when DNSSECbis was
- published. It does, however, address some ambiguities and omissions
- in those documents that, if not recognized and addressed in
+ This document adds two cryptographic features to the core DNSSEC
+ protocol. Additionally, it addresses some ambiguities and omissions
+ in the core DNSSEC documents that, if not recognized and addressed in
implementations, could lead to security failures. In particular, the
validation algorithm clarifications in Section 3 are critical for
preserving the security properties DNSSEC offers. Furthermore,
failure to address some of the interoperability concerns in Section 4
could limit the ability to later change or expand DNSSEC, including
- by adding new algorithms.
+ adding new algorithms.
8. References
@@ -534,8 +541,8 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
[I-D.ietf-dnsext-dnssec-rsasha256]
Jansen, J., "Use of SHA-2 algorithms with RSA in DNSKEY
and RRSIG Resource Records for DNSSEC",
- draft-ietf-dnsext-dnssec-rsasha256-10 (work in progress),
- January 2009.
+ draft-ietf-dnsext-dnssec-rsasha256-14 (work in progress),
+ June 2009.
[RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
RFC 1034, STD 13, November 1987.
@@ -547,20 +554,19 @@ Internet-Draft DNSSECbis Implementation Notes January 2009
Rose, "DNS Security Introduction and Requirements",
RFC 4033, March 2005.
+
+
+Weiler & Blacka Expires March 9, 2010 [Page 10]
+
+Internet-Draft DNSSECbis Implementation Notes September 2009
+
+
[RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S.
Rose, "Resource Records for the DNS Security Extensions",
RFC 4034, March 2005.
[RFC4035] Arends, R., Austein, R., Larson, M., Massey, D., and S.
Rose, "Protocol Modifications for the DNS Security
-
-
-
-Weiler & Blacka Expires July 18, 2009 [Page 10]
-
-Internet-Draft DNSSECbis Implementation Notes January 2009
-
-
Extensions", RFC 4035, March 2005.
[RFC4509] Hardaker, W., "Use of SHA-256 in DNSSEC Delegation Signer
@@ -592,17 +598,25 @@ Appendix A. Acknowledgments
provided text suitable for inclusion in this document.
The lack of specificity about handling private algorithms, as
- described in Section 4.2, and the lack of specificity in handling ANY
+ described in Section 4.3, and the lack of specificity in handling ANY
queries, as described in Section 3.2, were discovered by David
Blacka.
The error in algorithm 1 key tag calculation, as described in
- Section 4.4, was found by Abhijit Hayatnagarkar. Donald Eastlake
- contributed text for Section 4.4.
+ Section 4.5, was found by Abhijit Hayatnagarkar. Donald Eastlake
+ contributed text for Section 4.5.
The bug relating to delegation NSEC RR's in Section 3.1 was found by
Roy Badami. Roy Arends found the related problem with DNAME.
+
+
+
+Weiler & Blacka Expires March 9, 2010 [Page 11]
+
+Internet-Draft DNSSECbis Implementation Notes September 2009
+
+
The errors in the [RFC4035] examples were found by Roy Arends, who
also contributed text for Section 5.3 of this document.
@@ -611,12 +625,6 @@ Appendix A. Acknowledgments
comments on the text of this document.
-
-Weiler & Blacka Expires July 18, 2009 [Page 11]
-
-Internet-Draft DNSSECbis Implementation Notes January 2009
-
-
Authors' Addresses
Samuel Weiler
@@ -660,13 +668,5 @@ Authors' Addresses
-
-
-
-
-
-
-
-
-Weiler & Blacka Expires July 18, 2009 [Page 12]
+Weiler & Blacka Expires March 9, 2010 [Page 12]
diff --git a/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt b/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt
deleted file mode 100644
index 00476ae5..00000000
--- a/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt
+++ /dev/null
@@ -1,522 +0,0 @@
-
-INTERNET-DRAFT Donald E. Eastlake 3rd
-UPDATES RFC 2845 Motorola Laboratories
-Expires: July 2006 January 2006
-
- HMAC SHA TSIG Algorithm Identifiers
- ---- --- ---- --------- -----------
- <draft-ietf-dnsext-tsig-sha-06.txt>
-
-
-Status of This Document
-
- By submitting this Internet-Draft, each author represents that any
- applicable patent or other IPR claims of which he or she is aware
- have been or will be disclosed, and any of which he or she becomes
- aware will be disclosed, in accordance with Section 6 of BCP 79.
-
- This draft is intended to be become a Proposed Standard RFC.
- Distribution of this document is unlimited. Comments should be sent
- to the DNSEXT working group mailing list <namedroppers@ops.ietf.org>.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at
- http://www.ietf.org/1id-abstracts.html
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html
-
-
-Abstract
-
- Use of the Domain Name System TSIG resource record requires
- specification of a cryptographic message authentication code.
- Currently identifiers have been specified only for the HMAC MD5
- (Message Digest) and GSS (Generic Security Service) TSIG algorithms.
- This document standardizes identifiers and implementation
- requirements for additional HMAC SHA (Secure Hash Algorithm) TSIG
- algorithms and standardizes how to specify and handle the truncation
- of HMAC values in TSIG.
-
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2006).
-
-
-
-D. Eastlake 3rd [Page 1]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-Table of Contents
-
- Status of This Document....................................1
- Abstract...................................................1
- Copyright Notice...........................................1
-
- Table of Contents..........................................2
-
- 1. Introduction............................................3
-
- 2. Algorithms and Identifiers..............................4
-
- 3. Specifying Truncation...................................5
- 3.1 Truncation Specification...............................5
-
- 4. TSIG Truncation Policy and Error Provisions.............6
-
- 5. IANA Considerations.....................................7
- 6. Security Considerations.................................7
- 7. Copyright and Disclaimer................................7
-
- 8. Normative References....................................8
- 9. Informative References..................................8
-
- Author's Address...........................................9
- Additional IPR Provisions..................................9
- Expiration and File Name...................................9
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-D. Eastlake 3rd [Page 2]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-1. Introduction
-
- [RFC 2845] specifies a TSIG Resource Record (RR) that can be used to
- authenticate DNS (Domain Name System [STD 13]) queries and responses.
- This RR contains a domain name syntax data item which names the
- authentication algorithm used. [RFC 2845] defines the HMAC-MD5.SIG-
- ALG.REG.INT name for authentication codes using the HMAC [RFC 2104]
- algorithm with the MD5 [RFC 1321] hash algorithm. IANA has also
- registered "gss-tsig" as an identifier for TSIG authentication where
- the cryptographic operations are delegated to the Generic Security
- Service (GSS) [RFC 3645].
-
- It should be noted that use of TSIG presumes prior agreement, between
- the resolver and server involved, as to the algorithm and key to be
- used.
-
- In Section 2, this document specifies additional names for TSIG
- authentication algorithms based on US NIST SHA (United States,
- National Institute of Science and Technology, Secure Hash Algorithm)
- algorithms and HMAC and specifies the implementation requirements for
- those algorithms.
-
- In Section 3, this document specifies the effect of inequality
- between the normal output size of the specified hash function and the
- length of MAC (message authentication code) data given in the TSIG
- RR. In particular, it specifies that a shorter length field value
- specifies truncation and a longer length field is an error.
-
- In Section 4, policy restrictions and implications related to
- truncation and a new error code to indicate truncation shorter than
- permitted by policy are described and specified.
-
- The use herein of MUST, SHOULD, MAY, MUST NOT, and SHOULD NOT is as
- defined in [RFC 2119].
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-D. Eastlake 3rd [Page 3]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-2. Algorithms and Identifiers
-
- TSIG Resource Records (RRs) [RFC 2845] are used to authenticate DNS
- queries and responses. They are intended to be efficient symmetric
- authentication codes based on a shared secret. (Asymmetric signatures
- can be provided using the SIG RR [RFC 2931]. In particular, SIG(0)
- can be used for transaction signatures.) Used with a strong hash
- function, HMAC [RFC 2104] provides a way to calculate such symmetric
- authentication codes. The only specified HMAC based TSIG algorithm
- identifier has been HMAC-MD5.SIG-ALG.REG.INT based on MD5 [RFC 1321].
-
- The use of SHA-1 [FIPS 180-2, RFC 3174], which is a 160 bit hash, as
- compared with the 128 bits for MD5, and additional hash algorithms in
- the SHA family [FIPS 180-2, RFC 3874, SHA2draft] with 224, 256, 384,
- and 512 bits, may be preferred in some cases particularly since
- increasingly successful cryptanalytic attacks are being made on the
- shorter hashes.
-
- Use of TSIG between a DNS resolver and server is by mutual agreement.
- That agreement can include the support of additional algorithms and
- criteria as to which algorithms and truncations are acceptable,
- subject to the restriction and guidelines in Section 3 and 4 below.
- Key agreement can be by the TKEY mechanism [RFC 2930] or other
- mutually agreeable method.
-
- The current HMAC-MD5.SIG-ALG.REG.INT and gss-tsig identifiers are
- included in the table below for convenience. Implementations which
- support TSIG MUST also implement HMAC SHA1 and HMAC SHA256 and MAY
- implement gss-tsig and the other algorithms listed below.
-
- Mandatory HMAC-MD5.SIG-ALG.REG.INT
- Optional gss-tsig
- Mandatory hmac-sha1
- Optional hmac-sha224
- Mandatory hmac-sha256
- Optional hamc-sha384
- Optional hmac-sha512
-
- SHA-1 truncated to 96 bits (12 octets) SHOULD be implemented.
-
-
-
-
-
-
-
-
-
-
-
-
-
-D. Eastlake 3rd [Page 4]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-3. Specifying Truncation
-
- When space is at a premium and the strength of the full length of an
- HMAC is not needed, it is reasonable to truncate the HMAC output and
- use the truncated value for authentication. HMAC SHA-1 truncated to
- 96 bits is an option available in several IETF protocols including
- IPSEC and TLS.
-
- The TSIG RR [RFC 2845] includes a "MAC size" field, which gives the
- size of the MAC field in octets. But [RFC 2845] does not specify what
- to do if this MAC size differs from the length of the output of HMAC
- for a particular hash function. Truncation is indicated by a MAC size
- less than the HMAC size as specified below.
-
-
-
-3.1 Truncation Specification
-
- The specification for TSIG handling is changed as follows:
-
- 1. If "MAC size" field is greater than HMAC output length:
- This case MUST NOT be generated and if received MUST cause the
- packet to be dropped and RCODE 1 (FORMERR) to be returned.
-
- 2. If "MAC size" field equals HMAC output length:
- Operation is as described in [RFC 2845] with the entire output
- HMAC output present.
-
- 3. "MAC size" field is less than HMAC output length but greater than
- that specified in case 4 below:
- This is sent when the signer has truncated the HMAC output to
- an allowable length, as described in RFC 2104, taking initial
- octets and discarding trailing octets. TSIG truncation can only be
- to an integral number of octets. On receipt of a packet with
- truncation thus indicated, the locally calculated MAC is similarly
- truncated and only the truncated values compared for
- authentication. The request MAC used when calculating the TSIG MAC
- for a reply is the truncated request MAC.
-
- 4. "MAC size" field is less than the larger of 10 (octets) and half
- the length of the hash function in use:
- With the exception of certain TSIG error messages described in
- RFC 2845 section 3.2 where it is permitted that the MAC size be
- zero, this case MUST NOT be generated and if received MUST cause
- the packet to be dropped and RCODE 1 (FORMERR) to be returned. The
- size limit for this case can also, for the hash functions
- mentioned in this document, be stated as less than half the hash
- function length for hash functions other than MD5 and less than 10
- octets for MD5.
-
-
-
-D. Eastlake 3rd [Page 5]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-4. TSIG Truncation Policy and Error Provisions
-
- Use of TSIG is by mutual agreement between a resolver and server.
- Implicit in such "agreement" are criterion as to acceptable keys and
- algorithms and, with the extensions in this document, truncations.
- Note that it is common for implementations to bind the TSIG secret
- key or keys that may be in place at a resolver and server to
- particular algorithms. Thus such implementations only permit the use
- of an algorithm if there is an associated key in place. Receipt of an
- unknown, unimplemented, or disabled algorithm typically results in a
- BADKEY error.
-
- Local policies MAY require the rejection of TSIGs even though they
- use an algorithm for which implementation is mandatory.
-
- When a local policy permits acceptance of a TSIG with a particular
- algorithm and a particular non-zero amount of truncation it SHOULD
- also permit the use of that algorithm with lesser truncation (a
- longer MAC) up to the full HMAC output.
-
- Regardless of a lower acceptable truncated MAC length specified by
- local policy, a reply SHOULD be sent with a MAC at least as long as
- that in the corresponding request unless the request specified a MAC
- length longer than the HMAC output.
-
- Implementations permitting multiple acceptable algorithms and/or
- truncations SHOULD permit this list to be ordered by presumed
- strength and SHOULD allow different truncations for the same
- algorithm to be treated as separate entities in this list. When so
- implemented, policies SHOULD accept a presumed stronger algorithm and
- truncation than the minimum strength required by the policy.
-
- If a TSIG is received with truncation which is permitted under
- Section 3 above but the MAC is too short for the local policy in
- force, an RCODE of TBA [22 suggested](BADTRUNC) MUST be returned.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-D. Eastlake 3rd [Page 6]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-5. IANA Considerations
-
- This document, on approval for publication as a standards track RFC,
- (1) registers the new TSIG algorithm identifiers listed in Section 2
- with IANA and (2) allocates the BADTRUNC RCODE TBA [22 suggested] in
- Section 4. [RFC 2845]
-
-
-
-6. Security Considerations
-
- For all of the message authentication code algorithms listed herein,
- those producing longer values are believed to be stronger; however,
- while there have been some arguments that mild truncation can
- strengthen a MAC by reducing the information available to an
- attacker, excessive truncation clearly weakens authentication by
- reducing the number of bits an attacker has to try to break the
- authentication by brute force [RFC 2104].
-
- Significant progress has been made recently in cryptanalysis of hash
- function of the type used herein, all of which ultimately derive from
- the design of MD4. While the results so far should not effect HMAC,
- the stronger SHA-1 and SHA-256 algorithms are being made mandatory
- due to caution.
-
- See the Security Considerations section of [RFC 2845]. See also the
- Security Considerations section of [RFC 2104] from which the limits
- on truncation in this RFC were taken.
-
-
-
-7. Copyright and Disclaimer
-
- Copyright (C) The Internet Society (2006).
-
- This document is subject to the rights, licenses and restrictions
- contained in BCP 78, and except as set forth therein, the authors
- retain all their rights.
-
-
- This document and the information contained herein are provided on an
- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
- ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
- INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-D. Eastlake 3rd [Page 7]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-8. Normative References
-
- [FIPS 180-2] - "Secure Hash Standard", (SHA-1/224/256/384/512) US
- Federal Information Processing Standard, with Change Notice 1,
- February 2004.
-
- [RFC 1321] - Rivest, R., "The MD5 Message-Digest Algorithm ", RFC
- 1321, April 1992.
-
- [RFC 2104] - Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
- Hashing for Message Authentication", RFC 2104, February 1997.
-
- [RFC 2119] - Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC 2845] - Vixie, P., Gudmundsson, O., Eastlake 3rd, D., and B.
- Wellington, "Secret Key Transaction Authentication for DNS (TSIG)",
- RFC 2845, May 2000.
-
- [RFC 3174] - Eastlake 3rd, D. and P. Jones, "US Secure Hash Algorithm
- 1 (SHA1)", RFC 3174, September 2001.
-
- [RFC 3874] - R. Housely, "A 224-bit One-way Hash Function: SHA-224",
- September 2004,
-
- [SHA2draft] - Eastlake, D., T. Hansen, "US Secure Hash Algorithms
- (SHA)", draft-eastlake-sha2-*.txt, work in progress.
-
- [STD 13]
- Mockapetris, P., "Domain names - concepts and facilities", STD
- 13, RFC 1034, November 1987.
-
- Mockapetris, P., "Domain names - implementation and
- specification", STD 13, RFC 1035, November 1987.
-
-
-
-9. Informative References.
-
- [RFC 2930] - Eastlake 3rd, D., "Secret Key Establishment for DNS
- (TKEY RR)", RFC 2930, September 2000.
-
- [RFC 2931] - Eastlake 3rd, D., "DNS Request and Transaction
- Signatures ( SIG(0)s )", RFC 2931, September 2000.
-
- [RFC 3645] - Kwan, S., Garg, P., Gilroy, J., Esibov, L., Westhead,
- J., and R. Hall, "Generic Security Service Algorithm for Secret Key
- Transaction Authentication for DNS (GSS-TSIG)", RFC 3645, October
- 2003.
-
-
-
-D. Eastlake 3rd [Page 8]
-
-
-INTERNET-DRAFT HMAC-SHA TSIG Identifiers
-
-
-Author's Address
-
- Donald E. Eastlake 3rd
- Motorola Laboratories
- 155 Beaver Street
- Milford, MA 01757 USA
-
- Telephone: +1-508-786-7554 (w)
-
- EMail: Donald.Eastlake@motorola.com
-
-
-
-Additional IPR Provisions
-
- The IETF takes no position regarding the validity or scope of any
- Intellectual Property Rights or other rights that might be claimed
- to pertain to the implementation or use of the technology
- described in this document or the extent to which any license
- under such rights might or might not be available; nor does it
- represent that it has made any independent effort to identify any
- such rights. Information on the procedures with respect to
- rights in RFC documents can be found in BCP 78 and BCP 79.
-
- Copies of IPR disclosures made to the IETF Secretariat and any
- assurances of licenses to be made available, or the result of an
- attempt made to obtain a general license or permission for the use
- of such proprietary rights by implementers or users of this
- specification can be obtained from the IETF on-line IPR repository
- at http://www.ietf.org/ipr.
-
- The IETF invites any interested party to bring to its attention
- any copyrights, patents or patent applications, or other
- proprietary rights that may cover technology that may be required
- to implement this standard. Please address the information to the
- IETF at ietf-ipr@ietf.org.
-
-
-
-Expiration and File Name
-
- This draft expires in July 2006.
-
- Its file name is draft-ietf-dnsext-tsig-sha-06.txt
-
-
-
-
-
-
-
-
-D. Eastlake 3rd [Page 9]
-
diff --git a/doc/misc/options b/doc/misc/options
index f092ff49..999b41af 100644
--- a/doc/misc/options
+++ b/doc/misc/options
@@ -44,7 +44,8 @@ lwres {
view <string> <optional_class>;
};
-managed-keys { <string> <integer> <integer> <integer> <quoted_string>; ... };
+managed-keys { <string> <string> <integer> <integer> <integer>
+ <quoted_string>; ... };
masters <string> [ port <integer> ] { ( <masters> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
@@ -316,7 +317,7 @@ view <string> <optional_class> {
key-directory <quoted_string>;
lame-ttl <integer>;
maintain-ixfr-base <boolean>; // obsolete
- managed-keys { <string> <integer> <integer> <integer>
+ managed-keys { <string> <string> <integer> <integer> <integer>
<quoted_string>; ... };
masterfile-format ( text | raw );
match-clients { <address_match_element>; ... };
@@ -421,7 +422,6 @@ view <string> <optional_class> {
check-srv-cname ( fail | warn | ignore );
check-wildcard <boolean>;
database <string>;
- ddns-autoconf <boolean>;
delegation-only <boolean>;
dialup <dialuptype>;
file <quoted_string>;
@@ -503,7 +503,6 @@ zone <string> <optional_class> {
check-srv-cname ( fail | warn | ignore );
check-wildcard <boolean>;
database <string>;
- ddns-autoconf <boolean>;
delegation-only <boolean>;
dialup <dialuptype>;
file <quoted_string>;
diff --git a/lib/bind9/Makefile.in b/lib/bind9/Makefile.in
index 7c1e5b0b..91e20836 100644
--- a/lib/bind9/Makefile.in
+++ b/lib/bind9/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.11 2007/06/19 23:47:16 tbox Exp $
+# $Id: Makefile.in,v 1.13 2009/09/02 23:48:01 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -28,7 +28,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I. ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \
${ISCCFG_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index b901e342..cb28c9f8 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.105 2009/07/14 23:47:54 tbox Exp $ */
+/* $Id: check.c,v 1.108 2009/09/02 16:10:03 each Exp $ */
/*! \file */
@@ -100,7 +100,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"rrset-order: invalid name '%s'", str);
@@ -199,7 +199,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) {
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
tresult = dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad name '%s'", str);
@@ -262,7 +262,7 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
str = cfg_obj_asstring(obj);
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'", str);
@@ -349,7 +349,7 @@ mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx,
str = cfg_obj_asstring(obj);
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'", str);
@@ -617,7 +617,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(name, &b,
dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'",
@@ -680,7 +680,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_init(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'", dlv);
@@ -709,13 +709,14 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
result = ISC_R_FAILURE;
}
- if(!cfg_obj_isvoid(anchor)) {
+ if (!cfg_obj_isvoid(anchor)) {
dlv = cfg_obj_asstring(anchor);
isc_buffer_init(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b,
dns_rootname,
- ISC_TRUE, NULL);
+ DNS_NAME_DOWNCASE,
+ NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'",
@@ -771,7 +772,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"empty-server: invalid name '%s'", str);
@@ -786,7 +787,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"empty-contact: invalid name '%s'", str);
@@ -805,7 +806,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"disable-empty-zone: invalid name '%s'",
@@ -990,7 +991,7 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -1004,8 +1005,7 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
- &b, dns_rootname,
- ISC_FALSE, NULL);
+ &b, dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(dname, logctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -1083,7 +1083,6 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
{ "notify", MASTERZONE | SLAVEZONE },
{ "also-notify", MASTERZONE | SLAVEZONE },
{ "dialup", MASTERZONE | SLAVEZONE | STUBZONE },
- { "ddns-autoconf", MASTERZONE },
{ "delegation-only", HINTZONE | STUBZONE | DELEGATIONZONE },
{ "forward", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE },
{ "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE },
@@ -1198,7 +1197,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
isc_buffer_init(&b, zname, strlen(zname));
isc_buffer_add(&b, strlen(zname));
tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b,
- dns_rootname, ISC_TRUE, NULL);
+ dns_rootname, DNS_NAME_DOWNCASE, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
"zone '%s': is not a valid name", zname);
@@ -1511,7 +1510,7 @@ check_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab,
isc_buffer_init(&b, keyid, strlen(keyid));
isc_buffer_add(&b, strlen(keyid));
tresult = dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
"key '%s': bad key name", keyid);
@@ -1681,7 +1680,7 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
isc_buffer_add(&b, strlen(keyval));
keyname = dns_fixedname_name(&fname);
tresult = dns_name_fromtext(keyname, &b, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(keys, logctx, ISC_LOG_ERROR,
"bad key name '%s'", keyval);
diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in
index 170031fb..eef55f1e 100644
--- a/lib/dns/Makefile.in
+++ b/lib/dns/Makefile.in
@@ -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.165 2009/07/01 23:47:36 tbox Exp $
+# $Id: Makefile.in,v 1.166 2009/09/01 00:22:26 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -34,7 +34,7 @@ USE_ISC_SPNEGO = @USE_ISC_SPNEGO@
CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} \
${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@
-CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_PKCS11@ @USE_GSSAPI@ \
+CDEFINES = -DBIND9 -DUSE_MD5 @USE_OPENSSL@ @USE_PKCS11@ @USE_GSSAPI@ \
${USE_ISC_SPNEGO}
CWARNINGS =
@@ -68,7 +68,7 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
resolver.@O@ result.@O@ rootns.@O@ rriterator.@O@ sdb.@O@ \
sdlz.@O@ soa.@O@ ssu.@O@ \
stats.@O@ tcpmsg.@O@ time.@O@ timer.@O@ tkey.@O@ \
- tsig.@O@ ttl.@O@ validator.@O@ \
+ tsec.@O@ tsig.@O@ ttl.@O@ validator.@O@ \
version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@
OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS}
@@ -94,7 +94,7 @@ DNSSRCS = acache.c acl.c adb.c byaddr.c \
resolver.c result.c rootns.c rriterator.c sdb.c sdlz.c \
soa.c ssu.c \
stats.c tcpmsg.c time.c timer.c tkey.c \
- tsig.c ttl.c validator.c \
+ tsec.c tsig.c ttl.c validator.c \
version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS}
SRCS = ${DSTSRCS} ${DNSSRCS}
diff --git a/lib/dns/byaddr.c b/lib/dns/byaddr.c
index 234d6b2c..6a3a6036 100644
--- a/lib/dns/byaddr.c
+++ b/lib/dns/byaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: byaddr.c,v 1.39 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: byaddr.c,v 1.41 2009/09/02 23:48:02 tbox Exp $ */
/*! \file */
@@ -43,25 +43,6 @@
* XXXRTH We could use a static event...
*/
-struct dns_byaddr {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t * mctx;
- isc_mutex_t lock;
- dns_fixedname_t name;
- /* Locked by lock. */
- unsigned int options;
- dns_lookup_t * lookup;
- isc_task_t * task;
- dns_byaddrevent_t * event;
- isc_boolean_t canceled;
-};
-
-#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd')
-#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC)
-
-#define MAX_RESTARTS 16
-
static char hex_digits[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
@@ -125,10 +106,29 @@ dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options,
len = (unsigned int)strlen(textname);
isc_buffer_init(&buffer, textname, len);
isc_buffer_add(&buffer, len);
- return (dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ return (dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL));
}
+#ifdef BIND9
+struct dns_byaddr {
+ /* Unlocked. */
+ unsigned int magic;
+ isc_mem_t * mctx;
+ isc_mutex_t lock;
+ dns_fixedname_t name;
+ /* Locked by lock. */
+ unsigned int options;
+ dns_lookup_t * lookup;
+ isc_task_t * task;
+ dns_byaddrevent_t * event;
+ isc_boolean_t canceled;
+};
+
+#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd')
+#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC)
+
+#define MAX_RESTARTS 16
+
static inline isc_result_t
copy_ptr_targets(dns_byaddr_t *byaddr, dns_rdataset_t *rdataset) {
isc_result_t result;
@@ -314,3 +314,4 @@ dns_byaddr_destroy(dns_byaddr_t **byaddrp) {
*byaddrp = NULL;
}
+#endif /* BIND9 */
diff --git a/lib/dns/cache.c b/lib/dns/cache.c
index 59098799..9752836f 100644
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: cache.c,v 1.84 2009/05/06 22:53:54 jinmei Exp $ */
+/* $Id: cache.c,v 1.85 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -450,6 +450,7 @@ dns_cache_setfilename(dns_cache_t *cache, const char *filename) {
return (ISC_R_SUCCESS);
}
+#ifdef BIND9
isc_result_t
dns_cache_load(dns_cache_t *cache) {
isc_result_t result;
@@ -465,6 +466,7 @@ dns_cache_load(dns_cache_t *cache) {
return (result);
}
+#endif /* BIND9 */
isc_result_t
dns_cache_dump(dns_cache_t *cache) {
@@ -475,10 +477,14 @@ dns_cache_dump(dns_cache_t *cache) {
if (cache->filename == NULL)
return (ISC_R_SUCCESS);
+#ifdef BIND9
LOCK(&cache->filelock);
result = dns_master_dump(cache->mctx, cache->db, NULL,
&dns_master_style_cache, cache->filename);
UNLOCK(&cache->filelock);
+#else
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
return (result);
}
diff --git a/lib/dns/client.c b/lib/dns/client.c
new file mode 100644
index 00000000..3124cf46
--- /dev/null
+++ b/lib/dns/client.c
@@ -0,0 +1,3008 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: client.c,v 1.5 2009/09/03 21:45:46 jinmei Exp $ */
+
+#include <config.h>
+
+#include <isc/app.h>
+#include <isc/mem.h>
+#include <isc/mutex.h>
+#include <isc/sockaddr.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/adb.h>
+#include <dns/client.h>
+#include <dns/db.h>
+#include <dns/dispatch.h>
+#include <dns/events.h>
+#include <dns/forward.h>
+#include <dns/keytable.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
+#include <dns/rdatatype.h>
+#include <dns/rdatasetiter.h>
+#include <dns/rdatastruct.h>
+#include <dns/request.h>
+#include <dns/resolver.h>
+#include <dns/result.h>
+#include <dns/tsec.h>
+#include <dns/tsig.h>
+#include <dns/view.h>
+
+#include <dst/dst.h>
+
+#define DNS_CLIENT_MAGIC ISC_MAGIC('D', 'N', 'S', 'c')
+#define DNS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, DNS_CLIENT_MAGIC)
+
+#define RCTX_MAGIC ISC_MAGIC('R', 'c', 't', 'x')
+#define RCTX_VALID(c) ISC_MAGIC_VALID(c, RCTX_MAGIC)
+
+#define REQCTX_MAGIC ISC_MAGIC('R', 'q', 'c', 'x')
+#define REQCTX_VALID(c) ISC_MAGIC_VALID(c, REQCTX_MAGIC)
+
+#define UCTX_MAGIC ISC_MAGIC('U', 'c', 't', 'x')
+#define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC)
+
+#define MAX_RESTARTS 16
+
+/*%
+ * DNS client object
+ */
+struct dns_client {
+ /* Unlocked */
+ unsigned int magic;
+ unsigned int attributes;
+ isc_mutex_t lock;
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ isc_taskmgr_t *taskmgr;
+ isc_task_t *task;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+ dns_dispatchmgr_t *dispatchmgr;
+ dns_dispatch_t *dispatchv4;
+ dns_dispatch_t *dispatchv6;
+
+ unsigned int update_timeout;
+ unsigned int update_udptimeout;
+ unsigned int update_udpretries;
+ unsigned int find_timeout;
+ unsigned int find_udpretries;
+
+ /* Locked */
+ unsigned int references;
+ dns_viewlist_t viewlist;
+ ISC_LIST(struct resctx) resctxs;
+ ISC_LIST(struct reqctx) reqctxs;
+ ISC_LIST(struct updatectx) updatectxs;
+};
+
+/*%
+ * Timeout/retry constants for dynamic update borrowed from nsupdate
+ */
+#define DEF_UPDATE_TIMEOUT 300
+#define MIN_UPDATE_TIMEOUT 30
+#define DEF_UPDATE_UDPTIMEOUT 3
+#define DEF_UPDATE_UDPRETRIES 3
+
+#define DEF_FIND_TIMEOUT 5
+#define DEF_FIND_UDPRETRIES 3
+
+#define DNS_CLIENTATTR_OWNCTX 0x01
+
+#define DNS_CLIENTVIEW_NAME "dnsclient"
+
+/*%
+ * Internal state for a single name resolution procedure
+ */
+typedef struct resctx {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_client_t *client;
+ isc_boolean_t want_dnssec;
+
+ /* Locked */
+ ISC_LINK(struct resctx) link;
+ isc_task_t *task;
+ dns_view_t *view;
+ unsigned int restarts;
+ dns_fixedname_t name;
+ dns_rdatatype_t type;
+ dns_fetch_t *fetch;
+ dns_namelist_t namelist;
+ isc_result_t result;
+ dns_clientresevent_t *event;
+ isc_boolean_t canceled;
+ dns_rdataset_t *rdataset;
+ dns_rdataset_t *sigrdataset;
+} resctx_t;
+
+/*%
+ * Argument of an internal event for synchronous name resolution.
+ */
+typedef struct resarg {
+ /* Unlocked */
+ isc_appctx_t *actx;
+ dns_client_t *client;
+ isc_mutex_t lock;
+
+ /* Locked */
+ isc_result_t result;
+ isc_result_t vresult;
+ dns_namelist_t *namelist;
+ dns_clientrestrans_t *trans;
+ isc_boolean_t canceled;
+} resarg_t;
+
+/*%
+ * Internal state for a single DNS request
+ */
+typedef struct reqctx {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_client_t *client;
+ unsigned int parseoptions;
+
+ /* Locked */
+ ISC_LINK(struct reqctx) link;
+ isc_boolean_t canceled;
+ dns_tsigkey_t *tsigkey;
+ dns_request_t *request;
+ dns_clientreqevent_t *event;
+} reqctx_t;
+
+/*%
+ * Argument of an internal event for synchronous DNS request.
+ */
+typedef struct reqarg {
+ /* Unlocked */
+ isc_appctx_t *actx;
+ dns_client_t *client;
+ isc_mutex_t lock;
+
+ /* Locked */
+ isc_result_t result;
+ dns_clientreqtrans_t *trans;
+ isc_boolean_t canceled;
+} reqarg_t;
+
+/*%
+ * Argument of an internal event for synchronous name resolution.
+ */
+typedef struct updatearg {
+ /* Unlocked */
+ isc_appctx_t *actx;
+ dns_client_t *client;
+ isc_mutex_t lock;
+
+ /* Locked */
+ isc_result_t result;
+ dns_clientupdatetrans_t *trans;
+ isc_boolean_t canceled;
+} updatearg_t;
+
+/*%
+ * Internal state for a single dynamic update procedure
+ */
+typedef struct updatectx {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_client_t *client;
+
+ /* Locked */
+ dns_request_t *updatereq;
+ dns_request_t *soareq;
+ dns_clientrestrans_t *restrans;
+ dns_clientrestrans_t *restrans2;
+ isc_boolean_t canceled;
+
+ /* Task Locked */
+ ISC_LINK(struct updatectx) link;
+ dns_clientupdatestate_t state;
+ dns_rdataclass_t rdclass;
+ dns_view_t *view;
+ dns_message_t *updatemsg;
+ dns_message_t *soaquery;
+ dns_clientupdateevent_t *event;
+ dns_tsigkey_t *tsigkey;
+ dst_key_t *sig0key;
+ dns_name_t *firstname;
+ dns_name_t soaqname;
+ dns_fixedname_t zonefname;
+ dns_name_t *zonename;
+ isc_sockaddrlist_t servers;
+ unsigned int nservers;
+ isc_sockaddr_t *currentserver;
+ struct updatectx *bp4;
+ struct updatectx *bp6;
+} updatectx_t;
+
+static isc_result_t request_soa(updatectx_t *uctx);
+static void client_resfind(resctx_t *rctx, dns_fetchevent_t *event);
+static isc_result_t send_update(updatectx_t *uctx);
+
+static isc_result_t
+getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
+ isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
+ isc_boolean_t is_shared, dns_dispatch_t **dispp)
+{
+ unsigned int attrs, attrmask;
+ isc_sockaddr_t sa;
+ dns_dispatch_t *disp;
+ unsigned buffersize, maxbuffers, maxrequests, buckets, increment;
+ isc_result_t result;
+
+ attrs = 0;
+ attrs |= DNS_DISPATCHATTR_UDP;
+ switch (family) {
+ case AF_INET:
+ attrs |= DNS_DISPATCHATTR_IPV4;
+ break;
+ case AF_INET6:
+ attrs |= DNS_DISPATCHATTR_IPV6;
+ break;
+ default:
+ INSIST(0);
+ }
+ attrmask = 0;
+ attrmask |= DNS_DISPATCHATTR_UDP;
+ attrmask |= DNS_DISPATCHATTR_TCP;
+ attrmask |= DNS_DISPATCHATTR_IPV4;
+ attrmask |= DNS_DISPATCHATTR_IPV6;
+
+ isc_sockaddr_anyofpf(&sa, family);
+
+ buffersize = 4096;
+ maxbuffers = is_shared ? 1000 : 8;
+ maxrequests = 32768;
+ buckets = is_shared ? 16411 : 3;
+ increment = is_shared ? 16433 : 5;
+
+ disp = NULL;
+ result = dns_dispatch_getudp(dispatchmgr, socketmgr,
+ taskmgr, &sa,
+ buffersize, maxbuffers, maxrequests,
+ buckets, increment,
+ attrs, attrmask, &disp);
+ if (result == ISC_R_SUCCESS)
+ *dispp = disp;
+
+ return (result);
+}
+
+static isc_result_t
+dns_client_createview(isc_mem_t *mctx, dns_rdataclass_t rdclass,
+ unsigned int options, isc_taskmgr_t *taskmgr,
+ unsigned int ntasks, isc_socketmgr_t *socketmgr,
+ isc_timermgr_t *timermgr, dns_dispatchmgr_t *dispatchmgr,
+ dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
+ dns_view_t **viewp)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+ const char *dbtype;
+
+ result = dns_view_create(mctx, rdclass, DNS_CLIENTVIEW_NAME, &view);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Workaround for a recent change in dns_view_create(): proactively
+ * create view->secroots if it's not created with view creation.
+ */
+ if (view->secroots == NULL) {
+ result = dns_keytable_create(mctx, &view->secroots);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+ }
+
+ result = dns_view_createresolver(view, taskmgr, ntasks, socketmgr,
+ timermgr, 0, dispatchmgr,
+ dispatchv4, dispatchv6);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+
+ /*
+ * Set cache DB.
+ * XXX: it may be better if specific DB implementations can be
+ * specified via some configuration knob.
+ */
+ if ((options & DNS_CLIENTCREATEOPT_USECACHE) != 0)
+ dbtype = "rbt";
+ else
+ dbtype = "ecdb";
+ result = dns_db_create(mctx, dbtype, dns_rootname, dns_dbtype_cache,
+ rdclass, 0, NULL, &view->cachedb);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+
+ *viewp = view;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_client_create(dns_client_t **clientp, unsigned int options) {
+ isc_result_t result;
+ isc_mem_t *mctx = NULL;
+ isc_appctx_t *actx = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_appctx_create(mctx, &actx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_app_ctxstart(actx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_socketmgr_createinctx(mctx, actx, &socketmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_timermgr_createinctx(mctx, actx, &timermgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
+ options, clientp);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ (*clientp)->attributes |= DNS_CLIENTATTR_OWNCTX;
+
+ /* client has its own reference to mctx, so we can detach it here */
+ isc_mem_detach(&mctx);
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (timermgr != NULL)
+ isc_timermgr_destroy(&timermgr);
+ if (socketmgr != NULL)
+ isc_socketmgr_destroy(&socketmgr);
+ if (taskmgr != NULL)
+ isc_taskmgr_destroy(&taskmgr);
+ if (actx != NULL)
+ isc_appctx_destroy(&actx);
+ isc_mem_detach(&mctx);
+
+ return (result);
+}
+
+isc_result_t
+dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
+ isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
+ unsigned int options, dns_client_t **clientp)
+{
+ dns_client_t *client;
+ isc_result_t result;
+ dns_dispatchmgr_t *dispatchmgr = NULL;
+ dns_dispatch_t *dispatchv4 = NULL;
+ dns_dispatch_t *dispatchv6 = NULL;
+ dns_view_t *view = NULL;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(taskmgr != NULL);
+ REQUIRE(timermgr != NULL);
+ REQUIRE(socketmgr != NULL);
+ REQUIRE(clientp != NULL && *clientp == NULL);
+
+ client = isc_mem_get(mctx, sizeof(*client));
+ if (client == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&client->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, client, sizeof(*client));
+ return (result);
+ }
+
+ client->actx = actx;
+ client->taskmgr = taskmgr;
+ client->socketmgr = socketmgr;
+ client->timermgr = timermgr;
+
+ client->task = NULL;
+ result = isc_task_create(client->taskmgr, 0, &client->task);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->dispatchmgr = dispatchmgr;
+
+ /* TODO: whether to use dispatch v4 or v6 should be configurable */
+ result = getudpdispatch(AF_INET, dispatchmgr, socketmgr,
+ taskmgr, ISC_TRUE, &dispatchv4);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->dispatchv4 = dispatchv4;
+ result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr,
+ taskmgr, ISC_TRUE, &dispatchv6);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->dispatchv6 = dispatchv6;
+
+ /* Create the default view for class IN */
+ result = dns_client_createview(mctx, dns_rdataclass_in, options,
+ taskmgr, 31, socketmgr, timermgr,
+ dispatchmgr, dispatchv4, dispatchv6,
+ &view);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ ISC_LIST_INIT(client->viewlist);
+ ISC_LIST_APPEND(client->viewlist, view, link);
+
+ dns_view_freeze(view); /* too early? */
+
+ ISC_LIST_INIT(client->resctxs);
+ ISC_LIST_INIT(client->reqctxs);
+ ISC_LIST_INIT(client->updatectxs);
+
+ client->mctx = NULL;
+ isc_mem_attach(mctx, &client->mctx);
+
+ client->update_timeout = DEF_UPDATE_TIMEOUT;
+ client->update_udptimeout = DEF_UPDATE_UDPTIMEOUT;
+ client->update_udpretries = DEF_UPDATE_UDPRETRIES;
+ client->find_timeout = DEF_FIND_TIMEOUT;
+ client->find_udpretries = DEF_FIND_UDPRETRIES;
+
+ client->references = 1;
+ client->magic = DNS_CLIENT_MAGIC;
+
+ *clientp = client;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (dispatchv4 != NULL)
+ dns_dispatch_detach(&dispatchv4);
+ if (dispatchv6 != NULL)
+ dns_dispatch_detach(&dispatchv6);
+ if (dispatchmgr != NULL)
+ dns_dispatchmgr_destroy(&dispatchmgr);
+ if (client->task != NULL)
+ isc_task_detach(&client->task);
+ isc_mem_put(mctx, client, sizeof(*client));
+
+ return (result);
+}
+
+static void
+destroyclient(dns_client_t **clientp) {
+ dns_client_t *client = *clientp;
+ dns_view_t *view;
+
+ while ((view = ISC_LIST_HEAD(client->viewlist)) != NULL) {
+ ISC_LIST_UNLINK(client->viewlist, view, link);
+ dns_view_detach(&view);
+ }
+
+ if (client->dispatchv4 != NULL)
+ dns_dispatch_detach(&client->dispatchv4);
+ if (client->dispatchv6 != NULL)
+ dns_dispatch_detach(&client->dispatchv6);
+
+ dns_dispatchmgr_destroy(&client->dispatchmgr);
+
+ isc_task_detach(&client->task);
+
+ /*
+ * If the client has created its own running environments,
+ * destroy them.
+ */
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) != 0) {
+ isc_taskmgr_destroy(&client->taskmgr);
+ isc_timermgr_destroy(&client->timermgr);
+ isc_socketmgr_destroy(&client->socketmgr);
+
+ isc_app_ctxfinish(client->actx);
+ isc_appctx_destroy(&client->actx);
+ }
+
+ DESTROYLOCK(&client->lock);
+ client->magic = 0;
+
+ isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
+
+ *clientp = NULL;
+}
+
+void
+dns_client_destroy(dns_client_t **clientp) {
+ dns_client_t *client;
+ isc_boolean_t destroyok = ISC_FALSE;
+
+ REQUIRE(clientp != NULL);
+ client = *clientp;
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ LOCK(&client->lock);
+ client->references--;
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs)) {
+ destroyok = ISC_TRUE;
+ }
+ UNLOCK(&client->lock);
+
+ if (destroyok)
+ destroyclient(&client);
+
+ *clientp = NULL;
+}
+
+isc_result_t
+dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace, isc_sockaddrlist_t *addrs)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(addrs != NULL);
+
+ if (namespace == NULL)
+ namespace = dns_rootname;
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ if (result != ISC_R_SUCCESS) {
+ UNLOCK(&client->lock);
+ return (result);
+ }
+ UNLOCK(&client->lock);
+
+ result = dns_fwdtable_add(view->fwdtable, namespace, addrs,
+ dns_fwdpolicy_only);
+
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+isc_result_t
+dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ if (namespace == NULL)
+ namespace = dns_rootname;
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ if (result != ISC_R_SUCCESS) {
+ UNLOCK(&client->lock);
+ return (result);
+ }
+ UNLOCK(&client->lock);
+
+ result = dns_fwdtable_delete(view->fwdtable, namespace);
+
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+static isc_result_t
+getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
+ dns_rdataset_t *rdataset;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
+
+ rdataset = isc_mem_get(mctx, sizeof(*rdataset));
+ if (rdataset == NULL)
+ return (ISC_R_NOMEMORY);
+
+ dns_rdataset_init(rdataset);
+
+ *rdatasetp = rdataset;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+putrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
+ dns_rdataset_t *rdataset;
+
+ REQUIRE(rdatasetp != NULL);
+ rdataset = *rdatasetp;
+ REQUIRE(rdataset != NULL);
+
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+
+ isc_mem_put(mctx, rdataset, sizeof(*rdataset));
+
+ *rdatasetp = NULL;
+}
+
+static void
+fetch_done(isc_task_t *task, isc_event_t *event) {
+ resctx_t *rctx = event->ev_arg;
+ dns_fetchevent_t *fevent;
+
+ REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
+ REQUIRE(RCTX_VALID(rctx));
+ REQUIRE(rctx->task == task);
+ fevent = (dns_fetchevent_t *)event;
+
+ client_resfind(rctx, fevent);
+}
+
+static inline isc_result_t
+start_fetch(resctx_t *rctx) {
+ isc_result_t result;
+
+ /*
+ * The caller must be holding the rctx's lock.
+ */
+
+ REQUIRE(rctx->fetch == NULL);
+
+ result = dns_resolver_createfetch(rctx->view->resolver,
+ dns_fixedname_name(&rctx->name),
+ rctx->type,
+ NULL, NULL, NULL, 0,
+ rctx->task, fetch_done, rctx,
+ rctx->rdataset,
+ rctx->sigrdataset,
+ &rctx->fetch);
+
+ return (result);
+}
+
+static isc_result_t
+view_find(resctx_t *rctx, dns_db_t **dbp, dns_dbnode_t **nodep,
+ dns_name_t *foundname)
+{
+ isc_result_t result;
+ dns_name_t *name = dns_fixedname_name(&rctx->name);
+ dns_rdatatype_t type;
+
+ if (rctx->type == dns_rdatatype_rrsig)
+ type = dns_rdatatype_any;
+ else
+ type = rctx->type;
+
+ result = dns_view_find(rctx->view, name, type, 0, 0, ISC_FALSE,
+ dbp, nodep, foundname, rctx->rdataset,
+ rctx->sigrdataset);
+
+ return (result);
+}
+
+static void
+client_resfind(resctx_t *rctx, dns_fetchevent_t *event) {
+ isc_mem_t *mctx;
+ isc_result_t result, tresult;
+ isc_result_t vresult = ISC_R_SUCCESS;
+ isc_boolean_t want_restart;
+ isc_boolean_t send_event = ISC_FALSE;
+ dns_name_t *name, *prefix;
+ dns_fixedname_t foundname, fixed;
+ dns_rdataset_t *trdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ unsigned int nlabels;
+ int order;
+ dns_namereln_t namereln;
+ dns_rdata_cname_t cname;
+ dns_rdata_dname_t dname;
+
+ REQUIRE(RCTX_VALID(rctx));
+
+ LOCK(&rctx->lock);
+
+ mctx = rctx->view->mctx;
+
+ result = ISC_R_SUCCESS;
+ name = dns_fixedname_name(&rctx->name);
+
+ do {
+ dns_name_t *fname = NULL;
+ dns_name_t *ansname = NULL;
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+
+ rctx->restarts++;
+ want_restart = ISC_FALSE;
+
+ if (event == NULL && !rctx->canceled) {
+ dns_fixedname_init(&foundname);
+ fname = dns_fixedname_name(&foundname);
+ INSIST(!dns_rdataset_isassociated(rctx->rdataset));
+ INSIST(rctx->sigrdataset == NULL ||
+ !dns_rdataset_isassociated(rctx->sigrdataset));
+ result = view_find(rctx, &db, &node, fname);
+ if (result == ISC_R_NOTFOUND) {
+ /*
+ * We don't know anything about the name.
+ * Launch a fetch.
+ */
+ if (node != NULL) {
+ INSIST(db != NULL);
+ dns_db_detachnode(db, &node);
+ }
+ if (db != NULL)
+ dns_db_detach(&db);
+ result = start_fetch(rctx);
+ if (result != ISC_R_SUCCESS) {
+ putrdataset(mctx, &rctx->rdataset);
+ if (rctx->sigrdataset != NULL)
+ putrdataset(mctx,
+ &rctx->sigrdataset);
+ send_event = ISC_TRUE;
+ }
+ goto done;
+ }
+ } else {
+ INSIST(event->fetch == rctx->fetch);
+ dns_resolver_destroyfetch(&rctx->fetch);
+ db = event->db;
+ node = event->node;
+ result = event->result;
+ vresult = event->vresult;
+ fname = dns_fixedname_name(&event->foundname);
+ INSIST(event->rdataset == rctx->rdataset);
+ INSIST(event->sigrdataset == rctx->sigrdataset);
+ }
+
+ /*
+ * If we've been canceled, forget about the result.
+ */
+ if (rctx->canceled)
+ result = ISC_R_CANCELED;
+ else {
+ /*
+ * Otherwise, get some resource for copying the
+ * result.
+ */
+ ansname = isc_mem_get(mctx, sizeof(*ansname));
+ if (ansname == NULL)
+ tresult = ISC_R_NOMEMORY;
+ else {
+ dns_name_t *aname;
+
+ aname = dns_fixedname_name(&rctx->name);
+ dns_name_init(ansname, NULL);
+ tresult = dns_name_dup(aname, mctx, ansname);
+ if (tresult != ISC_R_SUCCESS)
+ isc_mem_put(mctx, ansname,
+ sizeof(*ansname));
+ }
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+ }
+
+ switch (result) {
+ case ISC_R_SUCCESS:
+ send_event = ISC_TRUE;
+ /*
+ * This case is handled in the main line below.
+ */
+ break;
+ case DNS_R_CNAME:
+ /*
+ * Add the CNAME to the answer list.
+ */
+ trdataset = rctx->rdataset;
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ rctx->rdataset = NULL;
+ if (rctx->sigrdataset != NULL) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->sigrdataset, link);
+ rctx->sigrdataset = NULL;
+ }
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+
+ /*
+ * Copy the CNAME's target into the lookup's
+ * query name and start over.
+ */
+ tresult = dns_rdataset_first(trdataset);
+ if (tresult != ISC_R_SUCCESS)
+ goto done;
+ dns_rdataset_current(trdataset, &rdata);
+ tresult = dns_rdata_tostruct(&rdata, &cname, NULL);
+ dns_rdata_reset(&rdata);
+ if (tresult != ISC_R_SUCCESS)
+ goto done;
+ tresult = dns_name_copy(&cname.cname, name, NULL);
+ dns_rdata_freestruct(&cname);
+ if (tresult == ISC_R_SUCCESS)
+ want_restart = ISC_TRUE;
+ else
+ result = tresult;
+ goto done;
+ case DNS_R_DNAME:
+ /*
+ * Add the DNAME to the answer list.
+ */
+ trdataset = rctx->rdataset;
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ rctx->rdataset = NULL;
+ if (rctx->sigrdataset != NULL) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->sigrdataset, link);
+ rctx->sigrdataset = NULL;
+ }
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+
+ namereln = dns_name_fullcompare(name, fname, &order,
+ &nlabels);
+ INSIST(namereln == dns_namereln_subdomain);
+ /*
+ * Get the target name of the DNAME.
+ */
+ tresult = dns_rdataset_first(trdataset);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ goto done;
+ }
+ dns_rdataset_current(trdataset, &rdata);
+ tresult = dns_rdata_tostruct(&rdata, &dname, NULL);
+ dns_rdata_reset(&rdata);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ goto done;
+ }
+ /*
+ * Construct the new query name and start over.
+ */
+ dns_fixedname_init(&fixed);
+ prefix = dns_fixedname_name(&fixed);
+ dns_name_split(name, nlabels, prefix, NULL);
+ tresult = dns_name_concatenate(prefix, &dname.dname,
+ name, NULL);
+ dns_rdata_freestruct(&dname);
+ if (tresult == ISC_R_SUCCESS)
+ want_restart = ISC_TRUE;
+ else
+ result = tresult;
+ goto done;
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NCACHENXRRSET:
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+ rctx->rdataset = NULL;
+ /* What about sigrdataset? */
+ if (rctx->sigrdataset != NULL)
+ putrdataset(mctx, &rctx->sigrdataset);
+ send_event = ISC_TRUE;
+ goto done;
+ default:
+ if (rctx->rdataset != NULL)
+ putrdataset(mctx, &rctx->rdataset);
+ if (rctx->sigrdataset != NULL)
+ putrdataset(mctx, &rctx->sigrdataset);
+ send_event = ISC_TRUE;
+ goto done;
+ }
+
+ if (rctx->type == dns_rdatatype_any) {
+ int n = 0;
+ dns_rdatasetiter_t *rdsiter = NULL;
+
+ tresult = dns_db_allrdatasets(db, node, NULL, 0,
+ &rdsiter);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ goto done;
+ }
+
+ tresult = dns_rdatasetiter_first(rdsiter);
+ while (tresult == ISC_R_SUCCESS) {
+ dns_rdatasetiter_current(rdsiter,
+ rctx->rdataset);
+ if (rctx->rdataset->type != 0) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->rdataset,
+ link);
+ n++;
+ rctx->rdataset = NULL;
+ } else {
+ /*
+ * We're not interested in this
+ * rdataset.
+ */
+ dns_rdataset_disassociate(
+ rctx->rdataset);
+ }
+ tresult = dns_rdatasetiter_next(rdsiter);
+
+ if (tresult == ISC_R_SUCCESS &&
+ rctx->rdataset == NULL) {
+ tresult = getrdataset(mctx,
+ &rctx->rdataset);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ break;
+ }
+ }
+ }
+ if (n == 0) {
+ /*
+ * We didn't match any rdatasets (which means
+ * something went wrong in this
+ * implementation).
+ */
+ result = DNS_R_SERVFAIL; /* better code? */
+ } else {
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ if (tresult != ISC_R_NOMORE)
+ result = DNS_R_SERVFAIL; /* ditto */
+ else
+ result = ISC_R_SUCCESS;
+ goto done;
+ } else {
+ /*
+ * This is the "normal" case -- an ordinary question
+ * to which we've got the answer.
+ */
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ rctx->rdataset = NULL;
+ if (rctx->sigrdataset != NULL) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->sigrdataset, link);
+ rctx->sigrdataset = NULL;
+ }
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+ }
+
+ done:
+ /*
+ * Free temporary resources
+ */
+ if (ansname != NULL) {
+ dns_rdataset_t *rdataset;
+
+ while ((rdataset = ISC_LIST_HEAD(ansname->list))
+ != NULL) {
+ ISC_LIST_UNLINK(ansname->list, rdataset, link);
+ putrdataset(mctx, &rdataset);
+ }
+ dns_name_free(ansname, mctx);
+ isc_mem_put(mctx, ansname, sizeof(*ansname));
+ }
+
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (db != NULL)
+ dns_db_detach(&db);
+ if (event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&event));
+
+ /*
+ * Limit the number of restarts.
+ */
+ if (want_restart && rctx->restarts == MAX_RESTARTS) {
+ want_restart = ISC_FALSE;
+ result = ISC_R_QUOTA;
+ send_event = ISC_TRUE;
+ }
+
+ /*
+ * Prepare further find with new resources
+ */
+ if (want_restart) {
+ INSIST(rctx->rdataset == NULL &&
+ rctx->sigrdataset == NULL);
+
+ result = getrdataset(mctx, &rctx->rdataset);
+ if (result == ISC_R_SUCCESS && rctx->want_dnssec) {
+ result = getrdataset(mctx, &rctx->sigrdataset);
+ if (result != ISC_R_SUCCESS) {
+ putrdataset(mctx, &rctx->rdataset);
+ }
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ want_restart = ISC_FALSE;
+ send_event = ISC_TRUE;
+ }
+ }
+ } while (want_restart);
+
+ if (send_event) {
+ isc_task_t *task;
+
+ while ((name = ISC_LIST_HEAD(rctx->namelist)) != NULL) {
+ ISC_LIST_UNLINK(rctx->namelist, name, link);
+ ISC_LIST_APPEND(rctx->event->answerlist, name, link);
+ }
+
+ rctx->event->result = result;
+ rctx->event->vresult = vresult;
+ task = rctx->event->ev_sender;
+ rctx->event->ev_sender = rctx;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&rctx->event));
+ }
+
+ UNLOCK(&rctx->lock);
+}
+
+static void
+resolve_done(isc_task_t *task, isc_event_t *event) {
+ resarg_t *resarg = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+
+ UNUSED(task);
+
+ LOCK(&resarg->lock);
+
+ resarg->result = rev->result;
+ resarg->vresult = rev->vresult;
+ while ((name = ISC_LIST_HEAD(rev->answerlist)) != NULL) {
+ ISC_LIST_UNLINK(rev->answerlist, name, link);
+ ISC_LIST_APPEND(*resarg->namelist, name, link);
+ }
+
+ dns_client_destroyrestrans(&resarg->trans);
+ isc_event_free(&event);
+
+ if (!resarg->canceled) {
+ UNLOCK(&resarg->lock);
+
+ /* Exit from the internal event loop */
+ isc_app_ctxsuspend(resarg->actx);
+ } else {
+ /*
+ * We have already exited from the loop (due to some
+ * unexpected event). Just clean the arg up.
+ */
+ UNLOCK(&resarg->lock);
+ DESTROYLOCK(&resarg->lock);
+ isc_mem_put(resarg->client->mctx, resarg, sizeof(*resarg));
+ }
+}
+
+isc_result_t
+dns_client_resolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, dns_namelist_t *namelist)
+{
+ isc_result_t result;
+ isc_appctx_t *actx;
+ resarg_t *resarg;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(namelist != NULL && ISC_LIST_EMPTY(*namelist));
+
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 &&
+ (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) {
+ /*
+ * If the client is run under application's control, we need
+ * to create a new running (sub)environment for this
+ * particular resolution.
+ */
+ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */
+ } else
+ actx = client->actx;
+
+ resarg = isc_mem_get(client->mctx, sizeof(*resarg));
+ if (resarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&resarg->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, resarg, sizeof(*resarg));
+ return (result);
+ }
+
+ resarg->actx = actx;
+ resarg->client = client;
+ resarg->result = DNS_R_SERVFAIL;
+ resarg->namelist = namelist;
+ resarg->trans = NULL;
+ resarg->canceled = ISC_FALSE;
+ result = dns_client_startresolve(client, name, rdclass, type, options,
+ client->task, resolve_done, resarg,
+ &resarg->trans);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&resarg->lock);
+ isc_mem_put(client->mctx, resarg, sizeof(*resarg));
+ return (result);
+ }
+
+ /*
+ * Start internal event loop. It blocks until the entire process
+ * is completed.
+ */
+ result = isc_app_ctxrun(actx);
+
+ LOCK(&resarg->lock);
+ if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND)
+ result = resarg->result;
+ if (result != ISC_R_SUCCESS && resarg->vresult != ISC_R_SUCCESS) {
+ /*
+ * If this lookup failed due to some error in DNSSEC
+ * validation, return the validation error code.
+ * XXX: or should we pass the validation result separately?
+ */
+ result = resarg->vresult;
+ }
+ if (resarg->trans != NULL) {
+ /*
+ * Unusual termination (perhaps due to signal). We need some
+ * tricky cleanup process.
+ */
+ resarg->canceled = ISC_TRUE;
+ dns_client_cancelresolve(resarg->trans);
+
+ UNLOCK(&resarg->lock);
+
+ /* resarg will be freed in the event handler. */
+ } else {
+ UNLOCK(&resarg->lock);
+
+ DESTROYLOCK(&resarg->lock);
+ isc_mem_put(client->mctx, resarg, sizeof(*resarg));
+ }
+
+ return (result);
+}
+
+isc_result_t
+dns_client_startresolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_clientrestrans_t **transp)
+{
+ dns_view_t *view = NULL;
+ dns_clientresevent_t *event = NULL;
+ resctx_t *rctx = NULL;
+ isc_task_t *clone = NULL;
+ isc_mem_t *mctx;
+ isc_result_t result;
+ dns_rdataset_t *rdataset, *sigrdataset;
+ isc_boolean_t want_dnssec;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(transp != NULL && *transp == NULL);
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ mctx = client->mctx;
+ rdataset = NULL;
+ sigrdataset = NULL;
+ want_dnssec = ISC_TF((options & DNS_CLIENTRESOPT_NODNSSEC) == 0);
+
+ /*
+ * Prepare some intermediate resources
+ */
+ clone = NULL;
+ isc_task_attach(task, &clone);
+ event = (dns_clientresevent_t *)
+ isc_event_allocate(mctx, clone, DNS_EVENT_CLIENTRESDONE,
+ action, arg, sizeof(*event));
+ if (event == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ event->result = DNS_R_SERVFAIL;
+ ISC_LIST_INIT(event->answerlist);
+
+ rctx = isc_mem_get(mctx, sizeof(*rctx));
+ if (rctx == NULL)
+ result = ISC_R_NOMEMORY;
+ else {
+ result = isc_mutex_init(&rctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, rctx, sizeof(*rctx));
+ rctx = NULL;
+ }
+ }
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = getrdataset(mctx, &rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ rctx->rdataset = rdataset;
+
+ if (want_dnssec) {
+ result = getrdataset(mctx, &sigrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ rctx->sigrdataset = sigrdataset;
+
+ dns_fixedname_init(&rctx->name);
+ result = dns_name_copy(name, dns_fixedname_name(&rctx->name), NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ rctx->client = client;
+ ISC_LINK_INIT(rctx, link);
+ rctx->canceled = ISC_FALSE;
+ rctx->task = client->task;
+ rctx->type = type;
+ rctx->view = view;
+ rctx->restarts = 0;
+ rctx->fetch = NULL;
+ rctx->want_dnssec = want_dnssec;
+ ISC_LIST_INIT(rctx->namelist);
+ rctx->event = event;
+
+ rctx->magic = RCTX_MAGIC;
+
+ LOCK(&client->lock);
+ ISC_LIST_APPEND(client->resctxs, rctx, link);
+ UNLOCK(&client->lock);
+
+ client_resfind(rctx, NULL);
+
+ *transp = (dns_clientrestrans_t *)rctx;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (rdataset != NULL)
+ putrdataset(client->mctx, &rdataset);
+ if (sigrdataset != NULL)
+ putrdataset(client->mctx, &sigrdataset);
+ if (rctx != NULL) {
+ DESTROYLOCK(&rctx->lock);
+ isc_mem_put(mctx, rctx, sizeof(*rctx));
+ }
+ if (event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&event));
+ isc_task_detach(&clone);
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+void
+dns_client_cancelresolve(dns_clientrestrans_t *trans) {
+ resctx_t *rctx;
+
+ REQUIRE(trans != NULL);
+ rctx = (resctx_t *)trans;
+ REQUIRE(RCTX_VALID(rctx));
+
+ LOCK(&rctx->lock);
+
+ if (!rctx->canceled) {
+ rctx->canceled = ISC_TRUE;
+ if (rctx->fetch != NULL)
+ dns_resolver_cancelfetch(rctx->fetch);
+ }
+
+ UNLOCK(&rctx->lock);
+}
+
+void
+dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist) {
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(namelist != NULL);
+
+ while ((name = ISC_LIST_HEAD(*namelist)) != NULL) {
+ ISC_LIST_UNLINK(*namelist, name, link);
+ while ((rdataset = ISC_LIST_HEAD(name->list)) != NULL) {
+ ISC_LIST_UNLINK(name->list, rdataset, link);
+ putrdataset(client->mctx, &rdataset);
+ }
+ dns_name_free(name, client->mctx);
+ isc_mem_put(client->mctx, name, sizeof(*name));
+ }
+}
+
+void
+dns_client_destroyrestrans(dns_clientrestrans_t **transp) {
+ resctx_t *rctx;
+ isc_mem_t *mctx;
+ dns_client_t *client;
+ isc_boolean_t need_destroyclient = ISC_FALSE;
+
+ REQUIRE(transp != NULL);
+ rctx = (resctx_t *)*transp;
+ REQUIRE(RCTX_VALID(rctx));
+ REQUIRE(rctx->fetch == NULL);
+ REQUIRE(rctx->event == NULL);
+ client = rctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ mctx = client->mctx;
+ dns_view_detach(&rctx->view);
+
+ LOCK(&client->lock);
+
+ INSIST(ISC_LINK_LINKED(rctx, link));
+ ISC_LIST_UNLINK(client->resctxs, rctx, link);
+
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs))
+ need_destroyclient = ISC_TRUE;
+
+ UNLOCK(&client->lock);
+
+ INSIST(ISC_LIST_EMPTY(rctx->namelist));
+
+ DESTROYLOCK(&rctx->lock);
+ rctx->magic = 0;
+
+ isc_mem_put(mctx, rctx, sizeof(*rctx));
+
+ if (need_destroyclient)
+ destroyclient(&client);
+
+ *transp = NULL;
+}
+
+isc_result_t
+dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *keyname, isc_buffer_t *keydatabuf)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+ dst_key_t *dstkey = NULL;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dst_key_fromdns(keyname, rdclass, keydatabuf, client->mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dns_keytable_add(view->secroots, ISC_FALSE, &dstkey);
+
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+/*%
+ * Simple request routines
+ */
+static void
+request_done(isc_task_t *task, isc_event_t *event) {
+ dns_requestevent_t *reqev = NULL;
+ dns_request_t *request;
+ isc_result_t result, eresult;
+ reqctx_t *ctx;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
+ reqev = (dns_requestevent_t *)event;
+ request = reqev->request;
+ result = eresult = reqev->result;
+ ctx = reqev->ev_arg;
+ REQUIRE(REQCTX_VALID(ctx));
+
+ isc_event_free(&event);
+
+ LOCK(&ctx->lock);
+
+ if (eresult == ISC_R_SUCCESS) {
+ result = dns_request_getresponse(request, ctx->event->rmessage,
+ ctx->parseoptions);
+ }
+
+ if (ctx->tsigkey != NULL)
+ dns_tsigkey_detach(&ctx->tsigkey);
+
+ if (ctx->canceled)
+ ctx->event->result = ISC_R_CANCELED;
+ else
+ ctx->event->result = result;
+ task = ctx->event->ev_sender;
+ ctx->event->ev_sender = ctx;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&ctx->event));
+
+ UNLOCK(&ctx->lock);
+}
+
+static void
+localrequest_done(isc_task_t *task, isc_event_t *event) {
+ reqarg_t *reqarg = event->ev_arg;
+ dns_clientreqevent_t *rev =(dns_clientreqevent_t *)event;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_CLIENTREQDONE);
+
+ LOCK(&reqarg->lock);
+
+ reqarg->result = rev->result;
+ dns_client_destroyreqtrans(&reqarg->trans);
+ isc_event_free(&event);
+
+ if (!reqarg->canceled) {
+ UNLOCK(&reqarg->lock);
+
+ /* Exit from the internal event loop */
+ isc_app_ctxsuspend(reqarg->actx);
+ } else {
+ /*
+ * We have already exited from the loop (due to some
+ * unexpected event). Just clean the arg up.
+ */
+ UNLOCK(&reqarg->lock);
+ DESTROYLOCK(&reqarg->lock);
+ isc_mem_put(reqarg->client->mctx, reqarg, sizeof(*reqarg));
+ }
+}
+
+isc_result_t
+dns_client_request(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries)
+{
+ isc_appctx_t *actx;
+ reqarg_t *reqarg;
+ isc_result_t result;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(qmessage != NULL);
+ REQUIRE(rmessage != NULL);
+
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 &&
+ (options & DNS_CLIENTREQOPT_ALLOWRUN) == 0) {
+ /*
+ * If the client is run under application's control, we need
+ * to create a new running (sub)environment for this
+ * particular resolution.
+ */
+ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */
+ } else
+ actx = client->actx;
+
+ reqarg = isc_mem_get(client->mctx, sizeof(*reqarg));
+ if (reqarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&reqarg->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, reqarg, sizeof(*reqarg));
+ return (result);
+ }
+
+ reqarg->actx = actx;
+ reqarg->client = client;
+ reqarg->trans = NULL;
+ reqarg->canceled = ISC_FALSE;
+
+ result = dns_client_startrequest(client, qmessage, rmessage, server,
+ options, parseoptions, tsec, timeout,
+ udptimeout, udpretries,
+ client->task, localrequest_done,
+ reqarg, &reqarg->trans);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&reqarg->lock);
+ isc_mem_put(client->mctx, reqarg, sizeof(*reqarg));
+ return (result);
+ }
+
+ /*
+ * Start internal event loop. It blocks until the entire process
+ * is completed.
+ */
+ result = isc_app_ctxrun(actx);
+
+ LOCK(&reqarg->lock);
+ if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND)
+ result = reqarg->result;
+ if (reqarg->trans != NULL) {
+ /*
+ * Unusual termination (perhaps due to signal). We need some
+ * tricky cleanup process.
+ */
+ reqarg->canceled = ISC_TRUE;
+ dns_client_cancelresolve(reqarg->trans);
+
+ UNLOCK(&reqarg->lock);
+
+ /* reqarg will be freed in the event handler. */
+ } else {
+ UNLOCK(&reqarg->lock);
+
+ DESTROYLOCK(&reqarg->lock);
+ isc_mem_put(client->mctx, reqarg, sizeof(*reqarg));
+ }
+
+ return (result);
+}
+
+isc_result_t
+dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientreqtrans_t **transp)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+ isc_task_t *clone = NULL;
+ dns_clientreqevent_t *event = NULL;
+ reqctx_t *ctx = NULL;
+ dns_tsectype_t tsectype = dns_tsectype_none;
+
+ UNUSED(options);
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(qmessage != NULL);
+ REQUIRE(rmessage != NULL);
+ REQUIRE(transp != NULL && *transp == NULL);
+
+ if (tsec != NULL) {
+ tsectype = dns_tsec_gettype(tsec);
+ if (tsectype != dns_tsectype_tsig)
+ return (ISC_R_NOTIMPLEMENTED); /* XXX */
+ }
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ qmessage->rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ clone = NULL;
+ isc_task_attach(task, &clone);
+ event = (dns_clientreqevent_t *)
+ isc_event_allocate(client->mctx, clone,
+ DNS_EVENT_CLIENTREQDONE,
+ action, arg, sizeof(*event));
+ if (event == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+
+ ctx = isc_mem_get(client->mctx, sizeof(*ctx));
+ if (ctx == NULL)
+ result = ISC_R_NOMEMORY;
+ else {
+ result = isc_mutex_init(&ctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, ctx, sizeof(*ctx));
+ ctx = NULL;
+ }
+ }
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ ctx->client = client;
+ ISC_LINK_INIT(ctx, link);
+ ctx->parseoptions = parseoptions;
+ ctx->canceled = ISC_FALSE;
+ ctx->event = event;
+ ctx->event->rmessage = rmessage;
+ ctx->tsigkey = NULL;
+ if (tsec != NULL)
+ dns_tsec_getkey(tsec, &ctx->tsigkey);
+
+ ctx->magic = REQCTX_MAGIC;
+
+ LOCK(&client->lock);
+ ISC_LIST_APPEND(client->reqctxs, ctx, link);
+ UNLOCK(&client->lock);
+
+ ctx->request = NULL;
+ result = dns_request_createvia3(view->requestmgr, qmessage, NULL,
+ server, options, ctx->tsigkey,
+ timeout, udptimeout, udpretries,
+ client->task, request_done, ctx,
+ &ctx->request);
+ if (result == ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ *transp = (dns_clientreqtrans_t *)ctx;
+ return (ISC_R_SUCCESS);
+ }
+
+ cleanup:
+ if (ctx != NULL) {
+ LOCK(&client->lock);
+ ISC_LIST_UNLINK(client->reqctxs, ctx, link);
+ UNLOCK(&client->lock);
+ DESTROYLOCK(&ctx->lock);
+ isc_mem_put(client->mctx, ctx, sizeof(*ctx));
+ }
+ if (event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&event));
+ isc_task_detach(&clone);
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+void
+dns_client_cancelrequest(dns_clientreqtrans_t *trans) {
+ reqctx_t *ctx;
+
+ REQUIRE(trans != NULL);
+ ctx = (reqctx_t *)trans;
+ REQUIRE(REQCTX_VALID(ctx));
+
+ LOCK(&ctx->lock);
+
+ if (!ctx->canceled) {
+ ctx->canceled = ISC_TRUE;
+ if (ctx->request != NULL)
+ dns_request_cancel(ctx->request);
+ }
+
+ UNLOCK(&ctx->lock);
+}
+
+void
+dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) {
+ reqctx_t *ctx;
+ isc_mem_t *mctx;
+ dns_client_t *client;
+ isc_boolean_t need_destroyclient = ISC_FALSE;
+
+ REQUIRE(transp != NULL);
+ ctx = (reqctx_t *)*transp;
+ REQUIRE(REQCTX_VALID(ctx));
+ client = ctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(ctx->event == NULL);
+ REQUIRE(ctx->request != NULL);
+
+ dns_request_destroy(&ctx->request);
+ mctx = client->mctx;
+
+ LOCK(&client->lock);
+
+ INSIST(ISC_LINK_LINKED(ctx, link));
+ ISC_LIST_UNLINK(client->reqctxs, ctx, link);
+
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs)) {
+ need_destroyclient = ISC_TRUE;
+ }
+
+ UNLOCK(&client->lock);
+
+ DESTROYLOCK(&ctx->lock);
+ ctx->magic = 0;
+
+ isc_mem_put(mctx, ctx, sizeof(*ctx));
+
+ if (need_destroyclient)
+ destroyclient(&client);
+
+ *transp = NULL;
+}
+
+/*%
+ * Dynamic update routines
+ */
+static isc_result_t
+rcode2result(dns_rcode_t rcode) {
+ /* XXX: isn't there a similar function? */
+ switch (rcode) {
+ case dns_rcode_formerr:
+ return (DNS_R_FORMERR);
+ case dns_rcode_servfail:
+ return (DNS_R_SERVFAIL);
+ case dns_rcode_nxdomain:
+ return (DNS_R_NXDOMAIN);
+ case dns_rcode_notimp:
+ return (DNS_R_NOTIMP);
+ case dns_rcode_refused:
+ return (DNS_R_REFUSED);
+ case dns_rcode_yxdomain:
+ return (DNS_R_YXDOMAIN);
+ case dns_rcode_yxrrset:
+ return (DNS_R_YXRRSET);
+ case dns_rcode_nxrrset:
+ return (DNS_R_NXRRSET);
+ case dns_rcode_notauth:
+ return (DNS_R_NOTAUTH);
+ case dns_rcode_notzone:
+ return (DNS_R_NOTZONE);
+ case dns_rcode_badvers:
+ return (DNS_R_BADVERS);
+ }
+
+ return (ISC_R_FAILURE);
+}
+
+static void
+update_sendevent(updatectx_t *uctx, isc_result_t result) {
+ isc_task_t *task;
+
+ dns_message_destroy(&uctx->updatemsg);
+ if (uctx->tsigkey != NULL)
+ dns_tsigkey_detach(&uctx->tsigkey);
+ if (uctx->sig0key != NULL)
+ dst_key_free(&uctx->sig0key);
+
+ if (uctx->canceled)
+ uctx->event->result = ISC_R_CANCELED;
+ else
+ uctx->event->result = result;
+ uctx->event->state = uctx->state;
+ task = uctx->event->ev_sender;
+ uctx->event->ev_sender = uctx;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&uctx->event));
+}
+
+static void
+update_done(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ dns_requestevent_t *reqev = NULL;
+ dns_request_t *request;
+ dns_message_t *answer = NULL;
+ updatectx_t *uctx = event->ev_arg;
+ dns_client_t *client;
+ unsigned int timeout;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
+ reqev = (dns_requestevent_t *)event;
+ request = reqev->request;
+ REQUIRE(UCTX_VALID(uctx));
+ client = uctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ result = reqev->result;
+ if (result != ISC_R_SUCCESS)
+ goto out;
+
+ result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
+ &answer);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ uctx->state = dns_clientupdatestate_done;
+ result = dns_request_getresponse(request, answer,
+ DNS_MESSAGEPARSE_PRESERVEORDER);
+ if (result == ISC_R_SUCCESS && answer->rcode != dns_rcode_noerror)
+ result = rcode2result(answer->rcode);
+
+ out:
+ if (answer != NULL)
+ dns_message_destroy(&answer);
+ isc_event_free(&event);
+
+ LOCK(&uctx->lock);
+ uctx->currentserver = ISC_LIST_NEXT(uctx->currentserver, link);
+ dns_request_destroy(&uctx->updatereq);
+ if (result != ISC_R_SUCCESS && !uctx->canceled &&
+ uctx->currentserver != NULL) {
+ dns_message_renderreset(uctx->updatemsg);
+ dns_message_settsigkey(uctx->updatemsg, NULL);
+
+ timeout = client->update_timeout / uctx->nservers;
+ if (timeout < MIN_UPDATE_TIMEOUT)
+ timeout = MIN_UPDATE_TIMEOUT;
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ uctx->updatemsg,
+ NULL,
+ uctx->currentserver, 0,
+ uctx->tsigkey,
+ timeout,
+ client->update_udptimeout,
+ client->update_udpretries,
+ client->task,
+ update_done, uctx,
+ &uctx->updatereq);
+ UNLOCK(&uctx->lock);
+
+ if (result == ISC_R_SUCCESS) {
+ /* XXX: should we keep the 'done' state here? */
+ uctx->state = dns_clientupdatestate_sent;
+ return;
+ }
+ } else
+ UNLOCK(&uctx->lock);
+
+ update_sendevent(uctx, result);
+}
+
+static isc_result_t
+send_update(updatectx_t *uctx) {
+ isc_result_t result;
+ dns_name_t *name = NULL;
+ dns_rdataset_t *rdataset = NULL;
+ dns_client_t *client = uctx->client;
+ unsigned int timeout;
+
+ REQUIRE(uctx->zonename != NULL && uctx->currentserver != NULL);
+
+ result = dns_message_gettempname(uctx->updatemsg, &name);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ dns_name_init(name, NULL);
+ dns_name_clone(uctx->zonename, name);
+ result = dns_message_gettemprdataset(uctx->updatemsg, &rdataset);
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(uctx->updatemsg, &name);
+ return (result);
+ }
+ dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa);
+ ISC_LIST_INIT(name->list);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+ dns_message_addname(uctx->updatemsg, name, DNS_SECTION_ZONE);
+ if (uctx->tsigkey == NULL && uctx->sig0key != NULL) {
+ result = dns_message_setsig0key(uctx->updatemsg,
+ uctx->sig0key);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ timeout = client->update_timeout / uctx->nservers;
+ if (timeout < MIN_UPDATE_TIMEOUT)
+ timeout = MIN_UPDATE_TIMEOUT;
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ uctx->updatemsg,
+ NULL, uctx->currentserver, 0,
+ uctx->tsigkey, timeout,
+ client->update_udptimeout,
+ client->update_udpretries,
+ client->task, update_done, uctx,
+ &uctx->updatereq);
+ if (result == ISC_R_SUCCESS &&
+ uctx->state == dns_clientupdatestate_prepare) {
+ uctx->state = dns_clientupdatestate_sent;
+ }
+
+ return (result);
+}
+
+static void
+resolveaddr_done(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ int family;
+ dns_rdatatype_t qtype;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ updatectx_t *uctx;
+ isc_boolean_t completed = ISC_FALSE;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_arg != NULL);
+ uctx = *(updatectx_t **)event->ev_arg;
+ REQUIRE(UCTX_VALID(uctx));
+
+ if (event->ev_arg == &uctx->bp4) {
+ family = AF_INET;
+ qtype = dns_rdatatype_a;
+ LOCK(&uctx->lock);
+ dns_client_destroyrestrans(&uctx->restrans);
+ UNLOCK(&uctx->lock);
+ } else {
+ INSIST(event->ev_arg == &uctx->bp6);
+ family = AF_INET6;
+ qtype = dns_rdatatype_aaaa;
+ LOCK(&uctx->lock);
+ dns_client_destroyrestrans(&uctx->restrans2);
+ UNLOCK(&uctx->lock);
+ }
+
+ result = rev->result;
+ if (result != ISC_R_SUCCESS)
+ goto done;
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (!dns_rdataset_isassociated(rdataset))
+ continue;
+ if (rdataset->type != qtype)
+ continue;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata;
+ dns_rdata_in_a_t rdata_a;
+ dns_rdata_in_aaaa_t rdata_aaaa;
+ isc_sockaddr_t *sa;
+
+ sa = isc_mem_get(uctx->client->mctx,
+ sizeof(*sa));
+ if (sa == NULL) {
+ /*
+ * If we fail to get a sockaddr,
+ we simply move forward with the
+ * addresses we've got so far.
+ */
+ goto done;
+ }
+
+ dns_rdata_init(&rdata);
+ switch (family) {
+ case AF_INET:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+ isc_sockaddr_fromin(sa,
+ &rdata_a.in_addr,
+ 53);
+ dns_rdata_freestruct(&rdata_a);
+ break;
+ case AF_INET6:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_aaaa,
+ NULL);
+ isc_sockaddr_fromin6(sa,
+ &rdata_aaaa.in6_addr,
+ 53);
+ dns_rdata_freestruct(&rdata_aaaa);
+ break;
+ }
+
+ ISC_LINK_INIT(sa, link);
+ ISC_LIST_APPEND(uctx->servers, sa, link);
+ uctx->nservers++;
+ }
+ }
+ }
+
+ done:
+ dns_client_freeresanswer(uctx->client, &rev->answerlist);
+ isc_event_free(&event);
+
+ LOCK(&uctx->lock);
+ if (uctx->restrans == NULL && uctx->restrans2 == NULL)
+ completed = ISC_TRUE;
+ UNLOCK(&uctx->lock);
+
+ if (completed) {
+ INSIST(uctx->currentserver == NULL);
+ uctx->currentserver = ISC_LIST_HEAD(uctx->servers);
+ if (uctx->currentserver != NULL && !uctx->canceled)
+ send_update(uctx);
+ else {
+ if (result == ISC_R_SUCCESS)
+ result = ISC_R_NOTFOUND;
+ update_sendevent(uctx, result);
+ }
+ }
+}
+
+static isc_result_t
+process_soa(updatectx_t *uctx, dns_rdataset_t *soaset, dns_name_t *soaname) {
+ isc_result_t result;
+ dns_rdata_t soarr = DNS_RDATA_INIT;
+ dns_rdata_soa_t soa;
+ dns_name_t primary;
+
+ result = dns_rdataset_first(soaset);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ dns_rdata_init(&soarr);
+ dns_rdataset_current(soaset, &soarr);
+ result = dns_rdata_tostruct(&soarr, &soa, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_name_init(&primary, NULL);
+ dns_name_clone(&soa.origin, &primary);
+
+ if (uctx->zonename == NULL) {
+ uctx->zonename = dns_fixedname_name(&uctx->zonefname);
+ result = dns_name_copy(soaname, uctx->zonename, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ }
+
+ if (uctx->currentserver != NULL)
+ result = send_update(uctx);
+ else {
+ /*
+ * Get addresses of the primary server. We don't use the ADB
+ * feature so that we could avoid caching data.
+ */
+ LOCK(&uctx->lock);
+ uctx->bp4 = uctx;
+ result = dns_client_startresolve(uctx->client, &primary,
+ uctx->rdclass,
+ dns_rdatatype_a,
+ 0, uctx->client->task,
+ resolveaddr_done, &uctx->bp4,
+ &uctx->restrans);
+ if (result == ISC_R_SUCCESS) {
+ uctx->bp6 = uctx;
+ result = dns_client_startresolve(uctx->client,
+ &primary,
+ uctx->rdclass,
+ dns_rdatatype_aaaa,
+ 0, uctx->client->task,
+ resolveaddr_done,
+ &uctx->bp6,
+ &uctx->restrans2);
+ }
+ UNLOCK(&uctx->lock);
+ }
+
+ out:
+ dns_rdata_freestruct(&soa);
+
+ return (result);
+}
+
+static void
+receive_soa(isc_task_t *task, isc_event_t *event) {
+ dns_requestevent_t *reqev = NULL;
+ updatectx_t *uctx;
+ dns_client_t *client;
+ isc_result_t result, eresult;
+ dns_request_t *request;
+ dns_message_t *rcvmsg = NULL;
+ dns_section_t section;
+ dns_rdataset_t *soaset = NULL;
+ int pass = 0;
+ dns_name_t *name;
+ dns_message_t *soaquery = NULL;
+ isc_sockaddr_t *addr;
+ isc_boolean_t seencname = ISC_FALSE;
+ isc_boolean_t droplabel = ISC_FALSE;
+ dns_name_t tname;
+ unsigned int nlabels;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
+ reqev = (dns_requestevent_t *)event;
+ request = reqev->request;
+ result = eresult = reqev->result;
+ uctx = reqev->ev_arg;
+ client = uctx->client;
+ soaquery = uctx->soaquery;
+ addr = uctx->currentserver;
+ INSIST(addr != NULL);
+
+ isc_event_free(&event);
+
+ if (eresult != ISC_R_SUCCESS) {
+ result = eresult;
+ goto out;
+ }
+
+ result = dns_message_create(uctx->client->mctx,
+ DNS_MESSAGE_INTENTPARSE, &rcvmsg);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ result = dns_request_getresponse(request, rcvmsg,
+ DNS_MESSAGEPARSE_PRESERVEORDER);
+
+ if (result == DNS_R_TSIGERRORSET) {
+ dns_request_t *newrequest = NULL;
+
+ /* Retry SOA request without TSIG */
+ dns_message_destroy(&rcvmsg);
+ dns_message_renderreset(uctx->soaquery);
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ uctx->soaquery, NULL, addr, 0,
+ NULL,
+ client->find_timeout * 20,
+ client->find_timeout, 3,
+ uctx->client->task,
+ receive_soa, uctx,
+ &newrequest);
+ if (result == ISC_R_SUCCESS) {
+ LOCK(&uctx->lock);
+ dns_request_destroy(&uctx->soareq);
+ uctx->soareq = newrequest;
+ UNLOCK(&uctx->lock);
+
+ return;
+ }
+ goto out;
+ }
+
+ section = DNS_SECTION_ANSWER;
+
+ if (rcvmsg->rcode != dns_rcode_noerror &&
+ rcvmsg->rcode != dns_rcode_nxdomain) {
+ result = rcode2result(rcvmsg->rcode);
+ goto out;
+ }
+
+ lookforsoa:
+ if (pass == 0)
+ section = DNS_SECTION_ANSWER;
+ else if (pass == 1)
+ section = DNS_SECTION_AUTHORITY;
+ else {
+ droplabel = ISC_TRUE;
+ goto out;
+ }
+
+ result = dns_message_firstname(rcvmsg, section);
+ if (result != ISC_R_SUCCESS) {
+ pass++;
+ goto lookforsoa;
+ }
+ while (result == ISC_R_SUCCESS) {
+ name = NULL;
+ dns_message_currentname(rcvmsg, section, &name);
+ soaset = NULL;
+ result = dns_message_findtype(name, dns_rdatatype_soa, 0,
+ &soaset);
+ if (result == ISC_R_SUCCESS)
+ break;
+ if (section == DNS_SECTION_ANSWER) {
+ dns_rdataset_t *tset = NULL;
+ if (dns_message_findtype(name, dns_rdatatype_cname, 0,
+ &tset) == ISC_R_SUCCESS
+ ||
+ dns_message_findtype(name, dns_rdatatype_dname, 0,
+ &tset) == ISC_R_SUCCESS
+ )
+ {
+ seencname = ISC_TRUE;
+ break;
+ }
+ }
+
+ result = dns_message_nextname(rcvmsg, section);
+ }
+
+ if (soaset == NULL && !seencname) {
+ pass++;
+ goto lookforsoa;
+ }
+
+ if (seencname) {
+ droplabel = ISC_TRUE;
+ goto out;
+ }
+
+ result = process_soa(uctx, soaset, name);
+
+ out:
+ if (droplabel) {
+ result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION);
+ INSIST(result == ISC_R_SUCCESS);
+ name = NULL;
+ dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name);
+ nlabels = dns_name_countlabels(name);
+ if (nlabels == 1)
+ result = DNS_R_SERVFAIL; /* is there a better error? */
+ else {
+ dns_name_init(&tname, NULL);
+ dns_name_getlabelsequence(name, 1, nlabels - 1,
+ &tname);
+ dns_name_clone(&tname, name);
+ dns_request_destroy(&request);
+ LOCK(&uctx->lock);
+ uctx->soareq = NULL;
+ UNLOCK(&uctx->lock);
+ dns_message_renderreset(soaquery);
+ dns_message_settsigkey(soaquery, NULL);
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ soaquery, NULL,
+ uctx->currentserver, 0,
+ uctx->tsigkey,
+ client->find_timeout *
+ 20,
+ client->find_timeout,
+ 3, client->task,
+ receive_soa, uctx,
+ &uctx->soareq);
+ }
+ }
+
+ if (!droplabel || result != ISC_R_SUCCESS) {
+ dns_message_destroy(&uctx->soaquery);
+ LOCK(&uctx->lock);
+ dns_request_destroy(&uctx->soareq);
+ UNLOCK(&uctx->lock);
+ }
+
+ if (rcvmsg != NULL)
+ dns_message_destroy(&rcvmsg);
+
+ if (result != ISC_R_SUCCESS)
+ update_sendevent(uctx, result);
+}
+
+static isc_result_t
+request_soa(updatectx_t *uctx) {
+ isc_result_t result;
+ dns_message_t *soaquery = uctx->soaquery;
+ dns_name_t *name = NULL;
+ dns_rdataset_t *rdataset = NULL;
+
+ if (soaquery == NULL) {
+ result = dns_message_create(uctx->client->mctx,
+ DNS_MESSAGE_INTENTRENDER,
+ &soaquery);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ soaquery->flags |= DNS_MESSAGEFLAG_RD;
+ result = dns_message_gettempname(soaquery, &name);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ result = dns_message_gettemprdataset(soaquery, &rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa);
+ dns_name_clone(uctx->firstname, name);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+ dns_message_addname(soaquery, name, DNS_SECTION_QUESTION);
+ rdataset = NULL;
+ name = NULL;
+
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ soaquery, NULL, uctx->currentserver, 0,
+ uctx->tsigkey,
+ uctx->client->find_timeout * 20,
+ uctx->client->find_timeout, 3,
+ uctx->client->task, receive_soa, uctx,
+ &uctx->soareq);
+ if (result == ISC_R_SUCCESS) {
+ uctx->soaquery = soaquery;
+ return (ISC_R_SUCCESS);
+ }
+
+ fail:
+ if (rdataset != NULL) {
+ ISC_LIST_UNLINK(name->list, rdataset, link); /* for safety */
+ dns_message_puttemprdataset(soaquery, &rdataset);
+ }
+ if (name != NULL)
+ dns_message_puttempname(soaquery, &name);
+ dns_message_destroy(&soaquery);
+
+ return (result);
+}
+
+static void
+resolvesoa_done(isc_task_t *task, isc_event_t *event) {
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ updatectx_t *uctx;
+ dns_name_t *name, tname;
+ dns_rdataset_t *rdataset = NULL;
+ isc_result_t result = rev->result;
+ unsigned int nlabels;
+
+ UNUSED(task);
+
+ uctx = event->ev_arg;
+ REQUIRE(UCTX_VALID(uctx));
+
+ LOCK(&uctx->lock);
+ dns_client_destroyrestrans(&uctx->restrans);
+ UNLOCK(&uctx->lock);
+
+ uctx = event->ev_arg;
+ if (result != ISC_R_SUCCESS &&
+ result != DNS_R_NCACHENXDOMAIN &&
+ result != DNS_R_NCACHENXRRSET) {
+ /* XXX: what about DNSSEC failure? */
+ goto out;
+ }
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (dns_rdataset_isassociated(rdataset) &&
+ rdataset->type == dns_rdatatype_soa)
+ break;
+ }
+ }
+
+ if (rdataset == NULL) {
+ /* Drop one label and retry resolution. */
+ nlabels = dns_name_countlabels(&uctx->soaqname);
+ if (nlabels == 1) {
+ result = DNS_R_SERVFAIL; /* is there a better error? */
+ goto out;
+ }
+ dns_name_init(&tname, NULL);
+ dns_name_getlabelsequence(&uctx->soaqname, 1, nlabels - 1,
+ &tname);
+ dns_name_clone(&tname, &uctx->soaqname);
+
+ result = dns_client_startresolve(uctx->client, &uctx->soaqname,
+ uctx->rdclass,
+ dns_rdatatype_soa, 0,
+ uctx->client->task,
+ resolvesoa_done, uctx,
+ &uctx->restrans);
+ } else
+ result = process_soa(uctx, rdataset, &uctx->soaqname);
+
+ out:
+ dns_client_freeresanswer(uctx->client, &rev->answerlist);
+ isc_event_free(&event);
+
+ if (result != ISC_R_SUCCESS)
+ update_sendevent(uctx, result);
+}
+
+static isc_result_t
+copy_name(isc_mem_t *mctx, dns_message_t *msg, dns_name_t *name,
+ dns_name_t **newnamep)
+{
+ isc_result_t result;
+ dns_name_t *newname = NULL;
+ isc_region_t r;
+ isc_buffer_t *namebuf = NULL, *rdatabuf = NULL;
+ dns_rdatalist_t *rdatalist;
+ dns_rdataset_t *rdataset, *newrdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT, *newrdata;
+
+ result = dns_message_gettempname(msg, &newname);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_name_init(newname, NULL);
+ dns_name_setbuffer(newname, namebuf);
+ dns_message_takebuffer(msg, &namebuf);
+ result = dns_name_copy(name, newname, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ rdatalist = NULL;
+ result = dns_message_gettemprdatalist(msg, &rdatalist);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = rdataset->type;
+ rdatalist->rdclass = rdataset->rdclass;
+ rdatalist->covers = rdataset->covers;
+ rdatalist->ttl = rdataset->ttl;
+
+ result = dns_rdataset_first(rdataset);
+ while (result == ISC_R_SUCCESS) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+
+ newrdata = NULL;
+ result = dns_message_gettemprdata(msg, &newrdata);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdata_toregion(&rdata, &r);
+ rdatabuf = NULL;
+ result = isc_buffer_allocate(mctx, &rdatabuf,
+ r.length);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ isc_buffer_putmem(rdatabuf, r.base, r.length);
+ isc_buffer_usedregion(rdatabuf, &r);
+ dns_rdata_init(newrdata);
+ dns_rdata_fromregion(newrdata, rdata.rdclass,
+ rdata.type, &r);
+ newrdata->flags = rdata.flags;
+
+ ISC_LIST_APPEND(rdatalist->rdata, newrdata, link);
+ dns_message_takebuffer(msg, &rdatabuf);
+
+ result = dns_rdataset_next(rdataset);
+ }
+
+ newrdataset = NULL;
+ result = dns_message_gettemprdataset(msg, &newrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdataset_init(newrdataset);
+ dns_rdatalist_tordataset(rdatalist, newrdataset);
+
+ ISC_LIST_APPEND(newname->list, newrdataset, link);
+ }
+
+ *newnamep = newname;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ dns_message_puttempname(msg, &newname);
+
+ return (result);
+
+}
+
+static void
+internal_update_callback(isc_task_t *task, isc_event_t *event) {
+ updatearg_t *uarg = event->ev_arg;
+ dns_clientupdateevent_t *uev = (dns_clientupdateevent_t *)event;
+
+ UNUSED(task);
+
+ LOCK(&uarg->lock);
+
+ uarg->result = uev->result;
+
+ dns_client_destroyupdatetrans(&uarg->trans);
+ isc_event_free(&event);
+
+ if (!uarg->canceled) {
+ UNLOCK(&uarg->lock);
+
+ /* Exit from the internal event loop */
+ isc_app_ctxsuspend(uarg->actx);
+ } else {
+ /*
+ * We have already exited from the loop (due to some
+ * unexpected event). Just clean the arg up.
+ */
+ UNLOCK(&uarg->lock);
+ DESTROYLOCK(&uarg->lock);
+ isc_mem_put(uarg->client->mctx, uarg, sizeof(*uarg));
+ }
+}
+
+isc_result_t
+dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options)
+{
+ isc_result_t result;
+ isc_appctx_t *actx;
+ updatearg_t *uarg;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 &&
+ (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) {
+ /*
+ * If the client is run under application's control, we need
+ * to create a new running (sub)environment for this
+ * particular resolution.
+ */
+ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */
+ } else
+ actx = client->actx;
+
+ uarg = isc_mem_get(client->mctx, sizeof(*uarg));
+ if (uarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&uarg->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, uarg, sizeof(*uarg));
+ return (result);
+ }
+
+ uarg->actx = actx;
+ uarg->client = client;
+ uarg->result = ISC_R_FAILURE;
+ uarg->trans = NULL;
+ uarg->canceled = ISC_FALSE;
+
+ result = dns_client_startupdate(client, rdclass, zonename,
+ prerequisites, updates, servers,
+ tsec, options, client->task,
+ internal_update_callback, uarg,
+ &uarg->trans);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&uarg->lock);
+ isc_mem_put(client->mctx, uarg, sizeof(*uarg));
+ return (result);
+ }
+
+ /*
+ * Start internal event loop. It blocks until the entire process
+ * is completed.
+ */
+ result = isc_app_ctxrun(actx);
+
+ LOCK(&uarg->lock);
+ if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND)
+ result = uarg->result;
+
+ if (uarg->trans != NULL) {
+ /*
+ * Unusual termination (perhaps due to signal). We need some
+ * tricky cleanup process.
+ */
+ uarg->canceled = ISC_TRUE;
+ dns_client_cancelupdate(uarg->trans);
+
+ UNLOCK(&uarg->lock);
+
+ /* uarg will be freed in the event handler. */
+ } else {
+ UNLOCK(&uarg->lock);
+
+ DESTROYLOCK(&uarg->lock);
+ isc_mem_put(client->mctx, uarg, sizeof(*uarg));
+ }
+
+ return (result);
+}
+
+isc_result_t
+dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientupdatetrans_t **transp)
+{
+ dns_view_t *view = NULL;
+ isc_result_t result;
+ dns_name_t *name, *newname;
+ updatectx_t *uctx;
+ isc_task_t *clone = NULL;
+ dns_section_t section = DNS_SECTION_UPDATE;
+ isc_sockaddr_t *server, *sa = NULL;
+ dns_tsectype_t tsectype = dns_tsectype_none;
+
+ UNUSED(options);
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(transp != NULL && *transp == NULL);
+ REQUIRE(updates != NULL);
+ REQUIRE(task != NULL);
+
+ if (tsec != NULL) {
+ tsectype = dns_tsec_gettype(tsec);
+ if (tsectype != dns_tsectype_tsig)
+ return (ISC_R_NOTIMPLEMENTED); /* XXX */
+ }
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /* Create a context and prepare some resources */
+ uctx = isc_mem_get(client->mctx, sizeof(*uctx));
+ if (uctx == NULL) {
+ dns_view_detach(&view);
+ return (ISC_R_NOMEMORY);
+ }
+ result = isc_mutex_init(&uctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ isc_mem_put(client->mctx, uctx, sizeof(*uctx));
+ return (ISC_R_NOMEMORY);
+ }
+ clone = NULL;
+ isc_task_attach(task, &clone);
+ uctx->client = client;
+ ISC_LINK_INIT(uctx, link);
+ uctx->state = dns_clientupdatestate_prepare;
+ uctx->view = view;
+ uctx->rdclass = rdclass;
+ uctx->canceled = ISC_FALSE;
+ uctx->updatemsg = NULL;
+ uctx->soaquery = NULL;
+ uctx->updatereq = NULL;
+ uctx->restrans = NULL;
+ uctx->restrans2 = NULL;
+ uctx->bp4 = NULL;
+ uctx->bp6 = NULL;
+ uctx->soareq = NULL;
+ uctx->event = NULL;
+ uctx->tsigkey = NULL;
+ uctx->sig0key = NULL;
+ uctx->zonename = NULL;
+ dns_name_init(&uctx->soaqname, NULL);
+ ISC_LIST_INIT(uctx->servers);
+ uctx->nservers = 0;
+ uctx->currentserver = NULL;
+ dns_fixedname_init(&uctx->zonefname);
+ if (tsec != NULL)
+ dns_tsec_getkey(tsec, &uctx->tsigkey);
+ uctx->event = (dns_clientupdateevent_t *)
+ isc_event_allocate(client->mctx, clone, DNS_EVENT_UPDATEDONE,
+ action, arg, sizeof(*uctx->event));
+ if (uctx->event == NULL)
+ goto fail;
+ if (zonename != NULL) {
+ uctx->zonename = dns_fixedname_name(&uctx->zonefname);
+ result = dns_name_copy(zonename, uctx->zonename, NULL);
+ }
+ if (servers != NULL) {
+ for (server = ISC_LIST_HEAD(*servers);
+ server != NULL;
+ server = ISC_LIST_NEXT(server, link)) {
+ sa = isc_mem_get(client->mctx, sizeof(*sa));
+ if (sa == NULL)
+ goto fail;
+ sa->type = server->type;
+ sa->length = server->length;
+ ISC_LINK_INIT(sa, link);
+ ISC_LIST_APPEND(uctx->servers, sa, link);
+ if (uctx->currentserver == NULL)
+ uctx->currentserver = sa;
+ uctx->nservers++;
+ }
+ }
+
+ /* Make update message */
+ result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER,
+ &uctx->updatemsg);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ uctx->updatemsg->opcode = dns_opcode_update;
+
+ if (prerequisites != NULL) {
+ for (name = ISC_LIST_HEAD(*prerequisites); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ newname = NULL;
+ result = copy_name(client->mctx, uctx->updatemsg,
+ name, &newname);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_message_addname(uctx->updatemsg, newname,
+ DNS_SECTION_PREREQUISITE);
+ }
+ }
+
+ for (name = ISC_LIST_HEAD(*updates); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ newname = NULL;
+ result = copy_name(client->mctx, uctx->updatemsg, name,
+ &newname);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_message_addname(uctx->updatemsg, newname,
+ DNS_SECTION_UPDATE);
+ }
+
+ uctx->firstname = NULL;
+ result = dns_message_firstname(uctx->updatemsg, section);
+ if (result == ISC_R_NOMORE) {
+ section = DNS_SECTION_PREREQUISITE;
+ result = dns_message_firstname(uctx->updatemsg, section);
+ }
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_message_currentname(uctx->updatemsg, section, &uctx->firstname);
+
+ uctx->magic = UCTX_MAGIC;
+
+ LOCK(&client->lock);
+ ISC_LIST_APPEND(client->updatectxs, uctx, link);
+ UNLOCK(&client->lock);
+
+ if (uctx->zonename != NULL && uctx->currentserver != NULL) {
+ result = send_update(uctx);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ } else if (uctx->currentserver != NULL) {
+ result = request_soa(uctx);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ } else {
+ dns_name_clone(uctx->firstname, &uctx->soaqname);
+ result = dns_client_startresolve(uctx->client, &uctx->soaqname,
+ uctx->rdclass,
+ dns_rdatatype_soa, 0,
+ client->task, resolvesoa_done,
+ uctx, &uctx->restrans);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ }
+
+ *transp = (dns_clientupdatetrans_t *)uctx;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ if (ISC_LINK_LINKED(uctx, link)) {
+ LOCK(&client->lock);
+ ISC_LIST_UNLINK(client->updatectxs, uctx, link);
+ UNLOCK(&client->lock);
+ }
+ if (uctx->updatemsg != NULL)
+ dns_message_destroy(&uctx->updatemsg);
+ while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) {
+ ISC_LIST_UNLINK(uctx->servers, sa, link);
+ isc_mem_put(client->mctx, sa, sizeof(*sa));
+ }
+ if (uctx->event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&uctx->event));
+ if (uctx->tsigkey != NULL)
+ dns_tsigkey_detach(&uctx->tsigkey);
+ isc_task_detach(&clone);
+ DESTROYLOCK(&uctx->lock);
+ uctx->magic = 0;
+ isc_mem_put(client->mctx, uctx, sizeof(*uctx));
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+void
+dns_client_cancelupdate(dns_clientupdatetrans_t *trans) {
+ updatectx_t *uctx;
+
+ REQUIRE(trans != NULL);
+ uctx = (updatectx_t *)trans;
+ REQUIRE(UCTX_VALID(uctx));
+
+ LOCK(&uctx->lock);
+
+ if (!uctx->canceled) {
+ uctx->canceled = ISC_TRUE;
+ if (uctx->updatereq != NULL)
+ dns_request_cancel(uctx->updatereq);
+ if (uctx->soareq != NULL)
+ dns_request_cancel(uctx->soareq);
+ if (uctx->restrans != NULL)
+ dns_client_cancelresolve(&uctx->restrans);
+ if (uctx->restrans2 != NULL)
+ dns_client_cancelresolve(&uctx->restrans2);
+ }
+
+ UNLOCK(&uctx->lock);
+}
+
+void
+dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) {
+ updatectx_t *uctx;
+ isc_mem_t *mctx;
+ dns_client_t *client;
+ isc_boolean_t need_destroyclient = ISC_FALSE;
+ isc_sockaddr_t *sa;
+
+ REQUIRE(transp != NULL);
+ uctx = (updatectx_t *)*transp;
+ REQUIRE(UCTX_VALID(uctx));
+ client = uctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(uctx->updatereq == NULL && uctx->updatemsg == NULL &&
+ uctx->soareq == NULL && uctx->soaquery == NULL &&
+ uctx->event == NULL && uctx->tsigkey == NULL &&
+ uctx->sig0key == NULL);
+
+ mctx = client->mctx;
+ dns_view_detach(&uctx->view);
+ while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) {
+ ISC_LIST_UNLINK(uctx->servers, sa, link);
+ isc_mem_put(mctx, sa, sizeof(*sa));
+ }
+
+ LOCK(&client->lock);
+
+ INSIST(ISC_LINK_LINKED(uctx, link));
+ ISC_LIST_UNLINK(client->updatectxs, uctx, link);
+
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs))
+ need_destroyclient = ISC_TRUE;
+
+ UNLOCK(&client->lock);
+
+ DESTROYLOCK(&uctx->lock);
+ uctx->magic = 0;
+
+ isc_mem_put(mctx, uctx, sizeof(*uctx));
+
+ if (need_destroyclient)
+ destroyclient(&client);
+
+ *transp = NULL;
+}
+
+isc_mem_t *
+dns_client_mctx(dns_client_t *client) {
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ return (client->mctx);
+}
+
+typedef struct {
+ isc_buffer_t buffer;
+ dns_rdataset_t rdataset;
+ dns_rdatalist_t rdatalist;
+ dns_rdata_t rdata;
+ size_t size;
+ isc_mem_t * mctx;
+ unsigned char data[0];
+} dns_client_updaterec_t;
+
+isc_result_t
+dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner,
+ dns_rdatatype_t type, dns_rdata_t *source,
+ dns_ttl_t ttl, dns_name_t *target,
+ dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist,
+ dns_rdata_t *rdata, isc_mem_t *mctx)
+{
+ dns_client_updaterec_t *updaterec;
+ size_t size = sizeof(dns_client_updaterec_t);
+ isc_buffer_t *b = NULL;
+
+ REQUIRE(op < updateop_max);
+ REQUIRE(owner != NULL);
+ REQUIRE((rdataset != NULL && rdatalist != NULL && rdata != NULL) ||
+ (rdataset == NULL && rdatalist == NULL && rdata == NULL &&
+ mctx != NULL));
+ if (op == updateop_add)
+ REQUIRE(source != NULL);
+ if (source != NULL) {
+ REQUIRE(source->type == type);
+ REQUIRE(op == updateop_add || op == updateop_delete ||
+ op == updateop_exist);
+ }
+
+ size += owner->length;
+ if (source != NULL)
+ size += source->length;
+
+ if (rdataset == NULL) {
+ updaterec = isc_mem_get(mctx, size);
+ if (updaterec == NULL)
+ return (ISC_R_NOMEMORY);
+ rdataset = &updaterec->rdataset;
+ rdatalist = &updaterec->rdatalist;
+ rdata = &updaterec->rdata;
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_init(&updaterec->rdatalist);
+ dns_rdata_init(&updaterec->rdata);
+ isc_buffer_init(b, b + 1,
+ size - sizeof(dns_client_updaterec_t));
+ dns_name_copy(owner, target, b);
+ if (source != NULL) {
+ isc_region_t r;
+ dns_rdata_clone(source, rdata);
+ dns_rdata_toregion(rdata, &r);
+ rdata->data = isc_buffer_used(b);
+ isc_buffer_copyregion(b, &r);
+
+ }
+ updaterec->mctx = NULL;
+ isc_mem_attach(mctx, &updaterec->mctx);
+ } else if (source != NULL)
+ dns_rdata_clone(source, rdata);
+
+ switch (op) {
+ case updateop_add:
+ break;
+ case updateop_delete:
+ if (source != NULL) {
+ ttl = 0;
+ dns_rdata_makedelete(rdata);
+ } else
+ dns_rdata_deleterrset(rdata, type);
+ break;
+ case updateop_notexist:
+ dns_rdata_notexist(rdata, type);
+ break;
+ case updateop_exist:
+ if (source == NULL) {
+ ttl = 0;
+ dns_rdata_exists(rdata, type);
+ }
+ case updateop_none:
+ break;
+ default:
+ INSIST(0);
+ }
+
+ rdatalist->type = rdata->type;
+ rdatalist->rdclass = rdata->rdclass;
+ if (source != NULL) {
+ rdatalist->covers = dns_rdata_covers(rdata);
+ rdatalist->ttl = ttl;
+ }
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
+ ISC_LIST_APPEND(target->list, rdataset, link);
+ if (b != NULL) {
+ target->attributes |= DNS_NAMEATTR_HASUPDATEREC;
+ dns_name_setbuffer(target, b);
+ }
+ if (op == updateop_add || op == updateop_delete)
+ target->attributes |= DNS_NAMEATTR_UPDATE;
+ else
+ target->attributes |= DNS_NAMEATTR_PREREQUISITE;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_client_freeupdate(dns_name_t **namep) {
+ dns_client_updaterec_t *updaterec;
+ dns_rdatalist_t *rdatalist;
+ dns_rdataset_t *rdataset;
+ dns_rdata_t *rdata;
+ dns_name_t *name;
+
+ REQUIRE(namep != NULL && *namep != NULL);
+
+ name = *namep;
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_HEAD(name->list)) {
+ ISC_LIST_UNLINK(name->list, rdataset, link);
+ rdatalist = NULL;
+ dns_rdatalist_fromrdataset(rdataset, &rdatalist);
+ if (rdatalist == NULL) {
+ dns_rdataset_disassociate(rdataset);
+ continue;
+ }
+ for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
+ rdata != NULL;
+ rdata = ISC_LIST_HEAD(rdatalist->rdata))
+ ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
+ dns_rdataset_disassociate(rdataset);
+ }
+
+ if ((name->attributes & DNS_NAMEATTR_HASUPDATEREC) != 0) {
+ updaterec = (dns_client_updaterec_t *)name->buffer;
+ INSIST(updaterec != NULL);
+ isc_mem_putanddetach(&updaterec->mctx, updaterec,
+ updaterec->size);
+ *namep = NULL;
+ }
+}
diff --git a/lib/dns/db.c b/lib/dns/db.c
index f120fcbb..bc64bd85 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.c,v 1.93 2009/07/19 23:47:55 tbox Exp $ */
+/* $Id: db.c,v 1.94 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -63,14 +63,18 @@ struct dns_dbimplementation {
*/
#include "rbtdb.h"
+#ifdef BIND9
#include "rbtdb64.h"
+#endif
static ISC_LIST(dns_dbimplementation_t) implementations;
static isc_rwlock_t implock;
static isc_once_t once = ISC_ONCE_INIT;
static dns_dbimplementation_t rbtimp;
+#ifdef BIND9
static dns_dbimplementation_t rbt64imp;
+#endif
static void
initialize(void) {
@@ -82,15 +86,19 @@ initialize(void) {
rbtimp.driverarg = NULL;
ISC_LINK_INIT(&rbtimp, link);
+#ifdef BIND9
rbt64imp.name = "rbt64";
rbt64imp.create = dns_rbtdb64_create;
rbt64imp.mctx = NULL;
rbt64imp.driverarg = NULL;
ISC_LINK_INIT(&rbt64imp, link);
+#endif
ISC_LIST_INIT(implementations);
ISC_LIST_APPEND(implementations, &rbtimp, link);
+#ifdef BIND9
ISC_LIST_APPEND(implementations, &rbt64imp, link);
+#endif
}
static inline dns_dbimplementation_t *
@@ -292,6 +300,7 @@ dns_db_class(dns_db_t *db) {
return (db->rdclass);
}
+#ifdef BIND9
isc_result_t
dns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp,
dns_dbload_t **dbloadp) {
@@ -383,6 +392,7 @@ dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename,
return ((db->methods->dump)(db, version, filename, masterformat));
}
+#endif /* BIND9 */
/***
*** Version Methods
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index 9103dd69..e1323055 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.163 2009/04/28 21:39:00 jinmei Exp $ */
+/* $Id: dispatch.c,v 1.164 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -417,7 +417,7 @@ request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
/*%
* ARC4 random number generator derived from OpenBSD.
- * Only dispatch_arc4random() and dispatch_arc4uniformrandom() are expected
+ * Only dispatch_random() and dispatch_uniformrandom() are expected
* to be called from general dispatch routines; the rest of them are subroutines
* for these two.
*
@@ -437,8 +437,11 @@ request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef BIND9
static void
-dispatch_arc4init(arc4ctx_t *actx, isc_entropy_t *entropy, isc_mutex_t *lock) {
+dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
+ isc_mutex_t *lock)
+{
int n;
for (n = 0; n < 256; n++)
actx->s[n] = n;
@@ -527,7 +530,7 @@ dispatch_arc4stir(arc4ctx_t *actx) {
}
static isc_uint16_t
-dispatch_arc4random(arc4ctx_t *actx) {
+dispatch_random(arc4ctx_t *actx) {
isc_uint16_t result;
if (actx->lock != NULL)
@@ -543,9 +546,38 @@ dispatch_arc4random(arc4ctx_t *actx) {
return (result);
}
+#else
+/*
+ * For general purpose library, we don't have to be too strict about the
+ * quality of random values. Performance doesn't matter much, either.
+ * So we simply use the isc_random module to keep the library as small as
+ * possible.
+ */
+
+static void
+dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
+ isc_mutex_t *lock)
+{
+ UNUSED(actx);
+ UNUSED(entropy);
+ UNUSED(lock);
+
+ return;
+}
+
+static isc_uint16_t
+dispatch_random(arc4ctx_t *actx) {
+ isc_uint32_t r;
+
+ UNUSED(actx);
+
+ isc_random_get(&r);
+ return (r & 0xffff);
+}
+#endif /* BIND9 */
static isc_uint16_t
-dispatch_arc4uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
+dispatch_uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
isc_uint16_t min, r;
if (upper_bound < 2)
@@ -568,7 +600,7 @@ dispatch_arc4uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
* to re-roll.
*/
for (;;) {
- r = dispatch_arc4random(actx);
+ r = dispatch_random(actx);
if (r >= min)
break;
}
@@ -851,7 +883,7 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
*/
localaddr = disp->local;
for (i = 0; i < 64; i++) {
- port = ports[dispatch_arc4uniformrandom(DISP_ARC4CTX(disp),
+ port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp),
nports)];
isc_sockaddr_setport(&localaddr, port);
@@ -956,6 +988,7 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
INSIST(dispsock->portentry != NULL);
deref_portentry(disp, &dispsock->portentry);
+#ifdef BIND9
if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
destroy_dispsocket(disp, &dispsock);
else {
@@ -979,6 +1012,13 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
destroy_dispsocket(disp, &dispsock);
}
}
+#else
+ /* This kind of optimization isn't necessary for normal use */
+ UNUSED(qid);
+ UNUSED(result);
+
+ destroy_dispsocket(disp, &dispsock);
+#endif
}
/*
@@ -1704,8 +1744,10 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
DESTROYLOCK(&mgr->pool_lock);
+#ifdef BIND9
if (mgr->entropy != NULL)
isc_entropy_detach(&mgr->entropy);
+#endif /* BIND9 */
if (mgr->qid != NULL)
qid_destroy(mctx, &mgr->qid);
@@ -1744,9 +1786,13 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
return (result);
isc_socket_setname(sock, "dispatcher", NULL);
} else {
+#ifdef BIND9
result = isc_socket_open(sock);
if (result != ISC_R_SUCCESS)
return (result);
+#else
+ INSIST(0);
+#endif
}
#ifndef ISC_ALLOW_MAPPED
@@ -1756,8 +1802,13 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
if (result != ISC_R_SUCCESS) {
if (*sockp == NULL)
isc_socket_detach(&sock);
- else
+ else {
+#ifdef BIND9
isc_socket_close(sock);
+#else
+ INSIST(0);
+#endif
+ }
return (result);
}
@@ -1889,10 +1940,14 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
if (result != ISC_R_SUCCESS)
goto kill_dpool;
+#ifdef BIND9
if (entropy != NULL)
isc_entropy_attach(entropy, &mgr->entropy);
+#else
+ UNUSED(entropy);
+#endif
- dispatch_arc4init(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock);
+ dispatch_initrandom(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock);
*mgrp = mgr;
return (ISC_R_SUCCESS);
@@ -2393,7 +2448,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
ISC_LIST_INIT(disp->activesockets);
ISC_LIST_INIT(disp->inactivesockets);
disp->nsockets = 0;
- dispatch_arc4init(&disp->arc4ctx, mgr->entropy, NULL);
+ dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL);
disp->port_table = NULL;
disp->portpool = NULL;
@@ -2690,7 +2745,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
for (i = 0; i < 1024; i++) {
in_port_t prt;
- prt = ports[dispatch_arc4uniformrandom(
+ prt = ports[dispatch_uniformrandom(
DISP_ARC4CTX(disp),
nports)];
isc_sockaddr_setport(&localaddr_bound, prt);
@@ -2826,8 +2881,10 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
disp->task[i] = NULL;
result = isc_task_create(taskmgr, 0, &disp->task[i]);
if (result != ISC_R_SUCCESS) {
- while (--i >= 0)
- isc_task_destroy(&disp->task[i]);
+ while (--i >= 0) {
+ isc_task_shutdown(disp->task[i]);
+ isc_task_detach(&disp->task[i]);
+ }
goto kill_socket;
}
isc_task_setname(disp->task[i], "udpdispatch", disp);
@@ -3027,7 +3084,7 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
/*
* Try somewhat hard to find an unique ID.
*/
- id = (dns_messageid_t)dispatch_arc4random(DISP_ARC4CTX(disp));
+ id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
bucket = dns_hash(qid, dest, id, localport);
ok = ISC_FALSE;
for (i = 0; i < 64; i++) {
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index ba652038..664e4989 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -16,7 +16,7 @@
*/
/*
- * $Id: dnssec.c,v 1.98 2009/07/19 23:47:55 tbox Exp $
+ * $Id: dnssec.c,v 1.100 2009/09/02 23:48:02 tbox Exp $
*/
/*! \file */
@@ -958,8 +958,8 @@ dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
dns_dnsseckey_t **dkp)
{
isc_result_t result;
- isc_stdtime_t when;
dns_dnsseckey_t *dk;
+ int major, minor;
REQUIRE(dkp != NULL && *dkp == NULL);
dk = isc_mem_get(mctx, sizeof(dns_dnsseckey_t));
@@ -973,6 +973,7 @@ dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
dk->hint_publish = ISC_FALSE;
dk->hint_sign = ISC_FALSE;
dk->hint_remove = ISC_FALSE;
+ dk->prepublish = 0;
dk->source = dns_keysource_unknown;
dk->index = 0;
@@ -980,8 +981,8 @@ dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
dk->ksk = ISC_TF((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) != 0);
/* Is this an old-style key? */
- result = dst_key_gettime(dk->key, DST_TIME_CREATED, &when);
- dk->legacy = ISC_TF(result != ISC_R_SUCCESS);
+ result = dst_key_getprivateformat(dk->key, &major, &minor);
+ dk->legacy = ISC_TF(major == 1 && minor <= 2);
ISC_LINK_INIT(dk, link);
*dkp = dk;
@@ -1003,7 +1004,7 @@ dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp) {
static void
get_hints(dns_dnsseckey_t *key) {
isc_result_t result;
- isc_stdtime_t now, publish, active, revoke, remove, delete;
+ isc_stdtime_t now, publish, active, revoke, unpublish, delete;
isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE;
isc_boolean_t revset = ISC_FALSE, remset = ISC_FALSE;
isc_boolean_t delset = ISC_FALSE;
@@ -1024,7 +1025,7 @@ get_hints(dns_dnsseckey_t *key) {
if (result == ISC_R_SUCCESS)
revset = ISC_TRUE;
- result = dst_key_gettime(key->key, DST_TIME_REMOVE, &remove);
+ result = dst_key_gettime(key->key, DST_TIME_UNPUBLISH, &unpublish);
if (result == ISC_R_SUCCESS)
remset = ISC_TRUE;
@@ -1057,6 +1058,13 @@ get_hints(dns_dnsseckey_t *key) {
key->hint_publish = ISC_TRUE;
/*
+ * If activation date is in the future, make note of how far off
+ */
+ if (key->hint_publish && actset && active > now) {
+ key->prepublish = active - now;
+ }
+
+ /*
* Metadata says revoke. If the key is published,
* we *have to* sign with it per RFC5011--even if it was
* not active before.
@@ -1074,10 +1082,10 @@ get_hints(dns_dnsseckey_t *key) {
}
/*
- * Metadata says remove or delete, so don't publish
+ * Metadata says unpublish or delete, so don't publish
* this key or sign with it.
*/
- if ((remset && remove < now) ||
+ if ((remset && unpublish < now) ||
(delset && delete < now)) {
key->hint_publish = ISC_FALSE;
key->hint_sign = ISC_FALSE;
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
index 00221e05..429060e4 100644
--- a/lib/dns/dst_api.c
+++ b/lib/dns/dst_api.c
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.25 2009/07/29 23:45:24 each Exp $
+ * $Id: dst_api.c,v 1.29 2009/09/03 04:09:58 marka Exp $
*/
/*! \file */
@@ -69,7 +69,9 @@
#define DST_AS_STR(t) ((t).value.as_textregion.base)
static dst_func_t *dst_t_func[DST_MAX_ALGS];
+#ifdef BIND9
static isc_entropy_t *dst_entropy_pool = NULL;
+#endif
static unsigned int dst_entropy_flags = 0;
static isc_boolean_t dst_initialized = ISC_FALSE;
@@ -126,7 +128,7 @@ static isc_result_t addsuffix(char *filename, unsigned int len,
return (_r); \
} while (0); \
-#ifdef OPENSSL
+#if defined(OPENSSL) && defined(BIND9)
static void *
default_memalloc(void *arg, size_t size) {
UNUSED(arg);
@@ -146,12 +148,17 @@ isc_result_t
dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
isc_result_t result;
- REQUIRE(mctx != NULL && ectx != NULL);
+ REQUIRE(mctx != NULL);
+#ifdef BIND9
+ REQUIRE(ectx != NULL);
+#else
+ UNUSED(ectx);
+#endif
REQUIRE(dst_initialized == ISC_FALSE);
dst__memory_pool = NULL;
-#ifdef OPENSSL
+#if defined(OPENSSL) && defined(BIND9)
UNUSED(mctx);
/*
* When using --with-openssl, there seems to be no good way of not
@@ -170,7 +177,9 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
#else
isc_mem_attach(mctx, &dst__memory_pool);
#endif
+#ifdef BIND9
isc_entropy_attach(ectx, &dst_entropy_pool);
+#endif
dst_entropy_flags = eflags;
dst_result_register();
@@ -218,9 +227,10 @@ dst_lib_destroy(void) {
#endif
if (dst__memory_pool != NULL)
isc_mem_detach(&dst__memory_pool);
+#ifdef BIND9
if (dst_entropy_pool != NULL)
isc_entropy_detach(&dst_entropy_pool);
-
+#endif
}
isc_boolean_t
@@ -422,7 +432,6 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
{
isc_result_t result;
dst_key_t *pubkey = NULL, *key = NULL;
- dns_keytag_t id;
char *newfilename = NULL;
int newfilenamelen = 0;
isc_lex_t *lex = NULL;
@@ -479,11 +488,10 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
key = get_key_struct(pubkey->key_name, pubkey->key_alg,
pubkey->key_flags, pubkey->key_proto, 0,
pubkey->key_class, mctx);
- id = pubkey->key_id;
- dst_key_free(&pubkey);
-
- if (key == NULL)
+ if (key == NULL) {
+ dst_key_free(&pubkey);
return (ISC_R_NOMEMORY);
+ }
if (key->func->parse == NULL)
RETERR(DST_R_UNSUPPORTEDALG);
@@ -502,17 +510,20 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
RETERR(isc_lex_openfile(lex, newfilename));
isc_mem_put(mctx, newfilename, newfilenamelen);
- RETERR(key->func->parse(key, lex));
+ RETERR(key->func->parse(key, lex, pubkey));
isc_lex_destroy(&lex);
RETERR(computeid(key));
- if (id != key->key_id)
+ if (pubkey->key_id != key->key_id)
RETERR(DST_R_INVALIDPRIVATEKEY);
+ dst_key_free(&pubkey);
*keyp = key;
return (ISC_R_SUCCESS);
out:
+ if (pubkey != NULL)
+ dst_key_free(&pubkey);
if (newfilename != NULL)
isc_mem_put(mctx, newfilename, newfilenamelen);
if (lex != NULL)
@@ -647,7 +658,7 @@ dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) {
RETERR(isc_lex_create(key->mctx, 1500, &lex));
RETERR(isc_lex_openbuffer(lex, buffer));
- RETERR(key->func->parse(key, lex));
+ RETERR(key->func->parse(key, lex, NULL));
out:
if (lex != NULL)
isc_lex_destroy(&lex);
@@ -776,7 +787,7 @@ dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep) {
REQUIRE(VALID_KEY(key));
REQUIRE(timep != NULL);
REQUIRE(type <= DST_MAX_TIMES);
- if (key->times[type] == 0)
+ if (!key->timeset[type])
return (ISC_R_NOTFOUND);
*timep = key->times[type];
return (ISC_R_SUCCESS);
@@ -787,6 +798,31 @@ dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) {
REQUIRE(VALID_KEY(key));
REQUIRE(type <= DST_MAX_TIMES);
key->times[type] = when;
+ key->timeset[type] = ISC_TRUE;
+}
+
+void
+dst_key_unsettime(dst_key_t *key, int type) {
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(type <= DST_MAX_TIMES);
+ key->timeset[type] = ISC_FALSE;
+}
+
+isc_result_t
+dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp) {
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(majorp != NULL);
+ REQUIRE(minorp != NULL);
+ *majorp = key->fmt_major;
+ *minorp = key->fmt_minor;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dst_key_setprivateformat(dst_key_t *key, int major, int minor) {
+ REQUIRE(VALID_KEY(key));
+ key->fmt_major = major;
+ key->fmt_minor = minor;
}
isc_boolean_t
@@ -944,6 +980,7 @@ get_key_struct(dns_name_t *name, unsigned int alg,
{
dst_key_t *key;
isc_result_t result;
+ int i;
key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t));
if (key == NULL)
@@ -967,12 +1004,17 @@ get_key_struct(dns_name_t *name, unsigned int alg,
key->key_alg = alg;
key->key_flags = flags;
key->key_proto = protocol;
- memset(key->times, 0, sizeof(key->times));
key->mctx = mctx;
key->keydata.generic = NULL;
key->key_size = bits;
key->key_class = rdclass;
key->func = dst_t_func[alg];
+ key->fmt_major = 0;
+ key->fmt_minor = 0;
+ for (i = 0; i < (DST_MAX_TIMES + 1); i++) {
+ key->times[i] = 0;
+ key->timeset[i] = ISC_FALSE;
+ }
return (key);
}
@@ -1045,7 +1087,7 @@ dst_key_read_public(const char *filename, int type,
isc_buffer_init(&b, DST_AS_STR(token), strlen(DST_AS_STR(token)));
isc_buffer_add(&b, strlen(DST_AS_STR(token)));
ret = dns_name_fromtext(dns_fixedname_name(&name), &b, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup;
@@ -1138,14 +1180,17 @@ issymmetric(const dst_key_t *key) {
static void
printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) {
isc_result_t result;
- isc_stdtime_t when;
const char *output;
+ isc_stdtime_t when;
+ time_t t;
result = dst_key_gettime(key, type, &when);
if (result == ISC_R_NOTFOUND)
return;
- output = ctime((time_t *) &when);
+ /* time_t and isc_stdtime_t might be different sizes */
+ t = when;
+ output = ctime(&t);
fprintf(stream, "%s: %s", tag, output);
}
@@ -1229,7 +1274,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) {
printtime(key, DST_TIME_PUBLISH, "; Publish", fp);
printtime(key, DST_TIME_ACTIVATE, "; Activate", fp);
printtime(key, DST_TIME_REVOKE, "; Revoke", fp);
- printtime(key, DST_TIME_REMOVE, "; Remove", fp);
+ printtime(key, DST_TIME_UNPUBLISH, "; Unpublish", fp);
printtime(key, DST_TIME_DELETE, "; Delete", fp);
}
@@ -1394,13 +1439,25 @@ addsuffix(char *filename, unsigned int len, const char *odirname,
isc_result_t
dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
+#ifdef BIND9
unsigned int flags = dst_entropy_flags;
if (pseudo)
flags &= ~ISC_ENTROPY_GOODONLY;
return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
+#else
+ UNUSED(buf);
+ UNUSED(len);
+ UNUSED(pseudo);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
}
unsigned int
dst__entropy_status(void) {
+#ifdef BIND9
return (isc_entropy_status(dst_entropy_pool));
+#else
+ return (0);
+#endif
}
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h
index 6bdd5ed2..c597a6be 100644
--- a/lib/dns/dst_internal.h
+++ b/lib/dns/dst_internal.h
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_internal.h,v 1.15 2009/07/19 04:18:05 each Exp $ */
+/* $Id: dst_internal.h,v 1.17 2009/09/03 04:09:58 marka Exp $ */
#ifndef DST_DST_INTERNAL_H
#define DST_DST_INTERNAL_H 1
@@ -117,6 +117,11 @@ struct dst_key {
} keydata; /*%< pointer to key in crypto pkg fmt */
isc_stdtime_t times[DST_MAX_TIMES + 1]; /*%< key timing metadata */
+ isc_boolean_t timeset[DST_MAX_TIMES + 1]; /*%< metadata set? */
+
+ int fmt_major; /*%< private key format, major version */
+ int fmt_minor; /*%< private key format, minor version */
+
dst_func_t * func; /*%< crypto package specific functions */
};
@@ -168,7 +173,9 @@ struct dst_func {
isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data);
isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data);
isc_result_t (*tofile)(const dst_key_t *key, const char *directory);
- isc_result_t (*parse)(dst_key_t *key, isc_lex_t *lexer);
+ isc_result_t (*parse)(dst_key_t *key,
+ isc_lex_t *lexer,
+ dst_key_t *pub);
/* cleanup */
void (*cleanup)(void);
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c
index af66e746..807fc056 100644
--- a/lib/dns/dst_parse.c
+++ b/lib/dns/dst_parse.c
@@ -31,7 +31,7 @@
/*%
* Principal Author: Brian Wellington
- * $Id: dst_parse.c,v 1.19 2009/07/19 23:47:55 tbox Exp $
+ * $Id: dst_parse.c,v 1.20 2009/09/02 06:29:01 each Exp $
*/
#include <config.h>
@@ -62,7 +62,7 @@ static const char *metatags[METADATA_NTAGS] = {
"Publish:",
"Activate:",
"Revoke:",
- "Remove:",
+ "Unpublish:",
"Delete:"
};
@@ -309,7 +309,7 @@ dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) {
priv->nelements = 0;
}
-int
+isc_result_t
dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
isc_mem_t *mctx, dst_private_t *priv)
{
@@ -373,6 +373,11 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
goto fail;
}
+ /*
+ * Store the private key format version number
+ */
+ dst_key_setprivateformat(key, major, minor);
+
READLINE(lex, opt, &token);
/*
@@ -474,7 +479,7 @@ fail:
return (ret);
}
-int
+isc_result_t
dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory)
{
@@ -487,6 +492,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
isc_stdtime_t when;
isc_buffer_t b;
isc_region_t r;
+ int major, minor;
REQUIRE(priv != NULL);
@@ -507,11 +513,17 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
&access);
(void)isc_fsaccess_set(filename, access);
+ dst_key_getprivateformat(key, &major, &minor);
+ if (major == 0 && minor == 0) {
+ major = MAJOR_VERSION;
+ minor = MINOR_VERSION;
+ }
+
/* XXXDCL return value should be checked for full filesystem */
- fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION,
- MINOR_VERSION);
+ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, major, minor);
fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key));
+
/* XXXVIX this switch statement is too sparse to gen a jump table. */
switch (dst_key_alg(key)) {
case DST_ALG_RSAMD5:
@@ -576,21 +588,23 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
}
/* Add the timing metadata tags */
- for (i = 0; i < METADATA_NTAGS; i++) {
- result = dst_key_gettime(key, i, &when);
- if (result != ISC_R_SUCCESS)
- continue;
-
- isc_buffer_init(&b, buffer, sizeof(buffer));
- result = dns_time32_totext(when, &b);
- if (result != ISC_R_SUCCESS)
- continue;
-
- isc_buffer_usedregion(&b, &r);
-
- fprintf(fp, "%s ", metatags[i]);
- fwrite(r.base, 1, r.length, fp);
- fprintf(fp, "\n");
+ if (major > 1 || (major == 1 && minor >= 3)) {
+ for (i = 0; i < METADATA_NTAGS; i++) {
+ result = dst_key_gettime(key, i, &when);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ isc_buffer_init(&b, buffer, sizeof(buffer));
+ result = dns_time32_totext(when, &b);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ isc_buffer_usedregion(&b, &r);
+
+ fprintf(fp, "%s ", metatags[i]);
+ fwrite(r.base, 1, r.length, fp);
+ fprintf(fp, "\n");
+ }
}
fflush(fp);
diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h
index 66c4399f..d893c2dc 100644
--- a/lib/dns/dst_parse.h
+++ b/lib/dns/dst_parse.h
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_parse.h,v 1.13 2009/07/19 23:47:55 tbox Exp $ */
+/* $Id: dst_parse.h,v 1.14 2009/09/02 06:29:01 each Exp $ */
/*! \file */
#ifndef DST_DST_PARSE_H
@@ -126,11 +126,11 @@ ISC_LANG_BEGINDECLS
void
dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx);
-int
+isc_result_t
dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
isc_mem_t *mctx, dst_private_t *priv);
-int
+isc_result_t
dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory);
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
new file mode 100644
index 00000000..cb36edb7
--- /dev/null
+++ b/lib/dns/ecdb.c
@@ -0,0 +1,797 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: ecdb.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#include "config.h"
+
+#include <isc/result.h>
+#include <isc/util.h>
+#include <isc/mutex.h>
+#include <isc/mem.h>
+
+#include <dns/db.h>
+#include <dns/ecdb.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
+#include <dns/rdataslab.h>
+
+#define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B')
+#define VALID_ECDB(db) ((db) != NULL && \
+ (db)->common.impmagic == ECDB_MAGIC)
+
+#define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N')
+#define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC)
+
+#if DNS_RDATASET_FIXED
+#error "Fixed rdataset isn't supported in this implementation"
+#endif
+
+/*%
+ * The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides
+ * temporary storage for ongoing name resolution with the common DB interfaces.
+ * It actually doesn't cache anything. The implementation expects any stored
+ * data is released within a short period, and does not care about the
+ * scalability in terms of the number of nodes.
+ */
+
+typedef struct dns_ecdb {
+ /* Unlocked */
+ dns_db_t common;
+ isc_mutex_t lock;
+
+ /* Locked */
+ unsigned int references;
+ ISC_LIST(struct dns_ecdbnode) nodes;
+} dns_ecdb_t;
+
+typedef struct dns_ecdbnode {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_ecdb_t *ecdb;
+ dns_name_t name;
+ ISC_LINK(struct dns_ecdbnode) link;
+
+ /* Locked */
+ ISC_LIST(struct rdatasetheader) rdatasets;
+ unsigned int references;
+} dns_ecdbnode_t;
+
+typedef struct rdatasetheader {
+ dns_rdatatype_t type;
+ dns_ttl_t ttl;
+ dns_trust_t trust;
+ dns_rdatatype_t covers;
+ unsigned int attributes;
+
+ ISC_LINK(struct rdatasetheader) link;
+} rdatasetheader_t;
+
+/* Copied from rbtdb.c */
+#define RDATASET_ATTR_NXDOMAIN 0x0010
+#define NXDOMAIN(header) \
+ (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
+
+static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin,
+ dns_dbtype_t type,
+ dns_rdataclass_t rdclass,
+ unsigned int argc, char *argv[],
+ void *driverarg, dns_db_t **dbp);
+
+static void rdataset_disassociate(dns_rdataset_t *rdataset);
+static isc_result_t rdataset_first(dns_rdataset_t *rdataset);
+static isc_result_t rdataset_next(dns_rdataset_t *rdataset);
+static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
+static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
+static unsigned int rdataset_count(dns_rdataset_t *rdataset);
+
+static dns_rdatasetmethods_t rdataset_methods = {
+ rdataset_disassociate,
+ rdataset_first,
+ rdataset_next,
+ rdataset_current,
+ rdataset_clone,
+ rdataset_count,
+ NULL, /* addnoqname */
+ NULL, /* getnoqname */
+ NULL, /* addclosest */
+ NULL, /* getclosest */
+ NULL, /* getadditional */
+ NULL, /* setadditional */
+ NULL /* putadditional */
+};
+
+typedef struct ecdb_rdatasetiter {
+ dns_rdatasetiter_t common;
+ rdatasetheader_t *current;
+} ecdb_rdatasetiter_t;
+
+static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
+static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
+static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
+static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
+ dns_rdataset_t *rdataset);
+
+static dns_rdatasetitermethods_t rdatasetiter_methods = {
+ rdatasetiter_destroy,
+ rdatasetiter_first,
+ rdatasetiter_next,
+ rdatasetiter_current
+};
+
+isc_result_t
+dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) {
+ REQUIRE(mctx != NULL);
+ REQUIRE(dbimp != NULL && *dbimp == NULL);
+
+ return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp));
+}
+
+void
+dns_ecdb_unregister(dns_dbimplementation_t **dbimp) {
+ REQUIRE(dbimp != NULL && *dbimp != NULL);
+
+ dns_db_unregister(dbimp);
+}
+
+/*%
+ * DB routines
+ */
+
+static void
+attach(dns_db_t *source, dns_db_t **targetp) {
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)source;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ LOCK(&ecdb->lock);
+ ecdb->references++;
+ UNLOCK(&ecdb->lock);
+
+ *targetp = source;
+}
+
+static void
+destroy_ecdb(dns_ecdb_t **ecdbp) {
+ dns_ecdb_t *ecdb = *ecdbp;
+ isc_mem_t *mctx = ecdb->common.mctx;
+
+ if (dns_name_dynamic(&ecdb->common.origin))
+ dns_name_free(&ecdb->common.origin, mctx);
+
+ DESTROYLOCK(&ecdb->lock);
+
+ ecdb->common.impmagic = 0;
+ ecdb->common.magic = 0;
+
+ isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb));
+
+ *ecdbp = NULL;
+}
+
+static void
+detach(dns_db_t **dbp) {
+ dns_ecdb_t *ecdb;
+ isc_boolean_t need_destroy = ISC_FALSE;
+
+ REQUIRE(dbp != NULL);
+ ecdb = (dns_ecdb_t *)*dbp;
+ REQUIRE(VALID_ECDB(ecdb));
+
+ LOCK(&ecdb->lock);
+ ecdb->references--;
+ if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
+ need_destroy = ISC_TRUE;
+ UNLOCK(&ecdb->lock);
+
+ if (need_destroy)
+ destroy_ecdb(&ecdb);
+
+ *dbp = NULL;
+}
+
+static void
+attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ dns_ecdbnode_t *node = (dns_ecdbnode_t *)source;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(VALID_ECDBNODE(node));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ LOCK(&node->lock);
+ INSIST(node->references > 0);
+ node->references++;
+ INSIST(node->references != 0); /* Catch overflow. */
+ UNLOCK(&node->lock);
+
+ *targetp = node;
+}
+
+static void
+destroynode(dns_ecdbnode_t *node) {
+ isc_mem_t *mctx;
+ dns_ecdb_t *ecdb = node->ecdb;
+ isc_boolean_t need_destroydb = ISC_FALSE;
+ rdatasetheader_t *header;
+
+ mctx = ecdb->common.mctx;
+
+ LOCK(&ecdb->lock);
+ ISC_LIST_UNLINK(ecdb->nodes, node, link);
+ if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
+ need_destroydb = ISC_TRUE;
+ UNLOCK(&ecdb->lock);
+
+ dns_name_free(&node->name, mctx);
+
+ while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) {
+ unsigned int headersize;
+
+ ISC_LIST_UNLINK(node->rdatasets, header, link);
+ headersize =
+ dns_rdataslab_size((unsigned char *)header,
+ sizeof(*header));
+ isc_mem_put(mctx, header, headersize);
+ }
+
+ DESTROYLOCK(&node->lock);
+
+ node->magic = 0;
+ isc_mem_put(mctx, node, sizeof(*node));
+
+ if (need_destroydb)
+ destroy_ecdb(&ecdb);
+}
+
+static void
+detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ dns_ecdbnode_t *node;
+ isc_boolean_t need_destroy = ISC_FALSE;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(nodep != NULL);
+ node = (dns_ecdbnode_t *)*nodep;
+ REQUIRE(VALID_ECDBNODE(node));
+
+ UNUSED(ecdb); /* in case REQUIRE() is empty */
+
+ LOCK(&node->lock);
+ INSIST(node->references > 0);
+ node->references--;
+ if (node->references == 0)
+ need_destroy = ISC_TRUE;
+ UNLOCK(&node->lock);
+
+ if (need_destroy)
+ destroynode(node);
+
+ *nodep = NULL;
+}
+
+static isc_result_t
+find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+
+ REQUIRE(VALID_ECDB(ecdb));
+
+ UNUSED(name);
+ UNUSED(version);
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(now);
+ UNUSED(nodep);
+ UNUSED(foundname);
+ UNUSED(rdataset);
+ UNUSED(sigrdataset);
+
+ return (ISC_R_NOTFOUND);
+}
+
+static isc_result_t
+findzonecut(dns_db_t *db, dns_name_t *name,
+ unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+
+ REQUIRE(VALID_ECDB(ecdb));
+
+ UNUSED(name);
+ UNUSED(options);
+ UNUSED(now);
+ UNUSED(nodep);
+ UNUSED(foundname);
+ UNUSED(rdataset);
+ UNUSED(sigrdataset);
+
+ return (ISC_R_NOTFOUND);
+}
+
+static isc_result_t
+findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_dbnode_t **nodep)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ isc_mem_t *mctx;
+ dns_ecdbnode_t *node;
+ isc_result_t result;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(nodep != NULL && *nodep == NULL);
+
+ UNUSED(name);
+
+ if (create != ISC_TRUE) {
+ /* an 'ephemeral' node is never reused. */
+ return (ISC_R_NOTFOUND);
+ }
+
+ mctx = ecdb->common.mctx;
+ node = isc_mem_get(mctx, sizeof(*node));
+ if (node == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&node->lock);
+ if (result != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_mutex_init() failed: %s",
+ isc_result_totext(result));
+ isc_mem_put(mctx, node, sizeof(*node));
+ return (ISC_R_UNEXPECTED);
+ }
+
+ dns_name_init(&node->name, NULL);
+ result = dns_name_dup(name, mctx, &node->name);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&node->lock);
+ isc_mem_put(mctx, node, sizeof(*node));
+ return (result);
+ }
+ node->ecdb= ecdb;
+ node->references = 1;
+ ISC_LIST_INIT(node->rdatasets);
+
+ ISC_LINK_INIT(node, link);
+
+ LOCK(&ecdb->lock);
+ ISC_LIST_APPEND(ecdb->nodes, node, link);
+ UNLOCK(&ecdb->lock);
+
+ node->magic = ECDBNODE_MAGIC;
+
+ *nodep = node;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
+ rdatasetheader_t *header, dns_rdataset_t *rdataset)
+{
+ unsigned char *raw;
+
+ /*
+ * Caller must be holding the node lock.
+ */
+
+ REQUIRE(!dns_rdataset_isassociated(rdataset));
+
+ rdataset->methods = &rdataset_methods;
+ rdataset->rdclass = ecdb->common.rdclass;
+ rdataset->type = header->type;
+ rdataset->covers = header->covers;
+ rdataset->ttl = header->ttl;
+ rdataset->trust = header->trust;
+ if (NXDOMAIN(header))
+ rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
+
+ rdataset->private1 = ecdb;
+ rdataset->private2 = node;
+ raw = (unsigned char *)header + sizeof(*header);
+ rdataset->private3 = raw;
+ rdataset->count = 0;
+
+ /*
+ * Reset iterator state.
+ */
+ rdataset->privateuint4 = 0;
+ rdataset->private5 = NULL;
+
+ INSIST(node->references > 0);
+ node->references++;
+}
+
+static isc_result_t
+addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
+ dns_rdataset_t *addedrdataset)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ isc_region_t r;
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_mem_t *mctx;
+ dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
+ rdatasetheader_t *header;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(VALID_ECDBNODE(ecdbnode));
+
+ UNUSED(version);
+ UNUSED(now);
+ UNUSED(options);
+
+ mctx = ecdb->common.mctx;
+
+ LOCK(&ecdbnode->lock);
+
+ /*
+ * Sanity check: this implementation does not allow overriding an
+ * existing rdataset of the same type.
+ */
+ for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL;
+ header = ISC_LIST_NEXT(header, link)) {
+ INSIST(header->type != rdataset->type ||
+ header->covers != rdataset->covers);
+ }
+
+ result = dns_rdataslab_fromrdataset(rdataset, mctx,
+ &r, sizeof(rdatasetheader_t));
+ if (result != ISC_R_SUCCESS)
+ goto unlock;
+
+ header = (rdatasetheader_t *)r.base;
+ header->type = rdataset->type;
+ header->ttl = rdataset->ttl;
+ header->trust = rdataset->trust;
+ header->covers = rdataset->covers;
+ header->attributes = 0;
+ if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
+ header->attributes |= RDATASET_ATTR_NXDOMAIN;
+ ISC_LINK_INIT(header, link);
+ ISC_LIST_APPEND(ecdbnode->rdatasets, header, link);
+
+ if (addedrdataset == NULL)
+ goto unlock;
+
+ bind_rdataset(ecdb, ecdbnode, header, addedrdataset);
+
+ unlock:
+ UNLOCK(&ecdbnode->lock);
+
+ return (result);
+}
+
+static isc_result_t
+deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ dns_rdatatype_t type, dns_rdatatype_t covers)
+{
+ UNUSED(db);
+ UNUSED(node);
+ UNUSED(version);
+ UNUSED(type);
+ UNUSED(covers);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+
+static isc_result_t
+createiterator(dns_db_t *db, isc_boolean_t relative_names,
+ dns_dbiterator_t **iteratorp)
+{
+ UNUSED(db);
+ UNUSED(relative_names);
+ UNUSED(iteratorp);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+
+static isc_result_t
+allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
+ isc_mem_t *mctx;
+ ecdb_rdatasetiter_t *iterator;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(VALID_ECDBNODE(ecdbnode));
+
+ mctx = ecdb->common.mctx;
+
+ iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t));
+ if (iterator == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iterator->common.magic = DNS_RDATASETITER_MAGIC;
+ iterator->common.methods = &rdatasetiter_methods;
+ iterator->common.db = db;
+ iterator->common.node = NULL;
+ attachnode(db, node, &iterator->common.node);
+ iterator->common.version = version;
+ iterator->common.now = now;
+
+ *iteratorp = (dns_rdatasetiter_t *)iterator;
+
+ return (ISC_R_SUCCESS);
+}
+
+static dns_dbmethods_t ecdb_methods = {
+ attach,
+ detach,
+ NULL, /* beginload */
+ NULL, /* endload */
+ NULL, /* dump */
+ NULL, /* currentversion */
+ NULL, /* newversion */
+ NULL, /* attachversion */
+ NULL, /* closeversion */
+ findnode,
+ find,
+ findzonecut,
+ attachnode,
+ detachnode,
+ NULL, /* expirenode */
+ NULL, /* printnode */
+ createiterator, /* createiterator */
+ NULL, /* findrdataset */
+ allrdatasets,
+ addrdataset,
+ NULL, /* subtractrdataset */
+ deleterdataset,
+ NULL, /* issecure */
+ NULL, /* nodecount */
+ NULL, /* ispersistent */
+ NULL, /* overmem */
+ NULL, /* settask */
+ NULL, /* getoriginnode */
+ NULL, /* transfernode */
+ NULL, /* getnsec3parameters */
+ NULL, /* findnsec3node */
+ NULL, /* setsigningtime */
+ NULL, /* getsigningtime */
+ NULL, /* resigned */
+ NULL, /* isdnssec */
+ NULL /* getrrsetstats */
+};
+
+static isc_result_t
+dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
+ dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
+ void *driverarg, dns_db_t **dbp)
+{
+ dns_ecdb_t *ecdb;
+ isc_result_t result;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(origin == dns_rootname);
+ REQUIRE(type == dns_dbtype_cache);
+ REQUIRE(dbp != NULL && *dbp == NULL);
+
+ UNUSED(argc);
+ UNUSED(argv);
+ UNUSED(driverarg);
+
+ ecdb = isc_mem_get(mctx, sizeof(*ecdb));
+ if (ecdb == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ecdb->common.attributes = DNS_DBATTR_CACHE;
+ ecdb->common.rdclass = rdclass;
+ ecdb->common.methods = &ecdb_methods;
+ dns_name_init(&ecdb->common.origin, NULL);
+ result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, ecdb, sizeof(*ecdb));
+ return (result);
+ }
+
+ result = isc_mutex_init(&ecdb->lock);
+ if (result != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_mutex_init() failed: %s",
+ isc_result_totext(result));
+ if (dns_name_dynamic(&ecdb->common.origin))
+ dns_name_free(&ecdb->common.origin, mctx);
+ isc_mem_put(mctx, ecdb, sizeof(*ecdb));
+ return (ISC_R_UNEXPECTED);
+ }
+
+ ecdb->references = 1;
+ ISC_LIST_INIT(ecdb->nodes);
+
+ ecdb->common.mctx = NULL;
+ isc_mem_attach(mctx, &ecdb->common.mctx);
+ ecdb->common.impmagic = ECDB_MAGIC;
+ ecdb->common.magic = DNS_DB_MAGIC;
+
+ *dbp = (dns_db_t *)ecdb;
+
+ return (ISC_R_SUCCESS);
+}
+
+/*%
+ * Rdataset Methods
+ */
+
+static void
+rdataset_disassociate(dns_rdataset_t *rdataset) {
+ dns_db_t *db = rdataset->private1;
+ dns_dbnode_t *node = rdataset->private2;
+
+ dns_db_detachnode(db, &node);
+}
+
+static isc_result_t
+rdataset_first(dns_rdataset_t *rdataset) {
+ unsigned char *raw = rdataset->private3;
+ unsigned int count;
+
+ count = raw[0] * 256 + raw[1];
+ if (count == 0) {
+ rdataset->private5 = NULL;
+ return (ISC_R_NOMORE);
+ }
+ raw += 2;
+ /*
+ * The privateuint4 field is the number of rdata beyond the cursor
+ * position, so we decrement the total count by one before storing
+ * it.
+ */
+ count--;
+ rdataset->privateuint4 = count;
+ rdataset->private5 = raw;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+rdataset_next(dns_rdataset_t *rdataset) {
+ unsigned int count;
+ unsigned int length;
+ unsigned char *raw;
+
+ count = rdataset->privateuint4;
+ if (count == 0)
+ return (ISC_R_NOMORE);
+ count--;
+ rdataset->privateuint4 = count;
+ raw = rdataset->private5;
+ length = raw[0] * 256 + raw[1];
+ raw += length + 2;
+ rdataset->private5 = raw;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
+ unsigned char *raw = rdataset->private5;
+ isc_region_t r;
+ unsigned int length;
+ unsigned int flags = 0;
+
+ REQUIRE(raw != NULL);
+
+ length = raw[0] * 256 + raw[1];
+ raw += 2;
+ if (rdataset->type == dns_rdatatype_rrsig) {
+ if (*raw & DNS_RDATASLAB_OFFLINE)
+ flags |= DNS_RDATA_OFFLINE;
+ length--;
+ raw++;
+ }
+ r.length = length;
+ r.base = raw;
+ dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
+ rdata->flags |= flags;
+}
+
+static void
+rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
+ dns_db_t *db = source->private1;
+ dns_dbnode_t *node = source->private2;
+ dns_dbnode_t *cloned_node = NULL;
+
+ attachnode(db, node, &cloned_node);
+ *target = *source;
+
+ /*
+ * Reset iterator state.
+ */
+ target->privateuint4 = 0;
+ target->private5 = NULL;
+}
+
+static unsigned int
+rdataset_count(dns_rdataset_t *rdataset) {
+ unsigned char *raw = rdataset->private3;
+ unsigned int count;
+
+ count = raw[0] * 256 + raw[1];
+
+ return (count);
+}
+
+/*
+ * Rdataset Iterator Methods
+ */
+
+static void
+rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
+ ecdb_rdatasetiter_t *ecdbiterator;
+ isc_mem_t *mctx;
+
+ REQUIRE(iteratorp != NULL);
+ ecdbiterator = (ecdb_rdatasetiter_t *)*iteratorp;
+ REQUIRE(DNS_RDATASETITER_VALID(&ecdbiterator->common));
+
+ mctx = ecdbiterator->common.db->mctx;
+
+ ecdbiterator->common.magic = 0;
+
+ dns_db_detachnode(ecdbiterator->common.db, &ecdbiterator->common.node);
+ isc_mem_put(mctx, ecdbiterator, sizeof(ecdb_rdatasetiter_t));
+
+ *iteratorp = NULL;
+}
+
+static isc_result_t
+rdatasetiter_first(dns_rdatasetiter_t *iterator) {
+ ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
+ dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)iterator->node;
+
+ REQUIRE(DNS_RDATASETITER_VALID(iterator));
+
+ if (ISC_LIST_EMPTY(ecdbnode->rdatasets))
+ return (ISC_R_NOMORE);
+ ecdbiterator->current = ISC_LIST_HEAD(ecdbnode->rdatasets);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+rdatasetiter_next(dns_rdatasetiter_t *iterator) {
+ ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
+
+ REQUIRE(DNS_RDATASETITER_VALID(iterator));
+
+ ecdbiterator->current = ISC_LIST_NEXT(ecdbiterator->current, link);
+ if (ecdbiterator->current == NULL)
+ return (ISC_R_NOMORE);
+ else
+ return (ISC_R_SUCCESS);
+}
+
+static void
+rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
+ ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
+ dns_ecdb_t *ecdb;
+
+ ecdb = (dns_ecdb_t *)iterator->db;
+ REQUIRE(VALID_ECDB(ecdb));
+
+ bind_rdataset(ecdb, iterator->node, ecdbiterator->current, rdataset);
+}
diff --git a/lib/dns/forward.c b/lib/dns/forward.c
index 39e2ef5d..7ec4e5c9 100644
--- a/lib/dns/forward.c
+++ b/lib/dns/forward.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: forward.c,v 1.12 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: forward.c,v 1.14 2009/09/02 23:48:02 tbox Exp $ */
/*! \file */
@@ -133,11 +133,27 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
}
isc_result_t
+dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name) {
+ isc_result_t result;
+
+ REQUIRE(VALID_FWDTABLE(fwdtable));
+
+ RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
+ result = dns_rbt_deletename(fwdtable->table, name, ISC_FALSE);
+ RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
+
+ if (result == DNS_R_PARTIALMATCH)
+ result = ISC_R_NOTFOUND;
+
+ return (result);
+}
+
+isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name,
dns_forwarders_t **forwardersp)
{
return (dns_fwdtable_find2(fwdtable, name, NULL, forwardersp));
-}
+}
isc_result_t
dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name,
diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c
index 11eadb96..6724590b 100644
--- a/lib/dns/gssapictx.c
+++ b/lib/dns/gssapictx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gssapictx.c,v 1.12 2008/04/03 06:09:04 tbox Exp $ */
+/* $Id: gssapictx.c,v 1.14 2009/09/02 23:48:02 tbox Exp $ */
#include <config.h>
@@ -630,7 +630,7 @@ dst_gssapi_acceptctx(gss_cred_id_t cred,
isc_buffer_add(&namebuf, r.length);
RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname,
- ISC_FALSE, NULL));
+ 0, NULL));
if (gnamebuf.length != 0) {
gret = gss_release_buffer(&minor, &gnamebuf);
diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c
index fce98d70..1fe5db64 100644
--- a/lib/dns/hmac_link.c
+++ b/lib/dns/hmac_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: hmac_link.c,v 1.11 2008/04/01 23:47:10 tbox Exp $
+ * $Id: hmac_link.c,v 1.13 2009/09/03 23:48:12 tbox Exp $
*/
#include <config.h>
@@ -268,13 +268,14 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv);
if (result != ISC_R_SUCCESS)
@@ -537,13 +538,14 @@ hmacsha1_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
&priv);
@@ -807,13 +809,14 @@ hmacsha224_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
&priv);
@@ -1077,13 +1080,14 @@ hmacsha256_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
&priv);
@@ -1347,13 +1351,14 @@ hmacsha384_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
&priv);
@@ -1617,13 +1622,14 @@ hmacsha512_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
&priv);
diff --git a/lib/dns/include/dns/client.h b/lib/dns/include/dns/client.h
new file mode 100644
index 00000000..d21dff78
--- /dev/null
+++ b/lib/dns/include/dns/client.h
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: client.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef DNS_CLIENT_H
+#define DNS_CLIENT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ *
+ * \brief
+ * The DNS client module provides convenient programming interfaces to various
+ * DNS services, such as name resolution with or without DNSSEC validation or
+ * dynamic DNS update. This module is primarily expected to be used by other
+ * applications than BIND9-related ones that need such advanced DNS features.
+ *
+ * MP:
+ *\li In the typical usage of this module, application threads will not share
+ * the same data structures created and manipulated in this module.
+ * However, the module still ensures appropriate synchronization of such
+ * data structures.
+ *
+ * Resources:
+ *\li TBS
+ *
+ * Security:
+ *\li This module does not handle any low-level data directly, and so no
+ * security issue specific to this module is anticipated.
+ */
+
+#include <isc/event.h>
+#include <isc/sockaddr.h>
+
+#include <dns/tsig.h>
+#include <dns/types.h>
+
+#include <dst/dst.h>
+
+typedef enum {
+ updateop_none = 0,
+ updateop_add = 1,
+ updateop_delete = 2,
+ updateop_exist = 3,
+ updateop_notexist = 4,
+ updateop_max = 5
+} dns_client_updateop_t;
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*%
+ * Optional flags for dns_client_create(x).
+ */
+/*%< Enable caching resolution results (experimental). */
+#define DNS_CLIENTCREATEOPT_USECACHE 0x8000
+
+/*%
+ * Optional flags for dns_client_(start)resolve.
+ */
+/*%< Disable DNSSEC validation. */
+#define DNS_CLIENTRESOPT_NODNSSEC 0x01
+/*%< Allow running external context. */
+#define DNS_CLIENTRESOPT_ALLOWRUN 0x02
+
+/*%
+ * Optional flags for dns_client_(start)request.
+ */
+/*%< Allow running external context. */
+#define DNS_CLIENTREQOPT_ALLOWRUN 0x01
+
+/*%
+ * A dns_clientresevent_t is sent when name resolution performed by a client
+ * completes. 'result' stores the result code of the entire resolution
+ * procedure. 'vresult' specifically stores the result code of DNSSEC
+ * validation if it is performed. When name resolution successfully completes,
+ * 'answerlist' is typically non empty, containing answer names along with
+ * RRsets. It is the receiver's responsibility to free this list by calling
+ * dns_client_freeresanswer() before freeing the event structure.
+ */
+typedef struct dns_clientresevent {
+ ISC_EVENT_COMMON(struct dns_clientresevent);
+ isc_result_t result;
+ isc_result_t vresult;
+ dns_namelist_t answerlist;
+} dns_clientresevent_t; /* too long? */
+
+/*%
+ * Status of a dynamic update procedure.
+ */
+typedef enum {
+ dns_clientupdatestate_prepare, /*%< no updates have been sent */
+ dns_clientupdatestate_sent, /*%< updates were sent, no response */
+ dns_clientupdatestate_done /*%< update was sent and succeeded */
+} dns_clientupdatestate_t;
+
+/*%
+ * A dns_clientreqevent_t is sent when a DNS request is completed by a client.
+ * 'result' stores the result code of the entire transaction.
+ * If the transaction is successfully completed but the response packet cannot
+ * be parsed, 'result' will store the result code of dns_message_parse().
+ * If the response packet is received, 'rmessage' will contain the response
+ * message, whether it is successfully parsed or not.
+ */
+typedef struct dns_clientreqevent {
+ ISC_EVENT_COMMON(struct dns_clientreqevent);
+ isc_result_t result;
+ dns_message_t *rmessage;
+} dns_clientreqevent_t; /* too long? */
+
+/*%
+ * A dns_clientupdateevent_t is sent when dynamic update performed by a client
+ * completes. 'result' stores the result code of the entire update procedure.
+ * 'state' specifies the status of the update procedure when this event is
+ * sent. This can be used as a hint by the receiver to determine whether
+ * the update attempt was ever made. In particular, if the state is
+ * dns_clientupdatestate_prepare, the receiver can be sure that the requested
+ * update was not applied.
+ */
+typedef struct dns_clientupdateevent {
+ ISC_EVENT_COMMON(struct dns_clientupdateevent);
+ isc_result_t result;
+ dns_clientupdatestate_t state;
+} dns_clientupdateevent_t; /* too long? */
+
+isc_result_t
+dns_client_create(dns_client_t **clientp, unsigned int options);
+
+isc_result_t
+dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
+ isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
+ unsigned int options, dns_client_t **clientp);
+/*%<
+ * Create a DNS client. These functions create a new client object with
+ * minimal internal resources such as the default 'view' for the IN class and
+ * IPv4/IPv6 dispatches for the view.
+ *
+ * dns_client_createx() takes 'manager' arguments so that the caller can
+ * control the behavior of the client through the underlying event framework.
+ * On the other hand, dns_client_create() simplifies the interface and creates
+ * the managers internally. A DNS client object created via
+ * dns_client_create() is expected to be used by an application that only needs
+ * simple synchronous services or by a thread-based application.
+ *
+ * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
+ * dns_client_create(x) will create a cache database with the view.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'actx' is a valid application context.
+ *
+ *\li 'taskmgr' is a valid task manager.
+ *
+ *\li 'socketmgr' is a valid socket manager.
+ *
+ *\li 'timermgr' is a valid timer manager.
+ *
+ *\li clientp != NULL && *clientp == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_client_destroy(dns_client_t **clientp);
+/*%<
+ * Destroy 'client'.
+ *
+ * Requires:
+ *
+ *\li '*clientp' is a valid client.
+ *
+ * Ensures:
+ *
+ *\li *clientp == NULL.
+ */
+
+isc_result_t
+dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace, isc_sockaddrlist_t *addrs);
+/*%<
+ * Specify a list of addresses of recursive name servers that the client will
+ * use for name resolution. A view for the 'rdclass' class must be created
+ * beforehand. If 'namespace' is non NULL, the specified server will be used
+ * if and only if the query name is a subdomain of 'namespace'. When servers
+ * for multiple 'namespace's are provided, and a query name is covered by
+ * more than one 'namespace', the servers for the best (longest) matching
+ * namespace will be used. If 'namespace' is NULL, it works as if
+ * dns_rootname (.) were specified.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'namespace' is NULL or a valid name.
+ *
+ *\li 'addrs' != NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+isc_result_t
+dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace);
+/*%<
+ * Remove configured recursive name servers for the 'rdclass' and 'namespace'
+ * from the client. See the description of dns_client_setservers() for
+ * the requirements about 'rdclass' and 'namespace'.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'namespace' is NULL or a valid name.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+isc_result_t
+dns_client_resolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, dns_namelist_t *namelist);
+
+isc_result_t
+dns_client_startresolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_clientrestrans_t **transp);
+/*%<
+ * Perform name resolution for 'name', 'rdclass', and 'type'.
+ *
+ * If any trusted keys are configured and the query name is considered to
+ * belong to a secure zone, these functions also validate the responses
+ * using DNSSEC by default. If the DNS_CLIENTRESOPT_NODNSSEC flag is set
+ * in 'options', DNSSEC validation is disabled regardless of the configured
+ * trusted keys or the query name.
+ *
+ * dns_client_resolve() provides a synchronous service. This function starts
+ * name resolution internally and blocks until it completes. On success,
+ * 'namelist' will contain a list of answer names, each of which has
+ * corresponding RRsets. The caller must provide a valid empty list, and
+ * is responsible for freeing the list content via dns_client_freeresanswer().
+ * If the name resolution fails due to an error in DNSSEC validation,
+ * dns_client_resolve() returns the result code indicating the validation
+ * error. Otherwise, it returns the result code of the entire resolution
+ * process, either success or failure.
+ *
+ * It is typically expected that the client object passed to
+ * dns_client_resolve() was created via dns_client_create() and has its own
+ * managers and contexts. However, if the DNS_CLIENTRESOPT_ALLOWRUN flag is
+ * set in 'options', this function performs the synchronous service even if
+ * it does not have its own manager and context structures.
+ *
+ * dns_client_startresolve() is an asynchronous version of dns_client_resolve()
+ * and does not block. When name resolution is completed, 'action' will be
+ * called with the argument of a 'dns_clientresevent_t' object, which contains
+ * the resulting list of answer names (on success). On return, '*transp' is
+ * set to an opaque transaction ID so that the caller can cancel this
+ * resolution process.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'addrs' != NULL.
+ *
+ *\li 'name' is a valid name.
+ *
+ *\li 'namelist' != NULL and is not empty.
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'transp' != NULL && *transp == NULL;
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_client_cancelresolve(dns_clientrestrans_t *trans);
+/*%<
+ * Cancel an ongoing resolution procedure started via
+ * dns_client_startresolve().
+ *
+ * Notes:
+ *
+ *\li If the resolution procedure has not completed, post its CLIENTRESDONE
+ * event with a result code of #ISC_R_CANCELED.
+ *
+ * Requires:
+ *
+ *\li 'trans' is a valid transaction ID.
+ */
+
+void
+dns_client_destroyrestrans(dns_clientrestrans_t **transp);
+/*%<
+ * Destroy name resolution transaction state identified by '*transp'.
+ *
+ * Requires:
+ *
+ *\li '*transp' is a valid transaction ID.
+ *
+ *\li The caller has received the CLIENTRESDONE event (either because the
+ * resolution completed or because dns_client_cancelresolve() was called).
+ *
+ * Ensures:
+ *
+ *\li *transp == NULL.
+ */
+
+void
+dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
+/*%<
+ * Free resources allocated for the content of 'namelist'.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'namelist' != NULL.
+ */
+
+isc_result_t
+dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *keyname, isc_buffer_t *keydatabuf);
+/*%<
+ * Add a DNSSEC trusted key for the 'rdclass' class. A view for the 'rdclass'
+ * class must be created beforehand. 'keyname' is the DNS name of the key,
+ * and 'keydatabuf' stores the resource data of the key.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'keyname' is a valid name.
+ *
+ *\li 'keydatabuf' is a valid buffer.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+isc_result_t
+dns_client_request(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries);
+
+isc_result_t
+dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientreqtrans_t **transp);
+
+/*%<
+ * Send a DNS request containig a query message 'query' to 'server'.
+ *
+ * 'parseoptions' will be used when the response packet is parsed, and will be
+ * passed to dns_message_parse() via dns_request_getresponse(). See
+ * dns_message_parse() for more details.
+ *
+ * 'tsec' is a transaction security object containing, e.g. a TSIG key for
+ * authenticating the request/response transaction. This is optional and can
+ * be NULL, in which case this library performs the transaction without any
+ * transaction authentication.
+ *
+ * 'timeout', 'udptimeout', and 'udpretries' are passed to
+ * dns_request_createvia3(). See dns_request_createvia3() for more details.
+ *
+ * dns_client_request() provides a synchronous service. This function sends
+ * the request and blocks until a response is received. On success,
+ * 'rmessage' will contain the response message. The caller must provide a
+ * valid initialized message.
+ *
+ * It is usually expected that the client object passed to
+ * dns_client_request() was created via dns_client_create() and has its own
+ * managers and contexts. However, if the DNS_CLIENTREQOPT_ALLOWRUN flag is
+ * set in 'options', this function performs the synchronous service even if
+ * it does not have its own manager and context structures.
+ *
+ * dns_client_startrequest() is an asynchronous version of dns_client_request()
+ * and does not block. When the transaction is completed, 'action' will be
+ * called with the argument of a 'dns_clientreqevent_t' object, which contains
+ * the response message (on success). On return, '*transp' is set to an opaque
+ * transaction ID so that the caller can cancel this request.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'qmessage' and 'rmessage' are valid initialized message.
+ *
+ *\li 'server' is a valid socket address structure.
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'transp' != NULL && *transp == NULL;
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ *
+ *\li Any result that dns_message_parse() can return.
+ */
+
+void
+dns_client_cancelrequest(dns_clientreqtrans_t *transp);
+/*%<
+ * Cancel an ongoing DNS request procedure started via
+ * dns_client_startrequest().
+ *
+ * Notes:
+ *
+ *\li If the request procedure has not completed, post its CLIENTREQDONE
+ * event with a result code of #ISC_R_CANCELED.
+ *
+ * Requires:
+ *
+ *\li 'trans' is a valid transaction ID.
+ */
+
+void
+dns_client_destroyreqtrans(dns_clientreqtrans_t **transp);
+/*%
+ * Destroy DNS request transaction state identified by '*transp'.
+ *
+ * Requires:
+ *
+ *\li '*transp' is a valid transaction ID.
+ *
+ *\li The caller has received the CLIENTREQDONE event (either because the
+ * request completed or because dns_client_cancelrequest() was called).
+ *
+ * Ensures:
+ *
+ *\li *transp == NULL.
+ */
+
+isc_result_t
+dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options);
+
+isc_result_t
+dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientupdatetrans_t **transp);
+/*%<
+ * Perform DNS dynamic update for 'updates' of the 'rdclass' class with
+ * optional 'prerequisites'.
+ *
+ * 'updates' are a list of names with associated RRsets to be updated.
+ *
+ * 'prerequisites' are a list of names with associated RRsets corresponding to
+ * the prerequisites of the updates. This is optional and can be NULL, in
+ * which case the prerequisite section of the update message will be empty.
+ *
+ * Both 'updates' and 'prerequisites' must be constructed as specified in
+ * RFC2136.
+ *
+ * 'zonename' is the name of the zone in which the updated names exist.
+ * This is optional and can be NULL. In this case, these functions internally
+ * identify the appropriate zone through some queries for the SOA RR starting
+ * with the first name in prerequisites or updates.
+ *
+ * 'servers' is a list of authoritative servers to which the update message
+ * should be sent. This is optional and can be NULL. In this case, these
+ * functions internally identify the appropriate primary server name and its
+ * addresses through some queries for the SOA RR (like the case of zonename)
+ * and supplemental A/AAAA queries for the server name.
+ * Note: The client module generally assumes the given addresses are of the
+ * primary server of the corresponding zone. It will work even if a secondary
+ * server address is specified as long as the server allows update forwarding,
+ * it is generally discouraged to include secondary server addresses unless
+ * there's strong reason to do so.
+ *
+ * 'tsec' is a transaction security object containing, e.g. a TSIG key for
+ * authenticating the update transaction (and the supplemental query/response
+ * transactions if the server is specified). This is optional and can be
+ * NULL, in which case the library tries the update without any transaction
+ * authentication.
+ *
+ * dns_client_update() provides a synchronous service. This function blocks
+ * until the entire update procedure completes, including the additional
+ * queries when necessary.
+ *
+ * dns_client_startupdate() is an asynchronous version of dns_client_update().
+ * It immediately returns (typically with *transp being set to a non-NULL
+ * pointer), and performs the update procedure through a set of internal
+ * events. All transactions including the additional query exchanges are
+ * performed as a separate event, so none of these events cause blocking
+ * operation. When the update procedure completes, the specified function
+ * 'action' will be called with the argument of a 'dns_clientupdateevent_t'
+ * structure. On return, '*transp' is set to an opaque transaction ID so that
+ * the caller can cancel this update process.
+ *
+ * Notes:
+ *\li No options are currently defined.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'updates' != NULL.
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'transp' != NULL && *transp == NULL;
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_client_cancelupdate(dns_clientupdatetrans_t *trans);
+/*%<
+ * Cancel an ongoing dynamic update procedure started via
+ * dns_client_startupdate().
+ *
+ * Notes:
+ *
+ *\li If the update procedure has not completed, post its UPDATEDONE
+ * event with a result code of #ISC_R_CANCELED.
+ *
+ * Requires:
+ *
+ *\li 'trans' is a valid transaction ID.
+ */
+
+void
+dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp);
+/*%<
+ * Destroy dynamic update transaction identified by '*transp'.
+ *
+ * Requires:
+ *
+ *\li '*transp' is a valid transaction ID.
+ *
+ *\li The caller has received the UPDATEDONE event (either because the
+ * update completed or because dns_client_cancelupdate() was called).
+ *
+ * Ensures:
+ *
+ *\li *transp == NULL.
+ */
+
+isc_result_t
+dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner,
+ dns_rdatatype_t type, dns_rdata_t *source,
+ dns_ttl_t ttl, dns_name_t *target,
+ dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist,
+ dns_rdata_t *rdata, isc_mem_t *mctx);
+/*%<
+ * TBD
+ */
+
+void
+dns_client_freeupdate(dns_name_t **namep);
+/*%<
+ * TBD
+ */
+
+isc_mem_t *
+dns_client_mctx(dns_client_t *client);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_CLIENT_H */
diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h
index ea1c9167..9064a737 100644
--- a/lib/dns/include/dns/dnssec.h
+++ b/lib/dns/include/dns/dnssec.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec.h,v 1.35 2009/07/19 04:18:05 each Exp $ */
+/* $Id: dnssec.h,v 1.36 2009/09/02 06:29:01 each Exp $ */
#ifndef DNS_DNSSEC_H
#define DNS_DNSSEC_H 1
@@ -52,6 +52,7 @@ struct dns_dnsseckey {
isc_boolean_t hint_sign; /*% metadata says to sign with this key */
isc_boolean_t force_sign; /*% sign with key regardless of metadata */
isc_boolean_t hint_remove; /*% metadata says *don't* publish */
+ unsigned int prepublish; /*% how long until active? */
dns_keysource_t source; /*% how the key was found */
isc_boolean_t ksk; /*% this is a key-signing key */
isc_boolean_t legacy; /*% this is old-style key with no
diff --git a/lib/dns/include/dns/ecdb.h b/lib/dns/include/dns/ecdb.h
new file mode 100644
index 00000000..5c735b53
--- /dev/null
+++ b/lib/dns/include/dns/ecdb.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: ecdb.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef DNS_ECDB_H
+#define DNS_ECDB_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/* TBD */
+
+/***
+ *** Imports
+ ***/
+
+#include <dns/types.h>
+
+/***
+ *** Types
+ ***/
+
+/***
+ *** Functions
+ ***/
+
+/* TBD: describe those */
+
+isc_result_t
+dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp);
+
+void
+dns_ecdb_unregister(dns_dbimplementation_t **dbimp);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_ECDB_H */
diff --git a/lib/dns/include/dns/events.h b/lib/dns/include/dns/events.h
index ec4aee01..c92f44be 100644
--- a/lib/dns/include/dns/events.h
+++ b/lib/dns/include/dns/events.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: events.h,v 1.52 2009/06/30 02:52:32 each Exp $ */
+/* $Id: events.h,v 1.53 2009/09/01 00:22:26 jinmei Exp $ */
#ifndef DNS_EVENTS_H
#define DNS_EVENTS_H 1
@@ -70,6 +70,8 @@
#define DNS_EVENT_ACACHEOVERMEM (ISC_EVENTCLASS_DNS + 40)
#define DNS_EVENT_RBTPRUNE (ISC_EVENTCLASS_DNS + 41)
#define DNS_EVENT_MANAGEKEYS (ISC_EVENTCLASS_DNS + 42)
+#define DNS_EVENT_CLIENTRESDONE (ISC_EVENTCLASS_DNS + 43)
+#define DNS_EVENT_CLIENTREQDONE (ISC_EVENTCLASS_DNS + 44)
#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
diff --git a/lib/dns/include/dns/forward.h b/lib/dns/include/dns/forward.h
index 512c5e3c..23e94be7 100644
--- a/lib/dns/include/dns/forward.h
+++ b/lib/dns/include/dns/forward.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: forward.h,v 1.11 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: forward.h,v 1.13 2009/09/02 23:48:02 tbox Exp $ */
#ifndef DNS_FORWARD_H
#define DNS_FORWARD_H 1
@@ -67,6 +67,21 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
*/
isc_result_t
+dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name);
+/*%<
+ * Removes an entry for 'name' from the forwarding table. If an entry
+ * that exactly matches 'name' does not exist, ISC_R_NOTFOUND will be returned.
+ *
+ * Requires:
+ * \li fwdtable is a valid forwarding table.
+ * \li name is a valid name
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_NOTFOUND
+ */
+
+isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name,
dns_forwarders_t **forwardersp);
/*%<
diff --git a/lib/dns/include/dns/lib.h b/lib/dns/include/dns/lib.h
index fd3325b9..a78562f9 100644
--- a/lib/dns/include/dns/lib.h
+++ b/lib/dns/include/dns/lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: lib.h,v 1.18 2009/09/02 23:48:02 tbox Exp $ */
#ifndef DNS_LIB_H
#define DNS_LIB_H 1
@@ -40,6 +40,20 @@ dns_lib_initmsgcat(void);
* has not already been initialized.
*/
+isc_result_t
+dns_lib_init(void);
+/*%<
+ * A set of initialization procedure used in the DNS library. This function
+ * is provided for an application that is not aware of the underlying ISC or
+ * DNS libraries much.
+ */
+
+void
+dns_lib_shutdown(void);
+/*%<
+ * Free temporary resources allocated in dns_lib_init().
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_LIB_H */
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index c499e5a2..044b0103 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: message.h,v 1.127 2009/01/17 23:47:43 tbox Exp $ */
+/* $Id: message.h,v 1.128 2009/09/01 00:22:26 jinmei Exp $ */
#ifndef DNS_MESSAGE_H
#define DNS_MESSAGE_H 1
@@ -81,8 +81,7 @@
* name = NULL;
* name = dns_message_gettempname(message, &name);
* dns_name_init(name, NULL);
- * result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE,
- * buffer);
+ * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
* dns_message_takebuffer(message, &buffer);
* \endcode
*
diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h
index 4c6c5231..8608ef38 100644
--- a/lib/dns/include/dns/name.h
+++ b/lib/dns/include/dns/name.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name.h,v 1.130 2009/06/30 02:52:32 each Exp $ */
+/* $Id: name.h,v 1.132 2009/09/01 17:36:51 jinmei Exp $ */
#ifndef DNS_NAME_H
#define DNS_NAME_H 1
@@ -127,21 +127,27 @@ struct dns_name {
#define DNS_NAME_MAGIC ISC_MAGIC('D','N','S','n')
-#define DNS_NAMEATTR_ABSOLUTE 0x0001
-#define DNS_NAMEATTR_READONLY 0x0002
-#define DNS_NAMEATTR_DYNAMIC 0x0004
-#define DNS_NAMEATTR_DYNOFFSETS 0x0008
-#define DNS_NAMEATTR_NOCOMPRESS 0x0010
+#define DNS_NAMEATTR_ABSOLUTE 0x00000001
+#define DNS_NAMEATTR_READONLY 0x00000002
+#define DNS_NAMEATTR_DYNAMIC 0x00000004
+#define DNS_NAMEATTR_DYNOFFSETS 0x00000008
+#define DNS_NAMEATTR_NOCOMPRESS 0x00000010
/*
* Attributes below 0x0100 reserved for name.c usage.
*/
-#define DNS_NAMEATTR_CACHE 0x0100 /*%< Used by resolver. */
-#define DNS_NAMEATTR_ANSWER 0x0200 /*%< Used by resolver. */
-#define DNS_NAMEATTR_NCACHE 0x0400 /*%< Used by resolver. */
-#define DNS_NAMEATTR_CHAINING 0x0800 /*%< Used by resolver. */
-#define DNS_NAMEATTR_CHASE 0x1000 /*%< Used by resolver. */
-#define DNS_NAMEATTR_WILDCARD 0x2000 /*%< Used by server. */
+#define DNS_NAMEATTR_CACHE 0x00000100 /*%< Used by resolver. */
+#define DNS_NAMEATTR_ANSWER 0x00000200 /*%< Used by resolver. */
+#define DNS_NAMEATTR_NCACHE 0x00000400 /*%< Used by resolver. */
+#define DNS_NAMEATTR_CHAINING 0x00000800 /*%< Used by resolver. */
+#define DNS_NAMEATTR_CHASE 0x00001000 /*%< Used by resolver. */
+#define DNS_NAMEATTR_WILDCARD 0x00002000 /*%< Used by server. */
+#define DNS_NAMEATTR_PREREQUISITE 0x00004000 /*%< Used by client. */
+#define DNS_NAMEATTR_UPDATE 0x00008000 /*%< Used by client. */
+#define DNS_NAMEATTR_HASUPDATEREC 0x00010000 /*%< Used by client. */
+/*
+ * Various flags.
+ */
#define DNS_NAME_DOWNCASE 0x0001
#define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */
#define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */
@@ -1151,50 +1157,17 @@ dns_name_tostring(dns_name_t *source, char **target, isc_mem_t *mctx);
*/
isc_result_t
-dns_name_fromstring(dns_name_t *target, const char *src, isc_mem_t *mctx);
-/*%<
- * Convert a string to a name and place it in target, allocating memory
- * as necessary.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *
- *\li Any error that dns_name_fromtext() can return.
- *
- *\li Any error that dns_name_dup() can return.
- */
-
-isc_result_t
-dns_name_tostring(dns_name_t *source, char **target, isc_mem_t *mctx);
-/*%<
- * Convert 'name' to string format, allocating sufficient memory to
- * hold it (free with isc_mem_free()).
- *
- * Differs from dns_name_format in that it allocates its own memory.
- *
- * Requires:
- *
- *\li 'name' is a valid name.
- *\li 'target' is not NULL.
- *\li '*target' is NULL.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\li Any error that dns_name_totext() can return.
- */
-
-isc_result_t
-dns_name_fromstring(dns_name_t *target, const char *src, isc_mem_t *mctx);
+dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
+ isc_mem_t *mctx);
/*%<
* Convert a string to a name and place it in target, allocating memory
- * as necessary.
+ * as necessary. 'options' has the same semantics as that of
+ * dns_name_fromtext().
*
* Requires:
*
* \li 'target' is a valid name that is not read-only.
+ * \li 'src' is not NULL.
*
* Returns:
*
diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h
index 7b1d7f2c..6051752c 100644
--- a/lib/dns/include/dns/rdata.h
+++ b/lib/dns/include/dns/rdata.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.h,v 1.73 2009/01/17 23:47:43 tbox Exp $ */
+/* $Id: rdata.h,v 1.74 2009/09/01 00:22:26 jinmei Exp $ */
#ifndef DNS_RDATA_H
#define DNS_RDATA_H 1
@@ -95,6 +95,7 @@
#include <dns/types.h>
#include <dns/name.h>
+#include <dns/message.h>
ISC_LANG_BEGINDECLS
@@ -698,6 +699,21 @@ dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad);
* 'bad' to be NULL or valid.
*/
+void
+dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type);
+
+void
+dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type);
+
+void
+dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type);
+
+void
+dns_rdata_makedelete(dns_rdata_t *rdata);
+
+const char *
+dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section);
+
ISC_LANG_ENDDECLS
#endif /* DNS_RDATA_H */
diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h
index 04a7a1e0..bdf4c643 100644
--- a/lib/dns/include/dns/resolver.h
+++ b/lib/dns/include/dns/resolver.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.h,v 1.63 2009/01/27 22:29:59 jinmei Exp $ */
+/* $Id: resolver.h,v 1.64 2009/09/01 00:22:26 jinmei Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -81,6 +81,7 @@ typedef struct dns_fetchevent {
dns_fixedname_t foundname;
isc_sockaddr_t * client;
dns_messageid_t id;
+ isc_result_t vresult;
} dns_fetchevent_t;
/*
diff --git a/lib/dns/include/dns/soa.h b/lib/dns/include/dns/soa.h
index 81425d46..696235ee 100644
--- a/lib/dns/include/dns/soa.h
+++ b/lib/dns/include/dns/soa.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: soa.h,v 1.11 2009/07/01 23:47:36 tbox Exp $ */
+/* $Id: soa.h,v 1.12 2009/09/10 01:47:09 each Exp $ */
#ifndef DNS_SOA_H
#define DNS_SOA_H 1
@@ -40,12 +40,28 @@
ISC_LANG_BEGINDECLS
+#define DNS_SOA_BUFFERSIZE ((2 * DNS_NAME_MAXWIRE) + (4 * 5))
+
isc_result_t
dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact,
dns_rdataclass_t rdclass,
isc_uint32_t serial, isc_uint32_t refresh,
isc_uint32_t retry, isc_uint32_t expire,
- isc_uint32_t minimum, dns_rdata_t *rdata);
+ isc_uint32_t minimum, unsigned char *buffer,
+ dns_rdata_t *rdata);
+/*%<
+ * Build the rdata of an SOA record.
+ *
+ * Requires:
+ *\li buffer Points to a temporary buffer of at least
+ * DNS_SOA_BUFFERSIZE bytes.
+ *\li rdata Points to an initialized dns_rdata_t.
+ *
+ * Ensures:
+ * \li *rdata Contains a valid SOA rdata. The 'data' member
+ * refers to 'buffer'.
+ */
+
isc_uint32_t
dns_soa_getserial(dns_rdata_t *rdata);
isc_uint32_t
diff --git a/lib/dns/include/dns/tsec.h b/lib/dns/include/dns/tsec.h
new file mode 100644
index 00000000..c6b376a1
--- /dev/null
+++ b/lib/dns/include/dns/tsec.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: tsec.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef DNS_TSEC_H
+#define DNS_TSEC_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ *
+ * \brief
+ * The TSEC (Transaction Security) module is an abstraction layer for managing
+ * DNS transaction mechanisms such as TSIG or SIG(0). A TSEC structure is a
+ * mechanism-independent object containing key information specific to the
+ * mechanism, and is expected to be used as an argument to other modules
+ * that use transaction security in a mechanism-independent manner.
+ *
+ * MP:
+ *\li A TSEC structure is expected to be thread-specific. No inter-thread
+ * synchronization is ensured in multiple access to a single TSEC
+ * structure.
+ *
+ * Resources:
+ *\li TBS
+ *
+ * Security:
+ *\li This module does not handle any low-level data directly, and so no
+ * security issue specific to this module is anticipated.
+ */
+
+#include <dns/types.h>
+
+#include <dst/dst.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*%
+ * Transaction security types.
+ */
+typedef enum {
+ dns_tsectype_none,
+ dns_tsectype_tsig,
+ dns_tsectype_sig0
+} dns_tsectype_t;
+
+isc_result_t
+dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key,
+ dns_tsec_t **tsecp);
+/*%<
+ * Create a TSEC structure and stores a type-dependent key structure in it.
+ * For a TSIG key (type is dns_tsectype_tsig), dns_tsec_create() creates a
+ * TSIG key structure from '*key' and keeps it in the structure. For other
+ * types, this function simply retains '*key' in the structure. In either
+ * case, the ownership of '*key' is transferred to the TSEC module; the caller
+ * must not modify or destroy it after the call to dns_tsec_create().
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'type' is a valid value of dns_tsectype_t (see above).
+ *
+ *\li 'key' is a valid key.
+ *
+ *\li tsecp != NULL && *tsecp == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_tsec_destroy(dns_tsec_t **tsecp);
+/*%<
+ * Destroy the TSEC structure. The stored key is also detached or destroyed.
+ *
+ * Requires
+ *
+ *\li '*tsecp' is a valid TSEC structure.
+ *
+ * Ensures
+ *
+ *\li *tsecp == NULL.
+ *
+ */
+
+dns_tsectype_t
+dns_tsec_gettype(dns_tsec_t *tsec);
+/*%<
+ * Return the TSEC type of '*tsec'.
+ *
+ * Requires
+ *
+ *\li 'tsec' is a valid TSEC structure.
+ *
+ */
+
+void
+dns_tsec_getkey(dns_tsec_t *tsec, void *keyp);
+/*%<
+ * Return the TSEC key of '*tsec' in '*keyp'.
+ *
+ * Requires
+ *
+ *\li keyp != NULL
+ *
+ * Ensures
+ *
+ *\li *tsecp points to a valid key structure depending on the TSEC type.
+ */
+
+#endif /* DNS_TSEC_H */
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 2e100d31..79be222e 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.135 2009/07/19 04:18:05 each Exp $ */
+/* $Id: types.h,v 1.136 2009/09/01 00:22:27 jinmei Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
@@ -44,6 +44,10 @@ typedef struct dns_adbentry dns_adbentry_t;
typedef struct dns_adbfind dns_adbfind_t;
typedef ISC_LIST(dns_adbfind_t) dns_adbfindlist_t;
typedef struct dns_byaddr dns_byaddr_t;
+typedef struct dns_client dns_client_t;
+typedef void dns_clientrestrans_t;
+typedef void dns_clientreqtrans_t;
+typedef void dns_clientupdatetrans_t;
typedef struct dns_cache dns_cache_t;
typedef isc_uint16_t dns_cert_t;
typedef struct dns_compress dns_compress_t;
@@ -114,6 +118,7 @@ typedef struct dns_stats dns_stats_t;
typedef isc_uint32_t dns_rdatastatstype_t;
typedef struct dns_tkeyctx dns_tkeyctx_t;
typedef isc_uint16_t dns_trust_t;
+typedef struct dns_tsec dns_tsec_t;
typedef struct dns_tsig_keyring dns_tsig_keyring_t;
typedef struct dns_tsigkey dns_tsigkey_t;
typedef isc_uint32_t dns_ttl_t;
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
index 0236248f..258e6143 100644
--- a/lib/dns/include/dst/dst.h
+++ b/lib/dns/include/dst/dst.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst.h,v 1.16 2009/07/19 04:18:05 each Exp $ */
+/* $Id: dst.h,v 1.17 2009/09/02 06:29:01 each Exp $ */
#ifndef DST_DST_H
#define DST_DST_H 1
@@ -84,7 +84,7 @@ typedef struct dst_context dst_context_t;
#define DST_TIME_PUBLISH 1
#define DST_TIME_ACTIVATE 2
#define DST_TIME_REVOKE 3
-#define DST_TIME_REMOVE 4
+#define DST_TIME_UNPUBLISH 4
#define DST_TIME_DELETE 5
#define DST_MAX_TIMES 5
@@ -683,6 +683,39 @@ dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when);
* "type" is no larger than DST_MAX_TIMES
*/
+void
+dst_key_unsettime(dst_key_t *key, int type);
+/*%<
+ * Flag a member of the timing metadata array as "not set".
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_TIMES
+ */
+
+isc_result_t
+dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp);
+/*%<
+ * Get the private key format version number. (If the key does not have
+ * a private key associated with it, the version will be 0.0.) The major
+ * version number is placed in '*majorp', and the minor version number in
+ * '*minorp'.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "majorp" is not NULL.
+ * "minorp" is not NULL.
+ */
+
+void
+dst_key_setprivateformat(dst_key_t *key, int major, int minor);
+/*%<
+ * Set the private key format version number.
+ *
+ * Requires:
+ * "key" is a valid key.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DST_DST_H */
diff --git a/lib/dns/journal.c b/lib/dns/journal.c
index b7970215..bc1ba0cd 100644
--- a/lib/dns/journal.c
+++ b/lib/dns/journal.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.c,v 1.105 2009/01/17 23:47:42 tbox Exp $ */
+/* $Id: journal.c,v 1.106 2009/08/25 07:41:28 marka Exp $ */
#include <config.h>
@@ -562,11 +562,9 @@ journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write,
if (result == ISC_R_FILENOTFOUND) {
if (create) {
- isc_log_write(JOURNAL_COMMON_LOGARGS,
- ISC_LOG_INFO,
+ isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(1),
"journal file %s does not exist, "
- "creating it",
- j->filename);
+ "creating it", j->filename);
CHECK(journal_file_create(mctx, filename));
/*
* Retry.
diff --git a/lib/dns/lib.c b/lib/dns/lib.c
index 6f98b537..df16fa22 100644
--- a/lib/dns/lib.c
+++ b/lib/dns/lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.c,v 1.16 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: lib.c,v 1.19 2009/09/03 00:12:23 each Exp $ */
/*! \file */
@@ -23,11 +23,20 @@
#include <stddef.h>
-#include <isc/once.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
#include <isc/msgcat.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
#include <isc/util.h>
+#include <dns/db.h>
+#include <dns/ecdb.h>
#include <dns/lib.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
/***
*** Globals
@@ -63,3 +72,97 @@ dns_lib_initmsgcat(void) {
RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS);
}
+
+static isc_once_t init_once = ISC_ONCE_INIT;
+static isc_mem_t *dns_g_mctx = NULL;
+#ifndef BIND9
+static dns_dbimplementation_t *dbimp = NULL;
+#endif
+static isc_boolean_t initialize_done = ISC_FALSE;
+static isc_mutex_t reflock;
+static unsigned int references = 0;
+
+static void
+initialize(void) {
+ isc_result_t result;
+
+ REQUIRE(initialize_done == ISC_FALSE);
+
+ result = isc_mem_create(0, 0, &dns_g_mctx);
+ if (result != ISC_R_SUCCESS)
+ return;
+ dns_result_register();
+#ifndef BIND9
+ result = dns_ecdb_register(dns_g_mctx, &dbimp);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_mctx;
+#endif
+ result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_db;
+
+ result = dst_lib_init(dns_g_mctx, NULL, 0);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_hash;
+
+ result = isc_mutex_init(&reflock);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_dst;
+
+ initialize_done = ISC_TRUE;
+ return;
+
+ cleanup_dst:
+ dst_lib_destroy();
+ cleanup_hash:
+ isc_hash_destroy();
+ cleanup_db:
+#ifndef BIND9
+ dns_ecdb_unregister(&dbimp);
+ cleanup_mctx:
+#endif
+ isc_mem_detach(&dns_g_mctx);
+}
+
+isc_result_t
+dns_lib_init(void) {
+ isc_result_t result;
+
+ /*
+ * Since this routine is expected to be used by a normal application,
+ * it should be better to return an error, instead of an emergency
+ * abort, on any failure.
+ */
+ result = isc_once_do(&init_once, initialize);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (!initialize_done)
+ return (ISC_R_FAILURE);
+
+ LOCK(&reflock);
+ references++;
+ UNLOCK(&reflock);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_lib_shutdown(void) {
+ isc_boolean_t cleanup_ok = ISC_FALSE;
+
+ LOCK(&reflock);
+ if (--references == 0)
+ cleanup_ok = ISC_TRUE;
+ UNLOCK(&reflock);
+
+ if (!cleanup_ok)
+ return;
+
+ dst_lib_destroy();
+ isc_hash_destroy();
+#ifndef BIND9
+ dns_ecdb_unregister(&dbimp);
+#endif
+ isc_mem_detach(&dns_g_mctx);
+}
diff --git a/lib/dns/master.c b/lib/dns/master.c
index 35543520..49e2985c 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.c,v 1.177 2009/06/30 02:52:32 each Exp $ */
+/* $Id: master.c,v 1.178 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -1382,7 +1382,7 @@ load_text(dns_loadctx_t *lctx) {
isc_buffer_setactive(&buffer,
token.value.as_region.length);
result = dns_name_fromtext(new_name, &buffer,
- ictx->origin, ISC_FALSE, NULL);
+ ictx->origin, 0, NULL);
if (MANYERRS(lctx, result)) {
SETRESULT(lctx, result);
LOGIT(result);
diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c
index ce949627..a451d98d 100644
--- a/lib/dns/masterdump.c
+++ b/lib/dns/masterdump.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.97 2009/01/17 23:47:42 tbox Exp $ */
+/* $Id: masterdump.c,v 1.98 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -162,6 +162,7 @@ static char spaces[N_SPACES+1] = " ";
#define N_TABS 10
static char tabs[N_TABS+1] = "\t\t\t\t\t\t\t\t\t\t";
+#ifdef BIND9
struct dns_dumpctx {
unsigned int magic;
isc_mem_t *mctx;
@@ -189,6 +190,7 @@ struct dns_dumpctx {
dns_totext_ctx_t *ctx,
isc_buffer_t *buffer, FILE *f);
};
+#endif /* BIND9 */
#define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
@@ -698,6 +700,7 @@ dns_master_questiontotext(dns_name_t *owner_name,
ISC_FALSE, target));
}
+#ifdef BIND9
/*
* Print an rdataset. 'buffer' is a scratch buffer, which must have been
* dynamically allocated by the caller. It must be large enough to
@@ -1775,6 +1778,7 @@ dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
return (result);
}
+#endif /* BIND9 */
isc_result_t
dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags,
diff --git a/lib/dns/name.c b/lib/dns/name.c
index c5c37404..fc7d5be3 100644
--- a/lib/dns/name.c
+++ b/lib/dns/name.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name.c,v 1.167 2009/03/11 23:47:35 tbox Exp $ */
+/* $Id: name.c,v 1.169 2009/09/01 17:36:51 jinmei Exp $ */
/*! \file */
@@ -1019,7 +1019,6 @@ dns_name_toregion(dns_name_t *name, isc_region_t *r) {
DNS_NAME_TOREGION(name, r);
}
-
isc_result_t
dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
dns_name_t *origin, unsigned int options,
@@ -2374,18 +2373,22 @@ dns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
* allocating memory as needed
*/
isc_result_t
-dns_name_fromstring(dns_name_t *target, const char *src, isc_mem_t *mctx) {
+dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
+ isc_mem_t *mctx)
+{
isc_result_t result;
isc_buffer_t buf;
dns_fixedname_t fn;
dns_name_t *name;
+ REQUIRE(src != NULL);
+
isc_buffer_init(&buf, src, strlen(src));
isc_buffer_add(&buf, strlen(src));
dns_fixedname_init(&fn);
name = dns_fixedname_name(&fn);
- result = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &buf, dns_rootname, options, NULL);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
index 41e9e2f5..cb223ae5 100644
--- a/lib/dns/openssl_link.c
+++ b/lib/dns/openssl_link.c
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: openssl_link.c,v 1.25 2009/02/11 03:04:18 jinmei Exp $
+ * $Id: openssl_link.c,v 1.26 2009/09/03 04:09:58 marka Exp $
*/
#ifdef OPENSSL
@@ -223,7 +223,7 @@ dst__openssl_init() {
if (result != ISC_R_SUCCESS)
goto cleanup_rm;
}
-#endif /* USE_PKCS11 */
+#else /* USE_PKCS11 */
if (engine_id != NULL) {
e = ENGINE_by_id(engine_id);
if (e == NULL) {
@@ -237,6 +237,8 @@ dst__openssl_init() {
}
ENGINE_set_default(e, ENGINE_METHOD_ALL);
ENGINE_free(e);
+ if (he == NULL)
+ he = e;
} else {
ENGINE_register_all_complete();
for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
@@ -251,6 +253,7 @@ dst__openssl_init() {
}
}
}
+#endif /* USE_PKCS11 */
re = ENGINE_get_default_RAND();
if (re == NULL) {
re = ENGINE_new();
@@ -292,10 +295,11 @@ dst__openssl_destroy() {
#endif
EVP_cleanup();
#if defined(USE_ENGINE)
- if (e != NULL) {
+ if (he != NULL)
+ ENGINE_finish(he);
+ else if (e != NULL)
ENGINE_finish(e);
- e = NULL;
- }
+ he = e = NULL;
#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
ENGINE_cleanup();
#endif
@@ -345,7 +349,6 @@ dst__openssl_getengine(const char *name) {
UNUSED(name);
-
#if defined(USE_ENGINE)
return (he);
#else
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c
index abc3b7c2..43506d55 100644
--- a/lib/dns/openssldh_link.c
+++ b/lib/dns/openssldh_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: openssldh_link.c,v 1.14 2008/04/01 23:47:10 tbox Exp $
+ * $Id: openssldh_link.c,v 1.16 2009/09/03 23:48:13 tbox Exp $
*/
#ifdef OPENSSL
@@ -476,7 +476,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
+openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
@@ -484,6 +484,7 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
isc_mem_t *mctx;
#define DST_RET(a) {ret = a; goto err;}
+ UNUSED(pub);
mctx = key->mctx;
/* read private key file */
diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c
index 815eff1d..3cad0f90 100644
--- a/lib/dns/openssldsa_link.c
+++ b/lib/dns/openssldsa_link.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: openssldsa_link.c,v 1.15 2009/01/14 23:48:00 tbox Exp $ */
+/* $Id: openssldsa_link.c,v 1.16 2009/09/03 04:09:58 marka Exp $ */
#ifdef OPENSSL
#ifndef USE_EVP
@@ -512,7 +512,7 @@ openssldsa_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
+openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
@@ -520,6 +520,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
isc_mem_t *mctx = key->mctx;
#define DST_RET(a) {ret = a; goto err;}
+ UNUSED(pub);
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c
index 131b4cb5..828ca3bd 100644
--- a/lib/dns/opensslrsa_link.c
+++ b/lib/dns/opensslrsa_link.c
@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: opensslrsa_link.c,v 1.24 2009/07/19 04:18:05 each Exp $
+ * $Id: opensslrsa_link.c,v 1.27 2009/09/07 12:54:59 fdupont Exp $
*/
#ifdef OPENSSL
#ifndef USE_EVP
@@ -767,16 +767,52 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
+rsa_check(RSA *rsa, RSA *pub)
+{
+ /* Public parameters should be the same but if they are not set
+ * copy them from the public key. */
+ if (pub != NULL) {
+ if (rsa->n != NULL) {
+ if (BN_cmp(rsa->n, pub->n) != 0)
+ return (DST_R_INVALIDPRIVATEKEY);
+ } else {
+ rsa->n = pub->n;
+ pub->n = NULL;
+ }
+ if (rsa->e != NULL) {
+ if (BN_cmp(rsa->e, pub->e) != 0)
+ return (DST_R_INVALIDPRIVATEKEY);
+ } else {
+ rsa->e = pub->e;
+ pub->e = NULL;
+ }
+ }
+ if (rsa->n == NULL || rsa->e == NULL)
+ return (DST_R_INVALIDPRIVATEKEY);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
- RSA *rsa = NULL;
+ RSA *rsa = NULL, *pubrsa = NULL;
ENGINE *e = NULL;
isc_mem_t *mctx = key->mctx;
- const char *name = NULL, *label = NULL;
+ const char *engine = NULL, *label = NULL;
EVP_PKEY *pkey = NULL;
+#if USE_EVP
+ if (pub != NULL && pub->keydata.pkey != NULL)
+ pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey);
+#else
+ if (pub != NULL && pub->keydata.rsa != NULL) {
+ pubrsa = pub->keydata.rsa;
+ pub->keydata.rsa = NULL;
+ }
+#endif
+
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
@@ -785,7 +821,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
for (i = 0; i < priv.nelements; i++) {
switch (priv.elements[i].tag) {
case TAG_RSA_ENGINE:
- name = (char *)priv.elements[i].data;
+ engine = (char *)priv.elements[i].data;
break;
case TAG_RSA_LABEL:
label = (char *)priv.elements[i].data;
@@ -798,33 +834,40 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
* Is this key is stored in a HSM?
* See if we can fetch it.
*/
- if (name != NULL || label != NULL) {
- INSIST(name != NULL);
- INSIST(label != NULL);
- e = dst__openssl_getengine(name);
+ if (label != NULL) {
+ if (engine == NULL)
+ DST_RET(DST_R_NOENGINE);
+ e = dst__openssl_getengine(engine);
if (e == NULL)
DST_RET(DST_R_NOENGINE);
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL) {
- ERR_print_errors_fp(stderr);
- DST_RET(ISC_R_FAILURE);
+ /* ERR_print_errors_fp(stderr); */
+ DST_RET(ISC_R_NOTFOUND);
}
- key->engine = isc_mem_strdup(key->mctx, name);
+ key->engine = isc_mem_strdup(key->mctx, engine);
if (key->engine == NULL)
DST_RET(ISC_R_NOMEMORY);
key->label = isc_mem_strdup(key->mctx, label);
if (key->label == NULL)
DST_RET(ISC_R_NOMEMORY);
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ if (rsa == NULL)
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
key->key_size = EVP_PKEY_bits(pkey);
#if USE_EVP
key->keydata.pkey = pkey;
+ RSA_free(rsa);
#else
- key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL)
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ key->keydata.rsa = rsa;
EVP_PKEY_free(pkey);
#endif
dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
return (ISC_R_SUCCESS);
}
@@ -837,9 +880,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
pkey = EVP_PKEY_new();
if (pkey == NULL)
DST_RET(ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
+ if (!EVP_PKEY_set1_RSA(pkey, rsa))
DST_RET(ISC_R_FAILURE);
- }
key->keydata.pkey = pkey;
#else
key->keydata.rsa = rsa;
@@ -889,8 +931,13 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
}
}
dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
key->key_size = BN_num_bits(rsa->n);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
#if USE_EVP
RSA_free(rsa);
#endif
@@ -904,6 +951,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
#endif
if (rsa != NULL)
RSA_free(rsa);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
opensslrsa_destroy(key);
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
@@ -917,33 +966,61 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
ENGINE *e = NULL;
isc_result_t ret;
EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL, *pubrsa = NULL;
+ char *colon;
UNUSED(pin);
e = dst__openssl_getengine(engine);
if (e == NULL)
DST_RET(DST_R_NOENGINE);
+ pkey = ENGINE_load_public_key(e, label, NULL, NULL);
+ if (pkey != NULL) {
+ pubrsa = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (pubrsa == NULL)
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL)
- DST_RET(ISC_R_NOMEMORY);
- key->engine = isc_mem_strdup(key->mctx, label);
- if (key->engine == NULL)
- DST_RET(ISC_R_NOMEMORY);
+ DST_RET(ISC_R_NOTFOUND);
+ if (engine != NULL) {
+ key->engine = isc_mem_strdup(key->mctx, engine);
+ if (key->engine == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ } else {
+ key->engine = isc_mem_strdup(key->mctx, label);
+ if (key->engine == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ colon = strchr(key->engine, ':');
+ if (colon != NULL)
+ *colon = '\0';
+ }
key->label = isc_mem_strdup(key->mctx, label);
if (key->label == NULL)
DST_RET(ISC_R_NOMEMORY);
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ if (rsa == NULL)
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
key->key_size = EVP_PKEY_bits(pkey);
#if USE_EVP
key->keydata.pkey = pkey;
+ RSA_free(rsa);
#else
- key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
+ key->keydata.rsa = rsa;
EVP_PKEY_free(pkey);
- if (key->keydata.rsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#endif
return (ISC_R_SUCCESS);
err:
+ if (rsa != NULL)
+ RSA_free(rsa);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
if (pkey != NULL)
EVP_PKEY_free(pkey);
return (ret);
diff --git a/lib/dns/peer.c b/lib/dns/peer.c
index 12474cb8..c55d73dd 100644
--- a/lib/dns/peer.c
+++ b/lib/dns/peer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: peer.c,v 1.31 2008/04/03 06:09:04 tbox Exp $ */
+/* $Id: peer.c,v 1.33 2009/09/02 23:48:02 tbox Exp $ */
/*! \file */
@@ -536,7 +536,7 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
isc_buffer_init(&b, keyval, strlen(keyval));
isc_buffer_add(&b, strlen(keyval));
result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index bcd01a1e..0bbf3d9c 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.277 2009/07/13 07:02:46 marka Exp $ */
+/* $Id: rbtdb.c,v 1.278 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -625,8 +625,10 @@ typedef struct rbtdb_dbiterator {
static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log,
isc_event_t *event);
static void overmem(dns_db_t *db, isc_boolean_t overmem);
+#ifdef BIND9
static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
isc_boolean_t *nsec3createflag);
+#endif
/*%
* 'init_count' is used to initialize 'newheader->count' which inturn
@@ -1925,6 +1927,13 @@ cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) {
static void
iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) {
+#ifndef BIND9
+ UNUSED(db);
+ UNUSED(version);
+ UNUSED(origin);
+
+ return;
+#else
dns_rdataset_t keyset;
dns_rdataset_t nsecset, signsecset;
dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -1988,12 +1997,14 @@ iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) {
version->secure = dns_db_partial;
else
version->secure = dns_db_insecure;
+#endif
}
/*%<
* Walk the origin node looking for NSEC3PARAM records.
* Cache the nsec3 parameters.
*/
+#ifdef BIND9
static void
setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
isc_boolean_t *nsec3createflag)
@@ -2098,6 +2109,7 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
isc_rwlocktype_read);
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
}
+#endif
static void
closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
@@ -6505,9 +6517,17 @@ dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
REQUIRE(VALID_RBTDB(rbtdb));
+#ifdef BIND9
return (dns_master_dump2(rbtdb->common.mctx, db, version,
&dns_master_style_default,
filename, masterformat));
+#else
+ UNUSED(version);
+ UNUSED(filename);
+ UNUSED(masterformat);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#endif /* BIND9 */
}
static void
@@ -8089,6 +8109,21 @@ rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
dns_name_t *fname, dns_message_t *msg,
isc_stdtime_t now)
{
+#ifndef BIND9
+ UNUSED(rdataset);
+ UNUSED(type);
+ UNUSED(qtype);
+ UNUSED(acache);
+ UNUSED(zonep);
+ UNUSED(dbp);
+ UNUSED(versionp);
+ UNUSED(nodep);
+ UNUSED(fname);
+ UNUSED(msg);
+ UNUSED(now);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#else
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
@@ -8205,8 +8240,10 @@ acache_callback(dns_acacheentry_t *entry, void **arg) {
dns_db_detach((dns_db_t **)(void*)&rbtdb);
*arg = NULL;
+#endif /* BIND9 */
}
+#ifdef BIND9
static void
acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry,
acache_cbarg_t **cbargp)
@@ -8227,6 +8264,7 @@ acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry,
*cbargp = NULL;
}
+#endif /* BIND9 */
static isc_result_t
rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
@@ -8235,6 +8273,19 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
dns_dbversion_t *version, dns_dbnode_t *node,
dns_name_t *fname)
{
+#ifndef BIND9
+ UNUSED(rdataset);
+ UNUSED(type);
+ UNUSED(qtype);
+ UNUSED(acache);
+ UNUSED(zone);
+ UNUSED(db);
+ UNUSED(version);
+ UNUSED(node);
+ UNUSED(fname);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#else
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
@@ -8358,12 +8409,21 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
}
return (result);
+#endif
}
static isc_result_t
rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
dns_rdatasetadditional_t type, dns_rdatatype_t qtype)
{
+#ifndef BIND9
+ UNUSED(acache);
+ UNUSED(rdataset);
+ UNUSED(type);
+ UNUSED(qtype);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#else
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
@@ -8428,6 +8488,7 @@ rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
}
return (ISC_R_SUCCESS);
+#endif
}
/*%
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c
index 032c3d8c..5e4e471a 100644
--- a/lib/dns/rdata.c
+++ b/lib/dns/rdata.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.c,v 1.200 2008/12/12 04:37:23 marka Exp $ */
+/* $Id: rdata.c,v 1.202 2009/09/02 23:48:02 tbox Exp $ */
/*! \file */
@@ -38,6 +38,7 @@
#include <dns/enumtype.h>
#include <dns/keyflags.h>
#include <dns/keyvalues.h>
+#include <dns/message.h>
#include <dns/rcode.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
@@ -1767,3 +1768,93 @@ dns_rdatatype_isknown(dns_rdatatype_t type) {
return (ISC_TRUE);
return (ISC_FALSE);
}
+
+void
+dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ rdata->data = NULL;
+ rdata->length = 0;
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = type;
+ rdata->rdclass = dns_rdataclass_any;
+}
+
+void
+dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ rdata->data = NULL;
+ rdata->length = 0;
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = type;
+ rdata->rdclass = dns_rdataclass_none;
+}
+
+void
+dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ rdata->data = NULL;
+ rdata->length = 0;
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = type;
+ rdata->rdclass = dns_rdataclass_any;
+}
+
+void
+dns_rdata_makedelete(dns_rdata_t *rdata) {
+ REQUIRE(rdata != NULL);
+
+ rdata->rdclass = dns_rdataclass_none;
+}
+
+const char *
+dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ switch (section) {
+ case DNS_SECTION_PREREQUISITE:
+ switch (rdata->rdclass) {
+ case dns_rdataclass_none:
+ switch (rdata->type) {
+ case dns_rdatatype_any:
+ return ("domain doesn't exist");
+ default:
+ return ("rrset doesn't exist");
+ }
+ case dns_rdataclass_any:
+ switch (rdata->type) {
+ case dns_rdatatype_any:
+ return ("domain exists");
+ default:
+ return ("rrset exists (value independent)");
+ }
+ default:
+ return ("rrset exists (value dependent)");
+ }
+ case DNS_SECTION_UPDATE:
+ switch (rdata->rdclass) {
+ case dns_rdataclass_none:
+ return ("delete");
+ case dns_rdataclass_any:
+ switch (rdata->type) {
+ case dns_rdatatype_any:
+ return ("delete all rrsets");
+ default:
+ return ("delete rrset");
+ }
+ default:
+ return ("add");
+ }
+ }
+ return ("invalid");
+}
diff --git a/lib/dns/rdata/generic/hip_55.c b/lib/dns/rdata/generic/hip_55.c
index c5e0687e..10106620 100644
--- a/lib/dns/rdata/generic/hip_55.c
+++ b/lib/dns/rdata/generic/hip_55.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hip_55.c,v 1.3 2009/02/26 11:18:56 tbox Exp $ */
+/* $Id: hip_55.c,v 1.4 2009/09/02 23:43:54 each Exp $ */
/* reviewed: TBC */
@@ -215,7 +215,7 @@ fromwire_hip(ARGS_FROMWIRE) {
if (key_len == 0)
RETERR(DNS_R_FORMERR);
isc_region_consume(&region, 2);
- if (region.length < hit_len + key_len)
+ if (region.length < (unsigned) (hit_len + key_len))
RETERR(DNS_R_FORMERR);
RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len));
diff --git a/lib/dns/request.c b/lib/dns/request.c
index d0637ad6..ba19154b 100644
--- a/lib/dns/request.c
+++ b/lib/dns/request.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: request.c,v 1.84 2009/01/17 23:47:43 tbox Exp $ */
+/* $Id: request.c,v 1.85 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -449,7 +449,8 @@ req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
}
static isc_result_t
-new_request(isc_mem_t *mctx, dns_request_t **requestp) {
+new_request(isc_mem_t *mctx, dns_request_t **requestp)
+{
dns_request_t *request;
request = isc_mem_get(mctx, sizeof(*request));
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 888b1595..4cfc737e 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.403 2009/07/13 06:24:27 marka Exp $ */
+/* $Id: resolver.c,v 1.405 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -1013,6 +1013,7 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
ISC_LIST_UNLINK(fctx->events, event, ev_link);
task = event->ev_sender;
event->ev_sender = fctx;
+ event->vresult = fctx->vresult;
if (!HAVE_ANSWER(fctx))
event->result = result;
@@ -2530,6 +2531,16 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
}
}
+static isc_boolean_t
+isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) {
+ int order;
+ unsigned int nlabels;
+ dns_namereln_t namereln;
+
+ namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
+ return (ISC_TF(namereln == dns_namereln_subdomain));
+}
+
static isc_result_t
fctx_getaddresses(fetchctx_t *fctx) {
dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -2575,6 +2586,8 @@ fctx_getaddresses(fetchctx_t *fctx) {
dns_name_t *name = &fctx->name;
dns_name_t suffix;
unsigned int labels;
+ dns_fixedname_t fixed;
+ dns_name_t *domain;
/*
* DS records are found in the parent server.
@@ -2587,11 +2600,26 @@ fctx_getaddresses(fetchctx_t *fctx) {
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
name = &suffix;
}
- result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
- &forwarders);
+
+ dns_fixedname_init(&fixed);
+ domain = dns_fixedname_name(&fixed);
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ domain, &forwarders);
if (result == ISC_R_SUCCESS) {
sa = ISC_LIST_HEAD(forwarders->addrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
+ if (fctx->fwdpolicy == dns_fwdpolicy_only &&
+ isstrictsubdomain(domain, &fctx->domain)) {
+ isc_mem_t *mctx;
+
+ mctx = res->buckets[fctx->bucketnum].mctx;
+ dns_name_free(&fctx->domain, mctx);
+ dns_name_init(&fctx->domain, NULL);
+ result = dns_name_dup(domain, mctx,
+ &fctx->domain);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
}
}
@@ -3862,6 +3890,7 @@ validated(isc_task_t *task, isc_event_t *event) {
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
vevent = (dns_validatorevent_t *)event;
+ fctx->vresult = vevent->result;
FCTXTRACE("received validation completion event");
@@ -7124,6 +7153,7 @@ dns_resolver_create(dns_view_t *view,
return (result);
}
+#ifdef BIND9
static void
prime_done(isc_task_t *task, isc_event_t *event) {
dns_resolver_t *res;
@@ -7229,6 +7259,7 @@ dns_resolver_prime(dns_resolver_t *res) {
}
}
}
+#endif /* BIND9 */
void
dns_resolver_freeze(dns_resolver_t *res) {
diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c
index 6dc02f35..34c3455d 100644
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.69 2009/06/26 06:21:02 marka Exp $ */
+/* $Id: sdb.c,v 1.70 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -450,7 +450,7 @@ getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) {
isc_buffer_init(&b, name, strlen(name));
isc_buffer_add(&b, strlen(name));
- result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL);
+ result = dns_name_fromtext(newname, &b, origin, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 176470d8..2138e38e 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.c,v 1.21 2009/06/26 06:21:03 marka Exp $ */
+/* $Id: sdlz.c,v 1.22 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -1620,7 +1620,7 @@ dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
isc_buffer_init(&b, name, strlen(name));
isc_buffer_add(&b, strlen(name));
- result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL);
+ result = dns_name_fromtext(newname, &b, origin, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/lib/dns/soa.c b/lib/dns/soa.c
index a68d0aa9..1b58bfec 100644
--- a/lib/dns/soa.c
+++ b/lib/dns/soa.c
@@ -15,11 +15,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: soa.c,v 1.10 2009/07/01 23:47:36 tbox Exp $ */
+/* $Id: soa.c,v 1.12 2009/09/10 02:18:40 each Exp $ */
/*! \file */
#include <config.h>
+#include <string.h>
#include <isc/buffer.h>
#include <isc/util.h>
@@ -67,14 +68,17 @@ dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact,
dns_rdataclass_t rdclass,
isc_uint32_t serial, isc_uint32_t refresh,
isc_uint32_t retry, isc_uint32_t expire,
- isc_uint32_t minimum, dns_rdata_t *rdata) {
+ isc_uint32_t minimum, unsigned char *buffer,
+ dns_rdata_t *rdata) {
dns_rdata_soa_t soa;
- char soadata[DNS_NAME_FORMATSIZE];
isc_buffer_t rdatabuf;
REQUIRE(origin != NULL);
REQUIRE(contact != NULL);
+ memset(buffer, 0, DNS_SOA_BUFFERSIZE);
+ isc_buffer_init(&rdatabuf, buffer, DNS_SOA_BUFFERSIZE);
+
soa.common.rdtype = dns_rdatatype_soa;
soa.common.rdclass = rdclass;
soa.mctx = NULL;
@@ -88,7 +92,6 @@ dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact,
dns_name_init(&soa.contact, NULL);
dns_name_clone(contact, &soa.contact);
- isc_buffer_init(&rdatabuf, soadata, sizeof(soadata));
return (dns_rdata_fromstruct(rdata, rdclass, dns_rdatatype_soa,
&soa, &rdatabuf));
}
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
index 9e59dfaf..02f93deb 100644
--- a/lib/dns/tkey.c
+++ b/lib/dns/tkey.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $Id: tkey.c,v 1.90 2008/04/03 00:45:23 marka Exp $
+ * $Id: tkey.c,v 1.92 2009/09/02 23:48:02 tbox Exp $
*/
/*! \file */
#include <config.h>
@@ -724,8 +724,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
}
isc_buffer_init(&b, randomtext, sizeof(randomtext));
isc_buffer_add(&b, sizeof(randomtext));
- result = dns_name_fromtext(keyname, &b, NULL,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &b, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
goto failure;
}
diff --git a/lib/dns/tsec.c b/lib/dns/tsec.c
new file mode 100644
index 00000000..c90d4ee2
--- /dev/null
+++ b/lib/dns/tsec.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: tsec.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/mem.h>
+
+#include <dns/tsec.h>
+#include <dns/tsig.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#define DNS_TSEC_MAGIC ISC_MAGIC('T', 's', 'e', 'c')
+#define DNS_TSEC_VALID(t) ISC_MAGIC_VALID(t, DNS_TSEC_MAGIC)
+
+/*%
+ * DNS Transaction Security object. We assume this is not shared by
+ * multiple threads, and so the structure does not contain a lock.
+ */
+struct dns_tsec {
+ unsigned int magic;
+ dns_tsectype_t type;
+ isc_mem_t *mctx;
+ union {
+ dns_tsigkey_t *tsigkey;
+ dst_key_t *key;
+ } ukey;
+};
+
+isc_result_t
+dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key,
+ dns_tsec_t **tsecp)
+{
+ isc_result_t result;
+ dns_tsec_t *tsec;
+ dns_tsigkey_t *tsigkey = NULL;
+ dns_name_t *algname;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(tsecp != NULL && *tsecp == NULL);
+
+ tsec = isc_mem_get(mctx, sizeof(*tsec));
+ if (tsec == NULL)
+ return (ISC_R_NOMEMORY);
+
+ tsec->type = type;
+ tsec->mctx = mctx;
+
+ switch (type) {
+ case dns_tsectype_tsig:
+ switch (dst_key_alg(key)) {
+ case DST_ALG_HMACMD5:
+ algname = dns_tsig_hmacmd5_name;
+ break;
+ case DST_ALG_HMACSHA1:
+ algname = dns_tsig_hmacsha1_name;
+ break;
+ case DST_ALG_HMACSHA224:
+ algname = dns_tsig_hmacsha224_name;
+ break;
+ case DST_ALG_HMACSHA256:
+ algname = dns_tsig_hmacsha256_name;
+ break;
+ case DST_ALG_HMACSHA384:
+ algname = dns_tsig_hmacsha384_name;
+ break;
+ case DST_ALG_HMACSHA512:
+ algname = dns_tsig_hmacsha512_name;
+ break;
+ default:
+ isc_mem_put(mctx, tsec, sizeof(*tsec));
+ return (DNS_R_BADALG);
+ }
+ result = dns_tsigkey_createfromkey(dst_key_name(key),
+ algname, key, ISC_FALSE,
+ NULL, 0, 0, mctx, NULL,
+ &tsigkey);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, tsec, sizeof(*tsec));
+ return (result);
+ }
+ tsec->ukey.tsigkey = tsigkey;
+ break;
+ case dns_tsectype_sig0:
+ tsec->ukey.key = key;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ tsec->magic = DNS_TSEC_MAGIC;
+
+ *tsecp = tsec;
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_tsec_destroy(dns_tsec_t **tsecp) {
+ dns_tsec_t *tsec;
+
+ REQUIRE(tsecp != NULL && *tsecp != NULL);
+ tsec = *tsecp;
+ REQUIRE(DNS_TSEC_VALID(tsec));
+
+ switch (tsec->type) {
+ case dns_tsectype_tsig:
+ dns_tsigkey_detach(&tsec->ukey.tsigkey);
+ break;
+ case dns_tsectype_sig0:
+ dst_key_free(&tsec->ukey.key);
+ break;
+ default:
+ INSIST(0);
+ }
+
+ tsec->magic = 0;
+ isc_mem_put(tsec->mctx, tsec, sizeof(*tsec));
+
+ *tsecp = NULL;
+}
+
+dns_tsectype_t
+dns_tsec_gettype(dns_tsec_t *tsec) {
+ REQUIRE(DNS_TSEC_VALID(tsec));
+
+ return (tsec->type);
+}
+
+void
+dns_tsec_getkey(dns_tsec_t *tsec, void *keyp) {
+ REQUIRE(DNS_TSEC_VALID(tsec));
+ REQUIRE(keyp != NULL);
+
+ switch (tsec->type) {
+ case dns_tsectype_tsig:
+ dns_tsigkey_attach(tsec->ukey.tsigkey, (dns_tsigkey_t **)keyp);
+ break;
+ case dns_tsectype_sig0:
+ *(dst_key_t **)keyp = tsec->ukey.key;
+ break;
+ default:
+ INSIST(0);
+ }
+}
diff --git a/lib/dns/view.c b/lib/dns/view.c
index 57dc6174..0c477c36 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.155 2009/06/30 02:52:32 each Exp $ */
+/* $Id: view.c,v 1.156 2009/09/01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -86,6 +86,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
if (result != ISC_R_SUCCESS)
goto cleanup_name;
+#ifdef BIND9
view->zonetable = NULL;
result = dns_zt_create(mctx, rdclass, &view->zonetable);
if (result != ISC_R_SUCCESS) {
@@ -95,6 +96,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
result = ISC_R_UNEXPECTED;
goto cleanup_mutex;
}
+#endif
view->secroots = NULL;
view->fwdtable = NULL;
result = dns_fwdtable_create(mctx, &view->fwdtable);
@@ -177,9 +179,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->maxudp = 0;
dns_fixedname_init(&view->dlv_fixed);
+#ifdef BIND9
result = dns_order_create(view->mctx, &view->order);
if (result != ISC_R_SUCCESS)
goto cleanup_dynkeys;
+#endif
result = dns_peerlist_new(view->mctx, &view->peers);
if (result != ISC_R_SUCCESS)
@@ -209,9 +213,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
dns_peerlist_detach(&view->peers);
cleanup_order:
+#ifdef BIND9
dns_order_detach(&view->order);
cleanup_dynkeys:
+#endif
dns_tsigkeyring_destroy(&view->dynamickeys);
cleanup_references:
@@ -221,9 +227,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
dns_fwdtable_destroy(&view->fwdtable);
cleanup_zt:
+#ifdef BIND9
dns_zt_detach(&view->zonetable);
cleanup_mutex:
+#endif
DESTROYLOCK(&view->lock);
cleanup_name:
@@ -244,8 +252,10 @@ destroy(dns_view_t *view) {
REQUIRE(ADBSHUTDOWN(view));
REQUIRE(REQSHUTDOWN(view));
+#ifdef BIND9
if (view->order != NULL)
dns_order_detach(&view->order);
+#endif
if (view->peers != NULL)
dns_peerlist_detach(&view->peers);
if (view->dynamickeys != NULL)
@@ -256,11 +266,13 @@ destroy(dns_view_t *view) {
dns_adb_detach(&view->adb);
if (view->resolver != NULL)
dns_resolver_detach(&view->resolver);
+#ifdef BIND9
if (view->acache != NULL) {
if (view->cachedb != NULL)
dns_acache_putdb(view->acache, view->cachedb);
dns_acache_detach(&view->acache);
}
+#endif
if (view->requestmgr != NULL)
dns_requestmgr_detach(&view->requestmgr);
if (view->task != NULL)
@@ -399,12 +411,14 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
dns_adb_shutdown(view->adb);
if (!REQSHUTDOWN(view))
dns_requestmgr_shutdown(view->requestmgr);
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_shutdown(view->acache);
if (view->flush)
dns_zt_flushanddetach(&view->zonetable);
else
dns_zt_detach(&view->zonetable);
+#endif
done = all_done(view);
UNLOCK(&view->lock);
}
@@ -425,6 +439,7 @@ dns_view_detach(dns_view_t **viewp) {
view_flushanddetach(viewp, ISC_FALSE);
}
+#ifdef BIND9
static isc_result_t
dialup(dns_zone_t *zone, void *dummy) {
UNUSED(dummy);
@@ -437,6 +452,7 @@ dns_view_dialup(dns_view_t *view) {
REQUIRE(DNS_VIEW_VALID(view));
(void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
}
+#endif
void
dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
@@ -628,8 +644,10 @@ dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
view->cacheshared = shared;
if (view->cache != NULL) {
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_putdb(view->acache, view->cachedb);
+#endif
dns_db_detach(&view->cachedb);
dns_cache_detach(&view->cache);
}
@@ -637,8 +655,10 @@ dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
dns_cache_attachdb(cache, &view->cachedb);
INSIST(DNS_DB_VALID(view->cachedb));
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
+#endif
}
isc_boolean_t
@@ -673,6 +693,7 @@ dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
view->dstport = dstport;
}
+#ifdef BIND9
isc_result_t
dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
isc_result_t result;
@@ -684,6 +705,7 @@ dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
return (result);
}
+#endif
void
dns_view_freeze(dns_view_t *view) {
@@ -697,6 +719,7 @@ dns_view_freeze(dns_view_t *view) {
view->frozen = ISC_TRUE;
}
+#ifdef BIND9
isc_result_t
dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
isc_result_t result;
@@ -711,6 +734,7 @@ dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
return (result);
}
+#endif
isc_result_t
dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
@@ -725,6 +749,10 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
dns_rdataset_t zrdataset, zsigrdataset;
dns_zone_t *zone;
+#ifndef BIND9
+ UNUSED(use_hints);
+#endif
+
/*
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
@@ -750,6 +778,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
zone = NULL;
db = NULL;
node = NULL;
+#ifdef BIND9
result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
result = dns_zone_getdb(zone, &db);
@@ -759,6 +788,11 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
goto cleanup;
} else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
dns_db_attach(view->cachedb, &db);
+#else
+ result = ISC_R_NOTFOUND;
+ if (view->cachedb != NULL)
+ dns_db_attach(view->cachedb, &db);
+#endif /* BIND9 */
else
goto cleanup;
@@ -841,6 +875,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
result = ISC_R_SUCCESS;
}
+#ifdef BIND9
if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
@@ -875,6 +910,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
if (db == NULL && node != NULL)
dns_db_detachnode(view->hints, &node);
}
+#endif /* BIND9 */
cleanup:
if (dns_rdataset_isassociated(&zrdataset)) {
@@ -903,8 +939,10 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
} else
INSIST(node == NULL);
+#ifdef BIND9
if (zone != NULL)
dns_zone_detach(&zone);
+#endif
return (result);
}
@@ -997,9 +1035,13 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
/*
* Find the right database.
*/
+#ifdef BIND9
result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
result = dns_zone_getdb(zone, &db);
+#else
+ result = ISC_R_NOTFOUND;
+#endif
if (result == ISC_R_NOTFOUND) {
/*
* We're not directly authoritative for this query name, nor
@@ -1131,8 +1173,10 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
}
if (db != NULL)
dns_db_detach(&db);
+#ifdef BIND9
if (zone != NULL)
dns_zone_detach(&zone);
+#endif
return (result);
}
@@ -1159,6 +1203,7 @@ dns_viewlist_find(dns_viewlist_t *list, const char *name,
return (ISC_R_SUCCESS);
}
+#ifdef BIND9
isc_result_t
dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
isc_boolean_t allclasses, dns_rdataclass_t rdclass,
@@ -1223,6 +1268,7 @@ dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
return (dns_zt_loadnew(view->zonetable, stop));
}
+#endif /* BIND9 */
isc_result_t
dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
@@ -1266,6 +1312,7 @@ dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
view->dynamickeys));
}
+#ifdef BIND9
isc_result_t
dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
isc_result_t result;
@@ -1280,6 +1327,7 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
dns_adb_dump(view->adb, fp);
return (ISC_R_SUCCESS);
}
+#endif
isc_result_t
dns_view_flushcache(dns_view_t *view) {
@@ -1299,12 +1347,16 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
if (result != ISC_R_SUCCESS)
return (result);
}
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_putdb(view->acache, view->cachedb);
+#endif
dns_db_detach(&view->cachedb);
dns_cache_attachdb(view->cache, &view->cachedb);
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
+#endif
dns_adb_flush(view->adb);
return (ISC_R_SUCCESS);
@@ -1436,11 +1488,13 @@ dns_view_getrootdelonly(dns_view_t *view) {
return (view->rootdelonly);
}
+#ifdef BIND9
isc_result_t
dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
REQUIRE(DNS_VIEW_VALID(view));
return (dns_zt_freezezones(view->zonetable, value));
}
+#endif
void
dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def
index 4ed7c413..f934ad7d 100644
--- a/lib/dns/win32/libdns.def
+++ b/lib/dns/win32/libdns.def
@@ -866,6 +866,7 @@ dst_key_fromgssapi
dst_key_fromlabel
dst_key_fromnamedfile
dst_key_generate
+dst_key_getprivateformat
dst_key_gettime
dst_key_id
dst_key_isnullkey
@@ -877,12 +878,14 @@ dst_key_proto
dst_key_secretsize
dst_key_setbits
dst_key_setflags
+dst_key_setprivateformat
dst_key_settime
dst_key_sigsize
dst_key_size
dst_key_tobuffer
dst_key_todns
dst_key_tofile
+dst_key_unsettime
dst_lib_destroy
dst_lib_init
dst_lib_initmsgcat
diff --git a/lib/dns/win32/libdns.dsp b/lib/dns/win32/libdns.dsp
index 34ebc72f..4b6d54c0 100644
--- a/lib/dns/win32/libdns.dsp
+++ b/lib/dns/win32/libdns.dsp
@@ -42,8 +42,8 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libdns_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/openssl/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /YX /FD /c
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "BIND9" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libdns_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/openssl/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "NDEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /YX /FD /c
# SUBTRACT CPP /X
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@@ -69,8 +69,8 @@ LINK32=link.exe
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libdns_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /FR /YX /FD /GZ /c
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libdns_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "_DEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
diff --git a/lib/dns/win32/libdns.mak b/lib/dns/win32/libdns.mak
index e89759c0..deb67634 100644
--- a/lib/dns/win32/libdns.mak
+++ b/lib/dns/win32/libdns.mak
@@ -207,7 +207,7 @@ CLEAN :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/openssl/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../../lib/isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/openssl/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../../lib/isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "NDEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
@@ -534,7 +534,7 @@ CLEAN :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../../lib/isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../../lib/isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "_DEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
@@ -964,7 +964,7 @@ SOURCE=..\dispatch.c
!IF "$(CFG)" == "libdns - Win32 Release"
-CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/openssl/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/openssl/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "NDEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
"$(INTDIR)\dispatch.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) @<<
@@ -974,7 +974,7 @@ CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /I "../../../../../openssl-0.9.8k/inc32/ope
!ELSEIF "$(CFG)" == "libdns - Win32 Debug"
-CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../isc/noatomic/include" /I "../../../../openssl-0.9.8k/inc32" /I "../../../../libxml2-2.7.3/include" /D "_DEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" /D "OPENSSL" /D "DST_USE_PRIVATE_OPENSSL" /D "LIBDNS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libdns.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
"$(INTDIR)\dispatch.obj" "$(INTDIR)\dispatch.sbr" : $(SOURCE) "$(INTDIR)"
$(CPP) @<<
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 6ece61e8..f1bd6be7 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.501 2009/07/17 23:47:40 tbox Exp $ */
+/* $Id: zone.c,v 1.505 2009/09/10 01:47:08 each Exp $ */
/*! \file */
@@ -2532,15 +2532,16 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
dns_rdatatype_dnskey, &r);
/* DSTKEY to KEYDATA. */
- dns_rdata_tostruct(&rdata, &dnskey, NULL);
- dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0, NULL);
+ CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
+ CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
+ NULL));
/* KEYDATA to rdata. */
dns_rdata_reset(&rdata);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
- dns_rdata_fromstruct(&rdata,
- zone->rdclass, dns_rdatatype_keydata,
- &keydata, &keyb);
+ CHECK(dns_rdata_fromstruct(&rdata,
+ zone->rdclass, dns_rdatatype_keydata,
+ &keydata, &keyb));
/* Add rdata to zone. */
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
@@ -2891,6 +2892,49 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
}
/*
+ * Create an SOA record for a newly-created zone
+ */
+static isc_result_t
+add_soa(dns_zone_t *zone, dns_db_t *db) {
+ isc_result_t result;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ unsigned char buf[DNS_SOA_BUFFERSIZE];
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+
+ dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
+
+ dns_diff_init(zone->mctx, &diff);
+ result = dns_db_newversion(db, &ver);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "add_soa:dns_db_newversion -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
+ /* Build SOA record */
+ result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
+ 0, 0, 0, 0, 0, buf, &rdata);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "add_soa:dns_soa_buildrdata -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
+ result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
+ &zone->origin, 0, &rdata);
+
+failure:
+ dns_diff_clear(&diff);
+ if (ver != NULL)
+ dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
+
+ return (result);
+}
+
+/*
* Synchronize the set of initializing keys found in managed-keys {}
* statements with the set of trust anchors found in the managed-keys.bind
* zone. If a domain is no longer named in managed-keys, delete all keys
@@ -2899,7 +2943,7 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
* the key zone with the initializing key(s) for that domain.
*/
static isc_result_t
-sync_keyzone(dns_zone_t *zone, dns_db_t *db, isc_boolean_t addsoa) {
+sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
isc_result_t result = ISC_R_SUCCESS;
isc_boolean_t changed = ISC_FALSE;
dns_rbtnodechain_t chain;
@@ -2919,6 +2963,7 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db, isc_boolean_t addsoa) {
origin = dns_fixedname_name(&fn);
dns_diff_init(zone->mctx, &diff);
+
result = dns_db_newversion(db, &ver);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -2927,68 +2972,46 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db, isc_boolean_t addsoa) {
goto failure;
}
- if (addsoa) {
- /* If this zone is being newly created, make an SOA record. */
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating key zone");
+ /*
+ * Walk the zone DB. If we find any keys whose names are no longer
+ * in managed-keys (or *are* in trusted-keys, meaning they are
+ * permanent and not RFC5011-maintained), delete them from the
+ * zone. Otherwise call load_secroots(), which loads keys into
+ * secroots as appropriate.
+ */
+ dns_rriterator_init(&rrit, db, ver, 0);
+ for (result = dns_rriterator_first(&rrit);
+ result == ISC_R_SUCCESS;
+ result = dns_rriterator_nextrrset(&rrit)) {
+ dns_rdataset_t *rdataset;
+ dns_name_t *rrname = NULL;
+ isc_uint32_t ttl;
- result = dns_soa_buildrdata(&zone->origin, dns_rootname,
- zone->rdclass,
- 0, 0, 0, 0, 0, &rdata);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "sync_keyzone:dns_soa_buildrdata -> %s\n",
- dns_result_totext(result));
+ dns_rriterator_current(&rrit, &rrname, &ttl,
+ &rdataset, NULL);
+ if (!dns_rdataset_isassociated(rdataset)) {
+ dns_rriterator_destroy(&rrit);
goto failure;
}
- CHECK(update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
- &zone->origin, 0, &rdata));
- } else {
- /*
- * Zone is not new, so walk the zone DB; if we find any keys
- * whose names are no longer in managed-keys (or *are*
- * in trusted-keys, meaning they are permanent and not
- * RFC5011-maintained), delete them from the zone. Otherwise
- * call load_secroots(), which loads keys into secroots as
- * appropriate.
- */
- dns_rriterator_init(&rrit, db, ver, 0);
- for (result = dns_rriterator_first(&rrit);
- result == ISC_R_SUCCESS;
- result = dns_rriterator_nextrrset(&rrit)) {
- dns_rdataset_t *rdataset;
- dns_name_t *rrname = NULL;
- isc_uint32_t ttl;
-
- dns_rriterator_current(&rrit, &rrname, &ttl,
- &rdataset, NULL);
- if (!dns_rdataset_isassociated(rdataset)) {
- dns_rriterator_destroy(&rrit);
- goto failure;
- }
-
- if (rdataset->type != dns_rdatatype_keydata)
- continue;
-
- result = dns_keytable_find(sr, rrname, &keynode);
+ if (rdataset->type != dns_rdatatype_keydata)
+ continue;
- if ((result != ISC_R_SUCCESS &&
- result != DNS_R_PARTIALMATCH) ||
- dns_keynode_managed(keynode) == ISC_FALSE) {
- CHECK(delete_keydata(db, ver, &diff,
- rrname, rdataset));
- } else {
- load_secroots(zone, rrname, rdataset);
- }
+ result = dns_keytable_find(sr, rrname, &keynode);
- if (keynode != NULL)
- dns_keytable_detachkeynode(sr, &keynode);
+ if ((result != ISC_R_SUCCESS &&
+ result != DNS_R_PARTIALMATCH) ||
+ dns_keynode_managed(keynode) == ISC_FALSE) {
+ CHECK(delete_keydata(db, ver, &diff,
+ rrname, rdataset));
+ } else {
+ load_secroots(zone, rrname, rdataset);
}
- dns_rriterator_destroy(&rrit);
+ if (keynode != NULL)
+ dns_keytable_detachkeynode(sr, &keynode);
}
+ dns_rriterator_destroy(&rrit);
/*
* Now walk secroots to find any managed keys that aren't
@@ -3035,6 +3058,9 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db, isc_boolean_t addsoa) {
}
RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+
if (changed) {
/* Write changes to journal file. */
result = increment_soa_serial(db, ver, &diff, zone->mctx);
@@ -3064,6 +3090,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
isc_time_t now;
isc_boolean_t needdump = ISC_FALSE;
isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
+ isc_boolean_t nomaster = ISC_FALSE;
unsigned int options;
TIME_NOW(&now);
@@ -3090,6 +3117,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
"loading from master file %s failed: %s",
zone->masterfile,
dns_result_totext(result));
+ nomaster = ISC_TRUE;
}
if (zone->type != dns_zone_key)
@@ -3105,6 +3133,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
else
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
+ /*
+ * If there's no master file for a key zone, then the zone is new:
+ * create an SOA record. (We do this now, instead of later, so that
+ * if there happens to be a journal file, we can roll forward from
+ * a sane starting point.)
+ */
+ if (nomaster && zone->type == dns_zone_key) {
+ result = add_soa(zone, db);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
/*
* Apply update log, if any, on initial load.
*/
@@ -3271,7 +3311,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
break;
case dns_zone_key:
- result = sync_keyzone(zone, db, ISC_TF(soacount == 0));
+ zone->serial = serial;
+ result = sync_keyzone(zone, db);
if (result != ISC_R_SUCCESS)
goto cleanup;
break;
@@ -3316,8 +3357,12 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
result = ISC_R_SUCCESS;
- if (needdump)
- zone_needdump(zone, DNS_DUMP_DELAY);
+ if (needdump) {
+ if (zone->type == dns_zone_key)
+ zone_needdump(zone, 30);
+ else
+ zone_needdump(zone, DNS_DUMP_DELAY);
+ }
if (zone->task != NULL) {
if (zone->type == dns_zone_master) {
@@ -3568,15 +3613,14 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
isc_uint32_t *expire, isc_uint32_t *minimum,
unsigned int *errors)
{
- dns_dbversion_t *version;
isc_result_t result;
isc_result_t answer = ISC_R_SUCCESS;
+ dns_dbversion_t *version = NULL;
dns_dbnode_t *node;
REQUIRE(db != NULL);
REQUIRE(zone != NULL);
- version = NULL;
dns_db_currentversion(db, &version);
node = NULL;
@@ -6000,6 +6044,7 @@ zone_sign(dns_zone_t *zone) {
dst_key_t *zone_keys[MAXZONEKEYS];
isc_int32_t signatures;
isc_boolean_t check_ksk, is_ksk;
+ isc_boolean_t commit = ISC_FALSE;
isc_boolean_t delegation;
isc_boolean_t finishedakey = ISC_FALSE;
isc_boolean_t secureupdated = ISC_FALSE;
@@ -6288,6 +6333,7 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
+
if (finishedakey) {
/*
* We have changed the RRset above so we need to update
@@ -6313,6 +6359,15 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
+
+ /*
+ * Have we changed anything?
+ */
+ if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
+ goto pauseall;
+
+ commit = ISC_TRUE;
+
result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
&sig_diff, zone_keys, nkeys, now);
if (result != ISC_R_SUCCESS) {
@@ -6344,9 +6399,12 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
- /* Write changes to journal file. */
+ /*
+ * Write changes to journal file.
+ */
zone_journal(zone, &sig_diff, "zone_sign");
+ pauseall:
/*
* Pause all iterators so that dns_db_closeversion() can succeed.
*/
@@ -6363,7 +6421,7 @@ zone_sign(dns_zone_t *zone) {
/*
* Everything has succeeded. Commit the changes.
*/
- dns_db_closeversion(db, &version, ISC_TRUE);
+ dns_db_closeversion(db, &version, commit);
/*
* Everything succeeded so we can clean these up now.
@@ -6379,9 +6437,11 @@ zone_sign(dns_zone_t *zone) {
set_resigntime(zone);
- LOCK_ZONE(zone);
- zone_needdump(zone, DNS_DUMP_DELAY);
- UNLOCK_ZONE(zone);
+ if (commit) {
+ LOCK_ZONE(zone);
+ zone_needdump(zone, DNS_DUMP_DELAY);
+ UNLOCK_ZONE(zone);
+ }
failure:
/*
@@ -6564,15 +6624,15 @@ minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) {
name, 0, &rdata));
/* Update refresh timer */
- dns_rdata_tostruct(&rdata, &keydata, NULL);
+ CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
keydata.refresh = refresh_time(kfetch);
set_refreshkeytimer(zone, &keydata, now);
dns_rdata_reset(&rdata);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
- dns_rdata_fromstruct(&rdata,
- zone->rdclass, dns_rdatatype_keydata,
- &keydata, &keyb);
+ CHECK(dns_rdata_fromstruct(&rdata,
+ zone->rdclass, dns_rdatatype_keydata,
+ &keydata, &keyb));
/* Insert updated version */
CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
diff --git a/lib/export/Makefile.in b/lib/export/Makefile.in
new file mode 100644
index 00000000..fc9d4ad4
--- /dev/null
+++ b/lib/export/Makefile.in
@@ -0,0 +1,27 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+# Note: the order of SUBDIRS is important.
+# Attempt to disable parallel processing.
+.NOTPARALLEL:
+.NO_PARALLEL:
+SUBDIRS = isc dns isccfg irs samples
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in
new file mode 100644
index 00000000..9d0cce2e
--- /dev/null
+++ b/lib/export/dns/Makefile.in
@@ -0,0 +1,172 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/dns
+
+# Attempt to disable parallel processing.
+.NOTPARALLEL:
+.NO_PARALLEL:
+
+@BIND9_VERSION@
+
+@LIBDNS_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} \
+ ${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@
+
+CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@
+
+CWARNINGS =
+
+ISCLIBS = ../isc/libisc.@A@
+
+ISCDEPLIBS = ../isc/libisc.@A@
+
+LIBS = @LIBS@
+
+# Alphabetically
+DSTOBJS = 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@
+
+DNSOBJS = acl.@O@ adb.@O@ byaddr.@O@ \
+ cache.@O@ callbacks.@O@ client.@O@ compress.@O@ \
+ db.@O@ dbiterator.@O@ diff.@O@ dispatch.@O@ dlz.@O@ dnssec.@O@ \
+ ds.@O@ \
+ forward.@O@ iptable.@O@ \
+ keytable.@O@ \
+ lib.@O@ log.@O@ \
+ master.@O@ masterdump.@O@ message.@O@ \
+ name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ \
+ peer.@O@ portlist.@O@ \
+ rbt.@O@ rbtdb.@O@ rcode.@O@ rdata.@O@ \
+ rdatalist.@O@ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ \
+ request.@O@ resolver.@O@ result.@O@ soa.@O@ stats.@O@ \
+ tcpmsg.@O@ time.@O@ tsec.@O@ tsig.@O@ ttl.@O@ \
+ validator.@O@ version.@O@ view.@O@
+PORTDNSOBJS = ecdb.@O@
+
+OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS}
+
+# Alphabetically
+DSTSRCS = 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 \
+ openssldsa_link.c opensslrsa_link.c
+
+DNSSRCS = acl.c adb.c byaddr.c \
+ cache.c callbacks.c client.c compress.c \
+ db.c dbiterator.c diff.c dispatch.c dlz.c dnssec.c ds.c \
+ forward.c iptable.c \
+ keytable.c \
+ lib.c log.c \
+ master.c masterdump.c message.c \
+ name.c ncache.c nsec.c nsec3.c \
+ peer.c portlist.c \
+ rbt.c rbtdb.c rcode.c rdata.c \
+ rdatalist.c rdataset.c rdatasetiter.c rdataslab.c \
+ request.c res.c resolver.c result.c soa.c stats.c \
+ tcpmsg.c time.c tsec.c tsig.c ttl.c \
+ validator.c version.c view.c
+PORTDNSSRCS = ecdb.c
+
+SRCS = ${DSTSRCS} ${DNSSRCS} ${PORTDNSSRCS}
+
+SUBDIRS = include
+TARGETS = include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h timestamp
+
+DEPENDEXTRA = ./gen -F include/dns/rdatastruct.h \
+ -s ${srcdir} -d >> Makefile ;
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libdns.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libdns.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ ${LIBS}
+
+timestamp: libdns.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libdns.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libdns.@A@ timestamp
+ rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h
+ rm -f include/dns/rdatastruct.h
+
+newrr::
+ rm -f code.h include/dns/enumtype.h include/dns/enumclass.h
+ rm -f include/dns/rdatastruct.h
+
+include: include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h
+
+rdata.@O@: code.h
+
+include/dns/enumtype.h: gen
+ ./gen -s ${srcdir} -t > $@
+
+include/dns/enumclass.h: gen
+ ./gen -s ${srcdir} -c > $@
+
+include/dns/rdatastruct.h: gen \
+ ${srcdir}/rdata/rdatastructpre.h \
+ ${srcdir}/rdata/rdatastructsuf.h
+ ./gen -s ${srcdir} -i \
+ -P ${srcdir}/rdata/rdatastructpre.h \
+ -S ${srcdir}/rdata/rdatastructsuf.h > $@
+
+code.h: gen
+ ./gen -s ${srcdir} > code.h
+
+gen: ${srcdir}/gen.c
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS}
+
+#We don't need rbtdb64 for this library
+#rbtdb64.@O@: rbtdb.c
+
+depend: include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h code.h
+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
diff --git a/lib/export/dns/include/Makefile.in b/lib/export/dns/include/Makefile.in
new file mode 100644
index 00000000..9fc0b66b
--- /dev/null
+++ b/lib/export/dns/include/Makefile.in
@@ -0,0 +1,23 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = dns dst
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/dns/include/dns/Makefile.in b/lib/export/dns/include/dns/Makefile.in
new file mode 100644
index 00000000..5e04d885
--- /dev/null
+++ b/lib/export/dns/include/dns/Makefile.in
@@ -0,0 +1,56 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = acl.h adb.h byaddr.h \
+ cache.h callbacks.h cert.h client.h compress.h \
+ db.h dbiterator.h diff.h dispatch.h dlz.h dnssec.h \
+ ds.h events.h fixedname.h ecdb.h \
+ forward.h iptable.h \
+ keytable.h keyvalues.h \
+ lib.h log.h \
+ master.h masterdump.h message.h \
+ name.h ncache.h nsec.h nsec3.h \
+ peer.h portlist.h \
+ rbt.h rbtdb.h rcode.h rdata.h rdataclass.h \
+ rdatalist.h rdataset.h rdatasetiter.h rdataslab.h rdatatype.h \
+ request.h resolver.h result.h \
+ secalg.h secproto.h soa.h stats.h \
+ tcpmsg.h time.h tsec.h tsig.h ttl.h types.h \
+ validator.h version.h view.h
+
+GENHEADERS = enumclass.h enumtype.h rdatastruct.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/dns
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/dns/include/dns/$$i \
+ ${DESTDIR}${export_includedir}/dns ; \
+ done
+ for i in ${GENHEADERS}; do \
+ ${INSTALL_DATA} $$i ${DESTDIR}${export_includedir}/dns ; \
+ done
diff --git a/lib/export/dns/include/dst/Makefile.in b/lib/export/dns/include/dst/Makefile.in
new file mode 100644
index 00000000..259e62ed
--- /dev/null
+++ b/lib/export/dns/include/dst/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = dst.h gssapi.h lib.h result.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/dst
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/dns/include/dst/$$i \
+ ${DESTDIR}${export_includedir}/dst ; \
+ done
diff --git a/lib/export/irs/Makefile.in b/lib/export/irs/Makefile.in
new file mode 100644
index 00000000..2cdc5818
--- /dev/null
+++ b/lib/export/irs/Makefile.in
@@ -0,0 +1,85 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/irs
+
+@BIND9_VERSION@
+
+@LIBIRS_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -I./include -I${srcdir}/include \
+ ${ISCCFG_INCLUDES} -I../dns/include ${DNS_INCLUDES} \
+ ${ISC_INCLUDES}
+CDEFINES =
+CWARNINGS =
+
+# Alphabetically
+OBJS = context.@O@ \
+ dnsconf.@O@ \
+ gai_strerror.@O@ getaddrinfo.@O@ getnameinfo.@O@ \
+ resconf.@O@
+
+# Alphabetically
+SRCS = context.c \
+ dnsconf.c \
+ gai_sterror.c getaddrinfo.c getnameinfo.c \
+ resconf.c
+
+ISCLIBS = ../isc/libisc.@A@
+DNSLIBS = ../dns/libdns.@A@
+ISCCFGLIBS = ../isccfg/libisccfg.@A@
+
+LIBS = @LIBS@
+
+SUBDIRS = include
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libirs.@SA@: ${OBJS} version.@O@
+ ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@
+ ${RANLIB} $@
+
+libirs.la: ${OBJS} version.@O@
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} version.@O@ ${LIBS} ${ISCCFGLIBS} ${DNSLIBS} ${ISCLIBS}
+
+timestamp: libirs.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libirs.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libirs.@A@ libirs.la timestamp
diff --git a/lib/export/irs/include/Makefile.in b/lib/export/irs/include/Makefile.in
new file mode 100644
index 00000000..6fad286e
--- /dev/null
+++ b/lib/export/irs/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = irs
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/irs/include/irs/Makefile.in b/lib/export/irs/include/irs/Makefile.in
new file mode 100644
index 00000000..c8507571
--- /dev/null
+++ b/lib/export/irs/include/irs/Makefile.in
@@ -0,0 +1,46 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = context.h dnsconf.h resconf.h types.h version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/irs
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/irs/include/irs/$$i \
+ ${DESTDIR}${export_includedir}/irs ; \
+ done
+ ${INSTALL_DATA} ${top_srcdir}/lib/irs/include/irs/netdb.h \
+ ${DESTDIR}${export_includedir}/irs
+ ${INSTALL_DATA} ${top_srcdir}/lib/irs/include/irs/platform.h \
+ ${DESTDIR}${export_includedir}/irs
+
+distclean::
+ rm -f netdb.h platform.h
diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in
new file mode 100644
index 00000000..52f6b37b
--- /dev/null
+++ b/lib/export/isc/Makefile.in
@@ -0,0 +1,136 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.4 2009/09/03 20:28:46 each Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc
+
+@BIND9_VERSION@
+
+@LIBISC_API@
+
+CINCLUDES = -I${srcdir}/unix/include \
+ -I${srcdir}/@ISC_THREAD_DIR@/include \
+ -I${srcdir}/@ISC_ARCH_DIR@/include \
+ -I${srcdir}/include @ISC_OPENSSL_INC@
+CDEFINES = @USE_OPENSSL@ -DUSE_APPIMPREGISTER -DUSE_MEMIMPREGISTER \
+ -DUSE_SOCKETIMPREGISTER -DUSE_TASKIMPREGISTER \
+ -DUSE_TIMERIMPREGISTER
+CWARNINGS =
+
+# Alphabetically
+# {file,dir}.c is necessary for isclog
+# symtab.c is necessary for isccfg
+APIOBJS = app_api.@O@ mem_api.@O@ socket_api.@O@ \
+ task_api.@O@ timer_api.@O@
+
+ISCDRIVEROBJS = mem.@O@ unix/socket.@O@ task.@O@ timer.@O@ lib.@O@ \
+ heap.@O@ #timer module depends on this
+
+UNIXOBJS = @ISC_ISCIPV6_O@ \
+ unix/app.@O@ \
+ unix/dir.@O@ \
+ unix/errno2result.@O@ \
+ unix/file.@O@ \
+ unix/fsaccess.@O@ \
+ unix/stdio.@O@ \
+ unix/stdtime.@O@ unix/strerror.@O@ unix/time.@O@
+
+NLSOBJS = nls/msgcat.@O@
+
+THREADOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@ \
+ @ISC_THREAD_DIR@/thread.@O@
+
+WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
+ win32/fsaccess.@O@ win32/once.@O@ win32/stdtime.@O@ \
+ win32/thread.@O@ win32/time.@O@
+
+# Alphabetically
+OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ backtrace-emptytbl.@O@ base32.@O@ \
+ base64.@O@ buffer.@O@ bufferlist.@O@ \
+ error.@O@ event.@O@ \
+ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \
+ md5.@O@ mutexblock.@O@ \
+ netaddr.@O@ netscope.@O@ \
+ ondestroy.@O@ \
+ parseint.@O@ portset.@O@ radix.@O@ \
+ random.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
+ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ string.@O@ \
+ symtab.@O@ \
+ version.@O@ \
+ ${APIOBJS} ${ISCDRIVEROBJS} \
+ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+
+# Alphabetically
+APISRCS = app_api.c mem_api.c socket_api.c \
+ task_api.c timer_api.c
+
+ISCDRIVERSRCS = mem.c task.c lib.c timer.c heap.c
+
+SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c backtrace-emptytbl.c base32.c \
+ base64.c buffer.c bufferlist.c \
+ error.c event.c \
+ hash.c hex.c hmacmd5.c hmacsha.c \
+ inet_aton.c iterated_hash.c lex.c log.c lfsr.c \
+ md5.c mutexblock.c \
+ netaddr.c netscope.c \
+ ondestroy.c \
+ parseint.c portset.c radix.c \
+ random.c refcount.c region.c result.c rwlock.c \
+ serial.c sha1.c sha2.c sockaddr.c stats.c string.c symtab.c \
+ version.c \
+ ${APISRCS} ${ISCDRIVERSRCS}
+
+LIBS = @LIBS@
+
+SUBDIRS = include unix nls @ISC_THREAD_DIR@
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libisc.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libisc.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${LIBS}
+
+timestamp: libisc.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libisc.@A@ libisc.la timestamp
diff --git a/lib/export/isc/include/Makefile.in b/lib/export/isc/include/Makefile.in
new file mode 100644
index 00000000..4a5e0c6b
--- /dev/null
+++ b/lib/export/isc/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/include/isc/Makefile.in b/lib/export/isc/include/isc/Makefile.in
new file mode 100644
index 00000000..1e0ff001
--- /dev/null
+++ b/lib/export/isc/include/isc/Makefile.in
@@ -0,0 +1,63 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = app.h assertions.h base64.h bitstring.h boolean.h buffer.h \
+ bufferlist.h commandline.h entropy.h error.h event.h \
+ eventclass.h file.h formatcheck.h fsaccess.h \
+ hash.h heap.h hex.h hmacmd5.h \
+ httpd.h \
+ interfaceiter.h @ISC_IPV6_H@ iterated_hash.h lang.h lex.h \
+ lfsr.h lib.h list.h log.h \
+ magic.h md5.h mem.h msgcat.h msgs.h \
+ mutexblock.h namespace.h netaddr.h ondestroy.h os.h parseint.h \
+ print.h quota.h radix.h random.h ratelimiter.h \
+ refcount.h region.h resource.h \
+ result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
+ sockaddr.h socket.h stdio.h stdlib.h string.h \
+ symtab.h \
+ task.h taskpool.h timer.h types.h util.h version.h \
+ xml.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/isc/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
+ ${INSTALL_DATA} ${top_srcdir}/lib/isc/include/isc/platform.h \
+ ${DESTDIR}${export_includedir}/isc
+ ${INSTALL_DATA} ${top_srcdir}/lib/isc/@ISC_ARCH_DIR@/include/isc/atomic.h \
+ ${DESTDIR}${export_includedir}/isc
+
+distclean::
+ rm -f platform.h
diff --git a/lib/export/isc/nls/Makefile.in b/lib/export/isc/nls/Makefile.in
new file mode 100644
index 00000000..a9e779f9
--- /dev/null
+++ b/lib/export/isc/nls/Makefile.in
@@ -0,0 +1,35 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/nls
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/unix/include \
+ ${ISC_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+OBJS = msgcat.@O@
+
+SRCS = msgcat.c
+
+SUBDIRS =
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/nothreads/Makefile.in b/lib/export/isc/nothreads/Makefile.in
new file mode 100644
index 00000000..e1bd5663
--- /dev/null
+++ b/lib/export/isc/nothreads/Makefile.in
@@ -0,0 +1,38 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/nothreads
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include \
+ -I${srcdir}/../unix/include \
+ -I../include \
+ -I${srcdir}/../include \
+ -I${srcdir}/..
+
+CDEFINES =
+CWARNINGS =
+
+OBJS = condition.@O@ mutex.@O@ thread.@O@
+
+SRCS = condition.c mutex.c thread.c
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/nothreads/include/Makefile.in b/lib/export/isc/nothreads/include/Makefile.in
new file mode 100644
index 00000000..4a5e0c6b
--- /dev/null
+++ b/lib/export/isc/nothreads/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/nothreads/include/isc/Makefile.in b/lib/export/isc/nothreads/include/isc/Makefile.in
new file mode 100644
index 00000000..eb25c885
--- /dev/null
+++ b/lib/export/isc/nothreads/include/isc/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = condition.h mutex.h once.h thread.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(top_srcdir)/lib/isc/nothreads/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
diff --git a/lib/export/isc/pthreads/Makefile.in b/lib/export/isc/pthreads/Makefile.in
new file mode 100644
index 00000000..92788ec1
--- /dev/null
+++ b/lib/export/isc/pthreads/Makefile.in
@@ -0,0 +1,38 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/pthreads
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include \
+ -I${srcdir}/../unix/include \
+ -I../include \
+ -I${srcdir}/../include \
+ -I${srcdir}/..
+
+CDEFINES =
+CWARNINGS =
+
+OBJS = condition.@O@ mutex.@O@ thread.@O@
+
+SRCS = condition.c mutex.c thread.c
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/pthreads/include/Makefile.in b/lib/export/isc/pthreads/include/Makefile.in
new file mode 100644
index 00000000..4a5e0c6b
--- /dev/null
+++ b/lib/export/isc/pthreads/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/pthreads/include/isc/Makefile.in b/lib/export/isc/pthreads/include/isc/Makefile.in
new file mode 100644
index 00000000..77d5c077
--- /dev/null
+++ b/lib/export/isc/pthreads/include/isc/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = condition.h mutex.h once.h thread.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(top_srcdir)/lib/isc/pthreads/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in
new file mode 100644
index 00000000..5a8eed88
--- /dev/null
+++ b/lib/export/isc/unix/Makefile.in
@@ -0,0 +1,57 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/unix
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include \
+ -I${srcdir}/../@ISC_THREAD_DIR@/include \
+ -I../include \
+ -I${srcdir}/../include \
+ -I${srcdir}/..
+
+CDEFINES = -DUSE_SOCKETIMPREGISTER -DUSE_APPIMPREGISTER
+
+CWARNINGS =
+
+# Alphabetically
+ISCDRIVEROBJS = app.@O@ socket.@O@
+
+OBJS = @ISC_IPV6_O@ \
+ dir.@O@ \
+ errno2result.@O@ \
+ file.@O@ fsaccess.@O@ \
+ stdio.@O@ stdtime.@O@ strerror.@O@ \
+ time.@O@ \
+ ${ISCDRIVEROBJS}
+
+# Alphabetically
+ISCDRIVERSRCS = app.c socket.c
+
+SRCS = @ISC_IPV6_C@ \
+ dir.c \
+ errno2result.c \
+ file.c fsaccess.c \
+ stdio.c stdtime.c strerror.c \
+ time.c \
+ ${ISCDRIVERSRCS}
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/unix/include/Makefile.in b/lib/export/isc/unix/include/Makefile.in
new file mode 100644
index 00000000..4a5e0c6b
--- /dev/null
+++ b/lib/export/isc/unix/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/unix/include/isc/Makefile.in b/lib/export/isc/unix/include/isc/Makefile.in
new file mode 100644
index 00000000..f19b8c65
--- /dev/null
+++ b/lib/export/isc/unix/include/isc/Makefile.in
@@ -0,0 +1,37 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = dir.h int.h net.h netdb.h offset.h stdtime.h \
+ syslog.h time.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(top_srcdir)/lib/isc/unix/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
diff --git a/lib/export/isccfg/Makefile.in b/lib/export/isccfg/Makefile.in
new file mode 100644
index 00000000..d15b6433
--- /dev/null
+++ b/lib/export/isccfg/Makefile.in
@@ -0,0 +1,81 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isccfg
+
+@BIND9_VERSION@
+
+@LIBISCCFG_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+ISCLIBS = ../isc/libisc.@A@
+DNSLIBS = ../dns/libdns.@A@
+
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+ISCCFGDEPLIBS = libisccfg.@A@
+
+LIBS = @LIBS@
+
+SUBDIRS = include
+
+# Alphabetically
+OBJS = dnsconf.@O@ log.@O@ parser.@O@ version.@O@
+
+# Alphabetically
+SRCS = dnsconf.c log.c parser.c version.c
+
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libisccfg.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libisccfg.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${LIBS} ${DNSLIBS} ${ISCLIBS}
+
+timestamp: libisccfg.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisccfg.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libisccfg.@A@ timestamp
diff --git a/lib/export/isccfg/include/Makefile.in b/lib/export/isccfg/include/Makefile.in
new file mode 100644
index 00000000..0c3d1853
--- /dev/null
+++ b/lib/export/isccfg/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.2 2009/09/01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isccfg
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isccfg/include/isccfg/Makefile.in b/lib/export/isccfg/include/isccfg/Makefile.in
new file mode 100644
index 00000000..5e9ea78d
--- /dev/null
+++ b/lib/export/isccfg/include/isccfg/Makefile.in
@@ -0,0 +1,42 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = cfg.h grammar.h log.h dnsconf.h version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs \
+ ${DESTDIR}${export_includedir}/isccfg
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/isccfg/include/isccfg/$$i \
+ ${DESTDIR}${export_includedir}/isccfg ; \
+ done
diff --git a/lib/export/samples/Makefile-postinstall.in b/lib/export/samples/Makefile-postinstall.in
new file mode 100644
index 00000000..174aed60
--- /dev/null
+++ b/lib/export/samples/Makefile-postinstall.in
@@ -0,0 +1,78 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile-postinstall.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+#prefix = @prefix@
+#exec_prefix = @exec_prefix@
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = -ldns @DNS_CRYPTO_LIBS@
+ISCLIBS = -lisc
+ISCCFGLIBS = -lisccfg
+IRSLIBS = -lirs
+
+LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+
+SUBDIRS =
+
+TARGETS = sample@EXEEXT@ sample-async@EXEEXT@ sample-gai@EXEEXT@ \
+ sample-update@EXEEXT@ sample-request@EXEEXT@ nsprobe@EXEEXT@ \
+ dlvchecks@EXEEXT@
+
+OBJS = sample.@O@ sample-async.@O@ sample-gai.@O@ sample-update.@O@ \
+ sample-request.@O@ nsprobe.@O@ dlvchecks.@O@
+
+SRCS = sample.c sample-async.c sample-gai.c sample-update.c \
+ sample-request.c nsprobe.c dlvchecks..c
+
+@BIND9_MAKE_RULES@
+
+# The following two may depend on BIND9_MAKE_RULES
+CINCLUDES = -I@export_includedir@
+LDFLAGS = -L@export_libdir@
+
+sample@EXEEXT@: sample.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample.@O@ ${LIBS}
+
+sample-async@EXEEXT@: sample-async.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-async.@O@ ${LIBS}
+
+sample-gai@EXEEXT@: sample-gai.@O@ ${IRSDEPLIBS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-gai.@O@ ${IRSLIBS} ${LIBS}
+
+sample-update@EXEEXT@: sample-update.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-update.@O@ ${LIBS}
+
+sample-request@EXEEXT@: sample-request.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-request.@O@ ${LIBS}
+
+nsprobe@EXEEXT@: nsprobe.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ nsprobe.@O@ ${LIBS}
+
+dlvchecks@EXEEXT@: dlvchecks.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dlvchecks.@O@ ${LIBS}
+
+clean distclean maintainer-clean::
+ rm -f ${TARGETS}
diff --git a/lib/export/samples/Makefile.in b/lib/export/samples/Makefile.in
new file mode 100644
index 00000000..4ab0286c
--- /dev/null
+++ b/lib/export/samples/Makefile.in
@@ -0,0 +1,96 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include -I../dns/include \
+ ${DNS_INCLUDES} ${ISC_INCLUDES} \
+ -I${top_srcdir}/lib/irs/include
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@
+ISCLIBS = ../isc/libisc.@A@
+ISCCFGLIBS = ../isccfg/libisccfg.@A@
+IRSLIBS = ../irs/libirs.@A@
+
+DNSDEPLIBS = ../dns/libdns.@A@
+ISCDEPLIBS = ../isc/libisc.@A@
+ISCCFGDEPLIBS = ../isccfg/libisccfg.@A@
+IRSDEPLIBS = ../irs/libirs.@A@
+
+DEPLIBS = ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS}
+
+LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+
+SUBDIRS =
+
+TARGETS = sample@EXEEXT@ sample-async@EXEEXT@ sample-gai@EXEEXT@ \
+ sample-update@EXEEXT@ sample-request@EXEEXT@ nsprobe@EXEEXT@
+
+OBJS = sample.@O@ sample-async.@O@ sample-gai.@O@ sample-update.@O@ \
+ sample-request.@O@ nsprobe.@O@
+
+UOBJS =
+
+SRCS = sample.c sample-async.c sample-gai.c sample-update.c \
+ sample-request.c nsprobe.c
+
+MANPAGES =
+
+HTMLPAGES =
+
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+@BIND9_MAKE_RULES@
+
+sample@EXEEXT@: sample.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample.@O@ ${LIBS}
+
+sample-async@EXEEXT@: sample-async.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-async.@O@ ${LIBS}
+
+sample-gai@EXEEXT@: sample-gai.@O@ ${IRSDEPLIBS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-gai.@O@ ${IRSLIBS} ${LIBS}
+
+sample-update@EXEEXT@: sample-update.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-update.@O@ ${LIBS}
+
+sample-request@EXEEXT@: sample-request.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-request.@O@ ${LIBS}
+
+nsprobe@EXEEXT@: nsprobe.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ nsprobe.@O@ ${LIBS}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+clean distclean maintainer-clean::
+ rm -f ${TARGETS}
diff --git a/lib/export/samples/nsprobe.c b/lib/export/samples/nsprobe.c
new file mode 100644
index 00000000..e706e290
--- /dev/null
+++ b/lib/export/samples/nsprobe.c
@@ -0,0 +1,1217 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: nsprobe.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/socket.h>
+#include <isc/sockaddr.h>
+#include <isc/string.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/lib.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#define MAX_PROBES 1000
+
+static dns_client_t *client = NULL;
+static isc_task_t *probe_task = NULL;
+static isc_appctx_t *actx = NULL;
+static isc_mem_t *mctx = NULL;
+static unsigned int outstanding_probes = 0;
+const char *cacheserver = "127.0.0.1";
+static FILE *fp;
+
+typedef enum {
+ none,
+ exist,
+ nxdomain,
+ othererr,
+ multiplesoa,
+ multiplecname,
+ brokenanswer,
+ lame,
+ timedout,
+ notype,
+ unexpected
+} query_result_t;
+
+struct server {
+ ISC_LINK(struct server) link;
+
+ isc_sockaddr_t address;
+ query_result_t result_a;
+ query_result_t result_aaaa;
+};
+
+struct probe_ns {
+ ISC_LINK(struct probe_ns) link;
+
+ dns_fixedname_t fixedname;
+ dns_name_t *name;
+ struct server *current_server;
+ ISC_LIST(struct server) servers;
+};
+
+struct probe_trans {
+ isc_boolean_t inuse;
+ char *domain;
+ dns_fixedname_t fixedname;
+ dns_name_t *qname;
+ const char **qlabel;
+ isc_boolean_t qname_found;
+ dns_clientrestrans_t *resid;
+ dns_message_t *qmessage;
+ dns_message_t *rmessage;
+ dns_clientreqtrans_t *reqid;
+
+ /* NS list */
+ struct probe_ns *current_ns;
+ ISC_LIST(struct probe_ns) nslist;
+};
+
+struct stat {
+ unsigned long valid;
+ unsigned long ignore;
+ unsigned long nxdomain;
+ unsigned long othererr;
+ unsigned long multiplesoa;
+ unsigned long multiplecname;
+ unsigned long brokenanswer;
+ unsigned long lame;
+ unsigned long unknown;
+} server_stat, domain_stat;
+
+static unsigned long number_of_domains = 0;
+static unsigned long number_of_servers = 0;
+static unsigned long multiple_error_domains = 0;
+static isc_boolean_t debug_mode = ISC_FALSE;
+static int verbose_level = 0;
+static const char *qlabels[] = {"www.", "ftp.", NULL};
+static struct probe_trans probes[MAX_PROBES];
+
+static isc_result_t probe_domain(struct probe_trans *trans);
+static void reset_probe(struct probe_trans *trans);
+static isc_result_t fetch_nsaddress(struct probe_trans *trans);
+static isc_result_t probe_name(struct probe_trans *trans,
+ dns_rdatatype_t type);
+
+/* Dump an rdataset for debug */
+static isc_result_t
+print_rdataset(dns_rdataset_t *rdataset, dns_name_t *owner) {
+ isc_buffer_t target;
+ isc_result_t result;
+ isc_region_t r;
+ char t[4096];
+
+ if (!debug_mode)
+ return (ISC_R_SUCCESS);
+
+ isc_buffer_init(&target, t, sizeof(t));
+
+ if (!dns_rdataset_isassociated(rdataset))
+ return (ISC_R_SUCCESS);
+ result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
+ &target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&target, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+print_name(dns_name_t *name) {
+ isc_result_t result;
+ isc_buffer_t target;
+ isc_region_t r;
+ char t[4096];
+
+ isc_buffer_init(&target, t, sizeof(t));
+ result = dns_name_totext(name, ISC_TRUE, &target);
+ if (result == ISC_R_SUCCESS) {
+ isc_buffer_usedregion(&target, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+ } else
+ printf("(invalid name)");
+
+ return (result);
+}
+
+static isc_result_t
+print_address(FILE *fp, isc_sockaddr_t *addr) {
+ char buf[NI_MAXHOST];
+
+ if (getnameinfo(&addr->type.sa, addr->length, buf, sizeof(buf),
+ NULL, 0, NI_NUMERICHOST) == 0) {
+ fprintf(fp, "%s", buf);
+ } else {
+ fprintf(fp, "(invalid address)");
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ if (*taskmgrp != NULL)
+ isc_taskmgr_destroy(taskmgrp);
+
+ if (*timermgrp != NULL)
+ isc_timermgr_destroy(timermgrp);
+
+ if (*socketmgrp != NULL)
+ isc_socketmgr_destroy(socketmgrp);
+
+ if (*actxp != NULL)
+ isc_appctx_destroy(actxp);
+
+ if (*mctxp != NULL)
+ isc_mem_destroy(mctxp);
+}
+
+static isc_result_t
+ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ isc_result_t result;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_appctx_create(*mctxp, actxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
+
+ return (result);
+}
+
+/*
+ * Common routine to make query data
+ */
+static isc_result_t
+make_querymessage(dns_message_t *message, dns_name_t *qname0,
+ dns_rdatatype_t rdtype)
+{
+ dns_name_t *qname = NULL;
+ dns_rdataset_t *qrdataset = NULL;
+ isc_result_t result;
+
+ message->opcode = dns_opcode_query;
+ message->rdclass = dns_rdataclass_in;
+
+ result = dns_message_gettempname(message, &qname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_message_gettemprdataset(message, &qrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_name_init(qname, NULL);
+ dns_name_clone(qname0, qname);
+ dns_rdataset_init(qrdataset);
+ dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
+ ISC_LIST_APPEND(qname->list, qrdataset, link);
+ dns_message_addname(message, qname, DNS_SECTION_QUESTION);
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (qname != NULL)
+ dns_message_puttempname(message, &qname);
+ if (qrdataset != NULL)
+ dns_message_puttemprdataset(message, &qrdataset);
+ if (message != NULL)
+ dns_message_destroy(&message);
+ return (result);
+}
+
+/*
+ * Update statistics
+ */
+static inline void
+increment_entry(unsigned long *entryp) {
+ (*entryp)++;
+ INSIST(*entryp != 0); /* check overflow */
+}
+
+static void
+update_stat(struct probe_trans *trans) {
+ struct probe_ns *pns;
+ struct server *server;
+ struct stat local_stat;
+ unsigned int err_count = 0;
+ const char *stattype;
+
+ increment_entry(&number_of_domains);
+ memset(&local_stat, 0, sizeof(local_stat));
+
+ /* Update per sever statistics */
+ for (pns = ISC_LIST_HEAD(trans->nslist); pns != NULL;
+ pns = ISC_LIST_NEXT(pns, link)) {
+ for (server = ISC_LIST_HEAD(pns->servers); server != NULL;
+ server = ISC_LIST_NEXT(server, link)) {
+ increment_entry(&number_of_servers);
+
+ if (server->result_aaaa == exist ||
+ server->result_aaaa == notype) {
+ /*
+ * Don't care about the result of A query if
+ * the answer to AAAA query was expected.
+ */
+ stattype = "valid";
+ increment_entry(&server_stat.valid);
+ increment_entry(&local_stat.valid);
+ } else if (server->result_a == exist) {
+ switch (server->result_aaaa) {
+ case exist:
+ case notype:
+ stattype = "valid";
+ increment_entry(&server_stat.valid);
+ increment_entry(&local_stat.valid);
+ break;
+ case timedout:
+ stattype = "ignore";
+ increment_entry(&server_stat.ignore);
+ increment_entry(&local_stat.ignore);
+ break;
+ case nxdomain:
+ stattype = "nxdomain";
+ increment_entry(&server_stat.nxdomain);
+ increment_entry(&local_stat.nxdomain);
+ break;
+ case othererr:
+ stattype = "othererr";
+ increment_entry(&server_stat.othererr);
+ increment_entry(&local_stat.othererr);
+ break;
+ case multiplesoa:
+ stattype = "multiplesoa";
+ increment_entry(&server_stat.multiplesoa);
+ increment_entry(&local_stat.multiplesoa);
+ break;
+ case multiplecname:
+ stattype = "multiplecname";
+ increment_entry(&server_stat.multiplecname);
+ increment_entry(&local_stat.multiplecname);
+ break;
+ case brokenanswer:
+ stattype = "brokenanswer";
+ increment_entry(&server_stat.brokenanswer);
+ increment_entry(&local_stat.brokenanswer);
+ break;
+ case lame:
+ stattype = "lame";
+ increment_entry(&server_stat.lame);
+ increment_entry(&local_stat.lame);
+ break;
+ default:
+ stattype = "unknown";
+ increment_entry(&server_stat.unknown);
+ increment_entry(&local_stat.unknown);
+ break;
+ }
+ } else {
+ stattype = "unknown";
+ increment_entry(&server_stat.unknown);
+ increment_entry(&local_stat.unknown);
+ }
+
+ if (verbose_level > 1 ||
+ (verbose_level == 1 &&
+ strcmp(stattype, "valid") != 0 &&
+ strcmp(stattype, "unknown") != 0)) {
+ print_name(pns->name);
+ putchar('(');
+ print_address(stdout, &server->address);
+ printf(") for %s:%s\n", trans->domain,
+ stattype);
+ }
+ }
+ }
+
+ /* Update per domain statistics */
+ if (local_stat.ignore > 0) {
+ if (verbose_level > 0)
+ printf("%s:ignore\n", trans->domain);
+ increment_entry(&domain_stat.ignore);
+ err_count++;
+ }
+ if (local_stat.nxdomain > 0) {
+ if (verbose_level > 0)
+ printf("%s:nxdomain\n", trans->domain);
+ increment_entry(&domain_stat.nxdomain);
+ err_count++;
+ }
+ if (local_stat.othererr > 0) {
+ if (verbose_level > 0)
+ printf("%s:othererr\n", trans->domain);
+ increment_entry(&domain_stat.othererr);
+ err_count++;
+ }
+ if (local_stat.multiplesoa > 0) {
+ if (verbose_level > 0)
+ printf("%s:multiplesoa\n", trans->domain);
+ increment_entry(&domain_stat.multiplesoa);
+ err_count++;
+ }
+ if (local_stat.multiplecname > 0) {
+ if (verbose_level > 0)
+ printf("%s:multiplecname\n", trans->domain);
+ increment_entry(&domain_stat.multiplecname);
+ err_count++;
+ }
+ if (local_stat.brokenanswer > 0) {
+ if (verbose_level > 0)
+ printf("%s:brokenanswer\n", trans->domain);
+ increment_entry(&domain_stat.brokenanswer);
+ err_count++;
+ }
+ if (local_stat.lame > 0) {
+ if (verbose_level > 0)
+ printf("%s:lame\n", trans->domain);
+ increment_entry(&domain_stat.lame);
+ err_count++;
+ }
+
+ if (err_count > 1)
+ increment_entry(&multiple_error_domains);
+
+ /*
+ * We regard the domain as valid if and only if no authoritative server
+ * has a problem and at least one server is known to be valid.
+ */
+ if (local_stat.valid > 0 && err_count == 0) {
+ if (verbose_level > 1)
+ printf("%s:valid\n", trans->domain);
+ increment_entry(&domain_stat.valid);
+ }
+
+ /*
+ * If the domain has no available server or all servers have the
+ * 'unknown' result, the domain's result is also regarded as unknown.
+ */
+ if (local_stat.valid == 0 && err_count == 0) {
+ if (verbose_level > 1)
+ printf("%s:unknown\n", trans->domain);
+ increment_entry(&domain_stat.unknown);
+ }
+}
+
+/*
+ * Search for an existent name with an A RR
+ */
+
+static isc_result_t
+set_nextqname(struct probe_trans *trans) {
+ isc_result_t result;
+ size_t domainlen;
+ isc_buffer_t b;
+ char buf[4096]; /* XXX ad-hoc constant, but should be enough */
+
+ if (*trans->qlabel == NULL)
+ return (ISC_R_NOMORE);
+
+ result = isc_string_copy(buf, sizeof(buf), *trans->qlabel);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_string_append(buf, sizeof(buf), trans->domain);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ domainlen = strlen(buf);
+ isc_buffer_init(&b, buf, domainlen);
+ isc_buffer_add(&b, domainlen);
+ dns_fixedname_init(&trans->fixedname);
+ trans->qname = dns_fixedname_name(&trans->fixedname);
+ result = dns_name_fromtext(trans->qname, &b, dns_rootname,
+ 0, NULL);
+
+ trans->qlabel++;
+
+ return (result);
+}
+
+static void
+request_done(isc_task_t *task, isc_event_t *event) {
+ struct probe_trans *trans = event->ev_arg;
+ dns_clientreqevent_t *rev = (dns_clientreqevent_t *)event;
+ dns_message_t *rmessage;
+ struct probe_ns *pns;
+ struct server *server;
+ isc_result_t result;
+ query_result_t *resultp;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ dns_rdatatype_t type;
+
+ REQUIRE(task == probe_task);
+ REQUIRE(trans != NULL && trans->inuse == ISC_TRUE);
+ rmessage = rev->rmessage;
+ REQUIRE(rmessage == trans->rmessage);
+ INSIST(outstanding_probes > 0);
+
+ server = trans->current_ns->current_server;
+ INSIST(server != NULL);
+
+ if (server->result_a == none) {
+ type = dns_rdatatype_a;
+ resultp = &server->result_a;
+ } else {
+ resultp = &server->result_aaaa;
+ type = dns_rdatatype_aaaa;
+ }
+
+ if (rev->result == ISC_R_SUCCESS) {
+ if ((rmessage->flags & DNS_MESSAGEFLAG_AA) == 0)
+ *resultp = lame;
+ else if (rmessage->rcode == dns_rcode_nxdomain)
+ *resultp = nxdomain;
+ else if (rmessage->rcode != dns_rcode_noerror)
+ *resultp = othererr;
+ else if (rmessage->counts[DNS_SECTION_ANSWER] == 0) {
+ /* no error but empty answer */
+ *resultp = notype;
+ } else {
+ result = dns_message_firstname(rmessage,
+ DNS_SECTION_ANSWER);
+ while (result == ISC_R_SUCCESS) {
+ name = NULL;
+ dns_message_currentname(rmessage,
+ DNS_SECTION_ANSWER,
+ &name);
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset,
+ link)) {
+ (void)print_rdataset(rdataset, name);
+
+ if (rdataset->type ==
+ dns_rdatatype_cname ||
+ rdataset->type ==
+ dns_rdatatype_dname) {
+ /* Should chase the chain? */
+ *resultp = exist;
+ goto found;
+ } else if (rdataset->type == type) {
+ *resultp = exist;
+ goto found;
+ }
+ }
+ result = dns_message_nextname(rmessage,
+ DNS_SECTION_ANSWER);
+ }
+
+ /*
+ * Something unexpected happened: the response
+ * contained a non-empty authoritative answer, but we
+ * could not find an expected result.
+ */
+ *resultp = unexpected;
+ }
+ } else if (rev->result == DNS_R_RECOVERABLE ||
+ rev->result == DNS_R_BADLABELTYPE) {
+ /* Broken response. Try identifying known cases. */
+ *resultp = brokenanswer;
+
+ if (rmessage->counts[DNS_SECTION_ANSWER] > 0) {
+ result = dns_message_firstname(rmessage,
+ DNS_SECTION_ANSWER);
+ while (result == ISC_R_SUCCESS) {
+ /*
+ * Check to see if the response has multiple
+ * CNAME RRs. Update the result code if so.
+ */
+ name = NULL;
+ dns_message_currentname(rmessage,
+ DNS_SECTION_ANSWER,
+ &name);
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset,
+ link)) {
+ if (rdataset->type ==
+ dns_rdatatype_cname &&
+ dns_rdataset_count(rdataset) > 1) {
+ *resultp = multiplecname;
+ goto found;
+ }
+ }
+ result = dns_message_nextname(rmessage,
+ DNS_SECTION_ANSWER);
+ }
+ }
+
+ if (rmessage->counts[DNS_SECTION_AUTHORITY] > 0) {
+ result = dns_message_firstname(rmessage,
+ DNS_SECTION_AUTHORITY);
+ while (result == ISC_R_SUCCESS) {
+ /*
+ * Check to see if the response has multiple
+ * SOA RRs. Update the result code if so.
+ */
+ name = NULL;
+ dns_message_currentname(rmessage,
+ DNS_SECTION_AUTHORITY,
+ &name);
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset,
+ link)) {
+ if (rdataset->type ==
+ dns_rdatatype_soa &&
+ dns_rdataset_count(rdataset) > 1) {
+ *resultp = multiplesoa;
+ goto found;
+ }
+ }
+ result = dns_message_nextname(rmessage,
+ DNS_SECTION_AUTHORITY);
+ }
+ }
+ } else if (rev->result == ISC_R_TIMEDOUT)
+ *resultp = timedout;
+ else {
+ fprintf(stderr, "unexpected result: %d (domain=%s, server=",
+ rev->result, trans->domain);
+ print_address(stderr, &server->address);
+ fputc('\n', stderr);
+ *resultp = unexpected;
+ }
+
+ found:
+ INSIST(*resultp != none);
+ if (type == dns_rdatatype_a && *resultp == exist)
+ trans->qname_found = ISC_TRUE;
+
+ dns_client_destroyreqtrans(&trans->reqid);
+ isc_event_free(&event);
+ dns_message_reset(trans->rmessage, DNS_MESSAGE_INTENTPARSE);
+
+ result = probe_name(trans, type);
+ if (result == ISC_R_NOMORE) {
+ /* We've tried all addresses of all servers. */
+ if (type == dns_rdatatype_a && trans->qname_found) {
+ /*
+ * If we've explored A RRs and found an existent
+ * record, we can move to AAAA.
+ */
+ trans->current_ns = ISC_LIST_HEAD(trans->nslist);
+ probe_name(trans, dns_rdatatype_aaaa);
+ result = ISC_R_SUCCESS;
+ } else if (type == dns_rdatatype_a) {
+ /*
+ * No server provided an existent A RR of this name.
+ * Try next label.
+ */
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ result = set_nextqname(trans);
+ if (result == ISC_R_SUCCESS) {
+ trans->current_ns =
+ ISC_LIST_HEAD(trans->nslist);
+ for (pns = trans->current_ns; pns != NULL;
+ pns = ISC_LIST_NEXT(pns, link)) {
+ for (server = ISC_LIST_HEAD(pns->servers);
+ server != NULL;
+ server = ISC_LIST_NEXT(server,
+ link)) {
+ INSIST(server->result_aaaa ==
+ none);
+ server->result_a = none;
+ }
+ }
+ result = probe_name(trans, dns_rdatatype_a);
+ }
+ }
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * We've explored AAAA RRs or failed to find a valid
+ * query label. Wrap up the result and move to the
+ * next domain.
+ */
+ reset_probe(trans);
+ }
+ } else if (result != ISC_R_SUCCESS)
+ reset_probe(trans); /* XXX */
+}
+
+static isc_result_t
+probe_name(struct probe_trans *trans, dns_rdatatype_t type) {
+ isc_result_t result;
+ struct probe_ns *pns;
+ struct server *server;
+
+ REQUIRE(trans->reqid == NULL);
+ REQUIRE(type == dns_rdatatype_a || type == dns_rdatatype_aaaa);
+
+ for (pns = trans->current_ns; pns != NULL;
+ pns = ISC_LIST_NEXT(pns, link)) {
+ for (server = ISC_LIST_HEAD(pns->servers); server != NULL;
+ server = ISC_LIST_NEXT(server, link)) {
+ if ((type == dns_rdatatype_a &&
+ server->result_a == none) ||
+ (type == dns_rdatatype_aaaa &&
+ server->result_aaaa == none)) {
+ pns->current_server = server;
+ goto found;
+ }
+ }
+ }
+
+ found:
+ trans->current_ns = pns;
+ if (pns == NULL)
+ return (ISC_R_NOMORE);
+
+ INSIST(pns->current_server != NULL);
+ dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER);
+ result = make_querymessage(trans->qmessage, trans->qname, type);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = dns_client_startrequest(client, trans->qmessage,
+ trans->rmessage,
+ &pns->current_server->address,
+ 0, DNS_MESSAGEPARSE_BESTEFFORT,
+ NULL, 120, 0, 4,
+ probe_task, request_done, trans,
+ &trans->reqid);
+
+ return (result);
+}
+
+/*
+ * Get IP addresses of NSes
+ */
+
+static void
+resolve_nsaddress(isc_task_t *task, isc_event_t *event) {
+ struct probe_trans *trans = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ struct probe_ns *pns = trans->current_ns;
+ isc_result_t result;
+
+ REQUIRE(task == probe_task);
+ REQUIRE(trans->inuse == ISC_TRUE);
+ REQUIRE(pns != NULL);
+ INSIST(outstanding_probes > 0);
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ (void)print_rdataset(rdataset, name);
+
+ if (rdataset->type != dns_rdatatype_a)
+ continue;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_in_a_t rdata_a;
+ struct server *server;
+
+ dns_rdataset_current(rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ server = isc_mem_get(mctx, sizeof(*server));
+ if (server == NULL) {
+ fprintf(stderr, "resolve_nsaddress: "
+ "mem_get failed");
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ isc_sockaddr_fromin(&server->address,
+ &rdata_a.in_addr, 53);
+ ISC_LINK_INIT(server, link);
+ server->result_a = none;
+ server->result_aaaa = none;
+ ISC_LIST_APPEND(pns->servers, server, link);
+ }
+ }
+ }
+
+ cleanup:
+ dns_client_freeresanswer(client, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->resid);
+ isc_event_free(&event);
+
+ next_ns:
+ trans->current_ns = ISC_LIST_NEXT(pns, link);
+ if (trans->current_ns == NULL) {
+ trans->current_ns = ISC_LIST_HEAD(trans->nslist);
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ result = set_nextqname(trans);
+ if (result == ISC_R_SUCCESS)
+ result = probe_name(trans, dns_rdatatype_a);
+ } else {
+ result = fetch_nsaddress(trans);
+ if (result != ISC_R_SUCCESS)
+ goto next_ns; /* XXX: this is unlikely to succeed */
+ }
+
+ if (result != ISC_R_SUCCESS)
+ reset_probe(trans);
+}
+
+static isc_result_t
+fetch_nsaddress(struct probe_trans *trans) {
+ struct probe_ns *pns;
+
+ pns = trans->current_ns;
+ REQUIRE(pns != NULL);
+
+ return (dns_client_startresolve(client, pns->name, dns_rdataclass_in,
+ dns_rdatatype_a, 0, probe_task,
+ resolve_nsaddress, trans,
+ &trans->resid));
+}
+
+/*
+ * Get NS RRset for a given domain
+ */
+
+static void
+reset_probe(struct probe_trans *trans) {
+ struct probe_ns *pns;
+ struct server *server;
+ isc_result_t result;
+
+ REQUIRE(trans->resid == NULL);
+ REQUIRE(trans->reqid == NULL);
+
+ update_stat(trans);
+
+ dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER);
+ dns_message_reset(trans->rmessage, DNS_MESSAGE_INTENTPARSE);
+
+ trans->inuse = ISC_FALSE;
+ if (trans->domain != NULL)
+ isc_mem_free(mctx, trans->domain);
+ trans->domain = NULL;
+ if (trans->qname != NULL)
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ trans->qlabel = qlabels;
+ trans->qname_found = ISC_FALSE;
+ trans->current_ns = NULL;
+
+ while ((pns = ISC_LIST_HEAD(trans->nslist)) != NULL) {
+ ISC_LIST_UNLINK(trans->nslist, pns, link);
+ while ((server = ISC_LIST_HEAD(pns->servers)) != NULL) {
+ ISC_LIST_UNLINK(pns->servers, server, link);
+ isc_mem_put(mctx, server, sizeof(*server));
+ }
+ isc_mem_put(mctx, pns, sizeof(*pns));
+ }
+
+ outstanding_probes--;
+
+ result = probe_domain(trans);
+ if (result == ISC_R_NOMORE && outstanding_probes == 0)
+ isc_app_ctxshutdown(actx);
+}
+
+static void
+resolve_ns(isc_task_t *task, isc_event_t *event) {
+ struct probe_trans *trans = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ struct probe_ns *pns;
+
+ REQUIRE(task == probe_task);
+ REQUIRE(trans->inuse == ISC_TRUE);
+ INSIST(outstanding_probes > 0);
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ (void)print_rdataset(rdataset, name);
+
+ if (rdataset->type != dns_rdatatype_ns)
+ continue;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_ns_t ns;
+
+ dns_rdataset_current(rdataset, &rdata);
+ /*
+ * Extract the name from the NS record.
+ */
+ result = dns_rdata_tostruct(&rdata, &ns, NULL);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ pns = isc_mem_get(mctx, sizeof(*pns));
+ if (pns == NULL) {
+ fprintf(stderr,
+ "resolve_ns: mem_get failed");
+ result = ISC_R_NOMEMORY;
+ /*
+ * XXX: should we continue with the
+ * available servers anyway?
+ */
+ goto cleanup;
+ }
+
+ dns_fixedname_init(&pns->fixedname);
+ pns->name =
+ dns_fixedname_name(&pns->fixedname);
+ ISC_LINK_INIT(pns, link);
+ ISC_LIST_APPEND(trans->nslist, pns, link);
+ ISC_LIST_INIT(pns->servers);
+
+ dns_name_copy(&ns.name, pns->name, NULL);
+ dns_rdata_reset(&rdata);
+ dns_rdata_freestruct(&ns);
+ }
+ }
+ }
+
+ cleanup:
+ dns_client_freeresanswer(client, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->resid);
+ isc_event_free(&event);
+
+ if (!ISC_LIST_EMPTY(trans->nslist)) {
+ /* Go get addresses of NSes */
+ trans->current_ns = ISC_LIST_HEAD(trans->nslist);
+ result = fetch_nsaddress(trans);
+ } else
+ result = ISC_R_FAILURE;
+
+ if (result == ISC_R_SUCCESS)
+ return;
+
+ reset_probe(trans);
+}
+
+static isc_result_t
+probe_domain(struct probe_trans *trans) {
+ isc_result_t result;
+ size_t domainlen;
+ isc_buffer_t b;
+ char buf[4096]; /* XXX ad hoc constant, but should be enough */
+ char *cp;
+
+ REQUIRE(trans != NULL);
+ REQUIRE(trans->inuse == ISC_FALSE);
+ REQUIRE(outstanding_probes < MAX_PROBES);
+
+ /* Construct domain */
+ cp = fgets(buf, sizeof(buf), fp);
+ if (cp == NULL)
+ return (ISC_R_NOMORE);
+ if ((cp = strchr(buf, '\n')) != NULL) /* zap NL if any */
+ *cp = '\0';
+ trans->domain = isc_mem_strdup(mctx, buf);
+ if (trans->domain == NULL) {
+ fprintf(stderr,
+ "failed to allocate memory for domain: %s", cp);
+ return (ISC_R_NOMEMORY);
+ }
+
+ /* Start getting NS for the domain */
+ domainlen = strlen(buf);
+ isc_buffer_init(&b, buf, domainlen);
+ isc_buffer_add(&b, domainlen);
+ dns_fixedname_init(&trans->fixedname);
+ trans->qname = dns_fixedname_name(&trans->fixedname);
+ result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_client_startresolve(client, trans->qname,
+ dns_rdataclass_in, dns_rdatatype_ns,
+ 0, probe_task, resolve_ns, trans,
+ &trans->resid);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ trans->inuse = ISC_TRUE;
+ outstanding_probes++;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_mem_free(mctx, trans->domain);
+ dns_fixedname_invalidate(&trans->fixedname);
+
+ return (result);
+}
+
+static void
+usage() {
+ fprintf(stderr, "usage: nsprobe [-d] [-v [-v...]] [-c cache_address] "
+ "[input_file]\n");
+
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ int i, ch, error;
+ struct addrinfo hints, *res;
+ isc_result_t result;
+ isc_sockaddr_t sa;
+ isc_sockaddrlist_t servers;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+
+ while ((ch = getopt(argc, argv, "c:dhv")) != -1) {
+ switch (ch) {
+ case 'c':
+ cacheserver = optarg;
+ break;
+ case 'd':
+ debug_mode = ISC_TRUE;
+ break;
+ case 'h':
+ usage();
+ break;
+ case 'v':
+ verbose_level++;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* Common set up */
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr,
+ &timermgr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "ctx create failed: %d\n", result);
+ exit(1);
+ }
+
+ isc_app_ctxstart(actx);
+
+ result = dns_client_createx(mctx, actx, taskmgr, socketmgr,
+ timermgr, 0, &client);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_createx failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set local cache server */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ error = getaddrinfo(cacheserver, "53", &hints, &res);
+ if (error != 0) {
+ fprintf(stderr, "failed to convert server name (%s): %s\n",
+ cacheserver, gai_strerror(error));
+ exit(1);
+ }
+
+ if (res->ai_addrlen > sizeof(sa.type)) {
+ fprintf(stderr,
+ "assumption failure: addrlen is too long: %d\n",
+ res->ai_addrlen);
+ exit(1);
+ }
+ memcpy(&sa.type.sa, res->ai_addr, res->ai_addrlen);
+ sa.length = res->ai_addrlen;
+ freeaddrinfo(res);
+ ISC_LINK_INIT(&sa, link);
+ ISC_LIST_INIT(servers);
+ ISC_LIST_APPEND(servers, &sa, link);
+ result = dns_client_setservers(client, dns_rdataclass_in, NULL,
+ &servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to set server: %d\n", result);
+ exit(1);
+ }
+
+ /* Create the main task */
+ probe_task = NULL;
+ result = isc_task_create(taskmgr, 0, &probe_task);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create task: %d\n", result);
+ exit(1);
+ }
+
+ /* Open input file */
+ if (argc == 0)
+ fp = stdin;
+ else {
+ fp = fopen(argv[0], "r");
+ if (fp == NULL) {
+ fprintf(stderr, "failed to open input file: %s\n",
+ argv[0]);
+ exit(1);
+ }
+ }
+
+ /* Set up and start probe */
+ for (i = 0; i < MAX_PROBES; i++) {
+ probes[i].inuse = ISC_FALSE;
+ probes[i].domain = NULL;
+ dns_fixedname_init(&probes[i].fixedname);
+ probes[i].qname = NULL;
+ probes[i].qlabel = qlabels;
+ probes[i].qname_found = ISC_FALSE;
+ probes[i].resid = NULL;
+ ISC_LIST_INIT(probes[i].nslist);
+ probes[i].reqid = NULL;
+
+ probes[i].qmessage = NULL;
+ result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
+ &probes[i].qmessage);
+ if (result == ISC_R_SUCCESS) {
+ result = dns_message_create(mctx,
+ DNS_MESSAGE_INTENTPARSE,
+ &probes[i].rmessage);
+ }
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "initialization failure\n");
+ exit(1);
+ }
+ }
+ for (i = 0; i < MAX_PROBES; i++) {
+ result = probe_domain(&probes[i]);
+ if (result == ISC_R_NOMORE)
+ break;
+ else if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to issue an initial probe\n");
+ exit(1);
+ }
+ }
+
+ /* Start event loop */
+ isc_app_ctxrun(actx);
+
+ /* Dump results */
+ printf("Per domain results (out of %lu domains):\n",
+ number_of_domains);
+ printf(" valid: %lu\n"
+ " ignore: %lu\n"
+ " nxdomain: %lu\n"
+ " othererr: %lu\n"
+ " multiplesoa: %lu\n"
+ " multiplecname: %lu\n"
+ " brokenanswer: %lu\n"
+ " lame: %lu\n"
+ " unknown: %lu\n"
+ " multiple errors: %lu\n",
+ domain_stat.valid, domain_stat.ignore, domain_stat.nxdomain,
+ domain_stat.othererr, domain_stat.multiplesoa,
+ domain_stat.multiplecname, domain_stat.brokenanswer,
+ domain_stat.lame, domain_stat.unknown, multiple_error_domains);
+ printf("Per server results (out of %lu servers):\n",
+ number_of_servers);
+ printf(" valid: %lu\n"
+ " ignore: %lu\n"
+ " nxdomain: %lu\n"
+ " othererr: %lu\n"
+ " multiplesoa: %lu\n"
+ " multiplecname: %lu\n"
+ " brokenanswer: %lu\n"
+ " lame: %lu\n"
+ " unknown: %lu\n",
+ server_stat.valid, server_stat.ignore, server_stat.nxdomain,
+ server_stat.othererr, server_stat.multiplesoa,
+ server_stat.multiplecname, server_stat.brokenanswer,
+ server_stat.lame, server_stat.unknown);
+
+ /* Cleanup */
+ for (i = 0; i < MAX_PROBES; i++) {
+ dns_message_destroy(&probes[i].qmessage);
+ dns_message_destroy(&probes[i].rmessage);
+ }
+ isc_task_detach(&probe_task);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+ isc_app_ctxfinish(actx);
+ ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-async.c b/lib/export/samples/sample-async.c
new file mode 100644
index 00000000..014b6a65
--- /dev/null
+++ b/lib/export/samples/sample-async.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: sample-async.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/socket.h>
+#include <isc/sockaddr.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdataset.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#define MAX_SERVERS 10
+#define MAX_QUERIES 100
+
+static dns_client_t *client = NULL;
+static isc_task_t *query_task = NULL;
+static isc_appctx_t *query_actx = NULL;
+static unsigned int outstanding_queries = 0;
+static const char *def_server = "127.0.0.1";
+static FILE *fp;
+
+struct query_trans {
+ int id;
+ isc_boolean_t inuse;
+ dns_rdatatype_t type;
+ dns_fixedname_t fixedname;
+ dns_name_t *qname;
+ dns_namelist_t answerlist;
+ dns_clientrestrans_t *xid;
+};
+
+static struct query_trans query_array[MAX_QUERIES];
+
+static isc_result_t dispatch_query(struct query_trans *trans);
+
+static void
+ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ if (*taskmgrp != NULL)
+ isc_taskmgr_destroy(taskmgrp);
+
+ if (*timermgrp != NULL)
+ isc_timermgr_destroy(timermgrp);
+
+ if (*socketmgrp != NULL)
+ isc_socketmgr_destroy(socketmgrp);
+
+ if (*actxp != NULL)
+ isc_appctx_destroy(actxp);
+
+ if (*mctxp != NULL)
+ isc_mem_destroy(mctxp);
+}
+
+static isc_result_t
+ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ isc_result_t result;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_appctx_create(*mctxp, actxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
+
+ return (result);
+}
+
+static isc_result_t
+printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
+ isc_buffer_t target;
+ isc_result_t result;
+ isc_region_t r;
+ char t[4096];
+
+ isc_buffer_init(&target, t, sizeof(t));
+
+ if (!dns_rdataset_isassociated(rdataset))
+ return (ISC_R_SUCCESS);
+ result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
+ &target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&target, &r);
+ printf(" %.*s", (int)r.length, (char *)r.base);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+process_answer(isc_task_t *task, isc_event_t *event) {
+ struct query_trans *trans = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ isc_result_t result;
+
+ REQUIRE(task == query_task);
+ REQUIRE(trans->inuse == ISC_TRUE);
+ REQUIRE(outstanding_queries > 0);
+
+ printf("answer[%2d]\n", trans->id);
+
+ if (rev->result != ISC_R_SUCCESS)
+ printf(" failed: %d(%s)\n", rev->result,
+ dns_result_totext(rev->result));
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ (void)printdata(rdataset, name);
+ }
+ }
+
+ dns_client_freeresanswer(client, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->xid);
+
+ isc_event_free(&event);
+
+ trans->inuse = ISC_FALSE;
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ outstanding_queries--;
+
+ result = dispatch_query(trans);
+#if 0 /* for cancel test */
+ if (result == ISC_R_SUCCESS) {
+ static int count = 0;
+
+ if ((++count) % 10 == 0)
+ dns_client_cancelresolve(trans->xid);
+ }
+#endif
+ if (result == ISC_R_NOMORE && outstanding_queries == 0)
+ isc_app_ctxshutdown(query_actx);
+}
+
+static isc_result_t
+dispatch_query(struct query_trans *trans) {
+ isc_result_t result;
+ size_t namelen;
+ isc_buffer_t b;
+ char buf[4096]; /* XXX ad hoc constant, but should be enough */
+ char *cp;
+
+ REQUIRE(trans != NULL);
+ REQUIRE(trans->inuse == ISC_FALSE);
+ REQUIRE(ISC_LIST_EMPTY(trans->answerlist));
+ REQUIRE(outstanding_queries < MAX_QUERIES);
+
+ /* Construct qname */
+ cp = fgets(buf, sizeof(buf), fp);
+ if (cp == NULL)
+ return (ISC_R_NOMORE);
+ /* zap NL if any */
+ if ((cp = strchr(buf, '\n')) != NULL)
+ *cp = '\0';
+ namelen = strlen(buf);
+ isc_buffer_init(&b, buf, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&trans->fixedname);
+ trans->qname = dns_fixedname_name(&trans->fixedname);
+ result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Start resolution */
+ result = dns_client_startresolve(client, trans->qname,
+ dns_rdataclass_in, trans->type, 0,
+ query_task, process_answer, trans,
+ &trans->xid);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ trans->inuse = ISC_TRUE;
+ outstanding_queries++;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ dns_fixedname_invalidate(&trans->fixedname);
+
+ return (result);
+}
+
+static void
+usage() {
+ fprintf(stderr, "usage: sample-async [-s server_address] [-t RR type] "
+ "input_file\n");
+
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch;
+ isc_textregion_t tr;
+ isc_mem_t *mctx = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+ int nservers = 0;
+ const char *serveraddr[MAX_SERVERS];
+ isc_sockaddr_t sa[MAX_SERVERS];
+ isc_sockaddrlist_t servers;
+ dns_rdatatype_t type = dns_rdatatype_a;
+ struct in_addr inaddr;
+ isc_result_t result;
+ int i;
+
+ while ((ch = getopt(argc, argv, "s:t:")) != -1) {
+ switch (ch) {
+ case 't':
+ tr.base = optarg;
+ tr.length = strlen(optarg);
+ result = dns_rdatatype_fromtext(&type, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "invalid RRtype: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ case 's':
+ if (nservers == MAX_SERVERS) {
+ fprintf(stderr,
+ "too many servers (up to %d)\n",
+ MAX_SERVERS);
+ exit(1);
+ }
+ serveraddr[nservers++] = (const char *)optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 1)
+ usage();
+
+ if (nservers == 0) {
+ nservers = 1;
+ serveraddr[0] = def_server;
+ }
+
+ for (i = 0; i < MAX_QUERIES; i++) {
+ query_array[i].id = i;
+ query_array[i].inuse = ISC_FALSE;
+ query_array[i].type = type;
+ dns_fixedname_init(&query_array[i].fixedname);
+ query_array[i].qname = NULL;
+ ISC_LIST_INIT(query_array[i].answerlist);
+ query_array[i].xid = NULL;
+ }
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ result = ctxs_init(&mctx, &query_actx, &taskmgr, &socketmgr,
+ &timermgr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "ctx create failed: %d\n", result);
+ exit(1);
+ }
+
+ isc_app_ctxstart(query_actx);
+
+ result = dns_client_createx(mctx, query_actx, taskmgr, socketmgr,
+ timermgr, 0, &client);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_createx failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set nameservers */
+ ISC_LIST_INIT(servers);
+ for (i = 0; i < nservers; i++) {
+ if (inet_pton(AF_INET, serveraddr[i], &inaddr) != 1) {
+ fprintf(stderr, "failed to parse IPv4 address %s\n",
+ serveraddr[i]);
+ exit(1);
+ }
+ isc_sockaddr_fromin(&sa[i], &inaddr, 53);
+ ISC_LIST_APPEND(servers, &sa[i], link);
+ }
+ result = dns_client_setservers(client, dns_rdataclass_in, NULL,
+ &servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "set server failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Create the main task */
+ query_task = NULL;
+ result = isc_task_create(taskmgr, 0, &query_task);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create task: %d\n", result);
+ exit(1);
+ }
+
+ /* Open input file */
+ fp = fopen(argv[0], "r");
+ if (fp == NULL) {
+ fprintf(stderr, "failed to open input file: %s\n", argv[1]);
+ exit(1);
+ }
+
+ /* Dispatch initial queries */
+ for (i = 0; i < MAX_QUERIES; i++) {
+ result = dispatch_query(&query_array[i]);
+ if (result == ISC_R_NOMORE)
+ break;
+ }
+
+ /* Start event loop */
+ isc_app_ctxrun(query_actx);
+
+ /* Sanity check */
+ for (i = 0; i < MAX_QUERIES; i++)
+ INSIST(query_array[i].inuse == ISC_FALSE);
+
+ /* Cleanup */
+ isc_task_detach(&query_task);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+ isc_app_ctxfinish(query_actx);
+ ctxs_destroy(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr);
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-gai.c b/lib/export/samples/sample-gai.c
new file mode 100644
index 00000000..6dc4014e
--- /dev/null
+++ b/lib/export/samples/sample-gai.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: sample-gai.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <irs/netdb.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static void
+do_gai(int family, char *hostname) {
+ struct addrinfo hints, *res, *res0;
+ int error;
+ char namebuf[1024], addrbuf[1024], servbuf[1024];
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+ error = getaddrinfo(hostname, "http", &hints, &res0);
+ if (error) {
+ fprintf(stderr, "getaddrinfo failed for %s,family=%d: %s\n",
+ hostname, family, gai_strerror(error));
+ return;
+ }
+
+ for (res = res0; res; res = res->ai_next) {
+ error = getnameinfo(res->ai_addr, res->ai_addrlen,
+ addrbuf, sizeof(addrbuf),
+ NULL, 0, NI_NUMERICHOST);
+ if (error == 0)
+ error = getnameinfo(res->ai_addr, res->ai_addrlen,
+ namebuf, sizeof(namebuf),
+ servbuf, sizeof(servbuf), 0);
+ if (error != 0) {
+ fprintf(stderr, "getnameinfo failed: %s\n",
+ gai_strerror(error));
+ } else {
+ printf("%s(%s/%s)=%s:%s\n", hostname,
+ res->ai_canonname, addrbuf, namebuf, servbuf);
+ }
+ }
+
+ freeaddrinfo(res);
+}
+
+int
+main(int argc, char *argv[]) {
+ if (argc < 2)
+ exit(1);
+
+ do_gai(AF_INET, argv[1]);
+ do_gai(AF_INET6, argv[1]);
+ do_gai(AF_UNSPEC, argv[1]);
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-request.c b/lib/export/samples/sample-request.c
new file mode 100644
index 00000000..4d7d2fc9
--- /dev/null
+++ b/lib/export/samples/sample-request.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: sample-request.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/lib.h>
+#include <dns/masterdump.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+
+#include <dst/dst.h>
+
+static isc_mem_t *mctx;
+static dns_fixedname_t fixedqname;
+
+static void
+usage() {
+ fprintf(stderr, "sample-request [-t RRtype] server_address hostname\n");
+
+ exit(1);
+}
+
+static isc_result_t
+make_querymessage(dns_message_t *message, const char *namestr,
+ dns_rdatatype_t rdtype)
+{
+ dns_name_t *qname = NULL, *qname0;
+ dns_rdataset_t *qrdataset = NULL;
+ isc_result_t result;
+ isc_buffer_t b;
+ size_t namelen;
+
+ /* Construct qname */
+ namelen = strlen(namestr);
+ isc_buffer_init(&b, namestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fixedqname);
+ qname0 = dns_fixedname_name(&fixedqname);
+ result = dns_name_fromtext(qname0, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to convert qname: %d\n", result);
+ return (result);
+ }
+
+ /* Construct query message */
+ message->opcode = dns_opcode_query;
+ message->rdclass = dns_rdataclass_in;
+
+ result = dns_message_gettempname(message, &qname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_message_gettemprdataset(message, &qrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_name_init(qname, NULL);
+ dns_name_clone(qname0, qname);
+ dns_rdataset_init(qrdataset);
+ dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
+ ISC_LIST_APPEND(qname->list, qrdataset, link);
+ dns_message_addname(message, qname, DNS_SECTION_QUESTION);
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (qname != NULL)
+ dns_message_puttempname(message, &qname);
+ if (qrdataset != NULL)
+ dns_message_puttemprdataset(message, &qrdataset);
+ if (message != NULL)
+ dns_message_destroy(&message);
+ return (result);
+}
+
+static void
+print_section(dns_message_t *message, int section, isc_buffer_t *buf) {
+ isc_result_t result;
+ isc_region_t r;
+
+ result = dns_message_sectiontotext(message, section,
+ &dns_master_style_full, 0, buf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ isc_buffer_usedregion(buf, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+
+ return;
+
+ fail:
+ fprintf(stderr, "failed to convert a section\n");
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch, i, gai_error;
+ struct addrinfo hints, *res;
+ isc_textregion_t tr;
+ dns_client_t *client = NULL;
+ isc_result_t result;
+ isc_sockaddr_t sa;
+ dns_message_t *qmessage, *rmessage;
+ dns_rdatatype_t type = dns_rdatatype_a;
+ isc_buffer_t *outputbuf;
+
+ while ((ch = getopt(argc, argv, "t:")) != -1) {
+ switch (ch) {
+ case 't':
+ tr.base = optarg;
+ tr.length = strlen(optarg);
+ result = dns_rdatatype_fromtext(&type, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "invalid RRtype: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ result = dns_client_create(&client, 0);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_create failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Prepare message structures */
+ mctx = NULL;
+ qmessage = NULL;
+ rmessage = NULL;
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create a memory context\n");
+ exit(1);
+ }
+ result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &qmessage);
+ if (result == ISC_R_SUCCESS) {
+ result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
+ &rmessage);
+ }
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create messages\n");
+ exit(1);
+ }
+
+ /* Initialize the nameserver address */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(argv[0], "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa.type));
+ memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa, link);
+
+ /* Construct qname */
+ result = make_querymessage(qmessage, argv[1], type);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create a query\n");
+ exit(1);
+ }
+
+ /* Send request and wait for a response */
+ result = dns_client_request(client, qmessage, rmessage, &sa, 0, 0,
+ NULL, 60, 0, 3);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to get a response: %s\n",
+ dns_result_totext(result));
+ }
+
+ /* Dump the response */
+ outputbuf = NULL;
+ result = isc_buffer_allocate(mctx, &outputbuf, 65535);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to allocate a result buffer\n");
+ exit(1);
+ }
+ for (i = 0; i < DNS_SECTION_MAX; i++) {
+ print_section(rmessage, i, outputbuf);
+ isc_buffer_clear(outputbuf);
+ }
+ isc_buffer_free(&outputbuf);
+
+ /* Cleanup */
+ dns_message_destroy(&qmessage);
+ dns_message_destroy(&rmessage);
+ isc_mem_destroy(&mctx);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-update.c b/lib/export/samples/sample-update.c
new file mode 100644
index 00000000..c614e77c
--- /dev/null
+++ b/lib/export/samples/sample-update.c
@@ -0,0 +1,751 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: sample-update.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/parseint.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/callbacks.h>
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+#include <dns/tsec.h>
+
+#include <dst/dst.h>
+
+static dns_tsec_t *tsec = NULL;
+static const dns_rdataclass_t default_rdataclass = dns_rdataclass_in;
+static isc_bufferlist_t usedbuffers;
+static ISC_LIST(dns_rdatalist_t) usedrdatalists;
+
+static void setup_tsec(char *keyfile, isc_mem_t *mctx);
+static void update_addordelete(isc_mem_t *mctx, char *cmdline,
+ isc_boolean_t isdelete, dns_name_t *name);
+static void evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name);
+
+static void
+usage() {
+ fprintf(stderr, "sample-update "
+ "[-a auth_server] "
+ "[-k keyfile] "
+ "[-p prerequisite] "
+ "[-r recursive_server] "
+ "[-z zonename] "
+ "(add|delete) \"name TTL RRtype RDATA\"\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch;
+ struct addrinfo hints, *res;
+ int gai_error;
+ dns_client_t *client = NULL;
+ char *zonenamestr = NULL;
+ char *keyfilename = NULL;
+ char *prereqstr = NULL;
+ isc_sockaddrlist_t auth_servers;
+ char *auth_server = NULL;
+ char *recursive_server = NULL;
+ isc_sockaddr_t sa_auth, sa_recursive;
+ isc_sockaddrlist_t rec_servers;
+ isc_result_t result;
+ isc_boolean_t isdelete;
+ isc_buffer_t b, *buf;
+ dns_fixedname_t zname0, pname0, uname0;
+ size_t namelen;
+ dns_name_t *zname = NULL, *uname, *pname;
+ dns_rdataset_t *rdataset;
+ dns_rdatalist_t *rdatalist;
+ dns_rdata_t *rdata;
+ dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
+ isc_mem_t *umctx = NULL;
+
+ while ((ch = getopt(argc, argv, "a:k:p:r:z:")) != -1) {
+ switch (ch) {
+ case 'k':
+ keyfilename = optarg;
+ break;
+ case 'a':
+ auth_server = optarg;
+ break;
+ case 'p':
+ prereqstr = optarg;
+ break;
+ case 'r':
+ recursive_server = optarg;
+ break;
+ case 'z':
+ zonenamestr = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ /* command line argument validation */
+ if (strcmp(argv[0], "delete") == 0)
+ isdelete = ISC_TRUE;
+ else if (strcmp(argv[0], "add") == 0)
+ isdelete = ISC_FALSE;
+ else {
+ fprintf(stderr, "invalid update command: %s\n", argv[0]);
+ exit(1);
+ }
+
+ if (auth_server == NULL && recursive_server == NULL) {
+ fprintf(stderr, "authoritative or recursive server "
+ "must be specified\n");
+ usage();
+ }
+
+ /* Initialization */
+ ISC_LIST_INIT(usedbuffers);
+ ISC_LIST_INIT(usedrdatalists);
+ ISC_LIST_INIT(prereqlist);
+ ISC_LIST_INIT(auth_servers);
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+ result = isc_mem_create(0, 0, &umctx);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to crate mctx\n");
+ exit(1);
+ }
+
+ result = dns_client_create(&client, 0);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_create failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set the authoritative server */
+ if (auth_server != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(auth_server, "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa_auth.type));
+ memcpy(&sa_auth.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa_auth.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa_auth, link);
+
+ ISC_LIST_APPEND(auth_servers, &sa_auth, link);
+ }
+
+ /* Set the recursive server */
+ if (recursive_server != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(recursive_server, "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa_recursive.type));
+ memcpy(&sa_recursive.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa_recursive.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa_recursive, link);
+ ISC_LIST_INIT(rec_servers);
+ ISC_LIST_APPEND(rec_servers, &sa_recursive, link);
+ result = dns_client_setservers(client, dns_rdataclass_in,
+ NULL, &rec_servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "set server failed: %d\n", result);
+ exit(1);
+ }
+ }
+
+ /* Construct zone name */
+ zname = NULL;
+ if (zonenamestr != NULL) {
+ namelen = strlen(zonenamestr);
+ isc_buffer_init(&b, zonenamestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&zname0);
+ zname = dns_fixedname_name(&zname0);
+ result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "failed to convert zone name: %d\n",
+ result);
+ }
+
+ /* Construct prerequisite name (if given) */
+ if (prereqstr != NULL) {
+ dns_fixedname_init(&pname0);
+ pname = dns_fixedname_name(&pname0);
+ evaluate_prereq(umctx, prereqstr, pname);
+ ISC_LIST_APPEND(prereqlist, pname, link);
+ prereqlistp = &prereqlist;
+ }
+
+ /* Construct update name */
+ ISC_LIST_INIT(updatelist);
+ dns_fixedname_init(&uname0);
+ uname = dns_fixedname_name(&uname0);
+ update_addordelete(umctx, argv[1], isdelete, uname);
+ ISC_LIST_APPEND(updatelist, uname, link);
+
+ /* Set up TSIG/SIG(0) key (if given) */
+ if (keyfilename != NULL)
+ setup_tsec(keyfilename, umctx);
+
+ /* Perform update */
+ result = dns_client_update(client,
+ default_rdataclass, /* XXX: fixed */
+ zname, prereqlistp, &updatelist,
+ (auth_server == NULL) ? NULL :
+ &auth_servers, tsec, 0);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "update failed: %s\n", dns_result_totext(result));
+ } else
+ fprintf(stderr, "update succeeded\n");
+
+ /* Cleanup */
+ while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) {
+ while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) {
+ ISC_LIST_UNLINK(pname->list, rdataset, link);
+ dns_rdataset_disassociate(rdataset);
+ isc_mem_put(umctx, rdataset, sizeof(*rdataset));
+ }
+ ISC_LIST_UNLINK(prereqlist, pname, link);
+ }
+ while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) {
+ while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) {
+ ISC_LIST_UNLINK(uname->list, rdataset, link);
+ dns_rdataset_disassociate(rdataset);
+ isc_mem_put(umctx, rdataset, sizeof(*rdataset));
+ }
+ ISC_LIST_UNLINK(updatelist, uname, link);
+ }
+ while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) {
+ while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) {
+ ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
+ isc_mem_put(umctx, rdata, sizeof(*rdata));
+ }
+ ISC_LIST_UNLINK(usedrdatalists, rdatalist, link);
+ isc_mem_put(umctx, rdatalist, sizeof(*rdatalist));
+ }
+ while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) {
+ ISC_LIST_UNLINK(usedbuffers, buf, link);
+ isc_buffer_free(&buf);
+ }
+ if (tsec != NULL)
+ dns_tsec_destroy(&tsec);
+ isc_mem_destroy(&umctx);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+
+ exit(0);
+}
+
+/*
+ * Subroutines borrowed from nsupdate.c
+ */
+#define MAXWIRE (64 * 1024)
+#define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */
+
+static char *
+nsu_strsep(char **stringp, const char *delim) {
+ char *string = *stringp;
+ char *s;
+ const char *d;
+ char sc, dc;
+
+ if (string == NULL)
+ return (NULL);
+
+ for (; *string != '\0'; string++) {
+ sc = *string;
+ for (d = delim; (dc = *d) != '\0'; d++) {
+ if (sc == dc)
+ break;
+ }
+ if (dc == 0)
+ break;
+ }
+
+ for (s = string; *s != '\0'; s++) {
+ sc = *s;
+ for (d = delim; (dc = *d) != '\0'; d++) {
+ if (sc == dc) {
+ *s++ = '\0';
+ *stringp = s;
+ return (string);
+ }
+ }
+ }
+ *stringp = NULL;
+ return (string);
+}
+
+static void
+fatal(const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+static inline void
+check_result(isc_result_t result, const char *msg) {
+ if (result != ISC_R_SUCCESS)
+ fatal("%s: %s", msg, isc_result_totext(result));
+}
+
+static void
+parse_name(char **cmdlinep, dns_name_t *name) {
+ isc_result_t result;
+ char *word;
+ isc_buffer_t source;
+
+ word = nsu_strsep(cmdlinep, " \t\r\n");
+ if (*word == 0) {
+ fprintf(stderr, "could not read owner name\n");
+ exit(1);
+ }
+
+ isc_buffer_init(&source, word, strlen(word));
+ isc_buffer_add(&source, strlen(word));
+ result = dns_name_fromtext(name, &source, dns_rootname, 0, NULL);
+ check_result(result, "dns_name_fromtext");
+ isc_buffer_invalidate(&source);
+}
+
+static void
+parse_rdata(isc_mem_t *mctx, char **cmdlinep, dns_rdataclass_t rdataclass,
+ dns_rdatatype_t rdatatype, dns_rdata_t *rdata)
+{
+ char *cmdline = *cmdlinep;
+ isc_buffer_t source, *buf = NULL, *newbuf = NULL;
+ isc_region_t r;
+ isc_lex_t *lex = NULL;
+ dns_rdatacallbacks_t callbacks;
+ isc_result_t result;
+
+ while (cmdline != NULL && *cmdline != 0 &&
+ isspace((unsigned char)*cmdline))
+ cmdline++;
+
+ if (cmdline != NULL && *cmdline != 0) {
+ dns_rdatacallbacks_init(&callbacks);
+ result = isc_lex_create(mctx, strlen(cmdline), &lex);
+ check_result(result, "isc_lex_create");
+ isc_buffer_init(&source, cmdline, strlen(cmdline));
+ isc_buffer_add(&source, strlen(cmdline));
+ result = isc_lex_openbuffer(lex, &source);
+ check_result(result, "isc_lex_openbuffer");
+ result = isc_buffer_allocate(mctx, &buf, MAXWIRE);
+ check_result(result, "isc_buffer_allocate");
+ result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex,
+ dns_rootname, 0, mctx, buf,
+ &callbacks);
+ isc_lex_destroy(&lex);
+ if (result == ISC_R_SUCCESS) {
+ isc_buffer_usedregion(buf, &r);
+ result = isc_buffer_allocate(mctx, &newbuf, r.length);
+ check_result(result, "isc_buffer_allocate");
+ isc_buffer_putmem(newbuf, r.base, r.length);
+ isc_buffer_usedregion(newbuf, &r);
+ dns_rdata_reset(rdata);
+ dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r);
+ isc_buffer_free(&buf);
+ ISC_LIST_APPEND(usedbuffers, newbuf, link);
+ } else {
+ fprintf(stderr, "invalid rdata format: %s\n",
+ isc_result_totext(result));
+ isc_buffer_free(&buf);
+ exit(1);
+ }
+ } else {
+ rdata->flags = DNS_RDATA_UPDATE;
+ }
+ *cmdlinep = cmdline;
+}
+
+static void
+update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete,
+ dns_name_t *name)
+{
+ isc_result_t result;
+ isc_uint32_t ttl;
+ char *word;
+ dns_rdataclass_t rdataclass;
+ dns_rdatatype_t rdatatype;
+ dns_rdata_t *rdata = NULL;
+ dns_rdatalist_t *rdatalist = NULL;
+ dns_rdataset_t *rdataset = NULL;
+ isc_textregion_t region;
+
+ /*
+ * Read the owner name.
+ */
+ parse_name(&cmdline, name);
+
+ rdata = isc_mem_get(mctx, sizeof(*rdata));
+ if (rdata == NULL) {
+ fprintf(stderr, "memory allocation for rdata failed\n");
+ exit(1);
+ }
+ dns_rdata_init(rdata);
+
+ /*
+ * If this is an add, read the TTL and verify that it's in range.
+ * If it's a delete, ignore a TTL if present (for compatibility).
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ if (!isdelete) {
+ fprintf(stderr, "could not read owner ttl\n");
+ exit(1);
+ }
+ else {
+ ttl = 0;
+ rdataclass = dns_rdataclass_any;
+ rdatatype = dns_rdatatype_any;
+ rdata->flags = DNS_RDATA_UPDATE;
+ goto doneparsing;
+ }
+ }
+ result = isc_parse_uint32(&ttl, word, 10);
+ if (result != ISC_R_SUCCESS) {
+ if (isdelete) {
+ ttl = 0;
+ goto parseclass;
+ } else {
+ fprintf(stderr, "ttl '%s': %s\n", word,
+ isc_result_totext(result));
+ exit(1);
+ }
+ }
+
+ if (isdelete)
+ ttl = 0;
+ else if (ttl > TTL_MAX) {
+ fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n",
+ word, TTL_MAX);
+ exit(1);
+ }
+
+ /*
+ * Read the class or type.
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ parseclass:
+ if (word == NULL || *word == 0) {
+ if (isdelete) {
+ rdataclass = dns_rdataclass_any;
+ rdatatype = dns_rdatatype_any;
+ rdata->flags = DNS_RDATA_UPDATE;
+ goto doneparsing;
+ } else {
+ fprintf(stderr, "could not read class or type\n");
+ exit(1);
+ }
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdataclass_fromtext(&rdataclass, &region);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Now read the type.
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ if (isdelete) {
+ rdataclass = dns_rdataclass_any;
+ rdatatype = dns_rdatatype_any;
+ rdata->flags = DNS_RDATA_UPDATE;
+ goto doneparsing;
+ } else {
+ fprintf(stderr, "could not read type\n");
+ exit(1);
+ }
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "'%s' is not a valid type: %s\n",
+ word, isc_result_totext(result));
+ exit(1);
+ }
+ } else {
+ rdataclass = default_rdataclass;
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "'%s' is not a valid class or type: "
+ "%s\n", word, isc_result_totext(result));
+ exit(1);
+ }
+ }
+
+ parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);
+
+ if (isdelete) {
+ if ((rdata->flags & DNS_RDATA_UPDATE) != 0)
+ rdataclass = dns_rdataclass_any;
+ else
+ rdataclass = dns_rdataclass_none;
+ } else {
+ if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
+ fprintf(stderr, "could not read rdata\n");
+ exit(1);
+ }
+ }
+
+ doneparsing:
+
+ rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
+ if (rdatalist == NULL) {
+ fprintf(stderr, "memory allocation for rdatalist failed\n");
+ exit(1);
+ }
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = rdatatype;
+ rdatalist->rdclass = rdataclass;
+ rdatalist->covers = rdatatype;
+ rdatalist->ttl = (dns_ttl_t)ttl;
+ ISC_LIST_INIT(rdatalist->rdata);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
+
+ rdataset = isc_mem_get(mctx, sizeof(*rdataset));
+ if (rdataset == NULL) {
+ fprintf(stderr, "memory allocation for rdataset failed\n");
+ exit(1);
+ }
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
+ ISC_LIST_INIT(name->list);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+}
+
+static void
+make_prereq(isc_mem_t *mctx, char *cmdline, isc_boolean_t ispositive,
+ isc_boolean_t isrrset, dns_name_t *name)
+{
+ isc_result_t result;
+ char *word;
+ isc_textregion_t region;
+ dns_rdataset_t *rdataset = NULL;
+ dns_rdatalist_t *rdatalist = NULL;
+ dns_rdataclass_t rdataclass;
+ dns_rdatatype_t rdatatype;
+ dns_rdata_t *rdata = NULL;
+
+ /*
+ * Read the owner name
+ */
+ parse_name(&cmdline, name);
+
+ /*
+ * If this is an rrset prereq, read the class or type.
+ */
+ if (isrrset) {
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ fprintf(stderr, "could not read class or type\n");
+ exit(1);
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdataclass_fromtext(&rdataclass, &region);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Now read the type.
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ fprintf(stderr, "could not read type\n");
+ exit(1);
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "invalid type: %s\n", word);
+ exit(1);
+ }
+ } else {
+ rdataclass = default_rdataclass;
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "invalid type: %s\n", word);
+ exit(1);
+ }
+ }
+ } else
+ rdatatype = dns_rdatatype_any;
+
+ rdata = isc_mem_get(mctx, sizeof(*rdata));
+ if (rdata == NULL) {
+ fprintf(stderr, "memory allocation for rdata failed\n");
+ exit(1);
+ }
+ dns_rdata_init(rdata);
+
+ if (isrrset && ispositive)
+ parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);
+ else
+ rdata->flags = DNS_RDATA_UPDATE;
+
+ rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
+ if (rdatalist == NULL) {
+ fprintf(stderr, "memory allocation for rdatalist failed\n");
+ exit(1);
+ }
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = rdatatype;
+ if (ispositive) {
+ if (isrrset && rdata->data != NULL)
+ rdatalist->rdclass = rdataclass;
+ else
+ rdatalist->rdclass = dns_rdataclass_any;
+ } else
+ rdatalist->rdclass = dns_rdataclass_none;
+ rdatalist->covers = 0;
+ rdatalist->ttl = 0;
+ rdata->rdclass = rdatalist->rdclass;
+ rdata->type = rdatatype;
+ ISC_LIST_INIT(rdatalist->rdata);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
+
+ rdataset = isc_mem_get(mctx, sizeof(*rdataset));
+ if (rdataset == NULL) {
+ fprintf(stderr, "memory allocation for rdataset failed\n");
+ exit(1);
+ }
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
+ ISC_LIST_INIT(name->list);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+}
+
+static void
+evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name) {
+ char *word;
+ isc_boolean_t ispositive, isrrset;
+
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ fprintf(stderr, "could not read operation code\n");
+ exit(1);
+ }
+ if (strcasecmp(word, "nxdomain") == 0) {
+ ispositive = ISC_FALSE;
+ isrrset = ISC_FALSE;
+ } else if (strcasecmp(word, "yxdomain") == 0) {
+ ispositive = ISC_TRUE;
+ isrrset = ISC_FALSE;
+ } else if (strcasecmp(word, "nxrrset") == 0) {
+ ispositive = ISC_FALSE;
+ isrrset = ISC_TRUE;
+ } else if (strcasecmp(word, "yxrrset") == 0) {
+ ispositive = ISC_TRUE;
+ isrrset = ISC_TRUE;
+ } else {
+ fprintf(stderr, "incorrect operation code: %s\n", word);
+ exit(1);
+ }
+
+ make_prereq(mctx, cmdline, ispositive, isrrset, name);
+}
+
+static void
+setup_tsec(char *keyfile, isc_mem_t *mctx) {
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+ dns_tsectype_t tsectype;
+
+ result = dst_key_fromnamedfile(keyfile, NULL,
+ DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "could not read key from %s: %s\n",
+ keyfile, isc_result_totext(result));
+ exit(1);
+ }
+
+ if (dst_key_alg(dstkey) == DST_ALG_HMACMD5)
+ tsectype = dns_tsectype_tsig;
+ else
+ tsectype = dns_tsectype_sig0;
+
+ result = dns_tsec_create(mctx, tsectype, dstkey, &tsec);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "could not create tsec: %s\n",
+ isc_result_totext(result));
+ exit(1);
+ }
+}
diff --git a/lib/export/samples/sample.c b/lib/export/samples/sample.c
new file mode 100644
index 00000000..f547e893
--- /dev/null
+++ b/lib/export/samples/sample.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: sample.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+
+#include <dst/dst.h>
+
+static char *algname;
+
+static isc_result_t
+printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
+ isc_buffer_t target;
+ isc_result_t result;
+ isc_region_t r;
+ char t[4096];
+
+ if (!dns_rdataset_isassociated(rdataset)) {
+ printf("[WARN: empty]\n");
+ return (ISC_R_SUCCESS);
+ }
+
+ isc_buffer_init(&target, t, sizeof(t));
+
+ result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
+ &target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&target, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+usage() {
+ fprintf(stderr, "sample [-t RRtype] "
+ "[[-a algorithm] [-e] -k keyname -K keystring] "
+ "[-s domain:serveraddr_for_domain ] "
+ "server_address hostname\n");
+
+ exit(1);
+}
+
+static void
+set_key(dns_client_t *client, char *keynamestr, char *keystr,
+ isc_boolean_t is_sep, isc_mem_t **mctxp)
+{
+ isc_result_t result;
+ dns_fixedname_t fkeyname;
+ size_t namelen;
+ dns_name_t *keyname;
+ dns_rdata_dnskey_t keystruct;
+ unsigned char keydata[4096];
+ isc_buffer_t keydatabuf;
+ unsigned char rrdata[4096];
+ isc_buffer_t rrdatabuf;
+ isc_buffer_t b;
+ isc_textregion_t tr;
+ isc_region_t r;
+ dns_secalg_t alg;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to crate mctx\n");
+ exit(1);
+ }
+
+ if (algname != NULL) {
+ tr.base = algname;
+ tr.length = strlen(algname);
+ result = dns_secalg_fromtext(&alg, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to identify the algorithm\n");
+ exit(1);
+ }
+ } else
+ alg = DNS_KEYALG_RSASHA1;
+
+ keystruct.common.rdclass = dns_rdataclass_in;
+ keystruct.common.rdtype = dns_rdatatype_dnskey;
+ keystruct.flags = DNS_KEYOWNER_ZONE; /* fixed */
+ if (is_sep)
+ keystruct.flags |= DNS_KEYFLAG_KSK;
+ keystruct.protocol = DNS_KEYPROTO_DNSSEC; /* fixed */
+ keystruct.algorithm = alg;
+
+ isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
+ isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
+ result = isc_base64_decodestring(keystr, &keydatabuf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "base64 decode failed\n");
+ exit(1);
+ }
+ isc_buffer_usedregion(&keydatabuf, &r);
+ keystruct.datalen = r.length;
+ keystruct.data = r.base;
+
+ result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
+ keystruct.common.rdtype,
+ &keystruct, &rrdatabuf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to construct key rdata\n");
+ exit(1);
+ }
+ namelen = strlen(keynamestr);
+ isc_buffer_init(&b, keynamestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fkeyname);
+ keyname = dns_fixedname_name(&fkeyname);
+ result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to construct key name\n");
+ exit(1);
+ }
+ result = dns_client_addtrustedkey(client, dns_rdataclass_in,
+ keyname, &rrdatabuf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to add key for %s\n",
+ keynamestr);
+ exit(1);
+ }
+}
+
+static void
+addserver(dns_client_t *client, const char *addrstr, const char *namespace) {
+ struct addrinfo hints, *res;
+ int gai_error;
+ isc_sockaddr_t sa;
+ isc_sockaddrlist_t servers;
+ isc_result_t result;
+ size_t namelen;
+ isc_buffer_t b;
+ dns_fixedname_t fname;
+ dns_name_t *name = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(addrstr, "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa.type));
+ memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa, link);
+ ISC_LIST_INIT(servers);
+ ISC_LIST_APPEND(servers, &sa, link);
+
+ if (namespace != NULL) {
+ namelen = strlen(namespace);
+ isc_buffer_init(&b, namespace, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to convert qname: %d\n",
+ result);
+ exit(1);
+ }
+ }
+
+ result = dns_client_setservers(client, dns_rdataclass_in, name,
+ &servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "set server failed: %d\n", result);
+ exit(1);
+ }
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch;
+ isc_textregion_t tr;
+ char *altserver = NULL;
+ char *altserveraddr = NULL;
+ char *altservername = NULL;
+ dns_client_t *client = NULL;
+ char *keynamestr = NULL;
+ char *keystr = NULL;
+ isc_result_t result;
+ isc_buffer_t b;
+ dns_fixedname_t qname0;
+ size_t namelen;
+ dns_name_t *qname, *name;
+ dns_rdatatype_t type = dns_rdatatype_a;
+ dns_rdataset_t *rdataset;
+ dns_namelist_t namelist;
+ isc_mem_t *keymctx = NULL;
+ unsigned int clientopt, resopt;
+ isc_boolean_t is_sep = ISC_FALSE;
+
+ while ((ch = getopt(argc, argv, "a:es:t:k:K:")) != -1) {
+ switch (ch) {
+ case 't':
+ tr.base = optarg;
+ tr.length = strlen(optarg);
+ result = dns_rdatatype_fromtext(&type, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "invalid RRtype: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'a':
+ algname = optarg;
+ break;
+ case 'e':
+ is_sep = ISC_TRUE;
+ break;
+ case 's':
+ if (altserver != NULL) {
+ fprintf(stderr, "alternate server "
+ "already defined: %s\n",
+ altserver);
+ exit(1);
+ }
+ altserver = optarg;
+ break;
+ case 'k':
+ keynamestr = optarg;
+ break;
+ case 'K':
+ keystr = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ if (altserver != NULL) {
+ char *cp;
+
+ cp = strchr(altserver, ':');
+ if (cp == NULL) {
+ fprintf(stderr, "invalid alternate server: %s\n",
+ altserver);
+ exit(1);
+ }
+ *cp = '\0';
+ altservername = altserver;
+ altserveraddr = cp + 1;
+ }
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ clientopt = 0;
+ result = dns_client_create(&client, clientopt);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_create failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set the nameserver */
+ addserver(client, argv[0], NULL);
+
+ /* Set the alternate nameserver (when specified) */
+ if (altserver != NULL)
+ addserver(client, altserveraddr, altservername);
+
+ /* Install DNSSEC key (if given) */
+ if (keynamestr != NULL) {
+ if (keystr == NULL) {
+ fprintf(stderr,
+ "key string is missing "
+ "while key name is provided\n");
+ exit(1);
+ }
+ set_key(client, keynamestr, keystr, is_sep, &keymctx);
+ }
+
+ /* Construct qname */
+ namelen = strlen(argv[1]);
+ isc_buffer_init(&b, argv[1], namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&qname0);
+ qname = dns_fixedname_name(&qname0);
+ result = dns_name_fromtext(qname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "failed to convert qname: %d\n", result);
+
+ /* Perform resolution */
+ resopt = 0;
+ if (keynamestr == NULL)
+ resopt |= DNS_CLIENTRESOPT_NODNSSEC;
+ ISC_LIST_INIT(namelist);
+ result = dns_client_resolve(client, qname, dns_rdataclass_in, type,
+ resopt, &namelist);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "resolution failed: %s\n", dns_result_totext(result));
+ }
+ for (name = ISC_LIST_HEAD(namelist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (printdata(rdataset, name) != ISC_R_SUCCESS)
+ fprintf(stderr, "print data failed\n");
+ }
+ }
+
+ dns_client_freeresanswer(client, &namelist);
+
+ /* Cleanup */
+ dns_client_destroy(&client);
+ if (keynamestr != NULL)
+ isc_mem_destroy(&keymctx);
+ dns_lib_shutdown();
+
+ exit(0);
+}
diff --git a/lib/irs/Makefile.in b/lib/irs/Makefile.in
new file mode 100644
index 00000000..ed869679
--- /dev/null
+++ b/lib/irs/Makefile.in
@@ -0,0 +1,80 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@LIBIRS_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -I./include -I${srcdir}/include \
+ ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+# Alphabetically
+OBJS = context.@O@ \
+ dnsconf.@O@ \
+ gai_strerror.@O@ getaddrinfo.@O@ getnameinfo.@O@ \
+ resconf.@O@
+
+# Alphabetically
+SRCS = context.c \
+ dnsconf.c \
+ gai_sterror.c getaddrinfo.c getnameinfo.c \
+ resconf.c
+
+LIBS = @LIBS@
+
+SUBDIRS = include
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libirs.@SA@: ${OBJS} version.@O@
+ ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@
+ ${RANLIB} $@
+
+libirs.la: ${OBJS} version.@O@
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs.la -rpath ${libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} version.@O@ ${LIBS}
+
+timestamp: libirs.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libirs.@A@ ${DESTDIR}${libdir}
+
+clean distclean::
+ rm -f libirs.@A@ libirs.la timestamp
diff --git a/lib/irs/api b/lib/irs/api
new file mode 100644
index 00000000..2240cdda
--- /dev/null
+++ b/lib/irs/api
@@ -0,0 +1,3 @@
+LIBINTERFACE = 50
+LIBREVISION = 1
+LIBAGE = 0
diff --git a/lib/irs/context.c b/lib/irs/context.c
new file mode 100644
index 00000000..be69622b
--- /dev/null
+++ b/lib/irs/context.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: context.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/app.h>
+#include <isc/lib.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/thread.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/lib.h>
+
+#include <irs/context.h>
+#include <irs/dnsconf.h>
+#include <irs/resconf.h>
+
+#define IRS_CONTEXT_MAGIC ISC_MAGIC('I', 'R', 'S', 'c')
+#define IRS_CONTEXT_VALID(c) ISC_MAGIC_VALID(c, IRS_CONTEXT_MAGIC)
+
+#ifndef RESOLV_CONF
+/*% location of resolve.conf */
+#define RESOLV_CONF "/etc/resolv.conf"
+#endif
+
+#ifndef DNS_CONF
+/*% location of dns.conf */
+#define DNS_CONF "/etc/dns.conf"
+#endif
+
+#ifndef ISC_PLATFORM_USETHREADS
+irs_context_t *irs_g_context = NULL;
+#else
+static isc_boolean_t thread_key_initialized = ISC_FALSE;
+static isc_mutex_t thread_key_mutex;
+static isc_thread_key_t irs_context_key;
+static isc_once_t once = ISC_ONCE_INIT;
+#endif
+
+
+struct irs_context {
+ /*
+ * An IRS context is a thread-specific object, and does not need to
+ * be locked.
+ */
+ unsigned int magic;
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ isc_taskmgr_t *taskmgr;
+ isc_task_t *task;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+ dns_client_t *dnsclient;
+ irs_resconf_t *resconf;
+ irs_dnsconf_t *dnsconf;
+};
+
+static void
+ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ if (taskmgrp != NULL)
+ isc_taskmgr_destroy(taskmgrp);
+
+ if (timermgrp != NULL)
+ isc_timermgr_destroy(timermgrp);
+
+ if (socketmgrp != NULL)
+ isc_socketmgr_destroy(socketmgrp);
+
+ if (actxp != NULL)
+ isc_appctx_destroy(actxp);
+
+ if (mctxp != NULL)
+ isc_mem_destroy(mctxp);
+}
+
+static isc_result_t
+ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ isc_result_t result;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_appctx_create(*mctxp, actxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
+
+ return (result);
+}
+
+#ifdef ISC_PLATFORM_USETHREADS
+static void
+free_specific_context(void *arg) {
+ irs_context_t *context = arg;
+
+ irs_context_destroy(&context);
+
+ isc_thread_key_setspecific(irs_context_key, NULL);
+}
+
+static void
+thread_key_mutex_init(void) {
+ RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
+}
+
+static isc_result_t
+thread_key_init() {
+ isc_result_t result;
+
+ result = isc_once_do(&once, thread_key_mutex_init);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (!thread_key_initialized) {
+ LOCK(&thread_key_mutex);
+
+ if (!thread_key_initialized &&
+ isc_thread_key_create(&irs_context_key,
+ free_specific_context) != 0) {
+ result = ISC_R_FAILURE;
+ } else
+ thread_key_initialized = ISC_TRUE;
+
+ UNLOCK(&thread_key_mutex);
+ }
+
+ return (result);
+}
+#endif /* ISC_PLATFORM_USETHREADS */
+
+isc_result_t
+irs_context_get(irs_context_t **contextp) {
+ irs_context_t *context;
+ isc_result_t result;
+
+ REQUIRE(contextp != NULL && *contextp == NULL);
+
+#ifndef ISC_PLATFORM_USETHREADS
+ if (irs_g_context == NULL) {
+ result = irs_context_create(&irs_g_context);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+
+ context = irs_g_context;
+#else
+ result = thread_key_init();
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ context = isc_thread_key_getspecific(irs_context_key);
+ if (context == NULL) {
+ result = irs_context_create(&context);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_thread_key_setspecific(irs_context_key, context);
+ if (result != ISC_R_SUCCESS) {
+ irs_context_destroy(&context);
+ return (result);
+ }
+ }
+#endif /* ISC_PLATFORM_USETHREADS */
+
+ *contextp = context;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+irs_context_create(irs_context_t **contextp) {
+ isc_result_t result;
+ irs_context_t *context;
+ isc_appctx_t *actx = NULL;
+ isc_mem_t *mctx = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+ dns_client_t *client = NULL;
+ isc_sockaddrlist_t *nameservers;
+ irs_dnsconf_dnskeylist_t *trustedkeys;
+ irs_dnsconf_dnskey_t *trustedkey;
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = isc_app_ctxstart(actx);
+ if (result != ISC_R_SUCCESS) {
+ ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+ return (result);
+ }
+
+ context = isc_mem_get(mctx, sizeof(*context));
+ if (context == NULL) {
+ ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+ return (ISC_R_NOMEMORY);
+ }
+
+ context->mctx = mctx;
+ context->actx = actx;
+ context->taskmgr = taskmgr;
+ context->socketmgr = socketmgr;
+ context->timermgr = timermgr;
+ context->resconf = NULL;
+ context->dnsconf = NULL;
+ context->task = NULL;
+ result = isc_task_create(taskmgr, 0, &context->task);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ /* Create a DNS client object */
+ result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
+ 0, &client);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ context->dnsclient = client;
+
+ /* Read resolver configuration file */
+ result = irs_resconf_load(mctx, RESOLV_CONF, &context->resconf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ /* Set nameservers */
+ nameservers = irs_resconf_getnameservers(context->resconf);
+ result = dns_client_setservers(client, dns_rdataclass_in, NULL,
+ nameservers);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ /* Read advanced DNS configuration (if any) */
+ result = irs_dnsconf_load(mctx, DNS_CONF, &context->dnsconf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ trustedkeys = irs_dnsconf_gettrustedkeys(context->dnsconf);
+ for (trustedkey = ISC_LIST_HEAD(*trustedkeys);
+ trustedkey != NULL;
+ trustedkey = ISC_LIST_NEXT(trustedkey, link)) {
+ result = dns_client_addtrustedkey(client, dns_rdataclass_in,
+ trustedkey->keyname,
+ trustedkey->keydatabuf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ }
+
+ context->magic = IRS_CONTEXT_MAGIC;
+ *contextp = context;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ if (context->task != NULL)
+ isc_task_detach(&context->task);
+ if (context->resconf != NULL)
+ irs_resconf_destroy(&context->resconf);
+ if (context->dnsconf != NULL)
+ irs_dnsconf_destroy(&context->dnsconf);
+ if (client != NULL)
+ dns_client_destroy(&client);
+ ctxs_destroy(NULL, &actx, &taskmgr, &socketmgr, &timermgr);
+ isc_mem_putanddetach(&mctx, context, sizeof(*context));
+
+ return (result);
+}
+
+void
+irs_context_destroy(irs_context_t **contextp) {
+ irs_context_t *context;
+
+ REQUIRE(contextp != NULL);
+ context = *contextp;
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ isc_task_detach(&context->task);
+ irs_dnsconf_destroy(&context->dnsconf);
+ irs_resconf_destroy(&context->resconf);
+ dns_client_destroy(&context->dnsclient);
+
+ ctxs_destroy(NULL, &context->actx, &context->taskmgr,
+ &context->socketmgr, &context->timermgr);
+
+ context->magic = 0;
+
+ isc_mem_putanddetach(&context->mctx, context, sizeof(*context));
+
+ *contextp = NULL;
+
+#ifndef ISC_PLATFORM_USETHREADS
+ irs_g_context = NULL;
+#else
+ (void)isc_thread_key_setspecific(irs_context_key, NULL);
+#endif
+}
+
+isc_mem_t *
+irs_context_getmctx(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->mctx);
+}
+
+isc_appctx_t *
+irs_context_getappctx(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->actx);
+}
+
+isc_taskmgr_t *
+irs_context_gettaskmgr(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->taskmgr);
+}
+
+isc_timermgr_t *
+irs_context_gettimermgr(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->timermgr);
+}
+
+isc_task_t *
+irs_context_gettask(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->task);
+}
+
+dns_client_t *
+irs_context_getdnsclient(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->dnsclient);
+}
+
+irs_resconf_t *
+irs_context_getresconf(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->resconf);
+}
+
+irs_dnsconf_t *
+irs_context_getdnsconf(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->dnsconf);
+}
diff --git a/lib/irs/dnsconf.c b/lib/irs/dnsconf.c
new file mode 100644
index 00000000..4a7d58bf
--- /dev/null
+++ b/lib/irs/dnsconf.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: dnsconf.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/file.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+#include <isccfg/dnsconf.h>
+
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdatastruct.h>
+
+#include <irs/dnsconf.h>
+
+#define IRS_DNSCONF_MAGIC ISC_MAGIC('D', 'c', 'f', 'g')
+#define IRS_DNSCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_DNSCONF_MAGIC)
+
+/*!
+ * configuration data structure
+ */
+
+struct irs_dnsconf {
+ unsigned int magic;
+ isc_mem_t *mctx;
+ irs_dnsconf_dnskeylist_t trusted_keylist;
+};
+
+static isc_result_t
+configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj,
+ dns_rdataclass_t rdclass)
+{
+ isc_mem_t *mctx = conf->mctx;
+ const cfg_obj_t *keys = NULL;
+ const cfg_obj_t *key, *keylist;
+ dns_fixedname_t fkeyname;
+ dns_name_t *keyname_base, *keyname;
+ const cfg_listelt_t *element, *element2;
+ isc_result_t result;
+ isc_uint32_t flags, proto, alg;
+ const char *keystr, *keynamestr;
+ unsigned char keydata[4096];
+ isc_buffer_t keydatabuf_base, *keydatabuf;
+ dns_rdata_dnskey_t keystruct;
+ unsigned char rrdata[4096];
+ isc_buffer_t rrdatabuf;
+ isc_region_t r;
+ isc_buffer_t namebuf;
+ irs_dnsconf_dnskey_t *keyent;
+
+ cfg_map_get(cfgobj, "trusted-keys", &keys);
+ if (keys == NULL)
+ return (ISC_R_SUCCESS);
+
+ for (element = cfg_list_first(keys);
+ element != NULL;
+ element = cfg_list_next(element)) {
+ keylist = cfg_listelt_value(element);
+ for (element2 = cfg_list_first(keylist);
+ element2 != NULL;
+ element2 = cfg_list_next(element2))
+ {
+ keydatabuf = NULL;
+ keyname = NULL;
+
+ key = cfg_listelt_value(element2);
+
+ flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
+ proto = cfg_obj_asuint32(cfg_tuple_get(key,
+ "protocol"));
+ alg = cfg_obj_asuint32(cfg_tuple_get(key,
+ "algorithm"));
+ keynamestr = cfg_obj_asstring(cfg_tuple_get(key,
+ "name"));
+
+ keystruct.common.rdclass = rdclass;
+ keystruct.common.rdtype = dns_rdatatype_dnskey;
+ keystruct.mctx = NULL;
+ ISC_LINK_INIT(&keystruct.common, link);
+
+ if (flags > 0xffff)
+ return (ISC_R_RANGE);
+ if (proto > 0xff)
+ return (ISC_R_RANGE);
+ if (alg > 0xff)
+ return (ISC_R_RANGE);
+ keystruct.flags = (isc_uint16_t)flags;
+ keystruct.protocol = (isc_uint8_t)proto;
+ keystruct.algorithm = (isc_uint8_t)alg;
+
+ isc_buffer_init(&keydatabuf_base, keydata,
+ sizeof(keydata));
+ isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
+
+ /* Configure key value */
+ keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
+ result = isc_base64_decodestring(keystr,
+ &keydatabuf_base);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&keydatabuf_base, &r);
+ keystruct.datalen = r.length;
+ keystruct.data = r.base;
+
+ result = dns_rdata_fromstruct(NULL,
+ keystruct.common.rdclass,
+ keystruct.common.rdtype,
+ &keystruct, &rrdatabuf);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&rrdatabuf, &r);
+ result = isc_buffer_allocate(mctx, &keydatabuf,
+ r.length);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_buffer_copyregion(keydatabuf, &r);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Configure key name */
+ dns_fixedname_init(&fkeyname);
+ keyname_base = dns_fixedname_name(&fkeyname);
+ isc_buffer_init(&namebuf, keynamestr,
+ strlen(keynamestr));
+ isc_buffer_add(&namebuf, strlen(keynamestr));
+ result = dns_name_fromtext(keyname_base, &namebuf,
+ dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ keyname = isc_mem_get(mctx, sizeof(*keyname));
+ if (keyname == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ dns_name_init(keyname, NULL);
+ result = dns_name_dup(keyname_base, mctx, keyname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Add the key data to the list */
+ keyent = isc_mem_get(mctx, sizeof(*keyent));
+ if (keyent == NULL) {
+ dns_name_free(keyname, mctx);
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ keyent->keyname = keyname;
+ keyent->keydatabuf = keydatabuf;
+
+ ISC_LIST_APPEND(conf->trusted_keylist, keyent, link);
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (keydatabuf != NULL)
+ isc_buffer_free(&keydatabuf);
+ if (keyname != NULL)
+ isc_mem_put(mctx, keyname, sizeof(*keyname));
+
+ return (result);
+}
+
+isc_result_t
+irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp)
+{
+ irs_dnsconf_t *conf;
+ cfg_parser_t *parser = NULL;
+ cfg_obj_t *cfgobj = NULL;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(confp != NULL && *confp == NULL);
+
+ conf = isc_mem_get(mctx, sizeof(*conf));
+ if (conf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ conf->mctx = mctx;
+ ISC_LIST_INIT(conf->trusted_keylist);
+
+ /*
+ * If the specified file does not exist, we'll simply with an empty
+ * configuration.
+ */
+ if (!isc_file_exists(filename))
+ goto cleanup;
+
+ result = cfg_parser_create(mctx, NULL, &parser);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_parse_file(parser, filename, &cfg_type_dnsconf,
+ &cfgobj);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = configure_dnsseckeys(conf, cfgobj, dns_rdataclass_in);
+
+ cleanup:
+ if (parser != NULL) {
+ if (cfgobj != NULL)
+ cfg_obj_destroy(parser, &cfgobj);
+ cfg_parser_destroy(&parser);
+ }
+
+ conf->magic = IRS_DNSCONF_MAGIC;
+
+ if (result == ISC_R_SUCCESS)
+ *confp = conf;
+ else
+ irs_dnsconf_destroy(&conf);
+
+ return (result);
+}
+
+void
+irs_dnsconf_destroy(irs_dnsconf_t **confp) {
+ irs_dnsconf_t *conf;
+ irs_dnsconf_dnskey_t *keyent;
+
+ REQUIRE(confp != NULL);
+ conf = *confp;
+ REQUIRE(IRS_DNSCONF_VALID(conf));
+
+ while ((keyent = ISC_LIST_HEAD(conf->trusted_keylist)) != NULL) {
+ ISC_LIST_UNLINK(conf->trusted_keylist, keyent, link);
+
+ isc_buffer_free(&keyent->keydatabuf);
+ dns_name_free(keyent->keyname, conf->mctx);
+ isc_mem_put(conf->mctx, keyent->keyname, sizeof(dns_name_t));
+ isc_mem_put(conf->mctx, keyent, sizeof(*keyent));
+ }
+
+ isc_mem_put(conf->mctx, conf, sizeof(*conf));
+
+ *confp = NULL;
+}
+
+irs_dnsconf_dnskeylist_t *
+irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf) {
+ REQUIRE(IRS_DNSCONF_VALID(conf));
+
+ return (&conf->trusted_keylist);
+}
diff --git a/lib/irs/gai_strerror.c b/lib/irs/gai_strerror.c
new file mode 100644
index 00000000..2fe39416
--- /dev/null
+++ b/lib/irs/gai_strerror.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: gai_strerror.c,v 1.5 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file gai_strerror.c
+ * gai_strerror() returns an error message corresponding to an
+ * error code returned by getaddrinfo() and getnameinfo(). The following error
+ * codes and their meaning are defined in
+ * \link netdb.h include/irs/netdb.h.\endlink
+ * This implementation is almost an exact copy of lwres/gai_sterror.c except
+ * that it catches up the latest API standard, RFC3493.
+ *
+ * \li #EAI_ADDRFAMILY address family for hostname not supported
+ * \li #EAI_AGAIN temporary failure in name resolution
+ * \li #EAI_BADFLAGS invalid value for ai_flags
+ * \li #EAI_FAIL non-recoverable failure in name resolution
+ * \li #EAI_FAMILY ai_family not supported
+ * \li #EAI_MEMORY memory allocation failure
+ * \li #EAI_NODATA no address associated with hostname (obsoleted in RFC3493)
+ * \li #EAI_NONAME hostname nor servname provided, or not known
+ * \li #EAI_SERVICE servname not supported for ai_socktype
+ * \li #EAI_SOCKTYPE ai_socktype not supported
+ * \li #EAI_SYSTEM system error returned in errno
+ * \li #EAI_BADHINTS Invalid value for hints (non-standard)
+ * \li #EAI_PROTOCOL Resolved protocol is unknown (non-standard)
+ * \li #EAI_OVERFLOW Argument buffer overflow
+ * \li #EAI_INSECUREDATA Insecure Data (experimental)
+ *
+ * The message invalid error code is returned if ecode is out of range.
+ *
+ * ai_flags, ai_family and ai_socktype are elements of the struct
+ * addrinfo used by lwres_getaddrinfo().
+ *
+ * \section gai_strerror_see See Also
+ *
+ * strerror(), getaddrinfo(), getnameinfo(), RFC3493.
+ */
+#include <config.h>
+
+#include <irs/netdb.h>
+
+/*% Text of error messages. */
+static const char *gai_messages[] = {
+ "no error",
+ "address family for hostname not supported",
+ "temporary failure in name resolution",
+ "invalid value for ai_flags",
+ "non-recoverable failure in name resolution",
+ "ai_family not supported",
+ "memory allocation failure",
+ "no address associated with hostname",
+ "hostname nor servname provided, or not known",
+ "servname not supported for ai_socktype",
+ "ai_socktype not supported",
+ "system error returned in errno",
+ "bad hints",
+ "bad protocol",
+ "argument buffer overflow",
+ "insecure data provided"
+};
+
+/*%
+ * Returns an error message corresponding to an error code returned by
+ * getaddrinfo() and getnameinfo()
+ */
+IRS_GAISTRERROR_RETURN_T
+gai_strerror(int ecode) {
+ union {
+ const char *const_ptr;
+ char *deconst_ptr;
+ } ptr;
+
+ if ((ecode < 0) ||
+ (ecode >= (int)(sizeof(gai_messages)/sizeof(*gai_messages))))
+ ptr.const_ptr = "invalid error code";
+ else
+ ptr.const_ptr = gai_messages[ecode];
+ return (ptr.deconst_ptr);
+}
diff --git a/lib/irs/getaddrinfo.c b/lib/irs/getaddrinfo.c
new file mode 100644
index 00000000..4b1f4a92
--- /dev/null
+++ b/lib/irs/getaddrinfo.c
@@ -0,0 +1,1295 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: getaddrinfo.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+/**
+ * getaddrinfo() is used to get a list of IP addresses and port
+ * numbers for host hostname and service servname as defined in RFC3493.
+ * hostname and servname are pointers to null-terminated strings
+ * or NULL. hostname is either a host name or a numeric host address
+ * string: a dotted decimal IPv4 address or an IPv6 address. servname is
+ * either a decimal port number or a service name as listed in
+ * /etc/services.
+ *
+ * If the operating system does not provide a struct addrinfo, the
+ * following structure is used:
+ *
+ * \code
+ * struct addrinfo {
+ * int ai_flags; // AI_PASSIVE, AI_CANONNAME
+ * int ai_family; // PF_xxx
+ * int ai_socktype; // SOCK_xxx
+ * int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
+ * size_t ai_addrlen; // length of ai_addr
+ * char *ai_canonname; // canonical name for hostname
+ * struct sockaddr *ai_addr; // binary address
+ * struct addrinfo *ai_next; // next structure in linked list
+ * };
+ * \endcode
+ *
+ *
+ * hints is an optional pointer to a struct addrinfo. This structure can
+ * be used to provide hints concerning the type of socket that the caller
+ * supports or wishes to use. The caller can supply the following
+ * structure elements in *hints:
+ *
+ * <ul>
+ * <li>ai_family:
+ * The protocol family that should be used. When ai_family is set
+ * to PF_UNSPEC, it means the caller will accept any protocol
+ * family supported by the operating system.</li>
+ *
+ * <li>ai_socktype:
+ * denotes the type of socket -- SOCK_STREAM, SOCK_DGRAM or
+ * SOCK_RAW -- that is wanted. When ai_socktype is zero the caller
+ * will accept any socket type.</li>
+ *
+ * <li>ai_protocol:
+ * indicates which transport protocol is wanted: IPPROTO_UDP or
+ * IPPROTO_TCP. If ai_protocol is zero the caller will accept any
+ * protocol.</li>
+ *
+ * <li>ai_flags:
+ * Flag bits. If the AI_CANONNAME bit is set, a successful call to
+ * getaddrinfo() will return a null-terminated string
+ * containing the canonical name of the specified hostname in
+ * ai_canonname of the first addrinfo structure returned. Setting
+ * the AI_PASSIVE bit indicates that the returned socket address
+ * structure is intended for used in a call to bind(2). In this
+ * case, if the hostname argument is a NULL pointer, then the IP
+ * address portion of the socket address structure will be set to
+ * INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6
+ * address.<br /><br />
+ *
+ * When ai_flags does not set the AI_PASSIVE bit, the returned
+ * socket address structure will be ready for use in a call to
+ * connect(2) for a connection-oriented protocol or connect(2),
+ * sendto(2), or sendmsg(2) if a connectionless protocol was
+ * chosen. The IP address portion of the socket address structure
+ * will be set to the loopback address if hostname is a NULL
+ * pointer and AI_PASSIVE is not set in ai_flags.<br /><br />
+ *
+ * If ai_flags is set to AI_NUMERICHOST it indicates that hostname
+ * should be treated as a numeric string defining an IPv4 or IPv6
+ * address and no name resolution should be attempted.
+ * </li></ul>
+ *
+ * All other elements of the struct addrinfo passed via hints must be
+ * zero.
+ *
+ * A hints of NULL is treated as if the caller provided a struct addrinfo
+ * initialized to zero with ai_familyset to PF_UNSPEC.
+ *
+ * After a successful call to getaddrinfo(), *res is a pointer to a
+ * linked list of one or more addrinfo structures. Each struct addrinfo
+ * in this list cn be processed by following the ai_next pointer, until a
+ * NULL pointer is encountered. The three members ai_family, ai_socktype,
+ * and ai_protocol in each returned addrinfo structure contain the
+ * corresponding arguments for a call to socket(2). For each addrinfo
+ * structure in the list, the ai_addr member points to a filled-in socket
+ * address structure of length ai_addrlen.
+ *
+ * All of the information returned by getaddrinfo() is dynamically
+ * allocated: the addrinfo structures, and the socket address structures
+ * and canonical host name strings pointed to by the addrinfostructures.
+ * Memory allocated for the dynamically allocated structures created by a
+ * successful call to getaddrinfo() is released by freeaddrinfo().
+ * ai is a pointer to a struct addrinfo created by a call to getaddrinfo().
+ *
+ * \section irsreturn RETURN VALUES
+ *
+ * getaddrinfo() returns zero on success or one of the error codes
+ * listed in gai_strerror() if an error occurs. If both hostname and
+ * servname are NULL getaddrinfo() returns #EAI_NONAME.
+ *
+ * \section irssee SEE ALSO
+ *
+ * getaddrinfo(), freeaddrinfo(),
+ * gai_strerror(), RFC3493, getservbyname(3), connect(2),
+ * sendto(2), sendmsg(2), socket(2).
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#include <irs/context.h>
+#include <irs/netdb.h>
+#include <irs/resconf.h>
+
+#define SA(addr) ((struct sockaddr *)(addr))
+#define SIN(addr) ((struct sockaddr_in *)(addr))
+#define SIN6(addr) ((struct sockaddr_in6 *)(addr))
+#define SLOCAL(addr) ((struct sockaddr_un *)(addr))
+
+/*! \struct addrinfo
+ */
+static struct addrinfo
+ *ai_concat(struct addrinfo *ai1, struct addrinfo *ai2),
+ *ai_reverse(struct addrinfo *oai),
+ *ai_clone(struct addrinfo *oai, int family),
+ *ai_alloc(int family, int addrlen);
+#ifdef AF_LOCAL
+static int get_local(const char *name, int socktype, struct addrinfo **res);
+#endif
+
+static int
+resolve_name(int family, const char *hostname, int flags,
+ struct addrinfo **aip, int socktype, int port);
+
+static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static void set_order(int, int (**)(const char *, int, struct addrinfo **,
+ int, int));
+
+#define FOUND_IPV4 0x1
+#define FOUND_IPV6 0x2
+#define FOUND_MAX 2
+
+#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
+/*%
+ * Get a list of IP addresses and port numbers for host hostname and
+ * service servname.
+ */
+int
+getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct servent *sp;
+ const char *proto;
+ int family, socktype, flags, protocol;
+ struct addrinfo *ai, *ai_list;
+ int err = 0;
+ int port, i;
+ int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
+ int, int);
+
+ if (hostname == NULL && servname == NULL)
+ return (EAI_NONAME);
+
+ proto = NULL;
+ if (hints != NULL) {
+ if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0)
+ return (EAI_BADFLAGS);
+ if (hints->ai_addrlen || hints->ai_canonname ||
+ hints->ai_addr || hints->ai_next) {
+ errno = EINVAL;
+ return (EAI_SYSTEM);
+ }
+ family = hints->ai_family;
+ socktype = hints->ai_socktype;
+ protocol = hints->ai_protocol;
+ flags = hints->ai_flags;
+ switch (family) {
+ case AF_UNSPEC:
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ }
+ break;
+ case AF_INET:
+ case AF_INET6:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_RAW:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ break;
+ case SOCK_DGRAM:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#endif
+ default:
+ return (EAI_FAMILY);
+ }
+ } else {
+ protocol = 0;
+ family = 0;
+ socktype = 0;
+ flags = 0;
+ }
+
+#ifdef AF_LOCAL
+ /*!
+ * First, deal with AF_LOCAL. If the family was not set,
+ * then assume AF_LOCAL if the first character of the
+ * hostname/servname is '/'.
+ */
+
+ if (hostname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *hostname == '/')))
+ return (get_local(hostname, socktype, res));
+
+ if (servname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *servname == '/')))
+ return (get_local(servname, socktype, res));
+#endif
+
+ /*
+ * Ok, only AF_INET and AF_INET6 left.
+ */
+ ai_list = NULL;
+
+ /*
+ * First, look up the service name (port) if it was
+ * requested. If the socket type wasn't specified, then
+ * try and figure it out.
+ */
+ if (servname != NULL) {
+ char *e;
+
+ port = strtol(servname, &e, 10);
+ if (*e == '\0') {
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+ if (port < 0 || port > 65535)
+ return (EAI_SERVICE);
+ port = htons((unsigned short) port);
+ } else {
+ sp = getservbyname(servname, proto);
+ if (sp == NULL)
+ return (EAI_SERVICE);
+ port = sp->s_port;
+ if (socktype == 0) {
+ if (strcmp(sp->s_proto, "tcp") == 0)
+ socktype = SOCK_STREAM;
+ else if (strcmp(sp->s_proto, "udp") == 0)
+ socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ port = 0;
+
+ /*
+ * Next, deal with just a service name, and no hostname.
+ * (we verified that one of them was non-null up above).
+ */
+ if (hostname == NULL && (flags & AI_PASSIVE) != 0) {
+ if (family == AF_INET || family == 0) {
+ ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN(ai->ai_addr)->sin_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ if (family == AF_INET6 || family == 0) {
+ ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
+ if (ai == NULL) {
+ freeaddrinfo(ai_list);
+ return (EAI_MEMORY);
+ }
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ *res = ai_list;
+ return (0);
+ }
+
+ /*
+ * If the family isn't specified or AI_NUMERICHOST specified, check
+ * first to see if it is a numeric address.
+ * Though the gethostbyname2() routine will recognize numeric addresses,
+ * it will only recognize the format that it is being called for. Thus,
+ * a numeric AF_INET address will be treated by the AF_INET6 call as
+ * a domain name, and vice versa. Checking for both numerics here
+ * avoids that.
+ */
+ if (hostname != NULL &&
+ (family == 0 || (flags & AI_NUMERICHOST) != 0)) {
+ char abuf[sizeof(struct in6_addr)];
+ char nbuf[NI_MAXHOST];
+ int addrsize, addroff;
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ char *p, *ep;
+ char ntmp[NI_MAXHOST];
+ isc_uint32_t scopeid;
+#endif
+
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ /*
+ * Scope identifier portion.
+ */
+ ntmp[0] = '\0';
+ if (strchr(hostname, '%') != NULL) {
+ strncpy(ntmp, hostname, sizeof(ntmp) - 1);
+ ntmp[sizeof(ntmp) - 1] = '\0';
+ p = strchr(ntmp, '%');
+ ep = NULL;
+
+ /*
+ * Vendors may want to support non-numeric
+ * scopeid around here.
+ */
+
+ if (p != NULL)
+ scopeid = (isc_uint32_t)strtoul(p + 1,
+ &ep, 10);
+ if (p != NULL && ep != NULL && ep[0] == '\0')
+ *p = '\0';
+ else {
+ ntmp[0] = '\0';
+ scopeid = 0;
+ }
+ } else
+ scopeid = 0;
+#endif
+
+ if (inet_pton(AF_INET, hostname, (struct in_addr *)abuf)
+ == 1) {
+ if (family == AF_INET6) {
+ /*
+ * Convert to a V4 mapped address.
+ */
+ struct in6_addr *a6 = (struct in6_addr *)abuf;
+ memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
+ memset(&a6->s6_addr[10], 0xff, 2);
+ memset(&a6->s6_addr[0], 0, 10);
+ goto inet6_addr;
+ }
+ addrsize = sizeof(struct in_addr);
+ addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
+ family = AF_INET;
+ goto common;
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ } else if (ntmp[0] != '\0' &&
+ inet_pton(AF_INET6, ntmp, abuf) == 1) {
+ if (family && family != AF_INET6)
+ return (EAI_NONAME);
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+ goto common;
+#endif
+ } else if (inet_pton(AF_INET6, hostname, abuf) == 1) {
+ if (family != 0 && family != AF_INET6)
+ return (EAI_NONAME);
+ inet6_addr:
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+
+ common:
+ ai = ai_alloc(family,
+ ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) :
+ sizeof(struct sockaddr_in)));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai_list = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);
+ if ((flags & AI_CANONNAME) != 0) {
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ if (ai->ai_family == AF_INET6)
+ SIN6(ai->ai_addr)->sin6_scope_id =
+ scopeid;
+#endif
+ if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ nbuf, sizeof(nbuf), NULL, 0,
+ NI_NUMERICHOST) == 0) {
+ ai->ai_canonname = strdup(nbuf);
+ if (ai->ai_canonname == NULL) {
+ freeaddrinfo(ai);
+ return (EAI_MEMORY);
+ }
+ } else {
+ /* XXX raise error? */
+ ai->ai_canonname = NULL;
+ }
+ }
+ goto done;
+ } else if ((flags & AI_NUMERICHOST) != 0) {
+ return (EAI_NONAME);
+ }
+ }
+
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ set_order(family, net_order);
+ for (i = 0; i < FOUND_MAX; i++) {
+ if (net_order[i] == NULL)
+ break;
+ err = (net_order[i])(hostname, flags, &ai_list,
+ socktype, port);
+ if (err != 0) {
+ if (ai_list != NULL)
+ freeaddrinfo(ai_list);
+ break;
+ }
+ }
+ } else
+ err = resolve_name(family, hostname, flags, &ai_list,
+ socktype, port);
+
+ if (ai_list == NULL) {
+ if (err == 0)
+ err = EAI_NONAME;
+ return (err);
+ }
+
+done:
+ ai_list = ai_reverse(ai_list);
+
+ *res = ai_list;
+ return (0);
+}
+
+typedef struct gai_restrans {
+ dns_clientrestrans_t *xid;
+ isc_boolean_t is_inprogress;
+ int error;
+ struct addrinfo ai_sentinel;
+ struct gai_resstate *resstate;
+} gai_restrans_t;
+
+typedef struct gai_resstate {
+ isc_mem_t *mctx;
+ struct gai_statehead *head;
+ dns_fixedname_t fixedname;
+ dns_name_t *qname;
+ gai_restrans_t *trans4;
+ gai_restrans_t *trans6;
+ ISC_LINK(struct gai_resstate) link;
+} gai_resstate_t;
+
+typedef struct gai_statehead {
+ int ai_family;
+ int ai_flags;
+ int ai_socktype;
+ int ai_port;
+ isc_appctx_t *actx;
+ dns_client_t *dnsclient;
+ ISC_LIST(struct gai_resstate) resstates;
+ unsigned int activestates;
+} gai_statehead_t;
+
+static isc_result_t
+make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname,
+ const char *domain, gai_resstate_t **statep)
+{
+ isc_result_t result;
+ gai_resstate_t *state;
+ dns_fixedname_t fixeddomain;
+ dns_name_t *qdomain;
+ size_t namelen;
+ isc_buffer_t b;
+ isc_boolean_t need_v4 = ISC_FALSE;
+ isc_boolean_t need_v6 = ISC_FALSE;
+
+ state = isc_mem_get(mctx, sizeof(*state));
+ if (state == NULL)
+ return (ISC_R_NOMEMORY);
+
+ /* Construct base domain name */
+ namelen = strlen(domain);
+ isc_buffer_init(&b, domain, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fixeddomain);
+ qdomain = dns_fixedname_name(&fixeddomain);
+ result = dns_name_fromtext(qdomain, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (result);
+ }
+
+ /* Construct query name */
+ namelen = strlen(hostname);
+ isc_buffer_init(&b, hostname, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&state->fixedname);
+ state->qname = dns_fixedname_name(&state->fixedname);
+ result = dns_name_fromtext(state->qname, &b, qdomain, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (result);
+ }
+
+ if (head->ai_family == AF_UNSPEC || head->ai_family == AF_INET)
+ need_v4 = ISC_TRUE;
+ if (head->ai_family == AF_UNSPEC || head->ai_family == AF_INET6)
+ need_v6 = ISC_TRUE;
+
+ state->trans6 = NULL;
+ state->trans4 = NULL;
+ if (need_v4) {
+ state->trans4 = isc_mem_get(mctx, sizeof(gai_restrans_t));
+ if (state->trans4 == NULL) {
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (ISC_R_NOMEMORY);
+ }
+ state->trans4->error = 0;
+ state->trans4->xid = NULL;
+ state->trans4->resstate = state;
+ state->trans4->is_inprogress = ISC_TRUE;
+ state->trans4->ai_sentinel.ai_next = NULL;
+ }
+ if (need_v6) {
+ state->trans6 = isc_mem_get(mctx, sizeof(gai_restrans_t));
+ if (state->trans6 == NULL) {
+ if (state->trans4 != NULL)
+ isc_mem_put(mctx, state->trans4,
+ sizeof(*state->trans4));
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (ISC_R_NOMEMORY);
+ }
+ state->trans6->error = 0;
+ state->trans6->xid = NULL;
+ state->trans6->resstate = state;
+ state->trans6->is_inprogress = ISC_TRUE;
+ state->trans6->ai_sentinel.ai_next = NULL;
+ }
+
+ state->mctx = mctx;
+ state->head = head;
+ ISC_LINK_INIT(state, link);
+
+ *statep = state;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+make_resstates(isc_mem_t *mctx, const char *hostname, gai_statehead_t *head,
+ irs_resconf_t *resconf)
+{
+ isc_result_t result;
+ irs_resconf_searchlist_t *searchlist;
+ irs_resconf_search_t *searchent;
+ gai_resstate_t *resstate, *resstate0;
+
+ resstate0 = NULL;
+ result = make_resstate(mctx, head, hostname, ".", &resstate0);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ searchlist = irs_resconf_getsearchlist(resconf);
+ for (searchent = ISC_LIST_HEAD(*searchlist); searchent != NULL;
+ searchent = ISC_LIST_NEXT(searchent, link)) {
+ resstate = NULL;
+ result = make_resstate(mctx, head, hostname,
+ (const char *)searchent->domain,
+ &resstate);
+ if (result != ISC_R_SUCCESS)
+ break;
+
+ ISC_LIST_APPEND(head->resstates, resstate, link);
+ head->activestates++;
+ }
+
+ /*
+ * Insert the original hostname either at the head or the tail of the
+ * state list, depending on the number of labels contained in the
+ * original name and the 'ndots' configuration parameter.
+ */
+ if (dns_name_countlabels(resstate0->qname) >
+ irs_resconf_getndots(resconf) + 1) {
+ ISC_LIST_PREPEND(head->resstates, resstate0, link);
+ } else
+ ISC_LIST_APPEND(head->resstates, resstate0, link);
+ head->activestates++;
+
+ if (result != ISC_R_SUCCESS) {
+ while ((resstate = ISC_LIST_HEAD(head->resstates)) != NULL) {
+ ISC_LIST_UNLINK(head->resstates, resstate, link);
+ if (resstate->trans4 != NULL) {
+ isc_mem_put(mctx, resstate->trans4,
+ sizeof(*resstate->trans4));
+ }
+ if (resstate->trans6 != NULL) {
+ isc_mem_put(mctx, resstate->trans6,
+ sizeof(*resstate->trans6));
+ }
+
+ isc_mem_put(mctx, resstate, sizeof(*resstate));
+ }
+ }
+
+ return (result);
+}
+
+static void
+process_answer(isc_task_t *task, isc_event_t *event) {
+ int error = 0, family;
+ gai_restrans_t *trans = event->ev_arg;
+ gai_resstate_t *resstate;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_rdatatype_t qtype;
+ dns_name_t *name;
+
+ REQUIRE(trans != NULL);
+ resstate = trans->resstate;
+ REQUIRE(resstate != NULL);
+ REQUIRE(task != NULL);
+
+ if (trans == resstate->trans4) {
+ family = AF_INET;
+ qtype = dns_rdatatype_a;
+ } else {
+ INSIST(trans == resstate->trans6);
+ family = AF_INET6;
+ qtype = dns_rdatatype_aaaa;
+ }
+
+ INSIST(trans->is_inprogress);
+ trans->is_inprogress = ISC_FALSE;
+
+ switch (rev->result) {
+ case ISC_R_SUCCESS:
+ case DNS_R_NCACHENXDOMAIN: /* treat this as a fatal error? */
+ case DNS_R_NCACHENXRRSET:
+ break;
+ default:
+ switch (rev->vresult) {
+ case DNS_R_SIGINVALID:
+ case DNS_R_SIGEXPIRED:
+ case DNS_R_SIGFUTURE:
+ case DNS_R_KEYUNAUTHORIZED:
+ case DNS_R_MUSTBESECURE:
+ case DNS_R_COVERINGNSEC:
+ case DNS_R_NOTAUTHORITATIVE:
+ case DNS_R_NOVALIDKEY:
+ case DNS_R_NOVALIDDS:
+ case DNS_R_NOVALIDSIG:
+ error = EAI_INSECUREDATA;
+ break;
+ default:
+ error = EAI_FAIL;
+ }
+ goto done;
+ }
+
+ /* Parse the response and construct the addrinfo chain */
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ isc_result_t result;
+ dns_rdataset_t *rdataset;
+ isc_buffer_t b;
+ isc_region_t r;
+ char t[1024];
+
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (!dns_rdataset_isassociated(rdataset))
+ continue;
+ if (rdataset->type != qtype)
+ continue;
+
+ if ((resstate->head->ai_flags & AI_CANONNAME) != 0) {
+ isc_buffer_init(&b, t, sizeof(t));
+ result = dns_name_totext(name, ISC_TRUE, &b);
+ if (result != ISC_R_SUCCESS) {
+ error = EAI_FAIL;
+ goto done;
+ }
+ isc_buffer_putuint8(&b, '\0');
+ isc_buffer_usedregion(&b, &r);
+ }
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ struct addrinfo *ai;
+ dns_rdata_t rdata;
+ dns_rdata_in_a_t rdata_a;
+ dns_rdata_in_aaaa_t rdata_aaaa;
+
+ ai = ai_alloc(family,
+ ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) :
+ sizeof(struct sockaddr_in)));
+ if (ai == NULL) {
+ error = EAI_MEMORY;
+ goto done;
+ }
+ ai->ai_socktype = resstate->head->ai_socktype;
+ ai->ai_next = trans->ai_sentinel.ai_next;
+ trans->ai_sentinel.ai_next = ai;
+
+ /*
+ * Set AF-specific parameters
+ * (IPv4/v6 address/port)
+ */
+ dns_rdata_init(&rdata);
+ switch (family) {
+ case AF_INET:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+
+ SIN(ai->ai_addr)->sin_port =
+ resstate->head->ai_port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr,
+ &rdata_a.in_addr, 4);
+ dns_rdata_freestruct(&rdata_a);
+ break;
+ case AF_INET6:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_aaaa,
+ NULL);
+ SIN6(ai->ai_addr)->sin6_port =
+ resstate->head->ai_port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr,
+ &rdata_aaaa.in6_addr, 16);
+ dns_rdata_freestruct(&rdata_aaaa);
+ break;
+ }
+
+ if ((resstate->head->ai_flags & AI_CANONNAME)
+ != 0) {
+ ai->ai_canonname =
+ strdup((const char *)r.base);
+ if (ai->ai_canonname == NULL) {
+ error = EAI_MEMORY;
+ goto done;
+ }
+ }
+ }
+ }
+ }
+
+ done:
+ dns_client_freeresanswer(resstate->head->dnsclient, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->xid);
+
+ isc_event_free(&event);
+
+ /* Make sure that error == 0 iff we have a non-empty list */
+ if (error == 0) {
+ if (trans->ai_sentinel.ai_next == NULL)
+ error = EAI_NONAME;
+ } else {
+ if (trans->ai_sentinel.ai_next != NULL) {
+ freeaddrinfo(trans->ai_sentinel.ai_next);
+ trans->ai_sentinel.ai_next = NULL;
+ }
+ }
+ trans->error = error;
+
+ /* Check whether we are done */
+ if ((resstate->trans4 == NULL || !resstate->trans4->is_inprogress) &&
+ (resstate->trans6 == NULL || !resstate->trans6->is_inprogress)) {
+ /*
+ * We're done for this state. If there is no other outstanding
+ * state, we can exit.
+ */
+ resstate->head->activestates--;
+ if (resstate->head->activestates == 0) {
+ isc_app_ctxsuspend(resstate->head->actx);
+ return;
+ }
+
+ /*
+ * There are outstanding states, but if we are at the head
+ * of the state list (i.e., at the highest search priority)
+ * and have any answer, we can stop now by canceling the
+ * others.
+ */
+ if (resstate == ISC_LIST_HEAD(resstate->head->resstates)) {
+ if ((resstate->trans4 != NULL &&
+ resstate->trans4->ai_sentinel.ai_next != NULL) ||
+ (resstate->trans6 != NULL &&
+ resstate->trans6->ai_sentinel.ai_next != NULL)) {
+ gai_resstate_t *rest;
+
+ for (rest = ISC_LIST_NEXT(resstate, link);
+ rest != NULL;
+ rest = ISC_LIST_NEXT(rest, link)) {
+ if (rest->trans4 != NULL &&
+ rest->trans4->xid != NULL)
+ dns_client_cancelresolve(
+ rest->trans4->xid);
+ if (rest->trans6 != NULL &&
+ rest->trans6->xid != NULL)
+ dns_client_cancelresolve(
+ rest->trans6->xid);
+ }
+ } else {
+ /*
+ * This search fails, so we move to the tail
+ * of the list so that the next entry will
+ * have the highest priority.
+ */
+ ISC_LIST_UNLINK(resstate->head->resstates,
+ resstate, link);
+ ISC_LIST_APPEND(resstate->head->resstates,
+ resstate, link);
+ }
+ }
+ }
+}
+
+static int
+resolve_name(int family, const char *hostname, int flags,
+ struct addrinfo **aip, int socktype, int port)
+{
+ isc_result_t result;
+ irs_context_t *irsctx;
+ irs_resconf_t *conf;
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ isc_task_t *task;
+ int terror = 0;
+ int error = 0;
+ dns_client_t *client;
+ gai_resstate_t *resstate;
+ gai_statehead_t head;
+ isc_boolean_t all_fail = ISC_TRUE;
+
+ /* get IRS context and the associated parameters */
+ irsctx = NULL;
+ result = irs_context_get(&irsctx);
+ if (result != ISC_R_SUCCESS)
+ return (EAI_FAIL);
+ actx = irs_context_getappctx(irsctx);
+
+ mctx = irs_context_getmctx(irsctx);
+ task = irs_context_gettask(irsctx);
+ conf = irs_context_getresconf(irsctx);
+ client = irs_context_getdnsclient(irsctx);
+
+ /* construct resolution states */
+ head.activestates = 0;
+ head.ai_family = family;
+ head.ai_socktype = socktype;
+ head.ai_flags = flags;
+ head.ai_port = port;
+ head.actx = actx;
+ head.dnsclient = client;
+ ISC_LIST_INIT(head.resstates);
+ result = make_resstates(mctx, hostname, &head, conf);
+ if (result != ISC_R_SUCCESS)
+ return (EAI_FAIL);
+
+ for (resstate = ISC_LIST_HEAD(head.resstates);
+ resstate != NULL; resstate = ISC_LIST_NEXT(resstate, link)) {
+ if (resstate->trans4 != NULL) {
+ result = dns_client_startresolve(client,
+ resstate->qname,
+ dns_rdataclass_in,
+ dns_rdatatype_a,
+ 0, task,
+ process_answer,
+ resstate->trans4,
+ &resstate->trans4->xid);
+ if (result == ISC_R_SUCCESS) {
+ resstate->trans4->is_inprogress = ISC_TRUE;
+ all_fail = ISC_FALSE;
+ } else
+ resstate->trans4->is_inprogress = ISC_FALSE;
+ }
+ if (resstate->trans6 != NULL) {
+ result = dns_client_startresolve(client,
+ resstate->qname,
+ dns_rdataclass_in,
+ dns_rdatatype_aaaa,
+ 0, task,
+ process_answer,
+ resstate->trans6,
+ &resstate->trans6->xid);
+ if (result == ISC_R_SUCCESS) {
+ resstate->trans6->is_inprogress = ISC_TRUE;
+ all_fail = ISC_FALSE;
+ } else
+ resstate->trans6->is_inprogress= ISC_FALSE;
+ }
+ }
+ if (!all_fail) {
+ /* Start all the events */
+ isc_app_ctxrun(actx);
+ } else
+ error = EAI_FAIL;
+
+ /* Cleanup */
+ while ((resstate = ISC_LIST_HEAD(head.resstates)) != NULL) {
+ int terror4 = 0, terror6 = 0;
+
+ ISC_LIST_UNLINK(head.resstates, resstate, link);
+
+ if (*aip == NULL) {
+ struct addrinfo *sentinel4 = NULL;
+ struct addrinfo *sentinel6 = NULL;
+
+ if (resstate->trans4 != NULL) {
+ sentinel4 =
+ resstate->trans4->ai_sentinel.ai_next;
+ resstate->trans4->ai_sentinel.ai_next = NULL;
+ }
+ if (resstate->trans6 != NULL) {
+ sentinel6 =
+ resstate->trans6->ai_sentinel.ai_next;
+ resstate->trans6->ai_sentinel.ai_next = NULL;
+ }
+ *aip = ai_concat(sentinel4, sentinel6);
+ }
+
+ if (resstate->trans4 != NULL) {
+ INSIST(resstate->trans4->xid == NULL);
+ terror4 = resstate->trans4->error;
+ isc_mem_put(mctx, resstate->trans4,
+ sizeof(*resstate->trans4));
+ }
+ if (resstate->trans6 != NULL) {
+ INSIST(resstate->trans6->xid == NULL);
+ terror6 = resstate->trans6->error;
+ isc_mem_put(mctx, resstate->trans6,
+ sizeof(*resstate->trans6));
+ }
+
+ /*
+ * If the entire lookup fails, we need to choose an appropriate
+ * error code from individual codes. We'll try to provide as
+ * specific a code as possible. In general, we are going to
+ * find an error code other than EAI_NONAME (which is too
+ * generic and may actually not be problematic in some cases).
+ * EAI_NONAME will be set below if no better code is found.
+ */
+ if (terror == 0 || terror == EAI_NONAME) {
+ if (terror4 != 0 && terror4 != EAI_NONAME)
+ terror = terror4;
+ else if (terror6 != 0 && terror6 != EAI_NONAME)
+ terror = terror6;
+ }
+
+ isc_mem_put(mctx, resstate, sizeof(*resstate));
+ }
+
+ if (*aip == NULL) {
+ error = terror;
+ if (error == 0)
+ error = EAI_NONAME;
+ }
+
+#if 1 /* XXX: enabled for finding leaks. should be cleaned up later. */
+ isc_app_ctxfinish(actx);
+ irs_context_destroy(&irsctx);
+#endif
+
+ return (error);
+}
+
+static char *
+irs_strsep(char **stringp, const char *delim) {
+ char *string = *stringp;
+ char *s;
+ const char *d;
+ char sc, dc;
+
+ if (string == NULL)
+ return (NULL);
+
+ for (s = string; *s != '\0'; s++) {
+ sc = *s;
+ for (d = delim; (dc = *d) != '\0'; d++)
+ if (sc == dc) {
+ *s++ = '\0';
+ *stringp = s;
+ return (string);
+ }
+ }
+ *stringp = NULL;
+ return (string);
+}
+
+static void
+set_order(int family, int (**net_order)(const char *, int, struct addrinfo **,
+ int, int))
+{
+ char *order, *tok;
+ int found;
+
+ if (family) {
+ switch (family) {
+ case AF_INET:
+ *net_order++ = add_ipv4;
+ break;
+ case AF_INET6:
+ *net_order++ = add_ipv6;
+ break;
+ }
+ } else {
+ order = getenv("NET_ORDER");
+ found = 0;
+ while (order != NULL) {
+ /*
+ * We ignore any unknown names.
+ */
+ tok = irs_strsep(&order, ":");
+ if (strcasecmp(tok, "inet6") == 0) {
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ found |= FOUND_IPV6;
+ } else if (strcasecmp(tok, "inet") == 0 ||
+ strcasecmp(tok, "inet4") == 0) {
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ found |= FOUND_IPV4;
+ }
+ }
+
+ /*
+ * Add in anything that we didn't find.
+ */
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ }
+ *net_order = NULL;
+ return;
+}
+
+static char v4_loop[4] = { 127, 0, 0, 1 };
+
+static int
+add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+
+ UNUSED(hostname);
+ UNUSED(flags);
+
+ ai = ai_clone(*aip, AF_INET); /* don't use ai_clone() */
+ if (ai == NULL) {
+ freeaddrinfo(*aip);
+ return (EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
+
+ return (0);
+}
+
+static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static int
+add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+
+ UNUSED(hostname);
+ UNUSED(flags);
+
+ ai = ai_clone(*aip, AF_INET6); /* don't use ai_clone() */
+ if (ai == NULL) {
+ freeaddrinfo(*aip);
+ return (EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
+
+ return (0);
+}
+
+/*% Free address info. */
+void
+freeaddrinfo(struct addrinfo *ai) {
+ struct addrinfo *ai_next;
+
+ while (ai != NULL) {
+ ai_next = ai->ai_next;
+ if (ai->ai_addr != NULL)
+ free(ai->ai_addr);
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ free(ai);
+ ai = ai_next;
+ }
+}
+
+#ifdef AF_LOCAL
+static int
+get_local(const char *name, int socktype, struct addrinfo **res) {
+ struct addrinfo *ai;
+ struct sockaddr_un *slocal;
+
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+
+ ai = ai_alloc(AF_LOCAL, sizeof(*slocal));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+
+ slocal = SLOCAL(ai->ai_addr);
+ strncpy(slocal->sun_path, name, sizeof(slocal->sun_path));
+
+ ai->ai_socktype = socktype;
+ /*
+ * ai->ai_flags, ai->ai_protocol, ai->ai_canonname,
+ * and ai->ai_next were initialized to zero.
+ */
+
+ *res = ai;
+ return (0);
+}
+#endif
+
+/*!
+ * Allocate an addrinfo structure, and a sockaddr structure
+ * of the specificed length. We initialize:
+ * ai_addrlen
+ * ai_family
+ * ai_addr
+ * ai_addr->sa_family
+ * ai_addr->sa_len (IRS_PLATFORM_HAVESALEN)
+ * and everything else is initialized to zero.
+ */
+static struct addrinfo *
+ai_alloc(int family, int addrlen) {
+ struct addrinfo *ai;
+
+ ai = (struct addrinfo *)calloc(1, sizeof(*ai));
+ if (ai == NULL)
+ return (NULL);
+
+ ai->ai_addr = SA(calloc(1, addrlen));
+ if (ai->ai_addr == NULL) {
+ free(ai);
+ return (NULL);
+ }
+ ai->ai_addrlen = addrlen;
+ ai->ai_family = family;
+ ai->ai_addr->sa_family = family;
+#ifdef IRS_PLATFORM_HAVESALEN
+ ai->ai_addr->sa_len = addrlen;
+#endif
+ return (ai);
+}
+
+static struct addrinfo *
+ai_clone(struct addrinfo *oai, int family) {
+ struct addrinfo *ai;
+
+ ai = ai_alloc(family, ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
+
+ if (ai == NULL) {
+ if (oai != NULL)
+ freeaddrinfo(oai);
+ return (NULL);
+ }
+ if (oai == NULL)
+ return (ai);
+
+ ai->ai_flags = oai->ai_flags;
+ ai->ai_socktype = oai->ai_socktype;
+ ai->ai_protocol = oai->ai_protocol;
+ ai->ai_canonname = NULL;
+ ai->ai_next = oai;
+ return (ai);
+}
+
+static struct addrinfo *
+ai_reverse(struct addrinfo *oai) {
+ struct addrinfo *nai, *tai;
+
+ nai = NULL;
+
+ while (oai != NULL) {
+ /*
+ * Grab one off the old list.
+ */
+ tai = oai;
+ oai = oai->ai_next;
+ /*
+ * Put it on the front of the new list.
+ */
+ tai->ai_next = nai;
+ nai = tai;
+ }
+ return (nai);
+}
+
+
+static struct addrinfo *
+ai_concat(struct addrinfo *ai1, struct addrinfo *ai2) {
+ struct addrinfo *ai_tmp;
+
+ if (ai1 == NULL)
+ return (ai2);
+ else if (ai2 == NULL)
+ return (ai1);
+
+ for (ai_tmp = ai1; ai_tmp != NULL && ai_tmp->ai_next != NULL;
+ ai_tmp = ai_tmp->ai_next)
+ ;
+
+ ai_tmp->ai_next = ai2;
+
+ return (ai1);
+}
diff --git a/lib/irs/getnameinfo.c b/lib/irs/getnameinfo.c
new file mode 100644
index 00000000..0b674dbd
--- /dev/null
+++ b/lib/irs/getnameinfo.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: getnameinfo.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * getnameinfo() returns the hostname for the struct sockaddr sa which is
+ * salen bytes long. The hostname is of length hostlen and is returned via
+ * *host. The maximum length of the hostname is 1025 bytes: #NI_MAXHOST.
+ *
+ * The name of the service associated with the port number in sa is
+ * returned in *serv. It is servlen bytes long. The maximum length of the
+ * service name is #NI_MAXSERV - 32 bytes.
+ *
+ * The flags argument sets the following bits:
+ *
+ * \li #NI_NOFQDN:
+ * A fully qualified domain name is not required for local hosts.
+ * The local part of the fully qualified domain name is returned
+ * instead.
+ *
+ * \li #NI_NUMERICHOST
+ * Return the address in numeric form, as if calling inet_ntop(),
+ * instead of a host name.
+ *
+ * \li #NI_NAMEREQD
+ * A name is required. If the hostname cannot be found in the DNS
+ * and this flag is set, a non-zero error code is returned. If the
+ * hostname is not found and the flag is not set, the address is
+ * returned in numeric form.
+ *
+ * \li #NI_NUMERICSERV
+ * The service name is returned as a digit string representing the
+ * port number.
+ *
+ * \li #NI_DGRAM
+ * Specifies that the service being looked up is a datagram
+ * service, and causes getservbyport() to be called with a second
+ * argument of "udp" instead of its default of "tcp". This is
+ * required for the few ports (512-514) that have different
+ * services for UDP and TCP.
+ *
+ * \section getnameinfo_return Return Values
+ *
+ * getnameinfo() returns 0 on success or a non-zero error code if
+ * an error occurs.
+ *
+ * \section getname_see See Also
+ *
+ * RFC3493, getservbyport(),
+ * getnamebyaddr(). inet_ntop().
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/byaddr.h>
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/result.h>
+
+#include <irs/context.h>
+#include <irs/netdb.h>
+
+#define SUCCESS 0
+
+/*% afd structure definition */
+static struct afd {
+ int a_af;
+ size_t a_addrlen;
+ size_t a_socklen;
+} afdl [] = {
+ /*!
+ * First entry is linked last...
+ */
+ { AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) },
+ { AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) },
+ {0, 0, 0},
+};
+
+/*!
+ * The test against 0 is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
+ */
+#define ERR(code) \
+ do { result = (code); \
+ if (result != 0) goto cleanup; \
+ } while (0)
+
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
+ IRS_GETNAMEINFO_BUFLEN_T hostlen, char *serv,
+ IRS_GETNAMEINFO_BUFLEN_T servlen, IRS_GETNAMEINFO_FLAGS_T flags)
+{
+ struct afd *afd;
+ struct servent *sp;
+ unsigned short port;
+#ifdef IRS_PLATFORM_HAVESALEN
+ size_t len;
+#endif
+ int family, i;
+ const void *addr;
+ char *p;
+#if 0
+ unsigned long v4a;
+ unsigned char pfx;
+#endif
+ char numserv[sizeof("65000")];
+ char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255")
+ + 1 + sizeof("4294967295")];
+ const char *proto;
+ int result = SUCCESS;
+
+ if (sa == NULL)
+ ERR(EAI_FAIL);
+
+#ifdef IRS_PLATFORM_HAVESALEN
+ len = sa->sa_len;
+ if (len != salen)
+ ERR(EAI_FAIL);
+#endif
+
+ family = sa->sa_family;
+ for (i = 0; afdl[i].a_af; i++)
+ if (afdl[i].a_af == family) {
+ afd = &afdl[i];
+ goto found;
+ }
+ ERR(EAI_FAMILY);
+
+ found:
+ if (salen != afd->a_socklen)
+ ERR(EAI_FAIL);
+
+ switch (family) {
+ case AF_INET:
+ port = ((const struct sockaddr_in *)sa)->sin_port;
+ addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr;
+ break;
+
+ case AF_INET6:
+ port = ((const struct sockaddr_in6 *)sa)->sin6_port;
+ addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
+ break;
+
+ default:
+ port = 0;
+ addr = NULL;
+ INSIST(0);
+ }
+ proto = (flags & NI_DGRAM) ? "udp" : "tcp";
+
+ if (serv == NULL || servlen == 0U) {
+ /*
+ * Caller does not want service.
+ */
+ } else if ((flags & NI_NUMERICSERV) != 0 ||
+ (sp = getservbyport(port, proto)) == NULL) {
+ snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
+ if ((strlen(numserv) + 1) > servlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(serv, numserv);
+ } else {
+ if ((strlen(sp->s_name) + 1) > servlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(serv, sp->s_name);
+ }
+
+#if 0
+ switch (sa->sa_family) {
+ case AF_INET:
+ v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ flags |= NI_NUMERICHOST;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ flags |= NI_NUMERICHOST;
+ break;
+
+ case AF_INET6:
+ pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ flags |= NI_NUMERICHOST;
+ break;
+ }
+#endif
+
+ if (host == NULL || hostlen == 0U) {
+ /*
+ * do nothing in this case.
+ * in case you are wondering if "&&" is more correct than
+ * "||" here: RFC3493 says that host == NULL or hostlen == 0
+ * means that the caller does not want the result.
+ */
+ } else if ((flags & NI_NUMERICHOST) != 0) {
+ if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ ERR(EAI_SYSTEM);
+#if defined(IRS_HAVE_SIN6_SCOPE_ID)
+ if (afd->a_af == AF_INET6 &&
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ char *p = numaddr + strlen(numaddr);
+ const char *stringscope = NULL;
+#ifdef VENDOR_SPECIFIC
+ /*
+ * Vendors may want to add support for
+ * non-numeric scope identifier.
+ */
+ stringscope = foo;
+#endif
+ if (stringscope == NULL) {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%u",
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id);
+ } else {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%s", stringscope);
+ }
+ }
+#endif
+ if (strlen(numaddr) + 1 > hostlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(host, numaddr);
+ } else {
+ isc_netaddr_t netaddr;
+ dns_fixedname_t ptrfname;
+ dns_name_t *ptrname;
+ irs_context_t *irsctx = NULL;
+ dns_client_t *client;
+ isc_boolean_t found = ISC_FALSE;
+ dns_namelist_t answerlist;
+ dns_rdataset_t *rdataset;
+ isc_region_t hostregion;
+ char hoststr[1024]; /* is this enough? */
+ isc_result_t iresult;
+
+ /* Get IRS context and the associated DNS client object */
+ iresult = irs_context_get(&irsctx);
+ if (iresult != ISC_R_SUCCESS)
+ ERR(EAI_FAIL);
+ client = irs_context_getdnsclient(irsctx);
+
+ /* Make query name */
+ isc_netaddr_fromsockaddr(&netaddr, (const isc_sockaddr_t *)sa);
+ dns_fixedname_init(&ptrfname);
+ ptrname = dns_fixedname_name(&ptrfname);
+ iresult = dns_byaddr_createptrname2(&netaddr, 0, ptrname);
+ if (iresult != ISC_R_SUCCESS)
+ ERR(EAI_FAIL);
+
+ /* Get the PTR RRset */
+ ISC_LIST_INIT(answerlist);
+ iresult = dns_client_resolve(client, ptrname,
+ dns_rdataclass_in,
+ dns_rdatatype_ptr,
+ DNS_CLIENTRESOPT_ALLOWRUN,
+ &answerlist);
+ switch (iresult) {
+ case ISC_R_SUCCESS:
+ /*
+ * a 'non-existent' error is not necessarily fatal for
+ * getnameinfo().
+ */
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NCACHENXRRSET:
+ break;
+ case DNS_R_SIGINVALID:
+ case DNS_R_SIGEXPIRED:
+ case DNS_R_SIGFUTURE:
+ case DNS_R_KEYUNAUTHORIZED:
+ case DNS_R_MUSTBESECURE:
+ case DNS_R_COVERINGNSEC:
+ case DNS_R_NOTAUTHORITATIVE:
+ case DNS_R_NOVALIDKEY:
+ case DNS_R_NOVALIDDS:
+ case DNS_R_NOVALIDSIG:
+ ERR(EAI_INSECUREDATA);
+ default:
+ ERR(EAI_FAIL);
+ }
+
+ /* Parse the answer for the hostname */
+ for (ptrname = ISC_LIST_HEAD(answerlist); ptrname != NULL;
+ ptrname = ISC_LIST_NEXT(ptrname, link)) {
+ for (rdataset = ISC_LIST_HEAD(ptrname->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (!dns_rdataset_isassociated(rdataset))
+ continue;
+ if (rdataset->type != dns_rdatatype_ptr)
+ continue;
+
+ for (iresult = dns_rdataset_first(rdataset);
+ iresult == ISC_R_SUCCESS;
+ iresult = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata;
+ dns_rdata_ptr_t rdata_ptr;
+ isc_buffer_t b;
+
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_ptr,
+ NULL);
+
+ isc_buffer_init(&b, hoststr,
+ sizeof(hoststr));
+ iresult =
+ dns_name_totext(&rdata_ptr.ptr,
+ ISC_TRUE, &b);
+ dns_rdata_freestruct(&rdata_ptr);
+ if (iresult == ISC_R_SUCCESS) {
+ /*
+ * We ignore the rest of the
+ * answer. After all,
+ * getnameinfo() can return
+ * at most one hostname.
+ */
+ found = ISC_TRUE;
+ isc_buffer_usedregion(
+ &b, &hostregion);
+ goto ptrfound;
+ }
+
+ }
+ }
+ }
+ ptrfound:
+ dns_client_freeresanswer(client, &answerlist);
+ if (found) {
+ if ((flags & NI_NOFQDN) != 0) {
+ p = strchr(hoststr, '.');
+ if (p)
+ *p = '\0';
+ }
+ if (hostregion.length + 1 > hostlen)
+ ERR(EAI_OVERFLOW);
+ snprintf(host, hostlen, "%.*s",
+ (int)hostregion.length,
+ (char *)hostregion.base);
+ } else {
+ if ((flags & NI_NAMEREQD) != 0)
+ ERR(EAI_NONAME);
+ if (inet_ntop(afd->a_af, addr, numaddr,
+ sizeof(numaddr)) == NULL)
+ ERR(EAI_SYSTEM);
+ if ((strlen(numaddr) + 1) > hostlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(host, numaddr);
+ }
+ }
+ result = SUCCESS;
+
+ cleanup:
+ return (result);
+}
diff --git a/lib/irs/include/Makefile.in b/lib/irs/include/Makefile.in
new file mode 100644
index 00000000..eca19452
--- /dev/null
+++ b/lib/irs/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = irs
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/irs/include/irs/Makefile.in b/lib/irs/include/irs/Makefile.in
new file mode 100644
index 00000000..3c3b6127
--- /dev/null
+++ b/lib/irs/include/irs/Makefile.in
@@ -0,0 +1,44 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/irs
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/irs ; \
+ done
+ ${INSTALL_DATA} netdb.h ${DESTDIR}${includedir}/irs
+ ${INSTALL_DATA} platform.h ${DESTDIR}${includedir}/irs
+
+distclean::
+ rm -f netdb.h platform.h
diff --git a/lib/irs/include/irs/context.h b/lib/irs/include/irs/context.h
new file mode 100644
index 00000000..f2ef3f47
--- /dev/null
+++ b/lib/irs/include/irs/context.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: context.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_CONTEXT_H
+#define IRS_CONTEXT_H 1
+
+/*! \file
+ *
+ * \brief
+ * The IRS context module provides an abstract interface to the DNS library
+ * with an application. An IRS context object initializes and holds various
+ * resources used in the DNS library.
+ */
+
+#include <dns/types.h>
+#include <irs/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+irs_context_create(irs_context_t **contextp);
+/*%<
+ * Create an IRS context. It internally initializes the ISC and DNS libraries
+ * (if not yet), creates a DNS client object and initializes the client using
+ * the configuration files parsed via the 'resconf' and 'dnsconf' IRS modules.
+ * Some of the internally initialized objects can be used by the application
+ * via irs_context_getxxx() functions (see below).
+ *
+ * Requires:
+ *
+ *\li contextp != NULL && *contextp == NULL.
+ */
+
+isc_result_t
+irs_context_get(irs_context_t **contextp);
+/*%<
+ * Return an IRS context for the calling thread. If no IRS context is
+ * associated to the thread, this function creates a new one by calling
+ * irs_context_create(), and associates it with the thread as a thread specific
+ * data value. This function is provided for standard libraries that are
+ * expected to be thread-safe but do not accept an appropriate IRS context
+ * as a library parameter, e.g., getaddrinfo().
+ *
+ * Requires:
+ *
+ *\li contextp != NULL && *contextp == NULL.
+ */
+
+void
+irs_context_destroy(irs_context_t **contextp);
+/*%<
+ * Destroy an IRS context.
+ *
+ * Requires:
+ *
+ *\li '*contextp' is a valid IRS context.
+ *
+ * Ensures:
+ *\li '*contextp' == NULL.
+ */
+
+isc_mem_t *
+irs_context_getmctx(irs_context_t *context);
+/*%<
+ * Return the memory context held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_appctx_t *
+irs_context_getappctx(irs_context_t *context);
+/*%<
+ * Return the application context held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_taskmgr_t *
+irs_context_gettaskmgr(irs_context_t *context);
+/*%<
+ * Return the task manager held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_timermgr_t *
+irs_context_gettimermgr(irs_context_t *context);
+/*%<
+ * Return the timer manager held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_task_t *
+irs_context_gettask(irs_context_t *context);
+/*%<
+ * Return the task object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+dns_client_t *
+irs_context_getdnsclient(irs_context_t *context);
+/*%<
+ * Return the DNS client object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+irs_resconf_t *
+irs_context_getresconf(irs_context_t *context);
+/*%<
+ * Return the resolver configuration object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+irs_dnsconf_t *
+irs_context_getdnsconf(irs_context_t *context);
+/*%<
+ * Return the advanced DNS configuration object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* IRS_CONTEXT_H */
diff --git a/lib/irs/include/irs/dnsconf.h b/lib/irs/include/irs/dnsconf.h
new file mode 100644
index 00000000..4f673ff2
--- /dev/null
+++ b/lib/irs/include/irs/dnsconf.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: dnsconf.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_DNSCONF_H
+#define IRS_DNSCONF_H 1
+
+/*! \file
+ *
+ * \brief
+ * The IRS dnsconf module parses an "advanced" configuration file related to
+ * the DNS library, such as trusted keys for DNSSEC validation, and creates
+ * the corresponding configuration objects for the DNS library modules.
+ *
+ * Notes:
+ * This module is very experimental and the configuration syntax or library
+ * interfaces may change in future versions. Currently, only the
+ * 'trusted-keys' statement is supported, whose syntax is the same as the
+ * same name of statement for named.conf.
+ */
+
+#include <irs/types.h>
+
+/*%
+ * A compound structure storing DNS key information mainly for DNSSEC
+ * validation. A dns_key_t object will be created using the 'keyname' and
+ * 'keydatabuf' members with the dst_key_fromdns() function.
+ */
+typedef struct irs_dnsconf_dnskey {
+ dns_name_t *keyname;
+ isc_buffer_t *keydatabuf;
+ ISC_LINK(struct irs_dnsconf_dnskey) link;
+} irs_dnsconf_dnskey_t;
+
+typedef ISC_LIST(irs_dnsconf_dnskey_t) irs_dnsconf_dnskeylist_t;
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp);
+/*%<
+ * Load the "advanced" DNS configuration file 'filename' in the "dns.conf"
+ * format, and create a new irs_dnsconf_t object from the configuration.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'filename' != NULL
+ *
+ *\li 'confp' != NULL && '*confp' == NULL
+ */
+
+void
+irs_dnsconf_destroy(irs_dnsconf_t **confp);
+/*%<
+ * Destroy the dnsconf object.
+ *
+ * Requires:
+ *
+ *\li '*confp' is a valid dnsconf object.
+ *
+ * Ensures:
+ *
+ *\li *confp == NULL
+ */
+
+irs_dnsconf_dnskeylist_t *
+irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf);
+/*%<
+ * Return a list of key information stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid dnsconf object.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* IRS_DNSCONF_H */
diff --git a/lib/irs/include/irs/netdb.h.in b/lib/irs/include/irs/netdb.h.in
new file mode 100644
index 00000000..299928b9
--- /dev/null
+++ b/lib/irs/include/irs/netdb.h.in
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: netdb.h.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#ifndef IRS_NETDB_H
+#define IRS_NETDB_H 1
+
+#include <stddef.h> /* Required on FreeBSD (and others?) for size_t. */
+#include <netdb.h> /* Contractual provision. */
+
+/*
+ * Define if <netdb.h> does not declare struct addrinfo.
+ */
+@ISC_IRS_NEEDADDRINFO@
+
+#ifdef ISC_IRS_NEEDADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for hostname */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+#endif
+
+/*
+ * Undefine all #defines we are interested in as <netdb.h> may or may not have
+ * defined them.
+ */
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#undef NETDB_INTERNAL
+#undef NETDB_SUCCESS
+#undef HOST_NOT_FOUND
+#undef TRY_AGAIN
+#undef NO_RECOVERY
+#undef NO_DATA
+#undef NO_ADDRESS
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo(). EAI_INSECUREDATA is our own extension
+ * and it's very unlikely to be already defined, but undef it just in case; it
+ * at least doesn't do any harm.
+ */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_OVERFLOW
+#undef EAI_INSECUREDATA
+#undef EAI_MAX
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_OVERFLOW 14
+#define EAI_INSECUREDATA 15
+#define EAI_MAX 16
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+
+#define AI_PASSIVE 0x00000001
+#define AI_CANONNAME 0x00000002
+#define AI_NUMERICHOST 0x00000004
+
+/*
+ * Flag values for getipnodebyname()
+ */
+#undef AI_V4MAPPED
+#undef AI_ALL
+#undef AI_ADDRCONFIG
+#undef AI_DEFAULT
+
+#define AI_V4MAPPED 0x00000008
+#define AI_ALL 0x00000010
+#define AI_ADDRCONFIG 0x00000020
+#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
+
+/*
+ * Constants for lwres_getnameinfo()
+ */
+#undef NI_MAXHOST
+#undef NI_MAXSERV
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+/*
+ * Flag values for lwres_getnameinfo()
+ */
+#undef NI_NOFQDN
+#undef NI_NUMERICHOST
+#undef NI_NAMEREQD
+#undef NI_NUMERICSERV
+#undef NI_DGRAM
+#undef NI_NUMERICSCOPE
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* IRS_NETDB_H */
diff --git a/lib/irs/include/irs/platform.h.in b/lib/irs/include/irs/platform.h.in
new file mode 100644
index 00000000..0e9be3ce
--- /dev/null
+++ b/lib/irs/include/irs/platform.h.in
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: platform.h.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#ifndef IRS_PLATFORM_H
+#define IRS_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+#ifndef IRS_PLATFORM_USEDECLSPEC
+#define LIBIRS_EXTERNAL_DATA
+#else
+#ifdef LIBIRS_EXPORTS
+#define LIBIRS_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBIRS_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* IRS_PLATFORM_H */
diff --git a/lib/irs/include/irs/resconf.h b/lib/irs/include/irs/resconf.h
new file mode 100644
index 00000000..78c87d51
--- /dev/null
+++ b/lib/irs/include/irs/resconf.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: resconf.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_RESCONF_H
+#define IRS_RESCONF_H 1
+
+/*! \file
+ *
+ * \brief
+ * The IRS resconf module parses the legacy "/etc/resolv.conf" file and
+ * creates the corresponding configuration objects for the DNS library
+ * modules.
+ */
+
+#include <irs/types.h>
+
+/*%
+ * A DNS search list specified in the 'domain' or 'search' statements
+ * in the "resolv.conf" file.
+ */
+typedef struct irs_resconf_search {
+ char *domain;
+ ISC_LINK(struct irs_resconf_search) link;
+} irs_resconf_search_t;
+
+typedef ISC_LIST(irs_resconf_search_t) irs_resconf_searchlist_t;
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp);
+/*%<
+ * Load the resolver configuration file 'filename' in the "resolv.conf" format,
+ * and create a new irs_resconf_t object from the configuration.
+ *
+ * Notes:
+ *
+ *\li Currently, only the following options are supported:
+ * nameserver, domain, search, sortlist, ndots, and options.
+ * In addition, 'sortlist' is not actually effective; it's parsed, but
+ * the application cannot use the configuration.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'filename' != NULL
+ *
+ *\li 'confp' != NULL && '*confp' == NULL
+ */
+
+void
+irs_resconf_destroy(irs_resconf_t **confp);
+/*%<
+ * Destroy the resconf object.
+ *
+ * Requires:
+ *
+ *\li '*confp' is a valid resconf object.
+ *
+ * Ensures:
+ *
+ *\li *confp == NULL
+ */
+
+isc_sockaddrlist_t *
+irs_resconf_getnameservers(irs_resconf_t *conf);
+/*%<
+ * Return a list of name server addresses stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+irs_resconf_searchlist_t *
+irs_resconf_getsearchlist(irs_resconf_t *conf);
+/*%<
+ * Return the search list stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+unsigned int
+irs_resconf_getndots(irs_resconf_t *conf);
+/*%<
+ * Return the 'ndots' value stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* IRS_RESCONF_H */
diff --git a/lib/irs/include/irs/types.h b/lib/irs/include/irs/types.h
new file mode 100644
index 00000000..0a539dec
--- /dev/null
+++ b/lib/irs/include/irs/types.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: types.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_TYPES_H
+#define IRS_TYPES_H 1
+
+/* Core Types. Alphabetized by defined type. */
+
+/*%< per-thread IRS context */
+typedef struct irs_context irs_context_t;
+/*%< resolv.conf configuration information */
+typedef struct irs_resconf irs_resconf_t;
+/*%< advanced DNS-related configuration information */
+typedef struct irs_dnsconf irs_dnsconf_t;
+
+#endif /* IRS_TYPES_H */
diff --git a/lib/irs/include/irs/version.h b/lib/irs/include/irs/version.h
new file mode 100644
index 00000000..bd7e5cf8
--- /dev/null
+++ b/lib/irs/include/irs/version.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: version.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <irs/platform.h>
+
+LIBIRS_EXTERNAL_DATA extern const char irs_version[];
+
+LIBIRS_EXTERNAL_DATA extern const unsigned int irs_libinterface;
+LIBIRS_EXTERNAL_DATA extern const unsigned int irs_librevision;
+LIBIRS_EXTERNAL_DATA extern const unsigned int irs_libage;
diff --git a/lib/irs/resconf.c b/lib/irs/resconf.c
new file mode 100644
index 00000000..f3181a30
--- /dev/null
+++ b/lib/irs/resconf.c
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: resconf.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file resconf.c */
+
+/**
+ * Module for parsing resolv.conf files (largely derived from lwconfig.c).
+ *
+ * irs_resconf_load() opens the file filename and parses it to initialize
+ * the configuration structure.
+ *
+ * \section lwconfig_return Return Values
+ *
+ * irs_resconf_load() returns #IRS_R_SUCCESS if it successfully read and
+ * parsed filename. It returns a non-0 error code if filename could not be
+ * opened or contained incorrect resolver statements.
+ *
+ * \section lwconfig_see See Also
+ *
+ * stdio(3), \link resolver resolver \endlink
+ *
+ * \section files Files
+ *
+ * /etc/resolv.conf
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/netaddr.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <irs/resconf.h>
+
+#define IRS_RESCONF_MAGIC ISC_MAGIC('R', 'E', 'S', 'c')
+#define IRS_RESCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_RESCONF_MAGIC)
+
+/*!
+ * protocol constants
+ */
+
+#if ! defined(NS_INADDRSZ)
+#define NS_INADDRSZ 4
+#endif
+
+#if ! defined(NS_IN6ADDRSZ)
+#define NS_IN6ADDRSZ 16
+#endif
+
+/*!
+ * resolv.conf parameters
+ */
+
+#define RESCONFMAXNAMESERVERS 3 /*%< max 3 "nameserver" entries */
+#define RESCONFMAXSEARCH 8 /*%< max 8 domains in "search" entry */
+#define RESCONFMAXLINELEN 256 /*%< max size of a line */
+#define RESCONFMAXSORTLIST 10 /*%< max 10 */
+
+/*!
+ * configuration data structure
+ */
+
+struct irs_resconf {
+ /*
+ * The configuration data is a thread-specific object, and does not
+ * need to be locked.
+ */
+ unsigned int magic;
+ isc_mem_t *mctx;
+
+ isc_sockaddrlist_t nameservers;
+ unsigned int numns; /*%< number of configured servers */
+
+ char *domainname;
+ char *search[RESCONFMAXSEARCH];
+ isc_uint8_t searchnxt; /*%< index for next free slot */
+
+ irs_resconf_searchlist_t searchlist;
+
+ struct {
+ isc_netaddr_t addr;
+ /*% mask has a non-zero 'family' if set */
+ isc_netaddr_t mask;
+ } sortlist[RESCONFMAXSORTLIST];
+ isc_uint8_t sortlistnxt;
+
+ /*%< non-zero if 'options debug' set */
+ isc_uint8_t resdebug;
+ /*%< set to n in 'options ndots:n' */
+ isc_uint8_t ndots;
+};
+
+static isc_result_t
+resconf_parsenameserver(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parsedomain(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parsesearch(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parsesortlist(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parseoption(irs_resconf_t *ctx, FILE *fp);
+
+/*!
+ * Eat characters from FP until EOL or EOF. Returns EOF or '\n'
+ */
+static int
+eatline(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF)
+ ch = fgetc(fp);
+
+ return (ch);
+}
+
+/*!
+ * Eats white space up to next newline or non-whitespace character (of
+ * EOF). Returns the last character read. Comments are considered white
+ * space.
+ */
+static int
+eatwhite(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
+ ch = fgetc(fp);
+
+ if (ch == ';' || ch == '#')
+ ch = eatline(fp);
+
+ return (ch);
+}
+
+/*!
+ * Skip over any leading whitespace and then read in the next sequence of
+ * non-whitespace characters. In this context newline is not considered
+ * whitespace. Returns EOF on end-of-file, or the character
+ * that caused the reading to stop.
+ */
+static int
+getword(FILE *fp, char *buffer, size_t size) {
+ int ch;
+ char *p = buffer;
+
+ REQUIRE(buffer != NULL);
+ REQUIRE(size > 0U);
+
+ *p = '\0';
+
+ ch = eatwhite(fp);
+
+ if (ch == EOF)
+ return (EOF);
+
+ do {
+ *p = '\0';
+
+ if (ch == EOF || isspace((unsigned char)ch))
+ break;
+ else if ((size_t) (p - buffer) == size - 1)
+ return (EOF); /* Not enough space. */
+
+ *p++ = (char)ch;
+ ch = fgetc(fp);
+ } while (1);
+
+ return (ch);
+}
+
+static isc_result_t
+add_server(isc_mem_t *mctx, const char *address_str,
+ isc_sockaddrlist_t *nameservers)
+{
+ int error;
+ isc_sockaddr_t *address = NULL;
+ struct addrinfo hints, *res;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ res = NULL;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ error = getaddrinfo(address_str, "53", &hints, &res);
+ if (error != 0)
+ return (ISC_R_BADADDRESSFORM);
+
+ /* XXX: special case: treat all-0 IPv4 address as loopback */
+ if (res->ai_family == AF_INET) {
+ struct in_addr *v4;
+ unsigned char zeroaddress[] = {0, 0, 0, 0};
+ unsigned char loopaddress[] = {127, 0, 0, 1};
+
+ v4 = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
+ if (memcmp(v4, zeroaddress, 4) == 0)
+ memcpy(v4, loopaddress, 4);
+ }
+
+ address = isc_mem_get(mctx, sizeof(*address));
+ if (address == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ if (res->ai_addrlen > sizeof(address->type)) {
+ isc_mem_put(mctx, address, sizeof(*address));
+ result = ISC_R_RANGE;
+ goto cleanup;
+ }
+ address->length = res->ai_addrlen;
+ memcpy(&address->type.sa, res->ai_addr, res->ai_addrlen);
+ ISC_LINK_INIT(address, link);
+ ISC_LIST_APPEND(*nameservers, address, link);
+
+ cleanup:
+ freeaddrinfo(res);
+
+ return (result);
+}
+
+static isc_result_t
+create_addr(const char *buffer, isc_netaddr_t *addr, int convert_zero) {
+ struct in_addr v4;
+ struct in6_addr v6;
+
+ if (inet_aton(buffer, &v4) == 1) {
+ if (convert_zero) {
+ unsigned char zeroaddress[] = {0, 0, 0, 0};
+ unsigned char loopaddress[] = {127, 0, 0, 1};
+ if (memcmp(&v4, zeroaddress, 4) == 0)
+ memcpy(&v4, loopaddress, 4);
+ }
+ addr->family = AF_INET;
+ memcpy(&addr->type.in, &v4, NS_INADDRSZ);
+ addr->zone = 0;
+ } else if (inet_pton(AF_INET6, buffer, &v6) == 1) {
+ addr->family = AF_INET6;
+ memcpy(&addr->type.in6, &v6, NS_IN6ADDRSZ);
+ addr->zone = 0;
+ } else
+ return (ISC_R_BADADDRESSFORM); /* Unrecognised format. */
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsenameserver(irs_resconf_t *conf, FILE *fp) {
+ char word[RESCONFMAXLINELEN];
+ int cp;
+ isc_result_t result;
+
+ if (conf->numns == RESCONFMAXNAMESERVERS)
+ return (ISC_R_SUCCESS);
+
+ cp = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Nothing on line. */
+ else if (cp == ' ' || cp == '\t')
+ cp = eatwhite(fp);
+
+ if (cp != EOF && cp != '\n')
+ return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */
+
+ result = add_server(conf->mctx, word, &conf->nameservers);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ conf->numns++;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsedomain(irs_resconf_t *conf, FILE *fp) {
+ char word[RESCONFMAXLINELEN];
+ int res, i;
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Nothing else on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */
+
+ if (conf->domainname != NULL)
+ isc_mem_free(conf->mctx, conf->domainname);
+
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ for (i = 0; i < RESCONFMAXSEARCH; i++) {
+ if (conf->search[i] != NULL) {
+ isc_mem_free(conf->mctx, conf->search[i]);
+ conf->search[i] = NULL;
+ }
+ }
+ conf->searchnxt = 0;
+
+ conf->domainname = isc_mem_strdup(conf->mctx, word);
+ if (conf->domainname == NULL)
+ return (ISC_R_NOMEMORY);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsesearch(irs_resconf_t *conf, FILE *fp) {
+ int idx, delim;
+ char word[RESCONFMAXLINELEN];
+
+ if (conf->domainname != NULL) {
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ isc_mem_free(conf->mctx, conf->domainname);
+ conf->domainname = NULL;
+ }
+
+ /*
+ * Remove any previous search definitions.
+ */
+ for (idx = 0; idx < RESCONFMAXSEARCH; idx++) {
+ if (conf->search[idx] != NULL) {
+ isc_mem_free(conf->mctx, conf->search[idx]);
+ conf->search[idx] = NULL;
+ }
+ }
+ conf->searchnxt = 0;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Nothing else on line. */
+
+ idx = 0;
+ while (strlen(word) > 0U) {
+ if (conf->searchnxt == RESCONFMAXSEARCH)
+ goto ignore; /* Too many domains. */
+
+ conf->search[idx] = isc_mem_strdup(conf->mctx, word);
+ if (conf->search[idx] == NULL)
+ return (ISC_R_NOMEMORY);
+ idx++;
+ conf->searchnxt++;
+
+ ignore:
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsesortlist(irs_resconf_t *conf, FILE *fp) {
+ int delim, res, idx;
+ char word[RESCONFMAXLINELEN];
+ char *p;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Empty line after keyword. */
+
+ while (strlen(word) > 0U) {
+ if (conf->sortlistnxt == RESCONFMAXSORTLIST)
+ return (ISC_R_QUOTA); /* Too many values. */
+
+ p = strchr(word, '/');
+ if (p != NULL)
+ *p++ = '\0';
+
+ idx = conf->sortlistnxt;
+ res = create_addr(word, &conf->sortlist[idx].addr, 1);
+ if (res != ISC_R_SUCCESS)
+ return (res);
+
+ if (p != NULL) {
+ res = create_addr(p, &conf->sortlist[idx].mask, 0);
+ if (res != ISC_R_SUCCESS)
+ return (res);
+ } else {
+ /*
+ * Make up a mask. (XXX: is this correct?)
+ */
+ conf->sortlist[idx].mask = conf->sortlist[idx].addr;
+ memset(&conf->sortlist[idx].mask.type, 0xff,
+ sizeof(conf->sortlist[idx].mask.type));
+ }
+
+ conf->sortlistnxt++;
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
+ int delim;
+ long ndots;
+ char *p;
+ char word[RESCONFMAXLINELEN];
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Empty line after keyword. */
+
+ while (strlen(word) > 0U) {
+ if (strcmp("debug", word) == 0) {
+ conf->resdebug = 1;
+ } else if (strncmp("ndots:", word, 6) == 0) {
+ ndots = strtol(word + 6, &p, 10);
+ if (*p != '\0') /* Bad string. */
+ return (ISC_R_UNEXPECTEDTOKEN);
+ if (ndots < 0 || ndots > 0xff) /* Out of range. */
+ return (ISC_R_RANGE);
+ conf->ndots = (isc_uint8_t)ndots;
+ }
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+add_search(irs_resconf_t *conf, char *domain) {
+ irs_resconf_search_t *entry;
+
+ entry = isc_mem_get(conf->mctx, sizeof(*entry));
+ if (entry == NULL)
+ return (ISC_R_NOMEMORY);
+
+ entry->domain = domain;
+ ISC_LINK_INIT(entry, link);
+ ISC_LIST_APPEND(conf->searchlist, entry, link);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*% parses a file and fills in the data structure. */
+isc_result_t
+irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp)
+{
+ FILE *fp = NULL;
+ char word[256];
+ isc_result_t rval, ret;
+ irs_resconf_t *conf;
+ int i, stopchar;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(filename != NULL);
+ REQUIRE(strlen(filename) > 0U);
+ REQUIRE(confp != NULL && *confp == NULL);
+
+ conf = isc_mem_get(mctx, sizeof(*conf));
+ if (conf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ conf->mctx = mctx;
+ ISC_LIST_INIT(conf->nameservers);
+ conf->numns = 0;
+ conf->domainname = NULL;
+ conf->searchnxt = 0;
+ conf->resdebug = 0;
+ conf->ndots = 1;
+ for (i = 0; i < RESCONFMAXSEARCH; i++)
+ conf->search[i] = NULL;
+
+ errno = 0;
+ if ((fp = fopen(filename, "r")) == NULL) {
+ isc_mem_put(mctx, conf, sizeof(*conf));
+ return (ISC_R_INVALIDFILE);
+ }
+
+ ret = ISC_R_SUCCESS;
+ do {
+ stopchar = getword(fp, word, sizeof(word));
+ if (stopchar == EOF) {
+ rval = ISC_R_SUCCESS;
+ break;
+ }
+
+ if (strlen(word) == 0U)
+ rval = ISC_R_SUCCESS;
+ else if (strcmp(word, "nameserver") == 0)
+ rval = resconf_parsenameserver(conf, fp);
+ else if (strcmp(word, "domain") == 0)
+ rval = resconf_parsedomain(conf, fp);
+ else if (strcmp(word, "search") == 0)
+ rval = resconf_parsesearch(conf, fp);
+ else if (strcmp(word, "sortlist") == 0)
+ rval = resconf_parsesortlist(conf, fp);
+ else if (strcmp(word, "options") == 0)
+ rval = resconf_parseoption(conf, fp);
+ else {
+ /* unrecognised word. Ignore entire line */
+ rval = ISC_R_SUCCESS;
+ stopchar = eatline(fp);
+ if (stopchar == EOF) {
+ break;
+ }
+ }
+ if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
+ ret = rval;
+ } while (1);
+
+ fclose(fp);
+
+ /* If we don't find a nameserver fall back to localhost */
+ if (conf->numns == 0) {
+ INSIST(ISC_LIST_EMPTY(conf->nameservers));
+
+ /* XXX: should we catch errors? */
+ (void)add_server(conf->mctx, "127.0.0.1", &conf->nameservers);
+ (void)add_server(conf->mctx, "::1", &conf->nameservers);
+ }
+
+ /*
+ * Construct unified search list from domain or configured
+ * search list
+ */
+ ISC_LIST_INIT(conf->searchlist);
+ if (conf->domainname != NULL) {
+ ret = add_search(conf, conf->domainname);
+ } else if (conf->searchnxt > 0) {
+ for (i = 0; i < conf->searchnxt; i++) {
+ ret = add_search(conf, conf->search[i]);
+ if (ret != ISC_R_SUCCESS)
+ break;
+ }
+ }
+
+ conf->magic = IRS_RESCONF_MAGIC;
+
+ if (ret != ISC_R_SUCCESS)
+ irs_resconf_destroy(&conf);
+ else
+ *confp = conf;
+
+ return (ret);
+}
+
+void
+irs_resconf_destroy(irs_resconf_t **confp) {
+ irs_resconf_t *conf;
+ isc_sockaddr_t *address;
+ irs_resconf_search_t *searchentry;
+ int i;
+
+ REQUIRE(confp != NULL);
+ conf = *confp;
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ while ((searchentry = ISC_LIST_HEAD(conf->searchlist)) != NULL) {
+ ISC_LIST_UNLINK(conf->searchlist, searchentry, link);
+ isc_mem_put(conf->mctx, searchentry, sizeof(*searchentry));
+ }
+
+ while ((address = ISC_LIST_HEAD(conf->nameservers)) != NULL) {
+ ISC_LIST_UNLINK(conf->nameservers, address, link);
+ isc_mem_put(conf->mctx, address, sizeof(*address));
+ }
+
+ if (conf->domainname != NULL)
+ isc_mem_free(conf->mctx, conf->domainname);
+
+ for (i = 0; i < RESCONFMAXSEARCH; i++) {
+ if (conf->search[i] != NULL)
+ isc_mem_free(conf->mctx, conf->search[i]);
+ }
+
+ isc_mem_put(conf->mctx, conf, sizeof(*conf));
+
+ *confp = NULL;
+}
+
+isc_sockaddrlist_t *
+irs_resconf_getnameservers(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return (&conf->nameservers);
+}
+
+irs_resconf_searchlist_t *
+irs_resconf_getsearchlist(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return (&conf->searchlist);
+}
+
+unsigned int
+irs_resconf_getndots(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return ((unsigned int)conf->ndots);
+}
diff --git a/lib/irs/version.c b/lib/irs/version.c
new file mode 100644
index 00000000..f50a3855
--- /dev/null
+++ b/lib/irs/version.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: version.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <irs/version.h>
+
+const char irs_version[] = VERSION;
+
+const unsigned int irs_libinterface = LIBINTERFACE;
+const unsigned int irs_librevision = LIBREVISION;
+const unsigned int irs_libage = LIBAGE;
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in
index 2eba9409..15f5a7dc 100644
--- a/lib/isc/Makefile.in
+++ b/lib/isc/Makefile.in
@@ -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.100 2009/02/06 12:26:22 fdupont Exp $
+# $Id: Makefile.in,v 1.103 2009/09/04 18:13:44 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -28,7 +28,7 @@ CINCLUDES = -I${srcdir}/unix/include \
-I${srcdir}/@ISC_ARCH_DIR@/include \
-I./include \
-I${srcdir}/include @ISC_OPENSSL_INC@
-CDEFINES = @USE_OPENSSL@
+CDEFINES = -DBIND9 @USE_OPENSSL@
CWARNINGS =
# Alphabetically
@@ -39,7 +39,6 @@ UNIXOBJS = @ISC_ISCIPV6_O@ \
unix/os.@O@ unix/resource.@O@ unix/socket.@O@ unix/stdio.@O@ \
unix/stdtime.@O@ unix/strerror.@O@ unix/syslog.@O@ unix/time.@O@
-
NLSOBJS = nls/msgcat.@O@
THREADOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@ \
@@ -51,8 +50,9 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
# Alphabetically
OBJS = @ISC_EXTRA_OBJS@ \
- assertions.@O@ base32.@O@ base64.@O@ bitstring.@O@ buffer.@O@ \
- bufferlist.@O@ commandline.@O@ error.@O@ event.@O@ \
+ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
+ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \
+ error.@O@ event.@O@ \
hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
@@ -63,11 +63,12 @@ OBJS = @ISC_EXTRA_OBJS@ \
serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+SYMTBLOBJS = backtrace-emptytbl.@O@
# Alphabetically
SRCS = @ISC_EXTRA_SRCS@ \
- assertions.c base32.c base64.c bitstring.c buffer.c \
- bufferlist.c commandline.c error.c event.c \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+ buffer.c bufferlist.c commandline.c error.c event.c \
heap.c hex.c hmacmd5.c hmacsha.c \
httpd.c inet_aton.c iterated_hash.c \
lex.c lfsr.c lib.c log.c \
@@ -76,7 +77,7 @@ SRCS = @ISC_EXTRA_SRCS@ \
parseint.c portset.c quota.c radix.c random.c \
ratelimiter.c refcount.c region.c result.c rwlock.c \
serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \
- symtab.c task.c taskpool.c timer.c version.c
+ symtab.c symtbl-empty.c task.c taskpool.c timer.c version.c
LIBS = @LIBS@
@@ -93,17 +94,27 @@ version.@O@: version.c
-DLIBAGE=${LIBAGE} \
-c ${srcdir}/version.c
-libisc.@SA@: ${OBJS}
+libisc.@SA@: ${OBJS} ${SYMTBLOBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS} ${SYMTBLOBJS}
+ ${RANLIB} $@
+
+libisc-nosymtbl.@SA@: ${OBJS}
${AR} ${ARFLAGS} $@ ${OBJS}
${RANLIB} $@
-libisc.la: ${OBJS}
+libisc.la: ${OBJS} ${SYMTBLOBJS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${SYMTBLOBJS} ${LIBS}
+
+libisc-nosymtbl.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc-nosymtbl.la -rpath ${libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
${OBJS} ${LIBS}
-timestamp: libisc.@A@
+timestamp: libisc.@A@ libisc-nosymtbl.@A@
touch timestamp
installdirs:
@@ -112,5 +123,9 @@ installdirs:
install:: timestamp installdirs
${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ ${DESTDIR}${libdir}
+install:: @ISC_ARCH_DIR@/include/isc/atomic.h
+ ${INSTALL_DATA} @ISC_ARCH_DIR@/include/isc/atomic.h ${DESTDIR}${includedir}/isc
+
clean distclean::
- rm -f libisc.@A@ libisc.la timestamp
+ rm -f libisc.@A@ libisc-nosymtbl.@A@ libisc.la \
+ libisc-nosymtbl.la timestamp
diff --git a/lib/isc/app_api.c b/lib/isc/app_api.c
new file mode 100644
index 00000000..ce767d17
--- /dev/null
+++ b/lib/isc/app_api.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: app_api.c,v 1.5 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_appctxcreatefunc_t appctx_createfunc = NULL;
+
+#define ISCAPI_APPMETHODS_VALID(m) ISC_MAGIC_VALID(m, ISCAPI_APPMETHODS_MAGIC)
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_app_register(isc_appctxcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (appctx_createfunc == NULL)
+ appctx_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(appctx_createfunc != NULL);
+ result = (*appctx_createfunc)(mctx, ctxp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_appctx_destroy(isc_appctx_t **ctxp) {
+ REQUIRE(ctxp != NULL && ISCAPI_APPCTX_VALID(*ctxp));
+
+ (*ctxp)->methods->ctxdestroy(ctxp);
+
+ ENSURE(*ctxp == NULL);
+}
+
+isc_result_t
+isc_app_ctxstart(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxstart(ctx));
+}
+
+isc_result_t
+isc_app_ctxrun(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxrun(ctx));
+}
+
+isc_result_t
+isc_app_ctxsuspend(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxsuspend(ctx));
+}
+
+isc_result_t
+isc_app_ctxshutdown(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxshutdown(ctx));
+}
+
+void
+isc_app_ctxfinish(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ ctx->methods->ctxfinish(ctx);
+}
+
+void
+isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+ REQUIRE(taskmgr != NULL);
+
+ ctx->methods->settaskmgr(ctx, taskmgr);
+}
+
+void
+isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+ REQUIRE(socketmgr != NULL);
+
+ ctx->methods->setsocketmgr(ctx, socketmgr);
+}
+
+void
+isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+ REQUIRE(timermgr != NULL);
+
+ ctx->methods->settimermgr(ctx, timermgr);
+}
diff --git a/lib/isc/assertions.c b/lib/isc/assertions.c
index 4c9251bd..368e9005 100644
--- a/lib/isc/assertions.c
+++ b/lib/isc/assertions.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: assertions.c,v 1.23 2008/10/15 23:47:31 tbox Exp $ */
+/* $Id: assertions.c,v 1.25 2009/09/02 23:48:02 tbox Exp $ */
/*! \file */
@@ -25,7 +25,16 @@
#include <stdlib.h>
#include <isc/assertions.h>
+#include <isc/backtrace.h>
#include <isc/msgs.h>
+#include <isc/result.h>
+
+/*
+ * The maximum number of stack frames to dump on assertion failure.
+ */
+#ifndef BACKTRACE_MAXFRAME
+#define BACKTRACE_MAXFRAME 128
+#endif
/*%
* Forward.
@@ -87,10 +96,36 @@ static void
default_callback(const char *file, int line, isc_assertiontype_t type,
const char *cond)
{
- fprintf(stderr, "%s:%d: %s(%s) %s.\n",
+ void *tracebuf[BACKTRACE_MAXFRAME];
+ int i, nframes;
+ const char *logsuffix = ".";
+ const char *fname;
+ isc_result_t result;
+
+ result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
+ if (result == ISC_R_SUCCESS && nframes > 0)
+ logsuffix = ", back trace";
+
+ fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
file, line, isc_assertion_typetotext(type), cond,
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
+ ISC_MSG_FAILED, "failed"), logsuffix);
+ if (result == ISC_R_SUCCESS) {
+ for (i = 0; i < nframes; i++) {
+ unsigned long offset;
+
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i], &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS) {
+ fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
+ tracebuf[i], fname, offset);
+ } else {
+ fprintf(stderr, "#%d %p in ??\n", i,
+ tracebuf[i]);
+ }
+ }
+ }
fflush(stderr);
abort();
/* NOTREACHED */
diff --git a/lib/isc/backtrace-emptytbl.c b/lib/isc/backtrace-emptytbl.c
new file mode 100644
index 00000000..bd534d60
--- /dev/null
+++ b/lib/isc/backtrace-emptytbl.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: backtrace-emptytbl.c,v 1.3 2009/09/01 20:13:44 each Exp $ */
+
+/*! \file */
+
+/*
+ * This file defines an empty (default) symbol table used in backtrace.c
+ * If the application wants to have a complete symbol table, it should redefine
+ * isc__backtrace_symtable with the complete table in some way, and link the
+ * version of the library not including this definition
+ * (e.g. libisc-nosymbol.a).
+ */
+
+#include <config.h>
+
+#include <isc/backtrace.h>
+
+const int isc__backtrace_nsymbols = 0;
+const isc_backtrace_symmap_t isc__backtrace_symtable[] = { { NULL, "" } };
diff --git a/lib/isc/backtrace.c b/lib/isc/backtrace.c
new file mode 100644
index 00000000..d2f044cb
--- /dev/null
+++ b/lib/isc/backtrace.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: backtrace.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_LIBCTRACE
+#include <execinfo.h>
+#endif
+
+#include <isc/backtrace.h>
+#include <isc/result.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_USEBACKTRACE
+/*
+ * Getting a back trace of a running process is tricky and highly platform
+ * dependent. Our current approach is as follows:
+ * 1. If the system library supports the "backtrace()" function, use it.
+ * 2. Otherwise, if the compiler is gcc and the architecture is x86_64 or IA64,
+ * then use gcc's (hidden) Unwind_Backtrace() function. Note that this
+ * function doesn't work for C programs on many other architectures.
+ * 3. Otherwise, if the architecture x86 or x86_64, try to unwind the stack
+ * frame following frame pointers. This assumes the executable binary
+ * compiled with frame pointers; this is not always true for x86_64 (rather,
+ * compiler optimizations often disable frame pointers). The validation
+ * checks in getnextframeptr() hopefully rejects bogus values stored in
+ * the RBP register in such a case. If the backtrace function itself crashes
+ * due to this problem, the whole package should be rebuilt with
+ * --disable-backtrace.
+ */
+#ifdef HAVE_LIBCTRACE
+#define BACKTRACE_LIBC
+#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__ia64__))
+#define BACKTRACE_GCC
+#elif defined(__x86_64__) || defined(__i386__)
+#define BACKTRACE_X86STACK
+#else
+#define BACKTRACE_DISABLED
+#endif /* HAVE_LIBCTRACE */
+#else /* !ISC_PLATFORM_USEBACKTRACE */
+#define BACKTRACE_DISABLED
+#endif /* ISC_PLATFORM_USEBACKTRACE */
+
+#ifdef BACKTRACE_LIBC
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ int n;
+
+ /*
+ * Validate the arguments: intentionally avoid using REQUIRE().
+ * See notes in backtrace.h.
+ */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ /*
+ * backtrace(3) includes this function itself in the address array,
+ * which should be eliminated from the returned sequence.
+ */
+ n = backtrace(addrs, maxaddrs);
+ if (n < 2)
+ return (ISC_R_NOTFOUND);
+ n--;
+ memmove(addrs, &addrs[1], sizeof(void *) * n);
+ *nframes = n;
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_GCC)
+extern int _Unwind_Backtrace(void* fn, void* a);
+extern void* _Unwind_GetIP(void* ctx);
+
+typedef struct {
+ void **result;
+ int max_depth;
+ int skip_count;
+ int count;
+} trace_arg_t;
+
+static int
+btcallback(void *uc, void *opq) {
+ trace_arg_t *arg = (trace_arg_t *)opq;
+
+ if (arg->skip_count > 0)
+ arg->skip_count--;
+ else
+ arg->result[arg->count++] = (void *)_Unwind_GetIP(uc);
+ if (arg->count == arg->max_depth)
+ return (5); /* _URC_END_OF_STACK */
+
+ return (0); /* _URC_NO_REASON */
+}
+
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ trace_arg_t arg;
+
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ arg.skip_count = 1;
+ arg.result = addrs;
+ arg.max_depth = maxaddrs;
+ arg.count = 0;
+ _Unwind_Backtrace(btcallback, &arg);
+
+ *nframes = arg.count;
+
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_X86STACK)
+#ifdef __x86_64__
+static unsigned long
+getrbp() {
+ __asm("movq %rbp, %rax\n");
+}
+#endif
+
+static void **
+getnextframeptr(void **sp) {
+ void **newsp = (void **)*sp;
+
+ /*
+ * Perform sanity check for the new frame pointer, derived from
+ * google glog. This can actually be bogus depending on compiler.
+ */
+
+ /* prohibit the stack frames from growing downwards */
+ if (newsp <= sp)
+ return (NULL);
+
+ /* A heuristics to reject "too large" frame: this actually happened. */
+ if ((char *)newsp - (char *)sp > 100000)
+ return (NULL);
+
+ /*
+ * Not sure if other checks used in glog are needed at this moment.
+ * For our purposes we don't have to consider non-contiguous frames,
+ * for example.
+ */
+
+ return (newsp);
+}
+
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ int i = 0;
+ void **sp;
+
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+#ifdef __x86_64__
+ sp = (void **)getrbp();
+ if (sp == NULL)
+ return (ISC_R_NOTFOUND);
+ /*
+ * sp is the frame ptr of this function itself due to the call to
+ * getrbp(), so need to unwind one frame for consistency.
+ */
+ sp = getnextframeptr(sp);
+#else
+ /*
+ * i386: the frame pointer is stored 2 words below the address for the
+ * first argument. Note that the body of this function cannot be
+ * inlined since it depends on the address of the function argument.
+ */
+ sp = (void **)&addrs - 2;
+#endif
+
+ while (sp != NULL && i < maxaddrs) {
+ addrs[i++] = *(sp + 1);
+ sp = getnextframeptr(sp);
+ }
+
+ *nframes = i;
+
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_DISABLED)
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ UNUSED(maxaddrs);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+#endif
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int index, const void **addrp,
+ const char **symbolp)
+{
+ REQUIRE(addrp != NULL && *addrp == NULL);
+ REQUIRE(symbolp != NULL && *symbolp == NULL);
+
+ if (index < 0 || index >= isc__backtrace_nsymbols)
+ return (ISC_R_RANGE);
+
+ *addrp = isc__backtrace_symtable[index].addr;
+ *symbolp = isc__backtrace_symtable[index].symbol;
+ return (ISC_R_SUCCESS);
+}
+
+static int
+symtbl_compare(const void *addr, const void *entryarg) {
+ const isc_backtrace_symmap_t *entry = entryarg;
+ const isc_backtrace_symmap_t *end =
+ &isc__backtrace_symtable[isc__backtrace_nsymbols - 1];
+
+ if (isc__backtrace_nsymbols == 1 || entry == end) {
+ if (addr >= entry->addr) {
+ /*
+ * If addr is equal to or larger than that of the last
+ * entry of the table, we cannot be sure if this is
+ * within a valid range so we consider it valid.
+ */
+ return (0);
+ }
+ return (-1);
+ }
+
+ /* entry + 1 is a valid entry from now on. */
+ if (addr < entry->addr)
+ return (-1);
+ else if (addr >= (entry + 1)->addr)
+ return (1);
+ return (0);
+}
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_backtrace_symmap_t *found;
+
+ /*
+ * Validate the arguments: intentionally avoid using REQUIRE().
+ * See notes in backtrace.h.
+ */
+ if (symbolp == NULL || *symbolp != NULL || offsetp == NULL)
+ return (ISC_R_FAILURE);
+
+ if (isc__backtrace_nsymbols < 1)
+ return (ISC_R_NOTFOUND);
+
+ /*
+ * Search the table for the entry that meets:
+ * entry.addr <= addr < next_entry.addr.
+ */
+ found = bsearch(addr, isc__backtrace_symtable, isc__backtrace_nsymbols,
+ sizeof(isc__backtrace_symtable[0]), symtbl_compare);
+ if (found == NULL)
+ result = ISC_R_NOTFOUND;
+ else {
+ *symbolp = found->symbol;
+ *offsetp = (const char *)addr - (char *)found->addr;
+ }
+
+ return (result);
+}
diff --git a/lib/isc/hash.c b/lib/isc/hash.c
index 2a1c112b..f1d68c77 100644
--- a/lib/isc/hash.c
+++ b/lib/isc/hash.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hash.c,v 1.15 2009/05/06 23:47:50 tbox Exp $ */
+/* $Id: hash.c,v 1.16 2009/09/01 00:22:28 jinmei Exp $ */
/*! \file
* Some portion of this code was derived from universal hash function
@@ -194,8 +194,12 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
hctx->vectorlen = vlen;
hctx->rndvector = rv;
+#ifdef BIND9
if (entropy != NULL)
isc_entropy_attach(entropy, &hctx->entropy);
+#else
+ UNUSED(entropy);
+#endif
*hctxp = hctx;
return (ISC_R_SUCCESS);
@@ -236,18 +240,22 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) {
void
isc_hash_ctxinit(isc_hash_t *hctx) {
- isc_result_t result;
-
LOCK(&hctx->lock);
if (hctx->initialized == ISC_TRUE)
goto out;
if (hctx->entropy) {
+#ifdef BIND9
+ isc_result_t result;
+
result = isc_entropy_getdata(hctx->entropy,
hctx->rndvector, hctx->vectorlen,
NULL, 0);
INSIST(result == ISC_R_SUCCESS);
+#else
+ INSIST(0);
+#endif
} else {
isc_uint32_t pr;
unsigned int i, copylen;
@@ -304,8 +312,10 @@ destroy(isc_hash_t **hctxp) {
isc_refcount_destroy(&hctx->refcnt);
mctx = hctx->mctx;
+#ifdef BIND9
if (hctx->entropy != NULL)
isc_entropy_detach(&hctx->entropy);
+#endif
if (hctx->rndvector != NULL)
isc_mem_put(mctx, hctx->rndvector, hctx->vectorlen);
diff --git a/lib/isc/include/isc/app.h b/lib/isc/include/isc/app.h
index c4d54cbe..e0be7906 100644
--- a/lib/isc/include/isc/app.h
+++ b/lib/isc/include/isc/app.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: app.h,v 1.8 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: app.h,v 1.11 2009/09/02 23:48:03 tbox Exp $ */
#ifndef ISC_APP_H
#define ISC_APP_H 1
@@ -54,12 +54,23 @@
* Use of this module is not required. In particular, isc_app_start() is
* NOT an ISC library initialization routine.
*
+ * This module also supports per-thread 'application contexts'. With this
+ * mode, a thread-based application will have a separate context, in which
+ * it uses other ISC library services such as tasks or timers. Signals are
+ * not caught in this mode, so that the application can handle the signals
+ * in its preferred way.
+ *
* \li MP:
* Clients must ensure that isc_app_start(), isc_app_run(), and
* isc_app_finish() are called at most once. isc_app_shutdown()
* is safe to use by any thread (provided isc_app_start() has been
* called previously).
*
+ * The same note applies to isc_app_ctxXXX() functions, but in this case
+ * it's a per-thread restriction. For example, a thread with an
+ * application context must ensure that isc_app_ctxstart() with the
+ * context is called at most once.
+ *
* \li Reliability:
* No anticipated impact.
*
@@ -75,17 +86,64 @@
#include <isc/eventclass.h>
#include <isc/lang.h>
+#include <isc/magic.h>
#include <isc/result.h>
+/***
+ *** Types
+ ***/
+
typedef isc_event_t isc_appevent_t;
#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0)
#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1)
#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535)
+/*%
+ * app module methods. Only app driver implementations use this structure.
+ * Other clients should use the top-level interfaces (i.e., isc_app_xxx
+ * functions). magic must be ISCAPI_APPMETHODS_MAGIC.
+ */
+typedef struct isc_appmethods {
+ void (*ctxdestroy)(isc_appctx_t **ctxp);
+ isc_result_t (*ctxstart)(isc_appctx_t *ctx);
+ isc_result_t (*ctxrun)(isc_appctx_t *ctx);
+ isc_result_t (*ctxsuspend)(isc_appctx_t *ctx);
+ isc_result_t (*ctxshutdown)(isc_appctx_t *ctx);
+ void (*ctxfinish)(isc_appctx_t *ctx);
+ void (*settaskmgr)(isc_appctx_t *ctx,
+ isc_taskmgr_t *timermgr);
+ void (*setsocketmgr)(isc_appctx_t *ctx,
+ isc_socketmgr_t *timermgr);
+ void (*settimermgr)(isc_appctx_t *ctx,
+ isc_timermgr_t *timermgr);
+} isc_appmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of an application context
+ * implementation's version of an isc_appctx_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. app implementations
+ * may change the structure. 'magic' must be ISCAPI_APPCTX_MAGIC for any
+ * of the isc_app_ routines to work. app implementations must maintain
+ * all app context invariants.
+ */
+struct isc_appctx {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_appmethods_t *methods;
+};
+
+#define ISCAPI_APPCTX_MAGIC ISC_MAGIC('A','a','p','c')
+#define ISCAPI_APPCTX_VALID(c) ((c) != NULL && \
+ (c)->magic == ISCAPI_APPCTX_MAGIC)
+
ISC_LANG_BEGINDECLS
isc_result_t
+isc_app_ctxstart(isc_appctx_t *ctx);
+
+isc_result_t
isc_app_start(void);
/*!<
* \brief Start an ISC library application.
@@ -93,6 +151,9 @@ isc_app_start(void);
* Notes:
* This call should be made before any other ISC library call, and as
* close to the beginning of the application as possible.
+ *
+ * Requires:
+ * 'ctx' is a valid application context (for app_ctxstart()).
*/
isc_result_t
@@ -102,7 +163,7 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
* \brief Request delivery of an event when the application is run.
*
* Requires:
- * isc_app_start() has been called.
+ *\li isc_app_start() has been called.
*
* Returns:
* ISC_R_SUCCESS
@@ -110,6 +171,9 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
*/
isc_result_t
+isc_app_ctxrun(isc_appctx_t *ctx);
+
+isc_result_t
isc_app_run(void);
/*!<
* \brief Run an ISC library application.
@@ -120,11 +184,12 @@ isc_app_run(void);
* caller should start shutting down the application.
*
* Requires:
- *\li isc_app_start() has been called.
+ *\li isc_app_[ctx]start() has been called.
*
* Ensures:
*\li Any events requested via isc_app_onrun() will have been posted (in
* FIFO order) before isc_app_run() blocks.
+ *\li 'ctx' is a valid application context (for app_ctxrun()).
*
* Returns:
*\li ISC_R_SUCCESS Shutdown has been requested.
@@ -132,6 +197,9 @@ isc_app_run(void);
*/
isc_result_t
+isc_app_ctxshutdown(isc_appctx_t *ctx);
+
+isc_result_t
isc_app_shutdown(void);
/*!<
* \brief Request application shutdown.
@@ -141,7 +209,8 @@ isc_app_shutdown(void);
* only be triggered once.
*
* Requires:
- *\li isc_app_run() has been called.
+ *\li isc_app_[ctx]run() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxshutdown()).
*
* Returns:
*\li ISC_R_SUCCESS
@@ -149,6 +218,12 @@ isc_app_shutdown(void);
*/
isc_result_t
+isc_app_ctxsuspend(isc_appctx_t *ctx);
+/*!<
+ * \brief This has the same behavior as isc_app_ctxsuspend().
+ */
+
+isc_result_t
isc_app_reload(void);
/*!<
* \brief Request application reload.
@@ -162,6 +237,9 @@ isc_app_reload(void);
*/
void
+isc_app_ctxfinish(isc_appctx_t *ctx);
+
+void
isc_app_finish(void);
/*!<
* \brief Finish an ISC library application.
@@ -171,6 +249,7 @@ isc_app_finish(void);
*
* Requires:
*\li isc_app_start() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxfinish()).
*
* Ensures:
*\li Any resources allocated by isc_app_start() have been released.
@@ -206,6 +285,90 @@ isc_app_unblock(void);
* \li isc_app_block() has been called by the same thread.
*/
+isc_result_t
+isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp);
+/*!<
+ * \brief Create an application context.
+ *
+ * Requires:
+ *\li 'mctx' is a valid memory context.
+ *\li 'ctxp' != NULL && *ctxp == NULL.
+ */
+
+void
+isc_appctx_destroy(isc_appctx_t **ctxp);
+/*!<
+ * \brief Destroy an application context.
+ *
+ * Requires:
+ *\li '*ctxp' is a valid application context.
+ *
+ * Ensures:
+ *\li *ctxp == NULL.
+ */
+
+void
+isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr);
+/*!<
+ * \brief Associate a task manager with an application context.
+ *
+ * This must be done before running tasks within the application context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'taskmgr' is a valid task manager.
+ */
+
+void
+isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr);
+/*!<
+ * \brief Associate a socket manager with an application context.
+ *
+ * This must be done before handling socket events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'socketmgr' is a valid socket manager.
+ */
+
+void
+isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr);
+/*!<
+ * \brief Associate a socket timer with an application context.
+ *
+ * This must be done before handling timer events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'timermgr' is a valid timer manager.
+ */
+
+#ifdef USE_APPIMPREGISTER
+/*%<
+ * See isc_appctx_create() above.
+ */
+typedef isc_result_t
+(*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
+
+isc_result_t
+isc_app_register(isc_appctxcreatefunc_t createfunc);
+/*%<
+ * Register a new application implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__app_register(void);
+/*%<
+ * A short cut function that specifies the application module in the ISC
+ * library for isc_app_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_APPIMPREGISTER */
ISC_LANG_ENDDECLS
diff --git a/lib/isc/include/isc/backtrace.h b/lib/isc/include/isc/backtrace.h
new file mode 100644
index 00000000..c0e98c0b
--- /dev/null
+++ b/lib/isc/include/isc/backtrace.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: backtrace.h,v 1.2 2009/09/01 18:40:25 jinmei Exp $ */
+
+/*! \file isc/backtrace.h
+ * \brief provide a back trace of the running process to help debug problems.
+ *
+ * This module tries to get a back trace of the process using some platform
+ * dependent way when available. It also manages an internal symbol table
+ * that maps function addresses used in the process to their textual symbols.
+ * This module is expected to be used to help debug when some fatal error
+ * happens.
+ *
+ * IMPORTANT NOTE: since the (major) intended use case of this module is
+ * dumping a back trace on a fatal error, normally followed by self termination,
+ * functions defined in this module generally doesn't employ assertion checks
+ * (if it did, a program bug could cause infinite recursive calls to a
+ * backtrace function). These functions still perform minimal checks and return
+ * ISC_R_FAILURE if they detect an error, but the caller should therefore be
+ * very careful about the use of these functions, and generally discouraged to
+ * use them except in an exit path. The exception is
+ * isc_backtrace_getsymbolfromindex(), which is expected to be used in a
+ * non-error-handling context and validates arguments with assertion checks.
+ */
+
+#ifndef ISC_BACKTRACE_H
+#define ISC_BACKTRACE_H 1
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+
+/***
+ *** Types
+ ***/
+struct isc_backtrace_symmap {
+ void *addr;
+ const char *symbol;
+};
+
+extern const int isc__backtrace_nsymbols;
+extern const isc_backtrace_symmap_t isc__backtrace_symtable[];
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
+/*%<
+ * Get a back trace of the running process above this function itself. On
+ * success, addrs[i] will store the address of the call point of the i-th
+ * stack frame (addrs[0] is the caller of this function). *nframes will store
+ * the total number of frames.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'addrs' is a valid array containing at least 'maxaddrs' void * entries.
+ *
+ *\li 'nframes' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int index, const void **addrp,
+ const char **symbolp);
+/*%<
+ * Returns the content of the internal symbol table of the given index.
+ * On success, *addrsp and *symbolp point to the address and the symbol of
+ * the 'index'th entry of the table, respectively. If 'index' is not in the
+ * range of the symbol table, ISC_R_RANGE will be returned.
+ *
+ * Requires
+ *
+ *\li 'addrp' must be non NULL && '*addrp' == NULL.
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_RANGE
+ */
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp);
+/*%<
+ * Searches the internal symbol table for the symbol that most matches the
+ * given 'addr'. On success, '*symbolp' will point to the name of function
+ * to which the address 'addr' belong, and '*offsetp' will store the offset
+ * from the function's entry address to 'addr'.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ *\li 'offsetp' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ */
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BACKTRACE_H */
diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h
index e64c7fac..68ae8ca8 100644
--- a/lib/isc/include/isc/file.h
+++ b/lib/isc/include/isc/file.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: file.h,v 1.36 2009/06/10 00:27:22 each Exp $ */
+/* $Id: file.h,v 1.37 2009/08/28 03:13:08 each Exp $ */
#ifndef ISC_FILE_H
#define ISC_FILE_H 1
@@ -259,6 +259,21 @@ isc_file_safecreate(const char *filename, FILE **fp);
* that only the owner can read/write it.
*/
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path,
+ char **dirname, char **basename);
+/*%<
+ * Split a path into dirname and basename. If 'path' contains no slash
+ * (or, on windows, backslash), then '*dirname' is set to ".".
+ *
+ * Allocates memory for '*dirname', which can be freed with isc_mem_free().
+ *
+ * Returns:
+ * - ISC_R_SUCCESS on success
+ * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/'
+ * - ISC_R_NOMEMORY if unable to allocate memory
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_FILE_H */
diff --git a/lib/isc/include/isc/lib.h b/lib/isc/include/isc/lib.h
index 765cdfaa..f24fef85 100644
--- a/lib/isc/include/isc/lib.h
+++ b/lib/isc/include/isc/lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.h,v 1.14 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: lib.h,v 1.16 2009/09/02 23:48:03 tbox Exp $ */
#ifndef ISC_LIB_H
#define ISC_LIB_H 1
@@ -36,6 +36,15 @@ isc_lib_initmsgcat(void);
* has not already been initialized.
*/
+void
+isc_lib_register(void);
+/*!<
+ * \brief Register the ISC library implementations for some base services
+ * such as memory or event management and handling socket or timer events.
+ * An external application that wants to use the ISC library must call this
+ * function very early in main().
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_LIB_H */
diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h
index a114d3eb..6d9f6063 100644
--- a/lib/isc/include/isc/mem.h
+++ b/lib/isc/include/isc/mem.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.h,v 1.81 2009/02/11 03:04:18 jinmei Exp $ */
+/* $Id: mem.h,v 1.86 2009/09/04 18:51:37 jinmei Exp $ */
#ifndef ISC_MEM_H
#define ISC_MEM_H 1
@@ -152,11 +152,29 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging;
#endif
-#define isc_mem_get(c, s) isc__mem_get((c), (s) _ISC_MEM_FILELINE)
-#define isc_mem_allocate(c, s) isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
-#define isc_mem_reallocate(c, p, s) isc__mem_reallocate((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE)
+/*%<
+ * We use either isc___mem (three underscores) or isc__mem (two) depending on
+ * whether it's for BIND9's internal purpose (with -DBIND9) or generic export
+ * library. This condition is generally handled in isc/namespace.h, but for
+ * Windows it doesn't work if it involves multiple times of macro expansion
+ * (such as isc_mem to isc__mem then to isc___mem). The following definitions
+ * are used to work around this portability issue. Right now, we don't support
+ * the export library for Windows, so we always use the three-underscore
+ * version.
+ */
+#ifdef WIN32
+#define ISCMEMFUNC(sfx) isc___mem_ ## sfx
+#define ISCMEMPOOLFUNC(sfx) isc___mempool_ ## sfx
+#else
+#define ISCMEMFUNC(sfx) isc__mem_ ## sfx
+#define ISCMEMPOOLFUNC(sfx) isc__mempool_ ## sfx
+#endif
+
+#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s) _ISC_MEM_FILELINE)
+#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s) _ISC_MEM_FILELINE)
+#define isc_mem_reallocate(c, p, s) ISCMEMFUNC(reallocate)((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE)
/*%
* isc_mem_putanddetach() is a convenience function for use where you
@@ -187,33 +205,101 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging;
* \endcode
*/
+/*% memory and memory pool methods */
+typedef struct isc_memmethods {
+ void (*attach)(isc_mem_t *source, isc_mem_t **targetp);
+ void (*detach)(isc_mem_t **mctxp);
+ void (*destroy)(isc_mem_t **mctxp);
+ void *(*memget)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
+ void (*memput)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG);
+ void (*memputanddetach)(isc_mem_t **mctxp, void *ptr,
+ size_t size _ISC_MEM_FLARG);
+ void *(*memallocate)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
+ void *(*memreallocate)(isc_mem_t *mctx, void *ptr,
+ size_t size _ISC_MEM_FLARG);
+ char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG);
+ void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG);
+ void (*setdestroycheck)(isc_mem_t *mctx, isc_boolean_t flag);
+ void (*setwater)(isc_mem_t *ctx, isc_mem_water_t water,
+ void *water_arg, size_t hiwater, size_t lowater);
+ void (*waterack)(isc_mem_t *ctx, int flag);
+ size_t (*inuse)(isc_mem_t *mctx);
+ isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size,
+ isc_mempool_t **mpctxp);
+} isc_memmethods_t;
+
+typedef struct isc_mempoolmethods {
+ void (*destroy)(isc_mempool_t **mpctxp);
+ void *(*get)(isc_mempool_t *mpctx _ISC_MEM_FLARG);
+ void (*put)(isc_mempool_t *mpctx, void *mem _ISC_MEM_FLARG);
+ unsigned int (*getallocated)(isc_mempool_t *mpctx);
+ void (*setmaxalloc)(isc_mempool_t *mpctx, unsigned int limit);
+ void (*setfreemax)(isc_mempool_t *mpctx, unsigned int limit);
+ void (*setname)(isc_mempool_t *mpctx, const char *name);
+ void (*associatelock)(isc_mempool_t *mpctx, isc_mutex_t *lock);
+ void (*setfillcount)(isc_mempool_t *mpctx, unsigned int limit);
+} isc_mempoolmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a memory context
+ * implementation's version of an isc_mem_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. mctx implementations
+ * may change the structure. 'magic' must be ISCAPI_MCTX_MAGIC for any of the
+ * isc_mem_ routines to work. mctx implementations must maintain all mctx
+ * invariants.
+ */
+struct isc_mem {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_memmethods_t *methods;
+};
+
+#define ISCAPI_MCTX_MAGIC ISC_MAGIC('A','m','c','x')
+#define ISCAPI_MCTX_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_MCTX_MAGIC)
+
+/*%
+ * This is the common prefix of a memory pool context. The same note as
+ * that for the mem structure applies.
+ */
+struct isc_mempool {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_mempoolmethods_t *methods;
+};
+
+#define ISCAPI_MPOOL_MAGIC ISC_MAGIC('A','m','p','l')
+#define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \
+ (mp)->magic == ISCAPI_MPOOL_MAGIC)
+
#if ISC_MEM_DEBUG
#define isc_mem_put(c, p, s) \
do { \
- isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
+ ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_putanddetach(c, p, s) \
do { \
- isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
+ ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_free(c, p) \
do { \
- isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
+ ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mempool_put(c, p) \
do { \
- isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
+ ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#else
-#define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_put(c, p, s) ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE)
#define isc_mem_putanddetach(c, p, s) \
- isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_free(c, p) isc__mem_free((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_put(c, p) isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
+ ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_free(c, p) ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_put(c, p) ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE)
#endif
/*@{*/
@@ -605,24 +691,50 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
* Pseudo-private functions for use via macros. Do not call directly.
*/
void *
-isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG);
void
-isc__mem_putanddetach(isc_mem_t **, void *,
- size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG);
void
-isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void *
-isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
void *
-isc__mem_reallocate(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void
-isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
+ISCMEMFUNC(free)(isc_mem_t *, void * _ISC_MEM_FLARG);
char *
-isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
+ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG);
void *
-isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
+ISCMEMPOOLFUNC(get)(isc_mempool_t * _ISC_MEM_FLARG);
void
-isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
+ISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG);
+
+#ifdef USE_MEMIMPREGISTER
+
+/*%<
+ * See isc_mem_create2() above.
+ */
+typedef isc_result_t
+(*isc_memcreatefunc_t)(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags);
+
+isc_result_t
+isc_mem_register(isc_memcreatefunc_t createfunc);
+/*%<
+ * Register a new memory management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * memory management library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__mem_register(void);
+/*%<
+ * A short cut function that specifies the memory management module in the ISC
+ * library for isc_mem_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_MEMIMPREGISTER */
ISC_LANG_ENDDECLS
diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h
new file mode 100644
index 00000000..33ec63a3
--- /dev/null
+++ b/lib/isc/include/isc/namespace.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: namespace.h,v 1.4 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISCAPI_NAMESPACE_H
+#define ISCAPI_NAMESPACE_H 1
+
+/*%
+ * name space conversions
+ */
+
+#ifdef BIND9
+
+#define isc_app_start isc__app_start
+#define isc_app_ctxstart isc__app_ctxstart
+#define isc_app_onrun isc__app_onrun
+#define isc_app_run isc__app_run
+#define isc_app_ctxrun isc__app_ctxrun
+#define isc_app_shutdown isc__app_shutdown
+#define isc_app_ctxshutdown isc__app_ctxshutdown
+#define isc_app_ctxsuspend isc__app_ctxsuspend
+#define isc_app_reload isc__app_reload
+#define isc_app_finish isc__app_finish
+#define isc_app_block isc__app_block
+#define isc_app_unblock isc__app_unblock
+#define isc_appctx_create isc__appctx_create
+#define isc_appctx_destroy isc__appctx_destroy
+#define isc_appctx_settaskmgr isc__appctx_settaskmgr
+#define isc_appctx_setsocketmgr isc__appctx_setsocketmgr
+#define isc_appctx_settimermgr isc__appctx_settimermgr
+
+#define isc_mem_checkdestroyed isc__mem_checkdestroyed
+#define isc_mem_createx isc__mem_createx
+#define isc_mem_createx2 isc__mem_createx2
+#define isc_mem_create isc__mem_create
+#define isc_mem_create2 isc__mem_create2
+#define isc_mem_attach isc__mem_attach
+#define isc_mem_detach isc__mem_detach
+#define isc__mem_putanddetach isc___mem_putanddetach
+#define isc_mem_destroy isc__mem_destroy
+#define isc_mem_ondestroy isc__mem_ondestroy
+#define isc__mem_get isc___mem_get
+#define isc__mem_put isc___mem_put
+#define isc_mem_stats isc__mem_stats
+#define isc__mem_allocate isc___mem_allocate
+#define isc__mem_free isc___mem_free
+#define isc__mem_strdup isc___mem_strdup
+#define isc__mem_reallocate isc___mem_reallocate
+#define isc_mem_references isc__mem_references
+#define isc_mem_setdestroycheck isc__mem_setdestroycheck
+#define isc_mem_setquota isc__mem_setquota
+#define isc_mem_getname isc__mem_getname
+#define isc_mem_getquota isc__mem_getquota
+#define isc_mem_gettag isc__mem_gettag
+#define isc_mem_inuse isc__mem_inuse
+#define isc_mem_setname isc__mem_setname
+#define isc_mem_setwater isc__mem_setwater
+#define isc_mem_printallactive isc__mem_printallactive
+#define isc_mem_waterack isc__mem_waterack
+#define isc_mempool_create isc__mempool_create
+#define isc_mempool_setname isc__mempool_setname
+#define isc_mempool_destroy isc__mempool_destroy
+#define isc_mempool_associatelock isc__mempool_associatelock
+#define isc__mempool_get isc___mempool_get
+#define isc__mempool_put isc___mempool_put
+#define isc_mempool_setfreemax isc__mempool_setfreemax
+#define isc_mempool_getfreemax isc__mempool_getfreemax
+#define isc_mempool_getfreecount isc__mempool_getfreecount
+#define isc_mempool_setmaxalloc isc__mempool_setmaxalloc
+#define isc_mempool_getmaxalloc isc__mempool_getmaxalloc
+#define isc_mempool_getallocated isc__mempool_getallocated
+#define isc_mempool_setfillcount isc__mempool_setfillcount
+#define isc_mempool_getfillcount isc__mempool_getfillcount
+
+#define isc_socket_create isc__socket_create
+#define isc_socket_attach isc__socket_attach
+#define isc_socket_detach isc__socket_detach
+#define isc_socketmgr_create isc__socketmgr_create
+#define isc_socketmgr_create2 isc__socketmgr_create2
+#define isc_socketmgr_destroy isc__socketmgr_destroy
+#define isc_socket_open isc__socket_open
+#define isc_socket_close isc__socket_close
+#define isc_socket_recvv isc__socket_recvv
+#define isc_socket_recv isc__socket_recv
+#define isc_socket_recv2 isc__socket_recv2
+#define isc_socket_send isc__socket_send
+#define isc_socket_sendto isc__socket_sendto
+#define isc_socket_sendv isc__socket_sendv
+#define isc_socket_sendtov isc__socket_sendtov
+#define isc_socket_sendto2 isc__socket_sendto2
+#define isc_socket_cleanunix isc__socket_cleanunix
+#define isc_socket_permunix isc__socket_permunix
+#define isc_socket_bind isc__socket_bind
+#define isc_socket_filter isc__socket_filter
+#define isc_socket_listen isc__socket_listen
+#define isc_socket_accept isc__socket_accept
+#define isc_socket_connect isc__socket_connect
+#define isc_socket_fdwatchcreate isc__socket_fdwatchcreate
+#define isc_socket_getname isc__socket_getname
+#define isc_socket_gettag isc__socket_gettag
+#define isc_socket_getpeername isc__socket_getpeername
+#define isc_socket_getsockname isc__socket_getsockname
+#define isc_socket_cancel isc__socket_cancel
+#define isc_socket_gettype isc__socket_gettype
+#define isc_socket_isbound isc__socket_isbound
+#define isc_socket_ipv6only isc__socket_ipv6only
+#define isc_socket_setname isc__socket_setname
+#define isc_socketmgr_getmaxsockets isc__socketmgr_getmaxsockets
+#define isc_socketmgr_setstats isc__socketmgr_setstats
+#define isc_socketmgr_setreserved isc__socketmgr_setreserved
+#define isc__socketmgr_maxudp isc___socketmgr_maxudp
+
+#define isc_task_create isc__task_create
+#define isc_task_attach isc__task_attach
+#define isc_task_detach isc__task_detach
+#define isc_task_send isc__task_send
+#define isc_task_sendanddetach isc__task_sendanddetach
+#define isc_task_purgerange isc__task_purgerange
+#define isc_task_purge isc__task_purge
+#define isc_task_purgeevent isc__task_purgeevent
+#define isc_task_unsendrange isc__task_unsendrange
+#define isc_task_unsend isc__task_unsend
+#define isc_task_onshutdown isc__task_onshutdown
+#define isc_task_shutdown isc__task_shutdown
+#define isc_task_destroy isc__task_destroy
+#define isc_task_setname isc__task_setname
+#define isc_task_getname isc__task_getname
+#define isc_task_gettag isc__task_gettag
+#define isc_task_getcurrenttime isc__task_getcurrenttime
+#define isc_taskmgr_create isc__taskmgr_create
+#define isc_taskmgr_destroy isc__taskmgr_destroy
+#define isc_task_beginexclusive isc__task_beginexclusive
+#define isc_task_endexclusive isc__task_endexclusive
+
+#define isc_timer_create isc__timer_create
+#define isc_timer_reset isc__timer_reset
+#define isc_timer_gettype isc__timer_gettype
+#define isc_timer_touch isc__timer_touch
+#define isc_timer_attach isc__timer_attach
+#define isc_timer_detach isc__timer_detach
+#define isc_timermgr_create isc__timermgr_create
+#define isc_timermgr_poke isc__timermgr_poke
+#define isc_timermgr_destroy isc__timermgr_destroy
+
+#endif /* BIND9 */
+
+#endif /* ISCAPI_NAMESPACE_H */
diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in
index fd5461e4..ef49d329 100644
--- a/lib/isc/include/isc/platform.h.in
+++ b/lib/isc/include/isc/platform.h.in
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: platform.h.in,v 1.51 2009/02/06 23:47:42 tbox Exp $ */
+/* $Id: platform.h.in,v 1.52 2009/09/01 18:40:25 jinmei Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
@@ -146,6 +146,11 @@
*/
@ISC_PLATFORM_HAVEDEVPOLL@
+/*! \brief
+ * Define if we want to log backtrace
+ */
+@ISC_PLATFORM_USEBACKTRACE@
+
/*
*** Printing.
***/
diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h
index 56b4ca6d..2347d5f8 100644
--- a/lib/isc/include/isc/result.h
+++ b/lib/isc/include/isc/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.71 2008/09/25 04:02:39 tbox Exp $ */
+/* $Id: result.h,v 1.73 2009/09/02 23:48:03 tbox Exp $ */
#ifndef ISC_RESULT_H
#define ISC_RESULT_H 1
@@ -42,6 +42,7 @@
#define ISC_R_EOF 14 /*%< end of file */
#define ISC_R_BOUND 15 /*%< socket already bound */
#define ISC_R_RELOAD 16 /*%< reload */
+#define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */
#define ISC_R_LOCKBUSY 17 /*%< lock busy */
#define ISC_R_EXISTS 18 /*%< already exists */
#define ISC_R_NOSPACE 19 /*%< ran out of space */
diff --git a/lib/isc/include/isc/resultclass.h b/lib/isc/include/isc/resultclass.h
index b32426fe..d91e800e 100644
--- a/lib/isc/include/isc/resultclass.h
+++ b/lib/isc/include/isc/resultclass.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resultclass.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: resultclass.h,v 1.20 2009/09/02 23:48:03 tbox Exp $ */
#ifndef ISC_RESULTCLASS_H
#define ISC_RESULTCLASS_H 1
@@ -45,6 +45,7 @@
#define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3)
#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4)
#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5)
+#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6)
#endif /* ISC_RESULTCLASS_H */
diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h
index 4f654a29..376dcc09 100644
--- a/lib/isc/include/isc/socket.h
+++ b/lib/isc/include/isc/socket.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.h,v 1.89 2009/03/05 03:13:55 marka Exp $ */
+/* $Id: socket.h,v 1.93 2009/09/02 23:43:54 each Exp $ */
#ifndef ISC_SOCKET_H
#define ISC_SOCKET_H 1
@@ -260,6 +260,79 @@ typedef enum {
#define ISC_SOCKFDWATCH_WRITE 0x00000002 /*%< watch for writable */
/*@}*/
+/*% Socket and socket manager methods */
+typedef struct isc_socketmgrmethods {
+ void (*destroy)(isc_socketmgr_t **managerp);
+ isc_result_t (*socketcreate)(isc_socketmgr_t *manager, int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+} isc_socketmgrmethods_t;
+
+typedef struct isc_socketmethods {
+ void (*attach)(isc_socket_t *socket,
+ isc_socket_t **socketp);
+ void (*detach)(isc_socket_t **socketp);
+ isc_result_t (*bind)(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options);
+ isc_result_t (*sendto)(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg, isc_sockaddr_t *address,
+ struct in6_pktinfo *pktinfo);
+ isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ void (*cancel)(isc_socket_t *sock, isc_task_t *task,
+ unsigned int how);
+ isc_result_t (*getsockname)(isc_socket_t *sock,
+ isc_sockaddr_t *addressp);
+ isc_sockettype_t (*gettype)(isc_socket_t *sock);
+ void (*ipv6only)(isc_socket_t *sock, isc_boolean_t yes);
+} isc_socketmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a socket manager
+ * object implementation's version of an isc_socketmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. socket implementations
+ * may change the structure. 'magic' must be ISCAPI_SOCKETMGR_MAGIC for any
+ * of the isc_socket_ routines to work. socket implementations must maintain
+ * all socket invariants.
+ * In effect, this definition is used only for non-BIND9 version ("export")
+ * of the library, and the export version does not work for win32. So, to avoid
+ * the definition conflict with win32/socket.c, we enable this definition only
+ * for non-Win32 (i.e. Unix) platforms.
+ */
+#ifndef WIN32
+struct isc_socketmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmgrmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A','s','m','g')
+#define ISCAPI_SOCKETMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_SOCKETMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a socket object. The same note as
+ * that for the socketmgr structure applies.
+ */
+#ifndef WIN32
+struct isc_socket {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A','s','c','t')
+#define ISCAPI_SOCKET_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_SOCKET_MAGIC)
+
/***
*** Socket and Socket Manager Functions
***
@@ -821,6 +894,10 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
/*@}*/
isc_result_t
+isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_socketmgr_t **managerp);
+
+isc_result_t
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
isc_result_t
@@ -831,6 +908,8 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
* maximum number of sockets that the created manager should handle.
* isc_socketmgr_create() is equivalent of isc_socketmgr_create2() with
* "maxsocks" being zero.
+ * isc_socketmgr_createinctx() also associates the new manager with the
+ * specified application context.
*
* Notes:
*
@@ -842,6 +921,8 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
*
*\li 'managerp' points to a NULL isc_socketmgr_t.
*
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
* Ensures:
*
*\li '*managerp' is a valid isc_socketmgr_t.
@@ -1008,6 +1089,31 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
#endif /* HAVE_LIBXML2 */
+#ifdef USE_SOCKETIMPREGISTER
+/*%<
+ * See isc_socketmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_socketmgrcreatefunc_t)(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socket_register(isc_socketmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new socket I/O implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__socket_register(void);
+/*%<
+ * A short cut function that specifies the socket I/O module in the ISC
+ * library for isc_socket_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_SOCKETIMPREGISTER */
+
ISC_LANG_ENDDECLS
#endif /* ISC_SOCKET_H */
diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h
index bf90281e..2fe99c47 100644
--- a/lib/isc/include/isc/task.h
+++ b/lib/isc/include/isc/task.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task.h,v 1.63 2009/01/18 23:48:14 tbox Exp $ */
+/* $Id: task.h,v 1.65 2009/09/02 18:38:40 jinmei Exp $ */
#ifndef ISC_TASK_H
#define ISC_TASK_H 1
@@ -96,6 +96,70 @@
ISC_LANG_BEGINDECLS
+/***
+ *** Types
+ ***/
+
+/*% Task and task manager methods */
+typedef struct isc_taskmgrmethods {
+ void (*destroy)(isc_taskmgr_t **managerp);
+ isc_result_t (*taskcreate)(isc_taskmgr_t *manager,
+ unsigned int quantum,
+ isc_task_t **taskp);
+} isc_taskmgrmethods_t;
+
+typedef struct isc_taskmethods {
+ void (*attach)(isc_task_t *source, isc_task_t **targetp);
+ void (*detach)(isc_task_t **taskp);
+ void (*destroy)(isc_task_t **taskp);
+ void (*send)(isc_task_t *task, isc_event_t **eventp);
+ void (*sendanddetach)(isc_task_t **taskp, isc_event_t **eventp);
+ unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ void (*shutdown)(isc_task_t *task);
+ void (*setname)(isc_task_t *task, const char *name, void *tag);
+ unsigned int (*purgeevents)(isc_task_t *task, void *sender,
+ isc_eventtype_t type, void *tag);
+ unsigned int (*purgerange)(isc_task_t *task, void *sender,
+ isc_eventtype_t first, isc_eventtype_t last,
+ void *tag);
+} isc_taskmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a task manager
+ * object implementation's version of an isc_taskmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. task implementations
+ * may change the structure. 'magic' must be ISCAPI_TASKMGR_MAGIC for any
+ * of the isc_task_ routines to work. task implementations must maintain
+ * all task invariants.
+ */
+struct isc_taskmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmgrmethods_t *methods;
+};
+
+#define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TASKMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TASKMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a task object. The same note as
+ * that for the taskmgr structure applies.
+ */
+struct isc_task {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmethods_t *methods;
+};
+
+#define ISCAPI_TASK_MAGIC ISC_MAGIC('A','t','s','t')
+#define ISCAPI_TASK_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TASK_MAGIC)
+
isc_result_t
isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
isc_task_t **taskp);
@@ -540,10 +604,15 @@ isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t);
*****/
isc_result_t
+isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ unsigned int workers, unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+isc_result_t
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
unsigned int default_quantum, isc_taskmgr_t **managerp);
/*%<
- * Create a new task manager.
+ * Create a new task manager. isc_taskmgr_createinctx() also associates
+ * the new manager with the specified application context.
*
* Notes:
*
@@ -565,6 +634,8 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
*
*\li managerp != NULL && *managerp == NULL
*
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
* Ensures:
*
*\li On success, '*managerp' will be attached to the newly created task
@@ -619,6 +690,31 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
#endif
+/*%<
+ * See isc_taskmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_taskmgrcreatefunc_t)(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+
+isc_result_t
+isc_task_register(isc_taskmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new task management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__task_register(void);
+/*%<
+ * A short cut function that specifies the task management module in the ISC
+ * library for isc_task_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_TASK_H */
diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h
index a4b2df7a..fa9abb16 100644
--- a/lib/isc/include/isc/timer.h
+++ b/lib/isc/include/isc/timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: timer.h,v 1.40 2008/06/23 23:47:11 tbox Exp $ */
+/* $Id: timer.h,v 1.43 2009/09/02 23:48:03 tbox Exp $ */
#ifndef ISC_TIMER_H
#define ISC_TIMER_H 1
@@ -103,6 +103,61 @@ typedef struct isc_timerevent {
#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3)
#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535)
+/*% Timer and timer manager methods */
+typedef struct {
+ void (*destroy)(isc_timermgr_t **managerp);
+ isc_result_t (*timercreate)(isc_timermgr_t *manager,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ const void *arg,
+ isc_timer_t **timerp);
+} isc_timermgrmethods_t;
+
+typedef struct {
+ void (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
+ void (*detach)(isc_timer_t **timerp);
+ isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge);
+ isc_result_t (*touch)(isc_timer_t *timer);
+} isc_timermethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a timer manager
+ * object implementation's version of an isc_timermgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. timer implementations
+ * may change the structure. 'magic' must be ISCAPI_TIMERMGR_MAGIC for any
+ * of the isc_timer_ routines to work. timer implementations must maintain
+ * all timer invariants.
+ */
+struct isc_timermgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermgrmethods_t *methods;
+};
+
+#define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TIMERMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TIMERMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a timer object. The same note as
+ * that for the timermgr structure applies.
+ */
+struct isc_timer {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermethods_t *methods;
+};
+
+#define ISCAPI_TIMER_MAGIC ISC_MAGIC('A','t','m','r')
+#define ISCAPI_TIMER_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TIMER_MAGIC)
+
/***
*** Timer and Timer Manager Functions
***
@@ -289,9 +344,14 @@ isc_timer_gettype(isc_timer_t *timer);
*/
isc_result_t
+isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_timermgr_t **managerp);
+
+isc_result_t
isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
/*%<
- * Create a timer manager.
+ * Create a timer manager. isc_timermgr_createinctx() also associates
+ * the new manager with the specified application context.
*
* Notes:
*
@@ -303,6 +363,8 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
*
*\li 'managerp' points to a NULL isc_timermgr_t.
*
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
* Ensures:
*
*\li '*managerp' is a valid isc_timermgr_t.
@@ -339,6 +401,31 @@ isc_timermgr_destroy(isc_timermgr_t **managerp);
void isc_timermgr_poke(isc_timermgr_t *m);
+#ifdef USE_TIMERIMPREGISTER
+/*%<
+ * See isc_timermgr_create() above.
+ */
+typedef isc_result_t
+(*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp);
+
+isc_result_t
+isc__timer_register(void);
+/*%<
+ * Register a new timer management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc_timer_register(isc_timermgrcreatefunc_t createfunc);
+/*%<
+ * A short cut function that specifies the timer management module in the ISC
+ * library for isc_timer_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_TIMERIMPREGISTER */
+
ISC_LANG_ENDDECLS
#endif /* ISC_TIMER_H */
diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h
index 469e7d62..03ada89a 100644
--- a/lib/isc/include/isc/types.h
+++ b/lib/isc/include/isc/types.h
@@ -15,11 +15,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.48 2009/01/27 23:47:54 tbox Exp $ */
+/* $Id: types.h,v 1.50 2009/09/01 18:40:25 jinmei Exp $ */
#ifndef ISC_TYPES_H
#define ISC_TYPES_H 1
+#include <isc/namespace.h>
+
/*! \file isc/types.h
* \brief
* OS-specific types, from the OS-specific include directories.
@@ -40,6 +42,8 @@
/* Core Types. Alphabetized by defined type. */
+typedef struct isc_appctx isc_appctx_t; /*%< Application context */
+typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */
typedef struct isc_bitstring isc_bitstring_t; /*%< Bitstring */
typedef struct isc_buffer isc_buffer_t; /*%< Buffer */
typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
diff --git a/lib/isc/lib.c b/lib/isc/lib.c
index f3a2c2dc..a5054255 100644
--- a/lib/isc/lib.c
+++ b/lib/isc/lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.c,v 1.14 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: lib.c,v 1.16 2009/09/02 23:48:02 tbox Exp $ */
/*! \file */
@@ -24,9 +24,15 @@
#include <stdio.h>
#include <stdlib.h>
-#include <isc/once.h>
-#include <isc/msgs.h>
+#include <isc/app.h>
#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
/***
*** Globals
@@ -41,7 +47,6 @@ LIBISC_EXTERNAL_DATA isc_msgcat_t * isc_msgcat = NULL;
static isc_once_t msgcat_once = ISC_ONCE_INIT;
-
/***
*** Functions
***/
@@ -77,3 +82,22 @@ isc_lib_initmsgcat(void) {
abort();
}
}
+
+#ifndef BIND9
+static isc_once_t register_once = ISC_ONCE_INIT;
+
+static void
+do_register(void) {
+ RUNTIME_CHECK(isc__mem_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__app_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__task_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__socket_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__timer_register() == ISC_R_SUCCESS);
+}
+
+void
+isc_lib_register() {
+ RUNTIME_CHECK(isc_once_do(&register_once, do_register)
+ == ISC_R_SUCCESS);
+}
+#endif
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index 2ee8c89e..ef6ece0c 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.c,v 1.149 2009/02/16 03:16:10 marka Exp $ */
+/* $Id: mem.c,v 1.153 2009/09/02 23:43:54 each Exp $ */
/*! \file */
@@ -60,6 +60,9 @@ LIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING;
/*
* Types.
*/
+typedef struct isc__mem isc__mem_t;
+typedef struct isc__mempool isc__mempool_t;
+
#if ISC_MEM_TRACKLINES
typedef struct debuglink debuglink_t;
struct debuglink {
@@ -89,7 +92,7 @@ typedef struct {
*/
union {
size_t size;
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
char bytes[ALIGNMENT_SIZE];
} u;
} size_info;
@@ -110,7 +113,7 @@ typedef ISC_LIST(debuglink_t) debuglist_t;
/* List of all active memory contexts. */
-static ISC_LIST(isc_mem_t) contexts;
+static ISC_LIST(isc__mem_t) contexts;
static isc_once_t once = ISC_ONCE_INIT;
static isc_mutex_t lock;
@@ -120,8 +123,8 @@ static isc_mutex_t lock;
*/
static isc_uint64_t totallost;
-struct isc_mem {
- unsigned int magic;
+struct isc__mem {
+ isc_mem_t common;
isc_ondestroy_t ondestroy;
unsigned int flags;
isc_mutex_t lock;
@@ -143,7 +146,7 @@ struct isc_mem {
isc_boolean_t hi_called;
isc_mem_water_t water;
void * water_arg;
- ISC_LIST(isc_mempool_t) pools;
+ ISC_LIST(isc__mempool_t) pools;
unsigned int poolcnt;
/* ISC_MEMFLAG_INTERNAL */
@@ -162,19 +165,19 @@ struct isc_mem {
#endif
unsigned int memalloc_failures;
- ISC_LINK(isc_mem_t) link;
+ ISC_LINK(isc__mem_t) link;
};
#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p')
#define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC)
-struct isc_mempool {
+struct isc__mempool {
/* always unlocked */
- unsigned int magic; /*%< magic number */
+ isc_mempool_t common; /*%< common header of mempool's */
isc_mutex_t *lock; /*%< optional lock */
- isc_mem_t *mctx; /*%< our memory context */
+ isc__mem_t *mctx; /*%< our memory context */
/*%< locked via the memory context's lock */
- ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */
+ ISC_LINK(isc__mempool_t) link; /*%< next pool in this mem context */
/*%< optionally locked from here down */
element *items; /*%< low water item list */
size_t size; /*%< size of each item on this pool */
@@ -209,13 +212,184 @@ struct isc_mempool {
#define DELETE_TRACE(a, b, c, d, e) delete_trace_entry(a, b, c, d, e)
static void
-print_active(isc_mem_t *ctx, FILE *out);
+print_active(isc__mem_t *ctx, FILE *out);
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_MEMFUNC_SCOPE
+#else
+#define ISC_MEMFUNC_SCOPE static
+#endif
+
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx2(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp, unsigned int flags);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create(size_t init_max_size, size_t target_size, isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create2(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags);
+ISC_MEMFUNC_SCOPE void
+isc__mem_attach(isc_mem_t *source, isc_mem_t **targetp);
+ISC_MEMFUNC_SCOPE void
+isc__mem_detach(isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE void
+isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mem_destroy(isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event);
+ISC_MEMFUNC_SCOPE void *
+isc___mem_get(isc_mem_t *ctx, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc___mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mem_stats(isc_mem_t *ctx, FILE *out);
+ISC_MEMFUNC_SCOPE void *
+isc___mem_allocate(isc_mem_t *ctx, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void *
+isc___mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc___mem_free(isc_mem_t *ctx, void *ptr FLARG);
+ISC_MEMFUNC_SCOPE char *
+isc___mem_strdup(isc_mem_t *mctx, const char *s FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setquota(isc_mem_t *ctx, size_t quota);
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_getquota(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_inuse(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
+ size_t hiwater, size_t lowater);
+ISC_MEMFUNC_SCOPE void
+isc__mem_waterack(isc_mem_t *ctx0, int flag);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setname(isc_mem_t *ctx, const char *name, void *tag);
+ISC_MEMFUNC_SCOPE const char *
+isc__mem_getname(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE void *
+isc__mem_gettag(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setname(isc_mempool_t *mpctx, const char *name);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_destroy(isc_mempool_t **mpctxp);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
+ISC_MEMFUNC_SCOPE void *
+isc___mempool_get(isc_mempool_t *mpctx FLARG);
+ISC_MEMFUNC_SCOPE void
+isc___mempool_put(isc_mempool_t *mpctx, void *mem FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreemax(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreecount(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getmaxalloc(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getallocated(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfillcount(isc_mempool_t *mpctx);
+#ifdef BIND9
+ISC_MEMFUNC_SCOPE void
+isc__mem_printactive(isc_mem_t *ctx0, FILE *file);
+ISC_MEMFUNC_SCOPE void
+isc__mem_printallactive(FILE *file);
+ISC_MEMFUNC_SCOPE void
+isc__mem_checkdestroyed(FILE *file);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mem_references(isc_mem_t *ctx0);
+#endif
+
+static struct isc__memmethods {
+ isc_memmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *createx, *create, *create2, *ondestroy, *stats,
+ *setquota, *getquota, *setname, *getname, *gettag;
+#endif
+} memmethods = {
+ {
+ isc__mem_attach,
+ isc__mem_detach,
+ isc__mem_destroy,
+ isc___mem_get,
+ isc___mem_put,
+ isc___mem_putanddetach,
+ isc___mem_allocate,
+ isc___mem_reallocate,
+ isc___mem_strdup,
+ isc___mem_free,
+ isc__mem_setdestroycheck,
+ isc__mem_setwater,
+ isc__mem_waterack,
+ isc__mem_inuse,
+ isc__mempool_create
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__mem_createx, (void *)isc__mem_create,
+ (void *)isc__mem_create2, (void *)isc__mem_ondestroy,
+ (void *)isc__mem_stats, (void *)isc__mem_setquota,
+ (void *)isc__mem_getquota, (void *)isc__mem_setname,
+ (void *)isc__mem_getname, (void *)isc__mem_gettag
+#endif
+};
+
+static struct isc__mempoolmethods {
+ isc_mempoolmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *getfreemax, *getfreecount, *getmaxalloc, *getfillcount;
+#endif
+} mempoolmethods = {
+ {
+ isc__mempool_destroy,
+ isc___mempool_get,
+ isc___mempool_put,
+ isc__mempool_getallocated,
+ isc__mempool_setmaxalloc,
+ isc__mempool_setfreemax,
+ isc__mempool_setname,
+ isc__mempool_associatelock,
+ isc__mempool_setfillcount
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__mempool_getfreemax, (void *)isc__mempool_getfreecount,
+ (void *)isc__mempool_getmaxalloc, (void *)isc__mempool_getfillcount
+#endif
+};
/*!
* mctx must be locked.
*/
static inline void
-add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
+add_trace_entry(isc__mem_t *mctx, const void *ptr, unsigned int size
FLARG)
{
debuglink_t *dl;
@@ -274,7 +448,7 @@ add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
}
static inline void
-delete_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size,
+delete_trace_entry(isc__mem_t *mctx, const void *ptr, unsigned int size,
const char *file, unsigned int line)
{
debuglink_t *dl;
@@ -345,7 +519,7 @@ quantize(size_t size) {
}
static inline isc_boolean_t
-more_basic_blocks(isc_mem_t *ctx) {
+more_basic_blocks(isc__mem_t *ctx) {
void *new;
unsigned char *curr, *next;
unsigned char *first, *last;
@@ -415,7 +589,7 @@ more_basic_blocks(isc_mem_t *ctx) {
}
static inline isc_boolean_t
-more_frags(isc_mem_t *ctx, size_t new_size) {
+more_frags(isc__mem_t *ctx, size_t new_size) {
int i, frags;
size_t total_size;
void *new;
@@ -477,7 +651,7 @@ more_frags(isc_mem_t *ctx, size_t new_size) {
}
static inline void *
-mem_getunlocked(isc_mem_t *ctx, size_t size) {
+mem_getunlocked(isc__mem_t *ctx, size_t size) {
size_t new_size = quantize(size);
void *ret;
@@ -558,7 +732,7 @@ check_overrun(void *mem, size_t size, size_t new_size) {
#endif
static inline void
-mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size) {
+mem_putunlocked(isc__mem_t *ctx, void *mem, size_t size) {
size_t new_size = quantize(size);
if (size == ctx->max_size || new_size >= ctx->max_size) {
@@ -606,7 +780,7 @@ mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size) {
* Perform a malloc, doing memory filling and overrun detection as necessary.
*/
static inline void *
-mem_get(isc_mem_t *ctx, size_t size) {
+mem_get(isc__mem_t *ctx, size_t size) {
char *ret;
#if ISC_MEM_CHECKOVERRUN
@@ -634,7 +808,7 @@ mem_get(isc_mem_t *ctx, size_t size) {
* Perform a free, doing memory filling and overrun detection as necessary.
*/
static inline void
-mem_put(isc_mem_t *ctx, void *mem, size_t size) {
+mem_put(isc__mem_t *ctx, void *mem, size_t size) {
#if ISC_MEM_CHECKOVERRUN
INSIST(((unsigned char *)mem)[size] == 0xbe);
#endif
@@ -650,7 +824,7 @@ mem_put(isc_mem_t *ctx, void *mem, size_t size) {
* Update internal counters after a memory get.
*/
static inline void
-mem_getstats(isc_mem_t *ctx, size_t size) {
+mem_getstats(isc__mem_t *ctx, size_t size) {
ctx->total += size;
ctx->inuse += size;
@@ -667,7 +841,7 @@ mem_getstats(isc_mem_t *ctx, size_t size) {
* Update internal counters after a memory put.
*/
static inline void
-mem_putstats(isc_mem_t *ctx, void *ptr, size_t size) {
+mem_putstats(isc__mem_t *ctx, void *ptr, size_t size) {
UNUSED(ptr);
INSIST(ctx->inuse >= size);
@@ -711,22 +885,22 @@ initialize_action(void) {
* Public.
*/
-isc_result_t
-isc_mem_createx(size_t init_max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
- isc_mem_t **ctxp)
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp)
{
- return (isc_mem_createx2(init_max_size, target_size, memalloc, memfree,
- arg, ctxp, ISC_MEMFLAG_DEFAULT));
+ return (isc__mem_createx2(init_max_size, target_size, memalloc, memfree,
+ arg, ctxp, ISC_MEMFLAG_DEFAULT));
}
-isc_result_t
-isc_mem_createx2(size_t init_max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
- isc_mem_t **ctxp, unsigned int flags)
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx2(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp, unsigned int flags)
{
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
isc_result_t result;
REQUIRE(ctxp != NULL && *ctxp == NULL);
@@ -766,7 +940,9 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
ctx->hi_called = ISC_FALSE;
ctx->water = NULL;
ctx->water_arg = NULL;
- ctx->magic = MEM_MAGIC;
+ ctx->common.impmagic = MEM_MAGIC;
+ ctx->common.magic = ISCAPI_MCTX_MAGIC;
+ ctx->common.methods = (isc_memmethods_t *)&memmethods;
isc_ondestroy_init(&ctx->ondestroy);
ctx->memalloc = memalloc;
ctx->memfree = memfree;
@@ -831,7 +1007,7 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
ISC_LIST_INITANDAPPEND(contexts, ctx, link);
UNLOCK(&lock);
- *ctxp = ctx;
+ *ctxp = (isc_mem_t *)ctx;
return (ISC_R_SUCCESS);
error:
@@ -852,30 +1028,29 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
return (result);
}
-isc_result_t
-isc_mem_create(size_t init_max_size, size_t target_size,
- isc_mem_t **ctxp)
-{
- return (isc_mem_createx2(init_max_size, target_size,
- default_memalloc, default_memfree, NULL,
- ctxp, ISC_MEMFLAG_DEFAULT));
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create(size_t init_max_size, size_t target_size, isc_mem_t **ctxp) {
+ return (isc__mem_createx2(init_max_size, target_size,
+ default_memalloc, default_memfree, NULL,
+ ctxp, ISC_MEMFLAG_DEFAULT));
}
-isc_result_t
-isc_mem_create2(size_t init_max_size, size_t target_size,
- isc_mem_t **ctxp, unsigned int flags)
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create2(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags)
{
- return (isc_mem_createx2(init_max_size, target_size,
- default_memalloc, default_memfree, NULL,
- ctxp, flags));
+ return (isc__mem_createx2(init_max_size, target_size,
+ default_memalloc, default_memfree, NULL,
+ ctxp, flags));
}
static void
-destroy(isc_mem_t *ctx) {
+destroy(isc__mem_t *ctx) {
unsigned int i;
isc_ondestroy_t ondest;
- ctx->magic = 0;
+ ctx->common.impmagic = 0;
+ ctx->common.magic = 0;
LOCK(&lock);
ISC_LIST_UNLINK(contexts, ctx, link);
@@ -938,8 +1113,10 @@ destroy(isc_mem_t *ctx) {
isc_ondestroy_notify(&ondest, ctx);
}
-void
-isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_attach(isc_mem_t *source0, isc_mem_t **targetp) {
+ isc__mem_t *source = (isc__mem_t *)source0;
+
REQUIRE(VALID_CONTEXT(source));
REQUIRE(targetp != NULL && *targetp == NULL);
@@ -947,16 +1124,16 @@ isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
source->references++;
MCTXUNLOCK(source, &source->lock);
- *targetp = source;
+ *targetp = (isc_mem_t *)source;
}
-void
-isc_mem_detach(isc_mem_t **ctxp) {
- isc_mem_t *ctx;
+ISC_MEMFUNC_SCOPE void
+isc__mem_detach(isc_mem_t **ctxp) {
+ isc__mem_t *ctx;
isc_boolean_t want_destroy = ISC_FALSE;
REQUIRE(ctxp != NULL);
- ctx = *ctxp;
+ ctx = (isc__mem_t *)*ctxp;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -982,15 +1159,15 @@ isc_mem_detach(isc_mem_t **ctxp) {
* isc_mem_detach(&mctx);
*/
-void
-isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
- isc_mem_t *ctx;
+ISC_MEMFUNC_SCOPE void
+isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
+ isc__mem_t *ctx;
isc_boolean_t want_destroy = ISC_FALSE;
size_info *si;
size_t oldsize;
REQUIRE(ctxp != NULL);
- ctx = *ctxp;
+ ctx = (isc__mem_t *)*ctxp;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(ptr != NULL);
@@ -1008,7 +1185,7 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
oldsize -= ALIGNMENT_SIZE;
INSIST(oldsize == size);
}
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc_mem_free((isc_mem_t *)ctx, ptr);
MCTXLOCK(ctx, &ctx->lock);
ctx->references--;
@@ -1042,9 +1219,9 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
destroy(ctx);
}
-void
-isc_mem_destroy(isc_mem_t **ctxp) {
- isc_mem_t *ctx;
+ISC_MEMFUNC_SCOPE void
+isc__mem_destroy(isc_mem_t **ctxp) {
+ isc__mem_t *ctx;
/*
* This routine provides legacy support for callers who use mctxs
@@ -1052,7 +1229,7 @@ isc_mem_destroy(isc_mem_t **ctxp) {
*/
REQUIRE(ctxp != NULL);
- ctx = *ctxp;
+ ctx = (isc__mem_t *)*ctxp;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1069,8 +1246,9 @@ isc_mem_destroy(isc_mem_t **ctxp) {
*ctxp = NULL;
}
-isc_result_t
-isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_ondestroy(isc_mem_t *ctx0, isc_task_t *task, isc_event_t **event) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
isc_result_t res;
MCTXLOCK(ctx, &ctx->lock);
@@ -1080,16 +1258,16 @@ isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
return (res);
}
-
-void *
-isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
void *ptr;
isc_boolean_t call_water = ISC_FALSE;
REQUIRE(VALID_CONTEXT(ctx));
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)
- return (isc__mem_allocate(ctx, size FLARG_PASS));
+ return (isc_mem_allocate((isc_mem_t *)ctx, size));
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock);
@@ -1121,9 +1299,9 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
return (ptr);
}
-void
-isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
-{
+ISC_MEMFUNC_SCOPE void
+isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
isc_boolean_t call_water = ISC_FALSE;
size_info *si;
size_t oldsize;
@@ -1139,7 +1317,7 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
oldsize -= ALIGNMENT_SIZE;
INSIST(oldsize == size);
}
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc_mem_free((isc_mem_t *)ctx, ptr);
return;
}
@@ -1170,8 +1348,10 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
}
-void
-isc_mem_waterack(isc_mem_t *ctx, int flag) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_waterack(isc_mem_t *ctx0, int flag) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1184,7 +1364,7 @@ isc_mem_waterack(isc_mem_t *ctx, int flag) {
#if ISC_MEM_TRACKLINES
static void
-print_active(isc_mem_t *mctx, FILE *out) {
+print_active(isc__mem_t *mctx, FILE *out) {
if (mctx->debuglist != NULL) {
debuglink_t *dl;
unsigned int i, j;
@@ -1226,11 +1406,12 @@ print_active(isc_mem_t *mctx, FILE *out) {
/*
* Print the stats[] on the stream "out" with suitable formatting.
*/
-void
-isc_mem_stats(isc_mem_t *ctx, FILE *out) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_stats(isc_mem_t *ctx0, FILE *out) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t i;
const struct stats *s;
- const isc_mempool_t *pool;
+ const isc__mempool_t *pool;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1303,7 +1484,8 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
*/
static void *
-isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
+isc__mem_allocateunlocked(isc_mem_t *ctx0, size_t size) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
size += ALIGNMENT_SIZE;
@@ -1325,8 +1507,9 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
return (&si[1]);
}
-void *
-isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
isc_boolean_t call_water = ISC_FALSE;
@@ -1334,9 +1517,9 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock);
- si = isc__mem_allocateunlocked(ctx, size);
+ si = isc__mem_allocateunlocked((isc_mem_t *)ctx, size);
} else {
- si = isc__mem_allocateunlocked(ctx, size);
+ si = isc__mem_allocateunlocked((isc_mem_t *)ctx, size);
MCTXLOCK(ctx, &ctx->lock);
if (si != NULL)
mem_getstats(ctx, si[-1].u.size);
@@ -1365,8 +1548,9 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
return (si);
}
-void *
-isc__mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
void *new_ptr = NULL;
size_t oldsize, copysize;
@@ -1384,23 +1568,24 @@ isc__mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG) {
* NULL if allocation fails or doesn't happen.
*/
if (size > 0U) {
- new_ptr = isc__mem_allocate(ctx, size FLARG_PASS);
+ new_ptr = isc__mem_allocate(ctx0, size FLARG_PASS);
if (new_ptr != NULL && ptr != NULL) {
oldsize = (((size_info *)ptr)[-1]).u.size;
INSIST(oldsize >= ALIGNMENT_SIZE);
oldsize -= ALIGNMENT_SIZE;
copysize = oldsize > size ? size : oldsize;
memcpy(new_ptr, ptr, copysize);
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc__mem_free(ctx0, ptr FLARG_PASS);
}
} else if (ptr != NULL)
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc__mem_free(ctx0, ptr FLARG_PASS);
return (new_ptr);
}
-void
-isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
+ISC_MEMFUNC_SCOPE void
+isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
size_t size;
isc_boolean_t call_water= ISC_FALSE;
@@ -1451,8 +1636,9 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
* Other useful things.
*/
-char *
-isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
+ISC_MEMFUNC_SCOPE char *
+isc___mem_strdup(isc_mem_t *mctx0, const char *s FLARG) {
+ isc__mem_t *mctx = (isc__mem_t *)mctx0;
size_t len;
char *ns;
@@ -1461,7 +1647,7 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
len = strlen(s);
- ns = isc__mem_allocate(mctx, len + 1 FLARG_PASS);
+ ns = isc___mem_allocate((isc_mem_t *)mctx, len + 1 FLARG_PASS);
if (ns != NULL)
strncpy(ns, s, len + 1);
@@ -1469,8 +1655,10 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
return (ns);
}
-void
-isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_setdestroycheck(isc_mem_t *ctx0, isc_boolean_t flag) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1483,8 +1671,10 @@ isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
* Quotas
*/
-void
-isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_setquota(isc_mem_t *ctx0, size_t quota) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1493,8 +1683,9 @@ isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
MCTXUNLOCK(ctx, &ctx->lock);
}
-size_t
-isc_mem_getquota(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_getquota(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t quota;
REQUIRE(VALID_CONTEXT(ctx));
@@ -1507,8 +1698,9 @@ isc_mem_getquota(isc_mem_t *ctx) {
return (quota);
}
-size_t
-isc_mem_inuse(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_inuse(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t inuse;
REQUIRE(VALID_CONTEXT(ctx));
@@ -1521,10 +1713,11 @@ isc_mem_inuse(isc_mem_t *ctx) {
return (inuse);
}
-void
-isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
+ISC_MEMFUNC_SCOPE void
+isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg,
size_t hiwater, size_t lowater)
{
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
isc_boolean_t callwater = ISC_FALSE;
isc_mem_water_t oldwater;
void *oldwater_arg;
@@ -1559,8 +1752,10 @@ isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
(oldwater)(oldwater_arg, ISC_MEM_LOWATER);
}
-void
-isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_setname(isc_mem_t *ctx0, const char *name, void *tag) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
LOCK(&ctx->lock);
@@ -1570,15 +1765,19 @@ isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
UNLOCK(&ctx->lock);
}
-const char *
-isc_mem_getname(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE const char *
+isc__mem_getname(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
return (ctx->name);
}
-void *
-isc_mem_gettag(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE void *
+isc__mem_gettag(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
return (ctx->tag);
@@ -1588,9 +1787,10 @@ isc_mem_gettag(isc_mem_t *ctx) {
* Memory pool stuff
*/
-isc_result_t
-isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
- isc_mempool_t *mpctx;
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mempool_create(isc_mem_t *mctx0, size_t size, isc_mempool_t **mpctxp) {
+ isc__mem_t *mctx = (isc__mem_t *)mctx0;
+ isc__mempool_t *mpctx;
REQUIRE(VALID_CONTEXT(mctx));
REQUIRE(size > 0U);
@@ -1600,11 +1800,13 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
* Allocate space for this pool, initialize values, and if all works
* well, attach to the memory context.
*/
- mpctx = isc_mem_get(mctx, sizeof(isc_mempool_t));
+ mpctx = isc_mem_get((isc_mem_t *)mctx, sizeof(isc__mempool_t));
if (mpctx == NULL)
return (ISC_R_NOMEMORY);
- mpctx->magic = MEMPOOL_MAGIC;
+ mpctx->common.methods = (isc_mempoolmethods_t *)&mempoolmethods;
+ mpctx->common.impmagic = MEMPOOL_MAGIC;
+ mpctx->common.magic = ISCAPI_MPOOL_MAGIC;
mpctx->lock = NULL;
mpctx->mctx = mctx;
mpctx->size = size;
@@ -1619,7 +1821,7 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
#endif
mpctx->items = NULL;
- *mpctxp = mpctx;
+ *mpctxp = (isc_mempool_t *)mpctx;
MCTXLOCK(mctx, &mctx->lock);
ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link);
@@ -1629,9 +1831,12 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
return (ISC_R_SUCCESS);
}
-void
-isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setname(isc_mempool_t *mpctx0, const char *name) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(name != NULL);
+ REQUIRE(VALID_MEMPOOL(mpctx));
#if ISC_MEMPOOL_NAMES
if (mpctx->lock != NULL)
@@ -1648,20 +1853,20 @@ isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
#endif
}
-void
-isc_mempool_destroy(isc_mempool_t **mpctxp) {
- isc_mempool_t *mpctx;
- isc_mem_t *mctx;
+ISC_MEMFUNC_SCOPE void
+isc__mempool_destroy(isc_mempool_t **mpctxp) {
+ isc__mempool_t *mpctx;
+ isc__mem_t *mctx;
isc_mutex_t *lock;
element *item;
REQUIRE(mpctxp != NULL);
- mpctx = *mpctxp;
+ mpctx = (isc__mempool_t *)*mpctxp;
REQUIRE(VALID_MEMPOOL(mpctx));
#if ISC_MEMPOOL_NAMES
if (mpctx->allocated > 0)
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mempool_destroy(): mempool %s "
+ "isc__mempool_destroy(): mempool %s "
"leaked memory",
mpctx->name);
#endif
@@ -1701,9 +1906,10 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
mctx->poolcnt--;
MCTXUNLOCK(mctx, &mctx->lock);
- mpctx->magic = 0;
+ mpctx->common.impmagic = 0;
+ mpctx->common.magic = 0;
- isc_mem_put(mpctx->mctx, mpctx, sizeof(isc_mempool_t));
+ isc_mem_put((isc_mem_t *)mpctx->mctx, mpctx, sizeof(isc__mempool_t));
if (lock != NULL)
UNLOCK(lock);
@@ -1711,8 +1917,10 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
*mpctxp = NULL;
}
-void
-isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_associatelock(isc_mempool_t *mpctx0, isc_mutex_t *lock) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(VALID_MEMPOOL(mpctx));
REQUIRE(mpctx->lock == NULL);
REQUIRE(lock != NULL);
@@ -1720,10 +1928,11 @@ isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
mpctx->lock = lock;
}
-void *
-isc__mempool_get(isc_mempool_t *mpctx FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mempool_get(isc_mempool_t *mpctx0 FLARG) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
element *item;
- isc_mem_t *mctx;
+ isc__mem_t *mctx;
unsigned int i;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1802,9 +2011,10 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
return (item);
}
-void
-isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
- isc_mem_t *mctx;
+ISC_MEMFUNC_SCOPE void
+isc___mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+ isc__mem_t *mctx;
element *item;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1859,8 +2069,10 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
* Quotas
*/
-void
-isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfreemax(isc_mempool_t *mpctx0, unsigned int limit) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
@@ -1872,8 +2084,9 @@ isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
UNLOCK(mpctx->lock);
}
-unsigned int
-isc_mempool_getfreemax(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreemax(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int freemax;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1889,8 +2102,9 @@ isc_mempool_getfreemax(isc_mempool_t *mpctx) {
return (freemax);
}
-unsigned int
-isc_mempool_getfreecount(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreecount(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int freecount;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1906,8 +2120,10 @@ isc_mempool_getfreecount(isc_mempool_t *mpctx) {
return (freecount);
}
-void
-isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setmaxalloc(isc_mempool_t *mpctx0, unsigned int limit) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(limit > 0);
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1921,8 +2137,9 @@ isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
UNLOCK(mpctx->lock);
}
-unsigned int
-isc_mempool_getmaxalloc(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getmaxalloc(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int maxalloc;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1938,8 +2155,9 @@ isc_mempool_getmaxalloc(isc_mempool_t *mpctx) {
return (maxalloc);
}
-unsigned int
-isc_mempool_getallocated(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getallocated(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int allocated;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1955,8 +2173,10 @@ isc_mempool_getallocated(isc_mempool_t *mpctx) {
return (allocated);
}
-void
-isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfillcount(isc_mempool_t *mpctx0, unsigned int limit) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(limit > 0);
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1969,8 +2189,10 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
UNLOCK(mpctx->lock);
}
-unsigned int
-isc_mempool_getfillcount(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfillcount(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
unsigned int fillcount;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1986,8 +2208,17 @@ isc_mempool_getfillcount(isc_mempool_t *mpctx) {
return (fillcount);
}
-void
-isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
+#ifdef USE_MEMIMPREGISTER
+isc_result_t
+isc__mem_register() {
+ return (isc_mem_register(isc__mem_create2));
+}
+#endif
+
+#ifdef BIND9
+ISC_MEMFUNC_SCOPE void
+isc__mem_printactive(isc_mem_t *ctx0, FILE *file) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(file != NULL);
@@ -2000,12 +2231,12 @@ isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
#endif
}
-void
-isc_mem_printallactive(FILE *file) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_printallactive(FILE *file) {
#if !ISC_MEM_TRACKLINES
UNUSED(file);
#else
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
@@ -2020,15 +2251,15 @@ isc_mem_printallactive(FILE *file) {
#endif
}
-void
-isc_mem_checkdestroyed(FILE *file) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_checkdestroyed(FILE *file) {
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
LOCK(&lock);
if (!ISC_LIST_EMPTY(contexts)) {
#if ISC_MEM_TRACKLINES
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
for (ctx = ISC_LIST_HEAD(contexts);
ctx != NULL;
@@ -2043,9 +2274,11 @@ isc_mem_checkdestroyed(FILE *file) {
UNLOCK(&lock);
}
-unsigned int
-isc_mem_references(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc_mem_references(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
unsigned int references;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -2065,7 +2298,7 @@ typedef struct summarystat {
} summarystat_t;
static void
-renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
+renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
REQUIRE(VALID_CONTEXT(ctx));
xmlTextWriterStartElement(writer, ISC_XMLCHAR "context");
@@ -2151,7 +2384,7 @@ renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
void
isc_mem_renderxml(xmlTextWriterPtr writer) {
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
summarystat_t summary;
isc_uint64_t lost;
@@ -2203,3 +2436,4 @@ isc_mem_renderxml(xmlTextWriterPtr writer) {
}
#endif /* HAVE_LIBXML2 */
+#endif /* BIND9 */
diff --git a/lib/isc/mem_api.c b/lib/isc/mem_api.c
new file mode 100644
index 00000000..470c8201
--- /dev/null
+++ b/lib/isc/mem_api.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: mem_api.c,v 1.5 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/once.h>
+#include <isc/util.h>
+
+#if ISC_MEM_TRACKLINES
+#define FLARG_PASS , file, line
+#define FLARG , const char *file, int line
+#else
+#define FLARG_PASS
+#define FLARG
+#endif
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_memcreatefunc_t mem_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_mem_register(isc_memcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (mem_createfunc == NULL)
+ mem_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(mem_createfunc != NULL);
+ result = (*mem_createfunc)(init_max_size, target_size, mctxp,
+ ISC_MEMFLAG_DEFAULT);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp,
+ unsigned int flags)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(mem_createfunc != NULL);
+ result = (*mem_createfunc)(init_max_size, target_size, mctxp, flags);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
+ REQUIRE(ISCAPI_MCTX_VALID(source));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ source->methods->attach(source, targetp);
+
+ ENSURE(*targetp == source);
+}
+
+void
+isc_mem_detach(isc_mem_t **mctxp) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->detach(mctxp);
+
+ ENSURE(*mctxp == NULL);
+}
+
+void
+isc_mem_destroy(isc_mem_t **mctxp) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->destroy(mctxp);
+
+ ENSURE(*mctxp == NULL);
+}
+
+void *
+isc__mem_get(isc_mem_t *mctx, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memget(mctx, size FLARG_PASS));
+}
+
+void
+isc__mem_put(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->memput(mctx, ptr, size FLARG_PASS);
+}
+
+void
+isc__mem_putanddetach(isc_mem_t **mctxp, void *ptr, size_t size FLARG) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->memputanddetach(mctxp, ptr, size FLARG_PASS);
+
+ /*
+ * XXX: We cannot always ensure *mctxp == NULL here
+ * (see lib/isc/mem.c).
+ */
+}
+
+void *
+isc__mem_allocate(isc_mem_t *mctx, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memallocate(mctx, size FLARG_PASS));
+}
+
+void *
+isc__mem_reallocate(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memreallocate(mctx, ptr, size FLARG_PASS));
+}
+
+char *
+isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memstrdup(mctx, s FLARG_PASS));
+}
+
+void
+isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->memfree(mctx, ptr FLARG_PASS);
+}
+
+void
+isc_mem_setdestroycheck(isc_mem_t *mctx, isc_boolean_t flag) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->setdestroycheck(mctx, flag);
+}
+
+void
+isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
+ size_t hiwater, size_t lowater)
+{
+ REQUIRE(ISCAPI_MCTX_VALID(ctx));
+
+ ctx->methods->setwater(ctx, water, water_arg, hiwater, lowater);
+}
+
+void
+isc_mem_waterack(isc_mem_t *ctx, int flag) {
+ REQUIRE(ISCAPI_MCTX_VALID(ctx));
+
+ ctx->methods->waterack(ctx, flag);
+}
+
+size_t
+isc_mem_inuse(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->inuse(mctx));
+}
+
+void
+isc_mem_setname(isc_mem_t *mctx, const char *name, void *tag) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ UNUSED(name);
+ UNUSED(tag);
+
+ return;
+}
+
+const char *
+isc_mem_getname(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return ("");
+}
+
+void *
+isc_mem_gettag(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (NULL);
+}
+
+isc_result_t
+isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->mpcreate(mctx, size, mpctxp));
+}
+
+void
+isc_mempool_destroy(isc_mempool_t **mpctxp) {
+ REQUIRE(mpctxp != NULL && ISCAPI_MPOOL_VALID(*mpctxp));
+
+ (*mpctxp)->methods->destroy(mpctxp);
+
+ ENSURE(*mpctxp == NULL);
+}
+
+void *
+isc__mempool_get(isc_mempool_t *mpctx FLARG) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ return (mpctx->methods->get(mpctx FLARG_PASS));
+}
+
+void
+isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->put(mpctx, mem FLARG_PASS);
+}
+
+unsigned int
+isc_mempool_getallocated(isc_mempool_t *mpctx) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ return (mpctx->methods->getallocated(mpctx));
+}
+
+void
+isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setmaxalloc(mpctx, limit);
+}
+
+void
+isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setfreemax(mpctx, limit);
+}
+
+void
+isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setname(mpctx, name);
+}
+
+void
+isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->associatelock(mpctx, lock);
+}
+
+void
+isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setfillcount(mpctx, limit);
+}
diff --git a/lib/isc/nls/Makefile.in b/lib/isc/nls/Makefile.in
index 695c3132..8302a927 100644
--- a/lib/isc/nls/Makefile.in
+++ b/lib/isc/nls/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.14 2007/06/19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.16 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ CINCLUDES = -I../unix/include \
-I../include \
-I${srcdir}/../include
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
OBJS = msgcat.@O@
diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in
index 75a2cb5e..eef17652 100644
--- a/lib/isc/nothreads/Makefile.in
+++ b/lib/isc/nothreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,11 +13,11 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.7 2007/06/19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.9 2009/09/02 23:48:03 tbox Exp $
-srcdir = @srcdir@
-VPATH = @srcdir@
top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/nothreads
+VPATH = @top_srcdir@/lib/isc/nothreads
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../unix/include \
@@ -25,7 +25,7 @@ CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../include \
-I${srcdir}/..
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
OBJS = condition.@O@ mutex.@O@ thread.@O@
diff --git a/lib/isc/pthreads/Makefile.in b/lib/isc/pthreads/Makefile.in
index a2874578..2cbda99f 100644
--- a/lib/isc/pthreads/Makefile.in
+++ b/lib/isc/pthreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.19 2007/06/19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.21 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,7 +25,7 @@ CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../include \
-I${srcdir}/..
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
OBJS = condition.@O@ mutex.@O@ thread.@O@
diff --git a/lib/isc/socket_api.c b/lib/isc/socket_api.c
new file mode 100644
index 00000000..8ba20607
--- /dev/null
+++ b/lib/isc/socket_api.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: socket_api.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_socketmgrcreatefunc_t socketmgr_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_socket_register(isc_socketmgrcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (socketmgr_createfunc == NULL)
+ socketmgr_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_socketmgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(socketmgr_createfunc != NULL);
+ result = (*socketmgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ if (result == ISC_R_SUCCESS)
+ isc_appctx_setsocketmgr(actx, *managerp);
+
+ return (result);
+}
+
+isc_result_t
+isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(socketmgr_createfunc != NULL);
+ result = (*socketmgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
+ REQUIRE(managerp != NULL && ISCAPI_SOCKETMGR_VALID(*managerp));
+
+ (*managerp)->methods->destroy(managerp);
+
+ ENSURE(*managerp == NULL);
+}
+
+isc_result_t
+isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
+ isc_socket_t **socketp)
+{
+ REQUIRE(ISCAPI_SOCKETMGR_VALID(manager));
+
+ return (manager->methods->socketcreate(manager, pf, type, socketp));
+}
+
+void
+isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+ REQUIRE(socketp != NULL && *socketp == NULL);
+
+ sock->methods->attach(sock, socketp);
+
+ ENSURE(*socketp == sock);
+}
+
+void
+isc_socket_detach(isc_socket_t **socketp) {
+ REQUIRE(socketp != NULL && ISCAPI_SOCKET_VALID(*socketp));
+
+ (*socketp)->methods->detach(socketp);
+
+ ENSURE(*socketp == NULL);
+}
+
+isc_result_t
+isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->bind(sock, sockaddr, options));
+}
+
+isc_result_t
+isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
+ isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->sendto(sock, region, task, action, arg, address,
+ pktinfo));
+}
+
+isc_result_t
+isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->connect(sock, addr, task, action, arg));
+}
+
+isc_result_t
+isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->recv(sock, region, minimum, task, action, arg));
+}
+
+void
+isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ sock->methods->cancel(sock, task, how);
+}
+
+isc_result_t
+isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->getsockname(sock, addressp));
+}
+
+void
+isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ sock->methods->ipv6only(sock, yes);
+}
+
+isc_sockettype_t
+isc_socket_gettype(isc_socket_t *sock) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->gettype(sock));
+}
+
+void
+isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
+ REQUIRE(ISCAPI_SOCKET_VALID(socket));
+
+ UNUSED(socket); /* in case REQUIRE() is empty */
+ UNUSED(name);
+ UNUSED(tag);
+}
diff --git a/lib/isc/task.c b/lib/isc/task.c
index a630173d..ddd4a534 100644
--- a/lib/isc/task.c
+++ b/lib/isc/task.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task.c,v 1.107 2008/03/27 23:46:57 tbox Exp $ */
+/* $Id: task.c,v 1.110 2009/09/02 23:48:02 tbox Exp $ */
/*! \file
* \author Principal Author: Bob Halley
@@ -40,9 +40,29 @@
#include <isc/util.h>
#include <isc/xml.h>
-#ifndef ISC_PLATFORM_USETHREADS
+/*%
+ * For BIND9 internal applications:
+ * when built with threads we use multiple worker threads shared by the whole
+ * application.
+ * when built without threads we share a single global task manager and use
+ * an integrated event loop for socket, timer, and other generic task events.
+ * For generic library:
+ * we don't use either of them: an application can have multiple task managers
+ * whether or not it's threaded, and if the application is threaded each thread
+ * is expected to have a separate manager; no "worker threads" are shared by
+ * the application threads.
+ */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_WORKER_THREADS
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#ifndef USE_WORKER_THREADS
#include "task_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
#ifdef ISC_TASK_TRACE
#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
@@ -66,7 +86,7 @@ typedef enum {
task_state_done
} task_state_t;
-#ifdef HAVE_LIBXML2
+#if defined(HAVE_LIBXML2) && defined(BIND9)
static const char *statenames[] = {
"idle", "ready", "running", "done",
};
@@ -75,10 +95,13 @@ static const char *statenames[] = {
#define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K')
#define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC)
-struct isc_task {
+typedef struct isc__task isc__task_t;
+typedef struct isc__taskmgr isc__taskmgr_t;
+
+struct isc__task {
/* Not locked. */
- unsigned int magic;
- isc_taskmgr_t * manager;
+ isc_task_t common;
+ isc__taskmgr_t * manager;
isc_mutex_t lock;
/* Locked by task lock. */
task_state_t state;
@@ -91,8 +114,8 @@ struct isc_task {
char name[16];
void * tag;
/* Locked by task manager lock. */
- LINK(isc_task_t) link;
- LINK(isc_task_t) ready_link;
+ LINK(isc__task_t) link;
+ LINK(isc__task_t) ready_link;
};
#define TASK_F_SHUTTINGDOWN 0x01
@@ -103,9 +126,11 @@ struct isc_task {
#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC)
-struct isc_taskmgr {
+typedef ISC_LIST(isc__task_t) isc__tasklist_t;
+
+struct isc__taskmgr {
/* Not locked. */
- unsigned int magic;
+ isc_taskmgr_t common;
isc_mem_t * mctx;
isc_mutex_t lock;
#ifdef ISC_PLATFORM_USETHREADS
@@ -114,8 +139,8 @@ struct isc_taskmgr {
#endif /* ISC_PLATFORM_USETHREADS */
/* Locked by task manager lock. */
unsigned int default_quantum;
- LIST(isc_task_t) tasks;
- isc_tasklist_t ready_tasks;
+ LIST(isc__task_t) tasks;
+ isc__tasklist_t ready_tasks;
#ifdef ISC_PLATFORM_USETHREADS
isc_condition_t work_available;
isc_condition_t exclusive_granted;
@@ -123,7 +148,7 @@ struct isc_taskmgr {
unsigned int tasks_running;
isc_boolean_t exclusive_requested;
isc_boolean_t exiting;
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
unsigned int refs;
#endif /* ISC_PLATFORM_USETHREADS */
};
@@ -132,17 +157,117 @@ struct isc_taskmgr {
#define DEFAULT_DEFAULT_QUANTUM 5
#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
-#ifndef ISC_PLATFORM_USETHREADS
-static isc_taskmgr_t *taskmgr = NULL;
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifdef USE_SHARED_MANAGER
+static isc__taskmgr_t *taskmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_TASKFUNC_SCOPE
+#else
+#define ISC_TASKFUNC_SCOPE static
+#endif
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
+ isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_attach(isc_task_t *source0, isc_task_t **targetp);
+ISC_TASKFUNC_SCOPE void
+isc__task_detach(isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_send(isc_task_t *task0, isc_event_t **eventp);
+ISC_TASKFUNC_SCOPE void
+isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag);
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_purgeevent(isc_task_t *task0, isc_event_t *event);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action,
+ const void *arg);
+ISC_TASKFUNC_SCOPE void
+isc__task_shutdown(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_destroy(isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_setname(isc_task_t *task0, const char *name, void *tag);
+ISC_TASKFUNC_SCOPE const char *
+isc__task_getname(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void *
+isc__task_gettag(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_destroy(isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_beginexclusive(isc_task_t *task);
+ISC_TASKFUNC_SCOPE void
+isc__task_endexclusive(isc_task_t *task0);
+
+static struct isc__taskmethods {
+ isc_taskmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *purgeevent, *unsendrange,
+ *getname, *gettag, *getcurrenttime, *beginexclusive,
+ *endexclusive;
+#endif
+} taskmethods = {
+ {
+ isc__task_attach,
+ isc__task_detach,
+ isc__task_destroy,
+ isc__task_send,
+ isc__task_sendanddetach,
+ isc__task_unsend,
+ isc__task_onshutdown,
+ isc__task_shutdown,
+ isc__task_setname,
+ isc__task_purge,
+ isc__task_purgerange
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__task_purgeevent, (void *)isc__task_unsendrange,
+ (void *)isc__task_getname, (void *)isc__task_gettag,
+ (void *)isc__task_getcurrenttime, (void *)isc__task_beginexclusive,
+ (void *)isc__task_endexclusive
+#endif
+};
+
+static isc_taskmgrmethods_t taskmgrmethods = {
+ isc__taskmgr_destroy,
+ isc__task_create
+};
/***
*** Tasks.
***/
static void
-task_finished(isc_task_t *task) {
- isc_taskmgr_t *manager = task->manager;
+task_finished(isc__task_t *task) {
+ isc__taskmgr_t *manager = task->manager;
REQUIRE(EMPTY(task->events));
REQUIRE(EMPTY(task->on_shutdown));
@@ -153,7 +278,7 @@ task_finished(isc_task_t *task) {
LOCK(&manager->lock);
UNLINK(manager->tasks, task, link);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
if (FINISHED(manager)) {
/*
* All tasks have completed and the
@@ -163,19 +288,21 @@ task_finished(isc_task_t *task) {
*/
BROADCAST(&manager->work_available);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
DESTROYLOCK(&task->lock);
- task->magic = 0;
+ task->common.impmagic = 0;
+ task->common.magic = 0;
isc_mem_put(manager->mctx, task, sizeof(*task));
}
-isc_result_t
-isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
- isc_task_t **taskp)
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
+ isc_task_t **taskp)
{
- isc_task_t *task;
+ isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
+ isc__task_t *task;
isc_boolean_t exiting;
isc_result_t result;
@@ -220,14 +347,17 @@ isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
return (ISC_R_SHUTTINGDOWN);
}
- task->magic = TASK_MAGIC;
- *taskp = task;
+ task->common.methods = (isc_taskmethods_t *)&taskmethods;
+ task->common.magic = ISCAPI_TASK_MAGIC;
+ task->common.impmagic = TASK_MAGIC;
+ *taskp = (isc_task_t *)task;
return (ISC_R_SUCCESS);
}
-void
-isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_attach(isc_task_t *source0, isc_task_t **targetp) {
+ isc__task_t *source = (isc__task_t *)source0;
/*
* Attach *targetp to source.
@@ -242,11 +372,11 @@ isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
source->references++;
UNLOCK(&source->lock);
- *targetp = source;
+ *targetp = (isc_task_t *)source;
}
static inline isc_boolean_t
-task_shutdown(isc_task_t *task) {
+task_shutdown(isc__task_t *task) {
isc_boolean_t was_idle = ISC_FALSE;
isc_event_t *event, *prev;
@@ -283,8 +413,8 @@ task_shutdown(isc_task_t *task) {
}
static inline void
-task_ready(isc_task_t *task) {
- isc_taskmgr_t *manager = task->manager;
+task_ready(isc__task_t *task) {
+ isc__taskmgr_t *manager = task->manager;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(task->state == task_state_ready);
@@ -294,15 +424,15 @@ task_ready(isc_task_t *task) {
LOCK(&manager->lock);
ENQUEUE(manager->ready_tasks, task, ready_link);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
SIGNAL(&manager->work_available);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
}
static inline isc_boolean_t
-task_detach(isc_task_t *task) {
+task_detach(isc__task_t *task) {
/*
* Caller must be holding the task lock.
@@ -330,9 +460,9 @@ task_detach(isc_task_t *task) {
return (ISC_FALSE);
}
-void
-isc_task_detach(isc_task_t **taskp) {
- isc_task_t *task;
+ISC_TASKFUNC_SCOPE void
+isc__task_detach(isc_task_t **taskp) {
+ isc__task_t *task;
isc_boolean_t was_idle;
/*
@@ -340,7 +470,7 @@ isc_task_detach(isc_task_t **taskp) {
*/
REQUIRE(taskp != NULL);
- task = *taskp;
+ task = (isc__task_t *)*taskp;
REQUIRE(VALID_TASK(task));
XTRACE("isc_task_detach");
@@ -356,7 +486,7 @@ isc_task_detach(isc_task_t **taskp) {
}
static inline isc_boolean_t
-task_send(isc_task_t *task, isc_event_t **eventp) {
+task_send(isc__task_t *task, isc_event_t **eventp) {
isc_boolean_t was_idle = ISC_FALSE;
isc_event_t *event;
@@ -385,8 +515,9 @@ task_send(isc_task_t *task, isc_event_t **eventp) {
return (was_idle);
}
-void
-isc_task_send(isc_task_t *task, isc_event_t **eventp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_send(isc_task_t *task0, isc_event_t **eventp) {
+ isc__task_t *task = (isc__task_t *)task0;
isc_boolean_t was_idle;
/*
@@ -426,10 +557,10 @@ isc_task_send(isc_task_t *task, isc_event_t **eventp) {
}
}
-void
-isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
isc_boolean_t idle1, idle2;
- isc_task_t *task;
+ isc__task_t *task;
/*
* Send '*event' to '*taskp' and then detach '*taskp' from its
@@ -437,7 +568,7 @@ isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
*/
REQUIRE(taskp != NULL);
- task = *taskp;
+ task = (isc__task_t *)*taskp;
REQUIRE(VALID_TASK(task));
XTRACE("isc_task_sendanddetach");
@@ -463,7 +594,7 @@ isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
#define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0)
static unsigned int
-dequeue_events(isc_task_t *task, void *sender, isc_eventtype_t first,
+dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first,
isc_eventtype_t last, void *tag,
isc_eventlist_t *events, isc_boolean_t purging)
{
@@ -502,10 +633,11 @@ dequeue_events(isc_task_t *task, void *sender, isc_eventtype_t first,
return (count);
}
-unsigned int
-isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
- isc_eventtype_t last, void *tag)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag)
{
+ isc__task_t *task = (isc__task_t *)task0;
unsigned int count;
isc_eventlist_t events;
isc_event_t *event, *next_event;
@@ -533,9 +665,9 @@ isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
return (count);
}
-unsigned int
-isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
- void *tag)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag)
{
/*
* Purge events from a task's event queue.
@@ -543,11 +675,12 @@ isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
XTRACE("isc_task_purge");
- return (isc_task_purgerange(task, sender, type, type, tag));
+ return (isc__task_purgerange(task, sender, type, type, tag));
}
-isc_boolean_t
-isc_task_purgeevent(isc_task_t *task, isc_event_t *event) {
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_purgeevent(isc_task_t *task0, isc_event_t *event) {
+ isc__task_t *task = (isc__task_t *)task0;
isc_event_t *curr_event, *next_event;
/*
@@ -588,10 +721,10 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event) {
return (ISC_TRUE);
}
-unsigned int
-isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
- isc_eventtype_t last, void *tag,
- isc_eventlist_t *events)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events)
{
/*
* Remove events from a task's event queue.
@@ -599,13 +732,13 @@ isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
XTRACE("isc_task_unsendrange");
- return (dequeue_events(task, sender, first, last, tag, events,
- ISC_FALSE));
+ return (dequeue_events((isc__task_t *)task, sender, first,
+ last, tag, events, ISC_FALSE));
}
-unsigned int
-isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
- void *tag, isc_eventlist_t *events)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events)
{
/*
* Remove events from a task's event queue.
@@ -613,13 +746,15 @@ isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
XTRACE("isc_task_unsend");
- return (dequeue_events(task, sender, type, type, tag, events,
- ISC_FALSE));
+ return (dequeue_events((isc__task_t *)task, sender, type,
+ type, tag, events, ISC_FALSE));
}
-isc_result_t
-isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action,
+ const void *arg)
{
+ isc__task_t *task = (isc__task_t *)task0;
isc_boolean_t disallowed = ISC_FALSE;
isc_result_t result = ISC_R_SUCCESS;
isc_event_t *event;
@@ -655,8 +790,9 @@ isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
return (result);
}
-void
-isc_task_shutdown(isc_task_t *task) {
+ISC_TASKFUNC_SCOPE void
+isc__task_shutdown(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
isc_boolean_t was_idle;
/*
@@ -673,8 +809,8 @@ isc_task_shutdown(isc_task_t *task) {
task_ready(task);
}
-void
-isc_task_destroy(isc_task_t **taskp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_destroy(isc_task_t **taskp) {
/*
* Destroy '*taskp'.
@@ -686,8 +822,9 @@ isc_task_destroy(isc_task_t **taskp) {
isc_task_detach(taskp);
}
-void
-isc_task_setname(isc_task_t *task, const char *name, void *tag) {
+ISC_TASKFUNC_SCOPE void
+isc__task_setname(isc_task_t *task0, const char *name, void *tag) {
+ isc__task_t *task = (isc__task_t *)task0;
/*
* Name 'task'.
@@ -702,18 +839,28 @@ isc_task_setname(isc_task_t *task, const char *name, void *tag) {
UNLOCK(&task->lock);
}
-const char *
-isc_task_getname(isc_task_t *task) {
+ISC_TASKFUNC_SCOPE const char *
+isc__task_getname(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+
return (task->name);
}
-void *
-isc_task_gettag(isc_task_t *task) {
+ISC_TASKFUNC_SCOPE void *
+isc__task_gettag(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+
return (task->tag);
}
-void
-isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) {
+ISC_TASKFUNC_SCOPE void
+isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t) {
+ isc__task_t *task = (isc__task_t *)task0;
+
REQUIRE(VALID_TASK(task));
REQUIRE(t != NULL);
@@ -728,12 +875,12 @@ isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) {
*** Task Manager.
***/
static void
-dispatch(isc_taskmgr_t *manager) {
- isc_task_t *task;
-#ifndef ISC_PLATFORM_USETHREADS
+dispatch(isc__taskmgr_t *manager) {
+ isc__task_t *task;
+#ifndef USE_WORKER_THREADS
unsigned int total_dispatch_count = 0;
- isc_tasklist_t ready_tasks;
-#endif /* ISC_PLATFORM_USETHREADS */
+ isc__tasklist_t ready_tasks;
+#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
@@ -787,12 +934,12 @@ dispatch(isc_taskmgr_t *manager) {
* unlocks. The while expression is always protected by the lock.
*/
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
ISC_LIST_INIT(ready_tasks);
#endif
LOCK(&manager->lock);
while (!FINISHED(manager)) {
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
/*
* For reasons similar to those given in the comment in
* isc_task_send() above, it is safe for us to dequeue
@@ -812,11 +959,11 @@ dispatch(isc_taskmgr_t *manager) {
ISC_MSGSET_TASK,
ISC_MSG_AWAKE, "awake"));
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WORKER_THREADS */
if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||
EMPTY(manager->ready_tasks))
break;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
ISC_MSG_WORKING, "working"));
@@ -859,13 +1006,15 @@ dispatch(isc_taskmgr_t *manager) {
"execute action"));
if (event->ev_action != NULL) {
UNLOCK(&task->lock);
- (event->ev_action)(task,event);
+ (event->ev_action)(
+ (isc_task_t *)task,
+ event);
LOCK(&task->lock);
}
dispatch_count++;
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
total_dispatch_count++;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
}
if (task->references == 0 &&
@@ -950,12 +1099,12 @@ dispatch(isc_taskmgr_t *manager) {
LOCK(&manager->lock);
manager->tasks_running--;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
if (manager->exclusive_requested &&
manager->tasks_running == 1) {
SIGNAL(&manager->exclusive_granted);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
if (requeue) {
/*
* We know we're awake, so we don't have
@@ -976,7 +1125,7 @@ dispatch(isc_taskmgr_t *manager) {
* were usually nonempty, the 'optimization'
* might even hurt rather than help.
*/
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
ENQUEUE(manager->ready_tasks, task,
ready_link);
#else
@@ -985,19 +1134,19 @@ dispatch(isc_taskmgr_t *manager) {
}
}
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
ISC_LIST_APPENDLIST(manager->ready_tasks, ready_tasks, ready_link);
#endif
UNLOCK(&manager->lock);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
static isc_threadresult_t
#ifdef _WIN32
WINAPI
#endif
run(void *uap) {
- isc_taskmgr_t *manager = uap;
+ isc__taskmgr_t *manager = uap;
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_STARTING, "starting"));
@@ -1009,31 +1158,36 @@ run(void *uap) {
return ((isc_threadresult_t)0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
static void
-manager_free(isc_taskmgr_t *manager) {
+manager_free(isc__taskmgr_t *manager) {
isc_mem_t *mctx;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
(void)isc_condition_destroy(&manager->exclusive_granted);
(void)isc_condition_destroy(&manager->work_available);
isc_mem_free(manager->mctx, manager->threads);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
DESTROYLOCK(&manager->lock);
- manager->magic = 0;
+ manager->common.impmagic = 0;
+ manager->common.magic = 0;
mctx = manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
+
+#ifdef USE_SHARED_MANAGER
+ taskmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
}
-isc_result_t
-isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
- unsigned int default_quantum, isc_taskmgr_t **managerp)
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp)
{
isc_result_t result;
unsigned int i, started = 0;
- isc_taskmgr_t *manager;
+ isc__taskmgr_t *manager;
/*
* Create a new task manager.
@@ -1042,28 +1196,31 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
REQUIRE(workers > 0);
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
UNUSED(i);
UNUSED(started);
- UNUSED(workers);
+#endif
+#ifdef USE_SHARED_MANAGER
if (taskmgr != NULL) {
taskmgr->refs++;
- *managerp = taskmgr;
+ *managerp = (isc_taskmgr_t *)taskmgr;
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
- manager->magic = TASK_MANAGER_MAGIC;
+ manager->common.methods = &taskmgrmethods;
+ manager->common.impmagic = TASK_MANAGER_MAGIC;
+ manager->common.magic = ISCAPI_TASKMGR_MAGIC;
manager->mctx = NULL;
result = isc_mutex_init(&manager->lock);
if (result != ISC_R_SUCCESS)
goto cleanup_mgr;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
manager->workers = 0;
manager->threads = isc_mem_allocate(mctx,
workers * sizeof(isc_thread_t));
@@ -1087,7 +1244,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
result = ISC_R_UNEXPECTED;
goto cleanup_workavailable;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
if (default_quantum == 0)
default_quantum = DEFAULT_DEFAULT_QUANTUM;
manager->default_quantum = default_quantum;
@@ -1099,7 +1256,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
isc_mem_attach(mctx, &manager->mctx);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
LOCK(&manager->lock);
/*
* Start workers.
@@ -1119,16 +1276,17 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
return (ISC_R_NOTHREADS);
}
isc_thread_setconcurrency(workers);
-#else /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
+#ifdef USE_SHARED_MANAGER
manager->refs = 1;
taskmgr = manager;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
- *managerp = manager;
+ *managerp = (isc_taskmgr_t *)manager;
return (ISC_R_SUCCESS);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
cleanup_workavailable:
(void)isc_condition_destroy(&manager->work_available);
cleanup_threads:
@@ -1141,10 +1299,10 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
return (result);
}
-void
-isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
- isc_taskmgr_t *manager;
- isc_task_t *task;
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
+ isc__taskmgr_t *manager;
+ isc__task_t *task;
unsigned int i;
/*
@@ -1152,18 +1310,20 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
*/
REQUIRE(managerp != NULL);
- manager = *managerp;
+ manager = (isc__taskmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
UNUSED(i);
+#endif /* USE_WORKER_THREADS */
+#ifdef USE_SHARED_MANAGER
if (manager->refs > 1) {
manager->refs--;
*managerp = NULL;
return;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif
XTHREADTRACE("isc_taskmgr_destroy");
/*
@@ -1203,7 +1363,7 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
ENQUEUE(manager->ready_tasks, task, ready_link);
UNLOCK(&task->lock);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
/*
* Wake up any sleeping workers. This ensures we get work done if
* there's work left to do, and if there are already no tasks left
@@ -1217,36 +1377,48 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
*/
for (i = 0; i < manager->workers; i++)
(void)isc_thread_join(manager->threads[i], NULL);
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WORKER_THREADS */
/*
* Dispatch the shutdown events.
*/
UNLOCK(&manager->lock);
- while (isc__taskmgr_ready())
- (void)isc__taskmgr_dispatch();
+ while (isc__taskmgr_ready((isc_taskmgr_t *)manager))
+ (void)isc__taskmgr_dispatch((isc_taskmgr_t *)manager);
+#ifdef BIND9
if (!ISC_LIST_EMPTY(manager->tasks))
isc_mem_printallactive(stderr);
+#endif
INSIST(ISC_LIST_EMPTY(manager->tasks));
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
manager_free(manager);
*managerp = NULL;
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
isc_boolean_t
-isc__taskmgr_ready(void) {
- if (taskmgr == NULL)
+isc__taskmgr_ready(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = taskmgr;
+#endif
+ if (manager == NULL)
return (ISC_FALSE);
- return (ISC_TF(!ISC_LIST_EMPTY(taskmgr->ready_tasks)));
+ return (ISC_TF(!ISC_LIST_EMPTY(manager->ready_tasks)));
}
isc_result_t
-isc__taskmgr_dispatch(void) {
- isc_taskmgr_t *manager = taskmgr;
+isc__taskmgr_dispatch(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
- if (taskmgr == NULL)
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = taskmgr;
+#endif
+ if (manager == NULL)
return (ISC_R_NOTFOUND);
dispatch(manager);
@@ -1254,12 +1426,13 @@ isc__taskmgr_dispatch(void) {
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
-isc_result_t
-isc_task_beginexclusive(isc_task_t *task) {
-#ifdef ISC_PLATFORM_USETHREADS
- isc_taskmgr_t *manager = task->manager;
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_beginexclusive(isc_task_t *task0) {
+#ifdef USE_WORKER_THREADS
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
REQUIRE(task->state == task_state_running);
LOCK(&manager->lock);
if (manager->exclusive_requested) {
@@ -1272,15 +1445,17 @@ isc_task_beginexclusive(isc_task_t *task) {
}
UNLOCK(&manager->lock);
#else
- UNUSED(task);
+ UNUSED(task0);
#endif
return (ISC_R_SUCCESS);
}
-void
-isc_task_endexclusive(isc_task_t *task) {
-#ifdef ISC_PLATFORM_USETHREADS
- isc_taskmgr_t *manager = task->manager;
+ISC_TASKFUNC_SCOPE void
+isc__task_endexclusive(isc_task_t *task0) {
+#ifdef USE_WORKER_THREADS
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
+
REQUIRE(task->state == task_state_running);
LOCK(&manager->lock);
REQUIRE(manager->exclusive_requested);
@@ -1288,16 +1463,22 @@ isc_task_endexclusive(isc_task_t *task) {
BROADCAST(&manager->work_available);
UNLOCK(&manager->lock);
#else
- UNUSED(task);
+ UNUSED(task0);
#endif
}
-#ifdef HAVE_LIBXML2
+#ifdef USE_SOCKETIMPREGISTER
+isc_result_t
+isc__task_register() {
+ return (isc_task_register(isc__taskmgr_create));
+}
+#endif
+#if defined(HAVE_LIBXML2) && defined(BIND9)
void
-isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer)
-{
- isc_task_t *task;
+isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
+ isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0;
+ isc__task_t *task;
LOCK(&mgr->lock);
@@ -1373,4 +1554,4 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer)
UNLOCK(&mgr->lock);
}
-#endif /* HAVE_LIBXML2 */
+#endif /* HAVE_LIBXML2 && BIND9 */
diff --git a/lib/isc/task_api.c b/lib/isc/task_api.c
new file mode 100644
index 00000000..89065355
--- /dev/null
+++ b/lib/isc/task_api.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: task_api.c,v 1.5 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/task.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_taskmgrcreatefunc_t taskmgr_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_task_register(isc_taskmgrcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (taskmgr_createfunc == NULL)
+ taskmgr_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ unsigned int workers, unsigned int default_quantum,
+ isc_taskmgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(taskmgr_createfunc != NULL);
+ result = (*taskmgr_createfunc)(mctx, workers, default_quantum,
+ managerp);
+
+ UNLOCK(&createlock);
+
+ if (result == ISC_R_SUCCESS)
+ isc_appctx_settaskmgr(actx, *managerp);
+
+ return (result);
+}
+
+isc_result_t
+isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(taskmgr_createfunc != NULL);
+ result = (*taskmgr_createfunc)(mctx, workers, default_quantum,
+ managerp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
+ REQUIRE(managerp != NULL && ISCAPI_TASKMGR_VALID(*managerp));
+
+ (*managerp)->methods->destroy(managerp);
+
+ ENSURE(*managerp == NULL);
+}
+
+isc_result_t
+isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
+ isc_task_t **taskp)
+{
+ REQUIRE(ISCAPI_TASKMGR_VALID(manager));
+ REQUIRE(taskp != NULL && *taskp == NULL);
+
+ return (manager->methods->taskcreate(manager, quantum, taskp));
+}
+
+void
+isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
+ REQUIRE(ISCAPI_TASK_VALID(source));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ source->methods->attach(source, targetp);
+
+ ENSURE(*targetp == source);
+}
+
+void
+isc_task_detach(isc_task_t **taskp) {
+ REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp));
+
+ (*taskp)->methods->detach(taskp);
+
+ ENSURE(*taskp == NULL);
+}
+
+void
+isc_task_send(isc_task_t *task, isc_event_t **eventp) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+ REQUIRE(eventp != NULL && *eventp != NULL);
+
+ task->methods->send(task, eventp);
+
+ ENSURE(*eventp == NULL);
+}
+
+void
+isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
+ REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp));
+ REQUIRE(eventp != NULL && *eventp != NULL);
+
+ (*taskp)->methods->sendanddetach(taskp, eventp);
+
+ ENSURE(*taskp == NULL && *eventp == NULL);
+}
+
+unsigned int
+isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->unsend(task, sender, type, tag, events));
+}
+
+isc_result_t
+isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->onshutdown(task, action, arg));
+}
+
+void
+isc_task_shutdown(isc_task_t *task) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ task->methods->shutdown(task);
+}
+
+void
+isc_task_setname(isc_task_t *task, const char *name, void *tag) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ task->methods->setname(task, name, tag);
+}
+
+unsigned int
+isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->purgeevents(task, sender, type, tag));
+}
+
+/*%
+ * This is necessary for libisc's internal timer implementation. Other
+ * implementation might skip implementing this.
+ */
+unsigned int
+isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->purgerange(task, sender, first, last, tag));
+}
diff --git a/lib/isc/task_p.h b/lib/isc/task_p.h
index c8881039..cab2a839 100644
--- a/lib/isc/task_p.h
+++ b/lib/isc/task_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task_p.h,v 1.11 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: task_p.h,v 1.13 2009/09/02 23:48:02 tbox Exp $ */
#ifndef ISC_TASK_P_H
#define ISC_TASK_P_H
@@ -23,9 +23,9 @@
/*! \file */
isc_boolean_t
-isc__taskmgr_ready(void);
+isc__taskmgr_ready(isc_taskmgr_t *taskmgr);
isc_result_t
-isc__taskmgr_dispatch(void);
+isc__taskmgr_dispatch(isc_taskmgr_t *taskmgr);
#endif /* ISC_TASK_P_H */
diff --git a/lib/isc/timer.c b/lib/isc/timer.c
index b40f404c..f9c4bf86 100644
--- a/lib/isc/timer.c
+++ b/lib/isc/timer.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: timer.c,v 1.89 2009/01/23 23:47:54 tbox Exp $ */
+/* $Id: timer.c,v 1.94 2009/09/03 21:55:13 jinmei Exp $ */
/*! \file */
@@ -34,9 +34,18 @@
#include <isc/timer.h>
#include <isc/util.h>
-#ifndef ISC_PLATFORM_USETHREADS
+/* See task.c about the following definition: */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_TIMER_THREAD
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#ifndef USE_TIMER_THREAD
#include "timer_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
#ifdef ISC_TIMER_TRACE
#define XTRACE(s) fprintf(stderr, "%s\n", (s))
@@ -58,10 +67,13 @@
#define TIMER_MAGIC ISC_MAGIC('T', 'I', 'M', 'R')
#define VALID_TIMER(t) ISC_MAGIC_VALID(t, TIMER_MAGIC)
-struct isc_timer {
+typedef struct isc__timer isc__timer_t;
+typedef struct isc__timermgr isc__timermgr_t;
+
+struct isc__timer {
/*! Not locked. */
- unsigned int magic;
- isc_timermgr_t * manager;
+ isc_timer_t common;
+ isc__timermgr_t * manager;
isc_mutex_t lock;
/*! Locked by timer lock. */
unsigned int references;
@@ -75,45 +87,119 @@ struct isc_timer {
void * arg;
unsigned int index;
isc_time_t due;
- LINK(isc_timer_t) link;
+ LINK(isc__timer_t) link;
};
#define TIMER_MANAGER_MAGIC ISC_MAGIC('T', 'I', 'M', 'M')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TIMER_MANAGER_MAGIC)
-struct isc_timermgr {
+struct isc__timermgr {
/* Not locked. */
- unsigned int magic;
+ isc_timermgr_t common;
isc_mem_t * mctx;
isc_mutex_t lock;
/* Locked by manager lock. */
isc_boolean_t done;
- LIST(isc_timer_t) timers;
+ LIST(isc__timer_t) timers;
unsigned int nscheduled;
isc_time_t due;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
isc_condition_t wakeup;
isc_thread_t thread;
-#else /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
+#ifdef USE_SHARED_MANAGER
unsigned int refs;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
isc_heap_t * heap;
};
-#ifndef ISC_PLATFORM_USETHREADS
+/*%
+ * The followings can be either static or public, depending on build
+ * environment.
+ */
+
+#ifdef BIND9
+#define ISC_TIMERFUNC_SCOPE
+#else
+#define ISC_TIMERFUNC_SCOPE static
+#endif
+
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_timer_t **timerp);
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_reset(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge);
+ISC_TIMERFUNC_SCOPE isc_timertype_t
+isc__timer_gettype(isc_timer_t *timer);
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_touch(isc_timer_t *timer);
+ISC_TIMERFUNC_SCOPE void
+isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp);
+ISC_TIMERFUNC_SCOPE void
+isc__timer_detach(isc_timer_t **timerp);
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_poke(isc_timermgr_t *manager0);
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_destroy(isc_timermgr_t **managerp);
+
+static struct isc__timermethods {
+ isc_timermethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *gettype;
+#endif
+} timermethods = {
+ {
+ isc__timer_attach,
+ isc__timer_detach,
+ isc__timer_reset,
+ isc__timer_touch
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__timer_gettype
+#endif
+};
+
+static struct isc__timermgrmethods {
+ isc_timermgrmethods_t methods;
+#ifndef BIND9
+ void *poke; /* see above */
+#endif
+} timermgrmethods = {
+ {
+ isc__timermgr_destroy,
+ isc__timer_create
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__timermgr_poke
+#endif
+};
+
+#ifdef USE_SHARED_MANAGER
/*!
- * If threads are not in use, there can be only one.
+ * If the manager is supposed to be shared, there can be only one.
*/
-static isc_timermgr_t *timermgr = NULL;
-#endif /* ISC_PLATFORM_USETHREADS */
+static isc__timermgr_t *timermgr = NULL;
+#endif /* USE_SHARED_MANAGER */
static inline isc_result_t
-schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
+schedule(isc__timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
isc_result_t result;
- isc_timermgr_t *manager;
+ isc__timermgr_t *manager;
isc_time_t due;
int cmp;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
isc_boolean_t timedwait;
#endif
@@ -123,13 +209,13 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
REQUIRE(timer->type != isc_timertype_inactive);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_TIMER_THREAD
UNUSED(signal_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
manager = timer->manager;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
/*!
* If the manager was timed wait, we may need to signal the
* manager to force a wakeup.
@@ -199,7 +285,7 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
* the current "next" timer. We do this either by waking up the
* run thread, or explicitly setting the value in the manager.
*/
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
/*
* This is a temporary (probably) hack to fix a bug on tru64 5.1
@@ -232,19 +318,19 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
"signal (schedule)"));
SIGNAL(&manager->wakeup);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_TIMER_THREAD */
if (timer->index == 1 &&
isc_time_compare(&timer->due, &manager->due) < 0)
manager->due = timer->due;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
return (ISC_R_SUCCESS);
}
static inline void
-deschedule(isc_timer_t *timer) {
+deschedule(isc__timer_t *timer) {
isc_boolean_t need_wakeup = ISC_FALSE;
- isc_timermgr_t *manager;
+ isc__timermgr_t *manager;
/*
* The caller must ensure locking.
@@ -258,20 +344,20 @@ deschedule(isc_timer_t *timer) {
timer->index = 0;
INSIST(manager->nscheduled > 0);
manager->nscheduled--;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
if (need_wakeup) {
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
ISC_MSG_SIGNALDESCHED,
"signal (deschedule)"));
SIGNAL(&manager->wakeup);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
}
}
static void
-destroy(isc_timer_t *timer) {
- isc_timermgr_t *manager = timer->manager;
+destroy(isc__timer_t *timer) {
+ isc__timermgr_t *manager = timer->manager;
/*
* The caller must ensure it is safe to destroy the timer.
@@ -291,17 +377,19 @@ destroy(isc_timer_t *timer) {
isc_task_detach(&timer->task);
DESTROYLOCK(&timer->lock);
- timer->magic = 0;
+ timer->common.impmagic = 0;
+ timer->common.magic = 0;
isc_mem_put(manager->mctx, timer, sizeof(*timer));
}
-isc_result_t
-isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_timer_t **timerp)
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_timer_t **timerp)
{
- isc_timer_t *timer;
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
+ isc__timer_t *timer;
isc_result_t result;
isc_time_t now;
@@ -382,7 +470,9 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
return (result);
}
ISC_LINK_INIT(timer, link);
- timer->magic = TIMER_MAGIC;
+ timer->common.impmagic = TIMER_MAGIC;
+ timer->common.magic = ISCAPI_TIMER_MAGIC;
+ timer->common.methods = (isc_timermethods_t *)&timermethods;
LOCK(&manager->lock);
@@ -401,25 +491,27 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
UNLOCK(&manager->lock);
if (result != ISC_R_SUCCESS) {
- timer->magic = 0;
+ timer->common.impmagic = 0;
+ timer->common.magic = 0;
DESTROYLOCK(&timer->lock);
isc_task_detach(&timer->task);
isc_mem_put(manager->mctx, timer, sizeof(*timer));
return (result);
}
- *timerp = timer;
+ *timerp = (isc_timer_t *)timer;
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
- isc_boolean_t purge)
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge)
{
+ isc__timer_t *timer = (isc__timer_t *)timer0;
isc_time_t now;
- isc_timermgr_t *manager;
+ isc__timermgr_t *manager;
isc_result_t result;
/*
@@ -489,8 +581,9 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
return (result);
}
-isc_timertype_t
-isc_timer_gettype(isc_timer_t *timer) {
+ISC_TIMERFUNC_SCOPE isc_timertype_t
+isc__timer_gettype(isc_timer_t *timer0) {
+ isc__timer_t *timer = (isc__timer_t *)timer0;
isc_timertype_t t;
REQUIRE(VALID_TIMER(timer));
@@ -502,8 +595,9 @@ isc_timer_gettype(isc_timer_t *timer) {
return (t);
}
-isc_result_t
-isc_timer_touch(isc_timer_t *timer) {
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_touch(isc_timer_t *timer0) {
+ isc__timer_t *timer = (isc__timer_t *)timer0;
isc_result_t result;
isc_time_t now;
@@ -532,8 +626,10 @@ isc_timer_touch(isc_timer_t *timer) {
return (result);
}
-void
-isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
+ISC_TIMERFUNC_SCOPE void
+isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
+ isc__timer_t *timer = (isc__timer_t *)timer0;
+
/*
* Attach *timerp to timer.
*/
@@ -545,12 +641,12 @@ isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
timer->references++;
UNLOCK(&timer->lock);
- *timerp = timer;
+ *timerp = (isc_timer_t *)timer;
}
-void
-isc_timer_detach(isc_timer_t **timerp) {
- isc_timer_t *timer;
+ISC_TIMERFUNC_SCOPE void
+isc__timer_detach(isc_timer_t **timerp) {
+ isc__timer_t *timer;
isc_boolean_t free_timer = ISC_FALSE;
/*
@@ -558,7 +654,7 @@ isc_timer_detach(isc_timer_t **timerp) {
*/
REQUIRE(timerp != NULL);
- timer = *timerp;
+ timer = (isc__timer_t *)*timerp;
REQUIRE(VALID_TIMER(timer));
LOCK(&timer->lock);
@@ -575,11 +671,11 @@ isc_timer_detach(isc_timer_t **timerp) {
}
static void
-dispatch(isc_timermgr_t *manager, isc_time_t *now) {
+dispatch(isc__timermgr_t *manager, isc_time_t *now) {
isc_boolean_t done = ISC_FALSE, post_event, need_schedule;
isc_timerevent_t *event;
isc_eventtype_t type = 0;
- isc_timer_t *timer;
+ isc__timer_t *timer;
isc_result_t result;
isc_boolean_t idle;
@@ -693,13 +789,13 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) {
}
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
static isc_threadresult_t
#ifdef _WIN32 /* XXXDCL */
WINAPI
#endif
run(void *uap) {
- isc_timermgr_t *manager = uap;
+ isc__timermgr_t *manager = uap;
isc_time_t now;
isc_result_t result;
@@ -734,11 +830,11 @@ run(void *uap) {
return ((isc_threadresult_t)0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
static isc_boolean_t
sooner(void *v1, void *v2) {
- isc_timer_t *t1, *t2;
+ isc__timer_t *t1, *t2;
t1 = v1;
t2 = v2;
@@ -752,7 +848,7 @@ sooner(void *v1, void *v2) {
static void
set_index(void *what, unsigned int index) {
- isc_timer_t *timer;
+ isc__timer_t *timer;
timer = what;
REQUIRE(VALID_TIMER(timer));
@@ -760,9 +856,9 @@ set_index(void *what, unsigned int index) {
timer->index = index;
}
-isc_result_t
-isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
- isc_timermgr_t *manager;
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
+ isc__timermgr_t *manager;
isc_result_t result;
/*
@@ -771,19 +867,21 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
if (timermgr != NULL) {
timermgr->refs++;
- *managerp = timermgr;
+ *managerp = (isc_timermgr_t *)timermgr;
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
- manager->magic = TIMER_MANAGER_MAGIC;
+ manager->common.impmagic = TIMER_MANAGER_MAGIC;
+ manager->common.magic = ISCAPI_TIMERMGR_MAGIC;
+ manager->common.methods = (isc_timermgrmethods_t *)&timermgrmethods;
manager->mctx = NULL;
manager->done = ISC_FALSE;
INIT_LIST(manager->timers);
@@ -803,7 +901,7 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
return (result);
}
isc_mem_attach(mctx, &manager->mctx);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) {
isc_mem_detach(&manager->mctx);
DESTROYLOCK(&manager->lock);
@@ -828,30 +926,33 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
ISC_MSG_FAILED, "failed"));
return (ISC_R_UNEXPECTED);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#endif
+#ifdef USE_SHARED_MANAGER
manager->refs = 1;
timermgr = manager;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
- *managerp = manager;
+ *managerp = (isc_timermgr_t *)manager;
return (ISC_R_SUCCESS);
}
-void
-isc_timermgr_poke(isc_timermgr_t *manager) {
-#ifdef ISC_PLATFORM_USETHREADS
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_poke(isc_timermgr_t *manager0) {
+#ifdef USE_TIMER_THREAD
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
+
REQUIRE(VALID_MANAGER(manager));
SIGNAL(&manager->wakeup);
#else
- UNUSED(manager);
+ UNUSED(manager0);
#endif
}
-void
-isc_timermgr_destroy(isc_timermgr_t **managerp) {
- isc_timermgr_t *manager;
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_destroy(isc_timermgr_t **managerp) {
+ isc__timermgr_t *manager;
isc_mem_t *mctx;
/*
@@ -859,34 +960,36 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
*/
REQUIRE(managerp != NULL);
- manager = *managerp;
+ manager = (isc__timermgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
LOCK(&manager->lock);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
if (manager->refs > 1) {
manager->refs--;
UNLOCK(&manager->lock);
*managerp = NULL;
return;
}
+#endif /* USE_SHARED_MANAGER */
- isc__timermgr_dispatch();
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifndef USE_TIMER_THREAD
+ isc__timermgr_dispatch((isc_timermgr_t *)manager);
+#endif
REQUIRE(EMPTY(manager->timers));
manager->done = ISC_TRUE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
ISC_MSG_SIGNALDESTROY, "signal (destroy)"));
SIGNAL(&manager->wakeup);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
UNLOCK(&manager->lock);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
/*
* Wait for thread to exit.
*/
@@ -895,39 +998,63 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
"isc_thread_join() %s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
/*
* Clean up.
*/
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
(void)isc_condition_destroy(&manager->wakeup);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
DESTROYLOCK(&manager->lock);
isc_heap_destroy(&manager->heap);
- manager->magic = 0;
+ manager->common.impmagic = 0;
+ manager->common.magic = 0;
mctx = manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
*managerp = NULL;
+
+#ifdef USE_SHARED_MANAGER
+ timermgr = NULL;
+#endif
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_TIMER_THREAD
isc_result_t
-isc__timermgr_nextevent(isc_time_t *when) {
- if (timermgr == NULL || timermgr->nscheduled == 0)
+isc__timermgr_nextevent(isc_timermgr_t *manager0, isc_time_t *when) {
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = timermgr;
+#endif
+ if (manager == NULL || manager->nscheduled == 0)
return (ISC_R_NOTFOUND);
- *when = timermgr->due;
+ *when = manager->due;
return (ISC_R_SUCCESS);
}
void
-isc__timermgr_dispatch(void) {
+isc__timermgr_dispatch(isc_timermgr_t *manager0) {
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
isc_time_t now;
- if (timermgr == NULL)
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = timermgr;
+#endif
+ if (manager == NULL)
return;
TIME_NOW(&now);
- dispatch(timermgr, &now);
+ dispatch(manager, &now);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
+
+#ifdef USE_TIMERIMPREGISTER
+isc_result_t
+isc__timer_register() {
+ return (isc_timer_register(isc__timermgr_create));
+}
+#endif
diff --git a/lib/isc/timer_api.c b/lib/isc/timer_api.c
new file mode 100644
index 00000000..97e62b3f
--- /dev/null
+++ b/lib/isc/timer_api.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: timer_api.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_timermgrcreatefunc_t timermgr_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_timer_register(isc_timermgrcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (timermgr_createfunc == NULL)
+ timermgr_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_timermgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(timermgr_createfunc != NULL);
+ result = (*timermgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ if (result == ISC_R_SUCCESS)
+ isc_appctx_settimermgr(actx, *managerp);
+
+ return (result);
+}
+
+isc_result_t
+isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(timermgr_createfunc != NULL);
+ result = (*timermgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_timermgr_destroy(isc_timermgr_t **managerp) {
+ REQUIRE(*managerp != NULL && ISCAPI_TIMERMGR_VALID(*managerp));
+
+ (*managerp)->methods->destroy(managerp);
+
+ ENSURE(*managerp == NULL);
+}
+
+isc_result_t
+isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_timer_t **timerp)
+{
+ REQUIRE(ISCAPI_TIMERMGR_VALID(manager));
+
+ return (manager->methods->timercreate(manager, type, expires,
+ interval, task, action, arg,
+ timerp));
+}
+
+void
+isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
+ REQUIRE(ISCAPI_TIMER_VALID(timer));
+ REQUIRE(timerp != NULL && *timerp == NULL);
+
+ timer->methods->attach(timer, timerp);
+
+ ENSURE(*timerp == timer);
+}
+
+void
+isc_timer_detach(isc_timer_t **timerp) {
+ REQUIRE(timerp != NULL && ISCAPI_TIMER_VALID(*timerp));
+
+ (*timerp)->methods->detach(timerp);
+
+ ENSURE(*timerp == NULL);
+}
+
+isc_result_t
+isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge)
+{
+ REQUIRE(ISCAPI_TIMER_VALID(timer));
+
+ return (timer->methods->reset(timer, type, expires, interval, purge));
+}
+
+isc_result_t
+isc_timer_touch(isc_timer_t *timer) {
+ REQUIRE(ISCAPI_TIMER_VALID(timer));
+
+ return (timer->methods->touch(timer));
+}
diff --git a/lib/isc/timer_p.h b/lib/isc/timer_p.h
index ec8e2e0b..d6f7c996 100644
--- a/lib/isc/timer_p.h
+++ b/lib/isc/timer_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: timer_p.h,v 1.10 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: timer_p.h,v 1.12 2009/09/02 23:48:02 tbox Exp $ */
#ifndef ISC_TIMER_P_H
#define ISC_TIMER_P_H
@@ -23,9 +23,9 @@
/*! \file */
isc_result_t
-isc__timermgr_nextevent(isc_time_t *when);
+isc__timermgr_nextevent(isc_timermgr_t *timermgr, isc_time_t *when);
void
-isc__timermgr_dispatch(void);
+isc__timermgr_dispatch(isc_timermgr_t *timermgr);
#endif /* ISC_TIMER_P_H */
diff --git a/lib/isc/unix/Makefile.in b/lib/isc/unix/Makefile.in
index 7d19b5c0..d47e5726 100644
--- a/lib/isc/unix/Makefile.in
+++ b/lib/isc/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.41 2007/06/19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.43 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,7 +25,7 @@ CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../include \
-I${srcdir}/..
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
# Alphabetically
diff --git a/lib/isc/unix/app.c b/lib/isc/unix/app.c
index 660b4386..04dfa7e5 100644
--- a/lib/isc/unix/app.c
+++ b/lib/isc/unix/app.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: app.c,v 1.60 2008/10/15 03:41:17 marka Exp $ */
+/* $Id: app.c,v 1.63 2009/09/02 23:48:03 tbox Exp $ */
/*! \file */
@@ -37,6 +37,7 @@
#include <isc/app.h>
#include <isc/boolean.h>
#include <isc/condition.h>
+#include <isc/mem.h>
#include <isc/msgs.h>
#include <isc/mutex.h>
#include <isc/event.h>
@@ -47,18 +48,26 @@
#include <isc/time.h>
#include <isc/util.h>
+/*%
+ * For BIND9 internal applications built with threads, we use a single app
+ * context and let multiple worker, I/O, timer threads do actual jobs.
+ * For other cases (including BIND9 built without threads) an app context acts
+ * as an event loop dispatching various events.
+ */
+#if defined(ISC_PLATFORM_USETHREADS) && defined(BIND9)
+#define USE_THREADS_SINGLECTX
+#endif
+
#ifdef ISC_PLATFORM_USETHREADS
#include <pthread.h>
-#else /* ISC_PLATFORM_USETHREADS */
+#endif
+
+#ifndef USE_THREADS_SINGLECTX
#include "../timer_p.h"
#include "../task_p.h"
#include "socket_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_THREADS_SINGLECTX */
-static isc_eventlist_t on_run;
-static isc_mutex_t lock;
-static isc_boolean_t shutdown_requested = ISC_FALSE;
-static isc_boolean_t running = ISC_FALSE;
/*!
* We assume that 'want_shutdown' can be read and written atomically.
*/
@@ -68,11 +77,110 @@ static volatile isc_boolean_t want_shutdown = ISC_FALSE;
*/
static volatile isc_boolean_t want_reload = ISC_FALSE;
-static isc_boolean_t blocked = ISC_FALSE;
#ifdef ISC_PLATFORM_USETHREADS
static pthread_t blockedthread;
#endif /* ISC_PLATFORM_USETHREADS */
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_APPFUNC_SCOPE
+#else
+#define ISC_APPFUNC_SCOPE static
+#endif
+
+ISC_APPFUNC_SCOPE isc_result_t isc__app_start(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxstart(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_onrun(isc_mem_t *mctx,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ void *arg);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxrun(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_run(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_shutdown(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_reload(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE void isc__app_ctxfinish(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE void isc__app_finish(void);
+ISC_APPFUNC_SCOPE void isc__app_block(void);
+ISC_APPFUNC_SCOPE void isc__app_unblock(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__appctx_create(isc_mem_t *mctx,
+ isc_appctx_t **ctxp);
+ISC_APPFUNC_SCOPE void isc__appctx_destroy(isc_appctx_t **ctxp);
+ISC_APPFUNC_SCOPE void isc__appctx_settaskmgr(isc_appctx_t *ctx,
+ isc_taskmgr_t *taskmgr);
+ISC_APPFUNC_SCOPE void isc__appctx_setsocketmgr(isc_appctx_t *ctx,
+ isc_socketmgr_t *socketmgr);
+ISC_APPFUNC_SCOPE void isc__appctx_settimermgr(isc_appctx_t *ctx,
+ isc_timermgr_t *timermgr);
+
+/*
+ * The application context of this module. This implementation actually
+ * doesn't use it. (This may change in the future).
+ */
+#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x')
+#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC)
+
+typedef struct isc__appctx {
+ isc_appctx_t common;
+ isc_mem_t *mctx;
+ isc_mutex_t lock;
+ isc_eventlist_t on_run;
+ isc_boolean_t shutdown_requested;
+ isc_boolean_t running;
+
+ /*!
+ * We assume that 'want_shutdown' can be read and written atomically.
+ */
+ isc_boolean_t want_shutdown;
+ /*
+ * We assume that 'want_reload' can be read and written atomically.
+ */
+ isc_boolean_t want_reload;
+
+ isc_boolean_t blocked;
+
+ isc_taskmgr_t *taskmgr;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+} isc__appctx_t;
+
+static isc__appctx_t isc_g_appctx;
+
+static struct {
+ isc_appmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *run, *shutdown, *start, *onrun, *reload, *finish,
+ *block, *unblock;
+#endif
+} appmethods = {
+ {
+ isc__appctx_destroy,
+ isc__app_ctxstart,
+ isc__app_ctxrun,
+ isc__app_ctxsuspend,
+ isc__app_ctxshutdown,
+ isc__app_ctxfinish,
+ isc__appctx_settaskmgr,
+ isc__appctx_setsocketmgr,
+ isc__appctx_settimermgr
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__app_run, (void *)isc__app_shutdown,
+ (void *)isc__app_start, (void *)isc__app_onrun, (void *)isc__app_reload,
+ (void *)isc__app_finish, (void *)isc__app_block,
+ (void *)isc__app_unblock
+#endif
+};
+
#ifdef HAVE_LINUXTHREADS
/*!
* Linux has sigwait(), but it appears to prevent signal handlers from
@@ -91,13 +199,13 @@ static pthread_t main_thread;
static void
exit_action(int arg) {
UNUSED(arg);
- want_shutdown = ISC_TRUE;
+ isc_g_appctx.want_shutdown = ISC_TRUE;
}
static void
reload_action(int arg) {
UNUSED(arg);
- want_reload = ISC_TRUE;
+ isc_g_appctx.want_reload = ISC_TRUE;
}
#endif
@@ -123,12 +231,12 @@ handle_signal(int sig, void (*handler)(int)) {
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_start(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxstart(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_result_t result;
- int presult;
- sigset_t sset;
- char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(VALID_APPCTX(ctx));
/*
* Start an ISC library application.
@@ -151,7 +259,35 @@ isc_app_start(void) {
main_thread = pthread_self();
#endif
- result = isc_mutex_init(&lock);
+ result = isc_mutex_init(&ctx->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ ISC_LIST_INIT(ctx->on_run);
+
+ ctx->shutdown_requested = ISC_FALSE;
+ ctx->running = ISC_FALSE;
+ ctx->want_shutdown = ISC_FALSE;
+ ctx->want_reload = ISC_FALSE;
+ ctx->blocked = ISC_FALSE;
+
+ return (ISC_R_SUCCESS);
+}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_start(void) {
+ isc_result_t result;
+ int presult;
+ sigset_t sset;
+ char strbuf[ISC_STRERRORSIZE];
+
+ isc_g_appctx.common.impmagic = APPCTX_MAGIC;
+ isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC;
+ isc_g_appctx.common.methods = &appmethods.methods;
+ isc_g_appctx.mctx = NULL;
+ /* The remaining members will be initialized in ctxstart() */
+
+ result = isc__app_ctxstart((isc_appctx_t *)&isc_g_appctx);
if (result != ISC_R_SUCCESS)
return (result);
@@ -253,22 +389,20 @@ isc_app_start(void) {
}
#endif /* ISC_PLATFORM_USETHREADS */
- ISC_LIST_INIT(on_run);
-
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
void *arg)
{
isc_event_t *event;
isc_task_t *cloned_task = NULL;
isc_result_t result;
- LOCK(&lock);
+ LOCK(&isc_g_appctx.lock);
- if (running) {
+ if (isc_g_appctx.running) {
result = ISC_R_ALREADYRUNNING;
goto unlock;
}
@@ -285,24 +419,25 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
goto unlock;
}
- ISC_LIST_APPEND(on_run, event, ev_link);
+ ISC_LIST_APPEND(isc_g_appctx.on_run, event, ev_link);
result = ISC_R_SUCCESS;
unlock:
- UNLOCK(&lock);
+ UNLOCK(&isc_g_appctx.lock);
return (result);
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_THREADS_SINGLECTX
/*!
* Event loop for nonthreaded programs.
*/
static isc_result_t
-evloop(void) {
+evloop(isc__appctx_t *ctx) {
isc_result_t result;
- while (!want_shutdown) {
+
+ while (!ctx->want_shutdown) {
int n;
isc_time_t when, now;
struct timeval tv, *tvp;
@@ -310,14 +445,27 @@ evloop(void) {
isc_boolean_t readytasks;
isc_boolean_t call_timer_dispatch = ISC_FALSE;
- readytasks = isc__taskmgr_ready();
+ /*
+ * Check the reload (or suspend) case first for exiting the
+ * loop as fast as possible in case:
+ * - the direct call to isc__taskmgr_dispatch() in
+ * isc__app_ctxrun() completes all the tasks so far,
+ * - there is thus currently no active task, and
+ * - there is a timer event
+ */
+ if (ctx->want_reload) {
+ ctx->want_reload = ISC_FALSE;
+ return (ISC_R_RELOAD);
+ }
+
+ readytasks = isc__taskmgr_ready(ctx->taskmgr);
if (readytasks) {
tv.tv_sec = 0;
tv.tv_usec = 0;
tvp = &tv;
call_timer_dispatch = ISC_TRUE;
} else {
- result = isc__timermgr_nextevent(&when);
+ result = isc__timermgr_nextevent(ctx->timermgr, &when);
if (result != ISC_R_SUCCESS)
tvp = NULL;
else {
@@ -334,7 +482,7 @@ evloop(void) {
}
swait = NULL;
- n = isc__socketmgr_waitevents(tvp, &swait);
+ n = isc__socketmgr_waitevents(ctx->socketmgr, tvp, &swait);
if (n == 0 || call_timer_dispatch) {
/*
@@ -351,11 +499,11 @@ evloop(void) {
* call, since this loop only runs in the non-thread
* mode.
*/
- isc__timermgr_dispatch();
+ isc__timermgr_dispatch(ctx->timermgr);
}
if (n > 0)
- (void)isc__socketmgr_dispatch(swait);
- (void)isc__taskmgr_dispatch();
+ (void)isc__socketmgr_dispatch(ctx->socketmgr, swait);
+ (void)isc__taskmgr_dispatch(ctx->taskmgr);
if (want_reload) {
want_reload = ISC_FALSE;
@@ -364,7 +512,9 @@ evloop(void) {
}
return (ISC_R_SUCCESS);
}
+#endif /* USE_THREADS_SINGLECTX */
+#ifndef ISC_PLATFORM_USETHREADS
/*
* This is a gross hack to support waiting for condition
* variables in nonthreaded programs in a limited way;
@@ -400,11 +550,11 @@ isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) {
INSIST(*mp == 1); /* Mutex must be locked on entry. */
--*mp;
- result = evloop();
+ result = evloop(&isc_g_appctx);
if (result == ISC_R_RELOAD)
- want_reload = ISC_TRUE;
+ isc_g_appctx.want_reload = ISC_TRUE;
if (signalled) {
- want_shutdown = ISC_FALSE;
+ isc_g_appctx.want_shutdown = ISC_FALSE;
signalled = ISC_FALSE;
}
@@ -420,43 +570,46 @@ isc__nothread_signal_hack(isc_condition_t *cp) {
INSIST(in_recursive_evloop);
- want_shutdown = ISC_TRUE;
+ isc_g_appctx.want_shutdown = ISC_TRUE;
signalled = ISC_TRUE;
return (ISC_R_SUCCESS);
}
#endif /* ISC_PLATFORM_USETHREADS */
-isc_result_t
-isc_app_run(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxrun(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
int result;
isc_event_t *event, *next_event;
isc_task_t *task;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_THREADS_SINGLECTX
sigset_t sset;
char strbuf[ISC_STRERRORSIZE];
#ifdef HAVE_SIGWAIT
int sig;
#endif
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_THREADS_SINGLECTX */
+
+ REQUIRE(VALID_APPCTX(ctx));
#ifdef HAVE_LINUXTHREADS
REQUIRE(main_thread == pthread_self());
#endif
- LOCK(&lock);
+ LOCK(&ctx->lock);
- if (!running) {
- running = ISC_TRUE;
+ if (!ctx->running) {
+ ctx->running = ISC_TRUE;
/*
* Post any on-run events (in FIFO order).
*/
- for (event = ISC_LIST_HEAD(on_run);
+ for (event = ISC_LIST_HEAD(ctx->on_run);
event != NULL;
event = next_event) {
next_event = ISC_LIST_NEXT(event, ev_link);
- ISC_LIST_UNLINK(on_run, event, ev_link);
+ ISC_LIST_UNLINK(ctx->on_run, event, ev_link);
task = event->ev_sender;
event->ev_sender = NULL;
isc_task_sendanddetach(&task, &event);
@@ -464,7 +617,7 @@ isc_app_run(void) {
}
- UNLOCK(&lock);
+ UNLOCK(&ctx->lock);
#ifndef HAVE_SIGWAIT
/*
@@ -473,19 +626,27 @@ isc_app_run(void) {
* We do this here to ensure that the signal handler is installed
* (i.e. that it wasn't a "one-shot" handler).
*/
- result = handle_signal(SIGHUP, reload_action);
- if (result != ISC_R_SUCCESS)
- return (ISC_R_SUCCESS);
+ if (ctx == &isc_g_appctx) {
+ result = handle_signal(SIGHUP, reload_action);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_R_SUCCESS);
+ }
#endif
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_THREADS_SINGLECTX
+ /*
+ * When we are using multiple contexts, we don't rely on signals.
+ */
+ if (ctx != &isc_g_appctx)
+ return (ISC_R_SUCCESS);
+
/*
* There is no danger if isc_app_shutdown() is called before we wait
* for signals. Signals are blocked, so any such signal will simply
* be made pending and we will get it when we call sigwait().
*/
- while (!want_shutdown) {
+ while (!ctx->want_shutdown) {
#ifdef HAVE_SIGWAIT
/*
* Wait for SIGHUP, SIGINT, or SIGTERM.
@@ -503,21 +664,19 @@ isc_app_run(void) {
#ifndef HAVE_UNIXWARE_SIGWAIT
result = sigwait(&sset, &sig);
if (result == 0) {
- if (sig == SIGINT ||
- sig == SIGTERM)
- want_shutdown = ISC_TRUE;
+ if (sig == SIGINT || sig == SIGTERM)
+ ctx->want_shutdown = ISC_TRUE;
else if (sig == SIGHUP)
- want_reload = ISC_TRUE;
+ ctx->want_reload = ISC_TRUE;
}
#else /* Using UnixWare sigwait semantics. */
sig = sigwait(&sset);
if (sig >= 0) {
- if (sig == SIGINT ||
- sig == SIGTERM)
- want_shutdown = ISC_TRUE;
+ if (sig == SIGINT || sig == SIGTERM)
+ ctx->want_shutdown = ISC_TRUE;
else if (sig == SIGHUP)
- want_reload = ISC_TRUE;
+ ctx->want_reload = ISC_TRUE;
}
#endif /* HAVE_UNIXWARE_SIGWAIT */
@@ -528,131 +687,174 @@ isc_app_run(void) {
if (sigemptyset(&sset) != 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_run() sigsetops: %s", strbuf);
+ "isc_app_run() sigsetops: %s",
+ strbuf);
return (ISC_R_UNEXPECTED);
}
result = sigsuspend(&sset);
#endif /* HAVE_SIGWAIT */
- if (want_reload) {
- want_reload = ISC_FALSE;
+ if (ctx->want_reload) {
+ ctx->want_reload = ISC_FALSE;
return (ISC_R_RELOAD);
}
- if (want_shutdown && blocked)
+ if (ctx->want_shutdown && ctx->blocked)
exit(1);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_THREADS_SINGLECTX */
- (void)isc__taskmgr_dispatch();
+ (void)isc__taskmgr_dispatch(ctx->taskmgr);
- result = evloop();
+ result = evloop(ctx);
if (result != ISC_R_SUCCESS)
return (result);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_THREADS_SINGLECTX */
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_shutdown(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_run() {
+ return (isc__app_ctxrun((isc_appctx_t *)&isc_g_appctx));
+}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxshutdown(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_boolean_t want_kill = ISC_TRUE;
char strbuf[ISC_STRERRORSIZE];
- LOCK(&lock);
+ REQUIRE(VALID_APPCTX(ctx));
+
+ LOCK(&ctx->lock);
- REQUIRE(running);
+ REQUIRE(ctx->running);
- if (shutdown_requested)
+ if (ctx->shutdown_requested)
want_kill = ISC_FALSE;
else
- shutdown_requested = ISC_TRUE;
+ ctx->shutdown_requested = ISC_TRUE;
- UNLOCK(&lock);
+ UNLOCK(&ctx->lock);
if (want_kill) {
+ if (ctx != &isc_g_appctx)
+ ctx->want_shutdown = ISC_TRUE;
+ else {
#ifdef HAVE_LINUXTHREADS
- int result;
-
- result = pthread_kill(main_thread, SIGTERM);
- if (result != 0) {
- isc__strerror(result, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_shutdown() pthread_kill: %s",
- strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ int result;
+
+ result = pthread_kill(main_thread, SIGTERM);
+ if (result != 0) {
+ isc__strerror(result, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_shutdown() "
+ "pthread_kill: %s",
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
#else
- if (kill(getpid(), SIGTERM) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_shutdown() kill: %s", strbuf);
- return (ISC_R_UNEXPECTED);
+ if (kill(getpid(), SIGTERM) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_shutdown() "
+ "kill: %s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+#endif /* HAVE_LINUXTHREADS */
}
-#endif
}
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_reload(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_shutdown() {
+ return (isc__app_ctxshutdown((isc_appctx_t *)&isc_g_appctx));
+}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxsuspend(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_boolean_t want_kill = ISC_TRUE;
char strbuf[ISC_STRERRORSIZE];
- LOCK(&lock);
+ REQUIRE(VALID_APPCTX(ctx));
- REQUIRE(running);
+ LOCK(&ctx->lock);
+
+ REQUIRE(ctx->running);
/*
* Don't send the reload signal if we're shutting down.
*/
- if (shutdown_requested)
+ if (ctx->shutdown_requested)
want_kill = ISC_FALSE;
- UNLOCK(&lock);
+ UNLOCK(&ctx->lock);
if (want_kill) {
+ if (ctx != &isc_g_appctx)
+ ctx->want_reload = ISC_TRUE;
+ else {
#ifdef HAVE_LINUXTHREADS
- int result;
-
- result = pthread_kill(main_thread, SIGHUP);
- if (result != 0) {
- isc__strerror(result, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_reload() pthread_kill: %s",
- strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ int result;
+
+ result = pthread_kill(main_thread, SIGHUP);
+ if (result != 0) {
+ isc__strerror(result, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_reload() "
+ "pthread_kill: %s",
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
#else
- if (kill(getpid(), SIGHUP) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_reload() kill: %s", strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ if (kill(getpid(), SIGHUP) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_reload() "
+ "kill: %s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
#endif
+ }
}
return (ISC_R_SUCCESS);
}
-void
-isc_app_finish(void) {
- DESTROYLOCK(&lock);
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_reload(void) {
+ return (isc__app_ctxsuspend((isc_appctx_t *)&isc_g_appctx));
}
-void
-isc_app_block(void) {
+ISC_APPFUNC_SCOPE void
+isc__app_ctxfinish(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ DESTROYLOCK(&ctx->lock);
+}
+
+ISC_APPFUNC_SCOPE void
+isc__app_finish(void) {
+ isc__app_ctxfinish((isc_appctx_t *)&isc_g_appctx);
+}
+
+ISC_APPFUNC_SCOPE void
+isc__app_block(void) {
#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
#endif /* ISC_PLATFORM_USETHREADS */
- REQUIRE(running);
- REQUIRE(!blocked);
+ REQUIRE(isc_g_appctx.running);
+ REQUIRE(!isc_g_appctx.blocked);
- blocked = ISC_TRUE;
+ isc_g_appctx.blocked = ISC_TRUE;
#ifdef ISC_PLATFORM_USETHREADS
blockedthread = pthread_self();
RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
@@ -662,16 +864,16 @@ isc_app_block(void) {
#endif /* ISC_PLATFORM_USETHREADS */
}
-void
-isc_app_unblock(void) {
+ISC_APPFUNC_SCOPE void
+isc__app_unblock(void) {
#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
#endif /* ISC_PLATFORM_USETHREADS */
- REQUIRE(running);
- REQUIRE(blocked);
+ REQUIRE(isc_g_appctx.running);
+ REQUIRE(isc_g_appctx.blocked);
- blocked = ISC_FALSE;
+ isc_g_appctx.blocked = ISC_FALSE;
#ifdef ISC_PLATFORM_USETHREADS
REQUIRE(blockedthread == pthread_self());
@@ -682,3 +884,77 @@ isc_app_unblock(void) {
RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0);
#endif /* ISC_PLATFORM_USETHREADS */
}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) {
+ isc__appctx_t *ctx;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(ctxp != NULL && *ctxp == NULL);
+
+ ctx = isc_mem_get(mctx, sizeof(*ctx));
+ if (ctx == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ctx->common.impmagic = APPCTX_MAGIC;
+ ctx->common.magic = ISCAPI_APPCTX_MAGIC;
+ ctx->common.methods = &appmethods.methods;
+
+ ctx->mctx = NULL;
+ isc_mem_attach(mctx, &ctx->mctx);
+
+ ctx->taskmgr = NULL;
+ ctx->socketmgr = NULL;
+ ctx->timermgr = NULL;
+
+ *ctxp = (isc_appctx_t *)ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_destroy(isc_appctx_t **ctxp) {
+ isc__appctx_t *ctx;
+
+ REQUIRE(ctxp != NULL);
+ ctx = (isc__appctx_t *)*ctxp;
+ REQUIRE(VALID_APPCTX(ctx));
+
+ isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx));
+
+ *ctxp = NULL;
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_settaskmgr(isc_appctx_t *ctx0, isc_taskmgr_t *taskmgr) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ ctx->taskmgr = taskmgr;
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_setsocketmgr(isc_appctx_t *ctx0, isc_socketmgr_t *socketmgr) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ ctx->socketmgr = socketmgr;
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ ctx->timermgr = timermgr;
+}
+
+#ifdef USE_APPIMPREGISTER
+isc_result_t
+isc__app_register() {
+ return (isc_app_register(isc__appctx_create));
+}
+#endif
diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c
index b7156c3a..4b1c58c7 100644
--- a/lib/isc/unix/file.c
+++ b/lib/isc/unix/file.c
@@ -48,7 +48,7 @@
* SUCH DAMAGE.
*/
-/* $Id: file.c,v 1.54 2009/06/10 00:27:22 each Exp $ */
+/* $Id: file.c,v 1.55 2009/08/28 03:13:08 each Exp $ */
/*! \file */
@@ -68,6 +68,7 @@
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/log.h>
+#include <isc/mem.h>
#include <isc/random.h>
#include <isc/string.h>
#include <isc/time.h>
@@ -478,3 +479,37 @@ isc_file_safecreate(const char *filename, FILE **fp) {
*fp = f;
return (ISC_R_SUCCESS);
}
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename)
+{
+ char *dir, *file, *slash;
+
+ slash = strrchr(path, '/');
+
+ if (slash == path) {
+ file = ++slash;
+ dir = isc_mem_strdup(mctx, "/");
+ } else if (slash != NULL) {
+ file = ++slash;
+ dir = isc_mem_allocate(mctx, slash - path);
+ if (dir != NULL)
+ strlcpy(dir, path, slash - path);
+ } else {
+ file = path;
+ dir = isc_mem_strdup(mctx, ".");
+ }
+
+ if (dir == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (*file == '\0') {
+ isc_mem_free(mctx, dir);
+ return (ISC_R_INVALIDFILE);
+ }
+
+ *dirname = dir;
+ *basename = file;
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
index 4955b786..e2e06934 100644
--- a/lib/isc/unix/socket.c
+++ b/lib/isc/unix/socket.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.318 2009/04/18 01:28:17 jinmei Exp $ */
+/* $Id: socket.c,v 1.324 2009/09/07 02:08:51 marka Exp $ */
/*! \file */
@@ -72,9 +72,18 @@
#include "errno2result.h"
-#ifndef ISC_PLATFORM_USETHREADS
+/* See task.c about the following definition: */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_WATCHER_THREAD
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#ifndef USE_WATCHER_THREAD
#include "socket_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#if defined(SO_BSDCOMPAT) && defined(__linux__)
#include <sys/utsname.h>
@@ -97,7 +106,7 @@ typedef struct {
#define USE_SELECT
#endif /* ISC_PLATFORM_HAVEKQUEUE */
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WATCHER_THREAD
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
struct isc_socketwait {
int nevents;
@@ -110,7 +119,7 @@ struct isc_socketwait {
int maxfd;
};
#endif /* USE_KQUEUE */
-#endif /* !ISC_PLATFORM_USETHREADS */
+#endif /* !USE_WATCHER_THREAD */
/*%
* Maximum number of allowable open sockets. This is also the maximum
@@ -244,7 +253,7 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t;
typedef isc_event_t intev_t;
#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o')
-#define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC)
+#define VALID_SOCKET(s) ISC_MAGIC_VALID(s, SOCKET_MAGIC)
/*!
* IPv6 control information. If the socket is an IPv6 socket we want
@@ -278,16 +287,21 @@ typedef isc_event_t intev_t;
*/
#define NRETRIES 10
-struct isc_socket {
+typedef struct isc__socket isc__socket_t;
+typedef struct isc__socketmgr isc__socketmgr_t;
+
+#define NEWCONNSOCK(ev) ((isc__socket_t *)(ev)->newsocket)
+
+struct isc__socket {
/* Not locked. */
- unsigned int magic;
- isc_socketmgr_t *manager;
+ isc_socket_t common;
+ isc__socketmgr_t *manager;
isc_mutex_t lock;
isc_sockettype_t type;
const isc_statscounter_t *statsindex;
/* Locked by socket lock. */
- ISC_LINK(isc_socket_t) link;
+ ISC_LINK(isc__socket_t) link;
unsigned int references;
int fd;
int pf;
@@ -335,9 +349,9 @@ struct isc_socket {
#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC)
-struct isc_socketmgr {
+struct isc__socketmgr {
/* Not locked. */
- unsigned int magic;
+ isc_socketmgr_t common;
isc_mem_t *mctx;
isc_mutex_t lock;
isc_mutex_t *fdlock;
@@ -366,14 +380,14 @@ struct isc_socketmgr {
#endif
/* Locked by fdlock. */
- isc_socket_t **fds;
+ isc__socket_t **fds;
int *fdstate;
#ifdef USE_DEVPOLL
pollinfo_t *fdpollinfo;
#endif
/* Locked by manager lock. */
- ISC_LIST(isc_socket_t) socklist;
+ ISC_LIST(isc__socket_t) socklist;
#ifdef USE_SELECT
fd_set *read_fds;
fd_set *read_fds_copy;
@@ -382,18 +396,18 @@ struct isc_socketmgr {
int maxfd;
#endif /* USE_SELECT */
int reserved; /* unlocked */
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_thread_t watcher;
isc_condition_t shutdown_ok;
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
unsigned int refs;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
int maxudp;
};
-#ifndef ISC_PLATFORM_USETHREADS
-static isc_socketmgr_t *socketmgr = NULL;
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifdef USE_SHARED_MANAGER
+static isc__socketmgr_t *socketmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
#define CLOSED 0 /* this one must be zero */
#define MANAGED 1
@@ -409,27 +423,157 @@ static isc_socketmgr_t *socketmgr = NULL;
# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER)
#endif
-static void send_recvdone_event(isc_socket_t *, isc_socketevent_t **);
-static void send_senddone_event(isc_socket_t *, isc_socketevent_t **);
-static void free_socket(isc_socket_t **);
-static isc_result_t allocate_socket(isc_socketmgr_t *, isc_sockettype_t,
- isc_socket_t **);
-static void destroy(isc_socket_t **);
+static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **);
+static void send_senddone_event(isc__socket_t *, isc_socketevent_t **);
+static void free_socket(isc__socket_t **);
+static isc_result_t allocate_socket(isc__socketmgr_t *, isc_sockettype_t,
+ isc__socket_t **);
+static void destroy(isc__socket_t **);
static void internal_accept(isc_task_t *, isc_event_t *);
static void internal_connect(isc_task_t *, isc_event_t *);
static void internal_recv(isc_task_t *, isc_event_t *);
static void internal_send(isc_task_t *, isc_event_t *);
static void internal_fdwatch_write(isc_task_t *, isc_event_t *);
static void internal_fdwatch_read(isc_task_t *, isc_event_t *);
-static void process_cmsg(isc_socket_t *, struct msghdr *, isc_socketevent_t *);
-static void build_msghdr_send(isc_socket_t *, isc_socketevent_t *,
+static void process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *);
+static void build_msghdr_send(isc__socket_t *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
-static void build_msghdr_recv(isc_socket_t *, isc_socketevent_t *,
+static void build_msghdr_recv(isc__socket_t *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
-#ifdef ISC_PLATFORM_USETHREADS
-static isc_boolean_t process_ctlfd(isc_socketmgr_t *manager);
+#ifdef USE_WATCHER_THREAD
+static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager);
+#endif
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_SOCKETFUNC_SCOPE
+#else
+#define ISC_SOCKETFUNC_SCOPE static
+#endif
+
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
+ isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_attach(isc_socket_t *sock, isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_detach(isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks);
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_destroy(isc_socketmgr_t **managerp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv2(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_filter(isc_socket_t *sock, const char *filter);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_listen(isc_socket_t *sock, unsigned int backlog);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_accept(isc_socket_t *sock,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how);
+ISC_SOCKETFUNC_SCOPE isc_sockettype_t
+isc__socket_gettype(isc_socket_t *sock);
+ISC_SOCKETFUNC_SCOPE isc_boolean_t
+isc__socket_isbound(isc_socket_t *sock);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
+#if defined(HAVE_LIBXML2) && defined(BIND9)
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer);
#endif
+static struct {
+ isc_socketmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *recvv, *send, *sendv, *sendto2, *cleanunix, *permunix, *filter,
+ *listen, *accept, *getpeername, *isbound;
+#endif
+} socketmethods = {
+ {
+ isc__socket_attach,
+ isc__socket_detach,
+ isc__socket_bind,
+ isc__socket_sendto,
+ isc__socket_connect,
+ isc__socket_recv,
+ isc__socket_cancel,
+ isc__socket_getsockname,
+ isc__socket_gettype,
+ isc__socket_ipv6only
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__socket_recvv, (void *)isc__socket_send,
+ (void *)isc__socket_sendv, (void *)isc__socket_sendto2,
+ (void *)isc__socket_cleanunix, (void *)isc__socket_permunix,
+ (void *)isc__socket_filter, (void *)isc__socket_listen,
+ (void *)isc__socket_accept, (void *)isc__socket_getpeername,
+ (void *)isc__socket_isbound
+#endif
+};
+
+static isc_socketmgrmethods_t socketmgrmethods = {
+ isc__socketmgr_destroy,
+ isc__socket_create
+};
+
#define SELECT_POKE_SHUTDOWN (-1)
#define SELECT_POKE_NOTHING (-2)
#define SELECT_POKE_READ (-3)
@@ -529,11 +673,11 @@ static const isc_statscounter_t fdwatchstatsindex[] = {
};
static void
-manager_log(isc_socketmgr_t *sockmgr,
+manager_log(isc__socketmgr_t *sockmgr,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
static void
-manager_log(isc_socketmgr_t *sockmgr,
+manager_log(isc__socketmgr_t *sockmgr,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
const char *fmt, ...)
{
@@ -552,12 +696,12 @@ manager_log(isc_socketmgr_t *sockmgr,
}
static void
-socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
+socket_log(isc__socket_t *sock, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_msgcat_t *msgcat, int msgset, int message,
const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10);
static void
-socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
+socket_log(isc__socket_t *sock, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_msgcat_t *msgcat, int msgset, int message,
const char *fmt, ...)
@@ -592,7 +736,7 @@ socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
* setting IPV6_V6ONLY.
*/
static void
-FIX_IPV6_RECVPKTINFO(isc_socket_t *sock)
+FIX_IPV6_RECVPKTINFO(isc__socket_t *sock)
{
char strbuf[ISC_STRERRORSIZE];
int on = 1;
@@ -629,7 +773,7 @@ inc_stats(isc_stats_t *stats, isc_statscounter_t counterid) {
}
static inline isc_result_t
-watch_fd(isc_socketmgr_t *manager, int fd, int msg) {
+watch_fd(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
#ifdef USE_KQUEUE
@@ -696,7 +840,7 @@ watch_fd(isc_socketmgr_t *manager, int fd, int msg) {
}
static inline isc_result_t
-unwatch_fd(isc_socketmgr_t *manager, int fd, int msg) {
+unwatch_fd(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
#ifdef USE_KQUEUE
@@ -782,7 +926,7 @@ unwatch_fd(isc_socketmgr_t *manager, int fd, int msg) {
}
static void
-wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) {
+wakeup_socket(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result;
int lockid = FDLOCK_ID(fd);
@@ -843,14 +987,14 @@ wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) {
}
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Poke the select loop when there is something for us to do.
* The write is required (by POSIX) to complete. That is, we
* will not get partial writes.
*/
static void
-select_poke(isc_socketmgr_t *mgr, int fd, int msg) {
+select_poke(isc__socketmgr_t *mgr, int fd, int msg) {
int cc;
int buf[2];
char strbuf[ISC_STRERRORSIZE];
@@ -889,7 +1033,7 @@ select_poke(isc_socketmgr_t *mgr, int fd, int msg) {
* Read a message on the internal fd.
*/
static void
-select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) {
+select_readmsg(isc__socketmgr_t *mgr, int *fd, int *msg) {
int buf[2];
int cc;
char strbuf[ISC_STRERRORSIZE];
@@ -916,19 +1060,19 @@ select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) {
*fd = buf[0];
*msg = buf[1];
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
/*
* Update the state of the socketmgr when something changes.
*/
static void
-select_poke(isc_socketmgr_t *manager, int fd, int msg) {
+select_poke(isc__socketmgr_t *manager, int fd, int msg) {
if (msg == SELECT_POKE_SHUTDOWN)
return;
else if (fd >= 0)
wakeup_socket(manager, fd, msg);
return;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
/*
* Make a fd non-blocking.
@@ -1021,7 +1165,7 @@ cmsg_space(ISC_SOCKADDR_LEN_T len) {
* Process control messages received on a socket.
*/
static void
-process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
+process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
#ifdef USE_CMSG
struct cmsghdr *cmsgp;
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
@@ -1124,7 +1268,7 @@ process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
* this transaction can send.
*/
static void
-build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
+build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
struct msghdr *msg, struct iovec *iov, size_t *write_countp)
{
unsigned int iovcount;
@@ -1243,7 +1387,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
* this transaction can receive.
*/
static void
-build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
+build_msghdr_recv(isc__socket_t *sock, isc_socketevent_t *dev,
struct msghdr *msg, struct iovec *iov, size_t *read_countp)
{
unsigned int iovcount;
@@ -1364,7 +1508,7 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
}
static void
-set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,
+set_dev_address(isc_sockaddr_t *address, isc__socket_t *sock,
isc_socketevent_t *dev)
{
if (sock->type == isc_sockettype_udp) {
@@ -1388,7 +1532,7 @@ destroy_socketevent(isc_event_t *event) {
}
static isc_socketevent_t *
-allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
+allocate_socketevent(isc__socket_t *sock, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
{
isc_socketevent_t *ev;
@@ -1441,7 +1585,7 @@ dump_msg(struct msghdr *msg) {
#define DOIO_EOF 3 /* EOF, no event sent */
static int
-doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
+doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
int cc;
struct iovec iov[MAXSCATTERGATHER_RECV];
size_t read_count;
@@ -1621,7 +1765,7 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
* No other return values are possible.
*/
static int
-doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
+doio_send(isc__socket_t *sock, isc_socketevent_t *dev) {
int cc;
struct iovec iov[MAXSCATTERGATHER_SEND];
size_t write_count;
@@ -1732,7 +1876,7 @@ doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
* references exist.
*/
static void
-closesocket(isc_socketmgr_t *manager, isc_socket_t *sock, int fd) {
+closesocket(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) {
isc_sockettype_t type = sock->type;
int lockid = FDLOCK_ID(fd);
@@ -1795,10 +1939,10 @@ closesocket(isc_socketmgr_t *manager, isc_socket_t *sock, int fd) {
}
static void
-destroy(isc_socket_t **sockp) {
+destroy(isc__socket_t **sockp) {
int fd;
- isc_socket_t *sock = *sockp;
- isc_socketmgr_t *manager = sock->manager;
+ isc__socket_t *sock = *sockp;
+ isc__socketmgr_t *manager = sock->manager;
socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET,
ISC_MSG_DESTROYING, "destroying");
@@ -1819,10 +1963,10 @@ destroy(isc_socket_t **sockp) {
ISC_LIST_UNLINK(manager->socklist, sock, link);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (ISC_LIST_EMPTY(manager->socklist))
SIGNAL(&manager->shutdown_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
UNLOCK(&manager->lock);
@@ -1830,10 +1974,10 @@ destroy(isc_socket_t **sockp) {
}
static isc_result_t
-allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
- isc_socket_t **socketp)
+allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
+ isc__socket_t **socketp)
{
- isc_socket_t *sock;
+ isc__socket_t *sock;
isc_result_t result;
ISC_SOCKADDR_LEN_T cmsgbuflen;
@@ -1844,7 +1988,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
result = ISC_R_UNEXPECTED;
- sock->magic = 0;
+ sock->common.magic = 0;
+ sock->common.impmagic = 0;
sock->references = 0;
sock->manager = manager;
@@ -1908,7 +2053,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
*/
result = isc_mutex_init(&sock->lock);
if (result != ISC_R_SUCCESS) {
- sock->magic = 0;
+ sock->common.magic = 0;
+ sock->common.impmagic = 0;
goto error;
}
@@ -1922,7 +2068,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW,
NULL, sock, sock, NULL, NULL);
- sock->magic = SOCKET_MAGIC;
+ sock->common.magic = ISCAPI_SOCKET_MAGIC;
+ sock->common.impmagic = SOCKET_MAGIC;
*socketp = sock;
return (ISC_R_SUCCESS);
@@ -1947,8 +2094,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
* also close the socket.
*/
static void
-free_socket(isc_socket_t **socketp) {
- isc_socket_t *sock = *socketp;
+free_socket(isc__socket_t **socketp) {
+ isc__socket_t *sock = *socketp;
INSIST(sock->references == 0);
INSIST(VALID_SOCKET(sock));
@@ -1968,7 +2115,8 @@ free_socket(isc_socket_t **socketp) {
isc_mem_put(sock->manager->mctx, sock->sendcmsgbuf,
sock->sendcmsgbuflen);
- sock->magic = 0;
+ sock->common.magic = 0;
+ sock->common.impmagic = 0;
DESTROYLOCK(&sock->lock);
@@ -2016,7 +2164,7 @@ clear_bsdcompat(void) {
#endif
static isc_result_t
-opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) {
+opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) {
char strbuf[ISC_STRERRORSIZE];
const char *err = "socket";
int tries = 0;
@@ -2287,11 +2435,12 @@ opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) {
* called with 'arg' as the arg value. The new socket is returned
* in 'socketp'.
*/
-isc_result_t
-isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
- isc_socket_t **socketp)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
+ isc_socket_t **socketp)
{
- isc_socket_t *sock = NULL;
+ isc__socket_t *sock = NULL;
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
isc_result_t result;
int lockid;
@@ -2327,8 +2476,9 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
return (result);
}
+ sock->common.methods = (isc_socketmethods_t *)&socketmethods;
sock->references = 1;
- *socketp = sock;
+ *socketp = (isc_socket_t *)sock;
/*
* Note we don't have to lock the socket like we normally would because
@@ -2359,9 +2509,11 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_socket_open(isc_socket_t *sock) {
+#ifdef BIND9
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_open(isc_socket_t *sock0) {
isc_result_t result;
+ isc__socket_t *sock = (isc__socket_t *)sock0;
REQUIRE(VALID_SOCKET(sock));
@@ -2408,12 +2560,13 @@ isc_socket_open(isc_socket_t *sock) {
* called with 'arg' as the arg value. The new socket is returned
* in 'socketp'.
*/
-isc_result_t
-isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
- isc_sockfdwatch_t callback, void *cbarg,
- isc_task_t *task, isc_socket_t **socketp)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags,
+ isc_sockfdwatch_t callback, void *cbarg,
+ isc_task_t *task, isc_socket_t **socketp)
{
- isc_socket_t *sock = NULL;
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+ isc__socket_t *sock = NULL;
isc_result_t result;
int lockid;
@@ -2431,8 +2584,9 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
sock->fdwatchtask = task;
sock->statsindex = fdwatchstatsindex;
+ sock->common.methods = (isc_socketmethods_t *)&socketmethods;
sock->references = 1;
- *socketp = sock;
+ *socketp = (isc_socket_t *)sock;
/*
* Note we don't have to lock the socket like we normally would because
@@ -2463,12 +2617,15 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
return (ISC_R_SUCCESS);
}
+#endif /* BIND9 */
/*
* Attach to a socket. Caller must explicitly detach when it is done.
*/
-void
-isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_attach(isc_socket_t *sock0, isc_socket_t **socketp) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
REQUIRE(VALID_SOCKET(sock));
REQUIRE(socketp != NULL && *socketp == NULL);
@@ -2476,20 +2633,20 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
sock->references++;
UNLOCK(&sock->lock);
- *socketp = sock;
+ *socketp = (isc_socket_t *)sock;
}
/*
* Dereference a socket. If this is the last reference to it, clean things
* up by destroying the socket.
*/
-void
-isc_socket_detach(isc_socket_t **socketp) {
- isc_socket_t *sock;
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_detach(isc_socket_t **socketp) {
+ isc__socket_t *sock;
isc_boolean_t kill_socket = ISC_FALSE;
REQUIRE(socketp != NULL);
- sock = *socketp;
+ sock = (isc__socket_t *)*socketp;
REQUIRE(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -2505,10 +2662,12 @@ isc_socket_detach(isc_socket_t **socketp) {
*socketp = NULL;
}
-isc_result_t
-isc_socket_close(isc_socket_t *sock) {
+#ifdef BIND9
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_close(isc_socket_t *sock0) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
int fd;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
isc_sockettype_t type;
REQUIRE(VALID_SOCKET(sock));
@@ -2546,6 +2705,7 @@ isc_socket_close(isc_socket_t *sock) {
return (ISC_R_SUCCESS);
}
+#endif /* BIND9 */
/*
* I/O is possible on a given socket. Schedule an event to this task that
@@ -2556,7 +2716,7 @@ isc_socket_close(isc_socket_t *sock) {
* The socket and manager must be locked before calling this function.
*/
static void
-dispatch_recv(isc_socket_t *sock) {
+dispatch_recv(isc__socket_t *sock) {
intev_t *iev;
isc_socketevent_t *ev;
isc_task_t *sender;
@@ -2590,7 +2750,7 @@ dispatch_recv(isc_socket_t *sock) {
}
static void
-dispatch_send(isc_socket_t *sock) {
+dispatch_send(isc__socket_t *sock) {
intev_t *iev;
isc_socketevent_t *ev;
isc_task_t *sender;
@@ -2627,7 +2787,7 @@ dispatch_send(isc_socket_t *sock) {
* Dispatch an internal accept event.
*/
static void
-dispatch_accept(isc_socket_t *sock) {
+dispatch_accept(isc__socket_t *sock) {
intev_t *iev;
isc_socket_newconnev_t *ev;
@@ -2653,7 +2813,7 @@ dispatch_accept(isc_socket_t *sock) {
}
static void
-dispatch_connect(isc_socket_t *sock) {
+dispatch_connect(isc__socket_t *sock) {
intev_t *iev;
isc_socket_connev_t *ev;
@@ -2683,7 +2843,7 @@ dispatch_connect(isc_socket_t *sock) {
* Caller must have the socket locked if the event is attached to the socket.
*/
static void
-send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
+send_recvdone_event(isc__socket_t *sock, isc_socketevent_t **dev) {
isc_task_t *task;
task = (*dev)->ev_sender;
@@ -2706,7 +2866,7 @@ send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
* Caller must have the socket locked if the event is attached to the socket.
*/
static void
-send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
+send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) {
isc_task_t *task;
INSIST(dev != NULL && *dev != NULL);
@@ -2737,8 +2897,8 @@ send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
*/
static void
internal_accept(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
- isc_socketmgr_t *manager;
+ isc__socket_t *sock;
+ isc__socketmgr_t *manager;
isc_socket_newconnev_t *dev;
isc_task_t *task;
ISC_SOCKADDR_LEN_T addrlen;
@@ -2793,9 +2953,9 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
* daemons such as BIND 8 and Apache.
*/
- addrlen = sizeof(dev->newsocket->peer_address.type);
- memset(&dev->newsocket->peer_address.type, 0, addrlen);
- fd = accept(sock->fd, &dev->newsocket->peer_address.type.sa,
+ addrlen = sizeof(NEWCONNSOCK(dev)->peer_address.type);
+ memset(&NEWCONNSOCK(dev)->peer_address.type, 0, addrlen);
+ fd = accept(sock->fd, &NEWCONNSOCK(dev)->peer_address.type.sa,
(void *)&addrlen);
#ifdef F_DUPFD
@@ -2865,14 +3025,14 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
(void)close(fd);
goto soft_error;
- } else if (dev->newsocket->peer_address.type.sa.sa_family !=
+ } else if (NEWCONNSOCK(dev)->peer_address.type.sa.sa_family !=
sock->pf)
{
UNEXPECTED_ERROR(__FILE__, __LINE__,
"internal_accept(): "
"accept() returned peer address "
"family %u (expected %u)",
- dev->newsocket->peer_address.
+ NEWCONNSOCK(dev)->peer_address.
type.sa.sa_family,
sock->pf);
(void)close(fd);
@@ -2891,8 +3051,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
}
if (fd != -1) {
- dev->newsocket->peer_address.length = addrlen;
- dev->newsocket->pf = sock->pf;
+ NEWCONNSOCK(dev)->peer_address.length = addrlen;
+ NEWCONNSOCK(dev)->pf = sock->pf;
}
/*
@@ -2921,28 +3081,28 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
int lockid = FDLOCK_ID(fd);
LOCK(&manager->fdlock[lockid]);
- manager->fds[fd] = dev->newsocket;
+ manager->fds[fd] = NEWCONNSOCK(dev);
manager->fdstate[fd] = MANAGED;
UNLOCK(&manager->fdlock[lockid]);
LOCK(&manager->lock);
- ISC_LIST_APPEND(manager->socklist, dev->newsocket, link);
+ ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link);
- dev->newsocket->fd = fd;
- dev->newsocket->bound = 1;
- dev->newsocket->connected = 1;
+ NEWCONNSOCK(dev)->fd = fd;
+ NEWCONNSOCK(dev)->bound = 1;
+ NEWCONNSOCK(dev)->connected = 1;
/*
* Save away the remote address
*/
- dev->address = dev->newsocket->peer_address;
+ dev->address = NEWCONNSOCK(dev)->peer_address;
#ifdef USE_SELECT
if (manager->maxfd < fd)
manager->maxfd = fd;
#endif
- socket_log(sock, &dev->newsocket->peer_address, CREATION,
+ socket_log(sock, &NEWCONNSOCK(dev)->peer_address, CREATION,
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN,
"accepted connection, new socket %p",
dev->newsocket);
@@ -2952,8 +3112,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]);
} else {
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]);
- dev->newsocket->references--;
- free_socket(&dev->newsocket);
+ NEWCONNSOCK(dev)->references--;
+ free_socket((isc__socket_t **)&dev->newsocket);
}
/*
@@ -2977,7 +3137,7 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
static void
internal_recv(isc_task_t *me, isc_event_t *ev) {
isc_socketevent_t *dev;
- isc_socket_t *sock;
+ isc__socket_t *sock;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTR);
@@ -3042,14 +3202,14 @@ internal_recv(isc_task_t *me, isc_event_t *ev) {
static void
internal_send(isc_task_t *me, isc_event_t *ev) {
isc_socketevent_t *dev;
- isc_socket_t *sock;
+ isc__socket_t *sock;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTW);
/*
* Find out what socket this is and lock it.
*/
- sock = (isc_socket_t *)ev->ev_sender;
+ sock = (isc__socket_t *)ev->ev_sender;
INSIST(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -3096,7 +3256,7 @@ internal_send(isc_task_t *me, isc_event_t *ev) {
static void
internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
+ isc__socket_t *sock;
int more_data;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTW);
@@ -3104,7 +3264,7 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
/*
* Find out what socket this is and lock it.
*/
- sock = (isc_socket_t *)ev->ev_sender;
+ sock = (isc__socket_t *)ev->ev_sender;
INSIST(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -3115,7 +3275,8 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
INSIST(sock->pending_send == 1);
UNLOCK(&sock->lock);
- more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg);
+ more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock,
+ sock->fdwatcharg);
LOCK(&sock->lock);
sock->pending_send = 0;
@@ -3136,7 +3297,7 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
static void
internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
+ isc__socket_t *sock;
int more_data;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTR);
@@ -3144,7 +3305,7 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
/*
* Find out what socket this is and lock it.
*/
- sock = (isc_socket_t *)ev->ev_sender;
+ sock = (isc__socket_t *)ev->ev_sender;
INSIST(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -3155,7 +3316,8 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
INSIST(sock->pending_recv == 1);
UNLOCK(&sock->lock);
- more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg);
+ more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock,
+ sock->fdwatcharg);
LOCK(&sock->lock);
sock->pending_recv = 0;
@@ -3179,10 +3341,10 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
* and unlocking twice if both reads and writes are possible.
*/
static void
-process_fd(isc_socketmgr_t *manager, int fd, isc_boolean_t readable,
+process_fd(isc__socketmgr_t *manager, int fd, isc_boolean_t readable,
isc_boolean_t writeable)
{
- isc_socket_t *sock;
+ isc__socket_t *sock;
isc_boolean_t unlock_sock;
isc_boolean_t unwatch_read = ISC_FALSE, unwatch_write = ISC_FALSE;
int lockid = FDLOCK_ID(fd);
@@ -3248,11 +3410,11 @@ check_write:
#ifdef USE_KQUEUE
static isc_boolean_t
-process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
+process_fds(isc__socketmgr_t *manager, struct kevent *events, int nevents) {
int i;
isc_boolean_t readable, writable;
isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
#endif
@@ -3270,7 +3432,7 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].ident < manager->maxsocks);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (events[i].ident == (uintptr_t)manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
@@ -3281,7 +3443,7 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
process_fd(manager, events[i].ident, readable, writable);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
#endif
@@ -3290,10 +3452,11 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
}
#elif defined(USE_EPOLL)
static isc_boolean_t
-process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
+process_fds(isc__socketmgr_t *manager, struct epoll_event *events, int nevents)
+{
int i;
isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
#endif
@@ -3306,7 +3469,7 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].data.fd < (int)manager->maxsocks);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (events[i].data.fd == manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
@@ -3328,7 +3491,7 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
(events[i].events & EPOLLOUT) != 0);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
#endif
@@ -3337,10 +3500,10 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
}
#elif defined(USE_DEVPOLL)
static isc_boolean_t
-process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
+process_fds(isc__socketmgr_t *manager, struct pollfd *events, int nevents) {
int i;
isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
#endif
@@ -3353,7 +3516,7 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].fd < (int)manager->maxsocks);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (events[i].fd == manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
@@ -3364,7 +3527,7 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
(events[i].events & POLLOUT) != 0);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
#endif
@@ -3373,27 +3536,27 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
}
#elif defined(USE_SELECT)
static void
-process_fds(isc_socketmgr_t *manager, int maxfd,
- fd_set *readfds, fd_set *writefds)
+process_fds(isc__socketmgr_t *manager, int maxfd, fd_set *readfds,
+ fd_set *writefds)
{
int i;
REQUIRE(maxfd <= (int)manager->maxsocks);
for (i = 0; i < maxfd; i++) {
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (i == manager->pipe_fds[0] || i == manager->pipe_fds[1])
continue;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
process_fd(manager, i, FD_ISSET(i, readfds),
FD_ISSET(i, writefds));
}
}
#endif
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
static isc_boolean_t
-process_ctlfd(isc_socketmgr_t *manager) {
+process_ctlfd(isc__socketmgr_t *manager) {
int msg, fd;
for (;;) {
@@ -3441,7 +3604,7 @@ process_ctlfd(isc_socketmgr_t *manager) {
*/
static isc_threadresult_t
watcher(void *uap) {
- isc_socketmgr_t *manager = uap;
+ isc__socketmgr_t *manager = uap;
isc_boolean_t done;
int ctlfd;
int cc;
@@ -3556,29 +3719,34 @@ watcher(void *uap) {
return ((isc_threadresult_t)0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
-void
-isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) {
+#ifdef BIND9
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_setreserved(isc_socketmgr_t *manager0, isc_uint32_t reserved) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
REQUIRE(VALID_MANAGER(manager));
manager->reserved = reserved;
}
-void
-isc__socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) {
+ISC_SOCKETFUNC_SCOPE void
+isc___socketmgr_maxudp(isc_socketmgr_t *manager0, int maxudp) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
REQUIRE(VALID_MANAGER(manager));
manager->maxudp = maxudp;
}
+#endif /* BIND9 */
/*
* Create a new socket manager.
*/
static isc_result_t
-setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
+setup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) {
isc_result_t result;
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
char strbuf[ISC_STRERRORSIZE];
@@ -3604,7 +3772,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->kqueue_fd);
@@ -3612,7 +3780,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(struct kevent) * manager->nevents);
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#elif defined(USE_EPOLL)
manager->nevents = ISC_SOCKET_MAXEVENTS;
manager->events = isc_mem_get(mctx, sizeof(struct epoll_event) *
@@ -3632,7 +3800,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(struct epoll_event) * manager->nevents);
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->epoll_fd);
@@ -3640,7 +3808,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(struct epoll_event) * manager->nevents);
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#elif defined(USE_DEVPOLL)
/*
* XXXJT: /dev/poll seems to reject large numbers of events,
@@ -3659,7 +3827,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
manager->maxsocks);
if (manager->fdpollinfo == NULL) {
isc_mem_put(mctx, manager->events,
- sizeof(pollinfo_t) * manager->maxsocks);
+ sizeof(struct pollfd) * manager->nevents);
return (ISC_R_NOMEMORY);
}
memset(manager->fdpollinfo, 0, sizeof(pollinfo_t) * manager->maxsocks);
@@ -3678,7 +3846,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(pollinfo_t) * manager->maxsocks);
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->devpoll_fd);
@@ -3688,7 +3856,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(pollinfo_t) * manager->maxsocks);
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#elif defined(USE_SELECT)
UNUSED(result);
@@ -3736,20 +3904,20 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
memset(manager->read_fds, 0, manager->fd_bufsize);
memset(manager->write_fds, 0, manager->fd_bufsize);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
(void)watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
manager->maxfd = manager->pipe_fds[0];
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
manager->maxfd = 0;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#endif /* USE_KQUEUE */
return (ISC_R_SUCCESS);
}
static void
-cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
-#ifdef ISC_PLATFORM_USETHREADS
+cleanup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) {
+#ifdef USE_WATCHER_THREAD
isc_result_t result;
result = unwatch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
@@ -3759,7 +3927,7 @@ cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#ifdef USE_KQUEUE
close(manager->kqueue_fd);
@@ -3787,35 +3955,35 @@ cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
#endif /* USE_KQUEUE */
}
-isc_result_t
-isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
- return (isc_socketmgr_create2(mctx, managerp, 0));
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
+ return (isc__socketmgr_create2(mctx, managerp, 0));
}
-isc_result_t
-isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
- unsigned int maxsocks)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks)
{
int i;
- isc_socketmgr_t *manager;
-#ifdef ISC_PLATFORM_USETHREADS
+ isc__socketmgr_t *manager;
+#ifdef USE_WATCHER_THREAD
char strbuf[ISC_STRERRORSIZE];
#endif
isc_result_t result;
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
if (socketmgr != NULL) {
/* Don't allow maxsocks to be updated */
if (maxsocks > 0 && socketmgr->maxsocks != maxsocks)
return (ISC_R_EXISTS);
socketmgr->refs++;
- *managerp = socketmgr;
+ *managerp = (isc_socketmgr_t *)socketmgr;
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
if (maxsocks == 0)
maxsocks = ISC_SOCKET_MAXSOCKETS;
@@ -3830,7 +3998,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
manager->reserved = 0;
manager->maxudp = 0;
manager->fds = isc_mem_get(mctx,
- manager->maxsocks * sizeof(isc_socket_t *));
+ manager->maxsocks * sizeof(isc__socket_t *));
if (manager->fds == NULL) {
result = ISC_R_NOMEMORY;
goto free_manager;
@@ -3842,7 +4010,9 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
}
manager->stats = NULL;
- manager->magic = SOCKET_MANAGER_MAGIC;
+ manager->common.methods = &socketmgrmethods;
+ manager->common.magic = ISCAPI_SOCKETMGR_MAGIC;
+ manager->common.impmagic = SOCKET_MANAGER_MAGIC;
manager->mctx = NULL;
memset(manager->fds, 0, manager->maxsocks * sizeof(isc_socket_t *));
ISC_LIST_INIT(manager->socklist);
@@ -3866,7 +4036,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
}
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_condition_init() %s",
@@ -3895,9 +4065,11 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
#if 0
RUNTIME_CHECK(make_nonblock(manager->pipe_fds[1]) == ISC_R_SUCCESS);
#endif
-#else /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
+
+#ifdef USE_SHARED_MANAGER
manager->refs = 1;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
/*
* Set up initial state for the select loop
@@ -3906,7 +4078,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
if (result != ISC_R_SUCCESS)
goto cleanup;
memset(manager->fdstate, 0, manager->maxsocks * sizeof(int));
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Start up the select/poll thread.
*/
@@ -3920,26 +4092,26 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
result = ISC_R_UNEXPECTED;
goto cleanup;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
isc_mem_attach(mctx, &manager->mctx);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
socketmgr = manager;
-#endif /* ISC_PLATFORM_USETHREADS */
- *managerp = manager;
+#endif /* USE_SHARED_MANAGER */
+ *managerp = (isc_socketmgr_t *)manager;
return (ISC_R_SUCCESS);
cleanup:
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
(void)close(manager->pipe_fds[0]);
(void)close(manager->pipe_fds[1]);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
cleanup_condition:
(void)isc_condition_destroy(&manager->shutdown_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
cleanup_lock:
@@ -3967,8 +4139,10 @@ free_manager:
return (result);
}
+#ifdef BIND9
isc_result_t
-isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
+isc__socketmgr_getmaxsockets(isc_socketmgr_t *manager0, unsigned int *nsockp) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(nsockp != NULL);
@@ -3978,7 +4152,9 @@ isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
}
void
-isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
+isc__socketmgr_setstats(isc_socketmgr_t *manager0, isc_stats_t *stats) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
REQUIRE(VALID_MANAGER(manager));
REQUIRE(ISC_LIST_EMPTY(manager->socklist));
REQUIRE(manager->stats == NULL);
@@ -3986,10 +4162,11 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
isc_stats_attach(stats, &manager->stats);
}
+#endif
-void
-isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
- isc_socketmgr_t *manager;
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_destroy(isc_socketmgr_t **managerp) {
+ isc__socketmgr_t *manager;
int i;
isc_mem_t *mctx;
@@ -3998,20 +4175,20 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
*/
REQUIRE(managerp != NULL);
- manager = *managerp;
+ manager = (isc__socketmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
if (manager->refs > 1) {
manager->refs--;
*managerp = NULL;
return;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
LOCK(&manager->lock);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Wait for all sockets to be destroyed.
*/
@@ -4022,7 +4199,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
"sockets exist"));
WAIT(&manager->shutdown_ok, &manager->lock);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
/*
* Hope all sockets have been destroyed.
*/
@@ -4033,7 +4210,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
"sockets exist"));
INSIST(0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
UNLOCK(&manager->lock);
@@ -4044,7 +4221,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
*/
select_poke(manager, 0, SELECT_POKE_SHUTDOWN);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Wait for thread to exit.
*/
@@ -4053,25 +4230,25 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
"isc_thread_join() %s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
/*
* Clean up.
*/
cleanup_watcher(manager->mctx, manager);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
(void)close(manager->pipe_fds[0]);
(void)close(manager->pipe_fds[1]);
(void)isc_condition_destroy(&manager->shutdown_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
for (i = 0; i < (int)manager->maxsocks; i++)
if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */
(void)close(i);
isc_mem_put(manager->mctx, manager->fds,
- manager->maxsocks * sizeof(isc_socket_t *));
+ manager->maxsocks * sizeof(isc__socket_t *));
isc_mem_put(manager->mctx, manager->fdstate,
manager->maxsocks * sizeof(int));
@@ -4085,17 +4262,22 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
FDLOCK_COUNT * sizeof(isc_mutex_t));
}
DESTROYLOCK(&manager->lock);
- manager->magic = 0;
+ manager->common.magic = 0;
+ manager->common.impmagic = 0;
mctx= manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
*managerp = NULL;
+
+#ifdef USE_SHARED_MANAGER
+ socketmgr = NULL;
+#endif
}
static isc_result_t
-socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
+socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
unsigned int flags)
{
int io_state;
@@ -4166,13 +4348,14 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
return (result);
}
-isc_result_t
-isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
- unsigned int minimum, isc_task_t *task,
- isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
unsigned int iocount;
isc_buffer_t *buffer;
@@ -4220,12 +4403,14 @@ isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
return (socket_recv(sock, dev, task, 0));
}
-isc_result_t
-isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv(isc_socket_t *sock0, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(action != NULL);
@@ -4239,14 +4424,16 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
if (dev == NULL)
return (ISC_R_NOMEMORY);
- return (isc_socket_recv2(sock, region, minimum, task, dev, 0));
+ return (isc__socket_recv2(sock0, region, minimum, task, dev, 0));
}
-isc_result_t
-isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
- unsigned int minimum, isc_task_t *task,
- isc_socketevent_t *event, unsigned int flags)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv2(isc_socket_t *sock0, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
event->ev_sender = sock;
event->result = ISC_R_UNEXPECTED;
ISC_LIST_INIT(event->bufferlist);
@@ -4271,7 +4458,7 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
}
static isc_result_t
-socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
+socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
unsigned int flags)
{
@@ -4362,24 +4549,25 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
return (result);
}
-isc_result_t
-isc_socket_send(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
/*
* REQUIRE() checking is performed in isc_socket_sendto().
*/
- return (isc_socket_sendto(sock, region, task, action, arg, NULL,
- NULL));
+ return (isc__socket_sendto(sock, region, task, action, arg, NULL,
+ NULL));
}
-isc_result_t
-isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(region != NULL);
@@ -4401,21 +4589,22 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
return (socket_send(sock, dev, task, address, pktinfo, 0));
}
-isc_result_t
-isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
- return (isc_socket_sendtov(sock, buflist, task, action, arg, NULL,
- NULL));
+ return (isc__socket_sendtov(sock, buflist, task, action, arg, NULL,
+ NULL));
}
-isc_result_t
-isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
unsigned int iocount;
isc_buffer_t *buffer;
@@ -4449,12 +4638,15 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
return (socket_send(sock, dev, task, address, pktinfo, 0));
}
-isc_result_t
-isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
- isc_socketevent_t *event, unsigned int flags)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto2(isc_socket_t *sock0, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
+ REQUIRE(VALID_SOCKET(sock));
REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0);
if ((flags & ISC_SOCKFLAG_NORETRY) != 0)
REQUIRE(sock->type == isc_sockettype_udp);
@@ -4469,8 +4661,8 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
return (socket_send(sock, event, task, address, pktinfo, flags));
}
-void
-isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
#ifdef ISC_PLATFORM_HAVESYSUNH
int s;
struct stat sb;
@@ -4599,8 +4791,8 @@ isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
#endif
}
-isc_result_t
-isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
isc_uint32_t owner, isc_uint32_t group)
{
#ifdef ISC_PLATFORM_HAVESYSUNH
@@ -4653,12 +4845,15 @@ isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
#endif
}
-isc_result_t
-isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
- unsigned int options) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr,
+ unsigned int options) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
char strbuf[ISC_STRERRORSIZE];
int on = 1;
+ REQUIRE(VALID_SOCKET(sock));
+
LOCK(&sock->lock);
INSIST(!sock->bound);
@@ -4717,8 +4912,9 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_socket_filter(isc_socket_t *sock, const char *filter) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_filter(isc_socket_t *sock0, const char *filter) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
#ifdef SO_ACCEPTFILTER
char strbuf[ISC_STRERRORSIZE];
struct accept_filter_arg afa;
@@ -4756,8 +4952,9 @@ isc_socket_filter(isc_socket_t *sock, const char *filter) {
* is a new connection we'll have to allocate a new one anyway, so we might
* as well keep things simple rather than having to track them.
*/
-isc_result_t
-isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
char strbuf[ISC_STRERRORSIZE];
REQUIRE(VALID_SOCKET(sock));
@@ -4790,14 +4987,15 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
/*
* This should try to do aggressive accept() XXXMLG
*/
-isc_result_t
-isc_socket_accept(isc_socket_t *sock,
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_accept(isc_socket_t *sock0,
isc_task_t *task, isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socket_newconnev_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
isc_task_t *ntask = NULL;
- isc_socket_t *nsock;
+ isc__socket_t *nsock;
isc_result_t result;
isc_boolean_t do_poke = ISC_FALSE;
@@ -4838,7 +5036,7 @@ isc_socket_accept(isc_socket_t *sock,
nsock->statsindex = sock->statsindex;
dev->ev_sender = ntask;
- dev->newsocket = nsock;
+ dev->newsocket = (isc_socket_t *)nsock;
/*
* Poke watcher here. We still have the socket locked, so there
@@ -4857,15 +5055,17 @@ isc_socket_accept(isc_socket_t *sock,
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr,
isc_task_t *task, isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socket_connev_t *dev;
isc_task_t *ntask = NULL;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
int cc;
char strbuf[ISC_STRERRORSIZE];
+ char addrbuf[ISC_SOCKADDR_FORMATSIZE];
REQUIRE(VALID_SOCKET(sock));
REQUIRE(addr != NULL);
@@ -4934,7 +5134,9 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
sock->connected = 0;
isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__, "%d/%s", errno, strbuf);
+ isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "connect(%s) %d/%s",
+ addrbuf, errno, strbuf);
UNLOCK(&sock->lock);
inc_stats(sock->manager->stats,
@@ -5000,7 +5202,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
*/
static void
internal_connect(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
+ isc__socket_t *sock;
isc_socket_connev_t *dev;
isc_task_t *task;
int cc;
@@ -5114,8 +5316,9 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev));
}
-isc_result_t
-isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getpeername(isc_socket_t *sock0, isc_sockaddr_t *addressp) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_result_t result;
REQUIRE(VALID_SOCKET(sock));
@@ -5135,8 +5338,9 @@ isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
return (result);
}
-isc_result_t
-isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getsockname(isc_socket_t *sock0, isc_sockaddr_t *addressp) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
ISC_SOCKADDR_LEN_T len;
isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
@@ -5173,8 +5377,9 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
* Run through the list of events on this socket, and cancel the ones
* queued for task "task" of type "how". "how" is a bitmask.
*/
-void
-isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
REQUIRE(VALID_SOCKET(sock));
@@ -5253,8 +5458,8 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
ISC_LIST_UNLINK(sock->accept_list, dev,
ev_link);
- dev->newsocket->references--;
- free_socket(&dev->newsocket);
+ NEWCONNSOCK(dev)->references--;
+ free_socket((isc__socket_t **)&dev->newsocket);
dev->result = ISC_R_CANCELED;
dev->ev_sender = sock;
@@ -5293,17 +5498,22 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
UNLOCK(&sock->lock);
}
-isc_sockettype_t
-isc_socket_gettype(isc_socket_t *sock) {
+ISC_SOCKETFUNC_SCOPE isc_sockettype_t
+isc__socket_gettype(isc_socket_t *sock0) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
REQUIRE(VALID_SOCKET(sock));
return (sock->type);
}
-isc_boolean_t
-isc_socket_isbound(isc_socket_t *sock) {
+ISC_SOCKETFUNC_SCOPE isc_boolean_t
+isc__socket_isbound(isc_socket_t *sock0) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_boolean_t val;
+ REQUIRE(VALID_SOCKET(sock));
+
LOCK(&sock->lock);
val = ((sock->bound) ? ISC_TRUE : ISC_FALSE);
UNLOCK(&sock->lock);
@@ -5311,8 +5521,9 @@ isc_socket_isbound(isc_socket_t *sock) {
return (val);
}
-void
-isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
#if defined(IPV6_V6ONLY)
int onoff = yes ? 1 : 0;
#else
@@ -5342,12 +5553,21 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
#endif
}
-#ifndef ISC_PLATFORM_USETHREADS
-/* In our assumed scenario, we can simply use a single static object. */
+#ifndef USE_WATCHER_THREAD
+/*
+ * In our assumed scenario, we can simply use a single static object.
+ * XXX: this is not true if the application uses multiple threads with
+ * 'multi-context' mode. Fixing this is a future TODO item.
+ */
static isc_socketwait_t swait_private;
int
-isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
+isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp,
+ isc_socketwait_t **swaitp)
+{
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
+
int n;
#ifdef USE_KQUEUE
struct timespec ts, *tsp;
@@ -5361,7 +5581,11 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
REQUIRE(swaitp != NULL && *swaitp == NULL);
- if (socketmgr == NULL)
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = socketmgr;
+#endif
+ if (manager == NULL)
return (0);
#ifdef USE_KQUEUE
@@ -5371,8 +5595,8 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
tsp = &ts;
} else
tsp = NULL;
- swait_private.nevents = kevent(socketmgr->kqueue_fd, NULL, 0,
- socketmgr->events, socketmgr->nevents,
+ swait_private.nevents = kevent(manager->kqueue_fd, NULL, 0,
+ manager->events, manager->nevents,
tsp);
n = swait_private.nevents;
#elif defined(USE_EPOLL)
@@ -5380,29 +5604,28 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000;
else
timeout = -1;
- swait_private.nevents = epoll_wait(socketmgr->epoll_fd,
- socketmgr->events,
- socketmgr->nevents, timeout);
+ swait_private.nevents = epoll_wait(manager->epoll_fd,
+ manager->events,
+ manager->nevents, timeout);
n = swait_private.nevents;
#elif defined(USE_DEVPOLL)
- dvp.dp_fds = socketmgr->events;
- dvp.dp_nfds = socketmgr->nevents;
+ dvp.dp_fds = manager->events;
+ dvp.dp_nfds = manager->nevents;
if (tvp != NULL) {
dvp.dp_timeout = tvp->tv_sec * 1000 +
(tvp->tv_usec + 999) / 1000;
} else
dvp.dp_timeout = -1;
- swait_private.nevents = ioctl(socketmgr->devpoll_fd, DP_POLL, &dvp);
+ swait_private.nevents = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
n = swait_private.nevents;
#elif defined(USE_SELECT)
- memcpy(socketmgr->read_fds_copy, socketmgr->read_fds,
- socketmgr->fd_bufsize);
- memcpy(socketmgr->write_fds_copy, socketmgr->write_fds,
- socketmgr->fd_bufsize);
+ memcpy(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize);
+ memcpy(manager->write_fds_copy, manager->write_fds,
+ manager->fd_bufsize);
- swait_private.readset = socketmgr->read_fds_copy;
- swait_private.writeset = socketmgr->write_fds_copy;
- swait_private.maxfd = socketmgr->maxfd + 1;
+ swait_private.readset = manager->read_fds_copy;
+ swait_private.writeset = manager->write_fds_copy;
+ swait_private.maxfd = manager->maxfd + 1;
n = select(swait_private.maxfd, swait_private.readset,
swait_private.writeset, NULL, tvp);
@@ -5413,24 +5636,32 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
}
isc_result_t
-isc__socketmgr_dispatch(isc_socketwait_t *swait) {
+isc__socketmgr_dispatch(isc_socketmgr_t *manager0, isc_socketwait_t *swait) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
REQUIRE(swait == &swait_private);
- if (socketmgr == NULL)
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = socketmgr;
+#endif
+ if (manager == NULL)
return (ISC_R_NOTFOUND);
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
- (void)process_fds(socketmgr, socketmgr->events, swait->nevents);
+ (void)process_fds(manager, manager->events, swait->nevents);
return (ISC_R_SUCCESS);
#elif defined(USE_SELECT)
- process_fds(socketmgr, swait->maxfd, swait->readset, swait->writeset);
+ process_fds(manager, swait->maxfd, swait->readset, swait->writeset);
return (ISC_R_SUCCESS);
#endif
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
+#ifdef BIND9
void
-isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
+isc__socket_setname(isc_socket_t *socket0, const char *name, void *tag) {
+ isc__socket_t *socket = (isc__socket_t *)socket0;
/*
* Name 'socket'.
@@ -5445,17 +5676,29 @@ isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
UNLOCK(&socket->lock);
}
-const char *
-isc_socket_getname(isc_socket_t *socket) {
+ISC_SOCKETFUNC_SCOPE const char *
+isc__socket_getname(isc_socket_t *socket0) {
+ isc__socket_t *socket = (isc__socket_t *)socket0;
+
return (socket->name);
}
void *
-isc_socket_gettag(isc_socket_t *socket) {
+isc__socket_gettag(isc_socket_t *socket0) {
+ isc__socket_t *socket = (isc__socket_t *)socket0;
+
return (socket->tag);
}
+#endif /* BIND9 */
-#ifdef HAVE_LIBXML2
+#ifdef USE_SOCKETIMPREGISTER
+isc_result_t
+isc__socket_register() {
+ return (isc_socket_register(isc__socketmgr_create));
+}
+#endif
+
+#if defined(HAVE_LIBXML2) && defined(BIND9)
static const char *
_socktype(isc_sockettype_t type)
@@ -5472,21 +5715,21 @@ _socktype(isc_sockettype_t type)
return ("not-initialized");
}
-void
-isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer)
-{
- isc_socket_t *sock;
+ISC_SOCKETFUNC_SCOPE void
+isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) {
+ isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0;
+ isc__socket_t *sock;
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_t addr;
ISC_SOCKADDR_LEN_T len;
LOCK(&mgr->lock);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
xmlTextWriterWriteFormatString(writer, "%d", mgr->refs);
xmlTextWriterEndElement(writer);
-#endif
+#endif /* USE_SHARED_MANAGER */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets");
sock = ISC_LIST_HEAD(mgr->socklist);
diff --git a/lib/isc/unix/socket_p.h b/lib/isc/unix/socket_p.h
index fc044e58..13160117 100644
--- a/lib/isc/unix/socket_p.h
+++ b/lib/isc/unix/socket_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket_p.h,v 1.13 2008/06/23 23:47:11 tbox Exp $ */
+/* $Id: socket_p.h,v 1.15 2009/09/02 23:48:03 tbox Exp $ */
#ifndef ISC_SOCKET_P_H
#define ISC_SOCKET_P_H
@@ -27,6 +27,7 @@
#endif
typedef struct isc_socketwait isc_socketwait_t;
-int isc__socketmgr_waitevents(struct timeval *, isc_socketwait_t **);
-isc_result_t isc__socketmgr_dispatch(isc_socketwait_t *);
+int isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *,
+ isc_socketwait_t **);
+isc_result_t isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *);
#endif /* ISC_SOCKET_P_H */
diff --git a/lib/isc/win32/Makefile.in b/lib/isc/win32/Makefile.in
index 5c71dffb..acfbf32b 100644
--- a/lib/isc/win32/Makefile.in
+++ b/lib/isc/win32/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.11 2007/06/19 23:47:19 tbox Exp $
+# $Id: Makefile.in,v 1.13 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,7 +23,7 @@ CINCLUDES = -I${srcdir}/.. \
-I./include \
-I${srcdir}/include \
-I${srcdir}/../include
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
# Alphabetically
diff --git a/lib/isc/win32/app.c b/lib/isc/win32/app.c
index b0db90d4..04b16387 100644
--- a/lib/isc/win32/app.c
+++ b/lib/isc/win32/app.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: app.c,v 1.7 2007/06/19 23:47:19 tbox Exp $ */
+/* $Id: app.c,v 1.9 2009/09/02 23:48:03 tbox Exp $ */
#include <config.h>
@@ -75,7 +75,7 @@ DWORD dwWaitResult;
static isc_thread_t main_thread;
isc_result_t
-isc_app_start(void) {
+isc__app_start(void) {
isc_result_t result;
/*
@@ -99,7 +99,7 @@ isc_app_start(void) {
}
isc_result_t
-isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
+isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
void *arg) {
isc_event_t *event;
isc_task_t *cloned_task = NULL;
@@ -133,7 +133,7 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
}
isc_result_t
-isc_app_run(void) {
+isc__app_run(void) {
isc_event_t *event, *next_event;
isc_task_t *task;
HANDLE *pHandles = NULL;
@@ -170,7 +170,7 @@ isc_app_run(void) {
FALSE, INFINITE);
/* See why we returned */
-
+
if (WaitSucceeded(dwWaitResult, NUM_EVENTS)) {
/*
* The return was due to one of the events
@@ -199,7 +199,7 @@ isc_app_run(void) {
}
isc_result_t
-isc_app_shutdown(void) {
+isc__app_shutdown(void) {
isc_boolean_t want_kill = ISC_TRUE;
LOCK(&lock);
@@ -218,7 +218,7 @@ isc_app_shutdown(void) {
}
isc_result_t
-isc_app_reload(void) {
+isc__app_reload(void) {
isc_boolean_t want_reload = ISC_TRUE;
LOCK(&lock);
@@ -238,12 +238,12 @@ isc_app_reload(void) {
}
void
-isc_app_finish(void) {
+isc__app_finish(void) {
DESTROYLOCK(&lock);
}
void
-isc_app_block(void) {
+isc__app_block(void) {
REQUIRE(running);
REQUIRE(!blocked);
@@ -252,7 +252,7 @@ isc_app_block(void) {
}
void
-isc_app_unblock(void) {
+isc__app_unblock(void) {
REQUIRE(running);
REQUIRE(blocked);
blocked = ISC_FALSE;
diff --git a/lib/isc/win32/file.c b/lib/isc/win32/file.c
index 026182e4..fabd5b6e 100644
--- a/lib/isc/win32/file.c
+++ b/lib/isc/win32/file.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: file.c,v 1.33 2009/06/11 23:47:55 tbox Exp $ */
+/* $Id: file.c,v 1.35 2009/09/02 17:58:06 each Exp $ */
#include <config.h>
@@ -31,10 +31,12 @@
#include <sys/utime.h>
#include <isc/file.h>
+#include <isc/mem.h>
#include <isc/result.h>
#include <isc/time.h>
#include <isc/util.h>
#include <isc/stat.h>
+#include <isc/string.h>
#include "errno2result.h"
@@ -541,3 +543,43 @@ isc_file_safecreate(const char *filename, FILE **fp) {
*fp = f;
return (ISC_R_SUCCESS);
}
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename)
+{
+ char *dir, *file, *slash;
+ char *backslash;
+
+ slash = strrchr(path, '/');
+
+ backslash = strrchr(path, '\\');
+ if ((slash != NULL && backslash != NULL && backslash > slash) ||
+ (slash == NULL && backslash != NULL))
+ slash = backslash;
+
+ if (slash == path) {
+ file = ++slash;
+ dir = isc_mem_strdup(mctx, "/");
+ } else if (slash != NULL) {
+ file = ++slash;
+ dir = isc_mem_allocate(mctx, slash - path);
+ if (dir != NULL)
+ strlcpy(dir, path, slash - path);
+ } else {
+ file = path;
+ dir = isc_mem_strdup(mctx, ".");
+ }
+
+ if (dir == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (*file == '\0') {
+ isc_mem_free(mctx, dir);
+ return (ISC_R_INVALIDFILE);
+ }
+
+ *dirname = dir;
+ *basename = file;
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def
index 151a4e3d..4133c419 100644
--- a/lib/isc/win32/libisc.def
+++ b/lib/isc/win32/libisc.def
@@ -5,6 +5,8 @@ EXPORTS
NTReportError
closelog
+isc__backtrace_nsymbols
+isc__backtrace_symtable
isc__buffer_activeregion
isc__buffer_add
isc__buffer_availableregion
@@ -26,28 +28,31 @@ isc__buffer_remainingregion
isc__buffer_setactive
isc__buffer_subtract
isc__buffer_usedregion
-isc__mem_allocate
-isc__mem_free
-isc__mem_get
-isc__mem_put
-isc__mem_putanddetach
-isc__mem_reallocate
-isc__mem_strdup
-isc__mempool_get
-isc__mempool_put
-isc__socketmgr_maxudp
+isc___mem_allocate
+isc___mem_free
+isc___mem_get
+isc___mem_put
+isc___mem_putanddetach
+isc___mem_reallocate
+isc___mem_strdup
+isc___mempool_get
+isc___mempool_put
+isc___socketmgr_maxudp
isc__socketmgr_setreserved
isc__strerror
-isc_app_block
-isc_app_finish
-isc_app_onrun
-isc_app_reload
-isc_app_run
-isc_app_shutdown
-isc_app_start
-isc_app_unblock
+isc__app_block
+isc__app_finish
+isc__app_onrun
+isc__app_reload
+isc__app_run
+isc__app_shutdown
+isc__app_start
+isc__app_unblock
isc_assertion_setcallback
isc_assertion_typetotext
+isc_backtrace_getsymbol
+isc_backtrace_getsymbolfromindex
+isc_backtrace_gettrace
isc_base32_decoderegion
isc_base32_decodestring
isc_base32_tobuffer
@@ -124,6 +129,7 @@ isc_file_renameunique
isc_file_safecreate
isc_file_safemovefile
isc_file_settime
+isc_file_splitpath
isc_file_template
isc_file_truncate
isc_fsaccess_add
@@ -252,39 +258,39 @@ isc_md5_final
isc_md5_init
isc_md5_invalidate
isc_md5_update
-isc_mem_attach
-isc_mem_checkdestroyed
-isc_mem_create
-isc_mem_create2
-isc_mem_createx
-isc_mem_createx2
-isc_mem_destroy
-isc_mem_detach
-isc_mem_getname
-isc_mem_getquota
-isc_mem_gettag
-isc_mem_inuse
-isc_mem_ondestroy
-isc_mem_references
+isc__mem_attach
+isc__mem_checkdestroyed
+isc__mem_create
+isc__mem_create2
+isc__mem_createx
+isc__mem_createx2
+isc__mem_destroy
+isc__mem_detach
+isc__mem_getname
+isc__mem_getquota
+isc__mem_gettag
+isc__mem_inuse
+isc__mem_ondestroy
+isc__mem_references
isc_mem_renderxml
-isc_mem_setdestroycheck
-isc_mem_setname
-isc_mem_setquota
-isc_mem_setwater
-isc_mem_stats
-isc_mem_waterack
-isc_mempool_associatelock
-isc_mempool_create
-isc_mempool_destroy
-isc_mempool_getallocated
-isc_mempool_getfillcount
-isc_mempool_getfreecount
-isc_mempool_getfreemax
-isc_mempool_getmaxalloc
-isc_mempool_setfillcount
-isc_mempool_setfreemax
-isc_mempool_setmaxalloc
-isc_mempool_setname
+isc__mem_setdestroycheck
+isc__mem_setname
+isc__mem_setquota
+isc__mem_setwater
+isc__mem_stats
+isc__mem_waterack
+isc__mempool_associatelock
+isc__mempool_create
+isc__mempool_destroy
+isc__mempool_getallocated
+isc__mempool_getfillcount
+isc__mempool_getfreecount
+isc__mempool_getfreemax
+isc__mempool_getmaxalloc
+isc__mempool_setfillcount
+isc__mempool_setfreemax
+isc__mempool_setmaxalloc
+isc__mempool_setname
isc_msgcat_close
isc_msgcat_get
isc_msgcat_open
@@ -415,41 +421,41 @@ isc_sockaddr_pf
isc_sockaddr_setport
isc_sockaddr_totext
isc_sockaddr_v6fromin
-isc_socket_accept
-isc_socket_attach
-isc_socket_bind
-isc_socket_cancel
-isc_socket_cleanunix
-isc_socket_close
-isc_socket_connect
-isc_socket_create
-isc_socket_detach
-isc_socket_filter
-isc_socket_getname
-isc_socket_getpeername
-isc_socket_getsockname
-isc_socket_gettag
-isc_socket_gettype
-isc_socket_ipv6only
-isc_socket_isbound
-isc_socket_listen
-isc_socket_open
-isc_socket_permunix
-isc_socket_recv
-isc_socket_recv2
-isc_socket_recvv
-isc_socket_send
-isc_socket_sendto
-isc_socket_sendto2
-isc_socket_sendtov
-isc_socket_sendv
-isc_socket_setname
-isc_socketmgr_create
-isc_socketmgr_create2
-isc_socketmgr_destroy
-isc_socketmgr_getmaxsockets
+isc__socket_accept
+isc__socket_attach
+isc__socket_bind
+isc__socket_cancel
+isc__socket_cleanunix
+isc__socket_close
+isc__socket_connect
+isc__socket_create
+isc__socket_detach
+isc__socket_filter
+isc__socket_getname
+isc__socket_getpeername
+isc__socket_getsockname
+isc__socket_gettag
+isc__socket_gettype
+isc__socket_ipv6only
+isc__socket_isbound
+isc__socket_listen
+isc__socket_open
+isc__socket_permunix
+isc__socket_recv
+isc__socket_recv2
+isc__socket_recvv
+isc__socket_send
+isc__socket_sendto
+isc__socket_sendto2
+isc__socket_sendtov
+isc__socket_sendv
+isc__socket_setname
+isc__socketmgr_create
+isc__socketmgr_create2
+isc__socketmgr_destroy
+isc__socketmgr_getmaxsockets
isc_socketmgr_renderxml
-isc_socketmgr_setstats
+isc__socketmgr_setstats
isc_stats_create
isc_stats_attach
isc_stats_detach
@@ -482,27 +488,27 @@ isc_symtab_destroy
isc_symtab_lookup
isc_symtab_undefine
isc_syslog_facilityfromstring
-isc_task_attach
-isc_task_beginexclusive
-isc_task_create
-isc_task_destroy
-isc_task_detach
-isc_task_endexclusive
-isc_task_getcurrenttime
-isc_task_getname
-isc_task_gettag
-isc_task_onshutdown
-isc_task_purge
-isc_task_purgeevent
-isc_task_purgerange
-isc_task_send
-isc_task_sendanddetach
-isc_task_setname
-isc_task_shutdown
-isc_task_unsend
-isc_task_unsendrange
-isc_taskmgr_create
-isc_taskmgr_destroy
+isc__task_attach
+isc__task_beginexclusive
+isc__task_create
+isc__task_destroy
+isc__task_detach
+isc__task_endexclusive
+isc__task_getcurrenttime
+isc__task_getname
+isc__task_gettag
+isc__task_onshutdown
+isc__task_purge
+isc__task_purgeevent
+isc__task_purgerange
+isc__task_send
+isc__task_sendanddetach
+isc__task_setname
+isc__task_shutdown
+isc__task_unsend
+isc__task_unsendrange
+isc__taskmgr_create
+isc__taskmgr_destroy
isc_taskmgr_renderxml
isc_taskpool_create
isc_taskpool_destroy
@@ -526,14 +532,14 @@ isc_time_seconds
isc_time_set
isc_time_settoepoch
isc_time_subtract
-isc_timer_attach
-isc_timer_create
-isc_timer_detach
-isc_timer_reset
-isc_timer_touch
-isc_timermgr_create
-isc_timermgr_destroy
-isc_timermgr_poke
+isc__timer_attach
+isc__timer_create
+isc__timer_detach
+isc__timer_reset
+isc__timer_touch
+isc__timermgr_create
+isc__timermgr_destroy
+isc__timermgr_poke
isc_win32os_majorversion
isc_win32os_minorversion
isc_win32os_servicepackmajor
diff --git a/lib/isc/win32/libisc.dsp b/lib/isc/win32/libisc.dsp
index c0ab28bc..6620613e 100644
--- a/lib/isc/win32/libisc.dsp
+++ b/lib/isc/win32/libisc.dsp
@@ -42,8 +42,8 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "./" /I "../../../" /I "../../../../libxml2-2.7.3/include" /I "include" /I "../include" /I "../noatomic/include" /I "win32" /I "../../isccfg/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /YX /FD /c
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "BIND9" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "./" /I "../../../" /I "../../../../libxml2-2.7.3/include" /I "include" /I "../include" /I "../noatomic/include" /I "win32" /I "../../isccfg/include" /D "BIND9" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -70,8 +70,8 @@ LINK32=link.exe
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "../../../../libxml2-2.7.3/include" /I "include" /I "../include" /I "../noatomic/include" /I "win32" /I "../../isccfg/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR /YX /FD /GZ /c
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "../../../../libxml2-2.7.3/include" /I "include" /I "../include" /I "../noatomic/include" /I "win32" /I "../../isccfg/include" /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -207,6 +207,14 @@ SOURCE=..\include\isc\assertions.h
# End Source File
# Begin Source File
+SOURCE=..\include\isc\backtrace.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\isc\backtrace-emptytbl.h
+# End Source File
+# Begin Source File
+
SOURCE=..\include\isc\base32.h
# End Source File
# Begin Source File
@@ -579,6 +587,14 @@ SOURCE=..\assertions.c
# End Source File
# Begin Source File
+SOURCE=..\backtrace.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\backtrace-emptytbl.c
+# End Source File
+# Begin Source File
+
SOURCE=..\base32.c
# End Source File
# Begin Source File
diff --git a/lib/isc/win32/libisc.mak b/lib/isc/win32/libisc.mak
index 1397e5e9..4bd5d1a7 100644
--- a/lib/isc/win32/libisc.mak
+++ b/lib/isc/win32/libisc.mak
@@ -116,6 +116,8 @@ ALL : "..\..\..\Build\Release\libisc.dll"
CLEAN :
-@erase "$(INTDIR)\app.obj"
-@erase "$(INTDIR)\assertions.obj"
+ -@erase "$(INTDIR)\backtrace.obj"
+ -@erase "$(INTDIR)\backtrace-emptytbl.obj"
-@erase "$(INTDIR)\base32.obj"
-@erase "$(INTDIR)\base64.obj"
-@erase "$(INTDIR)\bitstring.obj"
@@ -198,7 +200,7 @@ CLEAN :
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/noatomic/include" /I "win32" /I "../../isccfg/include" /I "../../../../libxml2-2.7.3/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /Fp"$(INTDIR)\libisc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/noatomic/include" /I "win32" /I "../../isccfg/include" /I "../../../../libxml2-2.7.3/include" /D "BIND9" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /Fp"$(INTDIR)\libisc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc"
@@ -236,6 +238,8 @@ LINK32_OBJS= \
"$(INTDIR)\version.obj" \
"$(INTDIR)\win32os.obj" \
"$(INTDIR)\assertions.obj" \
+ "$(INTDIR)\backtrace.obj" \
+ "$(INTDIR)\backtrace-emptytbl.obj" \
"$(INTDIR)\base32.obj" \
"$(INTDIR)\base64.obj" \
"$(INTDIR)\bitstring.obj" \
@@ -307,6 +311,10 @@ CLEAN :
-@erase "$(INTDIR)\app.sbr"
-@erase "$(INTDIR)\assertions.obj"
-@erase "$(INTDIR)\assertions.sbr"
+ -@erase "$(INTDIR)\backtrace.obj"
+ -@erase "$(INTDIR)\backtrace-emptytbl.obj"
+ -@erase "$(INTDIR)\backtrace.sbr"
+ -@erase "$(INTDIR)\backtrace-emptytbl.sbr"
-@erase "$(INTDIR)\base32.obj"
-@erase "$(INTDIR)\base32.sbr"
-@erase "$(INTDIR)\base64.obj"
@@ -467,7 +475,7 @@ CLEAN :
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/noatomic/include" /I "win32" /I "../../isccfg/include" /I "../../../../libxml2-2.7.3/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/noatomic/include" /I "win32" /I "../../isccfg/include" /I "../../../../libxml2-2.7.3/include" /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc"
@@ -499,6 +507,8 @@ BSC32_SBRS= \
"$(INTDIR)\version.sbr" \
"$(INTDIR)\win32os.sbr" \
"$(INTDIR)\assertions.sbr" \
+ "$(INTDIR)\backtrace.sbr" \
+ "$(INTDIR)\backtrace-emptytbl.sbr" \
"$(INTDIR)\base32.sbr" \
"$(INTDIR)\base64.sbr" \
"$(INTDIR)\bitstring.sbr" \
@@ -585,6 +595,8 @@ LINK32_OBJS= \
"$(INTDIR)\version.obj" \
"$(INTDIR)\win32os.obj" \
"$(INTDIR)\assertions.obj" \
+ "$(INTDIR)\backtrace.obj" \
+ "$(INTDIR)\backtrace-emptytbl.obj" \
"$(INTDIR)\base32.obj" \
"$(INTDIR)\base64.obj" \
"$(INTDIR)\bitstring.obj" \
@@ -1102,6 +1114,42 @@ SOURCE=..\assertions.c
!ENDIF
+SOURCE=..\backtrace.c
+
+!IF "$(CFG)" == "libisc - Win32 Release"
+
+
+"$(INTDIR)\backtrace.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "libisc - Win32 Debug"
+
+
+"$(INTDIR)\backtrace.obj" "$(INTDIR)\backtrace.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=..\backtrace-emptytbl.c
+
+!IF "$(CFG)" == "libisc - Win32 Release"
+
+
+"$(INTDIR)\backtrace-emptytbl.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "libisc - Win32 Debug"
+
+
+"$(INTDIR)\backtrace-emptytbl.obj" "$(INTDIR)\backtrace-emptytbl.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
SOURCE=..\base32.c
!IF "$(CFG)" == "libisc - Win32 Release"
diff --git a/lib/isc/win32/net.c b/lib/isc/win32/net.c
index 3785f8ab..b88349d1 100644
--- a/lib/isc/win32/net.c
+++ b/lib/isc/win32/net.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: net.c,v 1.18 2008/08/08 05:06:49 marka Exp $ */
+/* $Id: net.c,v 1.20 2009/09/08 23:41:50 tbox Exp $ */
#include <config.h>
@@ -197,7 +197,7 @@ try_ipv6only(void) {
ipv6only_result = ISC_R_SUCCESS;
close:
- closeocket(s);
+ closesocket(s);
return;
#endif /* IPV6_V6ONLY */
}
diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c
index e60618cd..459e286f 100644
--- a/lib/isc/win32/socket.c
+++ b/lib/isc/win32/socket.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.76 2009/07/17 06:25:44 each Exp $ */
+/* $Id: socket.c,v 1.78 2009/09/02 18:32:25 each Exp $ */
/* This code uses functions which are only available on Server 2003 and
* higher, and Windows XP and higher.
@@ -1594,7 +1594,7 @@ free_socket(isc_socket_t **sockp, int lineno) {
* in 'socketp'.
*/
isc_result_t
-isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
+isc__socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
isc_socket_t **socketp) {
isc_socket_t *sock = NULL;
isc_result_t result;
@@ -1774,7 +1774,7 @@ isc_socket_open(isc_socket_t *sock) {
* Attach to a socket. Caller must explicitly detach when it is done.
*/
void
-isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
+isc__socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
REQUIRE(VALID_SOCKET(sock));
REQUIRE(socketp != NULL && *socketp == NULL);
@@ -1791,7 +1791,7 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
* up by destroying the socket.
*/
void
-isc_socket_detach(isc_socket_t **socketp) {
+isc__socket_detach(isc_socket_t **socketp) {
isc_socket_t *sock;
isc_boolean_t kill_socket = ISC_FALSE;
@@ -2434,13 +2434,13 @@ SocketIoThread(LPVOID ThreadContext) {
* Create a new socket manager.
*/
isc_result_t
-isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
+isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
return (isc_socketmgr_create2(mctx, managerp, 0));
}
isc_result_t
-isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
- unsigned int maxsocks)
+isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks)
{
isc_socketmgr_t *manager;
isc_result_t result;
@@ -2489,7 +2489,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
}
isc_result_t
-isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
+isc__socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
REQUIRE(VALID_MANAGER(manager));
REQUIRE(nsockp != NULL);
@@ -2497,7 +2497,7 @@ isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
}
void
-isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
+isc__socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
REQUIRE(VALID_MANAGER(manager));
REQUIRE(ISC_LIST_EMPTY(manager->socklist));
REQUIRE(manager->stats == NULL);
@@ -2507,7 +2507,7 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
}
void
-isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
+isc__socketmgr_destroy(isc_socketmgr_t **managerp) {
isc_socketmgr_t *manager;
int i;
isc_mem_t *mctx;
@@ -2635,7 +2635,7 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
}
isc_result_t
-isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
unsigned int minimum, isc_task_t *task,
isc_taskaction_t action, const void *arg)
{
@@ -2705,8 +2705,9 @@ isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
}
isc_result_t
-isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+isc__socket_recv(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
{
isc_socketevent_t *dev;
isc_socketmgr_t *manager;
@@ -2742,9 +2743,9 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
}
isc_result_t
-isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
- unsigned int minimum, isc_task_t *task,
- isc_socketevent_t *event, unsigned int flags)
+isc__socket_recv2(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags)
{
isc_result_t ret;
@@ -2852,8 +2853,8 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
}
isc_result_t
-isc_socket_send(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+isc__socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
/*
* REQUIRE() checking is performed in isc_socket_sendto().
@@ -2863,9 +2864,9 @@ isc_socket_send(isc_socket_t *sock, isc_region_t *region,
}
isc_result_t
-isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+isc__socket_sendto(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
{
isc_socketevent_t *dev;
isc_socketmgr_t *manager;
@@ -2906,17 +2907,17 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
}
isc_result_t
-isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
return (isc_socket_sendtov(sock, buflist, task, action, arg, NULL,
NULL));
}
isc_result_t
-isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
{
isc_socketevent_t *dev;
isc_socketmgr_t *manager;
@@ -2969,10 +2970,10 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
}
isc_result_t
-isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
- isc_socketevent_t *event, unsigned int flags)
+isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags)
{
isc_result_t ret;
@@ -3004,8 +3005,8 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
}
isc_result_t
-isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
- unsigned int options) {
+isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options) {
int bind_errno;
char strbuf[ISC_STRERRORSIZE];
int on = 1;
@@ -3070,7 +3071,7 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
}
isc_result_t
-isc_socket_filter(isc_socket_t *sock, const char *filter) {
+isc__socket_filter(isc_socket_t *sock, const char *filter) {
UNUSED(sock);
UNUSED(filter);
@@ -3089,7 +3090,7 @@ isc_socket_filter(isc_socket_t *sock, const char *filter) {
* as well keep things simple rather than having to track them.
*/
isc_result_t
-isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
+isc__socket_listen(isc_socket_t *sock, unsigned int backlog) {
char strbuf[ISC_STRERRORSIZE];
REQUIRE(VALID_SOCKET(sock));
@@ -3134,8 +3135,8 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
* This should try to do aggressive accept() XXXMLG
*/
isc_result_t
-isc_socket_accept(isc_socket_t *sock,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+isc__socket_accept(isc_socket_t *sock,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
isc_socket_newconnev_t *adev;
isc_socketmgr_t *manager;
@@ -3245,8 +3246,8 @@ isc_socket_accept(isc_socket_t *sock,
}
isc_result_t
-isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
char strbuf[ISC_STRERRORSIZE];
isc_socket_connev_t *cdev;
@@ -3360,7 +3361,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
}
isc_result_t
-isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
isc_result_t result;
REQUIRE(VALID_SOCKET(sock));
@@ -3390,7 +3391,7 @@ isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
}
isc_result_t
-isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+isc__socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
ISC_SOCKADDR_LEN_T len;
isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
@@ -3437,7 +3438,7 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
* queued for task "task" of type "how". "how" is a bitmask.
*/
void
-isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
+isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
REQUIRE(VALID_SOCKET(sock));
@@ -3563,7 +3564,7 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
}
isc_sockettype_t
-isc_socket_gettype(isc_socket_t *sock) {
+isc__socket_gettype(isc_socket_t *sock) {
isc_sockettype_t type;
REQUIRE(VALID_SOCKET(sock));
@@ -3584,7 +3585,7 @@ isc_socket_gettype(isc_socket_t *sock) {
}
isc_boolean_t
-isc_socket_isbound(isc_socket_t *sock) {
+isc__socket_isbound(isc_socket_t *sock) {
isc_boolean_t val;
REQUIRE(VALID_SOCKET(sock));
@@ -3607,7 +3608,7 @@ isc_socket_isbound(isc_socket_t *sock) {
}
void
-isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
+isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
#if defined(IPV6_V6ONLY)
int onoff = yes ? 1 : 0;
#else
@@ -3625,14 +3626,14 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
}
void
-isc_socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active) {
+isc__socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active) {
UNUSED(addr);
UNUSED(active);
}
isc_result_t
-isc_socket_permunix(isc_sockaddr_t *addr, isc_uint32_t perm,
- isc_uint32_t owner, isc_uint32_t group)
+isc__socket_permunix(isc_sockaddr_t *addr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group)
{
UNUSED(addr);
UNUSED(perm);
@@ -3642,7 +3643,7 @@ isc_socket_permunix(isc_sockaddr_t *addr, isc_uint32_t perm,
}
void
-isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
+isc__socket_setname(isc_socket_t *socket, const char *name, void *tag) {
/*
* Name 'socket'.
@@ -3658,12 +3659,12 @@ isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
}
const char *
-isc_socket_getname(isc_socket_t *socket) {
+isc__socket_getname(isc_socket_t *socket) {
return (socket->name);
}
void *
-isc_socket_gettag(isc_socket_t *socket) {
+isc__socket_gettag(isc_socket_t *socket) {
return (socket->tag);
}
@@ -3674,7 +3675,7 @@ isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) {
}
void
-isc__socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) {
+isc___socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) {
UNUSED(manager);
UNUSED(maxudp);
diff --git a/lib/isc/win32/time.c b/lib/isc/win32/time.c
index 0cf75cb0..aafd70b1 100644
--- a/lib/isc/win32/time.c
+++ b/lib/isc/win32/time.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: time.c,v 1.50 2009/07/17 23:47:41 tbox Exp $ */
+/* $Id: time.c,v 1.52 2009/08/14 07:51:08 marka Exp $ */
#include <config.h>
@@ -226,28 +226,30 @@ isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
isc_uint32_t
isc_time_seconds(const isc_time_t *t) {
- SYSTEMTIME st;
+ SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
+ FILETIME temp;
+ ULARGE_INTEGER i1, i2;
+ LONGLONG i3;
- /*
- * Convert the time to a SYSTEMTIME structure and the grab the
- * milliseconds
- */
- FileTimeToSystemTime(&t->absolute, &st);
+ SystemTimeToFileTime(&epoch, &temp);
- return ((isc_uint32_t)(st.wMilliseconds / 1000));
+ i1.LowPart = t->absolute.dwLowDateTime;
+ i1.HighPart = t->absolute.dwHighDateTime;
+ i2.LowPart = temp.dwLowDateTime;
+ i2.HighPart = temp.dwHighDateTime;
+
+ i3 = (i1.QuadPart - i2.QuadPart) / 10000000;
+
+ return ((isc_uint32_t)i3);
}
isc_uint32_t
isc_time_nanoseconds(const isc_time_t *t) {
- SYSTEMTIME st;
-
- /*
- * Convert the time to a SYSTEMTIME structure and the grab the
- * milliseconds
- */
- FileTimeToSystemTime(&t->absolute, &st);
+ ULARGE_INTEGER i;
- return ((isc_uint32_t)(st.wMilliseconds * 1000000));
+ i.LowPart = t->absolute.dwLowDateTime;
+ i.HighPart = t->absolute.dwHighDateTime;
+ return ((isc_uint32_t)(i.QuadPart % 10000000) * 100);
}
void
diff --git a/lib/isccc/Makefile.in b/lib/isccc/Makefile.in
index 5dcc2251..31713e1a 100644
--- a/lib/isccc/Makefile.in
+++ b/lib/isccc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001, 2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.9 2007/06/19 23:47:21 tbox Exp $
+# $Id: Makefile.in,v 1.11 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,7 +27,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCC_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@
diff --git a/lib/isccfg/Makefile.in b/lib/isccfg/Makefile.in
index 6dcacdd3..d7dbb65a 100644
--- a/lib/isccfg/Makefile.in
+++ b/lib/isccfg/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.18 2007/06/19 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.20 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,7 +27,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES}
-CDEFINES = @USE_DLZ@
+CDEFINES = -DBIND9 @USE_DLZ@
CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@
diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c
index 3fc1070a..2b771944 100644
--- a/lib/isccfg/aclconf.c
+++ b/lib/isccfg/aclconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: aclconf.c,v 1.24 2009/01/18 23:48:14 tbox Exp $ */
+/* $Id: aclconf.c,v 1.25 2009/09/01 00:22:28 jinmei Exp $ */
#include <config.h>
@@ -150,7 +150,7 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx,
isc_buffer_add(&buf, keylen);
dns_fixedname_init(&fixname);
result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(keyobj, lctx, ISC_LOG_WARNING,
"key name '%s' is not a valid domain name",
diff --git a/lib/isccfg/dnsconf.c b/lib/isccfg/dnsconf.c
new file mode 100644
index 00000000..704d383a
--- /dev/null
+++ b/lib/isccfg/dnsconf.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: dnsconf.c,v 1.4 2009/09/02 23:48:03 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isccfg/cfg.h>
+#include <isccfg/grammar.h>
+
+/*%
+ * A trusted key, as used in the "trusted-keys" statement.
+ */
+static cfg_tuplefielddef_t trustedkey_fields[] = {
+ { "name", &cfg_type_astring, 0 },
+ { "flags", &cfg_type_uint32, 0 },
+ { "protocol", &cfg_type_uint32, 0 },
+ { "algorithm", &cfg_type_uint32, 0 },
+ { "key", &cfg_type_qstring, 0 },
+ { NULL, NULL, 0 }
+};
+
+static cfg_type_t cfg_type_trustedkey = {
+ "trustedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, trustedkey_fields
+};
+
+static cfg_type_t cfg_type_trustedkeys = {
+ "trusted-keys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_trustedkey
+};
+
+/*%
+ * Clauses that can be found within the top level of the dns.conf
+ * file only.
+ */
+static cfg_clausedef_t
+dnsconf_clauses[] = {
+ { "trusted-keys", &cfg_type_trustedkeys, CFG_CLAUSEFLAG_MULTI },
+ { NULL, NULL, 0 }
+};
+
+/*% The top-level dns.conf syntax. */
+
+static cfg_clausedef_t *
+dnsconf_clausesets[] = {
+ dnsconf_clauses,
+ NULL
+};
+
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_dnsconf = {
+ "dnsconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
+ &cfg_rep_map, dnsconf_clausesets
+};
diff --git a/lib/isccfg/include/isccfg/dnsconf.h b/lib/isccfg/include/isccfg/dnsconf.h
new file mode 100644
index 00000000..edc5e503
--- /dev/null
+++ b/lib/isccfg/include/isccfg/dnsconf.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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: dnsconf.h,v 1.3 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISCCFG_NAMEDCONF_H
+#define ISCCFG_NAMEDCONF_H 1
+
+/*! \file
+ * \brief
+ * This module defines the named.conf, rndc.conf, and rndc.key grammars.
+ */
+
+#include <isccfg/cfg.h>
+
+/*
+ * Configuration object types.
+ */
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_dnsconf;
+/*%< A complete dns.conf file. */
+
+#endif /* ISCCFG_CFG_H */
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index c8b43309..c2f89983 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.c,v 1.103 2009/07/29 17:52:00 each Exp $ */
+/* $Id: namedconf.c,v 1.105 2009/09/02 16:10:03 each Exp $ */
/*! \file */
@@ -428,7 +428,7 @@ static cfg_type_t cfg_type_category = {
/*%
- * A dnssec key, as used in the "trusted-keys" or "managed-keys" statement.
+ * A dnssec key, as used in the "trusted-keys" statement.
*/
static cfg_tuplefielddef_t dnsseckey_fields[] = {
{ "name", &cfg_type_astring, 0 },
@@ -443,6 +443,24 @@ static cfg_type_t cfg_type_dnsseckey = {
&cfg_rep_tuple, dnsseckey_fields
};
+/*%
+ * A managed key initialization specifier, as used in the
+ * "managed-keys" statement.
+ */
+static cfg_tuplefielddef_t managedkey_fields[] = {
+ { "name", &cfg_type_astring, 0 },
+ { "init", &cfg_type_ustring, 0 }, /* must be literal "initial-key" */
+ { "flags", &cfg_type_uint32, 0 },
+ { "protocol", &cfg_type_uint32, 0 },
+ { "algorithm", &cfg_type_uint32, 0 },
+ { "key", &cfg_type_qstring, 0 },
+ { NULL, NULL, 0 }
+};
+static cfg_type_t cfg_type_managedkey = {
+ "managedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, managedkey_fields
+};
+
static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring };
static cfg_type_t cfg_type_optional_wild_class = {
@@ -530,12 +548,25 @@ static cfg_type_t cfg_type_keylist = {
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring
};
-/*% A list of dnssec keys, as in "trusted-keys" and "managed-keys" stanzas */
+/*% A list of dnssec keys, as in "trusted-keys" */
static cfg_type_t cfg_type_dnsseckeys = {
"dnsseckeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_dnsseckey
};
+/*%
+ * A list of managed key entries, as in "trusted-keys". Currently
+ * (9.7.0) this has a format similar to dnssec keys, except the keyname
+ * is followed by the keyword "initial-key". In future releases, this
+ * keyword may take other values indicating different methods for the
+ * key to be initialized.
+ */
+
+static cfg_type_t cfg_type_managedkeys = {
+ "managedkeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_managedkey
+};
+
static const char *forwardtype_enums[] = { "first", "only", NULL };
static cfg_type_t cfg_type_forwardtype = {
"forwardtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
@@ -762,7 +793,7 @@ namedconf_or_view_clauses[] = {
{ "dlz", &cfg_type_dynamically_loadable_zones, 0 },
{ "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI },
{ "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
- { "managed-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
+ { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI },
{ NULL, NULL, 0 }
};
@@ -772,7 +803,7 @@ namedconf_or_view_clauses[] = {
static cfg_clausedef_t
bindkeys_clauses[] = {
{ "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
- { "managed-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
+ { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI },
{ NULL, NULL, 0 }
};
@@ -1132,7 +1163,6 @@ zone_only_clauses[] = {
{ "masters", &cfg_type_namesockaddrkeylist, 0 },
{ "pubkey", &cfg_type_pubkey,
CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE },
- { "ddns-autoconf", &cfg_type_boolean, 0 },
{ "update-policy", &cfg_type_updatepolicy, 0 },
{ "database", &cfg_type_astring, 0 },
{ "delegation-only", &cfg_type_boolean, 0 },
diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c
index 1314e7a5..e76a53df 100644
--- a/lib/isccfg/parser.c
+++ b/lib/isccfg/parser.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: parser.c,v 1.131 2009/06/11 23:47:55 tbox Exp $ */
+/* $Id: parser.c,v 1.132 2009/09/02 23:43:54 each Exp $ */
/*! \file */
@@ -29,12 +29,12 @@
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/netaddr.h>
+#include <isc/netscope.h>
#include <isc/print.h>
#include <isc/string.h>
#include <isc/sockaddr.h>
-#include <isc/netscope.h>
-#include <isc/util.h>
#include <isc/symtab.h>
+#include <isc/util.h>
#include <isccfg/cfg.h>
#include <isccfg/grammar.h>
diff --git a/lib/lwres/context.c b/lib/lwres/context.c
index 32233ff7..64bdaa10 100644
--- a/lib/lwres/context.c
+++ b/lib/lwres/context.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: context.c,v 1.52 2008/12/17 23:47:58 tbox Exp $ */
+/* $Id: context.c,v 1.55 2009/09/02 23:48:03 tbox Exp $ */
/*! \file context.c
lwres_context_create() creates a #lwres_context_t structure for use in
@@ -471,6 +471,17 @@ lwres_context_sendrecv(lwres_context_t *ctx,
result = lwres_context_send(ctx, sendbase, sendlen);
if (result != LWRES_R_SUCCESS)
return (result);
+
+ /*
+ * If this is not checked, select() can overflow,
+ * causing corruption elsewhere.
+ */
+ if (ctx->sock >= (int)FD_SETSIZE) {
+ close(ctx->sock);
+ ctx->sock = -1;
+ return (LWRES_R_IOERROR);
+ }
+
again:
FD_ZERO(&readfds);
FD_SET(ctx->sock, &readfds);
diff --git a/lib/lwres/getipnode.c b/lib/lwres/getipnode.c
index a6c50c28..3bd82177 100644
--- a/lib/lwres/getipnode.c
+++ b/lib/lwres/getipnode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getipnode.c,v 1.42 2007/06/18 23:47:51 tbox Exp $ */
+/* $Id: getipnode.c,v 1.47 2009/09/01 23:47:45 tbox Exp $ */
/*! \file */
@@ -23,7 +23,7 @@
* These functions perform thread safe, protocol independent
* nodename-to-address and address-to-nodename translation as defined in
* RFC2553. This use a struct hostent which is defined in namedb.h:
- *
+ *
* \code
* struct hostent {
* char *h_name; // official name of host
@@ -34,90 +34,90 @@
* };
* #define h_addr h_addr_list[0] // address, for backward compatibility
* \endcode
- *
+ *
* The members of this structure are:
- *
+ *
* \li h_name:
* The official (canonical) name of the host.
- *
+ *
* \li h_aliases:
* A NULL-terminated array of alternate names (nicknames) for the
* host.
- *
+ *
* \li h_addrtype:
* The type of address being returned - usually PF_INET or
* PF_INET6.
- *
+ *
* \li h_length:
* The length of the address in bytes.
- *
+ *
* \li h_addr_list:
* A NULL terminated array of network addresses for the host. Host
* addresses are returned in network byte order.
- *
+ *
* lwres_getipnodebyname() looks up addresses of protocol family af for
* the hostname name. The flags parameter contains ORed flag bits to
* specify the types of addresses that are searched for, and the types of
* addresses that are returned. The flag bits are:
- *
+ *
* \li #AI_V4MAPPED:
* This is used with an af of #AF_INET6, and causes IPv4 addresses
* to be returned as IPv4-mapped IPv6 addresses.
- *
+ *
* \li #AI_ALL:
* This is used with an af of #AF_INET6, and causes all known
* addresses (IPv6 and IPv4) to be returned. If #AI_V4MAPPED is
* also set, the IPv4 addresses are return as mapped IPv6
* addresses.
- *
+ *
* \li #AI_ADDRCONFIG:
* Only return an IPv6 or IPv4 address if here is an active
* network interface of that type. This is not currently
* implemented in the BIND 9 lightweight resolver, and the flag is
* ignored.
- *
+ *
* \li #AI_DEFAULT:
* This default sets the #AI_V4MAPPED and #AI_ADDRCONFIG flag bits.
- *
+ *
* lwres_getipnodebyaddr() performs a reverse lookup of address src which
* is len bytes long. af denotes the protocol family, typically PF_INET
* or PF_INET6.
- *
+ *
* lwres_freehostent() releases all the memory associated with the struct
* hostent pointer. Any memory allocated for the h_name, h_addr_list
* and h_aliases is freed, as is the memory for the hostent structure
* itself.
- *
+ *
* \section getipnode_return Return Values
- *
+ *
* If an error occurs, lwres_getipnodebyname() and
* lwres_getipnodebyaddr() set *error_num to an appropriate error code
* and the function returns a NULL pointer. The error codes and their
* meanings are defined in \link netdb.h <lwres/netdb.h>\endlink:
- *
+ *
* \li #HOST_NOT_FOUND:
* No such host is known.
- *
+ *
* \li #NO_ADDRESS:
* The server recognised the request and the name but no address
* is available. Another type of request to the name server for
* the domain might return an answer.
- *
+ *
* \li #TRY_AGAIN:
* A temporary and possibly transient error occurred, such as a
* failure of a server to respond. The request may succeed if
* retried.
- *
+ *
* \li #NO_RECOVERY:
* An unexpected failure occurred, and retrying the request is
* pointless.
- *
+ *
* lwres_hstrerror() translates these error codes to suitable error
* messages.
- *
+ *
* \section getipnode_see See Also
- *
- * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
+ *
+ * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
*/
#include <config.h>
@@ -146,21 +146,21 @@ LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#ifndef IN6_IS_ADDR_V4COMPAT
static const unsigned char in6addr_compat[12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
- ((x)->s6_addr[12] != 0 || \
- (x)->s6_addr[13] != 0 || \
- (x)->s6_addr[14] != 0 || \
- ((x)->s6_addr[15] != 0 && \
- (x)->s6_addr[15] != 1)))
+ ((x)->s6_addr[12] != 0 || \
+ (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && \
+ (x)->s6_addr[15] != 1)))
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
#endif
static const unsigned char in6addr_mapped[12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
};
/***
@@ -202,7 +202,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
struct in6_addr in6;
struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
int v4 = 0, v6 = 0;
- int tmp_err;
+ int tmp_err = 0;
lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL;
int n;
@@ -275,7 +275,6 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
tmp_err = NO_RECOVERY;
if (have_v6 && af == AF_INET6) {
-
n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
if (n == 0) {
he1 = hostfromname(by, AF_INET6);
@@ -285,7 +284,12 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
goto cleanup;
}
} else {
- tmp_err = HOST_NOT_FOUND;
+ if (n == LWRES_R_NOTFOUND)
+ tmp_err = HOST_NOT_FOUND;
+ else {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
}
}
@@ -437,9 +441,15 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
if (n != 0) {
lwres_conf_clear(lwrctx);
lwres_context_destroy(&lwrctx);
- *error_num = HOST_NOT_FOUND;
+
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+
return (NULL);
}
+
he1 = hostfromaddr(by, AF_INET6, src);
lwres_gnbaresponse_free(lwrctx, &by);
if (he1 == NULL)
@@ -492,7 +502,7 @@ lwres_freehostent(struct hostent *he) {
*/
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
- !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
+ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
#ifdef __hpux
#define lifc_len iflc_len
@@ -504,7 +514,7 @@ lwres_freehostent(struct hostent *he) {
#define ISC_HAVE_LIFC_FLAGS 1
#define LIFCONF lifconf
#endif
-
+
#ifdef __hpux
#define lifr_addr iflr_addr
#define lifr_name iflr_name
@@ -557,7 +567,7 @@ scan_interfaces6(int *have_v4, int *have_v6) {
/*
* Some OS's just return what will fit rather
* than set EINVAL if the buffer is too small
- * to fit all the interfaces in. If
+ * to fit all the interfaces in. If
* lifc.lifc_len is too near to the end of the
* buffer we will grow it just in case and
* retry.
@@ -619,13 +629,13 @@ scan_interfaces6(int *have_v4, int *have_v6) {
if ((lifreq.lifr_flags & IFF_UP) == 0)
break;
*have_v4 = 1;
- }
+ }
break;
case AF_INET6:
if (*have_v6 == 0) {
memcpy(&in6,
&((struct sockaddr_in6 *)
- &lifreq.lifr_addr)->sin6_addr,
+ &lifreq.lifr_addr)->sin6_addr,
sizeof(in6));
if (memcmp(&in6, &in6addr_any,
sizeof(in6)) == 0)
@@ -675,7 +685,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
InitSockets();
#endif
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
- !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
+ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
/*
* Try to scan the interfaces using IPv6 ioctls().
*/
@@ -721,7 +731,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
/*
* Some OS's just return what will fit rather
* than set EINVAL if the buffer is too small
- * to fit all the interfaces in. If
+ * to fit all the interfaces in. If
* ifc.ifc_len is too near to the end of the
* buffer we will grow it just in case and
* retry.
@@ -786,7 +796,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
if ((u.ifreq.ifr_flags & IFF_UP) == 0)
break;
*have_v4 = 1;
- }
+ }
break;
case AF_INET6:
if (*have_v6 == 0) {
diff --git a/lib/tests/Makefile.in b/lib/tests/Makefile.in
index 81b0bfbd..b336c9f3 100644
--- a/lib/tests/Makefile.in
+++ b/lib/tests/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001, 2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.25 2007/06/19 23:47:23 tbox Exp $
+# $Id: Makefile.in,v 1.27 2009/09/02 23:48:03 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -22,7 +22,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${TEST_INCLUDES}
-CDEFINES =
+CDEFINES = -DBIND9
CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@
diff --git a/make/rules.in b/make/rules.in
index 2effeef1..2bd67556 100644
--- a/make/rules.in
+++ b/make/rules.in
@@ -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.66 2009/01/10 23:47:28 tbox Exp $
+# $Id: rules.in,v 1.68 2009/09/01 18:40:25 jinmei Exp $
###
### Common Makefile rules for BIND 9.
@@ -35,6 +35,8 @@ sysconfdir = @sysconfdir@
localstatedir = @localstatedir@
mandir = @mandir@
datarootdir = @datarootdir@
+export_libdir = @export_libdir@
+export_includedir = @export_includedir@
DESTDIR =
@@ -122,7 +124,7 @@ ALL_CPPFLAGS = \
ALL_CFLAGS = ${EXT_CFLAGS} ${ALL_CPPFLAGS} ${CFLAGS} \
${ALWAYS_WARNINGS} ${STD_CWARNINGS} ${CWARNINGS}
-.c.@O@:
+@BIND9_CO_RULE@
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c $<
SHELL = @SHELL@
@@ -134,12 +136,83 @@ PURIFY = @PURIFY@
MKDEP = ${SHELL} ${top_builddir}/make/mkdep
+###
+### This is a template compound command to build an executable binary with
+### an internal symbol table.
+### This process is tricky. We first link all objects including a tentative
+### empty symbol table, then get a tentative list of symbols from the resulting
+### binary ($@tmp0). Next, we re-link all objects, but this time with the
+### symbol table just created ($tmp@1). The set of symbols should be the same,
+### but the corresponding addresses would be changed due to the difference on
+### the size of symbol tables. So we create the symbol table and re-create the
+### objects once again. Finally, we check the symbol table embedded in the
+### final binaryis consistent with the binary itself; otherwise the process is
+### terminated.
+###
+### To minimize the overhead of creating symbol tables, the autoconf switch
+### --enable-symtable takes an argument so that the symbol table can be created
+### on a per application basis: unless the argument is set to "all", the symbol
+### table is created only when a shell (environment) variable "MAKE_SYMTABLE" is
+### set to a non-null value in the rule to build the executable binary.
+###
+### Each Makefile.in that uses this macro is expected to define "LIBS" and
+### "NOSYMLIBS"; the former includes libisc with an empty symbol table, and
+### the latter includes libisc without the definition of a symbol table.
+### The rule to make the executable binary will look like this
+### binary@EXEEXT@: ${OBJS}
+### #export MAKE_SYMTABLE="yes"; \ <- enable if symtable is always needed
+### export BASEOBJS="${OBJS}"; \
+### ${FINALBUILDCMD}
+###
+### Normally, ${LIBS} includes all necessary libraries to build the binary;
+### there are some exceptions however, where the rule lists some of the
+### necessary libraries explicitly in addition to (or instead of) ${LIBS},
+### like this:
+### binary@EXEEXT@: ${OBJS}
+### cc -o $@ ${OBJS} ${OTHERLIB1} ${OTHERLIB2} ${lIBS}
+### in order to modify such a rule to use this compound command, a separate
+### variable "LIBS0" should be deinfed for the explicitly listed libraries,
+### while making sure ${LIBS} still includes libisc. So the above rule would
+### be modified as follows:
+### binary@EXEEXT@: ${OBJS}
+### export BASEOBJS="${OBJS}"; \
+### export LIBS0="${OTHERLIB1} ${OTHERLIB2}"; \
+### ${FINALBUILDCMD}
+### See bin/check/Makefile.in for a complete example of the use of LIBS0.
+###
+FINALBUILDCMD = if [ X"${MKSYMTBL_PROGRAM}" = X -o X"$${MAKE_SYMTABLE:-${ALWAYS_MAKE_SYMTABLE}}" = X ] ; then \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@ $${BASEOBJS} $${LIBS0} ${LIBS}; \
+ else \
+ rm -f $@tmp0; \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@tmp0 $${BASEOBJS} $${LIBS0} ${LIBS} || exit 1; \
+ rm -f $@-symtbl.c $@-symtbl.@O@; \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ -o $@-symtbl.c $@tmp0 || exit 1; \
+ $(MAKE) $@-symtbl.@O@ || exit 1; \
+ rm -f $@tmp1; \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@tmp1 $${BASEOBJS} $@-symtbl.@O@ $${LIBS0} ${NOSYMLIBS} || exit 1; \
+ rm -f $@-symtbl.c $@-symtbl.@O@; \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ -o $@-symtbl.c $@tmp1 || exit 1; \
+ $(MAKE) $@-symtbl.@O@ || exit 1; \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@tmp2 $${BASEOBJS} $@-symtbl.@O@ $${LIBS0} ${NOSYMLIBS}; \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ -o $@-symtbl2.c $@tmp2; \
+ diff $@-symtbl.c $@-symtbl2.c || exit 1;\
+ mv $@tmp2 $@; \
+ rm -f $@tmp0 $@tmp1 $@tmp2 $@-symtbl2.c; \
+ fi
+
cleandir: distclean
superclean: maintainer-clean
clean distclean maintainer-clean::
- rm -f *.@O@ *.o *.lo *.la core *.core .depend
- rm -rf .libs
+ rm -f *.@O@ *.o *.lo *.la core *.core *-symtbl.c *tmp0 *tmp1 *tmp2
+ rm -rf .depend .libs
distclean maintainer-clean::
rm -f Makefile
@@ -217,6 +290,16 @@ PDFLATEX = @PDFLATEX@
W3M = @W3M@
###
+### Script language program used to create internal symbol tables
+###
+MKSYMTBL_PROGRAM = @MKSYMTBL_PROGRAM@
+
+###
+### Switch to create internal symbol table selectively
+###
+ALWAYS_MAKE_SYMTABLE = @ALWAYS_MAKE_SYMTABLE@
+
+###
### DocBook -> HTML
### DocBook -> man page
###
diff --git a/util/mksymtbl.pl b/util/mksymtbl.pl
new file mode 100755
index 00000000..8ebc795c
--- /dev/null
+++ b/util/mksymtbl.pl
@@ -0,0 +1,127 @@
+#!/usr/bin/env perl
+#
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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.
+
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: mksymtbl.pl,v 1.3 2009/09/02 23:48:03 tbox Exp $
+
+use strict;
+use diagnostics;
+$^W = 1;
+
+my $rev = '$Id: mksymtbl.pl,v 1.3 2009/09/02 23:48:03 tbox Exp $';
+$rev =~ s/\$//g;
+$rev =~ s/,v//g;
+$rev =~ s/Id: //;
+
+use Getopt::Std;
+my %options;
+getopts('i:o:', \%options);
+
+my ($binname, $need_uscorefix, $outputfile, $nsyms, $ostype, $nm_prog);
+my %symmap;
+
+$binname = $ARGV[0];
+$need_uscorefix = 0;
+if ($options{'o'}) {
+ $outputfile = $options{'o'};
+} else {
+ $outputfile = "symtbl.c";
+}
+
+# OS-depending configuration
+$nm_prog = "nm";
+$ostype = `uname -s`;
+chop($ostype);
+if ($ostype eq "SunOS" || $ostype eq "HP-UX") {
+ $nm_prog = "/usr/ccs/bin/nm -x"
+}
+
+if ($options{'i'}) {
+ open(SYMBOLS, $options{'i'}) || die "failed to open $options{'i'}";
+} else {
+ open(SYMBOLS, "$nm_prog $binname |") ||
+ die "failed to invoke utility to get symbols";
+}
+open(TBLFILE, ">$outputfile") || die "failed to open output file: $outputfile";
+
+$nsyms = 0;
+while (<SYMBOLS>) {
+ my ($addr, $symbol) = (0, "");
+ if ($ostype eq "SunOS") {
+ if (/\[\d*\]\s*\|\s*0x([0-9a-f]*)\|\s*0x[0-9a-f]*\|FUNC\s*(.*)\|([^|]+)$/) {
+ next if ($2 =~ /UNDEF/); # skip undefined symbols
+ $addr = $1;
+ $symbol = $3;
+ chop($symbol);
+ }
+ } elsif ($ostype eq "HP-UX") {
+ if (/(\S*)\s*\|0x([0-9a-f]*)\|([^|]*\|entry|extern\|code)/) {
+ $addr = $2;
+ $symbol = $1;
+ # this filter catches a massive number of awkward
+ # symbols such as "$START$". we are not interested in
+ # those and ignore them.
+ next if ($symbol =~ /\$/);
+ }
+ } else {
+ # *BSDs, Linux, etc.
+ if (/([0-9a-f]*)\s[tT]\s(.*)/) {
+ ($addr, $symbol) = ($1, $2);
+ # heuristics: some compilers add a "_" to all program
+ # defined symbols. Detect and fix it for a well known
+ # symbol of "main".
+ $need_uscorefix = 1 if ($symbol eq "_main");
+ }
+ }
+ if ($symbol ne "") {
+ # XXX: HP-UX's nm can produce a duplicate entry for the same
+ # address. Ignore duplicate entries except the first one.
+ next if ($symmap{$addr});
+
+ $symmap{$addr} = $symbol;
+ $nsyms++;
+ }
+}
+
+print TBLFILE "/*\n * Generated by $rev \n */\n";
+print TBLFILE "#include <isc/backtrace.h>\n";
+print TBLFILE "const int isc__backtrace_nsymbols = $nsyms;\n";
+print TBLFILE "const isc_backtrace_symmap_t isc__backtrace_symtable[] = {\n";
+foreach (sort {hex($a) <=> hex($b)} keys(%symmap)) {
+ my ($addr, $symbol) = ($_, $symmap{$_});
+ if ($need_uscorefix && $symbol =~ /^_(.*)/) {
+ $symbol = $1;
+ }
+ print TBLFILE "\t{ (void *)0x$addr, \"$symbol\" },\n";
+}
+print TBLFILE "\t{ (void *)0x0, \"\" },\n";
+print TBLFILE "};\n";
+
+close(TBLFILE);
+close(SYMBOLS);
diff --git a/version b/version
index 80321bfc..05fab79b 100644
--- a/version
+++ b/version
@@ -1,4 +1,4 @@
-# $Id: version,v 1.46 2009/07/19 04:18:03 each Exp $
+# $Id: version,v 1.47 2009/09/02 06:41:31 each Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
@@ -7,4 +7,4 @@ MAJORVER=9
MINORVER=7
PATCHVER=0
RELEASETYPE=a
-RELEASEVER=2
+RELEASEVER=3
diff --git a/win32utils/readme1st.txt b/win32utils/readme1st.txt
index 15a8a661..bddc8e1c 100644
--- a/win32utils/readme1st.txt
+++ b/win32utils/readme1st.txt
@@ -2,7 +2,7 @@ Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
Copyright (C) 2001, 2003 Internet Software Consortium.
See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
-$Id: readme1st.txt,v 1.23 2009/06/22 23:47:53 tbox Exp $
+$Id: readme1st.txt,v 1.24 2009/09/01 06:51:47 marka Exp $
Release of BIND 9.7 for Windows and later.
@@ -11,7 +11,7 @@ This is a release of BIND 9.7 for Windows XP and later.
Important Kit Installation Information
As of release 9.3.0, BINDInstall requires that you install it under
-an account with restricted privileges. The installer will prompt
+a account with restricted privileges. The installer will prompt
you for an account name, the default is "named", and a password for
that account. It will also check for the existence of that account.
If it does not exist is will create it with only the privileges
@@ -28,6 +28,11 @@ or for master zones supporting dynamic updates. The account will
also need read access to the named.conf and any other file that it
needs to read.
+"NT AUTHORITY\LocalService" is also an acceptable account. This
+account is built into Windows and no password is required. Appropriate
+file permissions will also need to be set for "NT AUTHORITY\LocalService"
+similar to those that would have been required for the "named" account.
+
It is important that on Windows the directory directive is used in
the options section to tell BIND where to find the files used in
named.conf (default %WINDOWS%\system32\dns\etc\named.conf).
diff --git a/win32utils/win32-build.txt b/win32utils/win32-build.txt
index 4ee14fc8..699584d8 100644
--- a/win32utils/win32-build.txt
+++ b/win32utils/win32-build.txt
@@ -2,7 +2,7 @@ Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
Copyright (C) 2001, 2002 Internet Software Consortium.
See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
-$Id: win32-build.txt,v 1.15 2009/07/17 23:47:41 tbox Exp $
+$Id: win32-build.txt,v 1.16 2009/09/02 08:41:06 fdupont Exp $
BIND 9.7 for Win32 Source Build Instructions. 02-Jul-2009
@@ -80,7 +80,7 @@ directories:
cscript configure.js compiler=msvc vcmanifest=yes static=yes debug=no iconv=no
nmake /f Makefile.msvc libxml
-Step 2: Building BIND
+Step 3: Building BIND
You must build openssl and libxml2 first.