1 /*
2 * Copyright (c) 2002, 2003, 2004 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32 /*
33 * Copyright 2003 Christopher Kolina, Derek Cotton and Yuqing Mai
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. The name of the author may not be used to endorse or promote products
45 * derived from this software without specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 */
58
59 #include <sys/param.h>
60 #include <sys/types.h>
61
62 #include "config.h"
63
64 #ifdef HAVE_SYS_TIME_H
65 #include <sys/time.h>
66 #endif
67 #include <sys/stat.h>
68 #include <sys/tree.h>
69 #include <sys/queue.h>
70 #include <sys/wait.h>
71
72 #include <err.h>
73 #include <errno.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <string.h>
77 #include <syslog.h>
78 #include <unistd.h>
79 #include <dnet.h>
80 #include <ctype.h>
81
82 #undef timeout_pending
83 #undef timeout_initialized
84
85 #include <math.h>
86 #include <event.h>
87
88 #include "honeyd.h"
89 #include "personality.h"
90 #include "xprobe_assoc.h"
91
92 static int
assoc_compare(assoc_item * a,assoc_item * b)93 assoc_compare(assoc_item *a, assoc_item *b)
94 {
95 return strcmp(a->nmap_name, b->nmap_name);
96 }
97
98 SPLAY_HEAD(assoc_tree, assoc_item) associations;
99 SPLAY_PROTOTYPE(assoc_tree, assoc_item, node, assoc_compare);
100
101 SPLAY_GENERATE(assoc_tree, assoc_item, node, assoc_compare);
102
103 void
associations_init(void)104 associations_init(void)
105 {
106 SPLAY_INIT(&associations);
107 }
108
109 /**
110 * Retrieves a single line from the associations files and parses it.
111 *
112 * @param fp the FILE stream pointer
113 * @return NULL if the line did not parse to an association, or a new
114 * assoc_item if it did.
115 */
116
117 static assoc_item *
get_assoc(FILE * fp)118 get_assoc(FILE *fp)
119 {
120 char line[1024];
121 char *p, *q;
122 assoc_item *assoc = NULL;
123 struct xp_fingerprint fprint;
124
125 /* Get one line */
126 p = fgets(line, sizeof(line), fp);
127 if (p == NULL)
128 return (NULL);
129
130 /* Remove leading whitespace */
131 p += strspn(p, WHITESPACE);
132
133 /* Remove comments and blank lines */
134 if (*p == '\0' || *p == '#')
135 return (NULL);
136
137 /* Remove trailing comments */
138 q = p;
139 strsep(&q, "#\r\n");
140
141 /* Split on ; */
142 q = p;
143 p = strsep(&q, ";");
144 if (p == NULL || q == NULL)
145 return (NULL);
146
147 /* Make a new association */
148 assoc = (assoc_item *)calloc(1, sizeof(struct assoc_item));
149 if (assoc == NULL)
150 return (NULL);
151
152 /* The value in p is the nmap name. The value in q is the xprobe
153 * name.
154 */
155 fprint.os_id = q;
156 assoc->nmap_name = strdup(p);
157 assoc->xp_fprint = SPLAY_FIND(xp_fprint_tree, &xp_fprints, &fprint);
158
159 /* Make sure the strdup and SPLAY_FIND succeeded, otherwise clean up */
160 if (assoc->nmap_name == NULL || assoc->xp_fprint == NULL) {
161 if (assoc->nmap_name)
162 free (assoc->nmap_name);
163 free (assoc);
164 return (NULL);
165 }
166
167 /* fprintf(stderr, "%s <-> %s\n",p,q); */
168 return (assoc);
169 }
170
171 /**
172 * Loads associations by getting one association at a time, then adding it
173 * to the associations splay tree.
174 *
175 * @param fp the FILE stream pointer
176 * @return -1 on error, 0 on success
177 */
178
179 int
parse_associations(FILE * fp)180 parse_associations(FILE *fp)
181 {
182 assoc_item *assoc = NULL;
183
184 if (fp == NULL) {
185 fprintf(stderr, "Could not open associations file!\n");
186 return (-1);
187 }
188
189 while (!feof(fp)) {
190 assoc = get_assoc(fp);
191 if (assoc != NULL)
192 SPLAY_INSERT(assoc_tree, &associations, assoc);
193 }
194
195 return (0);
196 }
197
198 /**
199 * Takes a personality that is filled with NMAP personality information and
200 * adds the corresponding Xprobe OS (if possible) to the personality by looking
201 * up the NMAP OS name in the associations splay tree.
202 *
203 * @param pers The pre-filled NMAP personality to look up in the association tree
204 * @return 0 if no matching association was found, or 1 if one was
205 */
206
207 int
correlate_nmap_with_xprobe(struct personality * pers)208 correlate_nmap_with_xprobe(struct personality *pers)
209 {
210 struct assoc_item *assoc;
211 struct assoc_item lookup;
212
213 if (pers == NULL)
214 return 0;
215
216 /* Lookup the association */
217 lookup.nmap_name = pers->name;
218 if ((assoc = SPLAY_FIND(assoc_tree, &associations, &lookup)) == NULL)
219 return (0);
220
221 /*
222 * If we have the association, put the xprobe fingerprint in
223 * the personality.
224 */
225 pers->xp_fprint = assoc->xp_fprint;
226
227 return (0);
228 }
229