104 { |
104 { |
105 sprintf(_ssl_error_code, "%ld", verify_res); |
105 sprintf(_ssl_error_code, "%ld", verify_res); |
106 return _ssl_error_code; |
106 return _ssl_error_code; |
107 }*/ |
107 }*/ |
108 |
108 |
109 |
109 |
110 int |
110 int |
111 ssl_verify_cb (int preverify_ok, X509_STORE_CTX *x509_ctx) |
111 ssl_verify_cb (int preverify_ok, X509_STORE_CTX *x509_ctx) |
112 { |
112 { |
113 /* As this callback doesn't get auxiliary pointer parameter we |
113 /* As this callback doesn't get auxiliary pointer parameter we |
114 * cannot really use this. However, we can retrieve results later. */ |
114 * cannot really use this. However, we can retrieve results later. */ |
202 g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, |
202 g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, |
203 ssl_get_x509_err(verify_res), NULL); |
203 ssl_get_x509_err(verify_res), NULL); |
204 }*/ |
204 }*/ |
205 crt_subj = X509_get_subject_name(srv_crt); |
205 crt_subj = X509_get_subject_name(srv_crt); |
206 cn = (gchar *) g_malloc0(LM_SSL_CN_MAX + 1); |
206 cn = (gchar *) g_malloc0(LM_SSL_CN_MAX + 1); |
207 |
207 |
208 if (X509_NAME_get_text_by_NID(crt_subj, NID_commonName, cn, LM_SSL_CN_MAX) > 0) { |
208 if (X509_NAME_get_text_by_NID(crt_subj, NID_commonName, cn, LM_SSL_CN_MAX) > 0) { |
209 gchar *domain = cn; |
209 gchar *domain = cn; |
210 |
210 |
211 g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, |
211 g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, |
212 "%s: server = '%s', cn = '%s'\n", |
212 "%s: server = '%s', cn = '%s'\n", |
213 __FILE__, server, cn); |
213 __FILE__, server, cn); |
214 |
214 |
215 if ((cn[0] == '*') && (cn[1] == '.')) { |
215 if ((cn[0] == '*') && (cn[1] == '.')) { |
216 domain = strstr (cn, server); |
216 domain = strstr (cn, server); |
217 } |
217 } |
218 |
218 |
219 if ((domain == NULL) || (strncmp (server, domain, LM_SSL_CN_MAX) != 0)) { |
219 if ((domain == NULL) || (strncmp (server, domain, LM_SSL_CN_MAX) != 0)) { |
225 } |
225 } |
226 } else { |
226 } else { |
227 g_warning ("X509_NAME_get_text_by_NID() failed"); |
227 g_warning ("X509_NAME_get_text_by_NID() failed"); |
228 } |
228 } |
229 |
229 |
230 g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, |
230 g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, |
231 "%s:\n\tIssuer: %s\n\tSubject: %s\n\tFor: %s\n", |
231 "%s:\n\tIssuer: %s\n\tSubject: %s\n\tFor: %s\n", |
232 __FILE__, |
232 __FILE__, |
233 X509_NAME_oneline(X509_get_issuer_name(srv_crt), NULL, 0), |
233 X509_NAME_oneline(X509_get_issuer_name(srv_crt), NULL, 0), |
234 X509_NAME_oneline(X509_get_subject_name(srv_crt), NULL, 0), |
234 X509_NAME_oneline(X509_get_subject_name(srv_crt), NULL, 0), |
235 cn); |
235 cn); |
236 |
236 |
237 g_free(cn); |
237 g_free(cn); |
238 |
238 |
239 return retval; |
239 return retval; |
240 } |
240 } |
241 |
241 |
242 static GIOStatus |
242 static GIOStatus |
243 ssl_io_status_from_return (LmSSL *ssl, gint ret) |
243 ssl_io_status_from_return (LmSSL *ssl, gint ret) |
304 if (ssl->ssl_ctx == NULL) { |
304 if (ssl->ssl_ctx == NULL) { |
305 g_warning ("SSL_CTX_new() == NULL"); |
305 g_warning ("SSL_CTX_new() == NULL"); |
306 abort(); |
306 abort(); |
307 } |
307 } |
308 |
308 |
309 /* Set the NO_TICKET option on the context to allow for talk to Google Talk |
309 /* Set the NO_TICKET option on the context to allow for talk to Google Talk |
310 * which apparently seems to be having a problem handling empty session |
310 * which apparently seems to be having a problem handling empty session |
311 * tickets due to a bug in Java. |
311 * tickets due to a bug in Java. |
312 * |
312 * |
313 * See http://twistedmatrix.com/trac/ticket/3463 and |
313 * See http://twistedmatrix.com/trac/ticket/3463 and |
314 * Loudmouth [#28]. |
314 * Loudmouth [#28]. |
315 */ |
315 */ |
380 if (!ssl_verify_certificate (ssl, server)) { |
380 if (!ssl_verify_certificate (ssl, server)) { |
381 g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, |
381 g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, |
382 "*** SSL certificate verification failed"); |
382 "*** SSL certificate verification failed"); |
383 return FALSE; |
383 return FALSE; |
384 } |
384 } |
385 |
385 |
386 return TRUE; |
386 return TRUE; |
387 } |
387 } |
388 |
388 |
389 GIOStatus |
389 GIOStatus |
390 _lm_ssl_read (LmSSL *ssl, gchar *buf, gint len, gsize *bytes_read) |
390 _lm_ssl_read (LmSSL *ssl, gchar *buf, gint len, gsize *bytes_read) |
391 { |
391 { |
396 ssl_ret = SSL_read(ssl->ssl, buf, len); |
396 ssl_ret = SSL_read(ssl->ssl, buf, len); |
397 status = ssl_io_status_from_return(ssl, ssl_ret); |
397 status = ssl_io_status_from_return(ssl, ssl_ret); |
398 if (status == G_IO_STATUS_NORMAL) { |
398 if (status == G_IO_STATUS_NORMAL) { |
399 *bytes_read = ssl_ret; |
399 *bytes_read = ssl_ret; |
400 } |
400 } |
401 |
401 |
402 return status; |
402 return status; |
403 } |
403 } |
404 |
404 |
405 gint |
405 gint |
406 _lm_ssl_send (LmSSL *ssl, const gchar *str, gint len) |
406 _lm_ssl_send (LmSSL *ssl, const gchar *str, gint len) |