new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / win32 / read-registry.c
1 #include "shared.h"
2 #include "os_crypto/md5/md5_op.h"
3 #include "os_crypto/sha1/sha1_op.h"
4
5 /* Default values */
6 #define MAX_KEY_LENGTH   255
7 #define MAX_KEY         2048
8 #define MAX_VALUE_NAME 16383
9
10 char *(os_winreg_ignore_list[]) = {"SOFTWARE\\Classes", "test123", NULL};
11
12 HKEY sub_tree;
13 void os_winreg_open_key(char *subkey);
14
15
16 void os_winreg_querykey(HKEY hKey, char *p_key)
17 {
18     int i, rc;
19     DWORD j;
20
21     /* QueryInfo and EnumKey variables */
22     TCHAR sub_key_name_b[MAX_KEY_LENGTH + 1];
23     TCHAR class_name_b[MAX_PATH + 1];
24     DWORD sub_key_name_s;
25     DWORD class_name_s = MAX_PATH;
26
27     /* Number of sub keys */
28     DWORD subkey_count = 0;
29
30     /* Number of values */
31     DWORD value_count;
32
33     /* Variables for RegEnumValue */
34     TCHAR value_buffer[MAX_VALUE_NAME + 1];
35     TCHAR data_buffer[MAX_VALUE_NAME + 1];
36     DWORD value_size;
37     DWORD data_size;
38
39     /* Data type for RegEnumValue */
40     DWORD data_type = 0;
41
42     /* Initialize the memory for some variables */
43     class_name_b[0] = '\0';
44     class_name_b[MAX_PATH] = '\0';
45     sub_key_name_b[0] = '\0';
46     sub_key_name_b[MAX_KEY_LENGTH] = '\0';
47
48     /* We only use the class_name, subkey_count and value count */
49     rc = RegQueryInfoKey(hKey, class_name_b, &class_name_s, NULL,
50                          &subkey_count, NULL, NULL, &value_count,
51                          NULL, NULL, NULL, NULL);
52
53     /* Check return code of QueryInfo */
54     if (rc != ERROR_SUCCESS) {
55         return;
56     }
57
58     /* Check if we have sub keys */
59     if (subkey_count) {
60         /* Open each subkey and call open_key */
61         for (i = 0; i < subkey_count; i++) {
62             sub_key_name_s = MAX_KEY_LENGTH;
63             rc = RegEnumKeyEx(hKey, i, sub_key_name_b, &sub_key_name_s,
64                               NULL, NULL, NULL, NULL);
65
66             /* Check for the rc */
67             if (rc == ERROR_SUCCESS) {
68                 char new_key[MAX_KEY_LENGTH + 2];
69                 new_key[MAX_KEY_LENGTH + 1] = '\0';
70
71                 if (p_key) {
72                     snprintf(new_key, MAX_KEY_LENGTH,
73                              "%s\\%s", p_key, sub_key_name_b);
74                 } else {
75                     snprintf(new_key, MAX_KEY_LENGTH, "%s", sub_key_name_b);
76                 }
77
78                 /* Open subkey */
79                 os_winreg_open_key(new_key);
80             }
81         }
82     }
83
84     /* Get Values (if available) */
85     if (value_count) {
86         /* MD5 and SHA-1 */
87         os_md5 mf_sum;
88         os_sha1 sf_sum;
89
90         /* Clear the values for value_size and data_size */
91         value_buffer[MAX_VALUE_NAME] = '\0';
92         data_buffer[MAX_VALUE_NAME] = '\0';
93
94         for (i = 0; i < value_count; i++) {
95             value_size = MAX_VALUE_NAME;
96             data_size = MAX_VALUE_NAME;
97
98             value_buffer[0] = '\0';
99             data_buffer[0] = '\0';
100
101             rc = RegEnumValue(hKey, i, value_buffer, &value_size,
102                               NULL, &data_type, data_buffer, &data_size);
103
104             /* No more values available */
105             if (rc != ERROR_SUCCESS) {
106                 break;
107             }
108
109             /* Check if no value name is specified */
110             if (value_buffer[0] == '\0') {
111                 value_buffer[0] = '@';
112                 value_buffer[1] = '\0';
113             }
114             printf("   (%d) %s=", i + 1, value_buffer);
115             switch (data_type) {
116                 case REG_SZ:
117                 case REG_EXPAND_SZ:
118                     printf("%s\n", data_buffer);
119                     break;
120                 case REG_MULTI_SZ:
121                     /* Print multiple strings */
122                     printf("MULTI_SZ:");
123                     char *mt_data;
124
125                     mt_data = data_buffer;
126                     while (*mt_data) {
127                         printf("%s ", mt_data);
128                         mt_data += strlen(mt_data) + 1;
129                     }
130                     printf("\n");
131                     break;
132                 case REG_DWORD:
133                     printf("%08x\n", (unsigned int)*data_buffer);
134                     break;
135                 default:
136                     printf("UNSUPPORTED(%d-%d):", (int)data_type, data_size);
137                     for (j = 0; j < data_size; j++) {
138                         printf("%02x", (unsigned int)data_buffer[j]);
139                     }
140                     printf("\n");
141                     break;
142             }
143         }
144     }
145 }
146
147 /* Open the registry key */
148 void os_winreg_open_key(char *subkey)
149 {
150     int i = 0;
151     HKEY oshkey;
152
153     /* Registry ignore list */
154     if (subkey) {
155         while (os_winreg_ignore_list[i] != NULL) {
156             if (strcasecmp(os_winreg_ignore_list[i], subkey) == 0) {
157                 return;
158             }
159             i++;
160         }
161     }
162
163     if(RegOpenKeyEx(sub_tree, subkey, 0, (KEY_READ | KEY_WOW64_64KEY), &oshkey) != ERROR_SUCCESS)
164     {
165         merror(SK_REG_OPEN64, ARGV0, subkey);
166         return;
167     }
168
169     if(RegOpenKeyEx(sub_tree, subkey, 0, (KEY_READ | KEY_WOW64_32KEY), &oshkey) != ERROR_SUCCESS)
170     {
171         merror(SK_REG_OPEN, ARGV0, subkey);
172         return;
173     }
174
175     os_winreg_querykey(oshkey, subkey);
176     RegCloseKey(sub_tree);
177 }
178
179 /* Main function to read the registry */
180 int main(void)
181 {
182     sub_tree = HKEY_LOCAL_MACHINE;
183     char *rk = NULL;
184
185     os_winreg_open_key(rk);
186
187     return (0);
188 }
189