|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-07-13 06:08 UTC] develop at kristov dot de
Description: ------------ Currently, imap_open does not allow to specify a client certificate to be used for a SSL/TLS-encrypted connection. Newer c-client versions do support this (using the GET_SSLCLIENTCERT and GET_SSLCLIENTKEY callbacks). I propose a patch which addresses this issue: - it adds an additional parameter "keycert" to imap_open which receives the combined client certificate and key (similar to the "local_cert" option used e.g. by stream_socket_client/stream_context_create) - it adds an additional IMAP global variable imap_keycert to hold the value of this parameter until being used by the callback - it defines and registers a callback function mail_getkeycert which passes the combined client certificate and key to the c-client library if supported (the existence of both of the #defines SET_SSLCLIENTCERT and SET_SSLCLIENTKEY enables the callback) - it links in the external authenticator auth_ext as client certificates/keys often replace user/password combinations (the user is identified by the CN of the client certificate and the password is substituted by the valid client key) One technical detail: The external authenticator of the c-client library does not do a mm_login callback (see src/c-client/auth_ext.c, function auth_external_client). So the user name for the connection has to be set some other way. This is done by extending the caller's mailbox name by a user specification "/user=<user>" which is parsed and handled by the c-client library. The code to do this string insertion is a bit clumsy and can probably be improved; I'm afraid I do not know Zend very well and I was lucky to find a way for this string manipulation at all :-) The rest of the patch is trivial and consists mainly of memory management and parameter checks. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 19:00:01 2025 UTC |
Somehow I cannot add a patch file to this change request. So I include it here: diff -urN php-5.2.6/ext/imap/php_imap.c php-5.2.6_p1/ext/imap/php_imap.c --- php-5.2.6/ext/imap/php_imap.c 2008-04-17 13:04:49.000000000 +0200 +++ php-5.2.6_p1/ext/imap/php_imap.c 2008-07-12 11:42:12.000000000 +0200 @@ -229,6 +229,10 @@ efree(IMAPG(imap_password)); IMAPG(imap_password) = 0; } + if (IMAPG(imap_keycert)) { + efree(IMAPG(imap_keycert)); + IMAPG(imap_keycert) = 0; + } efree(imap_le_struct); } @@ -413,6 +417,21 @@ } /* }}} */ +#ifdef SET_SSLCLIENTCERT +#ifdef SET_SSLCLIENTKEY +/* {{{ mail_getkeycert + * + * Mail GET_SSLCLIENTCERT and GET_SSLCLIENTKEY callback + */ +char *mail_getkeycert(void) +{ + TSRMLS_FETCH(); + return IMAPG(imap_keycert); +} +/* }}} */ +#endif +#endif + #endif @@ -422,6 +441,7 @@ { imap_globals->imap_user = NIL; imap_globals->imap_password = NIL; + imap_globals->imap_keycert = NIL; imap_globals->imap_alertstack = NIL; imap_globals->imap_errorstack = NIL; @@ -469,6 +489,7 @@ mail_link(&dummydriver); /* link in the dummy driver */ #ifndef PHP_WIN32 + auth_link(&auth_ext); /* link in the external authenticator */ auth_link(&auth_log); /* link in the log authenticator */ auth_link(&auth_md5); /* link in the cram-md5 authenticator */ #if HAVE_IMAP_KRB && defined(HAVE_IMAP_AUTH_GSS) @@ -748,14 +769,15 @@ */ static void php_imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) { - zval **mailbox, **user, **passwd, **options, **retries; + zval **mailbox, **user, **passwd, **options, **retries, **keycert; MAILSTREAM *imap_stream; pils *imap_le_struct; long flags=NIL; long cl_flags=NIL; int myargc = ZEND_NUM_ARGS(); - - if (myargc < 3 || myargc > 5 || zend_get_parameters_ex(myargc, &mailbox, &user, &passwd, &options, &retries) == FAILURE) { + char *found = NULL; + + if (myargc < 3 || myargc > 6 || zend_get_parameters_ex(myargc, &mailbox, &user, &passwd, &options, &retries, &keycert) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -770,6 +792,9 @@ flags ^= PHP_EXPUNGE; } } + if (myargc >= 6) { + convert_to_string_ex(keycert); + } if (IMAPG(imap_user)) { efree(IMAPG(imap_user)); @@ -779,6 +804,10 @@ efree(IMAPG(imap_password)); } + if (IMAPG(imap_keycert)) { + efree(IMAPG(imap_keycert)); + } + /* local filename, need to perform open_basedir and safe_mode checks */ if (Z_STRVAL_PP(mailbox)[0] != '{' && (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || @@ -789,8 +818,40 @@ IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + found = php_memnstr(Z_STRVAL_PP(mailbox), + "}", + 1, + Z_STRVAL_PP(mailbox) + Z_STRLEN_PP(mailbox)); + if (found) { + zval *mailboxwithuser, *tmp; + MAKE_STD_ZVAL(mailboxwithuser); + ZVAL_STRINGL(mailboxwithuser, + Z_STRVAL_PP(mailbox), + found - Z_STRVAL_PP(mailbox), + 1); + + MAKE_STD_ZVAL(tmp); + ZVAL_STRING(tmp, "/user=", 0); + add_string_to_string(mailboxwithuser, mailboxwithuser, tmp); + ZVAL_STRING(tmp, IMAPG(imap_user), 0); + add_string_to_string(mailboxwithuser, mailboxwithuser, tmp); + ZVAL_STRINGL(tmp, + found, + Z_STRLEN_PP(mailbox) - (found - Z_STRVAL_PP(mailbox)), + 0); + add_string_to_string(mailboxwithuser, mailboxwithuser, tmp); + FREE_ZVAL(tmp); + + REPLACE_ZVAL_VALUE(mailbox, mailboxwithuser, 0); + FREE_ZVAL(mailboxwithuser); + } + + if (myargc >= 6) { + IMAPG(imap_keycert) = estrndup(Z_STRVAL_PP(keycert), Z_STRLEN_PP(keycert)); + } + #ifdef SET_MAXLOGINTRIALS - if (myargc == 5) { + if (myargc >= 5) { convert_to_long_ex(retries); if (Z_LVAL_PP(retries) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING ,"Retries must be greater or equal to 0"); @@ -800,12 +861,24 @@ } #endif +#ifdef SET_SSLCLIENTCERT +#ifdef SET_SSLCLIENTKEY + if (myargc >= 6) { + mail_parameters(NIL, SET_SSLCLIENTCERT, (void *) mail_getkeycert); + mail_parameters(NIL, SET_SSLCLIENTKEY, (void *) mail_getkeycert); + } +#endif +#endif + imap_stream = mail_open(NIL, Z_STRVAL_PP(mailbox), flags); if (imap_stream == NIL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't open stream %s", Z_STRVAL_PP(mailbox)); efree(IMAPG(imap_user)); IMAPG(imap_user) = 0; efree(IMAPG(imap_password)); IMAPG(imap_password) = 0; + if (myargc >= 6) { + efree(IMAPG(imap_keycert)); IMAPG(imap_keycert) = 0; + } RETURN_FALSE; } diff -urN php-5.2.6/ext/imap/php_imap.h php-5.2.6_p1/ext/imap/php_imap.h --- php-5.2.6/ext/imap/php_imap.h 2007-12-31 08:20:07.000000000 +0100 +++ php-5.2.6_p1/ext/imap/php_imap.h 2008-07-12 11:03:40.000000000 +0200 @@ -180,6 +180,7 @@ ZEND_BEGIN_MODULE_GLOBALS(imap) char *imap_user; char *imap_password; + char *imap_keycert; STRINGLIST *imap_alertstack; ERRORLIST *imap_errorstack;