1 /**
2 ** @internal
3 ** yafcygwin.c
4 ** YAF cygwin
5 **
6 ** ------------------------------------------------------------------------
7 ** Copyright (C) 2011-2016 Carnegie Mellon University. All Rights Reserved.
8 ** ------------------------------------------------------------------------
9 ** Authors: Chris Inacio
10 ** ------------------------------------------------------------------------
11 ** @OPENSOURCE_HEADER_START@
12 ** Use of the YAF system and related source code is subject to the terms
13 ** of the following licenses:
14 **
15 ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
16 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
17 **
18 ** NO WARRANTY
19 **
20 ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
21 ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
22 ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
23 ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
24 ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
25 ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
26 ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
27 ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
28 ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
29 ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
30 ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
31 ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
32 ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
33 ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
34 ** DELIVERABLES UNDER THIS LICENSE.
35 **
36 ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
37 ** Mellon University, its trustees, officers, employees, and agents from
38 ** all claims or demands made against them (and any related losses,
39 ** expenses, or attorney's fees) arising out of, or relating to Licensee's
40 ** and/or its sub licensees' negligent use or willful misuse of or
41 ** negligent conduct or willful misconduct regarding the Software,
42 ** facilities, or other rights or assistance granted by Carnegie Mellon
43 ** University under this License, including, but not limited to, any
44 ** claims of product liability, personal injury, death, damage to
45 ** property, or violation of any laws or regulations.
46 **
47 ** Carnegie Mellon University Software Engineering Institute authored
48 ** documents are sponsored by the U.S. Department of Defense under
49 ** Contract FA8721-05-C-0003. Carnegie Mellon University retains
50 ** copyrights in all material produced under this contract. The U.S.
51 ** Government retains a non-exclusive, royalty-free license to publish or
52 ** reproduce these documents, or allow others to do so, for U.S.
53 ** Government purposes only pursuant to the copyright license under the
54 ** contract clause at 252.227.7013.
55 **
56 ** @OPENSOURCE_HEADER_END@
57 ** ------------------------------------------------------------------------
58 */
59
60 /* Microsoft says to define _WIN32_WINNT to get the right
61 windows API version, but under Cygwin, you need to define
62 WINVER - which are related, (but not the same?). They
63 are believed to be the same under Cygwin */
64
65 #ifdef __CYGWIN__
66 #define _WIN32_WINNT 0x0600
67 #define WINVER 0x0600
68 #include <windows.h>
69 #endif
70
71 #include <string.h>
72 #include <stddef.h>
73 #include <ctype.h>
74 #include <stdio.h>
75
76
77 #define INITIAL_BUFFER_SIZE 8192
78 #define BUFFER_INCREMENT_SIZE 4096
79
80 /* for testing
81 #define NETSA_WINDOWSREG_REGHOME "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
82 #define SILK_WINDOWSREG_DATA_DIR_KEY "SystemRoot"
83 */
84
85 /* registry location/key definitions */
86 #define NETSA_WINDOWSREG_REGHOME "Software\\CERT\\NetSATools"
87 #define NETSA_WINDOWSREG_INSTALLDIR_KEY "InstallDir"
88 #define SILK_WINDOWSREG_DATA_DIR_KEY "SilkDataDir"
89 #define YAF_WINDOWSREG_CONF_DIR_KEY "YafConfDir"
90
91 #define SILK_DEFAULT_CYGWIN_DATA_DIR "/cygdrive/c/data"
92
93 #define CYGWIN_PATH_PREFIX "/cygdrive/"
94
95 static char *winRegDataDir = NULL;
96
97
98 /**
99 * yfCygwinClean
100 *
101 * frees up allocated memory used as caching within this cygwin module
102 * provided for future memory leak testing
103 *
104 */
105 void
yfCygwinClean(void)106 yfCygwinClean (void)
107 {
108
109 if (NULL != winRegDataDir) {
110 free(winRegDataDir);
111 }
112
113 return;
114 }
115
116 /**
117 *windowsToCygwinPath
118 *
119 * converts a "normal" windows path "C:\Windows\" into an equivalent
120 * cygwin path "/cygdrive/c/Windows/"
121 *
122 * @note this function creates callee deallocated memory
123 *
124 * @param winPath a character string containing a windows path
125 *
126 * @return a malloced string converted into a cygwin path, on error
127 * this function returns NULL
128 */
129 static
130 char *
windowsToCygwinPath(const char * winPath)131 windowsToCygwinPath (const char *winPath)
132 {
133
134 char *resultStr = NULL;
135 char *resultLoc = NULL;
136 const char *workLoc = winPath;
137
138 resultStr = (char *) malloc(strlen(winPath)+strlen(CYGWIN_PATH_PREFIX)+1);
139 if (NULL == resultStr) {
140 return NULL;
141 }
142 resultLoc = resultStr;
143
144 /* include the default prefix */
145 strcpy(resultLoc, CYGWIN_PATH_PREFIX);
146 resultLoc += strlen(CYGWIN_PATH_PREFIX);
147
148 /* first, let's try to find the drive prefix, e.g. c: or d: or z: */
149 workLoc = strchr(winPath, ':');
150 if (NULL == workLoc) {
151 /* it's a relative path, run with it? */
152 free(resultStr);
153 return NULL;
154 }
155
156 /* the character before workLoc should be the drive letter */
157 strncpy(resultLoc, (workLoc-1), 1);
158 *resultLoc++ = (char) tolower((int)*(workLoc-1));
159 workLoc++;
160
161 /* now copy in the rest of the path, converting "\" into "/" */
162 while (*workLoc) {
163 if ('\\' == *workLoc) {
164 *resultLoc = '/';
165 } else {
166 *resultLoc = *workLoc;
167 }
168 resultLoc++; workLoc++;
169 }
170
171 /* make sure resultLoc is terminated */
172 *resultLoc = '\0';
173
174 /* safety check, did we run off the end of resultLoc */
175 if ((resultLoc - resultStr) > (strlen(winPath)+strlen(CYGWIN_PATH_PREFIX)+1)) {
176 abort();
177 }
178
179 /* return the converted string */
180 return resultStr;
181 }
182
183
184
185 /**
186 * yfGetCygwinConfDir
187 *
188 * Gets the yaf config directory defined at INSTALLATION time on
189 * Windows machines via reading the windows registry.
190 * Caches the result in a file static.
191 *
192 * @return constant string with the data directory name
193 *
194 * @note must call yfCygwinClean to get rid of the memory
195 * for the cached result
196 */
197 const char *
yfGetCygwinConfDir()198 yfGetCygwinConfDir ()
199 {
200
201 char *dataBuffer = NULL;
202 DWORD bufferSize = 0;
203 DWORD rc;
204
205
206 if (NULL != winRegDataDir) {
207 return winRegDataDir;
208 }
209
210 /* allocate memory for the initial buffer,
211 likely this is big enough */
212 dataBuffer = (char *) malloc( sizeof(char) * INITIAL_BUFFER_SIZE);
213 if (NULL == dataBuffer) {
214 /* error couldn't allocate memory */
215 return NULL;
216 }
217 bufferSize = INITIAL_BUFFER_SIZE;
218
219 /* keeping asking the registry for the value until we have
220 a buffer big enough to hold it */
221 do {
222 rc = RegGetValue ( HKEY_LOCAL_MACHINE,
223 NETSA_WINDOWSREG_REGHOME,
224 SILK_WINDOWSREG_DATA_DIR_KEY, RRF_RT_ANY,
225 NULL, (PVOID)dataBuffer, &bufferSize);
226
227 if (ERROR_MORE_DATA == rc) {
228 dataBuffer = (char *) realloc(dataBuffer,
229 (bufferSize + BUFFER_INCREMENT_SIZE));
230 if (NULL == dataBuffer) {
231 return NULL;
232 }
233 bufferSize += BUFFER_INCREMENT_SIZE;
234 }
235 } while ( ERROR_MORE_DATA == rc);
236
237 if ( ERROR_SUCCESS == rc ) {
238 if ( 0 == bufferSize ) {
239 /* What makes sense to do when we can't find the registry entry?
240 In this case, we return a "sane" default for windows
241 */
242 winRegDataDir = SILK_DEFAULT_CYGWIN_DATA_DIR;
243 free(dataBuffer);
244 return SILK_DEFAULT_CYGWIN_DATA_DIR;
245 } else {
246 winRegDataDir = windowsToCygwinPath(dataBuffer);
247 free(dataBuffer);
248 return winRegDataDir;
249 }
250
251 } else {
252
253 return NULL;
254 }
255 }
256