Branch data Line data Source code
1 : : // $Id: Portmap.cc 6219 2008-10-01 05:39:07Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include "NetVar.h"
8 : : #include "XDR.h"
9 : : #include "Portmap.h"
10 : : #include "Event.h"
11 : :
12 : : #define PMAPPROC_NULL 0
13 : : #define PMAPPROC_SET 1
14 : : #define PMAPPROC_UNSET 2
15 : : #define PMAPPROC_GETPORT 3
16 : : #define PMAPPROC_DUMP 4
17 : : #define PMAPPROC_CALLIT 5
18 : :
19 : 0 : int PortmapperInterp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n)
20 : : {
21 [ # # ]: 0 : if ( c->Program() != 100000 )
22 : 0 : Weird("bad_RPC_program");
23 : :
24 [ # # # # # : 0 : switch ( c->Proc() ) {
# # ]
25 : : case PMAPPROC_NULL:
26 : 0 : break;
27 : :
28 : : case PMAPPROC_SET:
29 : : {
30 : 0 : Val* m = ExtractMapping(buf, n);
31 [ # # ]: 0 : if ( ! m )
32 : 0 : return 0;
33 : 0 : c->AddVal(m);
34 : : }
35 : 0 : break;
36 : :
37 : : case PMAPPROC_UNSET:
38 : : {
39 : 0 : Val* m = ExtractMapping(buf, n);
40 [ # # ]: 0 : if ( ! m )
41 : 0 : return 0;
42 : 0 : c->AddVal(m);
43 : : }
44 : 0 : break;
45 : :
46 : : case PMAPPROC_GETPORT:
47 : : {
48 : 0 : Val* pr = ExtractPortRequest(buf, n);
49 [ # # ]: 0 : if ( ! pr )
50 : 0 : return 0;
51 : 0 : c->AddVal(pr);
52 : : }
53 : 0 : break;
54 : :
55 : : case PMAPPROC_DUMP:
56 : 0 : break;
57 : :
58 : : case PMAPPROC_CALLIT:
59 : : {
60 : 0 : Val* call_it = ExtractCallItRequest(buf, n);
61 [ # # ]: 0 : if ( ! call_it )
62 : 0 : return 0;
63 : 0 : c->AddVal(call_it);
64 : : }
65 : 0 : break;
66 : :
67 : : default:
68 : 0 : return 0;
69 : : }
70 : :
71 : 0 : return 1;
72 : : }
73 : :
74 : : int PortmapperInterp::RPC_BuildReply(const RPC_CallInfo* c, int success,
75 : : const u_char*& buf, int& n,
76 : 0 : EventHandlerPtr& event, Val*& reply)
77 : : {
78 : 0 : reply = 0;
79 : :
80 [ # # # # # : 0 : switch ( c->Proc() ) {
# # ]
81 : : case PMAPPROC_NULL:
82 [ # # ]: 0 : event = success ? pm_request_null : pm_attempt_null;
83 : 0 : break;
84 : :
85 : : case PMAPPROC_SET:
86 [ # # ]: 0 : if ( success )
87 : : {
88 : 0 : uint32 status = extract_XDR_uint32(buf, n);
89 [ # # ]: 0 : if ( ! buf )
90 : 0 : return 0;
91 : :
92 : 0 : reply = new Val(status, TYPE_BOOL);
93 : 0 : event = pm_request_set;
94 : : }
95 : : else
96 : 0 : event = pm_attempt_set;
97 : :
98 : 0 : break;
99 : :
100 : : case PMAPPROC_UNSET:
101 [ # # ]: 0 : if ( success )
102 : : {
103 : 0 : uint32 status = extract_XDR_uint32(buf, n);
104 [ # # ]: 0 : if ( ! buf )
105 : 0 : return 0;
106 : :
107 : 0 : reply = new Val(status, TYPE_BOOL);
108 : 0 : event = pm_request_unset;
109 : : }
110 : : else
111 : 0 : event = pm_attempt_unset;
112 : :
113 : 0 : break;
114 : :
115 : : case PMAPPROC_GETPORT:
116 [ # # ]: 0 : if ( success )
117 : : {
118 : 0 : uint32 port = extract_XDR_uint32(buf, n);
119 [ # # ]: 0 : if ( ! buf )
120 : 0 : return 0;
121 : :
122 : 0 : RecordVal* rv = c->RequestVal()->AsRecordVal();
123 : 0 : Val* is_tcp = rv->Lookup(2);
124 : : reply = new PortVal(CheckPort(port),
125 : : is_tcp->IsOne() ?
126 [ # # ]: 0 : TRANSPORT_TCP : TRANSPORT_UDP);
127 : 0 : event = pm_request_getport;
128 : : }
129 : : else
130 : 0 : event = pm_attempt_getport;
131 : 0 : break;
132 : :
133 : : case PMAPPROC_DUMP:
134 [ # # ]: 0 : event = success ? pm_request_dump : pm_attempt_dump;
135 [ # # ]: 0 : if ( success )
136 : : {
137 : 0 : TableVal* mappings = new TableVal(pm_mappings);
138 : 0 : uint32 nmap = 0;
139 : :
140 : : // Each call in the loop test pulls the next "opted"
141 : : // element to see if there are more mappings.
142 [ # # ][ # # ]: 0 : while ( extract_XDR_uint32(buf, n) && buf )
[ # # ]
143 : : {
144 : 0 : Val* m = ExtractMapping(buf, n);
145 [ # # ]: 0 : if ( ! m )
146 : 0 : break;
147 : :
148 : 0 : Val* index = new Val(++nmap, TYPE_COUNT);
149 : 0 : mappings->Assign(index, m);
150 : 0 : Unref(index);
151 : : }
152 : :
153 [ # # ]: 0 : if ( ! buf )
154 : : {
155 : 0 : Unref(mappings);
156 : 0 : return 0;
157 : : }
158 : :
159 : 0 : reply = mappings;
160 : 0 : event = pm_request_dump;
161 : : }
162 : : else
163 : 0 : event = pm_attempt_dump;
164 : 0 : break;
165 : :
166 : : case PMAPPROC_CALLIT:
167 [ # # ]: 0 : if ( success )
168 : : {
169 : 0 : uint32 port = extract_XDR_uint32(buf, n);
170 : : int reply_n;
171 : : const u_char* opaque_reply =
172 : 0 : extract_XDR_opaque(buf, n, reply_n);
173 [ # # ]: 0 : if ( ! opaque_reply )
174 : 0 : return 0;
175 : :
176 : 0 : reply = new PortVal(CheckPort(port), TRANSPORT_UDP);
177 : 0 : event = pm_request_callit;
178 : : }
179 : : else
180 : 0 : event = pm_attempt_callit;
181 : 0 : break;
182 : :
183 : : default:
184 : 0 : return 0;
185 : : }
186 : :
187 : 0 : return 1;
188 : : }
189 : :
190 : 0 : Val* PortmapperInterp::ExtractMapping(const u_char*& buf, int& len)
191 : : {
192 : 0 : RecordVal* mapping = new RecordVal(pm_mapping);
193 : :
194 : 0 : mapping->Assign(0, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
195 : 0 : mapping->Assign(1, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
196 : :
197 : 0 : int is_tcp = extract_XDR_uint32(buf, len) == IPPROTO_TCP;
198 : 0 : uint32 port = extract_XDR_uint32(buf, len);
199 : : mapping->Assign(2, new PortVal(CheckPort(port),
200 [ # # ]: 0 : is_tcp ? TRANSPORT_TCP : TRANSPORT_UDP));
201 : :
202 [ # # ]: 0 : if ( ! buf )
203 : : {
204 : 0 : Unref(mapping);
205 : 0 : return 0;
206 : : }
207 : :
208 : 0 : return mapping;
209 : : }
210 : :
211 : 0 : Val* PortmapperInterp::ExtractPortRequest(const u_char*& buf, int& len)
212 : : {
213 : 0 : RecordVal* pr = new RecordVal(pm_port_request);
214 : :
215 : 0 : pr->Assign(0, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
216 : 0 : pr->Assign(1, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
217 : :
218 : 0 : int is_tcp = extract_XDR_uint32(buf, len) == IPPROTO_TCP;
219 : 0 : pr->Assign(2, new Val(is_tcp, TYPE_BOOL));
220 : 0 : (void) extract_XDR_uint32(buf, len); // consume the bogus port
221 : :
222 [ # # ]: 0 : if ( ! buf )
223 : : {
224 : 0 : Unref(pr);
225 : 0 : return 0;
226 : : }
227 : :
228 : 0 : return pr;
229 : : }
230 : :
231 : 0 : Val* PortmapperInterp::ExtractCallItRequest(const u_char*& buf, int& len)
232 : : {
233 : 0 : RecordVal* c = new RecordVal(pm_callit_request);
234 : :
235 : 0 : c->Assign(0, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
236 : 0 : c->Assign(1, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
237 : 0 : c->Assign(2, new Val(extract_XDR_uint32(buf, len), TYPE_COUNT));
238 : :
239 : : int arg_n;
240 : 0 : (void) extract_XDR_opaque(buf, len, arg_n);
241 : 0 : c->Assign(3, new Val(arg_n, TYPE_COUNT));
242 : :
243 [ # # ]: 0 : if ( ! buf )
244 : : {
245 : 0 : Unref(c);
246 : 0 : return 0;
247 : : }
248 : :
249 : 0 : return c;
250 : : }
251 : :
252 : 0 : uint32 PortmapperInterp::CheckPort(uint32 port)
253 : : {
254 [ # # ]: 0 : if ( port >= 65536 )
255 : : {
256 [ # # ]: 0 : if ( pm_bad_port )
257 : : {
258 : 0 : val_list* vl = new val_list;
259 : 0 : vl->append(analyzer->BuildConnVal());
260 : 0 : vl->append(new Val(port, TYPE_COUNT));
261 : 0 : analyzer->ConnectionEvent(pm_bad_port, vl);
262 : : }
263 : :
264 : 0 : port = 0;
265 : : }
266 : :
267 : 0 : return port;
268 : : }
269 : :
270 : 0 : void PortmapperInterp::Event(EventHandlerPtr f, Val* request, int status, Val* reply)
271 : : {
272 [ # # ]: 0 : if ( ! f )
273 : : {
274 : 0 : Unref(request);
275 : 0 : Unref(reply);
276 : 0 : return;
277 : : }
278 : :
279 : 0 : val_list* vl = new val_list;
280 : :
281 : 0 : vl->append(analyzer->BuildConnVal());
282 [ # # ]: 0 : if ( status == RPC_SUCCESS )
283 : : {
284 [ # # ]: 0 : if ( request )
285 : 0 : vl->append(request);
286 [ # # ]: 0 : if ( reply )
287 : 0 : vl->append(reply);
288 : : }
289 : : else
290 : : {
291 : 0 : vl->append(new EnumVal(status, enum_rpc_status));
292 [ # # ]: 0 : if ( request )
293 : 0 : vl->append(request);
294 : : }
295 : :
296 : 0 : analyzer->ConnectionEvent(f, vl);
297 : : }
298 : :
299 : 0 : Portmapper_Analyzer::Portmapper_Analyzer(Connection* conn)
300 : 0 : : RPC_Analyzer(AnalyzerTag::Portmapper, conn, new PortmapperInterp(this))
301 : : {
302 : 0 : orig_rpc = resp_rpc = 0;
303 : 0 : }
304 : :
305 : 0 : Portmapper_Analyzer::~Portmapper_Analyzer()
306 : : {
307 [ # # ][ # # ]: 0 : }
[ # # ]
308 : :
309 : 0 : void Portmapper_Analyzer::Init()
310 : : {
311 : 0 : RPC_Analyzer::Init();
312 : :
313 [ # # ]: 0 : if ( Conn()->ConnTransport() == TRANSPORT_TCP )
314 : : {
315 : 0 : orig_rpc = new Contents_RPC(Conn(), true, interp);
316 : 0 : resp_rpc = new Contents_RPC(Conn(), false, interp);
317 : 0 : AddSupportAnalyzer(orig_rpc);
318 : 0 : AddSupportAnalyzer(resp_rpc);
319 : : }
320 [ + - ][ + - ]: 6 : }
|