We are not regular PHP developers, but one of our programmers developed a 
patch to 4.0.5 that allows PHP to act as an SSL client.

This patch adds the fsockopen_ssl() and pfsockopen_ssl() functions.  It 
works at a lower level than the curl package and allows you to add SSL to 
anything by simply replacing the fsockopen() and pfsockopen() functions.

If you believe that it is useful, feel free to add to the PHP code base.

Best regards,

Jeff Groves

===================================================

--- php-4.0.5/ext/standard/Makefile.org Fri May 25 14:26:19 2001
+++ php-4.0.5/ext/standard/Makefile.in  Fri May 25 14:27:41 2001
@@ -17,6 +17,8 @@

  include $(top_srcdir)/build/dynlib.mk

+DEFS += -DSSL_CLIENT
+
  parsedate.c: $(srcdir)/parsedate.y

  $(srcdir)/url_scanner_ex.c: $(srcdir)/url_scanner_ex.re
--- php-4.0.5.org/ext/standard/basic_functions.c        Wed Mar 28 16:51:34 2001
+++ php-4.0.5/ext/standard/basic_functions.c    Fri May 25 14:27:20 2001
@@ -445,6 +445,10 @@
        /* functions from fsock.c */
        PHP_FE(fsockopen,                       third_and_fourth_args_force_ref)
        PHP_FE(pfsockopen,                      third_and_fourth_args_force_ref)
+#ifdef SSL_CLIENT
+       PHP_FE(fsockopen_ssl,                   third_and_fourth_args_force_ref)
+       PHP_FE(pfsockopen_ssl,                  third_and_fourth_args_force_ref)
+#endif

        /* functions from pack.c */
        PHP_FE(pack,                            NULL)
--- php-4.0.5.org/ext/standard/fsock.c  Thu Apr 26 09:07:57 2001
+++ php-4.0.5/ext/standard/fsock.c      Fri May 25 14:30:17 2001
@@ -209,7 +209,7 @@
     passed by reference.  The error code from the connect call is written
     to this variable.
  */
-static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
+static int php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
        pval **args[5];
        int *sock=emalloc(sizeof(int));
        int *sockp;
@@ -254,7 +254,7 @@
                CLOSE_SOCK(0);
                *sock = *sockp;
                ZEND_REGISTER_RESOURCE(return_value,sock,php_file_le_socket());
-               return;
+               return *sock;
        }
        
        if (portno) {
@@ -345,6 +345,8 @@
        if(key) efree(key);

        ZEND_REGISTER_RESOURCE(return_value,sock,php_file_le_socket());
+
+       return *sock;
  }
  /* }}} */

@@ -363,6 +365,38 @@
  }
  /* }}} */

+#ifdef SSL_CLIENT
+
+/* {{{ proto int fsockopen_ssl(string hostname, int port [, int errno [, 
string errstr [, double timeout]]])
+   Open Internet or Unix domain socket connection */
+PHP_FUNCTION(fsockopen_ssl)
+{
+       int s;
+
+       s = php_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+       if (s >= 0) {
+               php_sockset_ssl(s);
+       }
+}
+/* }}} */
+/* {{{ proto int pfsockopen_ssl(string hostname, int port [, int errno [, 
string errstr [, double timeout]]])
+   Open persistent Internet or Unix domain socket connection */
+PHP_FUNCTION(pfsockopen_ssl)
+{
+       int s;
+
+       s = php_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+       if (s >= 0) {
+               php_sockset_ssl(s);
+       }
+}
+/* }}} */
+
+#define SSL_SOCK_CLOSE(sock) if(sock->ssl_ctx) { 
SSL_shutdown(sock->sslfp); SSL_free(sock->sslfp); 
SSL_CTX_free(sock->ssl_ctx); sock->ssl_ctx = NULL; }
+#else
+#define SSL_SOCK_CLOSE(sock)
+#endif
+
  #define SOCK_DESTROY(sock) \
                if(sock->readbuf) pefree(sock->readbuf, sock->persistent); \
                if(sock->prev) sock->prev->next = sock->next; \
@@ -378,6 +412,7 @@
        for(now = FG(phpsockbuf); now; now = next) {
                next = now->next;
                if(now->persistent == persistent) {
+                       SSL_SOCK_CLOSE(now);
                        SOCK_DESTROY(now);
                }
        }
@@ -418,6 +453,10 @@
        sock->is_blocked = 1;
        sock->chunk_size = FG(def_chunk_size);
        sock->timeout.tv_sec = -1;
+#ifdef SSL_CLIENT
+       sock->ssl_ctx = NULL;
+       sock->sslfp = NULL;
+#endif
        FG(phpsockbuf) = sock;

        return sock;
@@ -451,6 +490,7 @@
        sock = php_sockfind(socket FLS_CC);
        if(sock) {
                ret = 1;
+               SSL_SOCK_CLOSE(sock);
                SOCK_DESTROY(sock);
        }

