From Thomas Anders fix some memory leaks
[obnox/wireshark/wip.git] / packet-http.c
1 /* packet-http.c
2  * Routines for HTTP packet disassembly
3  *
4  * Guy Harris <guy@alum.mit.edu>
5  *
6  * Copyright 2004, Jerry Talkington <jtalkington@users.sourceforge.net>
7  * Copyright 2002, Tim Potter <tpot@samba.org>
8  * Copyright 1999, Andrew Tridgell <tridge@samba.org>
9  *
10  * $Id: packet-http.c,v 1.109 2004/05/10 22:20:24 obiot Exp $
11  *
12  * Ethereal - Network traffic analyzer
13  * By Gerald Combs <gerald@ethereal.com>
14  * Copyright 1998 Gerald Combs
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <string.h>
36 #include <ctype.h>
37
38 #include <glib.h>
39 #include <epan/packet.h>
40 #include <epan/strutil.h>
41
42 #include "util.h"
43 #include "req_resp_hdrs.h"
44 #include "packet-http.h"
45 #include "prefs.h"
46
47 typedef enum _http_type {
48         HTTP_REQUEST,
49         HTTP_RESPONSE,
50         HTTP_NOTIFICATION,
51         HTTP_OTHERS
52 } http_type_t;
53
54 #include "tap.h"
55
56 static int http_tap = -1;
57
58 static int proto_http = -1;
59 static int hf_http_notification = -1;
60 static int hf_http_response = -1;
61 static int hf_http_request = -1;
62 static int hf_http_basic = -1;
63 static int hf_http_request_method = -1;
64 static int hf_http_response_code = -1;
65 static int hf_http_authorization = -1;
66 static int hf_http_proxy_authenticate = -1;
67 static int hf_http_proxy_authorization = -1;
68 static int hf_http_www_authenticate = -1;
69 static int hf_http_content_type = -1;
70 static int hf_http_content_length = -1;
71 static int hf_http_content_encoding = -1;
72 static int hf_http_transfer_encoding = -1;
73
74 static gint ett_http = -1;
75 static gint ett_http_ntlmssp = -1;
76 static gint ett_http_request = -1;
77 static gint ett_http_chunked_response = -1;
78 static gint ett_http_chunk_data = -1;
79 static gint ett_http_encoded_entity = -1;
80
81 static dissector_handle_t data_handle;
82 static dissector_handle_t media_handle;
83 static dissector_handle_t http_handle;
84
85 /*
86  * desegmentation of HTTP headers
87  * (when we are over TCP or another protocol providing the desegmentation API)
88  */
89 static gboolean http_desegment_headers = FALSE;
90
91 /*
92  * desegmentation of HTTP bodies
93  * (when we are over TCP or another protocol providing the desegmentation API)
94  * TODO let the user filter on content-type the bodies he wants desegmented
95  */
96 static gboolean http_desegment_body = FALSE;
97
98 /*
99  * De-chunking of content-encoding: chunk entity bodies.
100  */
101 static gboolean http_dechunk_body = TRUE;
102
103 /*
104  * Decompression of zlib encoded entities.
105  */
106 #ifdef HAVE_LIBZ
107 static gboolean http_decompress_body = TRUE;
108 #else
109 static gboolean http_decompress_body = FALSE;
110 #endif
111
112
113 #define TCP_PORT_HTTP                   80
114 #define TCP_PORT_PROXY_HTTP             3128
115 #define TCP_PORT_PROXY_ADMIN_HTTP       3132
116 #define TCP_ALT_PORT_HTTP               8080
117
118 /*
119  * SSDP is implemented atop HTTP (yes, it really *does* run over UDP).
120  */
121 #define TCP_PORT_SSDP                   1900
122 #define UDP_PORT_SSDP                   1900
123
124 /*
125  * Protocols implemented atop HTTP.
126  */
127 typedef enum {
128         PROTO_HTTP,             /* just HTTP */
129         PROTO_SSDP              /* Simple Service Discovery Protocol */
130 } http_proto_t;
131
132 typedef void (*RequestDissector)(tvbuff_t*, proto_tree*, int);
133
134 /*
135  * Structure holding information from headers needed by main
136  * HTTP dissector code.
137  */
138 typedef struct {
139         char    *content_type;
140         char    *content_type_parameters;
141         long    content_length; /* XXX - make it 64-bit? */
142         char    *content_encoding;
143         char    *transfer_encoding;
144 } headers_t;
145
146 static int is_http_request_or_reply(const gchar *data, int linelen, http_type_t *type,
147                 RequestDissector *req_dissector, int *req_strlen);
148 static int chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
149                 proto_tree *tree, int offset);
150 static void process_header(tvbuff_t *tvb, int offset, int next_offset,
151     const guchar *line, int linelen, int colon_offset, packet_info *pinfo,
152     proto_tree *tree, headers_t *eh_ptr);
153 static gint find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len);
154 static gboolean check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb,
155     packet_info *pinfo, gchar *value);
156 static gboolean check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb,
157     gchar *value);
158
159 static dissector_table_t port_subdissector_table;
160 static dissector_table_t media_type_subdissector_table;
161 static heur_dissector_list_t heur_subdissector_list;
162
163 static dissector_handle_t ntlmssp_handle=NULL;
164
165
166 /* Return a tvb that contains the binary representation of a base64
167    string */
168
169 static tvbuff_t *
170 base64_to_tvb(const char *base64)
171 {
172         tvbuff_t *tvb;
173         char *data = g_strdup(base64);
174         size_t len;
175
176         len = epan_base64_decode(data);
177         tvb = tvb_new_real_data((const guint8 *)data, len, len);
178
179         tvb_set_free_cb(tvb, g_free);
180
181         return tvb;
182 }
183
184 static void
185 dissect_http_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
186     const char *line)
187 {
188         tvbuff_t *ntlmssp_tvb;
189
190         ntlmssp_tvb = base64_to_tvb(line);
191         tvb_set_child_real_data_tvbuff(tvb, ntlmssp_tvb);
192         add_new_data_source(pinfo, ntlmssp_tvb, "NTLMSSP Data");
193
194         call_dissector(ntlmssp_handle, ntlmssp_tvb, pinfo, tree);
195 }
196
197 static void
198 cleanup_headers(void *arg)
199 {
200         headers_t *headers = arg;
201
202         if (headers->content_type != NULL)
203                 g_free(headers->content_type);
204         /*
205          * The content_type_parameters field actually points into the
206          * content_type headers, so don't free it, as that'll double-free
207          * some memory.
208          */
209         if (headers->content_encoding != NULL)
210                 g_free(headers->content_encoding);
211         if (headers->transfer_encoding != NULL)
212                 g_free(headers->transfer_encoding);
213 }
214
215 /*
216  * TODO: remove this ugly global variable.
217  *
218  * XXX - we leak "http_info_value_t" structures.
219  * XXX - this gets overwritten if there's more than one HTTP request or
220  * reply in the tvbuff.
221  */
222 static http_info_value_t        *stat_info;
223
224 static int
225 dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
226     proto_tree *tree)
227 {
228         http_proto_t    proto;
229         char            *proto_tag;
230         proto_tree      *http_tree = NULL;
231         proto_item      *ti = NULL;
232         const guchar    *line;
233         gint            next_offset;
234         const guchar    *linep, *lineend;
235         int             orig_offset;
236         int             first_linelen, linelen;
237         gboolean        is_request_or_reply;
238         gboolean        saw_req_resp_or_header;
239         guchar          c;
240         http_type_t     http_type;
241         proto_item      *hdr_item;
242         RequestDissector req_dissector;
243         int             req_strlen;
244         proto_tree      *req_tree;
245         int             colon_offset;
246         headers_t       headers;
247         int             datalen;
248         int             reported_datalen;
249         dissector_handle_t handle;
250         gboolean        dissected;
251
252         /*
253          * Is this a request or response?
254          *
255          * Note that "tvb_find_line_end()" will return a value that
256          * is not longer than what's in the buffer, so the
257          * "tvb_get_ptr()" call won't throw an exception.
258          */
259         first_linelen = tvb_find_line_end(tvb, offset,
260             tvb_ensure_length_remaining(tvb, offset), &next_offset,
261             FALSE);
262         /*
263          * Is the first line a request or response?
264          */
265         line = tvb_get_ptr(tvb, offset, first_linelen);
266         http_type = HTTP_OTHERS;        /* type not known yet */
267         is_request_or_reply = is_http_request_or_reply((const gchar *)line,
268                         first_linelen, &http_type, NULL, NULL);
269         if (is_request_or_reply) {
270                 /*
271                  * Yes, it's a request or response.
272                  * Do header desegmentation if we've been told to,
273                  * and do body desegmentation if we've been told to and
274                  * we find a Content-Length header.
275                  */
276                 if (!req_resp_hdrs_do_reassembly(tvb, pinfo,
277                     http_desegment_headers, http_desegment_body)) {
278                         /*
279                          * More data needed for desegmentation.
280                          */
281                         return -1;
282                 }
283         }
284
285         stat_info = g_malloc(sizeof(http_info_value_t));
286         stat_info->response_code = 0;
287         stat_info->request_method = NULL;
288
289         switch (pinfo->match_port) {
290
291         case TCP_PORT_SSDP:     /* TCP_PORT_SSDP = UDP_PORT_SSDP */
292                 proto = PROTO_SSDP;
293                 proto_tag = "SSDP";
294                 break;
295
296         default:
297                 proto = PROTO_HTTP;
298                 proto_tag = "HTTP";
299                 break;
300         }
301
302         if (check_col(pinfo->cinfo, COL_PROTOCOL))
303                 col_set_str(pinfo->cinfo, COL_PROTOCOL, proto_tag);
304         if (check_col(pinfo->cinfo, COL_INFO)) {
305                 /*
306                  * Put the first line from the buffer into the summary
307                  * if it's an HTTP request or reply (but leave out the
308                  * line terminator).
309                  * Otherwise, just call it a continuation.
310                  *
311                  * Note that "tvb_find_line_end()" will return a value that
312                  * is not longer than what's in the buffer, so the
313                  * "tvb_get_ptr()" call won't throw an exception.
314                  */
315                 line = tvb_get_ptr(tvb, offset, first_linelen);
316                 if (is_request_or_reply)
317                         col_add_str(pinfo->cinfo, COL_INFO,
318                             format_text(line, first_linelen));
319                 else
320                         col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
321         }
322
323         orig_offset = offset;
324         if (tree) {
325                 ti = proto_tree_add_item(tree, proto_http, tvb, offset, -1,
326                     FALSE);
327                 http_tree = proto_item_add_subtree(ti, ett_http);
328         }
329
330         /*
331          * Process the packet data, a line at a time.
332          */
333         http_type = HTTP_OTHERS;        /* type not known yet */
334         headers.content_type = NULL;    /* content type not known yet */
335         headers.content_type_parameters = NULL; /* content type parameters too */
336         headers.content_length = -1;    /* content length not known yet */
337         headers.content_encoding = NULL; /* content encoding not known yet */
338         headers.transfer_encoding = NULL; /* transfer encoding not known yet */
339         saw_req_resp_or_header = FALSE; /* haven't seen anything yet */
340         CLEANUP_PUSH(cleanup_headers, &headers);
341         while (tvb_reported_length_remaining(tvb, offset) != 0) {
342                 /*
343                  * Find the end of the line.
344                  */
345                 linelen = tvb_find_line_end(tvb, offset,
346                     tvb_ensure_length_remaining(tvb, offset), &next_offset,
347                     FALSE);
348                 if (linelen < 0)
349                         return -1;
350
351                 /*
352                  * Get a buffer that refers to the line.
353                  */
354                 line = tvb_get_ptr(tvb, offset, linelen);
355                 lineend = line + linelen;
356                 colon_offset = -1;
357
358                 /*
359                  * OK, does it look like an HTTP request or response?
360                  */
361                 req_dissector = NULL;
362                 is_request_or_reply = is_http_request_or_reply((const gchar *)line,
363                                 linelen, &http_type, &req_dissector, &req_strlen);
364                 if (is_request_or_reply)
365                         goto is_http;
366
367                 /*
368                  * No.  Does it look like a blank line (as would appear
369                  * at the end of an HTTP request)?
370                  */
371                 if (linelen == 0)
372                         goto is_http;   /* Yes. */
373
374                 /*
375                  * No.  Does it look like a header?
376                  */
377                 linep = line;
378                 colon_offset = offset;
379                 while (linep < lineend) {
380                         c = *linep++;
381
382                         /*
383                          * This must be a CHAR to be part of a token; that
384                          * means it must be ASCII.
385                          */
386                         if (!isascii(c))
387                                 break;  /* not ASCII, thus not a CHAR */
388
389                         /*
390                          * This mustn't be a CTL to be part of a token;
391                          * that means it must be printable.
392                          *
393                          * XXX - what about leading LWS on continuation
394                          * lines of a header?
395                          */
396                         if (!isprint(c))
397                                 break;  /* not printable, not a header */
398
399                         /*
400                          * This mustn't be a SEP to be part of a token;
401                          * a ':' ends the token, everything else is an
402                          * indication that this isn't a header.
403                          */
404                         switch (c) {
405
406                         case '(':
407                         case ')':
408                         case '<':
409                         case '>':
410                         case '@':
411                         case ',':
412                         case ';':
413                         case '\\':
414                         case '"':
415                         case '/':
416                         case '[':
417                         case ']':
418                         case '?':
419                         case '=':
420                         case '{':
421                         case '}':
422                         case ' ':
423                                 /*
424                                  * It's a separator, so it's not part of a
425                                  * token, so it's not a field name for the
426                                  * beginning of a header.
427                                  *
428                                  * (We don't have to check for HT; that's
429                                  * already been ruled out by "isprint()".)
430                                  */
431                                 goto not_http;
432
433                         case ':':
434                                 /*
435                                  * This ends the token; we consider this
436                                  * to be a header.
437                                  */
438                                 goto is_http;
439
440                         default:
441                                 colon_offset++;
442                                 break;
443                         }
444                 }
445
446                 /*
447                  * We haven't seen the colon, but everything else looks
448                  * OK for a header line.
449                  *
450                  * If we've already seen an HTTP request or response
451                  * line, or a header line, and we're at the end of
452                  * the tvbuff, we assume this is an incomplete header
453                  * line.  (We quit this loop after seeing a blank line,
454                  * so if we've seen a request or response line, or a
455                  * header line, this is probably more of the request
456                  * or response we're presumably seeing.  There is some
457                  * risk of false positives, but the same applies for
458                  * full request or response lines or header lines,
459                  * although that's less likely.)
460                  *
461                  * We throw an exception in that case, by checking for
462                  * the existence of the next byte after the last one
463                  * in the line.  If it exists, "tvb_ensure_bytes_exist()"
464                  * throws no exception, and we fall through to the
465                  * "not HTTP" case.  If it doesn't exist,
466                  * "tvb_ensure_bytes_exist()" will throw the appropriate
467                  * exception.
468                  */
469                 if (saw_req_resp_or_header)
470                         tvb_ensure_bytes_exist(tvb, offset, linelen + 1);
471
472         not_http:
473                 /*
474                  * We don't consider this part of an HTTP request or
475                  * reply, so we don't display it.
476                  * (Yeah, that means we don't display, say, a text/http
477                  * page, but you can get that from the data pane.)
478                  */
479                 break;
480
481         is_http:
482                 /*
483                  * Process this line.
484                  */
485                 if (linelen == 0) {
486                         /*
487                          * This is a blank line, which means that
488                          * whatever follows it isn't part of this
489                          * request or reply.
490                          */
491                         proto_tree_add_text(http_tree, tvb, offset,
492                             next_offset - offset, "%s",
493                             tvb_format_text(tvb, offset, next_offset - offset));
494                         offset = next_offset;
495                         break;
496                 }
497
498                 /*
499                  * Not a blank line - either a request, a reply, or a header
500                  * line.
501                  */
502                 saw_req_resp_or_header = TRUE;
503                 if (is_request_or_reply) {
504                         if (tree) {
505                                 hdr_item = proto_tree_add_text(http_tree, tvb,
506                                     offset, next_offset - offset, "%s",
507                                     tvb_format_text(tvb, offset,
508                                       next_offset - offset));
509                                 if (req_dissector) {
510                                         req_tree = proto_item_add_subtree(
511                                             hdr_item, ett_http_request);
512                                         req_dissector(tvb, req_tree,
513                                             req_strlen);
514                                 }
515                         }
516                 } else {
517                         /*
518                          * Header.
519                          */
520                         process_header(tvb, offset, next_offset, line, linelen,
521                             colon_offset, pinfo, http_tree, &headers);
522                 }
523                 offset = next_offset;
524         }
525
526         if (tree) {
527                 switch (http_type) {
528
529                 case HTTP_NOTIFICATION:
530                         proto_tree_add_boolean_hidden(http_tree,
531                             hf_http_notification, tvb, 0, 0, 1);
532                         break;
533
534                 case HTTP_RESPONSE:
535                         proto_tree_add_boolean_hidden(http_tree,
536                             hf_http_response, tvb, 0, 0, 1);
537                         break;
538
539                 case HTTP_REQUEST:
540                         proto_tree_add_boolean_hidden(http_tree,
541                             hf_http_request, tvb, 0, 0, 1);
542                         break;
543
544                 case HTTP_OTHERS:
545                 default:
546                         break;
547                 }
548         }
549
550         /*
551          * If a content length was supplied, the amount of data to be
552          * processed as HTTP payload is the minimum of the content
553          * length and the amount of data remaining in the frame.
554          *
555          * If no content length was supplied (or if a bad content length
556          * was supplied), the amount of data to be processed is the amount
557          * of data remaining in the frame.
558          *
559          * If there was no Content-Length entity header, we should
560          * accumulate all data until the end of the connection.
561          * That'd require that the TCP dissector call subdissectors
562          * for all frames with FIN, even if they contain no data,
563          * which would require subdissectors to deal intelligently
564          * with empty segments.
565          *
566          * Acccording to RFC 2616, however, 1xx responses, 204 responses,
567          * and 304 responses MUST NOT include a message body; if no
568          * content length is specified for them, we don't attempt to
569          * dissect the body.
570          *
571          * XXX - it says the same about responses to HEAD requests;
572          * unless there's a way to determine from the response
573          * whether it's a response to a HEAD request, we have to
574          * keep information about the request and associate that with
575          * the response in order to handle that.
576          */
577         datalen = tvb_length_remaining(tvb, offset);
578         if (headers.content_length != -1) {
579                 if (datalen > headers.content_length)
580                         datalen = headers.content_length;
581
582                 /*
583                  * XXX - limit the reported length in the tvbuff we'll
584                  * hand to a subdissector to be no greater than the
585                  * content length.
586                  *
587                  * We really need both unreassembled and "how long it'd
588                  * be if it were reassembled" lengths for tvbuffs, so
589                  * that we throw the appropriate exceptions for
590                  * "not enough data captured" (running past the length),
591                  * "packet needed reassembly" (within the length but
592                  * running past the unreassembled length), and
593                  * "packet is malformed" (running past the reassembled
594                  * length).
595                  */
596                 reported_datalen = tvb_reported_length_remaining(tvb, offset);
597                 if (reported_datalen > headers.content_length)
598                         reported_datalen = headers.content_length;
599         } else {
600                 if ((stat_info->response_code/100) == 1 ||
601                     stat_info->response_code == 204 ||
602                     stat_info->response_code == 304)
603                         datalen = 0;    /* no content! */
604                 else
605                         reported_datalen = -1;
606         }
607
608         if (datalen > 0) {
609                 /*
610                  * There's stuff left over; process it.
611                  */
612                 tvbuff_t *next_tvb;
613                 void *save_private_data = NULL;
614                 gint chunks_decoded = 0;
615
616                 /*
617                  * Create a tvbuff for the payload.
618                  *
619                  * The amount of data to be processed that's
620                  * available in the tvbuff is "datalen", which
621                  * is the minimum of the amount of data left in
622                  * the tvbuff and any specified content length.
623                  *
624                  * The amount of data to be processed that's in
625                  * this frame, regardless of whether it was
626                  * captured or not, is "reported_datalen",
627                  * which, if no content length was specified,
628                  * is -1, i.e. "to the end of the frame.
629                  */
630                 next_tvb = tvb_new_subset(tvb, offset, datalen,
631                     reported_datalen);
632                 /*
633                  * BEWARE - next_tvb is a subset of another tvb,
634                  * so we MUST NOT attempt tvb_free(next_tvb);
635                  */
636
637                 /*
638                  * Handle *transfer* encodings other than "identity".
639                  */
640                 if (headers.transfer_encoding != NULL &&
641                     strcasecmp(headers.transfer_encoding, "identity") != 0) {
642                         if (http_dechunk_body &&
643                             (strcasecmp(headers.transfer_encoding, "chunked")
644                             == 0)) {
645
646                                 chunks_decoded = chunked_encoding_dissector(
647                                     &next_tvb, pinfo, http_tree, 0);
648
649                                 if (chunks_decoded <= 0) {
650                                         /*
651                                          * The chunks weren't reassembled,
652                                          * or there was a single zero
653                                          * length chunk.
654                                          */
655                                         goto body_dissected;
656                                 } else {
657                                         /*
658                                          * Add a new data source for the
659                                          * de-chunked data.
660                                          */
661                                         tvb_set_child_real_data_tvbuff(tvb,
662                                                 next_tvb);
663                                         add_new_data_source(pinfo, next_tvb,
664                                                 "De-chunked entity body");
665                                 }
666                         } else {
667                                 /*
668                                  * We currently can't handle, for example,
669                                  * "gzip", "compress", or "deflate" as
670                                  * *transfer* encodings; just handle them
671                                  * as data for now.
672                                  */
673                                 call_dissector(data_handle, next_tvb, pinfo,
674                                     http_tree);
675                                 goto body_dissected;
676                         }
677                 }
678                 /*
679                  * At this point, any chunked *transfer* coding has been removed
680                  * (the entity body has been dechunked) so it can be presented
681                  * for the following operation (*content* encoding), or it has
682                  * been been handed off to the data dissector.
683                  *
684                  * Handle *content* encodings other than "identity" (which
685                  * shouldn't appear in a Content-Encoding header, but
686                  * we handle it in any case).
687                  */
688                 if (headers.content_encoding != NULL &&
689                     strcasecmp(headers.content_encoding, "identity") != 0) {
690                         /*
691                          * We currently can't handle, for example, "compress";
692                          * just handle them as data for now.
693                          *
694                          * After July 7, 2004 the LZW patent expires, so support
695                          * might be added then.  However, I don't think that
696                          * anybody ever really implemented "compress", due to
697                          * the aforementioned patent.
698                          */
699                         tvbuff_t *uncomp_tvb = NULL;
700                         proto_item *e_ti = NULL;
701                         proto_tree *e_tree = NULL;
702
703                         if (http_decompress_body &&
704                             (strcasecmp(headers.content_encoding, "gzip") == 0 ||
705                             strcasecmp(headers.content_encoding, "deflate")
706                             == 0)) {
707
708                                 uncomp_tvb = tvb_uncompress(next_tvb, 0,
709                                     tvb_length(next_tvb));
710                         }
711
712                         /*
713                          * Add the encoded entity to the protocol tree
714                          */
715                         e_ti = proto_tree_add_text(http_tree, next_tvb,
716                                         0, tvb_length(next_tvb),
717                                         "Content-encoded entity body (%s)",
718                                         headers.content_encoding);
719                         e_tree = proto_item_add_subtree(e_ti,
720                                         ett_http_encoded_entity);
721
722                         if (uncomp_tvb != NULL) {
723                                 /*
724                                  * Decompression worked
725                                  */
726
727                                 /* XXX - Don't free this, since it's possible
728                                  * that the data was only partially
729                                  * decompressed, such as when desegmentation
730                                  * isn't enabled.
731                                  *
732                                 tvb_free(next_tvb);
733                                 */
734                                 next_tvb = uncomp_tvb;
735                                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
736                                 add_new_data_source(pinfo, next_tvb,
737                                     "Uncompressed entity body");
738                         } else {
739                                 if (chunks_decoded > 1) {
740                                         tvb_set_child_real_data_tvbuff(tvb,
741                                             next_tvb);
742                                         add_new_data_source(pinfo, next_tvb,
743                                             "Compressed entity body");
744                                 }
745                                 call_dissector(data_handle, next_tvb, pinfo,
746                                     e_tree);
747
748                                 goto body_dissected;
749                         }
750                 }
751                 /*
752                  * Note that a new data source is added for the entity body
753                  * only if it was content-encoded and/or transfer-encoded.
754                  */
755
756                 /*
757                  * Do subdissector checks.
758                  *
759                  * First, check whether some subdissector asked that they
760                  * be called if something was on some particular port.
761                  */
762                 handle = dissector_get_port_handle(port_subdissector_table,
763                     pinfo->match_port);
764                 if (handle == NULL && headers.content_type != NULL) {
765                         /*
766                          * We didn't find any subdissector that
767                          * registered for the port, and we have a
768                          * Content-Type value.  Is there any subdissector
769                          * for that content type?
770                          */
771                         save_private_data = pinfo->private_data;
772                         /*
773                          * XXX - this won't get freed if the subdissector
774                          * throws an exception.  Do we really need to
775                          * strdup it?
776                          */
777                         if (headers.content_type_parameters)
778                                 pinfo->private_data = g_strdup(headers.content_type_parameters);
779                         else
780                                 pinfo->private_data = NULL;
781                         /*
782                          * Calling the string handle for the media type
783                          * dissector table will set pinfo->match_string
784                          * to headers.content_type for us.
785                          */
786                         pinfo->match_string = headers.content_type;
787                         handle = dissector_get_string_handle(
788                             media_type_subdissector_table,
789                             headers.content_type);
790                         /*
791                          * Calling the default media handle otherwise
792                          */
793                         if (handle == NULL) {
794                             handle = media_handle;
795                         }
796                 }
797                 if (handle != NULL) {
798                         /*
799                          * We have a subdissector - call it.
800                          */
801                         dissected = call_dissector(handle, next_tvb, pinfo,
802                             tree);
803                 } else {
804                         /*
805                          * We don't have a subdissector - try the heuristic
806                          * subdissectors.
807                          */
808                         dissected = dissector_try_heuristic(
809                             heur_subdissector_list, next_tvb, pinfo, tree);
810                 }
811                 if (dissected) {
812                         /*
813                          * The subdissector dissected the body.
814                          * Fix up the top-level item so that it doesn't
815                          * include the stuff for that protocol.
816                          */
817                         if (ti != NULL)
818                                 proto_item_set_len(ti, offset);
819                 } else {
820                         call_dissector(data_handle, next_tvb, pinfo,
821                             http_tree);
822                 }
823
824         body_dissected:
825                 /*
826                  * Do *not* attempt at freeing the private data;
827                  * it may be in use by subdissectors.
828                  */
829                 if (save_private_data)
830                         pinfo->private_data = save_private_data;
831                 /*
832                  * We've processed "datalen" bytes worth of data
833                  * (which may be no data at all); advance the
834                  * offset past whatever data we've processed.
835                  */
836                 offset += datalen;
837         }
838
839         /*
840          * Clean up any header stuff, by calling and popping the cleanup
841          * handler.
842          */
843         CLEANUP_CALL_AND_POP;
844
845         tap_queue_packet(http_tap, pinfo, stat_info);
846
847         return offset - orig_offset;
848 }
849
850 /* This can be used to dissect an HTTP request until such time
851  * that a more complete dissector is written for that HTTP request.
852  * This simple dissectory only puts http.request_method into a sub-tree.
853  */
854 static void
855 basic_request_dissector(tvbuff_t *tvb, proto_tree *tree, int req_strlen)
856 {
857         proto_tree_add_item(tree, hf_http_request_method, tvb, 0, req_strlen, FALSE);
858 }
859
860 static void
861 basic_response_dissector(tvbuff_t *tvb, proto_tree *tree, int resp_strlen)
862 {
863         gchar *data;
864         int minor, major, status_code;
865
866         /* BEWARE - sscanf() only operates on C strings.
867          * The pointer returned by tvb_get_ptr points into the real data,
868          * which is not necessarily NULL terminated. For this reason,
869          * the sscanf() call is only applied to a buffer guaranteed to
870          * only contain a NULL terminated string. */
871         data = g_strndup((const gchar *)tvb_get_ptr(tvb, 5, resp_strlen), resp_strlen);
872         if (sscanf((const gchar *)data, "%d.%d %d", &minor, &major, &status_code) == 3) {
873                 proto_tree_add_uint(tree, hf_http_response_code, tvb, 9, 3, status_code);
874                 stat_info->response_code = status_code;
875         }
876         g_free(data);
877 }
878
879 /*
880  * Dissect the http data chunks and add them to the tree.
881  */
882 static int
883 chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
884     proto_tree *tree, int offset)
885 {
886         guint8 *chunk_string = NULL;
887         gint chunk_size = 0;
888         gint chunk_offset = 0;
889         gint datalen = 0;
890         gint linelen = 0;
891         gint chunks_decoded = 0;
892         tvbuff_t *tvb = NULL;
893         tvbuff_t *new_tvb = NULL;
894         gint chunked_data_size = 0;
895         proto_tree *subtree = NULL;
896         proto_item *ti = NULL;
897
898         if (tvb_ptr == NULL || *tvb_ptr == NULL) {
899                 return 0;
900         }
901
902         tvb = *tvb_ptr;
903
904         datalen = tvb_reported_length_remaining(tvb, offset);
905
906         if (tree) {
907                 ti = proto_tree_add_text(tree, tvb, offset, datalen,
908                     "HTTP chunked response");
909                 subtree = proto_item_add_subtree(ti, ett_http_chunked_response);
910         }
911
912
913         while (datalen != 0) {
914                 proto_item *chunk_ti = NULL;
915                 proto_tree *chunk_subtree = NULL;
916                 tvbuff_t *data_tvb = NULL;
917                 gchar *c = NULL;
918
919                 linelen = tvb_find_line_end(tvb, offset, -1, &chunk_offset, TRUE);
920
921                 if (linelen <= 0) {
922                         /* Can't get the chunk size line */
923                         break;
924                 }
925
926                 chunk_string = tvb_get_string(tvb, offset, linelen);
927
928                 if (chunk_string == NULL) {
929                         /* Can't get the chunk size line */
930                         break;
931                 }
932
933                 c = chunk_string;
934
935                 /*
936                  * We don't care about the extensions.
937                  */
938                 if ((c = strchr(c, ';'))) {
939                         *c = '\0';
940                 }
941
942                 if (sscanf(chunk_string, "%x", &chunk_size) != 1) {
943                         g_free(chunk_string);
944                         break;
945                 }
946
947                 g_free(chunk_string);
948
949
950                 if (chunk_size > datalen) {
951                         /*
952                          * The chunk size is more than what's in the tvbuff,
953                          * so either the user hasn't enabled decoding, or all
954                          * of the segments weren't captured.
955                          */
956                         chunk_size = datalen;
957                 }/* else if (new_tvb == NULL) {
958                         new_tvb = tvb_new_composite();
959                 }
960
961
962
963                 if (new_tvb != NULL && chunk_size != 0) {
964                         tvbuff_t *chunk_tvb = NULL;
965
966                         chunk_tvb = tvb_new_subset(tvb, chunk_offset,
967                             chunk_size, datalen);
968
969                         tvb_composite_append(new_tvb, chunk_tvb);
970
971                 }
972                 */
973
974                 chunked_data_size += chunk_size;
975
976                 if (chunk_size != 0) {
977                         guint8 *raw_data = g_malloc(chunked_data_size);
978                         gint raw_len = 0;
979
980                         if (new_tvb != NULL) {
981                                 raw_len = tvb_length_remaining(new_tvb, 0);
982                                 tvb_memcpy(new_tvb, raw_data, 0, raw_len);
983
984                                 tvb_free(new_tvb);
985                         }
986
987                         tvb_memcpy(tvb, (guint8 *)(raw_data + raw_len),
988                             chunk_offset, chunk_size);
989
990                         new_tvb = tvb_new_real_data(raw_data,
991                             chunked_data_size, chunked_data_size);
992                         tvb_set_free_cb(new_tvb, g_free);
993
994                 }
995
996                 if (subtree) {
997                         if (chunk_size == 0) {
998                                 chunk_ti = proto_tree_add_text(subtree, tvb,
999                                     offset,
1000                                     chunk_offset - offset + chunk_size + 2,
1001                                     "Data chunk (last chunk)");
1002                         } else {
1003                                 chunk_ti = proto_tree_add_text(subtree, tvb,
1004                                     offset,
1005                                     chunk_offset - offset + chunk_size + 2,
1006                                     "Data chunk (%u octets)", chunk_size);
1007                         }
1008
1009                         chunk_subtree = proto_item_add_subtree(chunk_ti,
1010                             ett_http_chunk_data);
1011
1012                         proto_tree_add_text(chunk_subtree, tvb, offset,
1013                             chunk_offset - offset, "Chunk size: %u octets",
1014                             chunk_size);
1015
1016                         data_tvb = tvb_new_subset(tvb, chunk_offset, chunk_size,
1017                             datalen);
1018
1019
1020                         if (chunk_size > 0) {
1021                                 call_dissector(data_handle, data_tvb, pinfo,
1022                                     chunk_subtree);
1023                         }
1024
1025                         proto_tree_add_text(chunk_subtree, tvb, chunk_offset +
1026                             chunk_size, 2, "Chunk boundary");
1027                 }
1028
1029                 chunks_decoded++;
1030                 offset = chunk_offset + chunk_size + 2;
1031                 datalen = tvb_reported_length_remaining(tvb, offset);
1032         }
1033
1034         if (new_tvb != NULL) {
1035
1036                 /* Placeholder for the day that composite tvbuffer's will work.
1037                 tvb_composite_finalize(new_tvb);
1038                 / * tvb_set_reported_length(new_tvb, chunked_data_size); * /
1039                 */
1040
1041                 /*
1042                  * XXX - Don't free this, since the tvbuffer that was passed
1043                  * may be used if the data spans multiple frames and reassembly
1044                  * isn't enabled.
1045                  *
1046                 tvb_free(*tvb_ptr);
1047                  */
1048                 *tvb_ptr = new_tvb;
1049
1050         } else {
1051                 /*
1052                  * We didn't create a new tvb, so don't allow sub dissectors
1053                  * try to decode the non-existant entity body.
1054                  */
1055                 chunks_decoded = -1;
1056         }
1057
1058         return chunks_decoded;
1059
1060 }
1061
1062
1063 /*
1064  * XXX - this won't handle HTTP 0.9 replies, but they're all data
1065  * anyway.
1066  */
1067 static int
1068 is_http_request_or_reply(const gchar *data, int linelen, http_type_t *type,
1069                 RequestDissector *req_dissector, int *req_strlen)
1070 {
1071         int isHttpRequestOrReply = FALSE;
1072         int prefix_len = 0;
1073
1074         /*
1075          * From RFC 2774 - An HTTP Extension Framework
1076          *
1077          * Support the command prefix that identifies the presence of
1078          * a "mandatory" header.
1079          */
1080         if (linelen >= 2 && strncmp(data, "M-", 2) == 0) {
1081                 data += 2;
1082                 linelen -= 2;
1083                 prefix_len = 2;
1084         }
1085
1086         /*
1087          * From draft-cohen-gena-client-01.txt, available from the uPnP forum:
1088          *      NOTIFY, SUBSCRIBE, UNSUBSCRIBE
1089          *
1090          * From draft-ietf-dasl-protocol-00.txt, a now vanished Microsoft draft:
1091          *      SEARCH
1092          */
1093         if (linelen >= 5 && strncmp(data, "HTTP/", 5) == 0) {
1094                 *type = HTTP_RESPONSE;
1095                 isHttpRequestOrReply = TRUE;    /* response */
1096                 if (req_dissector) {
1097                         *req_dissector = basic_response_dissector;
1098                         *req_strlen = linelen - 5;
1099                 }
1100         } else {
1101                 const guchar * ptr = (const guchar *)data;
1102                 int              index = 0;
1103
1104                 /* Look for the space following the Method */
1105                 while (index < linelen) {
1106                         if (*ptr == ' ')
1107                                 break;
1108                         else {
1109                                 ptr++;
1110                                 index++;
1111                         }
1112                 }
1113
1114                 /* Check the methods that have same length */
1115                 switch (index) {
1116
1117                 case 3:
1118                         if (strncmp(data, "GET", index) == 0 ||
1119                             strncmp(data, "PUT", index) == 0) {
1120                                 *type = HTTP_REQUEST;
1121                                 isHttpRequestOrReply = TRUE;
1122                         }
1123                         else if (strncmp(data, "ICY", index) == 0) {
1124                                 *type = HTTP_RESPONSE;
1125                                 isHttpRequestOrReply = TRUE;
1126                         }
1127                         break;
1128
1129                 case 4:
1130                         if (strncmp(data, "COPY", index) == 0 ||
1131                             strncmp(data, "HEAD", index) == 0 ||
1132                             strncmp(data, "LOCK", index) == 0 ||
1133                             strncmp(data, "MOVE", index) == 0 ||
1134                             strncmp(data, "POLL", index) == 0 ||
1135                             strncmp(data, "POST", index) == 0) {
1136                                 *type = HTTP_REQUEST;
1137                                 isHttpRequestOrReply = TRUE;
1138                         }
1139                         break;
1140
1141                 case 5:
1142                         if (strncmp(data, "BCOPY", index) == 0 ||
1143                                 strncmp(data, "BMOVE", index) == 0 ||
1144                                 strncmp(data, "MKCOL", index) == 0 ||
1145                                 strncmp(data, "TRACE", index) == 0) {
1146                                 *type = HTTP_REQUEST;
1147                                 isHttpRequestOrReply = TRUE;
1148                         }
1149                         break;
1150
1151                 case 6:
1152                         if (strncmp(data, "DELETE", index) == 0 ||
1153                                 strncmp(data, "SEARCH", index) == 0 ||
1154                                 strncmp(data, "UNLOCK", index) == 0) {
1155                                 *type = HTTP_REQUEST;
1156                                 isHttpRequestOrReply = TRUE;
1157                         }
1158                         else if (strncmp(data, "NOTIFY", index) == 0) {
1159                                 *type = HTTP_NOTIFICATION;
1160                                 isHttpRequestOrReply = TRUE;
1161                         }
1162                         break;
1163
1164                 case 7:
1165                         if (strncmp(data, "BDELETE", index) == 0 ||
1166                             strncmp(data, "CONNECT", index) == 0 ||
1167                             strncmp(data, "OPTIONS", index) == 0) {
1168                                 *type = HTTP_REQUEST;
1169                                 isHttpRequestOrReply = TRUE;
1170                         }
1171                         break;
1172
1173                 case 8:
1174                         if (strncmp(data, "PROPFIND", index) == 0) {
1175                                 *type = HTTP_REQUEST;
1176                                 isHttpRequestOrReply = TRUE;
1177                         }
1178                         break;
1179
1180                 case 9:
1181                         if (strncmp(data, "SUBSCRIBE", index) == 0) {
1182                                 *type = HTTP_NOTIFICATION;
1183                                 isHttpRequestOrReply = TRUE;
1184                         } else if (strncmp(data, "PROPPATCH", index) == 0 ||
1185                             strncmp(data, "BPROPFIND", index) == 0) {
1186                                 *type = HTTP_REQUEST;
1187                                 isHttpRequestOrReply = TRUE;
1188                         }
1189                         break;
1190
1191                 case 10:
1192                         if (strncmp(data, "BPROPPATCH", index) == 0) {
1193                                 *type = HTTP_REQUEST;
1194                                 isHttpRequestOrReply = TRUE;
1195                         }
1196                         break;
1197
1198                 case 11:
1199                         if (strncmp(data, "UNSUBSCRIBE", index) == 0) {
1200                                 *type = HTTP_NOTIFICATION;
1201                                 isHttpRequestOrReply = TRUE;
1202                         }
1203                         break;
1204
1205                 default:
1206                         break;
1207                 }
1208
1209                 if (isHttpRequestOrReply && req_dissector) {
1210                         *req_dissector = basic_request_dissector;
1211                         *req_strlen = index + prefix_len;
1212                 }
1213                 if (isHttpRequestOrReply && req_dissector) {
1214                         if (!stat_info->request_method)
1215                                 stat_info->request_method = g_malloc( index+1 );
1216                                 strncpy( stat_info->request_method, data, index);
1217                                 stat_info->request_method[index] = '\0';
1218                 }
1219         }
1220
1221         return isHttpRequestOrReply;
1222 }
1223
1224 /*
1225  * Process headers.
1226  */
1227 typedef struct {
1228         char    *name;
1229         gint    *hf;
1230         int     special;
1231 } header_info;
1232
1233 #define HDR_NO_SPECIAL          0
1234 #define HDR_AUTHORIZATION       1
1235 #define HDR_AUTHENTICATE        2
1236 #define HDR_CONTENT_TYPE        3
1237 #define HDR_CONTENT_LENGTH      4
1238 #define HDR_CONTENT_ENCODING    5
1239 #define HDR_TRANSFER_ENCODING   6
1240
1241 static const header_info headers[] = {
1242         { "Authorization", &hf_http_authorization, HDR_AUTHORIZATION },
1243         { "Proxy-Authorization", &hf_http_proxy_authorization, HDR_AUTHORIZATION },
1244         { "Proxy-Authenticate", &hf_http_proxy_authenticate, HDR_AUTHENTICATE },
1245         { "WWW-Authenticate", &hf_http_www_authenticate, HDR_AUTHENTICATE },
1246         { "Content-Type", &hf_http_content_type, HDR_CONTENT_TYPE },
1247         { "Content-Length", &hf_http_content_length, HDR_CONTENT_LENGTH },
1248         { "Content-Encoding", &hf_http_content_encoding, HDR_CONTENT_ENCODING },
1249         { "Transfer-Encoding", &hf_http_transfer_encoding, HDR_TRANSFER_ENCODING },
1250 };
1251
1252 static void
1253 process_header(tvbuff_t *tvb, int offset, int next_offset,
1254     const guchar *line, int linelen, int colon_offset,
1255     packet_info *pinfo, proto_tree *tree, headers_t *eh_ptr)
1256 {
1257         int len;
1258         int line_end_offset;
1259         int header_len;
1260         gint hf_index;
1261         guchar c;
1262         int value_offset;
1263         int value_len;
1264         char *value;
1265         char *p;
1266         guchar *up;
1267         proto_item *hdr_item;
1268         int i;
1269
1270         len = next_offset - offset;
1271         line_end_offset = offset + linelen;
1272         header_len = colon_offset - offset;
1273         hf_index = find_header_hf_value(tvb, offset, header_len);
1274
1275         if (hf_index == -1) {
1276                 /*
1277                  * Not a header we know anything about.  Just put it into
1278                  * the tree as text.
1279                  */
1280                 if (tree) {
1281                         proto_tree_add_text(tree, tvb, offset, len,
1282                             "%s", format_text(line, len));
1283                 }
1284         } else {
1285                 /*
1286                  * Skip whitespace after the colon.
1287                  */
1288                 value_offset = colon_offset + 1;
1289                 while (value_offset < line_end_offset
1290                     && ((c = line[value_offset - offset]) == ' ' || c == '\t'))
1291                         value_offset++;
1292
1293                 /*
1294                  * Fetch the value.
1295                  */
1296                 value_len = line_end_offset - value_offset;
1297                 value = g_malloc(value_len + 1);
1298                 memcpy(value, &line[value_offset - offset], value_len);
1299                 value[value_len] = '\0';
1300                 CLEANUP_PUSH(g_free, value);
1301
1302                 /*
1303                  * Add it to the protocol tree as a particular field,
1304                  * but display the line as is.
1305                  */
1306                 if (tree) {
1307                         hdr_item = proto_tree_add_string_format(tree,
1308                             *headers[hf_index].hf, tvb, offset, len,
1309                             value, "%s", format_text(line, len));
1310                 } else
1311                         hdr_item = NULL;
1312
1313                 /*
1314                  * Do any special processing that particular headers
1315                  * require.
1316                  */
1317                 switch (headers[hf_index].special) {
1318
1319                 case HDR_AUTHORIZATION:
1320                         if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
1321                                 break;  /* dissected NTLMSSP */
1322                         check_auth_basic(hdr_item, tvb, value);
1323                         break;
1324
1325                 case HDR_AUTHENTICATE:
1326                         check_auth_ntlmssp(hdr_item, tvb, pinfo, value);
1327                         break;
1328
1329                 case HDR_CONTENT_TYPE:
1330                         if (eh_ptr->content_type != NULL)
1331                                 g_free(eh_ptr->content_type);
1332                         eh_ptr->content_type = g_malloc(value_len + 1);
1333                         for (i = 0; i < value_len; i++) {
1334                                 c = value[i];
1335                                 if (c == ';' || isspace(c)) {
1336                                         /*
1337                                          * End of subtype - either
1338                                          * white space or a ";"
1339                                          * separating the subtype from
1340                                          * a parameter.
1341                                          */
1342                                         break;
1343                                 }
1344
1345                                 /*
1346                                  * Map the character to lower case;
1347                                  * content types are case-insensitive.
1348                                  */
1349                                 eh_ptr->content_type[i] = tolower(c);
1350                         }
1351                         eh_ptr->content_type[i] = '\0';
1352                         /*
1353                          * Now find the start of the optional parameters;
1354                          * skip the optional white space and the semicolon
1355                          * if this has not been done before.
1356                          */
1357                         i++;
1358                         while (i < value_len) {
1359                                 c = value[i];
1360                                 if (c == ';' || isspace(c))
1361                                         /* Skip till start of parameters */
1362                                         i++;
1363                                 else
1364                                         break;
1365                         }
1366                         if (i < value_len)
1367                                 eh_ptr->content_type_parameters = value + i;
1368                         else
1369                                 eh_ptr->content_type_parameters = NULL;
1370                         break;
1371
1372                 case HDR_CONTENT_LENGTH:
1373                         eh_ptr->content_length = strtol(value, &p, 10);
1374                         up = (guchar *)p;
1375                         if (eh_ptr->content_length < 0 || p == value ||
1376                             (*up != '\0' && !isspace(*up)))
1377                                 eh_ptr->content_length = -1;    /* not valid */
1378                         break;
1379
1380                 case HDR_CONTENT_ENCODING:
1381                         if (eh_ptr->content_encoding != NULL)
1382                                 g_free(eh_ptr->content_encoding);
1383                         eh_ptr->content_encoding = g_malloc(value_len + 1);
1384                         memcpy(eh_ptr->content_encoding, value, value_len);
1385                         eh_ptr->content_encoding[value_len] = '\0';
1386                         break;
1387
1388                 case HDR_TRANSFER_ENCODING:
1389                         if (eh_ptr->transfer_encoding != NULL)
1390                                 g_free(eh_ptr->transfer_encoding);
1391                         eh_ptr->transfer_encoding = g_malloc(value_len + 1);
1392                         memcpy(eh_ptr->transfer_encoding, value, value_len);
1393                         eh_ptr->transfer_encoding[value_len] = '\0';
1394                         break;
1395                 }
1396
1397                 /*
1398                  * Free the value, by calling and popping the cleanup
1399                  * handler for it.
1400                  */
1401                 CLEANUP_CALL_AND_POP;
1402         }
1403 }
1404
1405 /* Returns index of header tag in headers */
1406 static gint
1407 find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len)
1408 {
1409         guint i;
1410
1411         for (i = 0; i < array_length(headers); i++) {
1412                 if (header_len == strlen(headers[i].name) &&
1413                     tvb_strncaseeql(tvb, offset,
1414                                                 headers[i].name, header_len) == 0)
1415                         return i;
1416         }
1417
1418         return -1;
1419 }
1420
1421 /*
1422  * Dissect Microsoft's abomination called NTLMSSP over HTTP.
1423  */
1424 static gboolean
1425 check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo,
1426     gchar *value)
1427 {
1428         static const char *ntlm_headers[] = {
1429                 "NTLM ",
1430                 "Negotiate ",
1431                 NULL
1432         };
1433         const char **header;
1434         size_t hdrlen;
1435         proto_tree *hdr_tree;
1436
1437         /*
1438          * Check for NTLM credentials and challenge; those can
1439          * occur with WWW-Authenticate.
1440          */
1441         for (header = &ntlm_headers[0]; *header != NULL; header++) {
1442                 hdrlen = strlen(*header);
1443                 if (strncmp(value, *header, hdrlen) == 0) {
1444                         if (hdr_item != NULL) {
1445                                 hdr_tree = proto_item_add_subtree(hdr_item,
1446                                     ett_http_ntlmssp);
1447                         } else
1448                                 hdr_tree = NULL;
1449                         value += hdrlen;
1450                         dissect_http_ntlmssp(tvb, pinfo, hdr_tree, value);
1451                         return TRUE;
1452                 }
1453         }
1454         return FALSE;
1455 }
1456
1457 /*
1458  * Dissect HTTP Basic authorization.
1459  */
1460 static gboolean
1461 check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value)
1462 {
1463         static const char *basic_headers[] = {
1464                 "Basic ",
1465                 NULL
1466         };
1467         const char **header;
1468         size_t hdrlen;
1469         proto_tree *hdr_tree;
1470         size_t len;
1471
1472         for (header = &basic_headers[0]; *header != NULL; header++) {
1473                 hdrlen = strlen(*header);
1474                 if (strncmp(value, *header, hdrlen) == 0) {
1475                         if (hdr_item != NULL) {
1476                                 hdr_tree = proto_item_add_subtree(hdr_item,
1477                                     ett_http_ntlmssp);
1478                         } else
1479                                 hdr_tree = NULL;
1480                         value += hdrlen;
1481
1482                         len = epan_base64_decode(value);
1483                         value[len] = '\0';
1484                         proto_tree_add_string(hdr_tree, hf_http_basic, tvb,
1485                             0, 0, value);
1486
1487                         return TRUE;
1488                 }
1489         }
1490         return FALSE;
1491 }
1492
1493 static void
1494 dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1495 {
1496         int             offset = 0;
1497         int             len;
1498
1499         while (tvb_reported_length_remaining(tvb, offset) != 0) {
1500                 len = dissect_http_message(tvb, offset, pinfo, tree);
1501                 if (len == -1)
1502                         break;
1503                 offset += len;
1504
1505                 /*
1506                  * OK, we've set the Protocol and Info columns for the
1507                  * first HTTP message; make the columns non-writable,
1508                  * so that we don't change it for subsequent HTTP messages.
1509                  */
1510                 col_set_writable(pinfo->cinfo, FALSE);
1511         }
1512 }
1513
1514 static void
1515 dissect_http_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1516 {
1517         dissect_http_message(tvb, 0, pinfo, tree);
1518 }
1519
1520 void
1521 proto_register_http(void)
1522 {
1523         static hf_register_info hf[] = {
1524             { &hf_http_notification,
1525               { "Notification",         "http.notification",
1526                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1527                 "TRUE if HTTP notification", HFILL }},
1528             { &hf_http_response,
1529               { "Response",             "http.response",
1530                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1531                 "TRUE if HTTP response", HFILL }},
1532             { &hf_http_request,
1533               { "Request",              "http.request",
1534                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1535                 "TRUE if HTTP request", HFILL }},
1536             { &hf_http_basic,
1537               { "Credentials",          "http.authbasic",
1538                 FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1539             { &hf_http_request_method,
1540               { "Request Method",       "http.request.method",
1541                 FT_STRING, BASE_NONE, NULL, 0x0,
1542                 "HTTP Request Method", HFILL }},
1543             { &hf_http_response_code,
1544               { "Response Code",        "http.response.code",
1545                 FT_UINT16, BASE_DEC, NULL, 0x0,
1546                 "HTTP Response Code", HFILL }},
1547             { &hf_http_authorization,
1548               { "Authorization",        "http.authorization",
1549                 FT_STRING, BASE_NONE, NULL, 0x0,
1550                 "HTTP Authorization header", HFILL }},
1551             { &hf_http_proxy_authenticate,
1552               { "Proxy-Authenticate",   "http.proxy_authenticate",
1553                 FT_STRING, BASE_NONE, NULL, 0x0,
1554                 "HTTP Proxy-Authenticate header", HFILL }},
1555             { &hf_http_proxy_authorization,
1556               { "Proxy-Authorization",  "http.proxy_authorization",
1557                 FT_STRING, BASE_NONE, NULL, 0x0,
1558                 "HTTP Proxy-Authorization header", HFILL }},
1559             { &hf_http_www_authenticate,
1560               { "WWW-Authenticate",     "http.www_authenticate",
1561                 FT_STRING, BASE_NONE, NULL, 0x0,
1562                 "HTTP WWW-Authenticate header", HFILL }},
1563             { &hf_http_content_type,
1564               { "Content-Type", "http.content_type",
1565                 FT_STRING, BASE_NONE, NULL, 0x0,
1566                 "HTTP Content-Type header", HFILL }},
1567             { &hf_http_content_length,
1568               { "Content-Length",       "http.content_length",
1569                 FT_STRING, BASE_NONE, NULL, 0x0,
1570                 "HTTP Content-Length header", HFILL }},
1571             { &hf_http_content_encoding,
1572               { "Content-Encoding",     "http.content_encoding",
1573                 FT_STRING, BASE_NONE, NULL, 0x0,
1574                 "HTTP Content-Encoding header", HFILL }},
1575             { &hf_http_transfer_encoding,
1576               { "Transfer-Encoding",    "http.transfer_encoding",
1577                 FT_STRING, BASE_NONE, NULL, 0x0,
1578                 "HTTP Transfer-Encoding header", HFILL }},
1579         };
1580         static gint *ett[] = {
1581                 &ett_http,
1582                 &ett_http_ntlmssp,
1583                 &ett_http_request,
1584                 &ett_http_chunked_response,
1585                 &ett_http_chunk_data,
1586                 &ett_http_encoded_entity,
1587         };
1588         module_t *http_module;
1589
1590         proto_http = proto_register_protocol("Hypertext Transfer Protocol",
1591             "HTTP", "http");
1592         proto_register_field_array(proto_http, hf, array_length(hf));
1593         proto_register_subtree_array(ett, array_length(ett));
1594         http_module = prefs_register_protocol(proto_http, NULL);
1595         prefs_register_bool_preference(http_module, "desegment_headers",
1596             "Desegment all HTTP headers spanning multiple TCP segments",
1597             "Whether the HTTP dissector should desegment all headers "
1598             "of a request spanning multiple TCP segments",
1599             &http_desegment_headers);
1600         prefs_register_bool_preference(http_module, "desegment_body",
1601             "Desegment HTTP bodies spanning multiple TCP segments",
1602             "Whether the HTTP dissector should use the "
1603             "\"Content-length:\" value, if present, to desegment "
1604             "the body of a request spanning multiple TCP segments, "
1605             "and desegment chunked data spanning multiple TCP segments",
1606             &http_desegment_body);
1607         prefs_register_bool_preference(http_module, "dechunk_body",
1608             "Reassemble chunked transfer-coded bodies",
1609             "Whether to reassemble bodies of entities that are transfered "
1610             "using the \"Transfer-Encoding: chunked\" method",
1611             &http_dechunk_body);
1612 #ifdef HAVE_LIBZ
1613         prefs_register_bool_preference(http_module, "decompress_body",
1614             "Uncompress entity bodies",
1615             "Whether to uncompress entity bodies that are compressed "
1616             "using \"Content-Encoding: \"",
1617             &http_decompress_body);
1618 #endif
1619
1620         http_handle = create_dissector_handle(dissect_http, proto_http);
1621
1622         /*
1623          * Dissectors shouldn't register themselves in this table;
1624          * instead, they should call "http_dissector_add()", and
1625          * we'll register the port number they specify as a port
1626          * for HTTP, and register them in our subdissector table.
1627          *
1628          * This only works for protocols such as IPP that run over
1629          * HTTP on a specific non-HTTP port.
1630          */
1631         port_subdissector_table = register_dissector_table("http.port",
1632             "TCP port for protocols using HTTP", FT_UINT16, BASE_DEC);
1633
1634         /*
1635          * Dissectors can register themselves in this table.
1636          * It's just "media_type", not "http.content_type", because
1637          * it's an Internet media type, usable by other protocols as well.
1638          */
1639         media_type_subdissector_table =
1640             register_dissector_table("media_type",
1641                 "Internet media type", FT_STRING, BASE_NONE);
1642
1643         /*
1644          * Heuristic dissectors SHOULD register themselves in
1645          * this table using the standard heur_dissector_add()
1646          * function.
1647          */
1648         register_heur_dissector_list("http", &heur_subdissector_list);
1649
1650         /*
1651          * Register for tapping
1652          */
1653         http_tap = register_tap("http");
1654 }
1655
1656 /*
1657  * Called by dissectors for protocols that run atop HTTP/TCP.
1658  */
1659 void
1660 http_dissector_add(guint32 port, dissector_handle_t handle)
1661 {
1662         /*
1663          * Register ourselves as the handler for that port number
1664          * over TCP.
1665          */
1666         dissector_add("tcp.port", port, http_handle);
1667
1668         /*
1669          * And register them in *our* table for that port.
1670          */
1671         dissector_add("http.port", port, handle);
1672 }
1673
1674 void
1675 proto_reg_handoff_http(void)
1676 {
1677         dissector_handle_t http_udp_handle;
1678
1679         data_handle = find_dissector("data");
1680         media_handle = find_dissector("media");
1681
1682         dissector_add("tcp.port", TCP_PORT_HTTP, http_handle);
1683         dissector_add("tcp.port", TCP_ALT_PORT_HTTP, http_handle);
1684         dissector_add("tcp.port", TCP_PORT_PROXY_HTTP, http_handle);
1685         dissector_add("tcp.port", TCP_PORT_PROXY_ADMIN_HTTP, http_handle);
1686
1687         /*
1688          * XXX - is there anything to dissect in the body of an SSDP
1689          * request or reply?  I.e., should there be an SSDP dissector?
1690          */
1691         dissector_add("tcp.port", TCP_PORT_SSDP, http_handle);
1692         http_udp_handle = create_dissector_handle(dissect_http_udp, proto_http);
1693         dissector_add("udp.port", UDP_PORT_SSDP, http_udp_handle);
1694
1695         ntlmssp_handle = find_dissector("ntlmssp");
1696 }
1697
1698 /*
1699  * Content-Type: message/http
1700  */
1701
1702 static gint proto_message_http = -1;
1703 static gint ett_message_http = -1;
1704 static dissector_handle_t message_http_handle;
1705
1706 static void
1707 dissect_message_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1708 {
1709         proto_tree      *subtree;
1710         proto_item      *ti;
1711         gint            offset = 0, next_offset;
1712         gint            len;
1713
1714         if (check_col(pinfo->cinfo, COL_INFO))
1715                 col_append_str(pinfo->cinfo, COL_INFO, " (message/http)");
1716         if (tree) {
1717                 ti = proto_tree_add_item(tree, proto_message_http,
1718                                 tvb, 0, -1, FALSE);
1719                 subtree = proto_item_add_subtree(ti, ett_message_http);
1720                 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1721                         len = tvb_find_line_end(tvb, offset,
1722                                         tvb_ensure_length_remaining(tvb, offset),
1723                                         &next_offset, FALSE);
1724                         if (len == -1)
1725                                 break;
1726                         proto_tree_add_text(subtree, tvb, offset, next_offset - offset,
1727                                         "%s", tvb_format_text(tvb, offset, len));
1728                         offset = next_offset;
1729                 }
1730         }
1731 }
1732
1733 void
1734 proto_register_message_http(void)
1735 {
1736         static gint *ett[] = {
1737                 &ett_message_http,
1738         };
1739
1740         proto_message_http = proto_register_protocol(
1741                         "Media Type: message/http",
1742                         "message/http",
1743                         "message-http"
1744         );
1745         proto_register_subtree_array(ett, array_length(ett));
1746         message_http_handle = create_dissector_handle(dissect_message_http,
1747                         proto_message_http);
1748 }
1749
1750 void
1751 proto_reg_handoff_message_http(void)
1752 {
1753         message_http_handle = create_dissector_handle(dissect_message_http,
1754                         proto_message_http);
1755
1756         dissector_add_string("media_type", "message/http", message_http_handle);
1757 }