X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e8757f091a502b858912a4c267210e009227d6e6..4ec52e2f8c1697994618b4bdfd013659f6defb1b:/src/gnutls.c diff --git a/src/gnutls.c b/src/gnutls.c index e3d84a0b61..5a296166cd 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -1,5 +1,5 @@ /* GnuTLS glue for GNU Emacs. - Copyright (C) 2010-2012 Free Software Foundation, Inc. + Copyright (C) 2010-2013 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -56,6 +56,9 @@ static Lisp_Object QCgnutls_bootprop_callbacks_verify; static void gnutls_log_function (int, const char *); static void gnutls_log_function2 (int, const char*, const char*); +#ifdef HAVE_GNUTLS3 +static void gnutls_audit_log_function (gnutls_session_t, const char *); +#endif #ifdef WINDOWSNT @@ -108,6 +111,9 @@ DEF_GNUTLS_FN (void, gnutls_dh_set_prime_bits, DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int)); DEF_GNUTLS_FN (int, gnutls_global_init, (void)); DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); +#ifdef HAVE_GNUTLS3 +DEF_GNUTLS_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func)); +#endif DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int)); DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions, (gnutls_alloc_function, gnutls_alloc_function, @@ -173,6 +179,9 @@ init_gnutls_functions (void) LOAD_GNUTLS_FN (library, gnutls_error_is_fatal); LOAD_GNUTLS_FN (library, gnutls_global_init); LOAD_GNUTLS_FN (library, gnutls_global_set_log_function); +#ifdef HAVE_GNUTLS3 + LOAD_GNUTLS_FN (library, gnutls_global_set_audit_log_function); +#endif LOAD_GNUTLS_FN (library, gnutls_global_set_log_level); LOAD_GNUTLS_FN (library, gnutls_global_set_mem_functions); LOAD_GNUTLS_FN (library, gnutls_handshake); @@ -230,6 +239,9 @@ init_gnutls_functions (void) #define fn_gnutls_error_is_fatal gnutls_error_is_fatal #define fn_gnutls_global_init gnutls_global_init #define fn_gnutls_global_set_log_function gnutls_global_set_log_function +#ifdef HAVE_GNUTLS3 +#define fn_gnutls_global_set_audit_log_function gnutls_global_set_audit_log_function +#endif #define fn_gnutls_global_set_log_level gnutls_global_set_log_level #define fn_gnutls_global_set_mem_functions gnutls_global_set_mem_functions #define fn_gnutls_handshake gnutls_handshake @@ -239,7 +251,9 @@ init_gnutls_functions (void) #define fn_gnutls_record_recv gnutls_record_recv #define fn_gnutls_record_send gnutls_record_send #define fn_gnutls_strerror gnutls_strerror +#ifdef WINDOWSNT #define fn_gnutls_transport_set_errno gnutls_transport_set_errno +#endif #define fn_gnutls_transport_set_ptr2 gnutls_transport_set_ptr2 #define fn_gnutls_x509_crt_check_hostname gnutls_x509_crt_check_hostname #define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit @@ -249,6 +263,18 @@ init_gnutls_functions (void) #endif /* !WINDOWSNT */ +#ifdef HAVE_GNUTLS3 +/* Function to log a simple audit message. */ +static void +gnutls_audit_log_function (gnutls_session_t session, const char* string) +{ + if (global_gnutls_log_level >= 1) + { + message ("gnutls.c: [audit] %s", string); + } +} +#endif + /* Function to log a simple message. */ static void gnutls_log_function (int level, const char* string) @@ -344,11 +370,13 @@ emacs_gnutls_record_check_pending (gnutls_session_t state) return fn_gnutls_record_check_pending (state); } +#ifdef WINDOWSNT void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err) { fn_gnutls_transport_set_errno (state, err); } +#endif ptrdiff_t emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) @@ -359,12 +387,7 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) if (proc->gnutls_initstage != GNUTLS_STAGE_READY) { -#ifdef EWOULDBLOCK - errno = EWOULDBLOCK; -#endif -#ifdef EAGAIN errno = EAGAIN; -#endif return 0; } @@ -384,14 +407,7 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) appropriately so that send_process retries the correct way instead of erroring out. */ if (rtnval == GNUTLS_E_AGAIN) - { -#ifdef EWOULDBLOCK - errno = EWOULDBLOCK; -#endif -#ifdef EAGAIN - errno = EAGAIN; -#endif - } + errno = EAGAIN; break; } } @@ -476,8 +492,20 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) else { ret = 1; - GNUTLS_LOG2 (1, max_log_level, "non-fatal error:", str); - /* TODO: EAGAIN AKA Qgnutls_e_again should be level 2. */ + + switch (err) + { + case GNUTLS_E_AGAIN: + GNUTLS_LOG2 (3, + max_log_level, + "retry:", + str); + default: + GNUTLS_LOG2 (1, + max_log_level, + "non-fatal error:", + str); + } } if (err == GNUTLS_E_WARNING_ALERT_RECEIVED @@ -779,16 +807,10 @@ one trustfile (usually a CA bundle). */) CHECK_LIST (proplist); if (NILP (Fgnutls_available_p ())) - { - error ("GnuTLS not available"); - return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED); - } + error ("GnuTLS not available"); if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon)) - { - error ("Invalid GnuTLS credential type"); - return gnutls_make_error (GNUTLS_EMACS_ERROR_INVALID_TYPE); - } + error ("Invalid GnuTLS credential type"); hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname); priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority); @@ -804,11 +826,13 @@ one trustfile (usually a CA bundle). */) c_hostname = SSDATA (hostname); state = XPROCESS (proc)->gnutls_state; - XPROCESS (proc)->gnutls_p = 1; if (TYPE_RANGED_INTEGERP (int, loglevel)) { fn_gnutls_global_set_log_function (gnutls_log_function); +#ifdef HAVE_GNUTLS3 + fn_gnutls_global_set_audit_log_function (gnutls_audit_log_function); +#endif fn_gnutls_global_set_log_level (XINT (loglevel)); max_log_level = XINT (loglevel); XPROCESS (proc)->gnutls_log_level = max_log_level; @@ -824,7 +848,6 @@ one trustfile (usually a CA bundle). */) emacs_gnutls_deinit (proc); /* Mark PROC as a GnuTLS process. */ - XPROCESS (proc)->gnutls_p = 1; XPROCESS (proc)->gnutls_state = NULL; XPROCESS (proc)->gnutls_x509_cred = NULL; XPROCESS (proc)->gnutls_anon_cred = NULL; @@ -1084,6 +1107,9 @@ one trustfile (usually a CA bundle). */) fn_gnutls_x509_crt_deinit (gnutls_verify_cert); } + /* Set this flag only if the whole initialization succeeded. */ + XPROCESS (proc)->gnutls_p = 1; + return gnutls_make_error (ret); }