printf("-n name signer's subject emailAddress, default %s\n", P7SIGNER);
printf("-4 work using IPv4 only\n");
printf("-6 work using IPv6 only\n");
- printf("-f resolv.conf use given resolv.conf to resolve -u name\n");
- printf("-r root.hints use given root.hints to resolve -u name\n"
+ printf("-f resolv.conf use given resolv.conf\n");
+ printf("-r root.hints use given root.hints\n"
" builtin root hints are used by default\n");
+ printf("-R fallback from -f to root query on error\n");
printf("-v more verbose\n");
printf("-C conf debug, read config\n");
printf("-P port use port for https connect, default 443\n");
do_certupdate(const char* root_anchor_file, const char* root_cert_file,
const char* urlname, const char* xmlname, const char* p7sname,
const char* p7signer, const char* res_conf, const char* root_hints,
- const char* debugconf, int ip4only, int ip6only, int port,
- struct ub_result* dnskey)
+ const char* debugconf, int ip4only, int ip6only, int port)
{
STACK_OF(X509)* cert;
BIO *xml, *p7s;
#ifndef S_SPLINT_S
sk_X509_pop_free(cert, X509_free);
#endif
- ub_resolve_free(dnskey);
ip_list_free(ip_list);
return 1;
}
return 0;
}
+static struct ub_result *
+fetch_root_key(const char* root_anchor_file, const char* res_conf,
+ const char* root_hints, const char* debugconf,
+ int ip4only, int ip6only)
+{
+ struct ub_ctx* ctx;
+ struct ub_result* dnskey;
+
+ ctx = create_unbound_context(res_conf, root_hints, debugconf,
+ ip4only, ip6only);
+ add_5011_probe_root(ctx, root_anchor_file);
+ dnskey = prime_root_key(ctx);
+ ub_ctx_delete(ctx);
+ return dnskey;
+}
+
/** perform the unbound-anchor work */
static int
do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
const char* urlname, const char* xmlname, const char* p7sname,
const char* p7signer, const char* res_conf, const char* root_hints,
- const char* debugconf, int ip4only, int ip6only, int force, int port)
+ const char* debugconf, int ip4only, int ip6only, int force,
+ int res_conf_fallback, int port)
{
- struct ub_ctx* ctx;
struct ub_result* dnskey;
int used_builtin = 0;
+ int rcode;
/* see if builtin rootanchor needs to be provided, or if
* rootanchor is 'revoked-trust-point' */
/* make unbound context with 5011-probe for root anchor,
* and probe . DNSKEY */
- ctx = create_unbound_context(res_conf, root_hints, debugconf,
- ip4only, ip6only);
- add_5011_probe_root(ctx, root_anchor_file);
- dnskey = prime_root_key(ctx);
- ub_ctx_delete(ctx);
-
+ dnskey = fetch_root_key(root_anchor_file, res_conf,
+ root_hints, debugconf, ip4only, ip6only);
+ rcode = dnskey->rcode;
+
+ if (res_conf_fallback && res_conf && !dnskey->secure) {
+ if (verb) printf("%s failed, retrying direct\n", res_conf);
+ ub_resolve_free(dnskey);
+ /* try direct query without res_conf */
+ dnskey = fetch_root_key(root_anchor_file, NULL,
+ root_hints, debugconf, ip4only, ip6only);
+ if (rcode != 0 && dnskey->rcode == 0) {
+ res_conf = NULL;
+ rcode = 0;
+ }
+ }
+
/* if secure: exit */
if(dnskey->secure && !force) {
if(verb) printf("success: the anchor is ok\n");
return used_builtin;
}
if(force && verb) printf("debug cert update forced\n");
+ ub_resolve_free(dnskey);
/* if not (and NOERROR): check date and do certupdate */
- if((dnskey->rcode == 0 &&
+ if((rcode == 0 &&
probe_date_allows_certupdate(root_anchor_file)) || force) {
if(do_certupdate(root_anchor_file, root_cert_file, urlname,
xmlname, p7sname, p7signer, res_conf, root_hints,
- debugconf, ip4only, ip6only, port, dnskey))
+ debugconf, ip4only, ip6only, port))
return 1;
return used_builtin;
}
if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n");
- ub_resolve_free(dnskey);
return used_builtin;
}
const char* root_hints = NULL;
const char* debugconf = NULL;
int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
+ int res_conf_fallback = 0;
/* parse the options */
- while( (c=getopt(argc, argv, "46C:FP:a:c:f:hln:r:s:u:vx:")) != -1) {
+ while( (c=getopt(argc, argv, "46C:FRP:a:c:f:hln:r:s:u:vx:")) != -1) {
switch(c) {
case 'l':
dolist = 1;
case 'r':
root_hints = optarg;
break;
+ case 'R':
+ res_conf_fallback = 1;
+ break;
case 'C':
debugconf = optarg;
break;
return do_root_update_work(root_anchor_file, root_cert_file, urlname,
xmlname, p7sname, p7signer, res_conf, root_hints, debugconf,
- ip4only, ip6only, force, port);
+ ip4only, ip6only, force, res_conf_fallback, port);
}