mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-30 11:44:32 +03:00
Adds support to the server ID generation
The server ID is a sha-1 identifier generated from the mac address of the first ethernet device plus the server name. The process is the same used by ModSecurity 2.9
This commit is contained in:
230
src/unique_id.cc
Normal file
230
src/unique_id.cc
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 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 "src/unique_id.h"
|
||||
#include "src/config.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__gnu_linux__)) || DARWIN
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef DARWIN
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef IFT_ETHER
|
||||
#define IFT_ETHER 0x6 /* Ethernet CSMACD */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__gnu_linux__))
|
||||
#include <linux/if.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/utils/sha1.h"
|
||||
|
||||
namespace ModSecurity {
|
||||
|
||||
void UniqueId::fillUniqueId() {
|
||||
std::string macAddress;
|
||||
std::string name;
|
||||
Utils::SHA1 sha1;
|
||||
|
||||
macAddress = ethernetMacAddress();
|
||||
name = machineName();
|
||||
|
||||
sha1.update(&macAddress);
|
||||
sha1.update(&name);
|
||||
|
||||
this->uniqueId_str = sha1.final();
|
||||
}
|
||||
|
||||
// Based on:
|
||||
// http://stackoverflow.com/questions/16858782/how-to-obtain-almost-unique-system-identifier-in-a-cross-platform-way
|
||||
std::string UniqueId::machineName() {
|
||||
char machine_name[MAX_MACHINE_NAME_SIZE];
|
||||
size_t len = MAX_MACHINE_NAME_SIZE;
|
||||
#ifdef WIN32
|
||||
DWORD lenComputerName = len;
|
||||
#endif
|
||||
|
||||
memset(machine_name, '\0', sizeof(char) * len);
|
||||
|
||||
#ifdef WIN32
|
||||
if (GetComputerName(machine_name, &lenComputerName) == 0) {
|
||||
goto failed;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
static struct utsname u;
|
||||
|
||||
if (uname(&u) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
snprintf(machine_name, len-1, "%s", u.nodename);
|
||||
#endif
|
||||
|
||||
return std::string(machine_name);
|
||||
|
||||
failed:
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::string UniqueId::ethernetMacAddress() {
|
||||
char mac[MAC_ADDRESS_SIZE];
|
||||
memset(mac, '\0', sizeof(char)*(MAC_ADDRESS_SIZE));
|
||||
#ifdef DARWIN
|
||||
struct ifaddrs* ifaphead;
|
||||
struct ifaddrs* ifap;
|
||||
int i = 0;
|
||||
|
||||
if (getifaddrs(&ifaphead) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// iterate over the net interfaces
|
||||
for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
|
||||
struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifap->ifa_addr;
|
||||
if (sdl && (sdl->sdl_family == AF_LINK) && (sdl->sdl_type == IFT_ETHER)
|
||||
&& mac[0] && mac[1] && mac[2] && i < 6) {
|
||||
snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned char)LLADDR(sdl)[0],
|
||||
(unsigned char)LLADDR(sdl)[1],
|
||||
(unsigned char)LLADDR(sdl)[2],
|
||||
(unsigned char)LLADDR(sdl)[3],
|
||||
(unsigned char)LLADDR(sdl)[4],
|
||||
(unsigned char)LLADDR(sdl)[5]);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(ifaphead);
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__gnu_linux__))
|
||||
struct ifconf conf;
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
struct ifreq* ifr;
|
||||
if ( sock < 0 ) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char ifconfbuf[128 * sizeof(struct ifreq)];
|
||||
memset(ifconfbuf, 0, sizeof(ifconfbuf));
|
||||
conf.ifc_buf = ifconfbuf;
|
||||
conf.ifc_len = sizeof(ifconfbuf);
|
||||
if (ioctl(sock, SIOCGIFCONF, &conf)) {
|
||||
close(sock);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (ifr = conf.ifc_req; ifr < conf.ifc_req + conf.ifc_len; ifr++) {
|
||||
if (ioctl(sock, SIOCGIFFLAGS, ifr)) {
|
||||
continue; // failed to get flags, skip it
|
||||
}
|
||||
|
||||
if (ioctl(sock, SIOCGIFHWADDR, ifr) == 0) {
|
||||
int i = 0;
|
||||
if (!ifr->ifr_addr.sa_data[0] && !ifr->ifr_addr.sa_data[1]
|
||||
&& !ifr->ifr_addr.sa_data[2]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned char)ifr->ifr_addr.sa_data[0],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[1],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[2],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[3],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[4],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[5]);
|
||||
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
#if WIN32
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
PIP_ADAPTER_INFO pAdapter = NULL;
|
||||
DWORD dwRetVal = 0;
|
||||
|
||||
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO *>(malloc( \
|
||||
sizeof (IP_ADAPTER_INFO)));
|
||||
if (!pAdapterInfo) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAdapterInfo);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO *>malloc(ulOutBufLen));
|
||||
if (!pAdapterInfo) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
|
||||
if (dwRetVal != NO_ERROR) {
|
||||
free(pAdapterInfo);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
pAdapter = pAdapterInfo;
|
||||
while (pAdapter && !mac[0] && !mac[1] && !mac[2]) {
|
||||
if (pAdapter->AddressLength > 4) {
|
||||
apr_snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned char)pAdapter->Address[0],
|
||||
(unsigned char)pAdapter->Address[1],
|
||||
(unsigned char)pAdapter->Address[2],
|
||||
(unsigned char)pAdapter->Address[3],
|
||||
(unsigned char)pAdapter->Address[4],
|
||||
(unsigned char)pAdapter->Address[5]);
|
||||
goto end;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
|
||||
free(pAdapterInfo);
|
||||
#endif
|
||||
|
||||
end:
|
||||
return std::string(reinterpret_cast<const char *>(mac));
|
||||
failed:
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
} // namespace ModSecurity
|
Reference in New Issue
Block a user