@@ -478,6 +518,7 @@
        sock = php_sockfind(socket FLS_CC);
        if(sock) {
                if(!sock->persistent) {
+                       SSL_SOCK_CLOSE(sock);
                        SOCK_CLOSE(sock->socket);
                        SOCK_DESTROY(sock);
                }
@@ -540,6 +581,12 @@
        }

        /* read at a maximum sock->chunk_size */
+#ifdef SSL_CLIENT
+       if (sock->sslfp) {
+               nr_bytes = SSL_read(sock->sslfp, 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) {
@@ -577,6 +624,55 @@
        }

        return nr_read;
+}
+
+#ifdef SSL_CLIENT
+PHPAPI int php_sockset_ssl(int socket)
+{
+       SSL_CTX *ctx;
+       SSL *ssl;
+       SSL_METHOD *meth;
+       SOCK_FIND(sock, socket);
+
+       SSLeay_add_ssl_algorithms();
+       //meth = SSLv2_client_method();
+       //meth = SSLv23_client_method();
+       //meth = SSLv3_client_method();
+       meth = TLSv1_client_method();
+       //SSL_load_error_strings();
+       if ((ctx = SSL_CTX_new(meth)) == NULL) {
+               return -1;
+       }
+
+       if ((ssl = SSL_new(ctx)) == NULL) {
+               return -1;
+       }
+
+       SSL_set_fd(ssl, socket);
+       if (SSL_connect(ssl) == -1) {
+               return -1;
+       }
+
+       //fprintf(logfile, "%s connection using %s\n", SSL_get_version(ssl), 
SSL_get_cipher(ssl));
+
+       sock->ssl_ctx = ctx;
+       sock->sslfp = ssl;
+
+       return socket;
+}
+#endif
+
+PHPAPI int php_sock_send(int s, const void *msg, size_t len, int flags)
+{
+#ifdef SSL_CLIENT
+       SOCK_FIND(sock, s);
+
+       if (sock->sslfp) {
+               return SSL_write(sock->sslfp, msg, len);
+       }
+       else
+#endif
+       return send(s, msg, len, flags);
  }

  PHPAPI int php_sockset_blocking(int socket, int mode)
--- php-4.0.5.org/ext/standard/fsock.h  Mon Feb 26 00:07:17 2001
+++ php-4.0.5/ext/standard/fsock.h      Fri May 25 14:36:43 2001
@@ -47,6 +47,10 @@
  #include <sys/time.h>
  #endif

+#ifdef SSL_CLIENT
+#include <openssl/ssl.h>
+#endif
+
  #define PHP_FSOCK_CHUNK_SIZE 8192

  struct php_sockbuf {
@@ -63,19 +67,31 @@
        size_t chunk_size;
        struct timeval timeout;
        char timeout_event;
+#ifdef SSL_CLIENT
+       SSL_CTX *ssl_ctx;
+       SSL *sslfp;
+#endif
  };

  typedef struct php_sockbuf php_sockbuf;

  PHP_FUNCTION(fsockopen);
  PHP_FUNCTION(pfsockopen);
+#ifdef SSL_CLIENT
+PHP_FUNCTION(fsockopen_ssl);
+PHP_FUNCTION(pfsockopen_ssl);
+#endif

+PHPAPI int php_sock_send(int s, const void *msg, size_t len, int flags);
  PHPAPI int php_lookup_hostname(const char *addr, struct in_addr *in);
  PHPAPI char *php_sock_fgets(char *buf, size_t maxlen, int socket);
  PHPAPI size_t php_sock_fread(char *buf, size_t maxlen, int socket);
  PHPAPI int php_sock_feof(int socket);
  PHPAPI int php_sock_fgetc(int socket);
  PHPAPI int php_is_persistent_sock(int);
+#ifdef SSL_CLIENT
+PHPAPI int php_sockset_ssl(int socket);
+#endif
  PHPAPI int php_sockset_blocking(int socket, int mode);
  PHPAPI void php_sockset_timeout(int socket, struct timeval *timeout);
  PHPAPI int php_sockdestroy(int socket);
--- php-4.0.5.org/main/fopen_wrappers.h Mon Feb 26 00:07:31 2001
+++ php-4.0.5/main/fopen_wrappers.h     Fri May 25 13:48:12 2001
@@ -42,8 +42,8 @@
  # define SOCK_CONN_ERR -1
  # define SOCK_RECV_ERR -1
  #endif
-#define SOCK_WRITE(d,s) send(s,d,strlen(d),0)
-#define SOCK_WRITEL(d,l,s) send(s,d,l,0)
+#define SOCK_WRITE(d,s) php_sock_send(s,d,strlen(d),0)
+#define SOCK_WRITEL(d,l,s) php_sock_send(s,d,l,0)
  #define SOCK_FGETC(s) php_sock_fgetc((s))
  #define SOCK_FGETS(b,l,s) php_sock_fgets((b),(l),(s))
  #define SOCK_FEOF(sock) php_sock_feof((sock)) 


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to