
diff -urw php-4.0.1pl2-orig/ext/standard/config.m4 php-4.0.1pl2/ext/standard/config.m4
--- php-4.0.1pl2-orig/ext/standard/config.m4 Tue May 23 09:09:11 2000
+++ php-4.0.1pl2/ext/standard/config.m4 Tue Aug 22 12:40:12 2000
@@ -146,5 +146,34 @@
fi
])
+PHP_ARG_WITH(ssl, for ssl support,
+[ --with-ssl[=DIR] Include ssl support])
+AC_DEFUN(PHP_SSL_SETUP_OPENSSL,[
+ for i in /usr/local/ssl /usr/local /usr /usr/local/openssl $PHP_OPENSSL; do
+ if test -r $i/include/openssl/evp.h; then
+ OPENSSL_DIR=$i
+ OPENSSL_INC=$i/include/openssl
+ elif test -r $i/include/evp.h; then
+ OPENSSL_DIR=$i
+ OPENSSL_INC=$i/include
+ fi
+ done
+
+ if test -z "$OPENSSL_DIR"; then
+ AC_MSG_ERROR(Cannot find OpenSSL's )
+ fi
+
+ AC_ADD_LIBPATH($OPENSSL_DIR/lib, SSL_SHARED_LIBADD)
+ AC_ADD_LIBRARY(ssl, yes, SSL_SHARED_LIBADD)
+ AC_ADD_LIBRARY(crypto, yes, SSL_SHARED_LIBADD)
+ AC_ADD_INCLUDE($OPENSSL_INC)
+])
+
+
+if test "$PHP_SSL" != "no"; then
+ PHP_SSL_SETUP_OPENSSL
+ AC_DEFINE(HAVE_SSL, 1, [ ])
+fi
+
PHP_EXTENSION(standard)
diff -urw php-4.0.1pl2-orig/ext/standard/file.c php-4.0.1pl2/ext/standard/file.c
--- php-4.0.1pl2-orig/ext/standard/file.c Tue Jun 27 09:55:52 2000
+++ php-4.0.1pl2/ext/standard/file.c Tue Aug 22 13:43:08 2000
@@ -1210,7 +1210,12 @@
}
if (issock){
+ /* FIXME: if anyone decides to use this macro to write to SSL sockets, it will fall over */
+#if HAVE_SSL
+ ret = php_sock_ssl_send((*arg2)->value.str.val,num_bytes,socketd);
+#else
ret = SOCK_WRITEL((*arg2)->value.str.val,num_bytes,socketd);
+#endif
} else {
ret = fwrite((*arg2)->value.str.val,1,num_bytes,(FILE*)what);
}
diff -urw php-4.0.1pl2-orig/ext/standard/fsock.c php-4.0.1pl2/ext/standard/fsock.c
--- php-4.0.1pl2-orig/ext/standard/fsock.c Mon Jun 19 09:02:48 2000
+++ php-4.0.1pl2/ext/standard/fsock.c Tue Aug 22 16:25:08 2000
@@ -200,6 +200,10 @@
#endif
}
/* }}} */
+
+
+static php_sockbuf *php_sockcreate(int socket FLS_DC);
+
/* {{{ php_fsockopen() */
/*
@@ -214,6 +218,7 @@
int arg_count=ZEND_NUM_ARGS();
int socketd = -1;
unsigned char udp = 0;
+ unsigned char use_ssl = 0; /* 1 = SSLv2/SSLv3, 2 = TLSv1 */
struct timeval timeout = { 60, 0 };
unsigned short portno;
unsigned long conv;
@@ -267,6 +272,24 @@
(*args[0])->value.str.val[5] == '/') {
udp = 1;
}
+#if HAVE_SSL
+ else if((*args[0])->value.str.val[0] == 's' &&
+ (*args[0])->value.str.val[1] == 's' &&
+ (*args[0])->value.str.val[2] == 'l' &&
+ (*args[0])->value.str.val[3] == ':' &&
+ (*args[0])->value.str.val[4] == '/' &&
+ (*args[0])->value.str.val[5] == '/') {
+ use_ssl = 1;
+ }
+ else if((*args[0])->value.str.val[0] == 't' &&
+ (*args[0])->value.str.val[1] == 'l' &&
+ (*args[0])->value.str.val[2] == 's' &&
+ (*args[0])->value.str.val[3] == ':' &&
+ (*args[0])->value.str.val[4] == '/' &&
+ (*args[0])->value.str.val[5] == '/') {
+ use_ssl = 2;
+ }
+#endif
socketd = socket(AF_INET,udp ? SOCK_DGRAM : SOCK_STREAM,0);
@@ -277,7 +300,7 @@
server.sin_family = AF_INET;
- if(lookup_hostname(udp ? &(*args[0])->value.str.val[6] : (*args[0])->value.str.val,&server.sin_addr)) {
+ if(lookup_hostname((use_ssl | udp) ? &(*args[0])->value.str.val[6] : (*args[0])->value.str.val,&server.sin_addr)) {
CLOSE_SOCK(1);
RETURN_FALSE;
}
@@ -335,6 +358,54 @@
#endif
#endif
+#if HAVE_SSL
+ if (use_ssl) {
+ /* we need to create sockbuf now so we can remember that we are using SSL */
+ php_sockbuf * sbuf = php_sockcreate(socketd FLS_CC);
+ if (sbuf) {
+ /* now fire up an SSL client context */
+ SSL_METHOD * meth;
+ SSL_CTX * ctx;
+ SSL * ssl;
+ int sslret;
+
+ meth = use_ssl == 1 ? SSLv23_client_method() : TLSv1_client_method();
+ ctx = SSL_CTX_new(meth);
+ ssl = SSL_new(ctx);
+ sbuf->ssl = ssl;
+
+ SSL_set_fd(sbuf->ssl, socketd);
+
+ sslret = SSL_connect(ssl);
+
+ if (sslret < 0) {
+ if(arg_count>2) (*args[2])->value.lval = SSL_get_error(sbuf->ssl, sslret);
+ if(arg_count>3) {
+ char buf[1024];
+ ERR_error_string((*args[2])->value.lval, buf);
+ (*args[3])->value.str.val = estrdup(buf);
+ (*args[3])->value.str.len = strlen((*args[3])->value.str.val);
+ }
+
+ CLOSE_SOCK(1);
+ RETURN_FALSE;
+ }
+ /* success - fall through to below */
+ }
+ else {
+ if(arg_count>2) (*args[2])->value.lval = ENOMEM;
+ if(arg_count>3) {
+ (*args[3])->value.str.val = estrdup("failed to create socket buffer");
+ (*args[3])->value.str.len = strlen((*args[3])->value.str.val);
+ }
+ CLOSE_SOCK(1);
+
+ RETURN_FALSE;
+ }
+ }
+
+#endif
+
*sock=socketd;
if (persistent) {
zend_hash_update(&FG(ht_fsock_keys), key, strlen(key) + 1,
@@ -366,12 +437,27 @@
#define CHUNK_SIZE 8192
#define SOCK_DESTROY(sock) \
if(sock->readbuf) pefree(sock->readbuf, sock->persistent); \
+ if(sock->ssl) php_ssl_cleanup_sockbuf(sock); \
if(sock->prev) sock->prev->next = sock->next; \
if(sock->next) sock->next->prev = sock->prev; \
if(sock == FG(phpsockbuf)) \
FG(phpsockbuf) = sock->next; \
pefree(sock, sock->persistent)
+#if HAVE_SSL
+static void php_ssl_cleanup_sockbuf(struct php_sockbuf * sock)
+{
+ SSL_CTX * ctx;
+ if (sock->ssl) {
+ SSL_shutdown(sock->ssl);
+ ctx = sock->ssl->ctx;
+ SSL_free(sock->ssl);
+ sock->ssl = NULL;
+ SSL_CTX_free(ctx);
+ }
+}
+#endif
+
static void php_cleanup_sockbuf(int persistent FLS_DC)
{
php_sockbuf *now, *next;
@@ -419,6 +505,7 @@
sock->is_blocked = 1;
sock->chunk_size = FG(def_chunk_size);
sock->timeout.tv_sec = -1;
+ sock->ssl = NULL;
FG(phpsockbuf) = sock;
return sock;
@@ -479,10 +566,18 @@
sock = php_sockfind(socket FLS_CC);
if(sock) {
if(!sock->persistent) {
+#if HAVE_SSL
+ if (sock->ssl)
+ php_ssl_cleanup_sockbuf(sock);
+#endif
SOCK_CLOSE(sock->socket);
SOCK_DESTROY(sock);
}
} else {
+#if HAVE_SSL
+ if (sock->ssl)
+ php_ssl_cleanup_sockbuf(sock);
+#endif
SOCK_CLOSE(socket);
}
@@ -541,6 +636,11 @@
}
/* read at a maximum sock->chunk_size */
+#if HAVE_SSL
+ if (sock->ssl)
+ nr_bytes = SSL_read(sock->ssl, buf, sock->chunk_size);
+ else
+#endif
nr_bytes = recv(sock->socket, buf, sock->chunk_size, 0);
if(nr_bytes > 0) {
if(sock->writepos + nr_bytes > sock->readbuflen) {
@@ -603,6 +703,20 @@
SOCK_FIND(sock, socket); \
if(sock->is_blocked) php_sockread_total(sock, max); else php_sockread(sock)
+
+#if HAVE_SSL
+/* {{{ php_sock_ssl_send
+ send to a socket that uses SSL
+*/
+int php_sock_ssl_send(char * buf, size_t len, int socket)
+{
+ SOCK_FIND(sock, socket);
+ if (sock->ssl)
+ return SSL_write(sock->ssl, buf, len);
+ return SOCK_WRITEL(buf, len, socket);
+}
+#endif
+
/* {{{ php_sock_fgets() */
/*
* FIXME: fgets depends on '\n' as line delimiter
@@ -738,6 +852,11 @@
PHP_MINIT_FUNCTION(fsock)
{
+#if HAVE_SSL
+ SSL_library_init();
+ SSL_load_error_strings();
+#endif
+
#ifdef ZTS
fsock_globals_id = ts_allocate_id(sizeof(php_fsock_globals), (ts_allocate_ctor) fsock_globals_ctor, (ts_allocate_dtor) fsock_globals_dtor);
#else
diff -urw php-4.0.1pl2-orig/ext/standard/fsock.h php-4.0.1pl2/ext/standard/fsock.h
--- php-4.0.1pl2-orig/ext/standard/fsock.h Mon Mar 6 20:37:11 2000
+++ php-4.0.1pl2/ext/standard/fsock.h Tue Aug 22 13:43:38 2000
@@ -55,6 +55,12 @@
#include
#endif
+#if HAVE_SSL
+#include
+#include
+#include
+#endif
+
struct php_sockbuf {
int socket;
unsigned char *readbuf;
@@ -69,6 +75,11 @@
size_t chunk_size;
struct timeval timeout;
char timeout_event;
+#if HAVE_SSL
+ SSL * ssl;
+#else
+ void * ssl;
+#endif
};
typedef struct php_sockbuf php_sockbuf;
@@ -88,6 +99,9 @@
int php_sock_close(int socket);
size_t php_sock_set_def_chunk_size(size_t size);
void php_msock_destroy(int *data);
+#if HAVE_SSL
+int php_sock_ssl_send(char * buf, size_t len, int socket);
+#endif
PHPAPI int connect_nonb(int sockfd, struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout);
PHPAPI struct php_sockbuf *php_get_socket(int socket);
diff -urw php-4.0.1pl2-orig/php_config.h.in php-4.0.1pl2/php_config.h.in
--- php-4.0.1pl2-orig/php_config.h.in Wed Jun 28 18:37:34 2000
+++ php-4.0.1pl2/php_config.h.in Tue Aug 22 13:18:08 2000
@@ -1409,6 +1409,9 @@
/* Whether the system supports BlowFish salt */
#undef PHP_BLOWFISH_CRYPT
+/* */
+#undef HAVE_SSL
+
/* Whether to build standard as dynamic module */
#undef COMPILE_DL_STANDARD