-
Notifications
You must be signed in to change notification settings - Fork 12
/
curl-7.21.2-gnutls.patch
90 lines (84 loc) · 2.94 KB
/
curl-7.21.2-gnutls.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
--- a/lib/gtls.c 2010-01-24 01:08:28 +0000
+++ b/lib/gtls.c 2010-01-24 01:10:15 +0000
@@ -85,15 +85,52 @@
* We use custom functions rather than the GNU TLS defaults because it allows
* us to get specific about the fourth "flags" argument, and to use arbitrary
* private data with gnutls_transport_set_ptr if we wish.
+ *
+ * On Windows translate WSAGetLastError() to errno values as GNU TLS does it
+ * internally too. This is necessary because send() and recv() on Windows
+ * don't set errno when they fail but GNU TLS expects a proper errno value.
+ *
+ * Use gnutls_transport_set_global_errno as the GNU TLS documentation suggests
+ * to avoid problems with different errno variables when GNU TLS and curl are
+ * linked to different versions of msvcrt.dll.
*/
+#ifdef USE_WINSOCK
+static void translate_wsa_to_errno(void)
+{
+ switch(WSAGetLastError()) {
+ case WSAEWOULDBLOCK:
+ gnutls_transport_set_global_errno(EAGAIN);
+ break;
+ case WSAEINTR:
+ gnutls_transport_set_global_errno(EINTR);
+ break;
+ default:
+ gnutls_transport_set_global_errno(EIO);
+ break;
+ }
+}
+#endif
+
static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
{
- return swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+ ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+#ifdef USE_WINSOCK
+ if(ret < 0) {
+ translate_wsa_to_errno();
+ }
+#endif
+ return ret;
}
static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
{
- return sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+ ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+#ifdef USE_WINSOCK
+ if(ret < 0) {
+ translate_wsa_to_errno();
+ }
+#endif
+ return ret;
}
/* Curl_gtls_init()
@@ -361,22 +398,28 @@
/* Use default priorities */
rc = gnutls_set_default_priority(session);
- if(rc != GNUTLS_E_SUCCESS)
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_set_default_priority() failed: %d", rc);
return CURLE_SSL_CONNECT_ERROR;
+ }
if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) {
static const int protocol_priority[] = { GNUTLS_SSL3, 0 };
- gnutls_protocol_set_priority(session, protocol_priority);
- if(rc != GNUTLS_E_SUCCESS)
+ rc = gnutls_protocol_set_priority(session, protocol_priority);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_protocol_set_priority() failed: %d", rc);
return CURLE_SSL_CONNECT_ERROR;
+ }
}
/* Sets the priority on the certificate types supported by gnutls. Priority
is higher for types specified before others. After specifying the types
you want, you must append a 0. */
rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
- if(rc != GNUTLS_E_SUCCESS)
+ if(rc != GNUTLS_E_SUCCESS && rc != GNUTLS_E_UNIMPLEMENTED_FEATURE) {
+ failf(data, "gnutls_certificate_type_set_priority() failed: %d", rc);
return CURLE_SSL_CONNECT_ERROR;
+ }
if(data->set.str[STRING_CERT]) {
if( gnutls_certificate_set_x509_key_file(