-/* @(#) $Id: win-registry.c,v 1.15 2009/08/31 18:26:04 dcid Exp $ */
-
/* Copyright (C) 2009 Trend Micro Inc.
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
- * License (version 3) as published by the FSF - Free Software
+ * License (version 2) as published by the FSF - Free Software
* Foundation.
- *
- * License details at the LICENSE file included with OSSEC or
- * online at: http://www.ossec.net/en/licensing.html
*/
-
-/* Windows only */
#ifdef WIN32
-
#include "shared.h"
#include "syscheck.h"
#include "os_crypto/md5/md5_op.h"
#include "os_crypto/sha1/sha1_op.h"
-#include "os_crypto/md5_sha1/md5_sha1_op.h"
-
+#include "os_crypto/md5_sha1/md5_sha1_op.h"
/* Default values */
-#define MAX_KEY_LENGTH 255
-#define MAX_KEY 2048
+#define MAX_KEY_LENGTH 255
+#define MAX_KEY 2048
#define MAX_VALUE_NAME 16383
-/* Places to story the registry values. */
+/* Places to story the registry values */
#define SYS_WIN_REG "syscheck/syscheckregistry.db"
#define SYS_REG_TMP "syscheck/syscheck_sum.tmp"
-
-
/* Global variables */
HKEY sub_tree;
int ig_count = 0;
int run_count = 0;
-
-
-
-/** Function prototypes 8*/
+/* Prototypes */
void os_winreg_open_key(char *subkey, char *fullkey_name);
int os_winreg_changed(char *key, char *md5, char *sha1)
{
- char buf[MAX_LINE +1];
-
- buf[MAX_LINE] = '\0';
+ char buf[MAX_LINE + 1];
+ buf[MAX_LINE] = '\0';
- /* Seeking to the beginning of the db */
+ /* Seek to the beginning of the db */
fseek(syscheck.reg_fp, 0, SEEK_SET);
- while(fgets(buf, MAX_LINE, syscheck.reg_fp) != NULL)
- {
- if((buf[0] != '#') && (buf[0] != ' ') && (buf[0] != '\n'))
- {
+ while (fgets(buf, MAX_LINE, syscheck.reg_fp) != NULL) {
+ if ((buf[0] != '#') && (buf[0] != ' ') && (buf[0] != '\n')) {
char *n_buf;
- /* Removing the \n before reading */
+ /* Remove the \n before reading */
n_buf = strchr(buf, '\n');
- if(n_buf == NULL)
+ if (n_buf == NULL) {
continue;
+ }
+
+ *n_buf = '\0';
- *n_buf = '\0';
-
n_buf = strchr(buf, ' ');
- if(n_buf == NULL)
+ if (n_buf == NULL) {
continue;
-
- if(strcmp(n_buf +1, key) != 0)
+ }
+
+ if (strcmp(n_buf + 1, key) != 0) {
continue;
-
- /* Entry found, checking if checksum is the same */
- *n_buf = '\0';
- if((strncmp(buf, md5, sizeof(os_md5) -1) == 0)&&
- (strcmp(buf + sizeof(os_md5) -1, sha1) == 0))
- {
- /* File didn't change. */
- return(0);
}
- /* File did changed */
- return(1);
+ /* Entry found, check if checksum is the same */
+ *n_buf = '\0';
+ if ((strncmp(buf, md5, sizeof(os_md5) - 1) == 0) &&
+ (strcmp(buf + sizeof(os_md5) - 1, sha1) == 0)) {
+ /* File didn't change */
+ return (0);
+ }
+
+ /* File did change */
+ return (1);
}
}
fseek(syscheck.reg_fp, 0, SEEK_END);
fprintf(syscheck.reg_fp, "%s%s %s\n", md5, sha1, key);
- return(1);
+ return (1);
}
-
-/** int notify_registry(char *msg)
- * Notifies of registry changes.
- */
-int notify_registry(char *msg, int send_now)
+/* Notify of registry changes */
+int notify_registry(char *msg, __attribute__((unused)) int send_now)
{
- if(SendMSG(syscheck.queue, msg,
- SYSCHECK_REG, SYSCHECK_MQ) < 0)
- {
+ if (SendMSG(syscheck.queue, msg,
+ SYSCHECK_REG, SYSCHECK_MQ) < 0) {
merror(QUEUE_SEND, ARGV0);
- if((syscheck.queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
- {
+ if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
}
SendMSG(syscheck.queue, msg, SYSCHECK_REG, SYSCHECK_MQ);
}
- return(0);
+ return (0);
}
-
-/** char *os_winreg_sethkey(char *reg_entry)
- * Checks if the registry entry is valid.
- */
+/* Check if the registry entry is valid */
char *os_winreg_sethkey(char *reg_entry)
{
char *ret = NULL;
char *tmp_str;
- /* Getting only the sub tree first */
+ /* Get only the sub tree first */
tmp_str = strchr(reg_entry, '\\');
- if(tmp_str)
- {
+ if (tmp_str) {
*tmp_str = '\0';
- ret = tmp_str+1;
+ ret = tmp_str + 1;
}
- /* Setting sub tree */
- if(strcmp(reg_entry, "HKEY_LOCAL_MACHINE") == 0)
- {
+ /* Set sub tree */
+ if (strcmp(reg_entry, "HKEY_LOCAL_MACHINE") == 0) {
sub_tree = HKEY_LOCAL_MACHINE;
- }
- else if(strcmp(reg_entry, "HKEY_CLASSES_ROOT") == 0)
- {
+ } else if (strcmp(reg_entry, "HKEY_CLASSES_ROOT") == 0) {
sub_tree = HKEY_CLASSES_ROOT;
- }
- else if(strcmp(reg_entry, "HKEY_CURRENT_CONFIG") == 0)
- {
+ } else if (strcmp(reg_entry, "HKEY_CURRENT_CONFIG") == 0) {
sub_tree = HKEY_CURRENT_CONFIG;
- }
- else if(strcmp(reg_entry, "HKEY_USERS") == 0)
- {
+ } else if (strcmp(reg_entry, "HKEY_USERS") == 0) {
sub_tree = HKEY_USERS;
- }
- else
- {
- /* Returning tmp_str to the previous value */
- if(tmp_str && (*tmp_str == '\0'))
+ } else {
+ /* Return tmp_str to the previous value */
+ if (tmp_str && (*tmp_str == '\0')) {
*tmp_str = '\\';
- return(NULL);
+ }
+ return (NULL);
}
- /* Checking if ret has nothing else. */
- if(ret && (*ret == '\0'))
+ /* Check if ret has nothing else */
+ if (ret && (*ret == '\0')) {
ret = NULL;
-
- /* fixing tmp_str and the real name of the registry */
- if(tmp_str && (*tmp_str == '\0'))
- *tmp_str = '\\';
-
- return(ret);
-}
+ }
+ /* Fix tmp_str and the real name of the registry */
+ if (tmp_str && (*tmp_str == '\0')) {
+ *tmp_str = '\\';
+ }
-/* void os_winreg_querykey(HKEY hKey, char *p_key)
- * Query the key and get all its values.
- */
-void os_winreg_querykey(HKEY hKey, char *p_key, char *full_key_name)
+ return (ret);
+}
+
+/* Query the key and get all its values */
+void os_winreg_querykey(HKEY hKey, char *p_key, char *full_key_name)
{
- int i, rc;
- DWORD j;
+ int rc;
+ DWORD i, j;
/* QueryInfo and EnumKey variables */
- TCHAR sub_key_name_b[MAX_KEY_LENGTH +2];
- TCHAR class_name_b[MAX_PATH +1];
+ TCHAR sub_key_name_b[MAX_KEY_LENGTH + 2];
+ TCHAR class_name_b[MAX_PATH + 1];
DWORD sub_key_name_s;
DWORD class_name_s = MAX_PATH;
DWORD value_count;
/* Variables for RegEnumValue */
- TCHAR value_buffer[MAX_VALUE_NAME +1];
- TCHAR data_buffer[MAX_VALUE_NAME +1];
+ TCHAR value_buffer[MAX_VALUE_NAME + 1];
+ TCHAR data_buffer[MAX_VALUE_NAME + 1];
DWORD value_size;
DWORD data_size;
/* Data type for RegEnumValue */
DWORD data_type = 0;
-
/* Initializing the memory for some variables */
class_name_b[0] = '\0';
class_name_b[MAX_PATH] = '\0';
sub_key_name_b[0] = '\0';
sub_key_name_b[MAX_KEY_LENGTH] = '\0';
- sub_key_name_b[MAX_KEY_LENGTH +1] = '\0';
-
+ sub_key_name_b[MAX_KEY_LENGTH + 1] = '\0';
- /* We use the class_name, subkey_count and the value count. */
+ /* We use the class_name, subkey_count and the value count */
rc = RegQueryInfoKey(hKey, class_name_b, &class_name_s, NULL,
- &subkey_count, NULL, NULL, &value_count,
- NULL, NULL, NULL, NULL);
+ &subkey_count, NULL, NULL, &value_count,
+ NULL, NULL, NULL, NULL);
/* Check return code of QueryInfo */
- if(rc != ERROR_SUCCESS)
- {
+ if (rc != ERROR_SUCCESS) {
return;
}
-
-
- /* Checking if we have sub keys */
- if(subkey_count)
- {
- /* We open each subkey and call open_key */
- for(i=0;i<subkey_count;i++)
- {
+ /* Check if we have sub keys */
+ if (subkey_count) {
+ /* Open each subkey and call open_key */
+ for (i = 0; i < subkey_count; i++) {
sub_key_name_s = MAX_KEY_LENGTH;
rc = RegEnumKeyEx(hKey, i, sub_key_name_b, &sub_key_name_s,
- NULL, NULL, NULL, NULL);
-
- /* Checking for the rc. */
- if(rc == ERROR_SUCCESS)
- {
+ NULL, NULL, NULL, NULL);
+
+ /* Checking for the rc */
+ if (rc == ERROR_SUCCESS) {
char new_key[MAX_KEY + 2];
char new_key_full[MAX_KEY + 2];
- new_key[MAX_KEY +1] = '\0';
- new_key_full[MAX_KEY +1] = '\0';
+ new_key[MAX_KEY + 1] = '\0';
+ new_key_full[MAX_KEY + 1] = '\0';
- if(p_key)
- {
- snprintf(new_key, MAX_KEY,
+ if (p_key) {
+ snprintf(new_key, MAX_KEY,
"%s\\%s", p_key, sub_key_name_b);
- snprintf(new_key_full, MAX_KEY,
+ snprintf(new_key_full, MAX_KEY,
"%s\\%s", full_key_name, sub_key_name_b);
- }
- else
- {
+ } else {
snprintf(new_key, MAX_KEY, "%s", sub_key_name_b);
- snprintf(new_key_full, MAX_KEY,
+ snprintf(new_key_full, MAX_KEY,
"%s\\%s", full_key_name, sub_key_name_b);
}
- /* Opening subkey */
+ /* Open subkey */
os_winreg_open_key(new_key, new_key_full);
}
}
}
-
- /* Getting Values (if available) */
- if (value_count)
- {
+
+ /* Get values (if available) */
+ if (value_count) {
/* md5 and sha1 sum */
os_md5 mf_sum;
os_sha1 sf_sum;
-
FILE *checksum_fp;
-
char *mt_data;
-
- /* Clearing the values for value_size and data_size */
+ /* Clear the values for value_size and data_size */
value_buffer[MAX_VALUE_NAME] = '\0';
data_buffer[MAX_VALUE_NAME] = '\0';
checksum_fp = fopen(SYS_REG_TMP, "w");
- if(!checksum_fp)
- {
- printf(FOPEN_ERROR, ARGV0, SYS_REG_TMP);
+ if (!checksum_fp) {
+ printf(FOPEN_ERROR, ARGV0, SYS_REG_TMP, errno, strerror(errno));
return;
}
- /* Getting each value */
- for(i=0;i<value_count;i++)
- {
- value_size = MAX_VALUE_NAME;
+ /* Get each value */
+ for (i = 0; i < value_count; i++) {
+ value_size = MAX_VALUE_NAME;
data_size = MAX_VALUE_NAME;
value_buffer[0] = '\0';
data_buffer[0] = '\0';
rc = RegEnumValue(hKey, i, value_buffer, &value_size,
- NULL, &data_type, data_buffer, &data_size);
+ NULL, &data_type, (LPBYTE)data_buffer, &data_size);
/* No more values available */
- if(rc != ERROR_SUCCESS)
- {
+ if (rc != ERROR_SUCCESS) {
break;
}
- /* Checking if no value name is specified */
- if(value_buffer[0] == '\0')
- {
+ /* Check if no value name is specified */
+ if (value_buffer[0] == '\0') {
value_buffer[0] = '@';
value_buffer[1] = '\0';
}
- /* Writing valud name and data in the file (for checksum later) */
+ /* Write value name and data in the file (for checksum later) */
fprintf(checksum_fp, "%s=", value_buffer);
- switch(data_type)
- {
+ switch (data_type) {
case REG_SZ:
case REG_EXPAND_SZ:
fprintf(checksum_fp, "%s\n", data_buffer);
break;
case REG_MULTI_SZ:
- /* Printing multiple strings */
+ /* Print multiple strings */
mt_data = data_buffer;
- while(*mt_data)
- {
+ while (*mt_data) {
fprintf(checksum_fp, "%s ", mt_data);
- mt_data += strlen(mt_data) +1;
+ mt_data += strlen(mt_data) + 1;
}
fprintf(checksum_fp, "\n");
break;
case REG_DWORD:
- fprintf(checksum_fp, "%08x\n",(unsigned int)*data_buffer);
+ fprintf(checksum_fp, "%08x\n", (unsigned int)*data_buffer);
break;
default:
- for(j = 0;j<data_size;j++)
- {
+ for (j = 0; j < data_size; j++) {
fprintf(checksum_fp, "%02x",
(unsigned int)data_buffer[j]);
}
fprintf(checksum_fp, "\n");
- break;
+ break;
}
}
- /* Generating checksum of the values */
+ /* Generate checksum of the values */
fclose(checksum_fp);
- if(OS_MD5_SHA1_File(SYS_REG_TMP, mf_sum, sf_sum) == -1)
- {
- merror(FOPEN_ERROR, ARGV0, SYS_REG_TMP);
+ if (OS_MD5_SHA1_File(SYS_REG_TMP, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_TEXT) == -1) {
+ merror(FOPEN_ERROR, ARGV0, SYS_REG_TMP, errno, strerror(errno));
return;
}
-
- /* Looking for p_key on the reg db */
- if(os_winreg_changed(full_key_name, mf_sum, sf_sum))
- {
- char reg_changed[MAX_LINE +1];
+ /* Look for p_key on the reg db */
+ if (os_winreg_changed(full_key_name, mf_sum, sf_sum)) {
+ char reg_changed[MAX_LINE + 1];
snprintf(reg_changed, MAX_LINE, "0:0:0:0:%s:%s %s",
- mf_sum, sf_sum, full_key_name);
+ mf_sum, sf_sum, full_key_name);
- /* Notifying server */
+ /* Notify server */
notify_registry(reg_changed, 0);
}
}
}
-
-/* int os_winreg_open_key(char *subkey)
- * Open the registry key
- */
+/* Open the registry key */
void os_winreg_open_key(char *subkey, char *full_key_name)
{
- int i = 0;
+ int i = 0;
HKEY oshkey;
- /* sleep X every Y files */
- if(ig_count >= syscheck.sleep_after)
- {
- sleep(syscheck.tsleep +1);
+ /* Sleep X every Y files */
+ if (ig_count >= syscheck.sleep_after) {
+ sleep(syscheck.tsleep + 1);
ig_count = 1;
}
ig_count++;
-
/* Registry ignore list */
- if(full_key_name && syscheck.registry_ignore)
- {
- while(syscheck.registry_ignore[i] != NULL)
- {
- if(strcasecmp(syscheck.registry_ignore[i], full_key_name) == 0)
- {
+ if (full_key_name && syscheck.registry_ignore) {
+ while (syscheck.registry_ignore[i] != NULL) {
+ if (strcasecmp(syscheck.registry_ignore[i], full_key_name) == 0) {
return;
}
i++;
}
- }
- else if(full_key_name && syscheck.registry_ignore_regex)
- {
+ } else if (full_key_name && syscheck.registry_ignore_regex) {
i = 0;
- while(syscheck.registry_ignore_regex[i] != NULL)
- {
- if(OSMatch_Execute(full_key_name, strlen(full_key_name),
- syscheck.registry_ignore_regex[i]))
- {
+ while (syscheck.registry_ignore_regex[i] != NULL) {
+ if (OSMatch_Execute(full_key_name, strlen(full_key_name),
+ syscheck.registry_ignore_regex[i])) {
return;
}
i++;
}
}
-
- if(RegOpenKeyEx(sub_tree, subkey, 0, KEY_READ, &oshkey) != ERROR_SUCCESS)
- {
+ if (RegOpenKeyEx(sub_tree, subkey, 0, KEY_READ, &oshkey) != ERROR_SUCCESS) {
merror(SK_REG_OPEN, ARGV0, subkey);
return;
}
return;
}
-
-/** void os_winreg_check()
- * Main function to read the registry.
- */
+/* Main function to read the registry */
void os_winreg_check()
{
int i = 0;
/* Debug entries */
debug1("%s: DEBUG: Starting os_winreg_check", ARGV0);
-
-
- /* Zeroing ig_count before checking */
+
+ /* Zero ig_count before checking */
ig_count = 1;
-
- /* Checking if the registry fp is open */
- if(syscheck.reg_fp == NULL)
- {
+ /* Check if the registry fp is open */
+ if (syscheck.reg_fp == NULL) {
syscheck.reg_fp = fopen(SYS_WIN_REG, "w+");
- if(!syscheck.reg_fp)
- {
- merror(FOPEN_ERROR, ARGV0, SYS_WIN_REG);
+ if (!syscheck.reg_fp) {
+ merror(FOPEN_ERROR, ARGV0, SYS_WIN_REG, errno, strerror(errno));
return;
}
}
-
- /* Getting sub class and a valid registry entry */
- while(syscheck.registry[i] != NULL)
- {
+ /* Get sub class and a valid registry entry */
+ while (syscheck.registry[i] != NULL) {
sub_tree = NULL;
rk = NULL;
-
+
/* Ignored entries are zeroed */
- if(*syscheck.registry[i] == '\0')
- {
+ if (*syscheck.registry[i] == '\0') {
i++;
continue;
}
-
-
- /* Reading syscheck registry entry */
+
+ /* Read syscheck registry entry */
debug1("%s: DEBUG: Attempt to read: %s", ARGV0, syscheck.registry[i]);
-
-
+
rk = os_winreg_sethkey(syscheck.registry[i]);
- if(sub_tree == NULL)
- {
+ if (sub_tree == NULL) {
merror(SK_INV_REG, ARGV0, syscheck.registry[i]);
*syscheck.registry[i] = '\0';
i++;
os_winreg_open_key(rk, syscheck.registry[i]);
i++;
- sleep(syscheck.tsleep *5);
+ sleep(syscheck.tsleep * 5);
}
-
- /* Notify of db completed. */
- if(run_count > 1)
- {
- sleep(syscheck.tsleep *5);
+ /* Notify of db completed */
+ if (run_count > 1) {
+ sleep(syscheck.tsleep * 5);
notify_registry(HC_SK_DB_COMPLETED, 1);
}
run_count++;
return;
}
-
-
#endif /* WIN32 */
-/* EOF */