mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
dirmngr: Add per-session verify callback to http.c
* dirmngr/http.h (http_verify_cb_t): New type. * dirmngr/http.c (http_session_s): Add fields flags, verify_cb, and verify_cb_value. (http_session_new): Remove arg tls_priority. Add args verify_cb and verify-cb_value. Store them in the session object. (send_request): Use per-session verify callback. (http_verify_server_credentials) [HTTP_USE_NTBTLS]: Return GPG_ERR_NOT_IMPLEMENTED. * dirmngr/ks-engine-hkp.c (send_request): Adjust for changed http_session_new. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/t-http.c (main): Ditto. * dirmngr/server.c (do_get_cert_local): Replace xmalloc by malloc. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
cd32ebd152
commit
a74902cccd
@ -221,6 +221,13 @@ struct http_session_s
|
|||||||
/* A callback function to log details of TLS certifciates. */
|
/* A callback function to log details of TLS certifciates. */
|
||||||
void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
|
void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
|
||||||
const void **, size_t *);
|
const void **, size_t *);
|
||||||
|
|
||||||
|
/* The flags passed to the session object. */
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
/* A per-session TLS verification callback. */
|
||||||
|
http_verify_cb_t verify_cb;
|
||||||
|
void *verify_cb_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -606,8 +613,9 @@ http_session_release (http_session_t sess)
|
|||||||
* HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
|
* HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
|
||||||
*/
|
*/
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
http_session_new (http_session_t *r_session, const char *tls_priority,
|
http_session_new (http_session_t *r_session,
|
||||||
const char *intended_hostname, unsigned int flags)
|
const char *intended_hostname, unsigned int flags,
|
||||||
|
http_verify_cb_t verify_cb, void *verify_cb_value)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
http_session_t sess;
|
http_session_t sess;
|
||||||
@ -618,6 +626,9 @@ http_session_new (http_session_t *r_session, const char *tls_priority,
|
|||||||
if (!sess)
|
if (!sess)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
sess->refcount = 1;
|
sess->refcount = 1;
|
||||||
|
sess->flags = flags;
|
||||||
|
sess->verify_cb = verify_cb;
|
||||||
|
sess->verify_cb_value = verify_cb_value;
|
||||||
|
|
||||||
#if HTTP_USE_NTBTLS
|
#if HTTP_USE_NTBTLS
|
||||||
{
|
{
|
||||||
@ -630,8 +641,6 @@ http_session_new (http_session_t *r_session, const char *tls_priority,
|
|||||||
size_t buflen;
|
size_t buflen;
|
||||||
char *pemname;
|
char *pemname;
|
||||||
|
|
||||||
(void)tls_priority;
|
|
||||||
|
|
||||||
pemname = make_filename_try (gnupg_datadir (),
|
pemname = make_filename_try (gnupg_datadir (),
|
||||||
"sks-keyservers.netCA.pem", NULL);
|
"sks-keyservers.netCA.pem", NULL);
|
||||||
if (!pemname)
|
if (!pemname)
|
||||||
@ -799,7 +808,7 @@ http_session_new (http_session_t *r_session, const char *tls_priority,
|
|||||||
gnutls_transport_set_ptr (sess->tls_session, NULL);
|
gnutls_transport_set_ptr (sess->tls_session, NULL);
|
||||||
|
|
||||||
rc = gnutls_priority_set_direct (sess->tls_session,
|
rc = gnutls_priority_set_direct (sess->tls_session,
|
||||||
tls_priority? tls_priority : "NORMAL",
|
"NORMAL",
|
||||||
&errpos);
|
&errpos);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@ -1823,10 +1832,27 @@ send_request (http_t hd, const char *httphost, const char *auth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hd->session->verify.done = 0;
|
hd->session->verify.done = 0;
|
||||||
if (tls_callback)
|
|
||||||
|
|
||||||
|
/* Try the available verify callbacks until one returns success
|
||||||
|
* or a real error. */
|
||||||
|
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
|
if (hd->session->verify_cb)
|
||||||
|
err = hd->session->verify_cb (hd->session->verify_cb_value,
|
||||||
|
hd, hd->session,
|
||||||
|
(hd->flags | hd->session->flags),
|
||||||
|
hd->session->tls_session);
|
||||||
|
|
||||||
|
if (tls_callback
|
||||||
|
&& gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
|
||||||
|
&& gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
|
||||||
err = tls_callback (hd, hd->session, 0);
|
err = tls_callback (hd, hd->session, 0);
|
||||||
else
|
|
||||||
|
if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
|
||||||
|
&& gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
|
||||||
err = http_verify_server_credentials (hd->session);
|
err = http_verify_server_credentials (hd->session);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_info ("TLS connection authentication failed: %s <%s>\n",
|
log_info ("TLS connection authentication failed: %s <%s>\n",
|
||||||
@ -1834,6 +1860,7 @@ send_request (http_t hd, const char *httphost, const char *auth,
|
|||||||
xfree (proxy_authstr);
|
xfree (proxy_authstr);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#elif HTTP_USE_GNUTLS
|
#elif HTTP_USE_GNUTLS
|
||||||
if (hd->uri->use_tls)
|
if (hd->uri->use_tls)
|
||||||
@ -2910,10 +2937,7 @@ cookie_close (void *cookie)
|
|||||||
gpg_error_t
|
gpg_error_t
|
||||||
http_verify_server_credentials (http_session_t sess)
|
http_verify_server_credentials (http_session_t sess)
|
||||||
{
|
{
|
||||||
#if HTTP_USE_NTBTLS
|
#if HTTP_USE_GNUTLS
|
||||||
(void)sess;
|
|
||||||
return 0; /* FIXME!! */
|
|
||||||
#elif HTTP_USE_GNUTLS
|
|
||||||
static const char const errprefix[] = "TLS verification of peer failed";
|
static const char const errprefix[] = "TLS verification of peer failed";
|
||||||
int rc;
|
int rc;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
@ -97,6 +97,13 @@ typedef struct http_session_s *http_session_t;
|
|||||||
struct http_context_s;
|
struct http_context_s;
|
||||||
typedef struct http_context_s *http_t;
|
typedef struct http_context_s *http_t;
|
||||||
|
|
||||||
|
/* A TLS verify callback function. */
|
||||||
|
typedef gpg_error_t (*http_verify_cb_t) (void *opaque,
|
||||||
|
http_t http,
|
||||||
|
http_session_t session,
|
||||||
|
unsigned int flags,
|
||||||
|
void *tls_context);
|
||||||
|
|
||||||
void http_set_verbose (int verbose, int debug);
|
void http_set_verbose (int verbose, int debug);
|
||||||
|
|
||||||
void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int));
|
void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int));
|
||||||
@ -105,9 +112,10 @@ void http_register_netactivity_cb (void (*cb)(void));
|
|||||||
|
|
||||||
|
|
||||||
gpg_error_t http_session_new (http_session_t *r_session,
|
gpg_error_t http_session_new (http_session_t *r_session,
|
||||||
const char *tls_priority,
|
|
||||||
const char *intended_hostname,
|
const char *intended_hostname,
|
||||||
unsigned int flags);
|
unsigned int flags,
|
||||||
|
http_verify_cb_t cb,
|
||||||
|
void *cb_value);
|
||||||
http_session_t http_session_ref (http_session_t sess);
|
http_session_t http_session_ref (http_session_t sess);
|
||||||
void http_session_release (http_session_t sess);
|
void http_session_release (http_session_t sess);
|
||||||
|
|
||||||
|
@ -1123,7 +1123,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
|
|||||||
|
|
||||||
*r_fp = NULL;
|
*r_fp = NULL;
|
||||||
|
|
||||||
err = http_session_new (&session, NULL, httphost, HTTP_FLAG_TRUST_DEF);
|
err = http_session_new (&session, httphost, HTTP_FLAG_TRUST_DEF,
|
||||||
|
NULL, ctrl);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
http_session_set_log_cb (session, cert_log_cb);
|
http_session_set_log_cb (session, cert_log_cb);
|
||||||
|
@ -76,7 +76,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
|
|||||||
once_more:
|
once_more:
|
||||||
/* Note that we only use the system provided certificates with the
|
/* Note that we only use the system provided certificates with the
|
||||||
* fetch command. */
|
* fetch command. */
|
||||||
err = http_session_new (&session, NULL, NULL, HTTP_FLAG_TRUST_SYS);
|
err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_SYS,
|
||||||
|
NULL, ctrl);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
http_session_set_log_cb (session, cert_log_cb);
|
http_session_set_log_cb (session, cert_log_cb);
|
||||||
|
@ -370,14 +370,15 @@ do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
|
|||||||
char *buf;
|
char *buf;
|
||||||
ksba_cert_t cert;
|
ksba_cert_t cert;
|
||||||
|
|
||||||
if (name)
|
buf = name? strconcat (command, " ", name, NULL) : xtrystrdup (command);
|
||||||
buf = xstrconcat (command, " ", name, NULL);
|
if (!buf)
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
else
|
else
|
||||||
buf = xstrdup (command);
|
{
|
||||||
|
|
||||||
rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
|
rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
|
||||||
&value, &valuelen, MAX_CERT_LENGTH);
|
&value, &valuelen, MAX_CERT_LENGTH);
|
||||||
xfree (buf);
|
xfree (buf);
|
||||||
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error (_("assuan_inquire(%s) failed: %s\n"),
|
log_error (_("assuan_inquire(%s) failed: %s\n"),
|
||||||
|
@ -262,7 +262,7 @@ main (int argc, char **argv)
|
|||||||
http_register_tls_callback (verify_callback);
|
http_register_tls_callback (verify_callback);
|
||||||
http_register_tls_ca (cafile);
|
http_register_tls_ca (cafile);
|
||||||
|
|
||||||
err = http_session_new (&session, NULL, NULL, HTTP_FLAG_TRUST_DEF);
|
err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_DEF, NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
log_error ("http_session_new failed: %s\n", gpg_strerror (err));
|
log_error ("http_session_new failed: %s\n", gpg_strerror (err));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user