- Timestamp:
- 2011-12-19T14:50:58Z (13 years ago)
- Branches:
- master
- Children:
- 78b8401
- Parents:
- 5a48afd
- Location:
- lib
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/http_client.c
r5a48afd r486ddb5 33 33 34 34 static gboolean http_connected( gpointer data, int source, b_input_condition cond ); 35 static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond );35 static gboolean http_ssl_connected( gpointer data, int returncode, void *source, b_input_condition cond ); 36 36 static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond ); 37 37 static void http_free( struct http_request *req ); … … 170 170 } 171 171 172 static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond ) 173 { 172 static gboolean http_ssl_connected( gpointer data, int returncode, void *source, b_input_condition cond ) 173 { 174 //The returncode is not used at the moment. 174 175 struct http_request *req = data; 175 176 -
lib/ssl_bogus.c
r5a48afd r486ddb5 56 56 } 57 57 58 void *ssl_starttls( int fd, ssl_input_function func, gpointer data )58 void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ) 59 59 { 60 60 return NULL; -
lib/ssl_client.h
r5a48afd r486ddb5 37 37 /* Some generic error codes. Especially SSL_AGAIN is important if you 38 38 want to do asynchronous I/O. */ 39 #define NSS_VERIFY_ERROR -2 40 #define OPENSSL_VERIFY_ERROR -1 39 41 #define SSL_OK 0 40 42 #define SSL_NOHANDSHAKE 1 41 43 #define SSL_AGAIN 2 44 #define VERIFY_CERT_ERROR 2 45 #define VERIFY_CERT_INVALID 4 46 #define VERIFY_CERT_REVOKED 8 47 #define VERIFY_CERT_SIGNER_NOT_FOUND 16 48 #define VERIFY_CERT_SIGNER_NOT_CA 32 49 #define VERIFY_CERT_INSECURE_ALGORITHM 64 50 #define VERIFY_CERT_NOT_ACTIVATED 128 51 #define VERIFY_CERT_EXPIRED 256 52 #define VERIFY_CERT_WRONG_HOSTNAME 512 42 53 43 54 extern int ssl_errno; 44 55 45 56 /* This is what your callback function should look like. */ 46 typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);57 typedef gboolean (*ssl_input_function)(gpointer, int, void*, b_input_condition); 47 58 48 59 … … 57 68 /* Start an SSL session on an existing fd. Useful for STARTTLS functionality, 58 69 for example in Jabber. */ 59 G_MODULE_EXPORT void *ssl_starttls( int fd, ssl_input_function func, gpointer data );70 G_MODULE_EXPORT void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ); 60 71 61 72 /* Obviously you need special read/write functions to read data. */ -
lib/ssl_gnutls.c
r5a48afd r486ddb5 25 25 26 26 #include <gnutls/gnutls.h> 27 #include <gnutls/x509.h> 27 28 #include <gcrypt.h> 28 29 #include <fcntl.h> … … 32 33 #include "sock.h" 33 34 #include "stdlib.h" 35 #include "bitlbee.h" 34 36 35 37 int ssl_errno = 0; … … 54 56 gboolean established; 55 57 int inpa; 58 char *hostname; 59 gboolean verify; 56 60 57 61 gnutls_session session; … … 92 96 } 93 97 94 void *ssl_starttls( int fd, ssl_input_function func, gpointer data )98 void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ) 95 99 { 96 100 struct scd *conn = g_new0( struct scd, 1 ); … … 100 104 conn->data = data; 101 105 conn->inpa = -1; 106 conn->hostname = hostname; 107 108 /* For now, SSL verification is globally enabled by setting the cafile 109 setting in bitlbee.conf. Commented out by default because probably 110 not everyone has this file in the same place and plenty of folks 111 may not have the cert of their private Jabber server in it. */ 112 conn->verify = verify && global.conf->cafile; 102 113 103 114 /* This function should be called via a (short) timeout instead of … … 122 133 } 123 134 135 static int verify_certificate_callback( gnutls_session_t session ) 136 { 137 unsigned int status; 138 const gnutls_datum_t *cert_list; 139 unsigned int cert_list_size; 140 int gnutlsret; 141 int verifyret = 0; 142 gnutls_x509_crt_t cert; 143 const char *hostname; 144 145 hostname = gnutls_session_get_ptr(session ); 146 147 gnutlsret = gnutls_certificate_verify_peers2( session, &status ); 148 if( gnutlsret < 0 ) 149 return VERIFY_CERT_ERROR; 150 151 if( status & GNUTLS_CERT_INVALID ) 152 verifyret |= VERIFY_CERT_INVALID; 153 154 if( status & GNUTLS_CERT_REVOKED ) 155 verifyret |= VERIFY_CERT_REVOKED; 156 157 if( status & GNUTLS_CERT_SIGNER_NOT_FOUND ) 158 verifyret |= VERIFY_CERT_SIGNER_NOT_FOUND; 159 160 if( status & GNUTLS_CERT_SIGNER_NOT_CA ) 161 verifyret |= VERIFY_CERT_SIGNER_NOT_CA; 162 163 if( status & GNUTLS_CERT_INSECURE_ALGORITHM ) 164 verifyret |= VERIFY_CERT_INSECURE_ALGORITHM; 165 166 if( status & GNUTLS_CERT_NOT_ACTIVATED ) 167 verifyret |= VERIFY_CERT_NOT_ACTIVATED; 168 169 if( status & GNUTLS_CERT_EXPIRED ) 170 verifyret |= VERIFY_CERT_EXPIRED; 171 172 /* The following check is already performed inside 173 * gnutls_certificate_verify_peers2, so we don't need it. 174 175 * if( gnutls_certificate_type_get( session ) != GNUTLS_CRT_X509 ) 176 * return GNUTLS_E_CERTIFICATE_ERROR; 177 */ 178 179 if( gnutls_x509_crt_init( &cert ) < 0 ) 180 return VERIFY_CERT_ERROR; 181 182 cert_list = gnutls_certificate_get_peers( session, &cert_list_size ); 183 if( cert_list == NULL || gnutls_x509_crt_import( cert, &cert_list[0], GNUTLS_X509_FMT_DER ) < 0 ) 184 return VERIFY_CERT_ERROR; 185 186 if( !gnutls_x509_crt_check_hostname( cert, hostname ) ) 187 { 188 verifyret |= VERIFY_CERT_INVALID; 189 verifyret |= VERIFY_CERT_WRONG_HOSTNAME; 190 } 191 192 gnutls_x509_crt_deinit( cert ); 193 194 return verifyret; 195 } 196 124 197 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ) 125 198 { … … 128 201 if( source == -1 ) 129 202 { 130 conn->func( conn->data, NULL, cond );203 conn->func( conn->data, 0, NULL, cond ); 131 204 g_free( conn ); 132 205 return FALSE; … … 136 209 137 210 gnutls_certificate_allocate_credentials( &conn->xcred ); 211 if( conn->verify && global.conf->cafile ) 212 { 213 gnutls_certificate_set_x509_trust_file( conn->xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM ); 214 gnutls_certificate_set_verify_flags( conn->xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT ); 215 } 216 138 217 gnutls_init( &conn->session, GNUTLS_CLIENT ); 218 if( conn->verify ) 219 gnutls_session_set_ptr( conn->session, (void *) conn->hostname ); 139 220 #if GNUTLS_VERSION_NUMBER < 0x020c00 140 221 gnutls_transport_set_lowat( conn->session, 0 ); … … 152 233 { 153 234 struct scd *conn = data; 154 int st ;235 int st, stver; 155 236 156 237 if( ( st = gnutls_handshake( conn->session ) ) < 0 ) … … 163 244 else 164 245 { 165 conn->func( conn->data, NULL, cond );246 conn->func( conn->data, 0, NULL, cond ); 166 247 167 248 gnutls_deinit( conn->session ); … … 174 255 else 175 256 { 176 /* For now we can't handle non-blocking perfectly everywhere... */ 177 sock_make_blocking( conn->fd ); 257 if( conn->verify && ( stver = verify_certificate_callback( conn->session ) ) != 0 ) 258 { 259 conn->func( conn->data, stver, NULL, cond ); 260 261 gnutls_deinit( conn->session ); 262 gnutls_certificate_free_credentials( conn->xcred ); 263 closesocket( conn->fd ); 264 265 g_free( conn ); 266 } 267 else 268 { 269 /* For now we can't handle non-blocking perfectly everywhere... */ 270 sock_make_blocking( conn->fd ); 178 271 179 conn->established = TRUE; 180 conn->func( conn->data, conn, cond ); 272 conn->established = TRUE; 273 conn->func( conn->data, 0, conn, cond ); 274 } 181 275 } 182 276 -
lib/ssl_nss.c
r5a48afd r486ddb5 52 52 PRFileDesc *prfd; 53 53 gboolean established; 54 gboolean verify; 54 55 }; 55 56 … … 132 133 } 133 134 134 void *ssl_starttls( int fd, ssl_input_function func, gpointer data )135 void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ) 135 136 { 136 137 struct scd *conn = g_new0( struct scd, 1 ); … … 139 140 conn->func = func; 140 141 conn->data = data; 142 conn->verify = verify; 141 143 142 144 /* This function should be called via a (short) timeout instead of … … 157 159 { 158 160 struct scd *conn = data; 161 162 /* Right now we don't have any verification functionality for nss so we 163 fail in case verification has been requested by the user. */ 164 165 if( conn->verify ) 166 { 167 conn->func( conn->data, NSS_VERIFY_ERROR, NULL, cond ); 168 if( source >= 0 ) closesocket( source ); 169 g_free( conn ); 170 171 return FALSE; 172 } 159 173 160 174 if( source == -1 ) … … 177 191 178 192 conn->established = TRUE; 179 conn->func( conn->data, conn, cond );193 conn->func( conn->data, 0, conn, cond ); 180 194 return FALSE; 181 195 182 196 ssl_connected_failure: 183 197 184 conn->func( conn->data, NULL, cond );198 conn->func( conn->data, 0, NULL, cond ); 185 199 186 200 PR_Close( conn -> prfd ); -
lib/ssl_openssl.c
r5a48afd r486ddb5 45 45 int fd; 46 46 gboolean established; 47 gboolean verify; 47 48 48 49 int inpa; … … 82 83 } 83 84 84 void *ssl_starttls( int fd, ssl_input_function func, gpointer data )85 void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ) 85 86 { 86 87 struct scd *conn = g_new0( struct scd, 1 ); … … 90 91 conn->data = data; 91 92 conn->inpa = -1; 93 conn->verify = verify; 92 94 93 95 /* This function should be called via a (short) timeout instead of … … 117 119 SSL_METHOD *meth; 118 120 121 /* Right now we don't have any verification functionality for openssl so we 122 fail in case verification has been requested by the user. */ 123 124 if( conn->verify ) 125 { 126 conn->func( conn->data, OPENSSL_VERIFY_ERROR, NULL, cond ); 127 if( source >= 0 ) closesocket( source ); 128 g_free( conn ); 129 130 return FALSE; 131 } 132 119 133 if( source == -1 ) 120 134 goto ssl_connected_failure; … … 141 155 142 156 ssl_connected_failure: 143 conn->func( conn->data, NULL, cond );157 conn->func( conn->data, 0, NULL, cond ); 144 158 145 159 if( conn->ssl ) … … 169 183 if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE ) 170 184 { 171 conn->func( conn->data, NULL, cond );185 conn->func( conn->data, 0, NULL, cond ); 172 186 173 187 SSL_shutdown( conn->ssl ); … … 187 201 conn->established = TRUE; 188 202 sock_make_blocking( conn->fd ); /* For now... */ 189 conn->func( conn->data, conn, cond );203 conn->func( conn->data, 0, conn, cond ); 190 204 return FALSE; 191 205 }
Note: See TracChangeset
for help on using the changeset viewer.