Back to index

php5  5.3.10
Classes | Typedefs | Functions | Variables
mcrypt_filter.c File Reference
#include "php.h"
#include "php_mcrypt_filter.h"
#include "php_ini.h"
#include <mcrypt.h>

Go to the source code of this file.

Classes

struct  _php_mcrypt_filter_data

Typedefs

typedef struct
_php_mcrypt_filter_data 
php_mcrypt_filter_data

Functions

static php_stream_filter_status_t php_mcrypt_filter (php_stream *stream, php_stream_filter *thisfilter, php_stream_bucket_brigade *buckets_in, php_stream_bucket_brigade *buckets_out, size_t *bytes_consumed, int flags TSRMLS_DC)
static void php_mcrypt_filter_dtor (php_stream_filter *thisfilter TSRMLS_DC)
static php_stream_filter * php_mcrypt_filter_create (const char *filtername, zval *filterparams, int persistent TSRMLS_DC)

Variables

static php_stream_filter_ops php_mcrypt_filter_ops
php_stream_filter_factory php_mcrypt_filter_factory

Class Documentation

struct _php_mcrypt_filter_data

Definition at line 27 of file mcrypt_filter.c.

Class Members
char * block_buffer
int block_used
int blocksize
char encrypt
MCRYPT module
char persistent

Typedef Documentation


Function Documentation

static php_stream_filter_status_t php_mcrypt_filter ( php_stream *  stream,
php_stream_filter *  thisfilter,
php_stream_bucket_brigade *  buckets_in,
php_stream_bucket_brigade *  buckets_out,
size_t bytes_consumed,
int flags  TSRMLS_DC 
) [static]

Definition at line 36 of file mcrypt_filter.c.

{
       php_mcrypt_filter_data *data;
       php_stream_bucket *bucket;
       size_t consumed = 0;
       php_stream_filter_status_t exit_status = PSFS_FEED_ME;

       if (!thisfilter || !thisfilter->abstract) {
              /* Should never happen */
              return PSFS_ERR_FATAL;
       }

       data = (php_mcrypt_filter_data *)(thisfilter->abstract);
       while(buckets_in->head) {
              bucket = buckets_in->head;

              consumed += bucket->buflen;

              if (data->blocksize) {
                     /* Blockmode cipher */
                     char *outchunk;
                     int chunklen = bucket->buflen + data->block_used, n;
                     php_stream_bucket *newbucket;

                     outchunk = pemalloc(chunklen, data->persistent);
                     if (data->block_used) {
                            memcpy(outchunk, data->block_buffer, data->block_used);
                     }
                     memcpy(outchunk + data->block_used, bucket->buf, bucket->buflen);

                     for(n=0; (n + data->blocksize) <= chunklen; n += data->blocksize) {

                            if (data->encrypt) {
                                   mcrypt_generic(data->module, outchunk + n, data->blocksize);
                            } else {
                                   mdecrypt_generic(data->module, outchunk + n, data->blocksize);
                            }
                     }
                     data->block_used = chunklen - n;
                     memcpy(data->block_buffer, outchunk + n, data->block_used);

                     newbucket = php_stream_bucket_new(stream, outchunk, n, 1, data->persistent TSRMLS_CC);
                     php_stream_bucket_append(buckets_out, newbucket TSRMLS_CC);

                     exit_status = PSFS_PASS_ON;

                     php_stream_bucket_unlink(bucket TSRMLS_CC);
                     php_stream_bucket_delref(bucket TSRMLS_CC);
              } else {
                     /* Stream cipher */
                     php_stream_bucket_make_writeable(bucket TSRMLS_CC);
                     if (data->encrypt) {
                            mcrypt_generic(data->module, bucket->buf, bucket->buflen);
                     } else {
                            mdecrypt_generic(data->module, bucket->buf, bucket->buflen);
                     }
                     php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);

                     exit_status = PSFS_PASS_ON;
              }
       }

       if ((flags & PSFS_FLAG_FLUSH_CLOSE) && data->blocksize && data->block_used) {
              php_stream_bucket *newbucket;

              memset(data->block_buffer + data->block_used, 0, data->blocksize - data->block_used);
              if (data->encrypt) {
                     mcrypt_generic(data->module, data->block_buffer, data->blocksize);
              } else {
                     mdecrypt_generic(data->module, data->block_buffer, data->blocksize);
              }

              newbucket = php_stream_bucket_new(stream, data->block_buffer, data->blocksize, 0, data->persistent TSRMLS_CC);
              php_stream_bucket_append(buckets_out, newbucket TSRMLS_CC);

              exit_status = PSFS_PASS_ON;
       }

       if (bytes_consumed) {
              *bytes_consumed = consumed;
       }

       return exit_status;
}

Here is the call graph for this function:

static php_stream_filter* php_mcrypt_filter_create ( const char *  filtername,
zval *  filterparams,
int persistent  TSRMLS_DC 
) [static]

Definition at line 152 of file mcrypt_filter.c.

