summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorblotus2017-10-02 16:53:49 +0200
committerGitHub2017-10-02 16:53:49 +0200
commit377cb2a15db578bc61f72c3f8d092599d7a44519 (patch)
treeec8ccd072e77df0507bd5e0c4e38449653afed4d
parent15216b5b09b918a45f8ea9a68393ca178d716dc3 (diff)
parent3552ac0647966ea8bd6ddf0df6ac899421503e8e (diff)
Merge pull request #19 from nbs-system/9-cookies-encryption-env-var
Allow to chose the environment variable to derive the cookie encryption key from.
-rw-r--r--doc/source/config.rst44
-rw-r--r--doc/source/features.rst13
-rw-r--r--src/sp_config.c13
-rw-r--r--src/sp_config.h39
-rw-r--r--src/sp_config_keywords.c35
-rw-r--r--src/sp_config_utils.c50
-rw-r--r--src/sp_cookie_encryption.c18
-rw-r--r--src/sp_network_utils.c31
-rw-r--r--src/sp_network_utils.h1
-rw-r--r--src/tests/broken_conf_expecting_int.phpt9
-rw-r--r--src/tests/broken_conf_line_too_long.phpt10
-rw-r--r--src/tests/broken_conf_no_closing_misc.phpt10
-rw-r--r--src/tests/config/broken_conf_expecting_int.ini2
-rw-r--r--src/tests/config/broken_conf_line_empty_string.ini2
-rw-r--r--src/tests/config/broken_conf_line_no_closing.ini2
-rw-r--r--src/tests/config/broken_conf_line_too_long.ini1
-rw-r--r--src/tests/config/broken_conf_lots_of_quotes.ini2
-rw-r--r--src/tests/config/broken_conf_no_closing_misc.ini1
-rw-r--r--src/tests/config/broken_conf_wrong_quotes.ini2
-rw-r--r--src/tests/config/config_encrypted_cookies.ini4
-rw-r--r--src/tests/config/encrypt_cookies_no_env.ini2
-rw-r--r--src/tests/config/encrypt_cookies_no_key.ini2
-rw-r--r--src/tests/encrypt_cookies.phpt2
-rw-r--r--src/tests/encrypt_cookies3.phpt2
-rw-r--r--src/tests/encrypt_cookies_no_env.phpt19
-rw-r--r--src/tests/encrypt_cookies_no_key.phpt19
26 files changed, 141 insertions, 194 deletions
diff --git a/doc/source/config.rst b/doc/source/config.rst
index 25a6b73..7170385 100644
--- a/doc/source/config.rst
+++ b/doc/source/config.rst
@@ -38,7 +38,7 @@ global_strict
38^^^^^^^^^^^^^ 38^^^^^^^^^^^^^
39`default: disabled` 39`default: disabled`
40 40
41``global_strict`` will enable the `strict <https://secure.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict>`_ mode globally, 41``global_strict`` will enable the `strict <https://secure.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict>`_ mode globally,
42forcing PHP to throw a `TypeError <https://secure.php.net/manual/en/class.typeerror.php>`_ 42forcing PHP to throw a `TypeError <https://secure.php.net/manual/en/class.typeerror.php>`_
43exception if an argument type being passed to a function does not match its corresponding declared parameter type. 43exception if an argument type being passed to a function does not match its corresponding declared parameter type.
44 44
@@ -53,7 +53,7 @@ harden_random
53^^^^^^^^^^^^^ 53^^^^^^^^^^^^^
54 * `default: enabled` 54 * `default: enabled`
55 * `more <features.html#weak-prng-via-rand-mt-rand>`__ 55 * `more <features.html#weak-prng-via-rand-mt-rand>`__
56 56
57``harden_random`` will silently replace the insecure `rand <https://secure.php.net/manual/en/function.rand.php>`_ 57``harden_random`` will silently replace the insecure `rand <https://secure.php.net/manual/en/function.rand.php>`_
58and `mt_rand <https://secure.php.net/manual/en/function.mt-rand.php>`_ functions with 58and `mt_rand <https://secure.php.net/manual/en/function.mt-rand.php>`_ functions with
59the secure PRNG `random_int <https://secure.php.net/manual/en/function.random-int.php>`_. 59the secure PRNG `random_int <https://secure.php.net/manual/en/function.random-int.php>`_.
@@ -85,7 +85,7 @@ unserialize_hmac
85^^^^^^^^^^^^^^^^ 85^^^^^^^^^^^^^^^^
86 * `default: disabled` 86 * `default: disabled`
87 * `more <features.html#unserialize-related-magic>`__ 87 * `more <features.html#unserialize-related-magic>`__
88 88
89``unserialize_hmac`` will add integrity check to ``unserialize`` calls, preventing 89``unserialize_hmac`` will add integrity check to ``unserialize`` calls, preventing
90abritrary code execution in their context. 90abritrary code execution in their context.
91 91
@@ -101,7 +101,7 @@ auto_cookie_secure
101^^^^^^^^^^^^^^^^^^ 101^^^^^^^^^^^^^^^^^^
102 * `default: disabled` 102 * `default: disabled`
103 * `more <features.html#session-cookie-stealing-via-xss>`__ 103 * `more <features.html#session-cookie-stealing-via-xss>`__
104 104
105``auto_cookie_secure`` will automatically mark cookies as `secure <https://en.wikipedia.org/wiki/HTTP_cookie#Secure_cookie>`_ 105``auto_cookie_secure`` will automatically mark cookies as `secure <https://en.wikipedia.org/wiki/HTTP_cookie#Secure_cookie>`_
106when the web page is requested over HTTPS. 106when the web page is requested over HTTPS.
107 107
@@ -112,17 +112,19 @@ It can either be ``enabled`` or ``disabled``.
112 sp.auto_cookie_secure.enable(); 112 sp.auto_cookie_secure.enable();
113 sp.auto_cookie_secure.disable(); 113 sp.auto_cookie_secure.disable();
114 114
115.. _cookie-encryption_config:
115cookie_encryption 116cookie_encryption
116^^^^^^^^^^^^^^^^^ 117^^^^^^^^^^^^^^^^^
117 * `default: disabled` 118 * `default: disabled`
118 * `more <features.html#session-cookie-stealing-via-xss>`__ 119 * `more <features.html#session-cookie-stealing-via-xss>`__
119 120
120.. warning:: 121.. warning::
121 122
122 To use this feature, you **must** set the :ref:`global.secret_key <config_global>` variable. 123 To use this feature, you **must** set the :ref:`global.secret_key <config_global>` and
124 and the :ref:`global.cookie_env_var <config_global>` variables.
123 This design decision prevents attacker from 125 This design decision prevents attacker from
124 `trivially bruteforcing <https://www.idontplaydarts.com/2011/11/decrypting-suhosin-sessions-and-cookies/>`_ 126 `trivially bruteforcing <https://www.idontplaydarts.com/2011/11/decrypting-suhosin-sessions-and-cookies/>`_
125 session cookies. 127 or re-using session cookies.
126 128
127``cookie_secure`` will activate transparent encryption of specific cookies. 129``cookie_secure`` will activate transparent encryption of specific cookies.
128 130
@@ -133,6 +135,26 @@ It can either be ``enabled`` or ``disabled``, and used in ``simulation`` mode.
133 sp.cookie_encryption.cookie("my_cookie_name"); 135 sp.cookie_encryption.cookie("my_cookie_name");
134 sp.cookie_encryption.cookie("another_cookie_name"); 136 sp.cookie_encryption.cookie("another_cookie_name");
135 137
138Choosing the proper environment variable
139""""""""""""""""""""""""""""""""""""""""
140
141It's up to you to chose a meaningul environment variable to derive the key from.
142Suhosin `is using <https://www.suhosin.org/stories/configuration.html#suhosin-session-cryptraddr>`_
143the ``REMOTE_ADDR`` one, tying the validity of the cookie to the IP address of the user;
144unfortunately, nowadays, people are `roaming <https://en.wikipedia.org/wiki/Roaming>`_ a lot on their smartphone,
145hopping from WiFi to 4G, …
146
147This is why we recommend, if possible, to use the *extended master secret*
148from TLS connections (`RFC7627 <https://tools.ietf.org/html/rfc7627>`_)
149instead, to make the valitity of the cookie TLS-dependent, by using the ``SSL_SESSION_ID`` variable.
150
151- In `Apache <https://httpd.apache.org/docs/current/mod/mod_ssl.html>`_,
152 it possible to enable by adding ``SSLOptions StdEnvVars`` in your Apache2 configuration.
153- In `nginx <https://nginx.org/en/docs/http/ngx_http_ssl_module.html#variables>`_,
154 you have to use ``fastcgi_param SSL_SESSION_ID $ssl_session_id if_not_empty;``.
155
156If you're not using TLS (you should.), you can always use the ``REMOTE_ADDR`` one,
157or ``X-Real-IP`` if you're behind a reverse proxy.
136 158
137readonly_exec 159readonly_exec
138^^^^^^^^^^^^^ 160^^^^^^^^^^^^^
@@ -151,7 +173,7 @@ upload_validation
151 * `default: disabled` 173 * `default: disabled`
152 * `more <features.html#remote-code-execution-via-file-upload>`__ 174 * `more <features.html#remote-code-execution-via-file-upload>`__
153 175
154``upload_validation`` will call a given script upon a file upload, with the path 176``upload_validation`` will call a given script upon a file upload, with the path
155to the file being uploaded as argument, and various information about it in the environment: 177to the file being uploaded as argument, and various information about it in the environment:
156 178
157* ``SP_FILENAME``: the name of the uploaded file 179* ``SP_FILENAME``: the name of the uploaded file
@@ -192,8 +214,8 @@ Snuffleupagus provides virtual-patching, via the ``disable_functions`` directive
192Admitting you have a call to ``system()`` that lacks proper user-input validation, thus leading to an **RCE**, this might be the right tool. 214Admitting you have a call to ``system()`` that lacks proper user-input validation, thus leading to an **RCE**, this might be the right tool.
193 215
194:: 216::
195 217
196 # Restrict calls to `system` to `id` in the `id.php` file 218 # Allow `id.php` to restrict system() calls to `id`
197 sp.disable_functions.function("system").filename("id.php").param("cmd").value("id").allow(); 219 sp.disable_functions.function("system").filename("id.php").param("cmd").value("id").allow();
198 sp.disable_functions.function("system").filename("id.php").drop() 220 sp.disable_functions.function("system").filename("id.php").drop()
199 221
@@ -293,4 +315,4 @@ Miscellaneous examples
293"""""""""""""""""""""" 315""""""""""""""""""""""
294 316
295.. literalinclude:: ../../config/examples.ini 317.. literalinclude:: ../../config/examples.ini
296 :language: python \ No newline at end of file 318 :language: python
diff --git a/doc/source/features.rst b/doc/source/features.rst
index fbb2a64..c0fade3 100644
--- a/doc/source/features.rst
+++ b/doc/source/features.rst
@@ -61,17 +61,16 @@ Session-cookie stealing via XSS
61^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 61^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62 62
63The goto payload for XSS is often to steal cookies. 63The goto payload for XSS is often to steal cookies.
64Like *Suhosin*, we are encrypting the cookies with a secret key, the IP of the user 64Like *Suhosin*, we are encrypting the cookies with a secret key,
65an environment variable (usually the IP of the user)
65and its user-agent. This means that an attacker with an XSS won't be able to use 66and its user-agent. This means that an attacker with an XSS won't be able to use
66the stolen cookie, since he (often) can't spoof the IP address of the user. 67the stolen cookie, since he can't spoof the content of the value of the environment
68variable for the user. Please do read the :ref:`documentation about this feature <cookie-encryption_config>`
69if you're planning to use it.
67 70
68This feature is roughly the same than the `Suhosin one <https://suhosin.org/stories/configuration.html#transparent-encryption-options>`_. 71This feature is roughly the same than the `Suhosin one <https://suhosin.org/stories/configuration.html#transparent-encryption-options>`_.
69 72
70Users behind the same IP address but with different browsers won't be able to use each other stolen cookies, 73Having a secret server-side key will prevent anyone (even the user himself)
71except if they can manage to guess the user agent. This isn't especially difficult,
72but an invalid decryption will leave a trace in the logs.
73
74Finally, having a secret server-side key will prevent anyone (even the user himself)
75from reading the content of the cookie, reducing the impact of an application storing sensitive data client-side. 74from reading the content of the cookie, reducing the impact of an application storing sensitive data client-side.
76 75
77The encryption is done via the `tweetnacl library <https://tweetnacl.cr.yp.to/>`_, 76The encryption is done via the `tweetnacl library <https://tweetnacl.cr.yp.to/>`_,
diff --git a/src/sp_config.c b/src/sp_config.c
index 3da027c..c41b8f7 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -55,19 +55,6 @@ int parse_empty(char *restrict line, char *restrict keyword, void *retval) {
55 return 0; 55 return 0;
56} 56}
57 57
58int parse_int(char *restrict line, char *restrict keyword, void *retval) {
59 size_t consumed = 0;
60 char *value = get_param(&consumed, line, SP_TYPE_INT, keyword);
61 if (value) {
62 sscanf(value, "%ud", (uint32_t *)retval);
63 pefree(value, 1);
64 return consumed;
65 } else {
66 sp_log_err("error", "%s) is expecting a valid integer on line %zu.", keyword, sp_line_no);
67 return -1;
68 }
69}
70
71int parse_php_type(char *restrict line, char *restrict keyword, void *retval) { 58int parse_php_type(char *restrict line, char *restrict keyword, void *retval) {
72 size_t consumed = 0; 59 size_t consumed = 0;
73 char *value = get_param(&consumed, line, SP_TYPE_STR, keyword); 60 char *value = get_param(&consumed, line, SP_TYPE_STR, keyword);
diff --git a/src/sp_config.h b/src/sp_config.h
index 8d41333..34096ce 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -15,16 +15,16 @@ typedef enum {
15} sp_type; 15} sp_type;
16 16
17typedef enum { 17typedef enum {
18 SP_PHP_TYPE_UNDEF = IS_UNDEF, 18 SP_PHP_TYPE_UNDEF = IS_UNDEF,
19 SP_PHP_TYPE_NULL = IS_NULL, 19 SP_PHP_TYPE_NULL = IS_NULL,
20 SP_PHP_TYPE_FALSE = IS_FALSE, 20 SP_PHP_TYPE_FALSE = IS_FALSE,
21 SP_PHP_TYPE_TRUE = IS_TRUE, 21 SP_PHP_TYPE_TRUE = IS_TRUE,
22 SP_PHP_TYPE_LONG = IS_LONG, 22 SP_PHP_TYPE_LONG = IS_LONG,
23 SP_PHP_TYPE_DOUBLE = IS_DOUBLE, 23 SP_PHP_TYPE_DOUBLE = IS_DOUBLE,
24 SP_PHP_TYPE_STRING = IS_STRING, 24 SP_PHP_TYPE_STRING = IS_STRING,
25 SP_PHP_TYPE_ARRAY = IS_ARRAY, 25 SP_PHP_TYPE_ARRAY = IS_ARRAY,
26 SP_PHP_TYPE_OBJECT = IS_OBJECT, 26 SP_PHP_TYPE_OBJECT = IS_OBJECT,
27 SP_PHP_TYPE_RESOURCE = IS_RESOURCE, 27 SP_PHP_TYPE_RESOURCE = IS_RESOURCE,
28 SP_PHP_TYPE_REFERENCE = IS_REFERENCE 28 SP_PHP_TYPE_REFERENCE = IS_REFERENCE
29} sp_php_type; 29} sp_php_type;
30 30
@@ -37,7 +37,10 @@ typedef struct {
37 uint8_t mask; 37 uint8_t mask;
38} sp_cidr; 38} sp_cidr;
39 39
40typedef struct { char *encryption_key; } sp_config_encryption_key; 40typedef struct {
41 char *encryption_key;
42 char *cookies_env_var;
43} sp_config_global;
41 44
42typedef struct { 45typedef struct {
43 bool enable; 46 bool enable;
@@ -52,11 +55,7 @@ typedef struct { bool enable; } sp_config_auto_cookie_secure;
52 55
53typedef struct { bool enable; } sp_config_disable_xxe; 56typedef struct { bool enable; } sp_config_disable_xxe;
54 57
55typedef struct { 58typedef struct { HashTable *names; } sp_config_cookie_encryption;
56 HashTable *names;
57 uint32_t mask_ipv4;
58 uint32_t mask_ipv6;
59} sp_config_cookie_encryption;
60 59
61typedef struct { 60typedef struct {
62 bool enable; 61 bool enable;
@@ -81,7 +80,7 @@ typedef struct {
81 char *ret; 80 char *ret;
82 pcre *r_ret; 81 pcre *r_ret;
83 sp_php_type ret_type; 82 sp_php_type ret_type;
84 83
85 pcre *regexp; 84 pcre *regexp;
86 char *value; 85 char *value;
87 86
@@ -122,7 +121,7 @@ typedef struct {
122 sp_config_readonly_exec *config_readonly_exec; 121 sp_config_readonly_exec *config_readonly_exec;
123 sp_config_upload_validation *config_upload_validation; 122 sp_config_upload_validation *config_upload_validation;
124 sp_config_cookie_encryption *config_cookie_encryption; 123 sp_config_cookie_encryption *config_cookie_encryption;
125 sp_config_encryption_key *config_snuffleupagus; 124 sp_config_global *config_snuffleupagus;
126 sp_config_auto_cookie_secure *config_auto_cookie_secure; 125 sp_config_auto_cookie_secure *config_auto_cookie_secure;
127 sp_config_global_strict *config_global_strict; 126 sp_config_global_strict *config_global_strict;
128 sp_config_disable_xxe *config_disable_xxe; 127 sp_config_disable_xxe *config_disable_xxe;
@@ -185,11 +184,10 @@ typedef struct {
185 184
186// cookies encryption 185// cookies encryption
187#define SP_TOKEN_NAME ".cookie(" 186#define SP_TOKEN_NAME ".cookie("
188#define SP_TOKEN_MASK_IPV4 ".mask_ipv4("
189#define SP_TOKEN_MASK_IPV6 ".mask_ipv6("
190 187
191// Global configuration options 188// Global configuration options
192#define SP_TOKEN_ENCRYPTION_KEY ".secret_key(" 189#define SP_TOKEN_ENCRYPTION_KEY ".secret_key("
190#define SP_TOKEN_ENV_VAR ".cookie_env_var("
193 191
194// upload_validator 192// upload_validator
195#define SP_TOKEN_UPLOAD_SCRIPT ".script(" 193#define SP_TOKEN_UPLOAD_SCRIPT ".script("
@@ -200,7 +198,6 @@ int parse_array(sp_disabled_function *);
200int parse_str(char *restrict, char *restrict, void *); 198int parse_str(char *restrict, char *restrict, void *);
201int parse_regexp(char *restrict, char *restrict, void *); 199int parse_regexp(char *restrict, char *restrict, void *);
202int parse_empty(char *restrict, char *restrict, void *); 200int parse_empty(char *restrict, char *restrict, void *);
203int parse_int(char *restrict, char *restrict, void *);
204int parse_cidr(char *restrict, char *restrict, void *); 201int parse_cidr(char *restrict, char *restrict, void *);
205int parse_php_type(char *restrict, char *restrict, void *); 202int parse_php_type(char *restrict, char *restrict, void *);
206 203
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c
index b068bec..cf52ae3 100644
--- a/src/sp_config_keywords.c
+++ b/src/sp_config_keywords.c
@@ -19,10 +19,10 @@ static int parse_enable(char *line, bool * restrict retval, bool * restrict simu
19 if (!(enable ^ disable)) { 19 if (!(enable ^ disable)) {
20 sp_log_err("config", "A rule can't be enabled and disabled on line %zu.", sp_line_no); 20 sp_log_err("config", "A rule can't be enabled and disabled on line %zu.", sp_line_no);
21 return -1; 21 return -1;
22 } 22 }
23 23
24 *retval = enable; 24 *retval = enable;
25 25
26 return ret; 26 return ret;
27} 27}
28 28
@@ -51,11 +51,13 @@ int parse_readonly_exec(char *line) {
51} 51}
52 52
53int parse_global(char *line) { 53int parse_global(char *line) {
54 sp_config_functions sp_config_funcs_encryption_key[] = { 54 sp_config_functions sp_config_global[] = {
55 {parse_str, SP_TOKEN_ENCRYPTION_KEY, 55 {parse_str, SP_TOKEN_ENCRYPTION_KEY,
56 &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)}, 56 &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)},
57 {parse_str, SP_TOKEN_ENV_VAR,
58 &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)},
57 {0}}; 59 {0}};
58 return parse_keywords(sp_config_funcs_encryption_key, line); 60 return parse_keywords(sp_config_global, line);
59} 61}
60 62
61int parse_cookie_encryption(char *line) { 63int parse_cookie_encryption(char *line) {
@@ -64,10 +66,6 @@ int parse_cookie_encryption(char *line) {
64 66
65 sp_config_functions sp_config_funcs_cookie_encryption[] = { 67 sp_config_functions sp_config_funcs_cookie_encryption[] = {
66 {parse_str, SP_TOKEN_NAME, &name}, 68 {parse_str, SP_TOKEN_NAME, &name},
67 {parse_int, SP_TOKEN_MASK_IPV4,
68 &(SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv4)},
69 {parse_int, SP_TOKEN_MASK_IPV6,
70 &(SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv6)},
71 {0}}; 69 {0}};
72 70
73 ret = parse_keywords(sp_config_funcs_cookie_encryption, line); 71 ret = parse_keywords(sp_config_funcs_cookie_encryption, line);
@@ -75,11 +73,16 @@ int parse_cookie_encryption(char *line) {
75 return ret; 73 return ret;
76 } 74 }
77 75
78 if (32 < SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv4) { 76 if (0 == (SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)) {
79 SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv4 = 32; 77 sp_log_err("config", "You're trying to use the cookie encryption feature"
80 } 78 "on line %zu without having set the `.cookie_env_var` option in"
81 if (128 < SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv6) { 79 "`sp.global`: please set it first.", sp_line_no);
82 SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv6 = 128; 80 return -1;
81 } else if (0 == (SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)) {
82 sp_log_err("config", "You're trying to use the cookie encryption feature"
83 "on line %zu without having set the `.encryption_key` option in"
84 "`sp.global`: please set it first.", sp_line_no);
85 return -1;
83 } 86 }
84 87
85 if (name) { 88 if (name) {
@@ -190,7 +193,7 @@ int parse_disabled_functions(char *line) {
190 } 193 }
191 df->param_is_array = 1; 194 df->param_is_array = 1;
192 } 195 }
193 196
194 if (df->var && strchr(df->var, '[')) { // assume that this is an array 197 if (df->var && strchr(df->var, '[')) { // assume that this is an array
195 df->var_array_keys = sp_new_list(); 198 df->var_array_keys = sp_new_list();
196 if (0 != array_to_list(&df->var, &df->var_array_keys)) { 199 if (0 != array_to_list(&df->var, &df->var_array_keys)) {
@@ -247,7 +250,7 @@ int parse_upload_validation(char *line) {
247 if (!(enable ^ disable)) { 250 if (!(enable ^ disable)) {
248 sp_log_err("config", "A rule can't be enabled and disabled on line %zu.", sp_line_no); 251 sp_log_err("config", "A rule can't be enabled and disabled on line %zu.", sp_line_no);
249 return -1; 252 return -1;
250 } 253 }
251 SNUFFLEUPAGUS_G(config).config_upload_validation->enable = enable; 254 SNUFFLEUPAGUS_G(config).config_upload_validation->enable = enable;
252 255
253 char const *script = SNUFFLEUPAGUS_G(config).config_upload_validation->script; 256 char const *script = SNUFFLEUPAGUS_G(config).config_upload_validation->script;
@@ -263,6 +266,6 @@ int parse_upload_validation(char *line) {
263 sp_log_err("config", "The `script` (%s) isn't executable on line %zu.", script, sp_line_no); 266 sp_log_err("config", "The `script` (%s) isn't executable on line %zu.", script, sp_line_no);
264 return -1; 267 return -1;
265 } 268 }
266 269
267 return ret; 270 return ret;
268} 271}
diff --git a/src/sp_config_utils.c b/src/sp_config_utils.c
index 39951cc..3ea82d0 100644
--- a/src/sp_config_utils.c
+++ b/src/sp_config_utils.c
@@ -2,18 +2,8 @@
2 2
3size_t sp_line_no; 3size_t sp_line_no;
4 4
5static int validate_int(const char *value);
6static int validate_str(const char *value); 5static int validate_str(const char *value);
7 6
8static sp_pure int validate_int(const char *value) {
9 for (size_t i = 0; i < strlen(value); i++) {
10 if (!isdigit(value[i])) {
11 return -1;
12 }
13 }
14 return 0;
15}
16
17static sp_pure int validate_str(const char *value) { 7static sp_pure int validate_str(const char *value) {
18 int balance = 0; // ghetto [] validation 8 int balance = 0; // ghetto [] validation
19 9
@@ -124,48 +114,14 @@ err:
124 return NULL; 114 return NULL;
125} 115}
126 116
127static char *get_misc(char *restrict line, const char *restrict keyword) {
128 size_t i = 0;
129 char *ret = pecalloc(sizeof(char), 1024, 1);
130
131 while (i < 1024 - 1 && line[i] && line[i] != SP_TOKEN_END_PARAM) {
132 ret[i] = line[i];
133 i++;
134 }
135
136 if (line[i] != SP_TOKEN_END_PARAM) {
137 if (i >= 1024 - 1) {
138 sp_log_err("config", "The following line is too long: %s on line %zu.", line, sp_line_no);
139 } else {
140 sp_log_err("config", "Missing closing %c in line %s on line %zu.", SP_TOKEN_END_PARAM,
141 line, sp_line_no);
142 }
143 return NULL;
144 } else if (i == 0) {
145 sp_log_err("config", "The keyword %s%c is expecting a parameter on line %zu.",
146 keyword, SP_TOKEN_END_PARAM, sp_line_no);
147 return NULL;
148 }
149 return ret;
150}
151
152char *get_param(size_t *consumed, char *restrict line, sp_type type, 117char *get_param(size_t *consumed, char *restrict line, sp_type type,
153 const char *restrict keyword) { 118 const char *restrict keyword) {
154 char *retval = NULL; 119 char *retval = get_string(consumed, line, keyword);
155 if (type == SP_TYPE_STR) {
156 retval = get_string(consumed, line, keyword);
157 } else {
158 retval = get_misc(line, keyword);
159 *consumed = retval ? strlen(retval) : 0;
160 }
161 120
162 if (retval) { 121 if (retval && 0 == validate_str(retval)) {
163 if (type == SP_TYPE_STR && 0 == validate_str(retval)) {
164 return retval;
165 } else if (type == SP_TYPE_INT && 0 == validate_int(retval)) {
166 return retval; 122 return retval;
167 }
168 } 123 }
124
169 return NULL; 125 return NULL;
170} 126}
171 127
diff --git a/src/sp_cookie_encryption.c b/src/sp_cookie_encryption.c
index a47f6e1..a65a748 100644
--- a/src/sp_cookie_encryption.c
+++ b/src/sp_cookie_encryption.c
@@ -9,7 +9,8 @@ static unsigned int nonce_d = 0;
9static inline void generate_key(unsigned char *key) { 9static inline void generate_key(unsigned char *key) {
10 PHP_SHA256_CTX ctx; 10 PHP_SHA256_CTX ctx;
11 const char *user_agent = sp_getenv("HTTP_USER_AGENT"); 11 const char *user_agent = sp_getenv("HTTP_USER_AGENT");
12 const char *remote_addr = sp_getenv("REMOTE_ADDR"); 12 const char *env_var =
13 sp_getenv(SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var);
13 const char *encryption_key = 14 const char *encryption_key =
14 SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key; 15 SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key;
15 16
@@ -22,10 +23,12 @@ static inline void generate_key(unsigned char *key) {
22 PHP_SHA256Update(&ctx, (unsigned char *)user_agent, strlen(user_agent)); 23 PHP_SHA256Update(&ctx, (unsigned char *)user_agent, strlen(user_agent));
23 } 24 }
24 25
25 if (remote_addr) { 26 if (env_var) {
26 char out[128]; 27 PHP_SHA256Update(&ctx, (unsigned char*)env_var, strlen(env_var));
27 apply_mask_on_ip(out, remote_addr); 28 } else {
28 PHP_SHA256Update(&ctx, (unsigned char*)out, sizeof(out)); 29 sp_log_err("cookie_encryption", "The environment variable '%s'"
30 "is empty, cookies are weakly encrypted.",
31 SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var);
29 } 32 }
30 33
31 if (encryption_key) { 34 if (encryption_key) {
@@ -115,8 +118,11 @@ static zend_string *encrypt_data(char *data, unsigned long long data_len) {
115 118
116 assert(sizeof(size_t) <= crypto_secretbox_NONCEBYTES); 119 assert(sizeof(size_t) <= crypto_secretbox_NONCEBYTES);
117 120
121 if (0 == nonce_d) {
122 nonce_d = getpid();
123 }
118 nonce_d++; 124 nonce_d++;
119 sscanf((char*)nonce, "%ud", &nonce_d); 125 sscanf((char*)nonce, "%ud", &nonce_d);
120 126
121 memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES); 127 memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES);
122 crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES, 128 crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES,
diff --git a/src/sp_network_utils.c b/src/sp_network_utils.c
index 28bc324..4b78ca5 100644
--- a/src/sp_network_utils.c
+++ b/src/sp_network_utils.c
@@ -12,37 +12,6 @@ static inline bool cidr6_match(const struct in6_addr address,
12 const struct in6_addr network, uint8_t bits); 12 const struct in6_addr network, uint8_t bits);
13static inline int get_ip_version(const char *ip); 13static inline int get_ip_version(const char *ip);
14 14
15void apply_mask_on_ip(char *out, const char *const remote_addr) {
16 uint8_t mask4 = SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv4;
17 uint8_t mask6 = SNUFFLEUPAGUS_G(config).config_cookie_encryption->mask_ipv6;
18 const int ip_version = get_ip_version(remote_addr);
19
20 memset(out, 0, 128);
21
22 if (ip_version == AF_INET) {
23 struct in_addr out4;
24 inet_pton(AF_INET, remote_addr, &out4);
25 const long n = out4.s_addr & htonl(0xFFFFFFFFu << (32 - mask4));
26 out[0] = (n >> 24) & 0xFF;
27 out[1] = (n >> 16) & 0xFF;
28 out[2] = (n >> 8) & 0xFF;
29 out[3] = (n >> 0) & 0xFF;
30 } else if (ip_version == AF_INET6) {
31 inet_pton(AF_INET6, remote_addr, out);
32 uint32_t *p_ip = (uint32_t *)out;
33 while (32 < mask6) {
34 *p_ip = 0xFFFFFFFFu;
35 p_ip++;
36 mask6 -= 32;
37 }
38 if (0 != mask6) {
39 *p_ip = htonl(0xFFFFFFFFu << (32 - mask6));
40 }
41 } else {
42 sp_log_err("ip_mask", "It seems that %s isn't a valid ip.", remote_addr);
43 }
44}
45
46/* http://fxr.watson.org/fxr/source/include/net/xfrm.h?v=linux-2.6#L840 */ 15/* http://fxr.watson.org/fxr/source/include/net/xfrm.h?v=linux-2.6#L840 */
47static inline bool cidr4_match(const struct in_addr addr, 16static inline bool cidr4_match(const struct in_addr addr,
48 const struct in_addr net, uint8_t bits) { 17 const struct in_addr net, uint8_t bits) {
diff --git a/src/sp_network_utils.h b/src/sp_network_utils.h
index 6b6ce92..2c1062a 100644
--- a/src/sp_network_utils.h
+++ b/src/sp_network_utils.h
@@ -3,6 +3,5 @@
3 3
4int get_ip_and_cidr(char *, sp_cidr *); 4int get_ip_and_cidr(char *, sp_cidr *);
5bool cidr_match(const char *, const sp_cidr *); 5bool cidr_match(const char *, const sp_cidr *);
6void apply_mask_on_ip(char *, const char * const);
7 6
8#endif /*SP_NETWORK_UTILS_H*/ 7#endif /*SP_NETWORK_UTILS_H*/
diff --git a/src/tests/broken_conf_expecting_int.phpt b/src/tests/broken_conf_expecting_int.phpt
deleted file mode 100644
index 207e21a..0000000
--- a/src/tests/broken_conf_expecting_int.phpt
+++ /dev/null
@@ -1,9 +0,0 @@
1--TEST--
2Bad integer value in configuration
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/broken_conf_expecting_int.ini
7--FILE--
8--EXPECT--
9[snuffleupagus][0.0.0.0][error][error] .mask_ipv4() is expecting a valid integer on line 2.
diff --git a/src/tests/broken_conf_line_too_long.phpt b/src/tests/broken_conf_line_too_long.phpt
deleted file mode 100644
index c4e3938..0000000
--- a/src/tests/broken_conf_line_too_long.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
1--TEST--
2Line too long in configuration
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/broken_conf_line_too_long.ini
7--FILE--
8--EXPECT--
9[snuffleupagus][0.0.0.0][config][error] The following line is too long: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111); on line 1.
10[snuffleupagus][0.0.0.0][error][error] .mask_ipv4() is expecting a valid integer on line 1.
diff --git a/src/tests/broken_conf_no_closing_misc.phpt b/src/tests/broken_conf_no_closing_misc.phpt
deleted file mode 100644
index 933f290..0000000
--- a/src/tests/broken_conf_no_closing_misc.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
1--TEST--
2Configuration line without closing parenthese, misc
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/broken_conf_no_closing_misc.ini
7--FILE--
8--EXPECT--
9[snuffleupagus][0.0.0.0][config][error] Missing closing ) in line 123 on line 1.
10[snuffleupagus][0.0.0.0][error][error] .mask_ipv4() is expecting a valid integer on line 1.
diff --git a/src/tests/config/broken_conf_expecting_int.ini b/src/tests/config/broken_conf_expecting_int.ini
deleted file mode 100644
index 8e2efea..0000000
--- a/src/tests/config/broken_conf_expecting_int.ini
+++ /dev/null
@@ -1,2 +0,0 @@
1sp.global.secret_key("abcdef");
2sp.cookie_encryption.cookie("super_cookie").mask_ipv4(abc);
diff --git a/src/tests/config/broken_conf_line_empty_string.ini b/src/tests/config/broken_conf_line_empty_string.ini
index 74d0e5a..c130384 100644
--- a/src/tests/config/broken_conf_line_empty_string.ini
+++ b/src/tests/config/broken_conf_line_empty_string.ini
@@ -1 +1 @@
sp.cookie_encryption.mask_ipv4(123).cookie( sp.cookie_encryption.cookie(
diff --git a/src/tests/config/broken_conf_line_no_closing.ini b/src/tests/config/broken_conf_line_no_closing.ini
index bcac291..24dc3f0 100644
--- a/src/tests/config/broken_conf_line_no_closing.ini
+++ b/src/tests/config/broken_conf_line_no_closing.ini
@@ -1 +1 @@
sp.cookie_encryption.mask_ipv4(123).cookie("123" sp.cookie_encryption.cookie("123"
diff --git a/src/tests/config/broken_conf_line_too_long.ini b/src/tests/config/broken_conf_line_too_long.ini
deleted file mode 100644
index ed057a5..0000000
--- a/src/tests/config/broken_conf_line_too_long.ini
+++ /dev/null
@@ -1 +0,0 @@
1sp.cookie_encryption.cookie("super_cookie").mask_ipv4(1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111);
diff --git a/src/tests/config/broken_conf_lots_of_quotes.ini b/src/tests/config/broken_conf_lots_of_quotes.ini
index dfd48e7..310bce5 100644
--- a/src/tests/config/broken_conf_lots_of_quotes.ini
+++ b/src/tests/config/broken_conf_lots_of_quotes.ini
@@ -1 +1 @@
sp.cookie_encryption.mask_ipv4(123).cookie("this\"is a weird\"\"\"cookie\"name""); sp.cookie_encryption.cookie("this\"is a weird\"\"\"cookie\"name"");
diff --git a/src/tests/config/broken_conf_no_closing_misc.ini b/src/tests/config/broken_conf_no_closing_misc.ini
deleted file mode 100644
index 2cb79a8..0000000
--- a/src/tests/config/broken_conf_no_closing_misc.ini
+++ /dev/null
@@ -1 +0,0 @@
1sp.cookie_encryption.cookie("123").mask_ipv4(123
diff --git a/src/tests/config/broken_conf_wrong_quotes.ini b/src/tests/config/broken_conf_wrong_quotes.ini
index c8cc949..1c13e96 100644
--- a/src/tests/config/broken_conf_wrong_quotes.ini
+++ b/src/tests/config/broken_conf_wrong_quotes.ini
@@ -1 +1 @@
sp.cookie_encryption.mask_ipv4(123).cookie("\) sp.cookie_encryption.cookie("\)
diff --git a/src/tests/config/config_encrypted_cookies.ini b/src/tests/config/config_encrypted_cookies.ini
index 710e863..977d27f 100644
--- a/src/tests/config/config_encrypted_cookies.ini
+++ b/src/tests/config/config_encrypted_cookies.ini
@@ -1,3 +1,3 @@
1sp.global.secret_key("abcdef"); 1sp.global.secret_key("abcdef").cookie_env_var("REMOTE_ADDR");
2sp.cookie_encryption.cookie("super_cookie").mask_ipv4(8).mask_ipv6(2); 2sp.cookie_encryption.cookie("super_cookie");
3sp.auto_cookie_secure.enable(); 3sp.auto_cookie_secure.enable();
diff --git a/src/tests/config/encrypt_cookies_no_env.ini b/src/tests/config/encrypt_cookies_no_env.ini
new file mode 100644
index 0000000..9e1c025
--- /dev/null
+++ b/src/tests/config/encrypt_cookies_no_env.ini
@@ -0,0 +1,2 @@
1sp.global.secret_key("abcdef");
2sp.cookie_encryption.cookie("super_cookie");
diff --git a/src/tests/config/encrypt_cookies_no_key.ini b/src/tests/config/encrypt_cookies_no_key.ini
new file mode 100644
index 0000000..1b5cf83
--- /dev/null
+++ b/src/tests/config/encrypt_cookies_no_key.ini
@@ -0,0 +1,2 @@
1sp.global.cookie_env_var("TEST");
2sp.cookie_encryption.cookie("super_cookie");
diff --git a/src/tests/encrypt_cookies.phpt b/src/tests/encrypt_cookies.phpt
index f8bf64f..d581dbc 100644
--- a/src/tests/encrypt_cookies.phpt
+++ b/src/tests/encrypt_cookies.phpt
@@ -5,7 +5,7 @@ Cookie decryption in ipv4
5--INI-- 5--INI--
6sp.configuration_file={PWD}/config/config_encrypted_cookies.ini 6sp.configuration_file={PWD}/config/config_encrypted_cookies.ini
7--COOKIE-- 7--COOKIE--
8super_cookie=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEmXkk3H0xheoOMxoWPEDw1Zd8NAmD9KbB2DSjQ=%3d;awful_cookie=awful_cookie_value; 8super_cookie=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3gV9YJZL/pUeNAjCKFW0U2ywmf1CwHzwd2pWM=;awful_cookie=awful_cookie_value;
9--ENV-- 9--ENV--
10return <<<EOF 10return <<<EOF
11REMOTE_ADDR=127.0.0.1 11REMOTE_ADDR=127.0.0.1
diff --git a/src/tests/encrypt_cookies3.phpt b/src/tests/encrypt_cookies3.phpt
index c85c5dc..b4acbc0 100644
--- a/src/tests/encrypt_cookies3.phpt
+++ b/src/tests/encrypt_cookies3.phpt
@@ -5,7 +5,7 @@ Cookie decryption with ipv6
5--INI-- 5--INI--
6sp.configuration_file={PWD}/config/config_encrypted_cookies.ini 6sp.configuration_file={PWD}/config/config_encrypted_cookies.ini
7--COOKIE-- 7--COOKIE--
8super_cookie=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNTUge7MpiVNi4q3DqstbcumllXBir0CbIQiDI%3D;awful_cookie=awful_cookie_value; 8super_cookie=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABM84SCotZTpP6b27Lr5lavORPMvqaKpcUahvxw=;awful_cookie=awful_cookie_value;
9--ENV-- 9--ENV--
10return <<<EOF 10return <<<EOF
11REMOTE_ADDR=2001:0db8:0000:0000:0000:fe00:0042:8329 11REMOTE_ADDR=2001:0db8:0000:0000:0000:fe00:0042:8329
diff --git a/src/tests/encrypt_cookies_no_env.phpt b/src/tests/encrypt_cookies_no_env.phpt
new file mode 100644
index 0000000..47de27f
--- /dev/null
+++ b/src/tests/encrypt_cookies_no_env.phpt
@@ -0,0 +1,19 @@
1--TEST--
2Cookie encryption - no environment variable specified
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/encrypt_cookies_no_env.ini
7display_errors=1
8display_startup_errors=1
9error_reporting=E_ALL
10--COOKIE--
11super_cookie=1337;awful_cookie=awful_cookie_value;
12--ENV--
13return <<<EOF
14REMOTE_ADDR=127.0.0.1
15EOF;
16--FILE--
17<?php echo "1\n\n\n\n\n"; ?>
18--EXPECT--
191
diff --git a/src/tests/encrypt_cookies_no_key.phpt b/src/tests/encrypt_cookies_no_key.phpt
new file mode 100644
index 0000000..b54690f
--- /dev/null
+++ b/src/tests/encrypt_cookies_no_key.phpt
@@ -0,0 +1,19 @@
1--TEST--
2Cookie encryption - no encryption key specified
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/encrypt_cookies_no_key.ini
7display_errors=1
8display_startup_errors=1
9error_reporting=E_ALL
10--COOKIE--
11super_cookie=1337;awful_cookie=awful_cookie_value;
12--ENV--
13return <<<EOF
14REMOTE_ADDR=127.0.0.1
15EOF;
16--FILE--
17<?php echo "1\n\n\n\n\n"; ?>
18--EXPECT--
191