1 /*
2     This file is part of Kismet
3 
4     Kismet is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     Kismet is distributed in the hope that it will be useful,
10       but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with Kismet; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19 #include "config.h"
20 
21 #include "dumpfile_string.h"
22 
dumpfilestring_chain_hook(CHAINCALL_PARMS)23 int dumpfilestring_chain_hook(CHAINCALL_PARMS) {
24 	Dumpfile_String *auxptr = (Dumpfile_String *) auxdata;
25 	return auxptr->chain_handler(in_pack);
26 }
27 
Dumpfile_String()28 Dumpfile_String::Dumpfile_String() {
29 	fprintf(stderr, "FATAL OOPS: Dumpfile_String called with no globalreg\n");
30 	exit(1);
31 }
32 
Dumpfile_String(GlobalRegistry * in_globalreg)33 Dumpfile_String::Dumpfile_String(GlobalRegistry *in_globalreg) :
34 	Dumpfile(in_globalreg) {
35 
36 	char errstr[STATUS_MAX];
37 	globalreg = in_globalreg;
38 
39 	stringfile = NULL;
40 
41 	type = "string";
42 
43 	if (globalreg->sourcetracker == NULL) {
44 		fprintf(stderr, "FATAL OOPS:  Sourcetracker missing before "
45 				"Dumpfile_String\n");
46 		exit(1);
47 	}
48 
49 	if (globalreg->builtindissector == NULL) {
50 		fprintf(stderr, "FATAL OOPS:  Sourcetracker missing before "
51 				"Dumpfile_String\n");
52 		exit(1);
53 	}
54 
55 	// Find the file name
56 	if ((fname = ProcessConfigOpt("string")) == "" ||
57 		globalreg->fatal_condition) {
58 		return;
59 	}
60 
61 	stringfile = fopen(fname.c_str(), "w");
62 	if (stringfile == NULL) {
63 		snprintf(errstr, STATUS_MAX, "Failed to open string dump file '%s': %s",
64 				 fname.c_str(), strerror(errno));
65 		_MSG(errstr, MSGFLAG_FATAL);
66 		globalreg->fatal_condition = 1;
67 		return;
68 	}
69 
70 	_MSG("Opened string log file '" + fname + "'", MSGFLAG_INFO);
71 
72 	globalreg->packetchain->RegisterHandler(&dumpfilestring_chain_hook, this,
73 											CHAINPOS_LOGGING, -100);
74 
75 	globalreg->RegisterDumpFile(this);
76 
77 	globalreg->builtindissector->SetStringExtract(2);
78 	_MSG("Dumpfile_String - forced string extraction from packets at all times",
79 		 MSGFLAG_INFO);
80 }
81 
~Dumpfile_String()82 Dumpfile_String::~Dumpfile_String() {
83 	globalreg->packetchain->RemoveHandler(&dumpfilestring_chain_hook,
84 										  CHAINPOS_LOGGING);
85 
86 	// Close files
87 	if (stringfile != NULL) {
88 		Flush();
89 		fclose(stringfile);
90 	}
91 
92 	stringfile = NULL;
93 }
94 
Flush()95 int Dumpfile_String::Flush() {
96 	if (stringfile == NULL)
97 		return 0;
98 
99 	fflush(stringfile);
100 
101 	return 1;
102 }
103 
chain_handler(kis_packet * in_pack)104 int Dumpfile_String::chain_handler(kis_packet *in_pack) {
105 	if (stringfile == NULL)
106 		return 0;
107 
108 	kis_string_info *stringinfo = NULL;
109 
110 	if (in_pack->error)
111 		return 0;
112 
113 	// Grab the 80211 info, compare, bail
114     kis_ieee80211_packinfo *packinfo;
115 	if ((packinfo =
116 		 (kis_ieee80211_packinfo *) in_pack->fetch(_PCM(PACK_COMP_80211))) == NULL)
117 		return 0;
118 	if (packinfo->corrupt)
119 		return 0;
120 	if (packinfo->type != packet_data || packinfo->subtype != packet_sub_data)
121 		return 0;
122 
123 	// If it's encrypted and hasn't been decrypted, we can't do anything
124 	// smart with it, so toss.
125 	if (packinfo->cryptset != 0 && packinfo->decrypted == 0)
126 		return 0;
127 	// Grab the strings
128 	stringinfo = (kis_string_info *) in_pack->fetch(_PCM(PACK_COMP_STRINGS));
129 
130 	if (stringinfo == NULL)
131 		return 0;
132 
133 	for (unsigned int x = 0; x < stringinfo->extracted_strings.size(); x++) {
134 		fprintf(stringfile, "%s %s %s %s\n",
135 				packinfo->bssid_mac.Mac2String().c_str(),
136 				packinfo->source_mac.Mac2String().c_str(),
137 				packinfo->dest_mac.Mac2String().c_str(),
138 				stringinfo->extracted_strings[x].c_str());
139 	}
140 
141 	dumped_frames++;
142 
143 	return 1;
144 }
145 
146