{
       int encrypt = 1, iv_len, key_len, keyl, result;
       const char *cipher = filtername + sizeof("mcrypt.") - 1;
       zval **tmpzval;
       MCRYPT mcrypt_module;
       char *iv = NULL, *key = NULL;
       char *algo_dir = INI_STR("mcrypt.algorithms_dir");
       char *mode_dir = INI_STR("mcrypt.modes_dir");
       char *mode = "cbc";
       php_mcrypt_filter_data *data;

       if (strncasecmp(filtername, "mdecrypt.", sizeof("mdecrypt.") - 1) == 0) {
              encrypt = 0;
              cipher += sizeof("de") - 1;
       } else if (strncasecmp(filtername, "mcrypt.", sizeof("mcrypt.") - 1) != 0) {
              /* Should never happen */
              return NULL;
       }

       if (!filterparams || Z_TYPE_P(filterparams) != IS_ARRAY) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter parameters for %s must be an array", filtername);
              return NULL;
       }

       if (zend_hash_find(HASH_OF(filterparams), "mode", sizeof("mode"), (void**)&tmpzval) == SUCCESS) {
              if (Z_TYPE_PP(tmpzval) == IS_STRING) {
                     mode = Z_STRVAL_PP(tmpzval);
              } else {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode is not a string, ignoring");
              }
       }

       if (zend_hash_find(HASH_OF(filterparams), "algorithms_dir", sizeof("algorithms_dir"), (void**)&tmpzval) == SUCCESS) {
              if (Z_TYPE_PP(tmpzval) == IS_STRING) {
                     algo_dir = Z_STRVAL_PP(tmpzval);
              } else {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "algorithms_dir is not a string, ignoring");
              }
       }

       if (zend_hash_find(HASH_OF(filterparams), "modes_dir", sizeof("modes_dir"), (void**)&tmpzval) == SUCCESS) {
              if (Z_TYPE_PP(tmpzval) == IS_STRING) {
                     mode_dir = Z_STRVAL_PP(tmpzval);
              } else {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "modes_dir is not a string, ignoring");
              }
       }

       if (zend_hash_find(HASH_OF(filterparams), "key", sizeof("key"), (void**)&tmpzval) == SUCCESS &&
              Z_TYPE_PP(tmpzval) == IS_STRING) {
              key = Z_STRVAL_PP(tmpzval);
              key_len = Z_STRLEN_PP(tmpzval);
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "key not specified or is not a string");
              return NULL;
       }

       mcrypt_module = mcrypt_module_open(cipher, algo_dir, mode, mode_dir);
       if (mcrypt_module == MCRYPT_FAILED) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open encryption module");
              return NULL;
       }
       iv_len = mcrypt_enc_get_iv_size(mcrypt_module);
       keyl = mcrypt_enc_get_key_size(mcrypt_module);
       if (keyl < key_len) {
              key_len = keyl;
       }

       if (zend_hash_find(HASH_OF(filterparams), "iv", sizeof("iv"), (void**) &tmpzval) == FAILURE ||
              Z_TYPE_PP(tmpzval) != IS_STRING) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter parameter[iv] not provided or not of type: string");
              mcrypt_module_close(mcrypt_module);
              return NULL;
       }

       iv = emalloc(iv_len + 1);
       if (iv_len <= Z_STRLEN_PP(tmpzval)) {
              memcpy(iv, Z_STRVAL_PP(tmpzval), iv_len);
       } else {
              memcpy(iv, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
              memset(iv + Z_STRLEN_PP(tmpzval), 0, iv_len - Z_STRLEN_PP(tmpzval));
       }

       result = mcrypt_generic_init(mcrypt_module, key, key_len, iv);
       efree(iv);
       if (result < 0) {
              switch (result) {
                     case -3:
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key length incorrect");
                            break;
                     case -4:
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation error");
                            break;
                     case -1:
                     default:
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error");
                            break;
              }
              mcrypt_module_close(mcrypt_module);
              return NULL;
       }

       data = pemalloc(sizeof(php_mcrypt_filter_data), persistent);
       data->module = mcrypt_module;
       data->encrypt = encrypt;
       if (mcrypt_enc_is_block_mode(mcrypt_module)) {
              data->blocksize = mcrypt_enc_get_block_size(mcrypt_module);
              data->block_buffer = pemalloc(data->blocksize, persistent);
       } else {
              data->blocksize = 0;
              data->block_buffer = NULL;
       }
       data->block_used = 0;
       data->persistent = persistent;

       return php_stream_filter_alloc(&php_mcrypt_filter_ops, data, persistent);
}

Here is the call graph for this function:

static void php_mcrypt_filter_dtor ( php_stream_filter *thisfilter  TSRMLS_DC) [static]

Definition at line 127 of file mcrypt_filter.c.

{
       if (thisfilter && thisfilter->abstract) {
              php_mcrypt_filter_data *data = (php_mcrypt_filter_data*)thisfilter->abstract;

              if (data->block_buffer) {
                     pefree(data->block_buffer, data->persistent);
              }

              mcrypt_generic_deinit(data->module);
              mcrypt_module_close(data->module);

              pefree(data, data->persistent);
       }
}

Variable Documentation

Initial value:

Definition at line 272 of file mcrypt_filter.c.

Initial value:

Definition at line 143 of file mcrypt_filter.c.