Author: rjung
Date: Fri Jun 22 09:00:23 2007
New Revision: 549857
URL: http://svn.apache.org/viewvc?view=rev&rev=549857
Log:
Update jk_canonenc and add it to IIS and Netscape.
- Remove unnecessary parts from the Apache reencoding port.
Those parts will become outdated and keeping them in the source
suggests they are well maintained.
Streamline jk_canonenc, in contrary to it's httpd origins,
we only use it in the reverse proxy case.
- Change the contract for jk_canonenc to make it better suited to
be used by all web servers:
- the length parameter now gives the maximum length to use
for the encoded URL
- the original URL needs to be '\0'-terminated.
- We now set a return value, indicating if the new URL got to large
- Add proxy encoding to IIS (new default)
and netscape (no choice).
- Add jk_url to the IIS build files
- Add forwarding debug logging to IIS and Netscape,
to make checking the URL reencoding easier.
Modified:
tomcat/connectors/trunk/jk/native/apache-1.3/mod_jk.c
tomcat/connectors/trunk/jk/native/apache-2.0/mod_jk.c
tomcat/connectors/trunk/jk/native/common/jk_url.c
tomcat/connectors/trunk/jk/native/common/jk_url.h
tomcat/connectors/trunk/jk/native/iis/Makefile.amd64
tomcat/connectors/trunk/jk/native/iis/Makefile.ia64
tomcat/connectors/trunk/jk/native/iis/Makefile.x86
tomcat/connectors/trunk/jk/native/iis/isapi.dsp
tomcat/connectors/trunk/jk/native/iis/jk_isapi_plugin.c
tomcat/connectors/trunk/jk/native/netscape/jk_nsapi_plugin.c
Modified: tomcat/connectors/trunk/jk/native/apache-1.3/mod_jk.c
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/apache-1.3/mod_jk.c?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/apache-1.3/mod_jk.c (original)
+++ tomcat/connectors/trunk/jk/native/apache-1.3/mod_jk.c Fri Jun 22 09:00:23
2007
@@ -612,10 +612,9 @@
break;
case JK_OPT_FWDURIPROXY:
- size = strlen(r->uri);
- s->req_uri = ap_palloc(r->pool, size * 3 + 1);
- jk_canonenc(s->req_uri, r->uri, size, enc_path, 0,
- JK_PROXYREQ_REVERSE);
+ size = 3 * strlen(r->uri) + 1;
+ s->req_uri = ap_palloc(r->pool, size);
+ jk_canonenc(r->uri, s->req_uri, size);
break;
case JK_OPT_FWDURIESCAPED:
Modified: tomcat/connectors/trunk/jk/native/apache-2.0/mod_jk.c
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/apache-2.0/mod_jk.c?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/apache-2.0/mod_jk.c (original)
+++ tomcat/connectors/trunk/jk/native/apache-2.0/mod_jk.c Fri Jun 22 09:00:23
2007
@@ -640,10 +640,9 @@
break;
case JK_OPT_FWDURIPROXY:
- size = strlen(r->uri);
- s->req_uri = apr_palloc(r->pool, size * 3 + 1);
- jk_canonenc(s->req_uri, r->uri, size, enc_path, 0,
- JK_PROXYREQ_REVERSE);
+ size = 3 * strlen(r->uri) + 1;
+ s->req_uri = apr_palloc(r->pool, size);
+ jk_canonenc(r->uri, s->req_uri, size);
break;
case JK_OPT_FWDURIESCAPED:
Modified: tomcat/connectors/trunk/jk/native/common/jk_url.c
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_url.c?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/common/jk_url.c (original)
+++ tomcat/connectors/trunk/jk/native/common/jk_url.c Fri Jun 22 09:00:23 2007
@@ -16,7 +16,7 @@
*/
/***************************************************************************
- * Description: URL manupilation subroutines. (ported from mod_proxy). *
+ * Description: URL manipulation subroutines. (ported from mod_proxy). *
* Version: $Revision: 531816 $ *
***************************************************************************/
@@ -35,61 +35,6 @@
#define JK_ISALNUM(x) isalnum((int)(unsigned char)((x)))
#endif
-/* already called in the knowledge that the characters are hex digits */
-static int jk_hex2c(const char *x)
-{
- int i, ch;
-
-#if !CHARSET_EBCDIC
- ch = x[0];
- if (JK_ISDIGIT(ch)) {
- i = ch - '0';
- }
- else if (JK_ISUPPER(ch)) {
- i = ch - ('A' - 10);
- }
- else {
- i = ch - ('a' - 10);
- }
- i <<= 4;
-
- ch = x[1];
- if (JK_ISDIGIT(ch)) {
- i += ch - '0';
- }
- else if (JK_ISUPPER(ch)) {
- i += ch - ('A' - 10);
- }
- else {
- i += ch - ('a' - 10);
- }
- return i;
-#else /*CHARSET_EBCDIC*/
- /*
- * we assume that the hex value refers to an ASCII character
- * so convert to EBCDIC so that it makes sense locally;
- *
- * example:
- *
- * client specifies %20 in URL to refer to a space char;
- * at this point we're called with EBCDIC "20"; after turning
- * EBCDIC "20" into binary 0x20, we then need to assume that 0x20
- * represents an ASCII char and convert 0x20 to EBCDIC, yielding
- * 0x40
- */
- char buf[1];
-
- if (1 == sscanf(x, "%2x", &i)) {
- buf[0] = i & 0xFF;
- jk_xlate_from_ascii(buf, 1);
- return buf[0];
- }
- else {
- return 0;
- }
-#endif /*CHARSET_EBCDIC*/
-}
-
static void jk_c2hex(int ch, char *x)
{
#if !CHARSET_EBCDIC
@@ -128,91 +73,52 @@
}
/*
- * canonicalise a URL-encoded string
- */
-
-/*
* Convert a URL-encoded string to canonical form.
- * It decodes characters which need not be encoded,
- * and encodes those which must be encoded, and does not touch
+ * It encodes those which must be encoded, and does not touch
* those which must not be touched.
+ * String x must be '\0'-terminated.
+ * String y must be pre-allocated with len maxlen
+ * (including the terminating '\0').
*/
-char * jk_canonenc(char *y, const char *x, int len,
- enum enctype t, int forcedec,
- int proxyreq)
+int jk_canonenc(const char *x, char *y, int maxlen)
{
- int i, j, ch;
+ int i, j;
+ int ch = x[0];
char *allowed; /* characters which should not be encoded */
char *reserved; /* characters which much not be en/de-coded */
/*
* N.B. in addition to :@&=, this allows ';' in an http path
* and '?' in an ftp path -- this may be revised
- *
- * Also, it makes a '+' character in a search string reserved, as
- * it may be form-encoded. (Although RFC 1738 doesn't allow this -
- * it only permits ; / ? : @ = & as reserved chars.)
*/
- if (t == enc_path) {
- allowed = "~$-_.+!*'(),;:@&=";
- }
- else if (t == enc_search) {
- allowed = "$-_.!*'(),;:@&=";
- }
- else if (t == enc_user) {
- allowed = "$-_.+!*'(),;@&=";
- }
- else if (t == enc_fpath) {
- allowed = "$-_.+!*'(),?:@&=";
- }
- else { /* if (t == enc_parm) */
- allowed = "$-_.+!*'(),?/:@&=";
- }
-
- if (t == enc_path) {
- reserved = "/";
- }
- else if (t == enc_search) {
- reserved = "+";
- }
- else {
- reserved = "";
- }
-
- /* y = apr_palloc(p, 3 * len + 1); */
+ allowed = "~$-_.+!*'(),;:@&=";
+ reserved = "/";
- for (i = 0, j = 0; i < len; i++, j++) {
+ for (i = 0, j = 0; ch != '\0' && j < maxlen; i++, j++, ch=x[i]) {
/* always handle '/' first */
- ch = x[i];
if (strchr(reserved, ch)) {
y[j] = ch;
continue;
}
-/*
- * decode it if not already done. do not decode reverse proxied URLs
- * unless specifically forced
- */
- if ((forcedec || (proxyreq && proxyreq != JK_PROXYREQ_REVERSE)) && ch
== '%') {
- if (!JK_ISXDIGIT(x[i + 1]) || !JK_ISXDIGIT(x[i + 2])) {
- return NULL;
- }
- ch = jk_hex2c(&x[i + 1]);
- i += 2;
- if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */
+/* recode it, if necessary */
+ if (!JK_ISALNUM(ch) && !strchr(allowed, ch)) {
+ if (j+2<maxlen) {
jk_c2hex(ch, &y[j]);
j += 2;
- continue;
}
- }
-/* recode it, if necessary */
- if (!JK_ISALNUM(ch) && !strchr(allowed, ch)) {
- jk_c2hex(ch, &y[j]);
- j += 2;
+ else {
+ return JK_FALSE;
+ }
}
else {
y[j] = ch;
}
}
- y[j] = '\0';
- return y;
+ if (j<maxlen) {
+ y[j] = '\0';
+ return JK_TRUE;
+ }
+ else {
+ return JK_FALSE;
+ }
}
Modified: tomcat/connectors/trunk/jk/native/common/jk_url.h
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_url.h?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/common/jk_url.h (original)
+++ tomcat/connectors/trunk/jk/native/common/jk_url.h Fri Jun 22 09:00:23 2007
@@ -16,7 +16,7 @@
*/
/***************************************************************************
- * Description: URL manupilation subroutines header file. (mod_proxy) *
+ * Description: URL manipulation subroutines header file. (mod_proxy) *
* Version: $Revision: 500534 $ *
***************************************************************************/
#ifndef _JK_URL_H
@@ -31,22 +31,12 @@
{
#endif /* __cplusplus */
-/* for proxy_canonenc() */
-enum enctype {
- enc_path, enc_search, enc_user, enc_fpath, enc_parm
-};
-
-#define JK_PROXYREQ_NONE 0 /**< No proxy */
-#define JK_PROXYREQ_PROXY 1 /**< Standard proxy */
-#define JK_PROXYREQ_REVERSE 2 /**< Reverse proxy */
-#define JK_PROXYREQ_RESPONSE 3 /**< Origin response */
-
/*
- * Do a canonical encoding of the x url y contains the result
- * and should have a size of at least 3 * len + 1 bytes.
+ * Do a canonical encoding of the url x.
+ * String y contains the result and is pre-allocated
+ * for at least maxlen bytes, including a '\0' terminator.
*/
-char * jk_canonenc(char *y, const char *x, int len,
- enum enctype t, int forcedec, int proxyreq);
+int jk_canonenc(const char *x, char *y, int maxlen);
#ifdef __cplusplus
}
Modified: tomcat/connectors/trunk/jk/native/iis/Makefile.amd64
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/iis/Makefile.amd64?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/iis/Makefile.amd64 (original)
+++ tomcat/connectors/trunk/jk/native/iis/Makefile.amd64 Fri Jun 22 09:00:23
2007
@@ -50,6 +50,7 @@
[EMAIL PROTECTED] "$(INTDIR)\jk_sockbuf.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_status.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_uri_worker_map.obj"
+ [EMAIL PROTECTED] "$(INTDIR)\jk_url.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_util.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_worker.obj"
[EMAIL PROTECTED] "$(OUTDIR)\isapi_redirect.dll"
@@ -89,6 +90,7 @@
"$(INTDIR)\jk_sockbuf.obj" \
"$(INTDIR)\jk_status.obj" \
"$(INTDIR)\jk_uri_worker_map.obj" \
+ "$(INTDIR)\jk_url.obj" \
"$(INTDIR)\jk_util.obj" \
"$(INTDIR)\jk_worker.obj" \
"$(INTDIR)\isapi_redirect.res" \
@@ -258,6 +260,12 @@
SOURCE=..\common\jk_uri_worker_map.c
"$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+SOURCE=..\common\jk_url.c
+
+"$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
Modified: tomcat/connectors/trunk/jk/native/iis/Makefile.ia64
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/iis/Makefile.ia64?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/iis/Makefile.ia64 (original)
+++ tomcat/connectors/trunk/jk/native/iis/Makefile.ia64 Fri Jun 22 09:00:23 2007
@@ -50,6 +50,7 @@
[EMAIL PROTECTED] "$(INTDIR)\jk_sockbuf.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_status.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_uri_worker_map.obj"
+ [EMAIL PROTECTED] "$(INTDIR)\jk_url.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_util.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_worker.obj"
[EMAIL PROTECTED] "$(OUTDIR)\isapi_redirect.dll"
@@ -89,6 +90,7 @@
"$(INTDIR)\jk_sockbuf.obj" \
"$(INTDIR)\jk_status.obj" \
"$(INTDIR)\jk_uri_worker_map.obj" \
+ "$(INTDIR)\jk_url.obj" \
"$(INTDIR)\jk_util.obj" \
"$(INTDIR)\jk_worker.obj" \
"$(INTDIR)\isapi_redirect.res" \
@@ -258,6 +260,12 @@
SOURCE=..\common\jk_uri_worker_map.c
"$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+SOURCE=..\common\jk_url.c
+
+"$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
Modified: tomcat/connectors/trunk/jk/native/iis/Makefile.x86
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/iis/Makefile.x86?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/iis/Makefile.x86 (original)
+++ tomcat/connectors/trunk/jk/native/iis/Makefile.x86 Fri Jun 22 09:00:23 2007
@@ -45,6 +45,7 @@
[EMAIL PROTECTED] "$(INTDIR)\jk_sockbuf.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_status.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_uri_worker_map.obj"
+ [EMAIL PROTECTED] "$(INTDIR)\jk_url.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_util.obj"
[EMAIL PROTECTED] "$(INTDIR)\jk_worker.obj"
[EMAIL PROTECTED] "$(OUTDIR)\isapi_redirect.dll"
@@ -84,6 +85,7 @@
"$(INTDIR)\jk_sockbuf.obj" \
"$(INTDIR)\jk_status.obj" \
"$(INTDIR)\jk_uri_worker_map.obj" \
+ "$(INTDIR)\jk_url.obj" \
"$(INTDIR)\jk_util.obj" \
"$(INTDIR)\jk_worker.obj" \
"$(INTDIR)\isapi_redirect.res" \
@@ -251,6 +253,12 @@
SOURCE=..\common\jk_uri_worker_map.c
"$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+SOURCE=..\common\jk_url.c
+
+"$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
Modified: tomcat/connectors/trunk/jk/native/iis/isapi.dsp
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/iis/isapi.dsp?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/iis/isapi.dsp (original)
+++ tomcat/connectors/trunk/jk/native/iis/isapi.dsp Fri Jun 22 09:00:23 2007
@@ -176,6 +176,10 @@
# End Source File
# Begin Source File
+SOURCE=..\common\jk_url.c
+# End Source File
+# Begin Source File
+
SOURCE=..\common\jk_util.c
# End Source File
# Begin Source File
@@ -273,6 +277,10 @@
# Begin Source File
SOURCE=..\common\jk_uri_worker_map.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\jk_url.h
# End Source File
# Begin Source File
Modified: tomcat/connectors/trunk/jk/native/iis/jk_isapi_plugin.c
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/iis/jk_isapi_plugin.c?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/iis/jk_isapi_plugin.c (original)
+++ tomcat/connectors/trunk/jk/native/iis/jk_isapi_plugin.c Fri Jun 22 09:00:23
2007
@@ -32,6 +32,7 @@
#include <wininet.h>
#include "jk_global.h"
+#include "jk_url.h"
#include "jk_util.h"
#include "jk_map.h"
#include "jk_pool.h"
@@ -94,6 +95,7 @@
#define URI_SELECT_PARSED_VERB ("parsed")
#define URI_SELECT_UNPARSED_VERB ("unparsed")
#define URI_SELECT_ESCAPED_VERB ("escaped")
+#define URI_SELECT_PROXY_VERB ("proxy")
#define URI_REWRITE_TAG ("rewrite_rule_file")
#define SHM_SIZE_TAG ("shm_size")
#define WORKER_MOUNT_RELOAD_TAG ("worker_mount_reload")
@@ -135,6 +137,7 @@
"Please try again later.</P></BODY></HTML>";
+#define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)")
#define JK_TOLOWER(x) ((char)tolower((BYTE)(x)))
#define GET_SERVER_VARIABLE_VALUE(name, place) \
@@ -195,8 +198,9 @@
#define URI_SELECT_OPT_PARSED 0
#define URI_SELECT_OPT_UNPARSED 1
#define URI_SELECT_OPT_ESCAPED 2
+#define URI_SELECT_OPT_PROXY 3
-static int uri_select_option = URI_SELECT_OPT_PARSED;
+static int uri_select_option = URI_SELECT_OPT_PROXY;
static jk_worker_env_t worker_env;
@@ -1316,6 +1320,21 @@
snuri);
forwardURI = snuri;
}
+ else if (uri_select_option == URI_SELECT_OPT_PROXY) {
+ if (!jk_canonenc(uri, snuri, INTERNET_MAX_URL_LENGTH)) {
+ jk_log(logger, JK_LOG_ERROR,
+ "[%s] re-encoding request exceeds maximum
buffer size.",
+ uri);
+ write_error_response(pfc, "400 Bad Request",
+ HTML_ERROR_400);
+ return SF_STATUS_REQ_FINISHED;
+ }
+ if (JK_IS_DEBUG_LEVEL(logger))
+ jk_log(logger, JK_LOG_DEBUG,
+ "fowarding escaped URI [%s]",
+ snuri);
+ forwardURI = snuri;
+ }
else {
forwardURI = uri;
}
@@ -1775,6 +1794,10 @@
return URI_SELECT_OPT_ESCAPED;
}
+ if (0 == strcasecmp(uri_select, URI_SELECT_PROXY_VERB)) {
+ return URI_SELECT_OPT_PROXY;
+ }
+
return -1;
}
@@ -2180,6 +2203,23 @@
}
else {
return JK_FALSE;
+ }
+
+ /* Dump all connection param so we can trace what's going to
+ * the remote tomcat
+ */
+ if (JK_IS_DEBUG_LEVEL(logger)) {
+ jk_log(logger, JK_LOG_DEBUG,
+ "Service protocol=%s method=%s host=%s addr=%s name=%s port=%d
auth=%s user=%s uri=%s",
+ STRNULL_FOR_NULL(s->protocol),
+ STRNULL_FOR_NULL(s->method),
+ STRNULL_FOR_NULL(s->remote_host),
+ STRNULL_FOR_NULL(s->remote_addr),
+ STRNULL_FOR_NULL(s->server_name),
+ s->server_port,
+ STRNULL_FOR_NULL(s->auth_type),
+ STRNULL_FOR_NULL(s->remote_user),
+ STRNULL_FOR_NULL(s->req_uri));
}
return JK_TRUE;
Modified: tomcat/connectors/trunk/jk/native/netscape/jk_nsapi_plugin.c
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/netscape/jk_nsapi_plugin.c?view=diff&rev=549857&r1=549856&r2=549857
==============================================================================
--- tomcat/connectors/trunk/jk/native/netscape/jk_nsapi_plugin.c (original)
+++ tomcat/connectors/trunk/jk/native/netscape/jk_nsapi_plugin.c Fri Jun 22
09:00:23 2007
@@ -34,6 +34,8 @@
#define URI_PATTERN "path"
#define DEFAULT_WORKER_NAME ("ajp13")
+#define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)")
+
struct nsapi_private_data
{
jk_pool_t p;
@@ -410,7 +412,11 @@
s->remote_host = session_dns(private_data->sn);
s->remote_addr = pblock_findval("ip", private_data->sn->client);
- s->req_uri = pblock_findval("uri", private_data->rq->reqpb);
+ tmp = pblock_findval("uri", private_data->rq->reqpb);
+ size = 3 * strlen(tmp) + 1;
+ s->req_uri = jk_pool_alloc(s->pool, size);
+ jk_canonenc(tmp, s->req_uri, size);
+
s->query_string = pblock_findval("query", private_data->rq->reqpb);
s->server_name = server_hostname;
@@ -466,7 +472,27 @@
s->ssl_session = NULL;
}
- return setup_http_headers(private_data, s);
+ rc = setup_http_headers(private_data, s);
+
+ /* Dump all connection param so we can trace what's going to
+ * the remote tomcat
+ */
+ if (JK_IS_DEBUG_LEVEL(logger)) {
+ jk_log(logger, JK_LOG_DEBUG,
+ "Service protocol=%s method=%s host=%s addr=%s name=%s port=%d
auth=%s user=%s uri=%s",
+ STRNULL_FOR_NULL(s->protocol),
+ STRNULL_FOR_NULL(s->method),
+ STRNULL_FOR_NULL(s->remote_host),
+ STRNULL_FOR_NULL(s->remote_addr),
+ STRNULL_FOR_NULL(s->server_name),
+ s->server_port,
+ STRNULL_FOR_NULL(s->auth_type),
+ STRNULL_FOR_NULL(s->remote_user),
+ STRNULL_FOR_NULL(s->req_uri));
+ }
+
+ return rc;
+
}
static int setup_http_headers(nsapi_private_data_t * private_data,
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]