|
Packit |
284210 |
/*
|
|
Packit |
284210 |
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
Packit |
284210 |
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* You may not use this file except in compliance with
|
|
Packit |
284210 |
* the License. You may obtain a copy of the License at
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* If any of the files related to licensing are missing or if you have any
|
|
Packit |
284210 |
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
Packit |
284210 |
* directly using the email address security@modsecurity.org.
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#include "msc_status_engine.h"
|
|
Packit |
284210 |
#include "apr_sha1.h"
|
|
Packit |
284210 |
#include "modsecurity_config.h"
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#ifdef WIN32
|
|
Packit |
284210 |
#include <winsock2.h>
|
|
Packit |
284210 |
#include <iphlpapi.h>
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#ifdef DARWIN
|
|
Packit |
284210 |
#include <arpa/inet.h>
|
|
Packit |
284210 |
#include <ifaddrs.h>
|
|
Packit |
284210 |
#include <net/if.h>
|
|
Packit |
284210 |
#include <net/if_dl.h>
|
|
Packit |
284210 |
#include <netinet/in.h>
|
|
Packit |
284210 |
#include <sys/types.h>
|
|
Packit |
284210 |
#include <sys/socket.h>
|
|
Packit |
284210 |
#ifndef IFT_ETHER
|
|
Packit |
284210 |
#define IFT_ETHER 0x6 /* Ethernet CSMACD */
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#if (defined(__linux__) || defined(__gnu_linux__))
|
|
Packit |
284210 |
#include <linux/if.h>
|
|
Packit |
284210 |
#include <linux/sockios.h>
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
#ifdef HAVE_SYS_UTSNAME_H
|
|
Packit |
284210 |
#include <sys/utsname.h>
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
// Bese32 encode, based on:
|
|
Packit |
284210 |
// https://code.google.com/p/google-authenticator/source/browse/libpam/base32.c
|
|
Packit |
284210 |
int DSOLOCAL msc_status_engine_base32_encode(char *encoded,
|
|
Packit |
284210 |
const char *data, int len) {
|
|
Packit |
284210 |
int buffer;
|
|
Packit |
284210 |
int count = 0;
|
|
Packit |
284210 |
char *result = encoded;
|
|
Packit |
284210 |
int length = strlen(data);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
buffer = data[0];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (encoded == NULL && len == 0) {
|
|
Packit |
284210 |
len = length * 3;
|
|
Packit |
284210 |
count++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (length > 0) {
|
|
Packit |
284210 |
int next = 1;
|
|
Packit |
284210 |
int bitsLeft = 8;
|
|
Packit |
284210 |
while (count < len && (bitsLeft > 0 || next < length)) {
|
|
Packit |
284210 |
int index;
|
|
Packit |
284210 |
if (bitsLeft < 5) {
|
|
Packit |
284210 |
if (next < length) {
|
|
Packit |
284210 |
buffer <<= 8;
|
|
Packit |
284210 |
buffer |= data[next++] & 0xff;
|
|
Packit |
284210 |
bitsLeft += 8;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
int pad = 5 - bitsLeft;
|
|
Packit |
284210 |
buffer <<= pad;
|
|
Packit |
284210 |
bitsLeft += pad;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
index = 0x1f & (buffer >> (bitsLeft - 5));
|
|
Packit |
284210 |
bitsLeft -= 5;
|
|
Packit |
284210 |
if (encoded != NULL) {
|
|
Packit |
284210 |
result[count] = msc_status_engine_basis_32[index];
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
count++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
if (count < len && encoded != NULL) {
|
|
Packit |
284210 |
result[count] = '\000';
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return count;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int DSOLOCAL msc_status_engine_fill_with_dots(char *encoded_with_dots,
|
|
Packit |
284210 |
const char *data, int len, int space)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
int i;
|
|
Packit |
284210 |
int count = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (encoded_with_dots == NULL) {
|
|
Packit |
284210 |
if (len == 0 && data != NULL) {
|
|
Packit |
284210 |
len = strlen(data);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (len == 0 && data == NULL) {
|
|
Packit |
284210 |
count = -1;
|
|
Packit |
284210 |
goto return_length;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
count = len/space + len + 1;
|
|
Packit |
284210 |
goto return_length;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for (i = 0; i < strlen(data) && i < len; i++) {
|
|
Packit |
284210 |
if (i % space == 0 && i != 0) {
|
|
Packit |
284210 |
encoded_with_dots[count++] = '.';
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
encoded_with_dots[count++] = data[i];
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
encoded_with_dots[count] = '\0';
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return_length:
|
|
Packit |
284210 |
return count;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
|
|
Packit |
284210 |
// Based on:
|
|
Packit |
284210 |
// http://stackoverflow.com/questions/16858782/how-to-obtain-almost-unique-system-identifier-in-a-cross-platform-way
|
|
Packit |
284210 |
int DSOLOCAL msc_status_engine_machine_name(char *machine_name, size_t len) {
|
|
Packit |
284210 |
#ifdef WIN32
|
|
Packit |
284210 |
DWORD lenComputerName = len;
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(machine_name, '\0', sizeof(char) * len);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#ifdef WIN32
|
|
Packit |
284210 |
if (GetComputerName(machine_name, &lenComputerName) == 0) {
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#ifdef HAVE_SYS_UTSNAME_H
|
|
Packit |
284210 |
static struct utsname u;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ( uname( &u ) < 0 ) {
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_snprintf(machine_name, len-1, "%s", u.nodename);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
failed:
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int DSOLOCAL msc_status_engine_mac_address (unsigned char *mac)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
#ifdef DARWIN
|
|
Packit |
284210 |
struct ifaddrs* ifaphead;
|
|
Packit |
284210 |
struct ifaddrs* ifap;
|
|
Packit |
284210 |
int i = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ( getifaddrs( &ifaphead ) != 0 ) {
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
// iterate over the net interfaces
|
|
Packit |
284210 |
for ( ifap = ifaphead; ifap; ifap = ifap->ifa_next ) {
|
|
Packit |
284210 |
struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifap->ifa_addr;
|
|
Packit |
284210 |
if ( sdl && ( sdl->sdl_family == AF_LINK ) && ( sdl->sdl_type == IFT_ETHER )
|
|
Packit |
284210 |
&& mac[0] && mac[1] && mac[2] && i < 6) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
Packit |
284210 |
(unsigned char)LLADDR(sdl)[0],
|
|
Packit |
284210 |
(unsigned char)LLADDR(sdl)[1],
|
|
Packit |
284210 |
(unsigned char)LLADDR(sdl)[2],
|
|
Packit |
284210 |
(unsigned char)LLADDR(sdl)[3],
|
|
Packit |
284210 |
(unsigned char)LLADDR(sdl)[4],
|
|
Packit |
284210 |
(unsigned char)LLADDR(sdl)[5]);
|
|
Packit |
284210 |
goto end;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
freeifaddrs( ifaphead );
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#if (defined(__linux__) || defined(__gnu_linux__))
|
|
Packit |
284210 |
struct ifconf conf;
|
|
Packit |
284210 |
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP );
|
|
Packit |
284210 |
struct ifreq* ifr;
|
|
Packit |
284210 |
if ( sock < 0 ) {
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
char ifconfbuf[ 128 * sizeof(struct ifreq) ];
|
|
Packit |
284210 |
memset( ifconfbuf, 0, sizeof( ifconfbuf ));
|
|
Packit |
284210 |
conf.ifc_buf = ifconfbuf;
|
|
Packit |
284210 |
conf.ifc_len = sizeof( ifconfbuf );
|
|
Packit |
284210 |
if ( ioctl( sock, SIOCGIFCONF, &conf )) {
|
|
Packit |
284210 |
close(sock);
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for ( ifr = conf.ifc_req; ifr < conf.ifc_req + conf.ifc_len; ifr++ ) {
|
|
Packit |
284210 |
if ( ioctl( sock, SIOCGIFFLAGS, ifr )) {
|
|
Packit |
284210 |
continue; // failed to get flags, skip it
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ( ioctl( sock, SIOCGIFHWADDR, ifr ) == 0 ) {
|
|
Packit |
284210 |
int i = 0;
|
|
Packit |
284210 |
if (!ifr->ifr_addr.sa_data[0] && !ifr->ifr_addr.sa_data[1]
|
|
Packit |
284210 |
&& !ifr->ifr_addr.sa_data[2]) {
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
Packit |
284210 |
(unsigned char)ifr->ifr_addr.sa_data[0],
|
|
Packit |
284210 |
(unsigned char)ifr->ifr_addr.sa_data[1],
|
|
Packit |
284210 |
(unsigned char)ifr->ifr_addr.sa_data[2],
|
|
Packit |
284210 |
(unsigned char)ifr->ifr_addr.sa_data[3],
|
|
Packit |
284210 |
(unsigned char)ifr->ifr_addr.sa_data[4],
|
|
Packit |
284210 |
(unsigned char)ifr->ifr_addr.sa_data[5]);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
goto end;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
close( sock );
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#if WIN32
|
|
Packit |
284210 |
PIP_ADAPTER_INFO pAdapterInfo;
|
|
Packit |
284210 |
PIP_ADAPTER_INFO pAdapter = NULL;
|
|
Packit |
284210 |
DWORD dwRetVal = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
|
|
Packit |
284210 |
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO));
|
|
Packit |
284210 |
if (!pAdapterInfo) {
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
|
Packit |
284210 |
free(pAdapterInfo);
|
|
Packit |
284210 |
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
|
|
Packit |
284210 |
if (!pAdapterInfo) {
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
|
|
Packit |
284210 |
if (dwRetVal != NO_ERROR) {
|
|
Packit |
284210 |
free(pAdapterInfo);
|
|
Packit |
284210 |
goto failed;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pAdapter = pAdapterInfo;
|
|
Packit |
284210 |
while (pAdapter && !mac[0] && !mac[1] && !mac[2])
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
if (pAdapter->AddressLength > 4)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
apr_snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
Packit |
284210 |
(unsigned char)pAdapter->Address[0],
|
|
Packit |
284210 |
(unsigned char)pAdapter->Address[1],
|
|
Packit |
284210 |
(unsigned char)pAdapter->Address[2],
|
|
Packit |
284210 |
(unsigned char)pAdapter->Address[3],
|
|
Packit |
284210 |
(unsigned char)pAdapter->Address[4],
|
|
Packit |
284210 |
(unsigned char)pAdapter->Address[5]);
|
|
Packit |
284210 |
goto end;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
pAdapter = pAdapter->Next;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
free(pAdapterInfo);
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
end:
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
failed:
|
|
Packit |
284210 |
return -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int DSOLOCAL msc_status_engine_unique_id (unsigned char *digest)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
unsigned char hex_digest[APR_SHA1_DIGESTSIZE];
|
|
Packit |
284210 |
unsigned char *mac_address = NULL;
|
|
Packit |
284210 |
char *machine_name = NULL;
|
|
Packit |
284210 |
int ret = 0;
|
|
Packit |
284210 |
int i = 0;
|
|
Packit |
284210 |
apr_sha1_ctx_t context;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
mac_address = malloc(sizeof(char)*(MAC_ADDRESS_SIZE));
|
|
Packit |
284210 |
if (!mac_address) {
|
|
Packit |
284210 |
ret = -1;
|
|
Packit |
284210 |
goto failed_mac_address;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
memset(mac_address, '\0', sizeof(char)*(MAC_ADDRESS_SIZE));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msc_status_engine_mac_address(mac_address)) {
|
|
Packit |
284210 |
ret = -1;
|
|
Packit |
284210 |
goto failed_set_mac_address;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
machine_name = malloc(sizeof(char)*MAX_MACHINE_NAME_SIZE);
|
|
Packit |
284210 |
if (!machine_name) {
|
|
Packit |
284210 |
ret = -1;
|
|
Packit |
284210 |
goto failed_machine_name;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
memset(machine_name, '\0', sizeof(char)*(MAX_MACHINE_NAME_SIZE));
|
|
Packit |
284210 |
if (msc_status_engine_machine_name(machine_name, MAC_ADDRESS_SIZE)) {
|
|
Packit |
284210 |
ret = -1;
|
|
Packit |
284210 |
goto failed_set_machine_name;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_sha1_init(&context);
|
|
Packit |
284210 |
apr_sha1_update(&context, machine_name, strlen(machine_name));
|
|
Packit |
284210 |
apr_sha1_update(&context, mac_address, strlen(mac_address));
|
|
Packit |
284210 |
apr_sha1_final(hex_digest, &context);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for (i = 0; i < APR_SHA1_DIGESTSIZE; i++)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
sprintf(digest, "%s%02x", digest, hex_digest[i]);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
failed_set_machine_name:
|
|
Packit |
284210 |
free(machine_name);
|
|
Packit |
284210 |
failed_machine_name:
|
|
Packit |
284210 |
failed_set_mac_address:
|
|
Packit |
284210 |
free(mac_address);
|
|
Packit |
284210 |
failed_mac_address:
|
|
Packit |
284210 |
return ret;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int DSOLOCAL msc_beacon_string (char *beacon_string, int beacon_string_max_len) {
|
|
Packit |
284210 |
char *apr = NULL;
|
|
Packit |
284210 |
const char *apr_loaded = NULL;
|
|
Packit |
284210 |
char pcre[7];
|
|
Packit |
284210 |
const char *pcre_loaded = NULL;
|
|
Packit |
284210 |
char *lua = NULL;
|
|
Packit |
284210 |
char *libxml = NULL;
|
|
Packit |
284210 |
char *modsec = NULL;
|
|
Packit |
284210 |
const char *apache = NULL;
|
|
Packit |
284210 |
char id[(APR_SHA1_DIGESTSIZE*2) + 1];
|
|
Packit |
284210 |
int beacon_string_len = -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr = APR_VERSION_STRING;
|
|
Packit |
284210 |
apr_loaded = apr_version_string();
|
|
Packit |
284210 |
apr_snprintf(pcre, 7, "%d.%d", PCRE_MAJOR, PCRE_MINOR);
|
|
Packit |
284210 |
pcre_loaded = pcre_version();
|
|
Packit |
284210 |
#ifdef WITH_LUA
|
|
Packit |
284210 |
lua = LUA_VERSION;
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
libxml = LIBXML_DOTTED_VERSION;
|
|
Packit |
284210 |
modsec = MODSEC_VERSION;
|
|
Packit |
284210 |
#ifdef VERSION_IIS
|
|
Packit |
284210 |
apache = "IIS";
|
|
Packit |
284210 |
#elif VERSION_NGINX
|
|
Packit |
284210 |
apache = "nginx";
|
|
Packit |
284210 |
#else
|
|
Packit |
284210 |
apache = real_server_signature;
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/* 6 represents: strlen("(null)") */
|
|
Packit |
284210 |
beacon_string_len = (modsec ? strlen(modsec) : 6) +
|
|
Packit |
284210 |
(apache ? strlen(apache) : 6) + (apr ? strlen(apr) : 6) +
|
|
Packit |
284210 |
(apr_loaded ? strlen(apr_loaded) : 6) + (pcre ? strlen(pcre) : 6) +
|
|
Packit |
284210 |
(pcre_loaded ? strlen(pcre_loaded) : 6) + (lua ? strlen(lua) : 6) +
|
|
Packit |
284210 |
(libxml ? strlen(libxml) : 6) + (APR_SHA1_DIGESTSIZE * 2);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
beacon_string_len = beacon_string_len + /* null terminator: */ 1 +
|
|
Packit |
284210 |
/* comma: */ 6 +
|
|
Packit |
284210 |
/* slash: */ 2;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (beacon_string == NULL || beacon_string_max_len == 0) {
|
|
Packit |
284210 |
goto return_length;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(id, '\0', sizeof(id));
|
|
Packit |
284210 |
if (msc_status_engine_unique_id(id)) {
|
|
Packit |
284210 |
sprintf(id, "no unique id");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
apr_snprintf(beacon_string, beacon_string_max_len,
|
|
Packit |
284210 |
"%.25s,%.25s,%s/%s,%s/%s,%s,%s,%s",
|
|
Packit |
284210 |
modsec, apache, apr, apr_loaded, pcre, pcre_loaded, lua, libxml, id);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return_length:
|
|
Packit |
284210 |
return beacon_string_len;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int DSOLOCAL msc_status_engine_prepare_hostname (char *hostname, const char *plain_data,
|
|
Packit |
284210 |
int max_length)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
int str_enc_len = 0;
|
|
Packit |
284210 |
int str_enc_spl_len = 0;
|
|
Packit |
284210 |
char *tmp = NULL;
|
|
Packit |
284210 |
int length = -1;
|
|
Packit |
284210 |
time_t ltime;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
str_enc_len = msc_status_engine_base32_encode(NULL, plain_data, 0);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
str_enc_spl_len = msc_status_engine_fill_with_dots(NULL, NULL, str_enc_len,
|
|
Packit |
284210 |
STATUS_ENGINE_DNS_IN_BETWEEN_DOTS);
|
|
Packit |
284210 |
if (str_enc_spl_len < 0) {
|
|
Packit |
284210 |
goto failed_enc_spl_len;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
length = str_enc_spl_len + strlen(STATUS_ENGINE_DNS_SUFFIX) +
|
|
Packit |
284210 |
/* epoch: */ 10 + /* dots: */ 2 + /* terminator: */ 1 -
|
|
Packit |
284210 |
/* removed unsed terminators from str_enc and str_enc_spl: */ 2;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (hostname == NULL || max_length == 0) {
|
|
Packit |
284210 |
goto return_length;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(hostname, '\0', sizeof(char) * max_length);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
msc_status_engine_base32_encode(hostname, plain_data, str_enc_len);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
tmp = strdup(hostname);
|
|
Packit |
284210 |
if (tmp == NULL) {
|
|
Packit |
284210 |
length = -1;
|
|
Packit |
284210 |
goto failed_strdup;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
str_enc_spl_len = msc_status_engine_fill_with_dots(hostname, tmp, max_length,
|
|
Packit |
284210 |
STATUS_ENGINE_DNS_IN_BETWEEN_DOTS);
|
|
Packit |
284210 |
if (str_enc_spl_len < 0) {
|
|
Packit |
284210 |
length = -1;
|
|
Packit |
284210 |
goto failed_enc_spl;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
time ( <ime );
|
|
Packit |
284210 |
apr_snprintf(hostname, max_length, "%s.%ld.%s", hostname,
|
|
Packit |
284210 |
(long) ltime, STATUS_ENGINE_DNS_SUFFIX);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
failed_enc_spl:
|
|
Packit |
284210 |
free(tmp);
|
|
Packit |
284210 |
failed_strdup:
|
|
Packit |
284210 |
return_length:
|
|
Packit |
284210 |
failed_enc_spl_len:
|
|
Packit |
284210 |
return length;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int msc_status_engine_call (void) {
|
|
Packit |
284210 |
char *beacon_str = NULL;
|
|
Packit |
284210 |
int beacon_str_len = 0;
|
|
Packit |
284210 |
char *hostname = NULL;
|
|
Packit |
284210 |
int hostname_len = 0;
|
|
Packit |
284210 |
int ret = -1;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/* Retrieve the beacon string */
|
|
Packit |
284210 |
beacon_str_len = msc_beacon_string(NULL, 0);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
beacon_str = malloc(sizeof(char) * beacon_str_len);
|
|
Packit |
284210 |
if (beacon_str == NULL) {
|
|
Packit |
284210 |
goto failed_beacon_string_malloc;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
msc_beacon_string(beacon_str, beacon_str_len);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
|
Packit |
284210 |
"ModSecurity: StatusEngine call: \"%s\"", beacon_str);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/* Get beacon string in the format of a hostname */
|
|
Packit |
284210 |
hostname_len = msc_status_engine_prepare_hostname(NULL, beacon_str, 0);
|
|
Packit |
284210 |
if (hostname_len < 0) {
|
|
Packit |
284210 |
goto failed_hostname_len;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
hostname = malloc(sizeof(char) * hostname_len);
|
|
Packit |
284210 |
if (hostname == NULL) {
|
|
Packit |
284210 |
goto failed_hostname_malloc;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
hostname_len = msc_status_engine_prepare_hostname(hostname, beacon_str,
|
|
Packit |
284210 |
hostname_len);
|
|
Packit |
284210 |
if (hostname_len < 0) {
|
|
Packit |
284210 |
goto failed_hostname;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
/* Perform the DNS query. */
|
|
Packit |
284210 |
if (gethostbyname(hostname)) {
|
|
Packit |
284210 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
|
Packit |
284210 |
"ModSecurity: StatusEngine call successfully sent. For more " \
|
|
Packit |
284210 |
"information visit: http://%s/", STATUS_ENGINE_DNS_SUFFIX);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
|
Packit |
284210 |
"ModSecurity: StatusEngine call failed. Query: %s",
|
|
Packit |
284210 |
hostname);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ret = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
failed_hostname:
|
|
Packit |
284210 |
free(hostname);
|
|
Packit |
284210 |
failed_hostname_malloc:
|
|
Packit |
284210 |
failed_hostname_len:
|
|
Packit |
284210 |
free(beacon_str);
|
|
Packit |
284210 |
failed_beacon_string_malloc:
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return ret;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|