Imported Upstream version 2.5.1
[ossec-hids.git] / src / rootcheck / os_string.c
1 /* @(#) $Id$ */
2
3 /* Included and modified strings.c from the OpenBSD project.
4  * Copyright bellow.
5  */
6  
7 /*
8  * Copyright (c) 1980, 1987, 1993
9  *      The Regents of the University of California.  All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36
37 #ifndef WIN32
38 #include <sys/types.h>
39
40 #include <ctype.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <locale.h>
47 #include <unistd.h>
48
49 #include <netinet/in.h>
50
51
52 /* Again, making solaris happy... */
53 #ifdef SOLARIS
54 #include <sys/exechdr.h>
55
56 #elif defined Darwin || defined HPUX
57
58 /* For some reason darwin does not have that */
59 struct exec
60 {
61   unsigned long a_info;         /* Use macros N_MAGIC, etc for access */
62   unsigned char   a_machtype;     /* machine type */
63   unsigned short  a_magic;        /* magic number */
64   unsigned a_text;              /* length of text, in bytes */
65   unsigned a_data;              /* length of data, in bytes */
66   unsigned a_bss;               /* length of uninitialized data area for file, in bytes */
67   unsigned a_syms;              /* length of symbol table data in file, in bytes */
68   unsigned a_entry;             /* start address */
69   unsigned a_trsize;            /* length of relocation info for text, in bytes */
70   unsigned a_drsize;            /* length of relocation info for data, in bytes */
71 };
72 #define OMAGIC 0407             /* Object file or impure executable.  */
73 #define NMAGIC 0410             /* Code indicating pure executable.  */
74 #define ZMAGIC 0413             /* Code indicating demand-paged executable.  */
75 #define BMAGIC 0415             /* Used by a b.out object.  */
76 #define M_OLDSUN2       0
77
78 #else
79
80 #include <a.out.h>
81 #endif
82
83
84 #ifndef PAGSIZ
85 #define       PAGSIZ          0x02000
86 #endif
87
88 #ifndef OLD_PAGSIZ
89 #define       OLD_PAGSIZ      0x00800
90 #endif
91
92 #ifndef N_BADMAG
93
94 #ifdef AIX
95 #define       N_BADMAG(x) \
96     (((x).magic)!=U802TOCMAGIC && ((x).magic)!=U803TOCMAGIC && ((x).magic)!=U803XTOCMAGIC && ((x).magic)!=U64_TOCMAGIC)
97 #else /* non AIX */
98 #define       N_BADMAG(x) \
99     (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
100 #endif
101
102 #endif  /* N_BADMAG */
103
104 #ifndef N_PAGSIZ
105 #define       N_PAGSIZ(x) \
106         ((x).a_machtype == M_OLDSUN2? OLD_PAGSIZ : PAGSIZ)
107 #endif
108
109 #ifndef N_TXTOFF
110
111 #ifdef AIX
112 #define         N_TXTOFF(x) \
113         /* text segment */ \
114             ((x).magic==U64_TOCMAGIC ? 0 : sizeof (struct aouthdr))
115 #else /* non AIX */
116 #define       N_TXTOFF(x) \
117         /* text segment */ \
118     ((x).a_machtype == M_OLDSUN2 \
119            ? ((x).a_magic==ZMAGIC ? N_PAGSIZ(x) : sizeof (struct exec)) \
120            : ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec)) )
121 #endif
122
123 #endif /* N_TXTOFF */
124
125
126 #include "headers/defs.h"
127 #include "headers/debug_op.h"
128 #include "headers/regex_op.h"
129
130 #include "error_messages/error_messages.h"
131
132 #define STR_MINLEN  4       /* Minumum length for a string */
133
134 #define ISSTR(ch)       (isascii(ch) && (isprint(ch) || ch == '\t'))
135
136
137 #ifdef AIX
138 typedef struct aouthdr EXEC;    
139 #else
140 typedef struct exec EXEC;    
141 #endif
142
143 typedef struct _os_strings
144 {
145     int head_len;
146     int read_len;
147     int hcnt;
148     long foff;
149     unsigned char hbfr[sizeof(EXEC)];
150     FILE *fp;
151 }os_strings;
152
153
154 /* os_getch: Read each character from a binary file */
155 int os_getch(os_strings *oss);
156
157
158 /* os_strings: List the strings of a binary and
159  * check if the regex given is there.
160  */
161 int os_string(char *file, char *regex)
162 {
163     int ch, cnt;
164     
165     unsigned char *C;
166     unsigned char *bfr;
167  
168     char line[OS_SIZE_1024 +1];
169     char *buf;
170     
171     EXEC *head;
172
173     os_strings oss;
174    
175     /* Return didn't match */
176     if(!file || !regex)
177     {
178         return(0);
179     }
180     
181     
182     /* Allocating for the buffer */ 
183     bfr = calloc(STR_MINLEN + 2, sizeof(char *));
184     if (!bfr)
185     {
186         merror(MEM_ERROR, ARGV0);
187         return(0);
188     }
189
190     /* Opening the file */
191     oss.fp = fopen(file, "r");
192     if(!oss.fp)
193     {
194         free(bfr);
195         return(0);
196     }
197
198     /* cleaning the line */
199     memset(line, '\0', OS_SIZE_1024 +1);
200     
201     /* starting .. (from old strings.c) */
202     oss.foff = 0;
203     oss.head_len = 0;
204     
205     oss.read_len = -1;
206     head = (EXEC *)oss.hbfr;
207
208     
209     if ((oss.head_len = read(fileno(oss.fp), head, sizeof(EXEC))) == -1)
210     {
211         oss.head_len = 0;
212         oss.read_len = -1;
213     }
214     else if (oss.head_len == sizeof(EXEC) && !N_BADMAG(*head)) 
215     {
216         oss.foff = N_TXTOFF(*head);
217         if (fseek(stdin, oss.foff, SEEK_SET) == -1)
218         {
219             oss.read_len = -1;
220         }
221         else
222         {
223             #ifdef AIX
224             oss.read_len = head->tsize + head->dsize;
225             #else
226             oss.read_len = head->a_text + head->a_data;
227             #endif
228         }
229
230         oss.head_len = 0;
231     }
232     else
233     {
234         oss.hcnt = 0;
235     }
236
237     /* Read the file and perform the regex comparison */
238     for (cnt = 0; (ch = os_getch(&oss)) != EOF;) 
239     {
240         if (ISSTR(ch)) 
241         {
242             if (!cnt)
243                 C = bfr;
244             *C++ = ch;
245             if (++cnt < STR_MINLEN)
246                 continue;
247             
248             strncpy(line, (char *)bfr, STR_MINLEN +1);
249             buf = line;
250             buf+=strlen(line);
251             
252
253             while ((ch = os_getch(&oss)) != EOF && ISSTR(ch))
254             {
255                 if(cnt < OS_SIZE_1024)
256                 {
257                     *buf = (char)ch;
258                     buf++;
259                 }
260                 else
261                 {
262                     *buf = '\0';
263                     break;
264                 }
265                 cnt++;
266             }
267
268             *buf = '\0';
269
270             if(OS_PRegex(line, regex))
271             {
272                 if(oss.fp)
273                     fclose(oss.fp);
274                 free(bfr);
275                 return(1);
276             }
277         }
278
279         cnt = 0;
280     }
281
282     if(oss.fp)
283         fclose(oss.fp);
284     free(bfr);
285     return(0);
286 }
287
288
289 /*
290  * getch (os_getch, modified)--
291  *      get next character from wherever
292  */
293 int os_getch(os_strings *oss)
294 {
295         ++oss->foff;
296         if (oss->head_len) 
297     {
298                 if (oss->hcnt < oss->head_len)
299                         return((int)oss->hbfr[oss->hcnt++]);
300                 oss->head_len = 0;
301         }
302         if (oss->read_len == -1 || oss->read_len-- > 0)
303     {
304                 return(fgetc(oss->fp));
305     }
306         return(EOF);
307 }
308
309 /* EOF */
310 #else
311 int os_string(char *file, char *regex)
312 {
313     return(0);
314 }
315 #endif