diff options
author | Wez Furlong <wez@php.net> | 2004-04-21 23:02:06 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2004-04-21 23:02:06 +0000 |
commit | e9920ede1fc54e2b1cfd99a2cfb4528a5e79d005 (patch) | |
tree | 60b06ff44f6f717ffafc132b2fc14f04e5febcf3 /ext/openssl | |
parent | 375b5df63d3e57520ddb1d08fea2dbe8ec50d59f (diff) | |
download | php-git-e9920ede1fc54e2b1cfd99a2cfb4528a5e79d005.tar.gz |
Fix bug #28096 - stream_socket_accept() on an SSL server socket doesn't
enable SSL on the accepted socket.
- Add cipher list context option
- Add helpful hint about why SSL server socket fails with mysterious
error (eg: you need an SSL certificate for most ciphers).
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/openssl.c | 7 | ||||
-rw-r--r-- | ext/openssl/xp_ssl.c | 98 |
2 files changed, 77 insertions, 28 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 996cd17bae..002fd47748 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3206,6 +3206,7 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) char *cafile = NULL; char *capath = NULL; char *certfile = NULL; + char *cipherlist = NULL; int ok = 1; @@ -3240,6 +3241,12 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); } + GET_VER_OPT_STRING("ciphers", cipherlist); + if (!cipherlist) { + cipherlist = "DEFAULT"; + } + SSL_CTX_set_cipher_list(ctx, cipherlist); + GET_VER_OPT_STRING("local_cert", certfile); if (certfile) { X509 *cert = NULL; diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index d4fe8685dc..2bcc0c232e 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -53,7 +53,7 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes TSRMLS_DC) char esbuf[512]; char *ebuf = NULL, *wptr = NULL; size_t ebuf_size = 0; - unsigned long code; + unsigned long code, ecode; int retry = 1; switch(err) { @@ -84,37 +84,49 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes TSRMLS_DC) } break; } + + /* fall through */ default: /* some other error */ - while ((code = ERR_get_error()) != 0) { - /* allow room for a NUL and an optional \n */ - if (ebuf) { - esbuf[0] = '\n'; - esbuf[1] = '\0'; - ERR_error_string_n(code, esbuf + 1, sizeof(esbuf) - 2); - } else { - esbuf[0] = '\0'; - ERR_error_string_n(code, esbuf, sizeof(esbuf) - 1); - } - code = strlen(esbuf); - esbuf[code] = '\0'; + ecode = ERR_get_error(); - ebuf = erealloc(ebuf, ebuf_size + code + 1); - if (wptr == NULL) { - wptr = ebuf; - } + switch (ERR_GET_REASON(ecode)) { + case SSL_R_NO_SHARED_CIPHER: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. This could be because the server is missing an SSL certificate (local_cert context option)"); + retry = 0; + break; - /* also copies the NUL */ - memcpy(wptr, esbuf, code + 1); - wptr += code; - } + default: + do { + /* allow room for a NUL and an optional \n */ + if (ebuf) { + esbuf[0] = '\n'; + esbuf[1] = '\0'; + ERR_error_string_n(ecode, esbuf + 1, sizeof(esbuf) - 2); + } else { + esbuf[0] = '\0'; + ERR_error_string_n(ecode, esbuf, sizeof(esbuf) - 1); + } + code = strlen(esbuf); + esbuf[code] = '\0'; + + ebuf = erealloc(ebuf, ebuf_size + code + 1); + if (wptr == NULL) { + wptr = ebuf; + } + + /* also copies the NUL */ + memcpy(wptr, esbuf, code + 1); + wptr += code; + } while ((ecode = ERR_get_error()) != 0); - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "SSL operation failed with code %d.%s%s", - err, - ebuf ? "OpenSSL Error messages:\n" : "", - ebuf ? ebuf : ""); + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "SSL operation failed with code %d. %s%s", + err, + ebuf ? "OpenSSL Error messages:\n" : "", + ebuf ? ebuf : ""); + } retry = 0; } @@ -424,6 +436,36 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ xparam->outputs.client->context = stream->context; } } + + if (xparam->outputs.client && sock->enable_on_connect) { + /* apply crypto */ + switch (sock->method) { + case STREAM_CRYPTO_METHOD_SSLv23_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_SSLv23_SERVER; + break; + case STREAM_CRYPTO_METHOD_SSLv2_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_SSLv2_SERVER; + break; + case STREAM_CRYPTO_METHOD_SSLv3_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_SSLv3_SERVER; + break; + case STREAM_CRYPTO_METHOD_TLS_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_TLS_SERVER; + break; + } + + clisockdata->method = sock->method; + + if (php_stream_xport_crypto_setup(xparam->outputs.client, clisockdata->method, + NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable( + xparam->outputs.client, 1 TSRMLS_CC) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enable crypto"); + + php_stream_close(xparam->outputs.client); + xparam->outputs.client = NULL; + xparam->outputs.returncode = -1; + } + } } return xparam->outputs.client == NULL ? -1 : 0; @@ -524,14 +566,14 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val } } return PHP_STREAM_OPTION_RETURN_OK; - break; case STREAM_XPORT_OP_ACCEPT: /* we need to copy the additional fields that the underlying tcp transport * doesn't know about */ xparam->outputs.returncode = php_openssl_tcp_sockop_accept(stream, sslsock, xparam STREAMS_CC TSRMLS_CC); + + return PHP_STREAM_OPTION_RETURN_OK; - break; default: /* fall through */ |