/* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * If any of the files related to licensing are missing or if you have any * other questions related to licensing please contact Trustwave Holdings, Inc. * directly using the email address security@modsecurity.org. */ #include "msc_unicode.h" #define CODEPAGE_SEPARATORS " \t\n\r" /** \brief Load Unicode file * * \param dcfg Pointer to directory configuration * \param error_msg Error message * * \retval 1 On Success * \retval 0 On Fail */ static int unicode_map_create(directory_config *dcfg, char **error_msg) { char errstr[1024]; apr_pool_t *mp = dcfg->mp; unicode_map *u_map = dcfg->u_map; apr_int32_t wanted = APR_FINFO_SIZE; apr_finfo_t finfo; apr_status_t rc; apr_size_t nbytes; unsigned int codepage = 0; char *buf = NULL, *p = NULL, *savedptr = NULL; char *ucode = NULL, *hmap = NULL; int found = 0, processing = 0; int Code = 0, Map = 0; if(unicode_map_table != NULL) { free(unicode_map_table); unicode_map_table = NULL; } if ((rc = apr_file_open(&u_map->map, u_map->mapfn, APR_READ, APR_OS_DEFAULT, mp)) != APR_SUCCESS) { *error_msg = apr_psprintf(mp, "Could not open unicode map file \"%s\": %s", u_map->mapfn, apr_strerror(rc, errstr, 1024)); return 0; } if ((rc = apr_file_info_get(&finfo, wanted, u_map->map)) != APR_SUCCESS) { *error_msg = apr_psprintf(mp, "Could not cannot get unicode map file information \"%s\": %s", u_map->mapfn, apr_strerror(rc, errstr, 1024)); apr_file_close(u_map->map); return 0; } buf = (char *)malloc(finfo.size+1); if (buf == NULL) { *error_msg = apr_psprintf(mp, "Could not alloc memory for unicode map"); apr_file_close(u_map->map); return 0; } rc = apr_file_read_full(u_map->map, buf, finfo.size, &nbytes); if (unicode_map_table != NULL) { memset(unicode_map_table, -1, (sizeof(int)*65536)); } else { unicode_map_table = (int *)malloc(sizeof(int) * 65536); if(unicode_map_table == NULL) { *error_msg = apr_psprintf(mp, "Could not alloc memory for unicode map"); free(buf); buf = NULL; apr_file_close(u_map->map); return 0; } memset(unicode_map_table, -1, (sizeof(int)*65536)); } /* Setting some unicode values - http://tools.ietf.org/html/rfc3490#section-3.1 */ /* Set 0x3002 -> 0x2e */ unicode_map_table[0x3002] = 0x2e; /* Set 0xFF61 -> 0x2e */ unicode_map_table[0xff61] = 0x2e; /* Set 0xFF0E -> 0x2e */ unicode_map_table[0xff0e] = 0x2e; /* Set 0x002E -> 0x2e */ unicode_map_table[0x002e] = 0x2e; p = apr_strtok(buf,CODEPAGE_SEPARATORS,&savedptr); while (p != NULL) { codepage = atol(p); if (codepage == unicode_codepage) { found = 1; } if (found == 1 && (strchr(p,':') != NULL)) { char *mapping = strdup(p); processing = 1; if(mapping != NULL) { ucode = apr_strtok(mapping,":", &hmap); sscanf(ucode,"%x",&Code); sscanf(hmap,"%x",&Map); if(Code >= 0 && Code <= 65535) { unicode_map_table[Code] = Map; } free(mapping); mapping = NULL; } } if (processing == 1 && (strchr(p,':') == NULL)) { free(buf); buf = NULL; break; } p = apr_strtok(NULL,CODEPAGE_SEPARATORS,&savedptr); } apr_file_close(u_map->map); if(buf) { free(buf); buf = NULL; } return 1; } /** \brief Init unicode map * * \param dcfg Pointer to directory configuration * \param mapfn Unicode map filename * \param error_msg Error message * * \retval unicode_map_create On Success * \retval -1 On Fail */ int unicode_map_init(directory_config *dcfg, const char *mapfn, char **error_msg) { *error_msg = NULL; if ((dcfg->u_map == NULL) || (dcfg->u_map == NOT_SET_P)) { dcfg->u_map = apr_pcalloc(dcfg->mp, sizeof(unicode_map)); if (dcfg->u_map == NULL) { return -1; } } dcfg->u_map->map = NULL; dcfg->u_map->mapfn = apr_pstrdup(dcfg->mp, mapfn); return unicode_map_create(dcfg, error_msg); }