diff --git a/CHANGES b/CHANGES index d91a2e4700..254ce62a0f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,287 @@ +2.3 | 2014-06-16 09:48:25 -0500 + + * Release 2.3. + +2.3-beta-33 | 2014-06-12 11:59:28 -0500 + + * Documentation improvements/fixes. (Daniel Thayer) + +2.3-beta-24 | 2014-06-11 15:35:31 -0500 + + * Fix SMTP state tracking when server response is missing. + (Robin Sommer) + +2.3-beta-22 | 2014-06-11 12:31:38 -0500 + + * Fix doc/test that broke due to a Bro script change. (Jon Siwek) + + * Remove unused --with-libmagic configure option. (Jon Siwek) + +2.3-beta-20 | 2014-06-10 18:16:51 -0700 + + * Fix use-after-free in some cases of reassigning a table index. + Addresses BIT-1202. (Jon Siwek) + +2.3-beta-18 | 2014-06-06 13:11:50 -0700 + + * Add two more SSL events, one triggered for each handshake message + and one triggered for the tls change cipherspec message. (Bernhard + Amann) + + * Small SSL bug fix. In case SSL::disable_analyzer_after_detection + was set to false, the ssl_established event would fire after each + data packet once the session is established. (Bernhard Amann) + +2.3-beta-16 | 2014-06-06 13:05:44 -0700 + + * Re-activate notice suppression for expiring certificates. + (Bernhard Amann) + +2.3-beta-14 | 2014-06-05 14:43:33 -0700 + + * Add new TLS extension type numbers from IANA (Bernhard Amann) + + * Switch to double hashing for Bloomfilters for better performance. + (Matthias Vallentin) + + * Bugfix to use full digest length instead of just one byte for + Bloomfilter's universal hash function. Addresses BIT-1140. + (Matthias Vallentin) + + * Make buffer for X509 certificate subjects larger. Addresses + BIT-1195 (Bernhard Amann) + +2.3-beta-5 | 2014-05-29 15:34:42 -0500 + + * Fix misc/load-balancing.bro's reference to + PacketFilter::sampling_filter (Jon Siwek) + +2.3-beta-4 | 2014-05-28 14:55:24 -0500 + + * Fix potential mem leak in remote function/event unserialization. + (Jon Siwek) + + * Fix reference counting bug in table coercion expressions (Jon Siwek) + + * Fix an "unused value" warning. (Jon Siwek) + + * Remove a duplicate unit test baseline dir. (Jon Siwek) + +2.3-beta | 2014-05-19 16:36:50 -0500 + + * Release 2.3-beta + + * Clean up OpenSSL data structures on exit. (Bernhard Amann) + + * Fixes for OCSP & x509 analysis memory leak issues. (Bernhard Amann) + + * Remove remaining references to BROMAGIC (Daniel Thayer) + + * Fix typos and formatting in event and BiF documentation (Daniel Thayer) + + * Update intel framework plugin for ssl server_name extension API + changes. (Bernhard Amann, Justin Azoff) + + * Fix expression errors in SSL/x509 scripts when unparseable data + is in certificate chain. (Bernhard Amann) + +2.2-478 | 2014-05-19 15:31:33 -0500 + + * Change record ctors to only allow record-field-assignment + expressions. (Jon Siwek) + +2.2-477 | 2014-05-19 14:13:00 -0500 + + * Fix X509::Result record's "result" field to be set internally as type int instead of type count. (Bernhard Amann) + + * Fix a couple of doc build warnings (Daniel Thayer) + +2.2-470 | 2014-05-16 15:16:32 -0700 + + * Add a new section "Cluster Configuration" to the docs that is + intended as a how-to for configuring a Bro cluster. Most of this + content was moved here from the BroControl doc (which is now + intended as more of a reference guide for more experienced users) + and the load balancing FAQ on the website. (Daniel Thayer) + + * Update some doc tests and line numbers (Daniel Thayer) + +2.2-457 | 2014-05-16 14:38:31 -0700 + + * New script policy/protocols/ssl/validate-ocsp.bro that adds OSCP + validation to ssl.log. The work is done by a new bif + x509_ocsp_verify(). (Bernhard Amann) + + * STARTTLS support for POP3 and SMTP. The SSL analyzer takes over + when seen. smtp.log now logs when a connection switches to SSL. + (Bernhard Amann) + + * Replace errors when parsing x509 certs with weirds. (Bernhard + Amann) + + * Improved Heartbleed attack/scan detection. (Bernhard Amann) + + * Let TLS analyzer fail better when no longer in sync with the data + stream. (Bernhard Amann) + +2.2-444 | 2014-05-16 14:10:32 -0500 + + * Disable all default AppStat plugins except facebook. (Jon Siwek) + + * Update for the active http test to force it to use ipv4. (Seth Hall) + +2.2-441 | 2014-05-15 11:29:56 -0700 + + * A new RADIUS analyzer. (Vlad Grigorescu) + + It produces a radius.log and generates two events: + + event radius_message(c: connection, result: RADIUS::Message); + event radius_attribute(c: connection, attr_type: count, value: string); + +2.2-427 | 2014-05-15 13:37:23 -0400 + + * Fix dynamic SumStats update on clusters (Bernhard Amann) + +2.2-425 | 2014-05-08 16:34:44 -0700 + + * Fix reassembly of data w/ sizes beyond 32-bit capacities. (Jon Siwek) + + Reassembly code (e.g. for TCP) now uses int64/uint64 (signedness + is situational) data types in place of int types in order to + support delivering data to analyzers that pass 2GB thresholds. + There's also changes in logic that accompany the change in data + types, e.g. to fix TCP sequence space arithmetic inconsistencies. + + Another significant change is in the Analyzer API: the *Packet and + *Undelivered methods now use a uint64 in place of an int for the + relative sequence space offset parameter. + + Addresses BIT-348. + + * Fixing compiler warnings. (Robin Sommer) + + * Update SNMP analyzer's DeliverPacket method signature. (Jon Siwek) + +2.2-417 | 2014-05-07 10:59:22 -0500 + + * Change handling of atypical OpenSSL error case in x509 verification. (Jon Siwek) + + * Fix memory leaks in X509 certificate parsing/verification. (Jon Siwek) + + * Fix new []/delete mismatch in input::reader::Raw::DoClose(). (Jon Siwek) + + * Fix buffer over-reads in file_analysis::Manager::Terminate() (Jon Siwek) + + * Fix buffer overlows in IP address masking logic. (Jon Siwek) + + That could occur either in taking a zero-length mask on an IPv6 address + (e.g. [fe80::]/0) or a reverse mask of length 128 on any address (e.g. + via the remask_addr BuiltIn Function). + + * Fix new []/delete mismatch in ~Base64Converter. (Jon Siwek) + +2.2-410 | 2014-05-02 12:49:53 -0500 + + * Replace an unneeded OPENSSL_malloc call. (Jon Siwek) + +2.2-409 | 2014-05-02 12:09:06 -0500 + + * Clean up and documentation for base SNMP script. (Jon Siwek) + + * Update base SNMP script to now produce a snmp.log. (Seth Hall) + + * Add DH support to SSL analyzer. When using DHE or DH-Anon, sever + key parameters are now available in scriptland. Also add script to + alert on weak certificate keys or weak dh-params. (Bernhard Amann) + + * Add a few more ciphers Bro did not know at all so far. (Bernhard Amann) + + * Log chosen curve when using ec cipher suite in TLS. (Bernhard Amann) + +2.2-397 | 2014-05-01 20:29:20 -0700 + + * Fix reference counting for lookup_ID() usages. (Jon Siwek) + +2.2-395 | 2014-05-01 20:25:48 -0700 + + * Fix missing "irc-dcc-data" service field from IRC DCC connections. + (Jon Siwek) + + * Correct a notice for heartbleed. The notice is thrown correctly, + just the message conteined wrong values. (Bernhard Amann) + + * Improve/standardize some malloc/realloc return value checks. (Jon + Siwek) + + * Improve file analysis manager shutdown/cleanup. (Jon Siwek) + +2.2-388 | 2014-04-24 18:38:07 -0700 + + * Fix decoding of MIME quoted-printable. (Mareq) + +2.2-386 | 2014-04-24 18:22:29 -0700 + + * Do a Intel::ADDR lookup for host field if we find an IP address + there. (jshlbrd) + +2.2-381 | 2014-04-24 17:08:45 -0700 + + * Add Java version to software framework. (Brian Little) + +2.2-379 | 2014-04-24 17:06:21 -0700 + + * Remove unused Val::attribs member. (Jon Siwek) + +2.2-377 | 2014-04-24 16:57:54 -0700 + + * A larger set of SSL improvements and extensions. Addresses + BIT-1178. (Bernhard Amann) + + - Fixes TLS protocol version detection. It also should + bail-out correctly on non-tls-connections now + + - Adds support for a few TLS extensions, including + server_name, alpn, and ec-curves. + + - Adds support for the heartbeat events. + + - Add Heartbleed detector script. + + - Adds basic support for OCSP stapling. + + * Fix parsing of DNS TXT RRs w/ multiple character-strings. + Addresses BIT-1156. (Jon Siwek) + +2.2-353 | 2014-04-24 16:12:30 -0700 + + * Adapt HTTP partial content to cache file analysis IDs. (Jon Siwek) + + * Adapt SSL analyzer to generate file analysis handles itself. (Jon + Siwek) + + * Adapt more of HTTP analyzer to use cached file analysis IDs. (Jon + Siwek) + + * Adapt IRC/FTP analyzers to cache file analysis IDs. (Jon Siwek) + + * Refactor regex/signature AcceptingSet data structure and usages. + (Jon Siwek) + + * Enforce data size limit when checking files for MIME matches. (Jon + Siwek) + + * Refactor file analysis file ID lookup. (Jon Siwek) + +2.2-344 | 2014-04-22 20:13:30 -0700 + + * Refactor various hex escaping code. (Jon Siwek) + +2.2-341 | 2014-04-17 18:01:41 -0500 + + * Fix duplicate DNS log entries. (Robin Sommer) + 2.2-341 | 2014-04-17 18:01:01 -0500 * Refactor initialization of ASCII log writer options. (Jon Siwek) @@ -125,8 +408,19 @@ 2.2-294 | 2014-03-30 22:08:25 +0200 - * TODO: x509 changes. (Bernhard Amann) - + * Rework and move X509 certificate processing from the SSL protocol + analyzer to a dedicated file analyzer. This will allow us to + examine X509 certificates from sources other than SSL in the + future. Furthermore, Bro now parses more fields and extensions + from the certificates (e.g. elliptic curve information, subject + alternative names, basic constraints). Certificate validation also + was improved, should be easier to use and exposes information like + the full verified certificate chain. (Bernhard Amann) + + This update changes the format of ssl.log and adds a new x509.log + with certificate information. Furthermore all x509 events and + handling functions have changed. + 2.2-271 | 2014-03-30 20:25:17 +0200 * Add unit tests covering vector/set/table ctors/inits. (Jon Siwek) diff --git a/NEWS b/NEWS index 6d0bb2a7e5..b6754e1389 100644 --- a/NEWS +++ b/NEWS @@ -7,14 +7,9 @@ their own ``CHANGES``.) Bro 2.3 ======= -[In progress] - Dependencies ------------ -- Bro no longer requires a pre-installed libmagic (because it now - ships its own). - - Libmagic is no longer a dependency. New Functionality @@ -34,12 +29,44 @@ New Functionality and "file-mime" gives the MIME type string of content that matches the magic and an optional strength value for the match. (See also "Changed Functionality" below for changes due to switching from - using libmagic to such wsignatures.) + using libmagic to such signatures.) - A new built-in function, "file_magic", can be used to get all file magic matches and their corresponding strength against a given chunk of data. +- The SSL analyzer now supports heartbeats as well as a few + extensions, including server_name, alpn, and ec-curves. + +- The SSL analyzer comes with Heartbleed detector script in + protocols/ssl/heartbleed.bro. Note that loading this script changes + the default value of "SSL::disable_analyzer_after_detection" from true + to false to prevent encrypted heartbeats from being ignored. + +- StartTLS is now supported for SMTP and POP3. + +- The X509 analyzer can now perform OSCP validation. + +- Bro now has analyzers for SNMP and Radius, which produce corresponding + snmp.log and radius.log output (as well as various events of course). + +- BroControl has a new option "BroPort" which allows a user to specify + the starting port number for Bro. + +- BroControl has a new option "StatsLogExpireInterval" which allows a + user to specify when entries in the stats.log file expire. + +- BroControl has a new option "PFRINGClusterType" which allows a user + to specify a PF_RING cluster type. + +- BroControl now supports PF_RING+DNA. There is also a new option + "PFRINGFirstAppInstance" that allows a user to specify the starting + application instance number for processes running on a DNA cluster. + See the BroControl documentation for more details. + +- BroControl now warns a user to run "broctl install" if Bro has + been upgraded or if the broctl or node configuration has changed + since the most recent install. Changed Functionality --------------------- @@ -57,17 +84,27 @@ Changed Functionality event x509_extension(c: connection, is_orig: bool, cert: X509, ext: X509_extension_info); -- Bro no longer special-cases SYN/FIN/RST-filtered traces by not - reporting missing data. The old behavior can be reverted by - redef'ing "detect_filtered_trace". +- In addition, there are several new, more specialized events for a + number of x509 extensions. - TODO: Update if we add a detector for filtered traces. +- Generally, all x509 events and handling functions have changed their + signatures. + +- X509 certificate verification now returns the complete certificate + chain that was used for verification. + +- Bro no longer special-cases SYN/FIN/RST-filtered traces by not + reporting missing data. Instead, if Bro never sees any data segments + for analyzed TCP connections, the new + base/misc/find-filtered-trace.bro script will log a warning in + reporter.log and to stderr. The old behavior can be reverted by + redef'ing "detect_filtered_trace". - We have removed the packet sorter component. - Bro no longer uses libmagic to identify file types but instead now comes with its own signature library (which initially is still - derived from libmagic;s database). This leads to a number of further + derived from libmagic's database). This leads to a number of further changes with regards to MIME types: * The second parameter of the "identify_data" built-in function @@ -82,7 +119,7 @@ Changed Functionality in Bro as magic databases are no longer used/installed. * Removed "binary" and "octet-stream" mime type detections. They - don' provide any more information than an uninitialized + don't provide any more information than an uninitialized mime_type field. * The "fa_file" record now contains a "mime_types" field that @@ -90,6 +127,19 @@ Changed Functionality (where the "mime_type" field is just a shortcut for the strongest match). +- dns_TXT_reply() now supports more than one string entry by receiving + a vector of strings. + +- BroControl now runs the "exec" and "df" broctl commands only once + per host, instead of once per Bro node. The output of these + commands has been changed slightly to include both the host and + node names. + +- Several performance improvements were made. Particular emphasis + was put on the File Analysis system, which generally will now emit + far fewer file handle request events due to protocol analyzers now + caching that information internally. + Bro 2.2 ======= diff --git a/VERSION b/VERSION index 85d7fee81b..bb576dbde1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2-341 +2.3 diff --git a/aux/binpac b/aux/binpac index b0877edc68..ec1e052afd 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit b0877edc68af6ae08face528fc411c8ce21f2e30 +Subproject commit ec1e052afd5a8cd3d1d2cbb28fcd688018e379a5 diff --git a/aux/bro-aux b/aux/bro-aux index 3f86e2d5db..5721df4f5f 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 3f86e2d5db2a0c5f2f104b15f359f4b752bb4558 +Subproject commit 5721df4f5f6fa84de6257cca6582a28e45831786 diff --git a/aux/broccoli b/aux/broccoli index 04e6a7f591..c2f5dd2cb7 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 04e6a7f591817f060a781f21c12e1afce7eb1e16 +Subproject commit c2f5dd2cb7876158fdf9721aebd22567db840db1 diff --git a/aux/broctl b/aux/broctl index d99150801b..8a13886f32 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit d99150801b7844e082b5421d1efe4050702d350e +Subproject commit 8a13886f322f3b618832c0ca3976e07f686d14da diff --git a/aux/btest b/aux/btest index 4e2ec35917..4da1bd2403 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 4e2ec35917acb883c7d2ab19af487f3863c687ae +Subproject commit 4da1bd24038d4977e655f2b210f34e37f0b73b78 diff --git a/configure b/configure index 5af2f25c8f..35095c333a 100755 --- a/configure +++ b/configure @@ -50,7 +50,6 @@ Usage: $0 [OPTION]... [VAR=VALUE]... --with-flex=PATH path to flex executable --with-bison=PATH path to bison executable --with-perl=PATH path to perl executable - --with-libmagic=PATH path to libmagic install root Optional Packages in Non-Standard Locations: --with-geoip=PATH path to the libGeoIP install root @@ -211,9 +210,6 @@ while [ $# -ne 0 ]; do --with-perl=*) append_cache_entry PERL_EXECUTABLE PATH $optarg ;; - --with-libmagic=*) - append_cache_entry LibMagic_ROOT_DIR PATH $optarg - ;; --with-geoip=*) append_cache_entry LibGeoIP_ROOT_DIR PATH $optarg ;; diff --git a/doc/conf.py.in b/doc/conf.py.in index 91e16452f3..9720d12ade 100644 --- a/doc/conf.py.in +++ b/doc/conf.py.in @@ -38,7 +38,6 @@ extensions += ["broxygen"] bro_binary = os.path.abspath("@CMAKE_SOURCE_DIR@/build/src/bro") broxygen_cache="@BROXYGEN_CACHE_DIR@" os.environ["BROPATH"] = "@BROPATH@" -os.environ["BROMAGIC"] = "@BROMAGIC@" # ----- End of Broxygen configuration. ----- # -- General configuration ----------------------------------------------------- diff --git a/doc/configuration/index.rst b/doc/configuration/index.rst new file mode 100644 index 0000000000..800d746e72 --- /dev/null +++ b/doc/configuration/index.rst @@ -0,0 +1,263 @@ + +.. _configuration: + +===================== +Cluster Configuration +===================== + +.. contents:: + +A *Bro Cluster* is a set of systems jointly analyzing the traffic of +a network link in a coordinated fashion. You can operate such a setup from +a central manager system easily using BroControl because BroControl +hides much of the complexity of the multi-machine installation. + +This section gives examples of how to setup common cluster configurations +using BroControl. For a full reference on BroControl, see the +:doc:`BroControl <../components/broctl/README>` documentation. + + +Preparing to Setup a Cluster +============================ + +In this document we refer to the user account used to set up the cluster +as the "Bro user". When setting up a cluster the Bro user must be set up +on all hosts, and this user must have ssh access from the manager to all +machines in the cluster, and it must work without being prompted for a +password/passphrase (for example, using ssh public key authentication). +Also, on the worker nodes this user must have access to the target +network interface in promiscuous mode. + +Additional storage must be available on all hosts under the same path, +which we will call the cluster's prefix path. We refer to this directory +as ````. If you build Bro from source, then ```` is +the directory specified with the ``--prefix`` configure option, +or ``/usr/local/bro`` by default. The Bro user must be able to either +create this directory or, where it already exists, must have write +permission inside this directory on all hosts. + +When trying to decide how to configure the Bro nodes, keep in mind that +there can be multiple Bro instances running on the same host. For example, +it's possible to run a proxy and the manager on the same host. However, it is +recommended to run workers on a different machine than the manager because +workers can consume a lot of CPU resources. The maximum recommended +number of workers to run on a machine should be one or two less than +the number of CPU cores available on that machine. Using a load-balancing +method (such as PF_RING) along with CPU pinning can decrease the load on +the worker machines. + + +Basic Cluster Configuration +=========================== + +With all prerequisites in place, perform the following steps to setup +a Bro cluster (do this as the Bro user on the manager host only): + +- Edit the BroControl configuration file, ``/etc/broctl.cfg``, + and change the value of any BroControl options to be more suitable for + your environment. You will most likely want to change the value of + the ``MailTo`` and ``LogRotationInterval`` options. A complete + reference of all BroControl options can be found in the + :doc:`BroControl <../components/broctl/README>` documentation. + +- Edit the BroControl node configuration file, ``/etc/node.cfg`` + to define where manager, proxies, and workers are to run. For a cluster + configuration, you must comment-out (or remove) the standalone node + in that file, and either uncomment or add node entries for each node + in your cluster (manager, proxy, and workers). For example, if you wanted + to run four Bro nodes (two workers, one proxy, and a manager) on a cluster + consisting of three machines, your cluster configuration would look like + this:: + + [manager] + type=manager + host=10.0.0.10 + + [proxy-1] + type=proxy + host=10.0.0.10 + + [worker-1] + type=worker + host=10.0.0.11 + interface=eth0 + + [worker-2] + type=worker + host=10.0.0.12 + interface=eth0 + + For a complete reference of all options that are allowed in the ``node.cfg`` + file, see the :doc:`BroControl <../components/broctl/README>` documentation. + +- Edit the network configuration file ``/etc/networks.cfg``. This + file lists all of the networks which the cluster should consider as local + to the monitored environment. + +- Install workers and proxies using BroControl:: + + > broctl install + +- Some tasks need to be run on a regular basis. On the manager node, + insert a line like this into the crontab of the user running the + cluster:: + + 0-59/5 * * * * /bin/broctl cron + + (Note: if you are editing the system crontab instead of a user's own + crontab, then you need to also specify the user which the command + will be run as. The username must be placed after the time fields + and before the broctl command.) + + Note that on some systems (FreeBSD in particular), the default PATH + for cron jobs does not include the directories where bash and python + are installed (the symptoms of this problem would be that "broctl cron" + works when run directly by the user, but does not work from a cron job). + To solve this problem, you would either need to create symlinks + to bash and python in a directory that is in the default PATH for + cron jobs, or specify a new PATH in the crontab. + + +PF_RING Cluster Configuration +============================= + +`PF_RING `_ allows speeding up the +packet capture process by installing a new type of socket in Linux systems. +It supports 10Gbit hardware packet filtering using standard network adapters, +and user-space DNA (Direct NIC Access) for fast packet capture/transmission. + +Installing PF_RING +^^^^^^^^^^^^^^^^^^ + +1. Download and install PF_RING for your system following the instructions + `here `_. The following + commands will install the PF_RING libraries and kernel module (replace + the version number 5.6.2 in this example with the version that you + downloaded):: + + cd /usr/src + tar xvzf PF_RING-5.6.2.tar.gz + cd PF_RING-5.6.2/userland/lib + ./configure --prefix=/opt/pfring + make install + + cd ../libpcap + ./configure --prefix=/opt/pfring + make install + + cd ../tcpdump-4.1.1 + ./configure --prefix=/opt/pfring + make install + + cd ../../kernel + make install + + modprobe pf_ring enable_tx_capture=0 min_num_slots=32768 + + Refer to the documentation for your Linux distribution on how to load the + pf_ring module at boot time. You will need to install the PF_RING + library files and kernel module on all of the workers in your cluster. + +2. Download the Bro source code. + +3. Configure and install Bro using the following commands:: + + ./configure --with-pcap=/opt/pfring + make + make install + +4. Make sure Bro is correctly linked to the PF_RING libpcap libraries:: + + ldd /usr/local/bro/bin/bro | grep pcap + libpcap.so.1 => /opt/pfring/lib/libpcap.so.1 (0x00007fa6d7d24000) + +5. Configure BroControl to use PF_RING (explained below). + +6. Run "broctl install" on the manager. This command will install Bro and + all required scripts to the other machines in your cluster. + +Using PF_RING +^^^^^^^^^^^^^ + +In order to use PF_RING, you need to specify the correct configuration +options for your worker nodes in BroControl's node configuration file. +Edit the ``node.cfg`` file and specify ``lb_method=pf_ring`` for each of +your worker nodes. Next, use the ``lb_procs`` node option to specify how +many Bro processes you'd like that worker node to run, and optionally pin +those processes to certain CPU cores with the ``pin_cpus`` option (CPU +numbering starts at zero). The correct ``pin_cpus`` setting to use is +dependent on your CPU architecture (Intel and AMD systems enumerate +processors in different ways). Using the wrong ``pin_cpus`` setting +can cause poor performance. Here is what a worker node entry should +look like when using PF_RING and CPU pinning:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=eth0 + lb_method=pf_ring + lb_procs=10 + pin_cpus=2,3,4,5,6,7,8,9,10,11 + + +Using PF_RING+DNA with symmetric RSS +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You must have a PF_RING+DNA license in order to do this. You can sniff +each packet only once. + +1. Load the DNA NIC driver (i.e. ixgbe) on each worker host. + +2. Run "ethtool -L dna0 combined 10" (this will establish 10 RSS queues + on your NIC) on each worker host. You must make sure that you set the + number of RSS queues to the same as the number you specify for the + lb_procs option in the node.cfg file. + +3. On the manager, configure your worker(s) in node.cfg:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=dna0 + lb_method=pf_ring + lb_procs=10 + + +Using PF_RING+DNA with pfdnacluster_master +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You must have a PF_RING+DNA license and a libzero license in order to do +this. You can load balance between multiple applications and sniff the +same packets multiple times with different tools. + +1. Load the DNA NIC driver (i.e. ixgbe) on each worker host. + +2. Run "ethtool -L dna0 1" (this will establish 1 RSS queues on your NIC) + on each worker host. + +3. Run the pfdnacluster_master command on each worker host. For example:: + + pfdnacluster_master -c 21 -i dna0 -n 10 + + Make sure that your cluster ID (21 in this example) matches the interface + name you specify in the node.cfg file. Also make sure that the number + of processes you're balancing across (10 in this example) matches + the lb_procs option in the node.cfg file. + +4. If you are load balancing to other processes, you can use the + pfringfirstappinstance variable in broctl.cfg to set the first + application instance that Bro should use. For example, if you are running + pfdnacluster_master with "-n 10,4" you would set + pfringfirstappinstance=4. Unfortunately that's still a global setting + in broctl.cfg at the moment but we may change that to something you can + set in node.cfg eventually. + +5. On the manager, configure your worker(s) in node.cfg:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=dnacluster:21 + lb_method=pf_ring + lb_procs=10 + diff --git a/doc/index.rst b/doc/index.rst index bab3d49204..6161ee1ff8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -15,6 +15,7 @@ Introduction Section cluster/index.rst install/index.rst quickstart/index.rst + configuration/index.rst .. @@ -30,6 +31,7 @@ Using Bro Section httpmonitor/index.rst broids/index.rst mimestats/index.rst + scripting/index.rst .. @@ -39,7 +41,6 @@ Reference Section .. toctree:: :maxdepth: 2 - scripting/index.rst frameworks/index.rst script-reference/index.rst components/index.rst diff --git a/doc/quickstart/index.rst b/doc/quickstart/index.rst index a61d0cc71d..173373c769 100644 --- a/doc/quickstart/index.rst +++ b/doc/quickstart/index.rst @@ -25,8 +25,8 @@ BroControl is an interactive shell for easily operating/managing Bro installations on a single system or even across multiple systems in a traffic-monitoring cluster. This section explains how to use BroControl to manage a stand-alone Bro installation. For instructions on how to -configure a Bro cluster, see the documentation for :doc:`BroControl -<../components/broctl/README>`. +configure a Bro cluster, see the :doc:`Cluster Configuration +<../configuration/index>` documentation. A Minimal Starting Configuration -------------------------------- @@ -234,7 +234,7 @@ is valid before installing it and then restarting the Bro instance: .. console:: [BroControl] > check - bro is ok. + bro scripts are ok. [BroControl] > install removing old policies in /usr/local/bro/spool/policy/site ... done. removing old policies in /usr/local/bro/spool/policy/auto ... done. @@ -250,15 +250,15 @@ is valid before installing it and then restarting the Bro instance: Now that the SSL notice is ignored, let's look at how to send an email on the SSH notice. The notice framework has a similar option called -``emailed_types``, but that can't differentiate between SSH servers and we -only want email for logins to certain ones. Then we come to the ``PolicyItem`` -record and ``policy`` set and realize that those are actually what get used -to implement the simple functionality of ``ignored_types`` and +``emailed_types``, but using that would generate email for all SSH servers and +we only want email for logins to certain ones. There is a ``policy`` hook +that is actually what is used to implement the simple functionality of +``ignored_types`` and ``emailed_types``, but it's extensible such that the condition and action taken on notices can be user-defined. -In ``local.bro``, let's add a new ``PolicyItem`` record to the ``policy`` set -that only takes the email action for SSH logins to a defined set of servers: +In ``local.bro``, let's define a new ``policy`` hook handler body +that takes the email action for SSH logins only for a defined set of servers: .. code:: bro @@ -276,9 +276,9 @@ that only takes the email action for SSH logins to a defined set of servers: You'll just have to trust the syntax for now, but what we've done is first declare our own variable to hold a set of watched addresses, -``watched_servers``; then added a record to the policy that will generate -an email on the condition that the predicate function evaluates to true, which -is whenever the notice type is an SSH login and the responding host stored +``watched_servers``; then added a hook handler body to the policy that will +generate an email whenever the notice type is an SSH login and the responding +host stored inside the ``Info`` record's connection field is in the set of watched servers. .. note:: Record field member access is done with the '$' character @@ -426,7 +426,7 @@ Running Bro Without Installing For developers that wish to run Bro directly from the ``build/`` directory (i.e., without performing ``make install``), they will have -to first adjust ``BROPATH`` and ``BROMAGIC`` to look for scripts and +to first adjust ``BROPATH`` to look for scripts and additional files inside the build directory. Sourcing either ``build/bro-path-dev.sh`` or ``build/bro-path-dev.csh`` as appropriate for the current shell accomplishes this and also augments your diff --git a/doc/scripting/framework_notice_shortcuts_01.bro b/doc/scripting/framework_notice_shortcuts_01.bro index cd51abd5b5..e637ce903e 100644 --- a/doc/scripting/framework_notice_shortcuts_01.bro +++ b/doc/scripting/framework_notice_shortcuts_01.bro @@ -2,7 +2,6 @@ @load base/protocols/ssh/ redef Notice::emailed_types += { - SSH::Interesting_Hostname_Login, - SSH::Login + SSH::Interesting_Hostname_Login }; diff --git a/doc/scripting/framework_notice_shortcuts_02.bro b/doc/scripting/framework_notice_shortcuts_02.bro index ac427ac8b7..a3301d138b 100644 --- a/doc/scripting/framework_notice_shortcuts_02.bro +++ b/doc/scripting/framework_notice_shortcuts_02.bro @@ -3,5 +3,4 @@ redef Notice::type_suppression_intervals += { [SSH::Interesting_Hostname_Login] = 1day, - [SSH::Login] = 12hrs, }; diff --git a/doc/scripting/index.rst b/doc/scripting/index.rst index b12330ceb4..99a4b4c987 100644 --- a/doc/scripting/index.rst +++ b/doc/scripting/index.rst @@ -87,7 +87,7 @@ Up until this point, the script has merely done some basic setup. With the next the script starts to define instructions to take in a given event. .. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/frameworks/files/detect-MHR.bro - :lines: 38-62 + :lines: 38-71 The workhorse of the script is contained in the event handler for ``file_hash``. The :bro:see:`file_hash` event allows scripts to access @@ -95,7 +95,7 @@ the information associated with a file for which Bro's file analysis framework h generated a hash. The event handler is passed the file itself as ``f``, the type of digest algorithm used as ``kind`` and the hash generated as ``hash``. -On line 3, an ``if`` statement is used to check for the correct type of hash, in this case +On line 34, an ``if`` statement is used to check for the correct type of hash, in this case a SHA1 hash. It also checks for a mime type we've defined as being of interest as defined in the constant ``match_file_types``. The comparison is made against the expression ``f$mime_type``, which uses the ``$`` dereference operator to check the value ``mime_type`` inside the variable ``f``. Once both @@ -113,22 +113,22 @@ this event continues and upon receipt of the values returned by the malware was first detected and the detection rate by splitting on an text space and storing the values returned in a local table variable. In line 12, if the table returned by ``split1`` has two entries, indicating a successful split, we store the detection -date in ``mhr_first_detected`` and the rate in ``mhr_detect_rate`` on lines 14 and 15 respectively +date in ``mhr_first_detected`` and the rate in ``mhr_detect_rate`` on lines 18 and 14 respectively using the appropriate conversion functions. From this point on, Bro knows it has seen a file transmitted which has a hash that has been seen by the Team Cymru Malware Hash Registry, the rest of the script is dedicated to producing a notice. -On line 17, the detection time is processed into a string representation and stored in +On line 19, the detection time is processed into a string representation and stored in ``readable_first_detected``. The script then compares the detection rate against the ``notice_threshold`` that was defined earlier. If the detection rate is high enough, the script -creates a concise description of the notice on line 22, a possible URL to check the sample against +creates a concise description of the notice on line 20, a possible URL to check the sample against ``virustotal.com``'s database, and makes the call to :bro:id:`NOTICE` to hand the relevant information off to the Notice framework. -In approximately 25 lines of code, Bro provides an amazing +In approximately a few dozen lines of code, Bro provides an amazing utility that would be incredibly difficult to implement and deploy -with other products. In truth, claiming that Bro does this in 25 -lines is a misdirection; there is a truly massive number of things +with other products. In truth, claiming that Bro does this in such a small +number of lines is a misdirection; there is a truly massive number of things going on behind-the-scenes in Bro, but it is the inclusion of the scripting language that gives analysts access to those underlying layers in a succinct and well defined manner. @@ -657,7 +657,7 @@ using a 20 bit subnet mask. Because this is a script that doesn't use any kind of network analysis, we can handle the event :bro:id:`bro_init` which is always -generated by Bro's core upon startup. On lines six and seven, two +generated by Bro's core upon startup. On lines five and six, two locally scoped vectors are created to hold our lists of subnets and IP addresses respectively. Then, using a set of nested ``for`` loops, we iterate over every subnet and every IP address and use an ``if`` @@ -760,7 +760,7 @@ string against which it will be tested to be on the right. In the sample above, two local variables are declared to hold our sample sentence and regular expression. Our regular expression in this case will return true if the string contains either the word -``quick`` or the word ``fox``. The ``if`` statement on line six uses +``quick`` or the word ``fox``. The ``if`` statement on line eight uses embedded matching and the ``in`` operator to check for the existence of the pattern within the string. If the statement resolves to true, :bro:id:`split` is called to break the string into separate pieces. @@ -947,7 +947,7 @@ Logging Framework when ``Log::write`` is called. Were there to be any name value pairs without the ``&log`` attribute, those fields would simply be ignored during logging but remain available for the lifespan of the variable. The next step is to create the logging -stream with :bro:id:`Log::create_stream` which takes a Log::ID and a +stream with :bro:id:`Log::create_stream` which takes a ``Log::ID`` and a record as its arguments. In this example, on line 25, we call the ``Log::create_stream`` method and pass ``Factor::LOG`` and the ``Factor::Info`` record as arguments. From here on out, if we issue @@ -1001,7 +1001,7 @@ filename for the current call to ``Log::write``. The definition for this function has to take as its parameters a ``Log::ID`` called id, a string called ``path`` and the appropriate record type for the logs called ``rec``. You can see the definition of ``mod5`` used in this example on -line one conforms to that requirement. The function simply returns +line 38 conforms to that requirement. The function simply returns ``factor-mod5`` if the factorial is divisible evenly by 5, otherwise, it returns ``factor-non5``. In the additional ``bro_init`` event handler, we define a locally scoped ``Log::Filter`` and assign it a @@ -1074,7 +1074,8 @@ make a call to :bro:id:`NOTICE` supplying it with an appropriate :bro:type:`Notice::Info` record. Often times the call to ``NOTICE`` includes just the ``Notice::Type``, and a concise message. There are however, significantly more options available when raising notices as -seen in the table below. The only field in the table below whose +seen in the definition of :bro:type:`Notice::Info`. The only field in +``Notice::Info`` whose attributes make it a required field is the ``note`` field. Still, good manners are always important and including a concise message in ``$msg`` and, where necessary, the contents of the connection record @@ -1086,57 +1087,6 @@ that are commonly included, ``$identifier`` and ``$suppress_for`` are built around the automated suppression feature of the Notice Framework which we will cover shortly. -.. todo:: - - Once the link to ``Notice::Info`` work I think we should take out - the table. That's too easy to get out of date. - -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| Field | Type | Attributes | Use | -+=====================+==================================================================+================+========================================+ -| ts | time | &log &optional | The time of the notice | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| uid | string | &log &optional | A unique connection ID | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| id | conn_id | &log &optional | A 4-tuple to identify endpoints | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| conn | connection | &optional | Shorthand for the uid and id | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| iconn | icmp_conn | &optional | Shorthand for the uid and id | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| proto | transport_proto | &log &optional | Transport protocol | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| note | Notice::Type | &log | The Notice::Type of the notice | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| msg | string | &log &optional | Human readable message | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| sub | string | &log &optional | Human readable message | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| src | addr | &log &optional | Source address if no conn_id | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| dst | addr | &log &optional | Destination addr if no conn_id | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| p | port | &log &optional | Port if no conn_id | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| n | count | &log &optional | Count or status code | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| src_peer | event_peer | &log &optional | Peer that raised the notice | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| peer_descr | string | &log &optional | Text description of the src_peer | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| actions | set[Notice::Action] | &log &optional | Actions applied to the notice | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| policy_items | set[count] | &log &optional | Policy items that have been applied | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| email_body_sections | vector | &optional | Body of the email for email notices. | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| email_delay_tokens | set[string] | &optional | Delay functionality for email notices. | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| identifier | string | &optional | A unique string identifier | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ -| suppress_for | interval | &log &optional | Length of time to suppress a notice. | -+---------------------+------------------------------------------------------------------+----------------+----------------------------------------+ - One of the default policy scripts raises a notice when an SSH login has been heuristically detected and the originating hostname is one that would raise suspicion. Effectively, the script attempts to @@ -1153,7 +1103,7 @@ possible while staying concise. While much of the script relates to the actual detection, the parts specific to the Notice Framework are actually quite interesting in -themselves. On line 18 the script's ``export`` block adds the value +themselves. On line 13 the script's ``export`` block adds the value ``SSH::Interesting_Hostname_Login`` to the enumerable constant ``Notice::Type`` to indicate to the Bro core that a new type of notice is being defined. The script then calls ``NOTICE`` and defines the @@ -1222,7 +1172,7 @@ from the connection relative to the behavior that has been observed by Bro. .. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ssl/expiring-certs.bro - :lines: 60-63 + :lines: 64-68 In the :doc:`/scripts/policy/protocols/ssl/expiring-certs.bro` script which identifies when SSL certificates are set to expire and raises @@ -1302,9 +1252,9 @@ in the call to ``NOTICE``. .. btest-include:: ${DOC_ROOT}/scripting/framework_notice_shortcuts_01.bro -The Notice Policy shortcut above adds the ``Notice::Types`` of -SSH::Interesting_Hostname_Login and SSH::Login to the -Notice::emailed_types set while the shortcut below alters the length +The Notice Policy shortcut above adds the ``Notice::Type`` of +``SSH::Interesting_Hostname_Login`` to the +``Notice::emailed_types`` set while the shortcut below alters the length of time for which those notices will be suppressed. .. btest-include:: ${DOC_ROOT}/scripting/framework_notice_shortcuts_02.bro diff --git a/scripts/base/frameworks/logging/writers/ascii.bro b/scripts/base/frameworks/logging/writers/ascii.bro index 50ce450bce..5f59229f7f 100644 --- a/scripts/base/frameworks/logging/writers/ascii.bro +++ b/scripts/base/frameworks/logging/writers/ascii.bro @@ -26,20 +26,20 @@ export { ## This option is also available as a per-filter ``$config`` option. const use_json = F &redef; - ## Format of timestamps when writing out JSON. By default, the JSON formatter will - ## use double values for timestamps which represent the number of seconds from the - ## UNIX epoch. + ## Format of timestamps when writing out JSON. By default, the JSON + ## formatter will use double values for timestamps which represent the + ## number of seconds from the UNIX epoch. const json_timestamps: JSON::TimestampFormat = JSON::TS_EPOCH &redef; ## If true, include lines with log meta information such as column names ## with types, the values of ASCII logging options that are in use, and ## the time when the file was opened and closed (the latter at the end). - ## + ## ## If writing in JSON format, this is implicitly disabled. const include_meta = T &redef; ## Prefix for lines with meta information. - ## + ## ## This option is also available as a per-filter ``$config`` option. const meta_prefix = "#" &redef; diff --git a/scripts/base/frameworks/notice/main.bro b/scripts/base/frameworks/notice/main.bro index 8bf42a33e0..4790245de0 100644 --- a/scripts/base/frameworks/notice/main.bro +++ b/scripts/base/frameworks/notice/main.bro @@ -20,7 +20,8 @@ export { ## category along with the specific notice separating words with ## underscores and using leading capitals on each word except for ## abbreviations which are kept in all capitals. For example, - ## SSH::Login is for heuristically guessed successful SSH logins. + ## SSH::Password_Guessing is for hosts that have crossed a threshold of + ## heuristically determined failed SSH logins. type Type: enum { ## Notice reporting a count of how often a notice occurred. Tally, diff --git a/scripts/base/frameworks/notice/weird.bro b/scripts/base/frameworks/notice/weird.bro index e7faf38df4..474f021cef 100644 --- a/scripts/base/frameworks/notice/weird.bro +++ b/scripts/base/frameworks/notice/weird.bro @@ -185,6 +185,7 @@ export { ["RPC_underflow"] = ACTION_LOG, ["RST_storm"] = ACTION_LOG, ["RST_with_data"] = ACTION_LOG, + ["SSL_many_server_names"] = ACTION_LOG, ["simultaneous_open"] = ACTION_LOG_PER_CONN, ["spontaneous_FIN"] = ACTION_IGNORE, ["spontaneous_RST"] = ACTION_IGNORE, diff --git a/scripts/base/frameworks/signatures/main.bro b/scripts/base/frameworks/signatures/main.bro index f293237acc..5b233d1db1 100644 --- a/scripts/base/frameworks/signatures/main.bro +++ b/scripts/base/frameworks/signatures/main.bro @@ -71,7 +71,7 @@ export { ## to be logged has occurred. ts: time &log; ## A unique identifier of the connection which triggered the - ## signature match event + ## signature match event. uid: string &log &optional; ## The host which triggered the signature match event. src_addr: addr &log &optional; diff --git a/scripts/base/frameworks/software/main.bro b/scripts/base/frameworks/software/main.bro index c8f413a8f2..f5c9927126 100644 --- a/scripts/base/frameworks/software/main.bro +++ b/scripts/base/frameworks/software/main.bro @@ -287,6 +287,13 @@ function parse_mozilla(unparsed_version: string): Description if ( 2 in parts ) v = parse(parts[2])$version; } + else if ( / Java\/[0-9]\./ in unparsed_version ) + { + software_name = "Java"; + parts = split_all(unparsed_version, /Java\/[0-9\._]*/); + if ( 2 in parts ) + v = parse(parts[2])$version; + } return [$version=v, $unparsed_version=unparsed_version, $name=software_name]; } diff --git a/scripts/base/frameworks/sumstats/cluster.bro b/scripts/base/frameworks/sumstats/cluster.bro index 67c59a8728..b609abf472 100644 --- a/scripts/base/frameworks/sumstats/cluster.bro +++ b/scripts/base/frameworks/sumstats/cluster.bro @@ -28,10 +28,6 @@ export { ## values for a sumstat. global cluster_ss_request: event(uid: string, ss_name: string, cleanup: bool); - # Event sent by nodes that are collecting sumstats after receiving a - # request for the sumstat from the manager. - #global cluster_ss_response: event(uid: string, ss_name: string, data: ResultTable, done: bool, cleanup: bool); - ## This event is sent by the manager in a cluster to initiate the ## collection of a single key value from a sumstat. It's typically used ## to get intermediate updates before the break interval triggers to @@ -144,7 +140,7 @@ event SumStats::cluster_ss_request(uid: string, ss_name: string, cleanup: bool) sending_results[uid] = (ss_name in result_store) ? result_store[ss_name] : table(); # Lookup the actual sumstats and reset it, the reference to the data - # currently stored will be maintained internally from the + # currently stored will be maintained internally from the # sending_results table. if ( cleanup && ss_name in stats_store ) reset(stats_store[ss_name]); @@ -159,7 +155,7 @@ event SumStats::cluster_get_result(uid: string, ss_name: string, key: Key, clean if ( uid in sending_results && key in sending_results[uid] ) { # Note: copy is needed to compensate serialization caching issue. This should be - # changed to something else later. + # changed to something else later. event SumStats::cluster_send_result(uid, ss_name, key, copy(sending_results[uid][key]), cleanup); delete sending_results[uid][key]; } @@ -170,12 +166,12 @@ event SumStats::cluster_get_result(uid: string, ss_name: string, key: Key, clean event SumStats::cluster_send_result(uid, ss_name, key, table(), cleanup); } } - else + else { if ( ss_name in result_store && key in result_store[ss_name] ) { # Note: copy is needed to compensate serialization caching issue. This should be - # changed to something else later. + # changed to something else later. event SumStats::cluster_send_result(uid, ss_name, key, copy(result_store[ss_name][key]), cleanup); } else @@ -195,6 +191,19 @@ event SumStats::cluster_threshold_crossed(ss_name: string, key: SumStats::Key, t threshold_tracker[ss_name][key] = thold_index; } +# request-key is a non-op on the workers. +# It only should be called by the manager. Due to the fact that we usually run the same scripts on the +# workers and the manager, it might also be called by the workers, so we just ignore it here. +# +# There is a small chance that people will try running it on events that are just thrown on the workers. +# This does not work at the moment and we cannot throw an error message, because we cannot distinguish it +# from the "script is running it everywhere" case. But - people should notice that they do not get results. +# Not entirely pretty, sorry :( +function request_key(ss_name: string, key: Key): Result + { + return Result(); + } + @endif @@ -215,7 +224,6 @@ global stats_keys: table[string] of set[Key] &read_expire=1min # matches the number of peer nodes that results should be coming from, the # result is written out and deleted from here. # Indexed on a uid. -# TODO: add an &expire_func in case not all results are received. global done_with: table[string] of count &read_expire=1min &default=0; # This variable is maintained by managers to track intermediate responses as @@ -414,7 +422,7 @@ event SumStats::cluster_send_result(uid: string, ss_name: string, key: Key, resu # Mark that a worker is done. if ( uid !in done_with ) done_with[uid] = 0; - + #print fmt("MANAGER: got a result for %s %s from %s", uid, key, get_event_peer()$descr); ++done_with[uid]; diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index f68132e280..65d15dc2cf 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2812,7 +2812,7 @@ export { ## Result of an X509 certificate chain verification type Result: record { ## OpenSSL result code - result: count; + result: int; ## Result as string result_string: string; ## References to the final certificate chain, if verification successful. End-host certificate is first. @@ -2829,6 +2829,24 @@ export { name: string &optional; } &log; } + +module RADIUS; + +export { + type RADIUS::AttributeList: vector of string; + type RADIUS::Attributes: table[count] of RADIUS::AttributeList; + + type RADIUS::Message: record { + ## The type of message (Access-Request, Access-Accept, etc.). + code : count; + ## The transaction ID. + trans_id : count; + ## The "authenticator" string. + authenticator : string; + ## Any attributes. + attributes : RADIUS::Attributes &optional; + }; +} module GLOBAL; @load base/bif/plugins/Bro_SNMP.types.bif diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 8b276eff0d..a15258d0cd 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -47,6 +47,7 @@ @load base/protocols/irc @load base/protocols/modbus @load base/protocols/pop3 +@load base/protocols/radius @load base/protocols/sip @load base/protocols/snmp @load base/protocols/smtp diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index fe371de2a8..83c9682e8c 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -183,7 +183,7 @@ function log_unmatched_msgs(msgs: PendingMessages) for ( trans_id in msgs ) log_unmatched_msgs_queue(msgs[trans_id]); - msgs = PendingMessages(); + clear_table(msgs); } function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info) @@ -382,9 +382,19 @@ event dns_A_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priori hook DNS::do_reply(c, msg, ans, fmt("%s", a)); } -event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, str: string) &priority=5 +event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, strs: string_vec) &priority=5 { - hook DNS::do_reply(c, msg, ans, str); + local txt_strings: string = ""; + + for ( i in strs ) + { + if ( i > 0 ) + txt_strings += " "; + + txt_strings += fmt("TXT %d %s", |strs[i]|, strs[i]); + } + + hook DNS::do_reply(c, msg, ans, txt_strings); } event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priority=5 diff --git a/scripts/base/protocols/irc/dcc-send.bro b/scripts/base/protocols/irc/dcc-send.bro index d95eb97517..437724004a 100644 --- a/scripts/base/protocols/irc/dcc-send.bro +++ b/scripts/base/protocols/irc/dcc-send.bro @@ -76,7 +76,7 @@ event irc_dcc_message(c: connection, is_orig: bool, dcc_expected_transfers[address, p] = c$irc; } -event expected_connection_seen(c: connection, a: Analyzer::Tag) &priority=10 +event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10 { local id = c$id; if ( [id$resp_h, id$resp_p] in dcc_expected_transfers ) diff --git a/scripts/base/protocols/radius/__load__.bro b/scripts/base/protocols/radius/__load__.bro new file mode 100644 index 0000000000..a10fe855df --- /dev/null +++ b/scripts/base/protocols/radius/__load__.bro @@ -0,0 +1 @@ +@load ./main diff --git a/scripts/base/protocols/radius/consts.bro b/scripts/base/protocols/radius/consts.bro new file mode 100644 index 0000000000..2401998c87 --- /dev/null +++ b/scripts/base/protocols/radius/consts.bro @@ -0,0 +1,231 @@ + +module RADIUS; + +const msg_types: table[count] of string = { + [1] = "Access-Request", + [2] = "Access-Accept", + [3] = "Access-Reject", + [4] = "Accounting-Request", + [5] = "Accounting-Response", + [11] = "Access-Challenge", + [12] = "Status-Server", + [13] = "Status-Client", +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const attr_types: table[count] of string = { + [1] = "User-Name", + [2] = "User-Password", + [3] = "CHAP-Password", + [4] = "NAS-IP-Address", + [5] = "NAS-Port", + [6] = "Service-Type", + [7] = "Framed-Protocol", + [8] = "Framed-IP-Address", + [9] = "Framed-IP-Netmask", + [10] = "Framed-Routing", + [11] = "Filter-Id", + [12] = "Framed-MTU", + [13] = "Framed-Compression", + [14] = "Login-IP-Host", + [15] = "Login-Service", + [16] = "Login-TCP-Port", + [18] = "Reply-Message", + [19] = "Callback-Number", + [20] = "Callback-Id", + [22] = "Framed-Route", + [23] = "Framed-IPX-Network", + [24] = "State", + [25] = "Class", + [26] = "Vendor-Specific", + [27] = "Session-Timeout", + [28] = "Idle-Timeout", + [29] = "Termination-Action", + [30] = "Called-Station-Id", + [31] = "Calling-Station-Id", + [32] = "NAS-Identifier", + [33] = "Proxy-State", + [34] = "Login-LAT-Service", + [35] = "Login-LAT-Node", + [36] = "Login-LAT-Group", + [37] = "Framed-AppleTalk-Link", + [38] = "Framed-AppleTalk-Network", + [39] = "Framed-AppleTalk-Zone", + [40] = "Acct-Status-Type", + [41] = "Acct-Delay-Time", + [42] = "Acct-Input-Octets", + [43] = "Acct-Output-Octets", + [44] = "Acct-Session-Id", + [45] = "Acct-Authentic", + [46] = "Acct-Session-Time", + [47] = "Acct-Input-Packets", + [48] = "Acct-Output-Packets", + [49] = "Acct-Terminate-Cause", + [50] = "Acct-Multi-Session-Id", + [51] = "Acct-Link-Count", + [52] = "Acct-Input-Gigawords", + [53] = "Acct-Output-Gigawords", + [55] = "Event-Timestamp", + [56] = "Egress-VLANID", + [57] = "Ingress-Filters", + [58] = "Egress-VLAN-Name", + [59] = "User-Priority-Table", + [60] = "CHAP-Challenge", + [61] = "NAS-Port-Type", + [62] = "Port-Limit", + [63] = "Login-LAT-Port", + [64] = "Tunnel-Type", + [65] = "Tunnel-Medium-Type", + [66] = "Tunnel-Client-EndPoint", + [67] = "Tunnel-Server-EndPoint", + [68] = "Acct-Tunnel-Connection", + [69] = "Tunnel-Password", + [70] = "ARAP-Password", + [71] = "ARAP-Features", + [72] = "ARAP-Zone-Access", + [73] = "ARAP-Security", + [74] = "ARAP-Security-Data", + [75] = "Password-Retry", + [76] = "Prompt", + [77] = "Connect-Info", + [78] = "Configuration-Token", + [79] = "EAP-Message", + [80] = "Message Authenticator", + [81] = "Tunnel-Private-Group-ID", + [82] = "Tunnel-Assignment-ID", + [83] = "Tunnel-Preference", + [84] = "ARAP-Challenge-Response", + [85] = "Acct-Interim-Interval", + [86] = "Acct-Tunnel-Packets-Lost", + [87] = "NAS-Port-Id", + [88] = "Framed-Pool", + [89] = "CUI", + [90] = "Tunnel-Client-Auth-ID", + [91] = "Tunnel-Server-Auth-ID", + [92] = "NAS-Filter-Rule", + [94] = "Originating-Line-Info", + [95] = "NAS-IPv6-Address", + [96] = "Framed-Interface-Id", + [97] = "Framed-IPv6-Prefix", + [98] = "Login-IPv6-Host", + [99] = "Framed-IPv6-Route", + [100] = "Framed-IPv6-Pool", + [101] = "Error-Cause", + [102] = "EAP-Key-Name", + [103] = "Digest-Response", + [104] = "Digest-Realm", + [105] = "Digest-Nonce", + [106] = "Digest-Response-Auth", + [107] = "Digest-Nextnonce", + [108] = "Digest-Method", + [109] = "Digest-URI", + [110] = "Digest-Qop", + [111] = "Digest-Algorithm", + [112] = "Digest-Entity-Body-Hash", + [113] = "Digest-CNonce", + [114] = "Digest-Nonce-Count", + [115] = "Digest-Username", + [116] = "Digest-Opaque", + [117] = "Digest-Auth-Param", + [118] = "Digest-AKA-Auts", + [119] = "Digest-Domain", + [120] = "Digest-Stale", + [121] = "Digest-HA1", + [122] = "SIP-AOR", + [123] = "Delegated-IPv6-Prefix", + [124] = "MIP6-Feature-Vector", + [125] = "MIP6-Home-Link-Prefix", + [126] = "Operator-Name", + [127] = "Location-Information", + [128] = "Location-Data", + [129] = "Basic-Location-Policy-Rules", + [130] = "Extended-Location-Policy-Rules", + [131] = "Location-Capable", + [132] = "Requested-Location-Info", + [133] = "Framed-Management-Protocol", + [134] = "Management-Transport-Protection", + [135] = "Management-Policy-Id", + [136] = "Management-Privilege-Level", + [137] = "PKM-SS-Cert", + [138] = "PKM-CA-Cert", + [139] = "PKM-Config-Settings", + [140] = "PKM-Cryptosuite-List", + [141] = "PKM-SAID", + [142] = "PKM-SA-Descriptor", + [143] = "PKM-Auth-Key", + [144] = "DS-Lite-Tunnel-Name", + [145] = "Mobile-Node-Identifier", + [146] = "Service-Selection", + [147] = "PMIP6-Home-LMA-IPv6-Address", + [148] = "PMIP6-Visited-LMA-IPv6-Address", + [149] = "PMIP6-Home-LMA-IPv4-Address", + [150] = "PMIP6-Visited-LMA-IPv4-Address", + [151] = "PMIP6-Home-HN-Prefix", + [152] = "PMIP6-Visited-HN-Prefix", + [153] = "PMIP6-Home-Interface-ID", + [154] = "PMIP6-Visited-Interface-ID", + [155] = "PMIP6-Home-IPv4-HoA", + [156] = "PMIP6-Visited-IPv4-HoA", + [157] = "PMIP6-Home-DHCP4-Server-Address", + [158] = "PMIP6-Visited-DHCP4-Server-Address", + [159] = "PMIP6-Home-DHCP6-Server-Address", + [160] = "PMIP6-Visited-DHCP6-Server-Address", + [161] = "PMIP6-Home-IPv4-Gateway", + [162] = "PMIP6-Visited-IPv4-Gateway", + [163] = "EAP-Lower-Layer", + [164] = "GSS-Acceptor-Service-Name", + [165] = "GSS-Acceptor-Host-Name", + [166] = "GSS-Acceptor-Service-Specifics", + [167] = "GSS-Acceptor-Realm-Name", + [168] = "Framed-IPv6-Address", + [169] = "DNS-Server-IPv6-Address", + [170] = "Route-IPv6-Information", + [171] = "Delegated-IPv6-Prefix-Pool", + [172] = "Stateful-IPv6-Address-Pool", + [173] = "IPv6-6rd-Configuration" +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const nas_port_types: table[count] of string = { + [0] = "Async", + [1] = "Sync", + [2] = "ISDN Sync", + [3] = "ISDN Async V.120", + [4] = "ISDN Async V.110", + [5] = "Virtual", + [6] = "PIAFS", + [7] = "HDLC Clear Channel", + [8] = "X.25", + [9] = "X.75", + [10] = "G.3 Fax", + [11] = "SDSL - Symmetric DSL", + [12] = "ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase Modulation", + [13] = "ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone", + [14] = "IDSL - ISDN Digital Subscriber Line", + [15] = "Ethernet", + [16] = "xDSL - Digital Subscriber Line of unknown type", + [17] = "Cable", + [18] = "Wireless - Other", + [19] = "Wireless - IEEE 802.11" +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const service_types: table[count] of string = { + [1] = "Login", + [2] = "Framed", + [3] = "Callback Login", + [4] = "Callback Framed", + [5] = "Outbound", + [6] = "Administrative", + [7] = "NAS Prompt", + [8] = "Authenticate Only", + [9] = "Callback NAS Prompt", + [10] = "Call Check", + [11] = "Callback Administrative", +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const framed_protocol_types: table[count] of string = { + [1] = "PPP", + [2] = "SLIP", + [3] = "AppleTalk Remote Access Protocol (ARAP)", + [4] = "Gandalf proprietary SingleLink/MultiLink protocol", + [5] = "Xylogics proprietary IPX/SLIP", + [6] = "X.75 Synchronous" +} &default=function(i: count): string { return fmt("unknown-%d", i); }; diff --git a/scripts/base/protocols/radius/main.bro b/scripts/base/protocols/radius/main.bro new file mode 100644 index 0000000000..96d4bc1701 --- /dev/null +++ b/scripts/base/protocols/radius/main.bro @@ -0,0 +1,126 @@ +##! Implements base functionality for RADIUS analysis. Generates the radius.log file. + +module RADIUS; + +@load ./consts.bro +@load base/utils/addrs + +export { + redef enum Log::ID += { LOG }; + + type Info: record { + ## Timestamp for when the event happened. + ts : time &log; + ## Unique ID for the connection. + uid : string &log; + ## The connection's 4-tuple of endpoint addresses/ports. + id : conn_id &log; + ## The username, if present. + username : string &log &optional; + ## MAC address, if present. + mac : string &log &optional; + ## Remote IP address, if present. + remote_ip : addr &log &optional; + ## Connect info, if present. + connect_info : string &log &optional; + ## Successful or failed authentication. + result : string &log &optional; + ## Whether this has already been logged and can be ignored. + logged : bool &optional; + + }; + + ## The amount of time we wait for an authentication response before + ## expiring it. + const expiration_interval = 10secs &redef; + + ## Logs an authentication attempt if we didn't see a response in time. + ## + ## t: A table of Info records. + ## + ## idx: The index of the connection$radius table corresponding to the + ## radius authentication about to expire. + ## + ## Returns: 0secs, which when this function is used as an + ## :bro:attr:`&expire_func`, indicates to remove the element at + ## *idx* immediately. + global expire: function(t: table[count] of Info, idx: count): interval; + + ## Event that can be handled to access the RADIUS record as it is sent on + ## to the loggin framework. + global log_radius: event(rec: Info); +} + +redef record connection += { + radius: table[count] of Info &optional &write_expire=expiration_interval &expire_func=expire; +}; + +const ports = { 1812/udp }; + +event bro_init() &priority=5 + { + Log::create_stream(RADIUS::LOG, [$columns=Info, $ev=log_radius]); + Analyzer::register_for_ports(Analyzer::ANALYZER_RADIUS, ports); + } + +event radius_message(c: connection, result: RADIUS::Message) + { + local info: Info; + + if ( c?$radius && result$trans_id in c$radius ) + info = c$radius[result$trans_id]; + else + { + c$radius = table(); + info$ts = network_time(); + info$uid = c$uid; + info$id = c$id; + } + + switch ( RADIUS::msg_types[result$code] ) { + case "Access-Request": + if ( result?$attributes ) { + # User-Name + if ( ! info?$username && 1 in result$attributes ) + info$username = result$attributes[1][0]; + + # Calling-Station-Id (we expect this to be a MAC) + if ( ! info?$mac && 31 in result$attributes ) + info$mac = normalize_mac(result$attributes[31][0]); + + # Tunnel-Client-EndPoint (useful for VPNs) + if ( ! info?$remote_ip && 66 in result$attributes ) + info$remote_ip = to_addr(result$attributes[66][0]); + + # Connect-Info + if ( ! info?$connect_info && 77 in result$attributes ) + info$connect_info = result$attributes[77][0]; + } + + break; + + case "Access-Accept": + info$result = "success"; + break; + + case "Access-Reject": + info$result = "failed"; + break; + } + + if ( info?$result && ! info?$logged ) + { + info$logged = T; + Log::write(RADIUS::LOG, info); + } + + c$radius[result$trans_id] = info; + } + + +function expire(t: table[count] of Info, idx: count): interval + { + t[idx]$result = "unknown"; + Log::write(RADIUS::LOG, t[idx]); + return 0secs; + } diff --git a/scripts/base/protocols/smtp/files.bro b/scripts/base/protocols/smtp/files.bro index f9ae2ab05f..352c2025a3 100644 --- a/scripts/base/protocols/smtp/files.bro +++ b/scripts/base/protocols/smtp/files.bro @@ -41,13 +41,13 @@ function describe_file(f: fa_file): string event bro_init() &priority=5 { - Files::register_protocol(Analyzer::ANALYZER_SMTP, + Files::register_protocol(Analyzer::ANALYZER_SMTP, [$get_file_handle = SMTP::get_file_handle, $describe = SMTP::describe_file]); } event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5 { - if ( c?$smtp ) + if ( c?$smtp && !c$smtp$tls ) c$smtp$fuids[|c$smtp$fuids|] = f$id; } diff --git a/scripts/base/protocols/smtp/main.bro b/scripts/base/protocols/smtp/main.bro index d3bd8a97b4..a22d93d2fa 100644 --- a/scripts/base/protocols/smtp/main.bro +++ b/scripts/base/protocols/smtp/main.bro @@ -49,38 +49,40 @@ export { path: vector of addr &log &optional; ## Value of the User-Agent header from the client. user_agent: string &log &optional; - + + ## Indicates that the connection has switched to using TLS. + tls: bool &log &default=F; ## Indicates if the "Received: from" headers should still be ## processed. process_received_from: bool &default=T; ## Indicates if client activity has been seen, but not yet logged. has_client_activity: bool &default=F; }; - + type State: record { helo: string &optional; ## Count the number of individual messages transmitted during ## this SMTP session. Note, this is not the number of ## recipients, but the number of message bodies transferred. messages_transferred: count &default=0; - + pending_messages: set[Info] &optional; }; - + ## Direction to capture the full "Received from" path. ## REMOTE_HOSTS - only capture the path until an internal host is found. ## LOCAL_HOSTS - only capture the path until the external host is discovered. ## ALL_HOSTS - always capture the entire path. ## NO_HOSTS - never capture the path. const mail_path_capture = ALL_HOSTS &redef; - + ## Create an extremely shortened representation of a log line. global describe: function(rec: Info): string; global log_smtp: event(rec: Info); } -redef record connection += { +redef record connection += { smtp: Info &optional; smtp_state: State &optional; }; @@ -93,7 +95,7 @@ event bro_init() &priority=5 Log::create_stream(SMTP::LOG, [$columns=SMTP::Info, $ev=log_smtp]); Analyzer::register_for_ports(Analyzer::ANALYZER_SMTP, ports); } - + function find_address_in_smtp_header(header: string): string { local ips = find_ip_addresses(header); @@ -114,17 +116,17 @@ function new_smtp_log(c: connection): Info l$ts=network_time(); l$uid=c$uid; l$id=c$id; - # The messages_transferred count isn't incremented until the message is + # The messages_transferred count isn't incremented until the message is # finished so we need to increment the count by 1 here. l$trans_depth = c$smtp_state$messages_transferred+1; - + if ( c$smtp_state?$helo ) l$helo = c$smtp_state$helo; - + # The path will always end with the hosts involved in this connection. # The lower values in the vector are the end of the path. l$path = vector(c$id$resp_h, c$id$orig_h); - + return l; } @@ -132,7 +134,7 @@ function set_smtp_session(c: connection) { if ( ! c?$smtp_state ) c$smtp_state = []; - + if ( ! c?$smtp ) c$smtp = new_smtp_log(c); } @@ -140,17 +142,17 @@ function set_smtp_session(c: connection) function smtp_message(c: connection) { if ( c$smtp$has_client_activity ) + { Log::write(SMTP::LOG, c$smtp); + c$smtp = new_smtp_log(c); + } } - + event smtp_request(c: connection, is_orig: bool, command: string, arg: string) &priority=5 { set_smtp_session(c); local upper_command = to_upper(command); - if ( upper_command != "QUIT" ) - c$smtp$has_client_activity = T; - if ( upper_command == "HELO" || upper_command == "EHLO" ) { c$smtp_state$helo = arg; @@ -159,23 +161,28 @@ event smtp_request(c: connection, is_orig: bool, command: string, arg: string) & else if ( upper_command == "RCPT" && /^[tT][oO]:/ in arg ) { - if ( ! c$smtp?$rcptto ) + if ( ! c$smtp?$rcptto ) c$smtp$rcptto = set(); add c$smtp$rcptto[split1(arg, /:[[:blank:]]*/)[2]]; + c$smtp$has_client_activity = T; } else if ( upper_command == "MAIL" && /^[fF][rR][oO][mM]:/ in arg ) { + # Flush last message in case we didn't see the server's acknowledgement. + smtp_message(c); + local partially_done = split1(arg, /:[[:blank:]]*/)[2]; c$smtp$mailfrom = split1(partially_done, /[[:blank:]]?/)[1]; + c$smtp$has_client_activity = T; } } - + event smtp_reply(c: connection, is_orig: bool, code: count, cmd: string, msg: string, cont_resp: bool) &priority=5 { set_smtp_session(c); - + # This continually overwrites, but we want the last reply, # so this actually works fine. c$smtp$last_reply = fmt("%d %s", code, msg); @@ -196,7 +203,6 @@ event smtp_reply(c: connection, is_orig: bool, code: count, cmd: string, event mime_one_header(c: connection, h: mime_header_rec) &priority=5 { if ( ! c?$smtp ) return; - c$smtp$has_client_activity = T; if ( h$name == "MESSAGE-ID" ) c$smtp$msg_id = h$value; @@ -239,19 +245,19 @@ event mime_one_header(c: connection, h: mime_header_rec) &priority=5 if ( 1 in addresses ) c$smtp$x_originating_ip = to_addr(addresses[1]); } - + else if ( h$name == "X-MAILER" || h$name == "USER-AGENT" || h$name == "X-USER-AGENT" ) c$smtp$user_agent = h$value; } - -# This event handler builds the "Received From" path by reading the + +# This event handler builds the "Received From" path by reading the # headers in the mail event mime_one_header(c: connection, h: mime_header_rec) &priority=3 { # If we've decided that we're done watching the received headers for - # whatever reason, we're done. Could be due to only watching until + # whatever reason, we're done. Could be due to only watching until # local addresses are seen in the received from headers. if ( ! c?$smtp || h$name != "RECEIVED" || ! c$smtp$process_received_from ) return; @@ -261,7 +267,7 @@ event mime_one_header(c: connection, h: mime_header_rec) &priority=3 return; local ip = to_addr(text_ip); - if ( ! addr_matches_host(ip, mail_path_capture) && + if ( ! addr_matches_host(ip, mail_path_capture) && ! Site::is_private_addr(ip) ) { c$smtp$process_received_from = F; @@ -276,6 +282,15 @@ event connection_state_remove(c: connection) &priority=-5 smtp_message(c); } +event smtp_starttls(c: connection) &priority=5 + { + if ( c?$smtp ) + { + c$smtp$tls = T; + c$smtp$has_client_activity = T; + } + } + function describe(rec: Info): string { if ( rec?$mailfrom && rec?$rcptto ) diff --git a/scripts/base/protocols/snmp/main.bro b/scripts/base/protocols/snmp/main.bro index a2fbb23713..4921794408 100644 --- a/scripts/base/protocols/snmp/main.bro +++ b/scripts/base/protocols/snmp/main.bro @@ -1,15 +1,182 @@ -##! Enables analysis of SNMP datagrams. +##! Enables analysis and logging of SNMP datagrams. module SNMP; export { + redef enum Log::ID += { LOG }; + + ## Information tracked per SNMP session. + type Info: record { + ## Timestamp of first packet belonging to the SNMP session. + ts: time &log; + ## The unique ID for the connection. + uid: string &log; + ## The connection's 5-tuple of addresses/ports (ports inherently + ## include transport protocol information) + id: conn_id &log; + ## The amount of time between the first packet beloning to + ## the SNMP session and the latest one seen. + duration: interval &log &default=0secs; + ## The version of SNMP being used. + version: string &log; + ## The community string of the first SNMP packet associated with + ## the session. This is used as part of SNMP's (v1 and v2c) + ## administrative/security framework. See :rfc:`1157` or :rfc:`1901`. + community: string &log &optional; + + ## The number of variable bindings in GetRequest/GetNextRequest PDUs + ## seen for the session. + get_requests: count &log &default=0; + ## The number of variable bindings in GetBulkRequest PDUs seen for + ## the session. + get_bulk_requests: count &log &default=0; + ## The number of variable bindings in GetResponse/Response PDUs seen + ## for the session. + get_responses: count &log &default=0; + ## The number of variable bindings in SetRequest PDUs seen for + ## the session. + set_requests: count &log &default=0; + + ## A system description of the SNMP responder endpoint. + display_string: string &log &optional; + ## The time at which the SNMP responder endpoint claims it's been + ## up since. + up_since: time &log &optional; + }; + + ## Maps an SNMP version integer to a human readable string. + const version_map: table[count] of string = { + [0] = "1", + [1] = "2c", + [3] = "3", + } &redef &default="unknown"; + + ## Event that can be handled to access the SNMP record as it is sent on + ## to the logging framework. + global log_snmp: event(rec: Info); } -const ports = { 161/udp, 162/udp }; +redef record connection += { + snmp: SNMP::Info &optional; +}; +const ports = { 161/udp, 162/udp }; redef likely_server_ports += { ports }; event bro_init() &priority=5 { Analyzer::register_for_ports(Analyzer::ANALYZER_SNMP, ports); + Log::create_stream(SNMP::LOG, [$columns=SNMP::Info, $ev=log_snmp]); } + +function init_state(c: connection, h: SNMP::Header): Info + { + if ( ! c?$snmp ) + { + c$snmp = Info($ts=network_time(), + $uid=c$uid, $id=c$id, + $version=version_map[h$version]); + } + + local s = c$snmp; + + if ( ! s?$community ) + { + if ( h?$v1 ) + s$community = h$v1$community; + else if ( h?$v2 ) + s$community = h$v2$community; + } + + s$duration = network_time() - s$ts; + return s; + } + + +event connection_state_remove(c: connection) &priority=-5 + { + if ( c?$snmp ) + Log::write(LOG, c$snmp); + } + +event snmp_get_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + s$get_requests += |pdu$bindings|; + } + +event snmp_get_bulk_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::BulkPDU) &priority=5 + { + local s = init_state(c, header); + s$get_bulk_requests += |pdu$bindings|; + } + +event snmp_get_next_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + s$get_requests += |pdu$bindings|; + } + +event snmp_response(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + s$get_responses += |pdu$bindings|; + + for ( i in pdu$bindings ) + { + local binding = pdu$bindings[i]; + + if ( binding$oid == "1.3.6.1.2.1.1.1.0" && binding$value?$octets ) + c$snmp$display_string = binding$value$octets; + else if ( binding$oid == "1.3.6.1.2.1.1.3.0" && binding$value?$unsigned ) + { + local up_seconds = binding$value$unsigned / 100.0; + s$up_since = network_time() - double_to_interval(up_seconds); + } + } + } + +event snmp_set_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + s$set_requests += |pdu$bindings|; + } + +event snmp_trap(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::TrapPDU) &priority=5 + { + init_state(c, header); + } + +event snmp_inform_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + init_state(c, header); + } + +event snmp_trapV2(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + init_state(c, header); + } + +event snmp_report(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + init_state(c, header); + } + +event snmp_unknown_pdu(c: connection, is_orig: bool, header: SNMP::Header, tag: count) &priority=5 + { + init_state(c, header); + } + +event snmp_unknown_scoped_pdu(c: connection, is_orig: bool, header: SNMP::Header, tag: count) &priority=5 + { + init_state(c, header); + } + +event snmp_encrypted_pdu(c: connection, is_orig: bool, header: SNMP::Header) &priority=5 + { + init_state(c, header); + } + +#event snmp_unknown_header_version(c: connection, is_orig: bool, version: count) &priority=5 +# { +# } diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index 1ccace102c..a19aaecbe5 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -14,15 +14,41 @@ export { [TLSv11] = "TLSv11", [TLSv12] = "TLSv12", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - - ## Mapping between numeric codes and human readable strings for alert + + ## TLS content types: + const CHANGE_CIPHER_SPEC = 20; + const ALERT = 21; + const HANDSHAKE = 22; + const APPLICATION_DATA = 23; + const HEARTBEAT = 24; + const V2_ERROR = 300; + const V2_CLIENT_HELLO = 301; + const V2_CLIENT_MASTER_KEY = 302; + const V2_SERVER_HELLO = 304; + + ## TLS Handshake types: + const HELLO_REQUEST = 0; + const CLIENT_HELLO = 1; + const SERVER_HELLO = 2; + const SESSION_TICKET = 4; # RFC 5077 + const CERTIFICATE = 11; + const SERVER_KEY_EXCHANGE = 12; + const CERTIFICATE_REQUEST = 13; + const SERVER_HELLO_DONE = 14; + const CERTIFICATE_VERIFY = 15; + const CLIENT_KEY_EXCHANGE = 16; + const FINISHED = 20; + const CERTIFICATE_URL = 21; # RFC 3546 + const CERTIFICATE_STATUS = 22; # RFC 3546 + + ## Mapping between numeric codes and human readable strings for alert ## levels. const alert_levels: table[count] of string = { [1] = "warning", [2] = "fatal", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - - ## Mapping between numeric codes and human readable strings for alert + + ## Mapping between numeric codes and human readable strings for alert ## descriptions. const alert_descriptions: table[count] of string = { [0] = "close_notify", @@ -58,7 +84,7 @@ export { [115] = "unknown_psk_identity", [120] = "no_application_protocol", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - + ## Mapping between numeric codes and human readable strings for SSL/TLS ## extensions. # More information can be found here: @@ -83,6 +109,10 @@ export { [16] = "application_layer_protocol_negotiation", [17] = "status_request_v2", [18] = "signed_certificate_timestamp", + [19] = "client_certificate_type", + [20] = "server_certificate_type", + [21] = "padding", # temporary till 2015-03-12 + [22] = "encrypt_then_mac", # temporary till 2015-06-05 [35] = "SessionTicket TLS", [40] = "extended_random", [13172] = "next_protocol_negotiation", @@ -93,7 +123,50 @@ export { [35655] = "padding", [65281] = "renegotiation_info" } &default=function(i: count):string { return fmt("unknown-%d", i); }; - + + ## Mapping between numeric codes and human readable string for SSL/TLS elliptic curves. + # See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + const ec_curves: table[count] of string = { + [1] = "sect163k1", + [2] = "sect163r1", + [3] = "sect163r2", + [4] = "sect193r1", + [5] = "sect193r2", + [6] = "sect233k1", + [7] = "sect233r1", + [8] = "sect239k1", + [9] = "sect283k1", + [10] = "sect283r1", + [11] = "sect409k1", + [12] = "sect409r1", + [13] = "sect571k1", + [14] = "sect571r1", + [15] = "secp160k1", + [16] = "secp160r1", + [17] = "secp160r2", + [18] = "secp192k1", + [19] = "secp192r1", + [20] = "secp224k1", + [21] = "secp224r1", + [22] = "secp256k1", + [23] = "secp256r1", + [24] = "secp384r1", + [25] = "secp521r1", + [26] = "brainpoolP256r1", + [27] = "brainpoolP384r1", + [28] = "brainpoolP512r1", + [0xFF01] = "arbitrary_explicit_prime_curves", + [0xFF02] = "arbitrary_explicit_char2_curves" + } &default=function(i: count):string { return fmt("unknown-%d", i); }; + + ## Mapping between numeric codes and human readable string for SSL/TLC EC point formats. + # See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-9 + const ec_point_formats: table[count] of string = { + [0] = "uncompressed", + [1] = "ansiX962_compressed_prime", + [2] = "ansiX962_compressed_char2" + } &default=function(i: count):string { return fmt("unknown-%d", i); }; + # SSLv2 const SSLv20_CK_RC4_128_WITH_MD5 = 0x010080; const SSLv20_CK_RC4_128_EXPORT40_WITH_MD5 = 0x020080; @@ -444,6 +517,10 @@ export { const TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9; const TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA; const TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB; + const TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC; + const TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD; + const TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE; + const TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF; # draft-agl-tls-chacha20poly1305-02 const TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13; const TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14; @@ -458,8 +535,8 @@ export { const SSL_RSA_WITH_DES_CBC_MD5 = 0xFF82; const SSL_RSA_WITH_3DES_EDE_CBC_MD5 = 0xFF83; const TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; - - ## This is a table of all known cipher specs. It can be used for + + ## This is a table of all known cipher specs. It can be used for ## detecting unknown ciphers and for converting the cipher spec ## constants into a human readable format. const cipher_desc: table[count] of string = { @@ -807,6 +884,10 @@ export { [TLS_PSK_WITH_AES_256_CCM_8] = "TLS_PSK_WITH_AES_256_CCM_8", [TLS_PSK_DHE_WITH_AES_128_CCM_8] = "TLS_PSK_DHE_WITH_AES_128_CCM_8", [TLS_PSK_DHE_WITH_AES_256_CCM_8] = "TLS_PSK_DHE_WITH_AES_256_CCM_8", + [TLS_ECDHE_ECDSA_WITH_AES_128_CCM] = "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", + [TLS_ECDHE_ECDSA_WITH_AES_256_CCM] = "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", + [TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8] = "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", + [TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8] = "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", [TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256] = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", [TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256] = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", [TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256] = "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", @@ -820,43 +901,5 @@ export { [SSL_RSA_WITH_3DES_EDE_CBC_MD5] = "SSL_RSA_WITH_3DES_EDE_CBC_MD5", [TLS_EMPTY_RENEGOTIATION_INFO_SCSV] = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - - ## Mapping between the constants and string values for SSL/TLS errors. - const x509_errors: table[count] of string = { - [0] = "ok", - [1] = "unable to get issuer cert", - [2] = "unable to get crl", - [3] = "unable to decrypt cert signature", - [4] = "unable to decrypt crl signature", - [5] = "unable to decode issuer public key", - [6] = "cert signature failure", - [7] = "crl signature failure", - [8] = "cert not yet valid", - [9] = "cert has expired", - [10] = "crl not yet valid", - [11] = "crl has expired", - [12] = "error in cert not before field", - [13] = "error in cert not after field", - [14] = "error in crl last update field", - [15] = "error in crl next update field", - [16] = "out of mem", - [17] = "depth zero self signed cert", - [18] = "self signed cert in chain", - [19] = "unable to get issuer cert locally", - [20] = "unable to verify leaf signature", - [21] = "cert chain too long", - [22] = "cert revoked", - [23] = "invalid ca", - [24] = "path length exceeded", - [25] = "invalid purpose", - [26] = "cert untrusted", - [27] = "cert rejected", - [28] = "subject issuer mismatch", - [29] = "akid skid mismatch", - [30] = "akid issuer serial mismatch", - [31] = "keyusage no certsign", - [32] = "unable to get crl issuer", - [33] = "unhandled critical extension", - } &default=function(i: count):string { return fmt("unknown-%d", i); }; } diff --git a/scripts/base/protocols/ssl/files.bro b/scripts/base/protocols/ssl/files.bro index 6b33c0f87b..65f43ed772 100644 --- a/scripts/base/protocols/ssl/files.bro +++ b/scripts/base/protocols/ssl/files.bro @@ -52,22 +52,8 @@ export { function get_file_handle(c: connection, is_orig: bool): string { - set_session(c); - - local depth: count; - - if ( is_orig ) - { - depth = c$ssl$client_depth; - ++c$ssl$client_depth; - } - else - { - depth = c$ssl$server_depth; - ++c$ssl$server_depth; - } - - return cat(Analyzer::ANALYZER_SSL, c$start_time, is_orig, id_string(c$id), depth); + # Unused. File handles are generated in the analyzer. + return ""; } function describe_file(f: fa_file): string @@ -135,13 +121,15 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori event ssl_established(c: connection) &priority=6 { # update subject and issuer information - if ( c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 ) + if ( c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 && + c$ssl$cert_chain[0]?$x509 ) { c$ssl$subject = c$ssl$cert_chain[0]$x509$certificate$subject; c$ssl$issuer = c$ssl$cert_chain[0]$x509$certificate$issuer; } - if ( c$ssl?$client_cert_chain && |c$ssl$client_cert_chain| > 0 ) + if ( c$ssl?$client_cert_chain && |c$ssl$client_cert_chain| > 0 && + c$ssl$client_cert_chain[0]?$x509 ) { c$ssl$client_subject = c$ssl$client_cert_chain[0]$x509$certificate$subject; c$ssl$client_issuer = c$ssl$client_cert_chain[0]$x509$certificate$issuer; diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index 5b974222a1..f1315f8c85 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -19,6 +19,8 @@ export { version: string &log &optional; ## SSL/TLS cipher suite that the server chose. cipher: string &log &optional; + ## Elliptic curve the server chose when using ECDH/ECDHE. + curve: string &log &optional; ## Value of the Server Name Indicator SSL/TLS extension. It ## indicates the server name that the client was requesting. server_name: string &log &optional; @@ -159,12 +161,23 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, server_ c$ssl$cipher = cipher_desc[cipher]; } -event ssl_extension(c: connection, is_orig: bool, code: count, val: string) &priority=5 +event ssl_server_curve(c: connection, curve: count) &priority=5 { set_session(c); - if ( is_orig && extensions[code] == "server_name" ) - c$ssl$server_name = sub_bytes(val, 6, |val|); + c$ssl$curve = ec_curves[curve]; + } + +event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec) &priority=5 + { + set_session(c); + + if ( is_orig && |names| > 0 ) + { + c$ssl$server_name = names[0]; + if ( |names| > 1 ) + event conn_weird("SSL_many_server_names", c, cat(names)); + } } event ssl_alert(c: connection, is_orig: bool, level: count, desc: count) &priority=5 @@ -194,7 +207,7 @@ event connection_state_remove(c: connection) &priority=-5 event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5 { - if ( atype == Analyzer::ANALYZER_SSL ) + if ( atype == Analyzer::ANALYZER_SSL ) { set_session(c); c$ssl$analyzer_id = aid; diff --git a/scripts/base/utils/addrs.bro b/scripts/base/utils/addrs.bro index e2031e3efa..9e33e6d585 100644 --- a/scripts/base/utils/addrs.bro +++ b/scripts/base/utils/addrs.bro @@ -1,4 +1,4 @@ -##! Functions for parsing and manipulating IP addresses. +##! Functions for parsing and manipulating IP and MAC addresses. # Regular expressions for matching IP addresses in strings. const ipv4_addr_regex = /[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/; @@ -14,13 +14,13 @@ const ipv6_compressed_hex4dec_regex = /(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?) # ipv6_compressed_hex4dec_regex; #const ip_addr_regex = ipv4_addr_regex | ipv6_addr_regex; -const ipv6_addr_regex = +const ipv6_addr_regex = /([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}/ | /(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)/ | # IPv6 Compressed Hex /(([0-9A-Fa-f]{1,4}:){6,6})([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/ | # 6Hex4Dec /(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}:)*)([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/; # CompressedHex4Dec -const ip_addr_regex = +const ip_addr_regex = /[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/ | /([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}/ | /(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)/ | # IPv6 Compressed Hex @@ -57,7 +57,7 @@ function is_valid_ip(ip_str: string): bool octets = split(ip_str, /\./); if ( |octets| != 4 ) return F; - + return has_valid_octets(octets); } else if ( ip_str == ipv6_addr_regex ) @@ -119,3 +119,30 @@ function addr_to_uri(a: addr): string else return fmt("[%s]", a); } + +## Given a string, extracts the hex digits and returns a MAC address in +## the format: 00:a0:32:d7:81:8f. If the string doesn't contain 12 or 16 hex +## digits, an empty string is returned. +## +## a: the string to normalize. +## +## Returns: a normalized MAC address, or an empty string in the case of an error. +function normalize_mac(a: string): string + { + local result = to_lower(gsub(a, /[^A-Fa-f0-9]/, "")); + local octets: string_vec; + + if ( |result| == 12 ) + { + octets = str_split(result, vector(2, 4, 6, 8, 10)); + return fmt("%s:%s:%s:%s:%s:%s", octets[1], octets[2], octets[3], octets[4], octets[5], octets[6]); + } + + if ( |result| == 16 ) + { + octets = str_split(result, vector(2, 4, 6, 8, 10, 12, 14)); + return fmt("%s:%s:%s:%s:%s:%s:%s:%s", octets[1], octets[2], octets[3], octets[4], octets[5], octets[6], octets[7], octets[8]); + } + + return ""; + } diff --git a/scripts/policy/frameworks/intel/seen/http-headers.bro b/scripts/policy/frameworks/intel/seen/http-headers.bro index 2a74548023..a961896640 100644 --- a/scripts/policy/frameworks/intel/seen/http-headers.bro +++ b/scripts/policy/frameworks/intel/seen/http-headers.bro @@ -8,11 +8,17 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) { switch ( name ) { - case "HOST": - Intel::seen([$indicator=value, - $indicator_type=Intel::DOMAIN, - $conn=c, - $where=HTTP::IN_HOST_HEADER]); + case "HOST": + if ( is_valid_ip(value) ) + Intel::seen([$host=to_addr(value), + $indicator_type=Intel::ADDR, + $conn=c, + $where=HTTP::IN_HOST_HEADER]); + else + Intel::seen([$indicator=value, + $indicator_type=Intel::DOMAIN, + $conn=c, + $where=HTTP::IN_HOST_HEADER]); break; case "REFERER": diff --git a/scripts/policy/frameworks/intel/seen/ssl.bro b/scripts/policy/frameworks/intel/seen/ssl.bro index c41dbbdbe1..70c70f5b71 100644 --- a/scripts/policy/frameworks/intel/seen/ssl.bro +++ b/scripts/policy/frameworks/intel/seen/ssl.bro @@ -2,10 +2,9 @@ @load base/protocols/ssl @load ./where-locations -event ssl_extension(c: connection, is_orig: bool, code: count, val: string) +event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec) { - if ( is_orig && SSL::extensions[code] == "server_name" && - c?$ssl && c$ssl?$server_name ) + if ( is_orig && c?$ssl && c$ssl?$server_name ) Intel::seen([$indicator=c$ssl$server_name, $indicator_type=Intel::DOMAIN, $conn=c, diff --git a/scripts/policy/misc/app-stats/plugins/__load__.bro b/scripts/policy/misc/app-stats/plugins/__load__.bro index 7a3ea2da81..64126764fb 100644 --- a/scripts/policy/misc/app-stats/plugins/__load__.bro +++ b/scripts/policy/misc/app-stats/plugins/__load__.bro @@ -1,6 +1,6 @@ @load ./facebook -@load ./gmail -@load ./google -@load ./netflix -@load ./pandora -@load ./youtube \ No newline at end of file +#@load ./gmail +#@load ./google +#@load ./netflix +#@load ./pandora +#@load ./youtube diff --git a/scripts/policy/misc/load-balancing.bro b/scripts/policy/misc/load-balancing.bro index c2adf23f09..ba770ae1af 100644 --- a/scripts/policy/misc/load-balancing.bro +++ b/scripts/policy/misc/load-balancing.bro @@ -82,7 +82,7 @@ event bro_init() &priority=5 ++lb_proc_track[that_node$ip, that_node$interface]; if ( total_lb_procs > 1 ) { - that_node$lb_filter = PacketFilter::sample_filter(total_lb_procs, this_lb_proc); + that_node$lb_filter = PacketFilter::sampling_filter(total_lb_procs, this_lb_proc); Communication::nodes[no]$capture_filter = that_node$lb_filter; } } diff --git a/scripts/policy/protocols/ssl/expiring-certs.bro b/scripts/policy/protocols/ssl/expiring-certs.bro index 9c02c63784..04ebeb3c5a 100644 --- a/scripts/policy/protocols/ssl/expiring-certs.bro +++ b/scripts/policy/protocols/ssl/expiring-certs.bro @@ -38,27 +38,32 @@ event ssl_established(c: connection) &priority=3 { # If there are no certificates or we are not interested in the server, just return. if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || - ! addr_matches_host(c$id$resp_h, notify_certs_expiration) ) + ! addr_matches_host(c$id$resp_h, notify_certs_expiration) || + ! c$ssl$cert_chain[0]?$x509 || ! c$ssl$cert_chain[0]?$sha1 ) return; local fuid = c$ssl$cert_chain_fuids[0]; local cert = c$ssl$cert_chain[0]$x509$certificate; + local hash = c$ssl$cert_chain[0]$sha1; if ( cert$not_valid_before > network_time() ) NOTICE([$note=Certificate_Not_Valid_Yet, $conn=c, $suppress_for=1day, $msg=fmt("Certificate %s isn't valid until %T", cert$subject, cert$not_valid_before), + $identifier=cat(c$id$resp_h, c$id$resp_p, hash), $fuid=fuid]); else if ( cert$not_valid_after < network_time() ) NOTICE([$note=Certificate_Expired, $conn=c, $suppress_for=1day, $msg=fmt("Certificate %s expired at %T", cert$subject, cert$not_valid_after), + $identifier=cat(c$id$resp_h, c$id$resp_p, hash), $fuid=fuid]); else if ( cert$not_valid_after - notify_when_cert_expiring_in < network_time() ) NOTICE([$note=Certificate_Expires_Soon, $msg=fmt("Certificate %s is going to expire at %T", cert$subject, cert$not_valid_after), $conn=c, $suppress_for=1day, + $identifier=cat(c$id$resp_h, c$id$resp_p, hash), $fuid=fuid]); } diff --git a/scripts/policy/protocols/ssl/extract-certs-pem.bro b/scripts/policy/protocols/ssl/extract-certs-pem.bro index 549c6943e6..18de3cbb7d 100644 --- a/scripts/policy/protocols/ssl/extract-certs-pem.bro +++ b/scripts/policy/protocols/ssl/extract-certs-pem.bro @@ -29,7 +29,8 @@ global extracted_certs: set[string] = set() &read_expire=1hr &redef; event ssl_established(c: connection) &priority=5 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$x509 ) return; if ( ! addr_matches_host(c$id$resp_h, extract_certs_pem) ) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro new file mode 100644 index 0000000000..77a5e9832a --- /dev/null +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -0,0 +1,238 @@ +##! Detect the TLS heartbleed attack. See http://heartbleed.com for more. + +@load base/protocols/ssl +@load base/frameworks/notice + +module Heartbleed; + +export { + redef enum Notice::Type += { + ## Indicates that a host performed a heartbleed attack or scan. + SSL_Heartbeat_Attack, + ## Indicates that a host performing a heartbleed attack was probably successful. + SSL_Heartbeat_Attack_Success, + ## Indicates we saw heartbeat requests with odd length. Probably an attack or scan. + SSL_Heartbeat_Odd_Length, + ## Indicates we saw many heartbeat requests without an reply. Might be an attack. + SSL_Heartbeat_Many_Requests + }; +} + +# Do not disable analyzers after detection - otherwhise we will not notice +# encrypted attacks. +redef SSL::disable_analyzer_after_detection=F; + +redef record SSL::Info += { + last_originator_heartbeat_request_size: count &optional; + last_responder_heartbeat_request_size: count &optional; + + originator_heartbeats: count &default=0; + responder_heartbeats: count &default=0; + + # Unencrypted connections - was an exploit attempt detected yet. + heartbleed_detected: bool &default=F; + + # Count number of appdata packages and bytes exchanged so far. + enc_appdata_packages: count &default=0; + enc_appdata_bytes: count &default=0; +}; + +type min_length: record { + cipher: pattern; + min_length: count; +}; + +global min_lengths: vector of min_length = vector(); +global min_lengths_tls11: vector of min_length = vector(); + +event bro_init() + { + # Minimum length a heartbeat packet must have for different cipher suites. + # Note - tls 1.1f and 1.0 have different lengths :( + # This should be all cipher suites usually supported by vulnerable servers. + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_AES_256_GCM_SHA384$/, $min_length=43]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_AES_128_GCM_SHA256$/, $min_length=43]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA384$/, $min_length=96]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA256$/, $min_length=80]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA$/, $min_length=64]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_128_CBC_SHA256$/, $min_length=80]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_128_CBC_SHA$/, $min_length=64]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_SEED_CBC_SHA$/, $min_length=64]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_IDEA_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_DES_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_DES40_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_128_SHA$/, $min_length=39]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_128_MD5$/, $min_length=35]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_40_MD5$/, $min_length=35]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC2_CBC_40_MD5$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_256_CBC_SHA$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_128_CBC_SHA$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_SEED_CBC_SHA$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_IDEA_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_DES_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_DES40_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_RC4_128_SHA$/, $min_length=39]; + min_lengths[|min_lengths|] = [$cipher=/_RC4_128_MD5$/, $min_length=35]; + min_lengths[|min_lengths|] = [$cipher=/_RC4_40_MD5$/, $min_length=35]; + min_lengths[|min_lengths|] = [$cipher=/_RC2_CBC_40_MD5$/, $min_length=40]; + } + +event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string) + { + if ( ! c?$ssl ) + return; + + if ( heartbeat_type == 1 ) + { + local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); + + if ( payload_length > checklength ) + { + c$ssl$heartbleed_detected = T; + NOTICE([$note=Heartbleed::SSL_Heartbeat_Attack, + $msg=fmt("An TLS heartbleed attack was detected! Record length %d. Payload length %d", length, payload_length), + $conn=c, + $identifier=cat(c$uid, length, payload_length) + ]); + } + else if ( is_orig ) + { + NOTICE([$note=Heartbleed::SSL_Heartbeat_Attack, + $msg=fmt("Heartbeat request before encryption. Probable Scan without exploit attempt. Message length: %d. Payload length: %d", length, payload_length), + $conn=c, + $n=length, + $identifier=cat(c$uid, length) + ]); + } + } + + if ( heartbeat_type == 2 && c$ssl$heartbleed_detected ) + { + NOTICE([$note=Heartbleed::SSL_Heartbeat_Attack_Success, + $msg=fmt("An TLS heartbleed attack detected before was probably exploited. Message length: %d. Payload length: %d", length, payload_length), + $conn=c, + $identifier=c$uid + ]); + } + } + +event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) + { + if ( is_orig ) + ++c$ssl$originator_heartbeats; + else + ++c$ssl$responder_heartbeats; + + local duration = network_time() - c$start_time; + + if ( c$ssl$enc_appdata_packages == 0 ) + NOTICE([$note=SSL_Heartbeat_Attack, + $msg=fmt("Heartbeat before ciphertext. Probable attack or scan. Length: %d, is_orig: %d", length, is_orig), + $conn=c, + $n=length, + $identifier=fmt("%s%s", c$uid, "early") + ]); + else if ( duration < 1min ) + NOTICE([$note=SSL_Heartbeat_Attack, + $msg=fmt("Heartbeat within first minute. Possible attack or scan. Length: %d, is_orig: %d, time: %s", length, is_orig, duration), + $conn=c, + $n=length, + $identifier=fmt("%s%s", c$uid, "early") + ]); + + if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) + NOTICE([$note=SSL_Heartbeat_Many_Requests, + $msg=fmt("More than 3 heartbeat requests without replies from server. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), + $conn=c, + $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats), + $identifier=fmt("%s%d", c$uid, c$ssl$responder_heartbeats/1000) # re-throw every 1000 heartbeats + ]); + + if ( c$ssl$responder_heartbeats > c$ssl$originator_heartbeats + 3 ) + NOTICE([$note=SSL_Heartbeat_Many_Requests, + $msg=fmt("Server sending more heartbeat responses than requests seen. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), + $conn=c, + $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats), + $identifier=fmt("%s%d", c$uid, c$ssl$responder_heartbeats/1000) # re-throw every 1000 heartbeats + ]); + + if ( is_orig && length < 19 ) + NOTICE([$note=SSL_Heartbeat_Odd_Length, + $msg=fmt("Heartbeat message smaller than minimum required length. Probable attack or scan. Message length: %d. Cipher: %s. Time: %f", length, c$ssl$cipher, duration), + $conn=c, + $n=length, + $identifier=fmt("%s-weak-%d", c$uid, length) + ]); + + # Examine request lengths based on used cipher... + local min_length_choice: vector of min_length; + if ( (c$ssl$version == "TLSv11") || (c$ssl$version == "TLSv12") ) # tls 1.1+ have different lengths for CBC + min_length_choice = min_lengths_tls11; + else + min_length_choice = min_lengths; + + for ( i in min_length_choice ) + { + if ( min_length_choice[i]$cipher in c$ssl$cipher ) + { + if ( length < min_length_choice[i]$min_length ) + { + NOTICE([$note=SSL_Heartbeat_Odd_Length, + $msg=fmt("Heartbeat message smaller than minimum required length. Probable attack. Message length: %d. Required length: %d. Cipher: %s. Cipher match: %s", length, min_length_choice[i]$min_length, c$ssl$cipher, min_length_choice[i]$cipher), + $conn=c, + $n=length, + $identifier=fmt("%s-weak-%d", c$uid, length) + ]); + } + + break; + } + + } + + if ( is_orig ) + { + if ( c$ssl?$last_responder_heartbeat_request_size ) + { + # server originated heartbeat. Ignore & continue + delete c$ssl$last_responder_heartbeat_request_size; + } + + else + c$ssl$last_originator_heartbeat_request_size = length; + } + else + { + if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size < length ) + { + NOTICE([$note=SSL_Heartbeat_Attack_Success, + $msg=fmt("An encrypted TLS heartbleed attack was probably detected! First packet client record length %d, first packet server record length %d. Time: %f", + c$ssl$last_originator_heartbeat_request_size, length, duration), + $conn=c, + $identifier=c$uid # only throw once per connection + ]); + } + + else if ( ! c$ssl?$last_originator_heartbeat_request_size ) + c$ssl$last_responder_heartbeat_request_size = length; + + if ( c$ssl?$last_originator_heartbeat_request_size ) + delete c$ssl$last_originator_heartbeat_request_size; + } + } + +event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, length: count) + { + if ( !c?$ssl ) + return; + + if ( content_type == SSL::HEARTBEAT ) + event ssl_encrypted_heartbeat(c, is_orig, length); + else if ( (content_type == SSL::APPLICATION_DATA) && (length > 0) ) + { + ++c$ssl$enc_appdata_packages; + c$ssl$enc_appdata_bytes += length; + } + } diff --git a/scripts/policy/protocols/ssl/known-certs.bro b/scripts/policy/protocols/ssl/known-certs.bro index 739b11e767..298c665459 100644 --- a/scripts/policy/protocols/ssl/known-certs.bro +++ b/scripts/policy/protocols/ssl/known-certs.bro @@ -48,7 +48,8 @@ event bro_init() &priority=5 event ssl_established(c: connection) &priority=3 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| < 1 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| < 1 || + ! c$ssl$cert_chain[0]?$x509 ) return; local fuid = c$ssl$cert_chain_fuids[0]; diff --git a/scripts/policy/protocols/ssl/notary.bro b/scripts/policy/protocols/ssl/notary.bro index 3646a4d43e..e2b0bb2faf 100644 --- a/scripts/policy/protocols/ssl/notary.bro +++ b/scripts/policy/protocols/ssl/notary.bro @@ -39,7 +39,8 @@ function clear_waitlist(digest: string) event ssl_established(c: connection) &priority=3 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$sha1 ) return; local digest = c$ssl$cert_chain[0]$sha1; diff --git a/scripts/policy/protocols/ssl/validate-certs.bro b/scripts/policy/protocols/ssl/validate-certs.bro index de22e2d30d..414f0d2a54 100644 --- a/scripts/policy/protocols/ssl/validate-certs.bro +++ b/scripts/policy/protocols/ssl/validate-certs.bro @@ -28,7 +28,8 @@ export { event ssl_established(c: connection) &priority=3 { # If there aren't any certs we can't very well do certificate validation. - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$x509 ) return; local chain_id = join_string_vec(c$ssl$cert_chain_fuids, "."); @@ -36,7 +37,8 @@ event ssl_established(c: connection) &priority=3 local chain: vector of opaque of x509 = vector(); for ( i in c$ssl$cert_chain ) { - chain[i] = c$ssl$cert_chain[i]$x509$handle; + if ( c$ssl$cert_chain[i]?$x509 ) + chain[i] = c$ssl$cert_chain[i]$x509$handle; } if ( chain_id in recently_validated_certs ) @@ -49,7 +51,7 @@ event ssl_established(c: connection) &priority=3 c$ssl$validation_status = result$result_string; recently_validated_certs[chain_id] = result$result_string; } - + if ( c$ssl$validation_status != "ok" ) { local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status); diff --git a/scripts/policy/protocols/ssl/validate-ocsp.bro b/scripts/policy/protocols/ssl/validate-ocsp.bro new file mode 100644 index 0000000000..01b6853226 --- /dev/null +++ b/scripts/policy/protocols/ssl/validate-ocsp.bro @@ -0,0 +1,66 @@ +##! Perform OCSP response validation. + +@load base/frameworks/notice +@load base/protocols/ssl + +module SSL; + +export { + redef enum Notice::Type += { + ## This indicates that the OCSP response was not deemed + ## to be valid. + Invalid_Ocsp_Response + }; + + redef record Info += { + ## Result of ocsp validation for this connection. + ocsp_status: string &log &optional; + + ## ocsp response as string. + ocsp_response: string &optional; + }; + +} + +# MD5 hash values for recently validated chains along with the OCSP validation +# status are kept in this table to avoid constant validation every time the same +# certificate chain is seen. +global recently_ocsp_validated: table[string] of string = table() &read_expire=5mins; + +event ssl_stapled_ocsp(c: connection, is_orig: bool, response: string) &priority=3 + { + c$ssl$ocsp_response = response; + } + +event ssl_established(c: connection) &priority=3 + { + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || !c$ssl?$ocsp_response ) + return; + + local chain: vector of opaque of x509 = vector(); + for ( i in c$ssl$cert_chain ) + { + if ( c$ssl$cert_chain[i]?$x509 ) + chain[i] = c$ssl$cert_chain[i]$x509$handle; + } + + local reply_id = cat(md5_hash(c$ssl$ocsp_response), join_string_vec(c$ssl$cert_chain_fuids, ".")); + + if ( reply_id in recently_ocsp_validated ) + { + c$ssl$ocsp_status = recently_ocsp_validated[reply_id]; + return; + } + + local result = x509_ocsp_verify(chain, c$ssl$ocsp_response, root_certs); + c$ssl$ocsp_status = result$result_string; + recently_ocsp_validated[reply_id] = result$result_string; + + if( result$result_string != "good" ) + { + local message = fmt("OCSP response validation failed with (%s)", result$result_string); + NOTICE([$note=Invalid_Ocsp_Response, $msg=message, + $sub=c$ssl$subject, $conn=c, + $identifier=cat(c$id$resp_h,c$id$resp_p,c$ssl$ocsp_status)]); + } + } diff --git a/scripts/policy/protocols/ssl/weak-keys.bro b/scripts/policy/protocols/ssl/weak-keys.bro new file mode 100644 index 0000000000..f11fb9da5e --- /dev/null +++ b/scripts/policy/protocols/ssl/weak-keys.bro @@ -0,0 +1,92 @@ +##! Generate notices when SSL/TLS connections use certificates or DH parameters +##! that have potentially unsafe key lengths. + +@load base/protocols/ssl +@load base/frameworks/notice +@load base/utils/directions-and-hosts + +module SSL; + +export { + redef enum Notice::Type += { + ## Indicates that a server is using a potentially unsafe key. + Weak_Key, + }; + + ## The category of hosts you would like to be notified about which have + ## certificates that are going to be expiring soon. By default, these + ## notices will be suppressed by the notice framework for 1 day after a particular + ## certificate has had a notice generated. Choices are: LOCAL_HOSTS, REMOTE_HOSTS, + ## ALL_HOSTS, NO_HOSTS + const notify_weak_keys = LOCAL_HOSTS &redef; + + ## The minimal key length in bits that is considered to be safe. Any shorter + ## (non-EC) key lengths will trigger the notice. + const notify_minimal_key_length = 1024 &redef; + + ## Warn if the DH key length is smaller than the certificate key length. This is + ## potentially unsafe because it gives a wrong impression of safety due to the + ## certificate key length. However, it is very common and cannot be avoided in some + ## settings (e.g. with old jave clients). + const notify_dh_length_shorter_cert_length = T &redef; +} + +# We check key lengths only for DSA or RSA certificates. For others, we do +# not know what is safe (e.g. EC is safe even with very short key lengths). +event ssl_established(c: connection) &priority=3 + { + # If there are no certificates or we are not interested in the server, just return. + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! addr_matches_host(c$id$resp_h, notify_weak_keys) || + ! c$ssl$cert_chain[0]?$x509 ) + return; + + local fuid = c$ssl$cert_chain_fuids[0]; + local cert = c$ssl$cert_chain[0]$x509$certificate; + + if ( !cert?$key_type || !cert?$key_length ) + return; + + if ( cert$key_type != "dsa" && cert$key_type != "rsa" ) + return; + + local key_length = cert$key_length; + + if ( key_length < notify_minimal_key_length ) + NOTICE([$note=Weak_Key, + $msg=fmt("Host uses weak certificate with %d bit key", key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) + ]); + } + +event ssl_dh_server_params(c: connection, p: string, q: string, Ys: string) &priority=3 + { + if ( ! addr_matches_host(c$id$resp_h, notify_weak_keys) ) + return; + + local key_length = |Ys| * 8; # key length in bits + + if ( key_length < notify_minimal_key_length ) + NOTICE([$note=Weak_Key, + $msg=fmt("Host uses weak DH parameters with %d key bits", key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) + ]); + + if ( notify_dh_length_shorter_cert_length && + c?$ssl && c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 && c$ssl$cert_chain[0]?$x509 && + c$ssl$cert_chain[0]$x509?$certificate && c$ssl$cert_chain[0]$x509$certificate?$key_type && + (c$ssl$cert_chain[0]$x509$certificate$key_type == "rsa" || + c$ssl$cert_chain[0]$x509$certificate$key_type == "dsa" )) + { + if ( c$ssl$cert_chain[0]$x509$certificate?$key_length && + c$ssl$cert_chain[0]$x509$certificate$key_length > key_length ) + NOTICE([$note=Weak_Key, + $msg=fmt("DH key length of %d bits is smaller certificate key length of %d bits", + key_length, c$ssl$cert_chain[0]$x509$certificate$key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p) + ]); + } + } diff --git a/scripts/site/local.bro b/scripts/site/local.bro index e1a3574424..afe1d9d4f2 100644 --- a/scripts/site/local.bro +++ b/scripts/site/local.bro @@ -81,3 +81,6 @@ # Detect SHA1 sums in Team Cymru's Malware Hash Registry. @load frameworks/files/detect-MHR +# Uncomment the following line to enable detection of the heartbleed attack. Enabling +# this might impact performance a bit. +# @load policy/protocols/ssl/heartbleed diff --git a/scripts/test-all-policy.bro b/scripts/test-all-policy.bro index 895a9a8901..5ab596dbfb 100644 --- a/scripts/test-all-policy.bro +++ b/scripts/test-all-policy.bro @@ -85,10 +85,13 @@ @load protocols/ssh/software.bro @load protocols/ssl/expiring-certs.bro @load protocols/ssl/extract-certs-pem.bro +@load protocols/ssl/heartbleed.bro @load protocols/ssl/known-certs.bro @load protocols/ssl/log-hostcerts-only.bro #@load protocols/ssl/notary.bro @load protocols/ssl/validate-certs.bro +@load protocols/ssl/validate-ocsp.bro +@load protocols/ssl/weak-keys.bro @load tuning/__load__.bro @load tuning/defaults/__load__.bro @load tuning/defaults/extracted_file_limits.bro diff --git a/src/3rdparty b/src/3rdparty index 3b3e189dab..7e15efe9d2 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 3b3e189dab3801cd0474dfdd376d9de633cd3766 +Subproject commit 7e15efe9d28d46bfa662fcdd1cbb15ce1db285c9 diff --git a/src/Base64.cc b/src/Base64.cc index 50732534ab..e76621e634 100644 --- a/src/Base64.cc +++ b/src/Base64.cc @@ -104,7 +104,7 @@ Base64Converter::Base64Converter(analyzer::Analyzer* arg_analyzer, const string& Base64Converter::~Base64Converter() { if ( base64_table != default_base64_table ) - delete base64_table; + delete [] base64_table; } int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf) diff --git a/src/Conn.cc b/src/Conn.cc index fa89f26d35..bc62902421 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -811,6 +811,17 @@ void Connection::Describe(ODesc* d) const d->NL(); } +void Connection::IDString(ODesc* d) const + { + d->Add(orig_addr); + d->AddRaw(":", 1); + d->Add(ntohs(orig_port)); + d->AddRaw(" > ", 3); + d->Add(resp_addr); + d->AddRaw(":", 1); + d->Add(ntohs(resp_port)); + } + bool Connection::Serialize(SerialInfo* info) const { return SerialObj::Serialize(info); diff --git a/src/Conn.h b/src/Conn.h index d982d3879d..966c77a9f8 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -204,6 +204,7 @@ public: bool IsPersistent() { return persistent; } void Describe(ODesc* d) const; + void IDString(ODesc* d) const; TimerMgr* GetTimerMgr() const; diff --git a/src/DFA.cc b/src/DFA.cc index ad9521709e..dbfed71ba3 100644 --- a/src/DFA.cc +++ b/src/DFA.cc @@ -211,9 +211,10 @@ void DFA_State::Dump(FILE* f, DFA_Machine* m) if ( accept ) { - for ( int i = 0; i < accept->length(); ++i ) - fprintf(f, "%s accept #%d", - i > 0 ? "," : "", int((*accept)[i])); + AcceptingSet::const_iterator it; + + for ( it = accept->begin(); it != accept->end(); ++it ) + fprintf(f, "%s accept #%d", it == accept->begin() ? "" : ",", *it); } fprintf(f, "\n"); @@ -285,7 +286,7 @@ unsigned int DFA_State::Size() { return sizeof(*this) + pad_size(sizeof(DFA_State*) * num_sym) - + (accept ? pad_size(sizeof(int) * accept->length()) : 0) + + (accept ? pad_size(sizeof(int) * accept->size()) : 0) + (nfa_states ? pad_size(sizeof(NFA_State*) * nfa_states->length()) : 0) + (meta_ec ? meta_ec->Size() : 0) + (centry ? padded_sizeof(CacheEntry) : 0); @@ -470,33 +471,20 @@ int DFA_Machine::StateSetToDFA_State(NFA_state_list* state_set, return 0; AcceptingSet* accept = new AcceptingSet; + for ( int i = 0; i < state_set->length(); ++i ) { int acc = (*state_set)[i]->Accept(); if ( acc != NO_ACCEPT ) - { - int j; - for ( j = 0; j < accept->length(); ++j ) - if ( (*accept)[j] == acc ) - break; - - if ( j >= accept->length() ) - // It's not already present. - accept->append(acc); - } + accept->insert(acc); } - if ( accept->length() == 0 ) + if ( accept->empty() ) { delete accept; accept = 0; } - else - { - accept->sort(int_list_cmp); - accept->resize(0); - } DFA_State* ds = new DFA_State(state_count++, ec, state_set, accept); d = dfa_state_cache->Insert(ds, hash); diff --git a/src/Debug.cc b/src/Debug.cc index 94b8abf952..09e8810edb 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -192,6 +192,7 @@ static void parse_function_name(vector& result, string fullname = make_full_var_name(current_module.c_str(), s.c_str()); debug_msg("Function %s not defined.\n", fullname.c_str()); plr.type = plrUnknown; + Unref(id); return; } @@ -199,6 +200,7 @@ static void parse_function_name(vector& result, { debug_msg("Function %s not declared.\n", id->Name()); plr.type = plrUnknown; + Unref(id); return; } @@ -206,6 +208,7 @@ static void parse_function_name(vector& result, { debug_msg("Function %s declared but not defined.\n", id->Name()); plr.type = plrUnknown; + Unref(id); return; } @@ -216,9 +219,12 @@ static void parse_function_name(vector& result, { debug_msg("Function %s is a built-in function\n", id->Name()); plr.type = plrUnknown; + Unref(id); return; } + Unref(id); + Stmt* body = 0; // the particular body we care about; 0 = all if ( bodies.size() == 1 ) diff --git a/src/Desc.cc b/src/Desc.cc index 62c6130f40..f636a028b5 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -216,18 +216,32 @@ void ODesc::Indent() } } -static const char hex_chars[] = "0123456789abcdef"; - -static const char* find_first_unprintable(ODesc* d, const char* bytes, unsigned int n) +static bool starts_with(const char* str1, const char* str2, size_t len) { - if ( d->IsBinary() ) + for ( size_t i = 0; i < len; ++i ) + if ( str1[i] != str2[i] ) + return false; + + return true; + } + +size_t ODesc::StartsWithEscapeSequence(const char* start, const char* end) + { + if ( escape_sequences.empty() ) return 0; - while ( n-- ) + escape_set::const_iterator it; + + for ( it = escape_sequences.begin(); it != escape_sequences.end(); ++it ) { - if ( ! isprint(*bytes) ) - return bytes; - ++bytes; + const string& esc_str = *it; + size_t esc_len = esc_str.length(); + + if ( start + esc_len > end ) + continue; + + if ( starts_with(start, esc_str.c_str(), esc_len) ) + return esc_len; } return 0; @@ -235,21 +249,23 @@ static const char* find_first_unprintable(ODesc* d, const char* bytes, unsigned pair ODesc::FirstEscapeLoc(const char* bytes, size_t n) { - pair p(find_first_unprintable(this, bytes, n), 1); + typedef pair escape_pos; - string str(bytes, n); - list::const_iterator it; - for ( it = escape_sequences.begin(); it != escape_sequences.end(); ++it ) + if ( IsBinary() ) + return escape_pos(0, 0); + + for ( size_t i = 0; i < n; ++i ) { - size_t pos = str.find(*it); - if ( pos != string::npos && (p.first == 0 || bytes + pos < p.first) ) - { - p.first = bytes + pos; - p.second = it->size(); - } + if ( ! isprint(bytes[i]) ) + return escape_pos(bytes + i, 1); + + size_t len = StartsWithEscapeSequence(bytes + i, bytes + n); + + if ( len ) + return escape_pos(bytes + i, len); } - return p; + return escape_pos(0, 0); } void ODesc::AddBytes(const void* bytes, unsigned int n) @@ -266,21 +282,11 @@ void ODesc::AddBytes(const void* bytes, unsigned int n) while ( s < e ) { pair p = FirstEscapeLoc(s, e - s); + if ( p.first ) { AddBytesRaw(s, p.first - s); - if ( p.second == 1 ) - { - char hex[6] = "\\x00"; - hex[2] = hex_chars[((*p.first) & 0xf0) >> 4]; - hex[3] = hex_chars[(*p.first) & 0x0f]; - AddBytesRaw(hex, 4); - } - else - { - string esc_str = get_escaped_string(string(p.first, p.second), true); - AddBytesRaw(esc_str.c_str(), esc_str.size()); - } + get_escaped_string(this, p.first, p.second, true); s = p.first + p.second; } else diff --git a/src/Desc.h b/src/Desc.h index 27dc326ff0..b7df7d75f7 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -4,7 +4,7 @@ #define descriptor_h #include -#include +#include #include #include "BroString.h" @@ -54,16 +54,16 @@ public: void SetFlush(int arg_do_flush) { do_flush = arg_do_flush; } void EnableEscaping(); - void AddEscapeSequence(const char* s) { escape_sequences.push_back(s); } + void AddEscapeSequence(const char* s) { escape_sequences.insert(s); } void AddEscapeSequence(const char* s, size_t n) - { escape_sequences.push_back(string(s, n)); } + { escape_sequences.insert(string(s, n)); } void AddEscapeSequence(const string & s) - { escape_sequences.push_back(s); } - void RemoveEscapeSequence(const char* s) { escape_sequences.remove(s); } + { escape_sequences.insert(s); } + void RemoveEscapeSequence(const char* s) { escape_sequences.erase(s); } void RemoveEscapeSequence(const char* s, size_t n) - { escape_sequences.remove(string(s, n)); } + { escape_sequences.erase(string(s, n)); } void RemoveEscapeSequence(const string & s) - { escape_sequences.remove(s); } + { escape_sequences.erase(s); } void PushIndent(); void PopIndent(); @@ -163,6 +163,15 @@ protected: */ pair FirstEscapeLoc(const char* bytes, size_t n); + /** + * @param start start of string to check for starting with an espace + * sequence. + * @param end one byte past the last character in the string. + * @return The number of bytes in the escape sequence that the string + * starts with. + */ + size_t StartsWithEscapeSequence(const char* start, const char* end); + desc_type type; desc_style style; @@ -171,7 +180,8 @@ protected: unsigned int size; // size of buffer in bytes bool escape; // escape unprintable characters in output? - list escape_sequences; // additional sequences of chars to escape + typedef set escape_set; + escape_set escape_sequences; // additional sequences of chars to escape BroFile* f; // or the file we're using. diff --git a/src/EventHandler.cc b/src/EventHandler.cc index a5dc62148a..2f0a19ccc0 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -39,7 +39,10 @@ FuncType* EventHandler::FType() if ( id->Type()->Tag() != TYPE_FUNC ) return 0; - return type = id->Type()->AsFuncType(); + type = id->Type()->AsFuncType(); + Unref(id); + + return type; } void EventHandler::SetLocalHandler(Func* f) diff --git a/src/Expr.cc b/src/Expr.cc index b3a4b8b096..4a29c11cb5 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3398,8 +3398,8 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list) if ( IsError() ) return; - // Spin through the list, which should be comprised of - // either record's or record-field-assign, and build up a + // Spin through the list, which should be comprised only of + // record-field-assign expressions, and build up a // record type to associate with this constructor. type_decl_list* record_types = new type_decl_list; @@ -3407,34 +3407,18 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list) loop_over_list(exprs, i) { Expr* e = exprs[i]; - BroType* t = e->Type(); - if ( e->Tag() == EXPR_FIELD_ASSIGN ) - { - FieldAssignExpr* field = (FieldAssignExpr*) e; - - BroType* field_type = field->Type()->Ref(); - char* field_name = copy_string(field->FieldName()); - - record_types->append(new TypeDecl(field_type, field_name)); - continue; - } - - if ( t->Tag() != TYPE_RECORD ) + if ( e->Tag() != EXPR_FIELD_ASSIGN ) { Error("bad type in record constructor", e); SetError(); continue; } - // It's a record - add in its fields. - const RecordType* rt = t->AsRecordType(); - int n = rt->NumFields(); - for ( int j = 0; j < n; ++j ) - { - const TypeDecl* td = rt->FieldDecl(j); - record_types->append(new TypeDecl(td->type->Ref(), td->id)); - } + FieldAssignExpr* field = (FieldAssignExpr*) e; + BroType* field_type = field->Type()->Ref(); + char* field_name = copy_string(field->FieldName()); + record_types->append(new TypeDecl(field_type, field_name)); } SetType(new RecordType(record_types)); @@ -4346,7 +4330,7 @@ Val* TableCoerceExpr::Fold(Val* v) const if ( tv->Size() > 0 ) Internal("coercion of non-empty table/set"); - return new TableVal(Type()->Ref()->AsTableType(), tv->Attrs()); + return new TableVal(Type()->AsTableType(), tv->Attrs()); } IMPLEMENT_SERIAL(TableCoerceExpr, SER_TABLE_COERCE_EXPR); diff --git a/src/Frag.cc b/src/Frag.cc index 30bec88af1..d0389c264a 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -97,9 +97,9 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) // Linux MTU discovery for UDP can do this, for example. s->Weird("fragment_with_DF", ip); - int offset = ip->FragOffset(); - int len = ip->TotalLen(); - int hdr_len = ip->HdrLen(); + uint16 offset = ip->FragOffset(); + uint32 len = ip->TotalLen(); + uint16 hdr_len = ip->HdrLen(); if ( len < hdr_len ) { @@ -107,7 +107,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) return; } - int upper_seq = offset + len - hdr_len; + uint64 upper_seq = offset + len - hdr_len; if ( ! offset ) // Make sure to use the first fragment header's next field. @@ -178,7 +178,7 @@ void FragReassembler::Weird(const char* name) const } } -void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n) +void FragReassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n) { if ( memcmp((const void*) b1, (const void*) b2, n) ) Weird("fragment_inconsistency"); @@ -231,7 +231,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) return; // We have it all. Compute the expected size of the fragment. - int n = proto_hdr_len + frag_size; + uint64 n = proto_hdr_len + frag_size; // It's possible that we have blocks associated with this fragment // that exceed this size, if we saw MF fragments (which don't lead diff --git a/src/Frag.h b/src/Frag.h index 0d2fbed5b3..7f3a0eec02 100644 --- a/src/Frag.h +++ b/src/Frag.h @@ -34,14 +34,14 @@ public: protected: void BlockInserted(DataBlock* start_block); - void Overlap(const u_char* b1, const u_char* b2, int n); + void Overlap(const u_char* b1, const u_char* b2, uint64 n); void Weird(const char* name) const; u_char* proto_hdr; IP_Hdr* reassembled_pkt; - int proto_hdr_len; + uint16 proto_hdr_len; NetSessions* s; - int frag_size; // size of fully reassembled fragment + uint64 frag_size; // size of fully reassembled fragment uint16 next_proto; // first IPv6 fragment header's next proto field HashKey* key; diff --git a/src/Func.cc b/src/Func.cc index 11749a8a9c..1f3ac6f93c 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -475,6 +475,7 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, type = id->Type()->Ref(); id->SetVal(new Val(this)); + Unref(id); } BuiltinFunc::~BuiltinFunc() diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 7fd3755042..7ccc3dce07 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -1,5 +1,6 @@ // See the file "COPYING" in the main distribution directory for copyright. +#include #include #include #include "IPAddr.h" @@ -45,6 +46,14 @@ HashKey* BuildConnIDHashKey(const ConnID& id) return new HashKey(&key, sizeof(key)); } +static inline uint32_t bit_mask32(int bottom_bits) + { + if ( bottom_bits >= 32 ) + return 0xffffffff; + + return (((uint32_t) 1) << bottom_bits) - 1; + } + void IPAddr::Mask(int top_bits_to_keep) { if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 ) @@ -53,25 +62,20 @@ void IPAddr::Mask(int top_bits_to_keep) return; } - uint32_t tmp[4]; - memcpy(tmp, in6.s6_addr, sizeof(in6.s6_addr)); + uint32_t mask_bits[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + std::ldiv_t res = std::ldiv(top_bits_to_keep, 32); - int word = 3; - int bits_to_chop = 128 - top_bits_to_keep; + if ( res.quot < 4 ) + mask_bits[res.quot] = + htonl(mask_bits[res.quot] & ~bit_mask32(32 - res.rem)); - while ( bits_to_chop >= 32 ) - { - tmp[word] = 0; - --word; - bits_to_chop -= 32; - } + for ( unsigned int i = res.quot + 1; i < 4; ++i ) + mask_bits[i] = 0; - uint32_t w = ntohl(tmp[word]); - w >>= bits_to_chop; - w <<= bits_to_chop; - tmp[word] = htonl(w); + uint32_t* p = reinterpret_cast(in6.s6_addr); - memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); + for ( unsigned int i = 0; i < 4; ++i ) + p[i] &= mask_bits[i]; } void IPAddr::ReverseMask(int top_bits_to_chop) @@ -82,25 +86,19 @@ void IPAddr::ReverseMask(int top_bits_to_chop) return; } - uint32_t tmp[4]; - memcpy(tmp, in6.s6_addr, sizeof(in6.s6_addr)); + uint32_t mask_bits[4] = { 0, 0, 0, 0 }; + std::ldiv_t res = std::ldiv(top_bits_to_chop, 32); - int word = 0; - int bits_to_chop = top_bits_to_chop; + if ( res.quot < 4 ) + mask_bits[res.quot] = htonl(bit_mask32(32 - res.rem)); - while ( bits_to_chop >= 32 ) - { - tmp[word] = 0; - ++word; - bits_to_chop -= 32; - } + for ( unsigned int i = res.quot + 1; i < 4; ++i ) + mask_bits[i] = 0xffffffff; - uint32_t w = ntohl(tmp[word]); - w <<= bits_to_chop; - w >>= bits_to_chop; - tmp[word] = htonl(w); + uint32_t* p = reinterpret_cast(in6.s6_addr); - memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); + for ( unsigned int i = 0; i < 4; ++i ) + p[i] &= mask_bits[i]; } void IPAddr::Init(const std::string& s) diff --git a/src/RE.cc b/src/RE.cc index 87117c1c3a..4855b0e39a 100644 --- a/src/RE.cc +++ b/src/RE.cc @@ -3,6 +3,7 @@ #include "config.h" #include +#include #include "RE.h" #include "DFA.h" @@ -266,6 +267,15 @@ void Specific_RE_Matcher::Dump(FILE* f) dfa->Dump(f); } +inline void RE_Match_State::AddMatches(const AcceptingSet& as, + MatchPos position) + { + typedef std::pair am_idx; + + for ( AcceptingSet::const_iterator it = as.begin(); it != as.end(); ++it ) + accepted_matches.insert(am_idx(*it, position)); + } + bool RE_Match_State::Match(const u_char* bv, int n, bool bol, bool eol, bool clear) { @@ -283,14 +293,9 @@ bool RE_Match_State::Match(const u_char* bv, int n, current_state = dfa->StartState(); const AcceptingSet* ac = current_state->Accept(); + if ( ac ) - { - loop_over_list(*ac, i) - { - accepted.append((*ac)[i]); - match_pos.append(0); - } - } + AddMatches(*ac, 0); } else if ( clear ) @@ -301,7 +306,7 @@ bool RE_Match_State::Match(const u_char* bv, int n, current_pos = 0; - int old_matches = accepted.length(); + size_t old_matches = accepted_matches.size(); int ec; int m = bol ? n + 1 : n; @@ -324,25 +329,17 @@ bool RE_Match_State::Match(const u_char* bv, int n, break; } - if ( next_state->Accept() ) - { - const AcceptingSet* ac = next_state->Accept(); - loop_over_list(*ac, i) - { - if ( ! accepted.is_member((*ac)[i]) ) - { - accepted.append((*ac)[i]); - match_pos.append(current_pos); - } - } - } + const AcceptingSet* ac = next_state->Accept(); + + if ( ac ) + AddMatches(*ac, current_pos); ++current_pos; current_state = next_state; } - return accepted.length() != old_matches; + return accepted_matches.size() != old_matches; } int Specific_RE_Matcher::LongestMatch(const u_char* bv, int n) @@ -399,7 +396,8 @@ unsigned int Specific_RE_Matcher::MemoryAllocation() const + equiv_class.Size() - padded_sizeof(EquivClass) + (dfa ? dfa->MemoryAllocation() : 0) // this is ref counted; consider the bytes here? + padded_sizeof(*any_ccl) - + accepted->MemoryAllocation(); + + padded_sizeof(*accepted) + + accepted->size() * padded_sizeof(AcceptingSet::key_type); } RE_Matcher::RE_Matcher() diff --git a/src/RE.h b/src/RE.h index a2fc709c88..7437dbb8b8 100644 --- a/src/RE.h +++ b/src/RE.h @@ -9,6 +9,9 @@ #include "CCL.h" #include "EquivClass.h" +#include +#include + #include typedef int (*cce_func)(int); @@ -33,7 +36,10 @@ extern int re_lex(void); extern int clower(int); extern void synerr(const char str[]); -typedef int_list AcceptingSet; +typedef int AcceptIdx; +typedef std::set AcceptingSet; +typedef uint64 MatchPos; +typedef std::map AcceptingMatchSet; typedef name_list string_list; typedef enum { MATCH_ANYWHERE, MATCH_EXACTLY, } match_type; @@ -135,8 +141,8 @@ public: current_state = 0; } - const AcceptingSet* Accepted() const { return &accepted; } - const int_list* MatchPositions() const { return &match_pos; } + const AcceptingMatchSet& AcceptedMatches() const + { return accepted_matches; } // Returns the number of bytes feeded into the matcher so far int Length() { return current_pos; } @@ -149,16 +155,16 @@ public: { current_pos = -1; current_state = 0; - accepted.clear(); - match_pos.clear(); + accepted_matches.clear(); } + void AddMatches(const AcceptingSet& as, MatchPos position); + protected: DFA_Machine* dfa; int* ecs; - AcceptingSet accepted; - int_list match_pos; + AcceptingMatchSet accepted_matches; DFA_State* current_state; int current_pos; }; diff --git a/src/Reassem.cc b/src/Reassem.cc index 19beaa0a16..27fb26561f 100644 --- a/src/Reassem.cc +++ b/src/Reassem.cc @@ -7,14 +7,9 @@ #include "Reassem.h" #include "Serializer.h" -const bool DEBUG_reassem = false; +static const bool DEBUG_reassem = false; -#ifdef DEBUG -int reassem_seen_bytes = 0; -int reassem_copied_bytes = 0; -#endif - -DataBlock::DataBlock(const u_char* data, int size, int arg_seq, +DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq, DataBlock* arg_prev, DataBlock* arg_next) { seq = arg_seq; @@ -23,10 +18,6 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq, memcpy((void*) block, (const void*) data, size); -#ifdef DEBUG - reassem_copied_bytes += size; -#endif - prev = arg_prev; next = arg_next; @@ -38,9 +29,9 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq, Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock); } -unsigned int Reassembler::total_size = 0; +uint64 Reassembler::total_size = 0; -Reassembler::Reassembler(int init_seq, ReassemblerType arg_type) +Reassembler::Reassembler(uint64 init_seq, ReassemblerType arg_type) { blocks = last_block = 0; trim_seq = last_reassem_seq = init_seq; @@ -51,24 +42,20 @@ Reassembler::~Reassembler() ClearBlocks(); } -void Reassembler::NewBlock(double t, int seq, int len, const u_char* data) +void Reassembler::NewBlock(double t, uint64 seq, uint64 len, const u_char* data) { if ( len == 0 ) return; -#ifdef DEBUG - reassem_seen_bytes += len; -#endif + uint64 upper_seq = seq + len; - int upper_seq = seq + len; - - if ( seq_delta(upper_seq, trim_seq) <= 0 ) + if ( upper_seq <= trim_seq ) // Old data, don't do any work for it. return; - if ( seq_delta(seq, trim_seq) < 0 ) + if ( seq < trim_seq ) { // Partially old data, just keep the good stuff. - int amount_old = seq_delta(trim_seq, seq); + uint64 amount_old = trim_seq - seq; data += amount_old; seq += amount_old; @@ -86,42 +73,42 @@ void Reassembler::NewBlock(double t, int seq, int len, const u_char* data) BlockInserted(start_block); } -int Reassembler::TrimToSeq(int seq) +uint64 Reassembler::TrimToSeq(uint64 seq) { - int num_missing = 0; + uint64 num_missing = 0; // Do this accounting before looking for Undelivered data, // since that will alter last_reassem_seq. if ( blocks ) { - if ( seq_delta(blocks->seq, last_reassem_seq) > 0 ) + if ( blocks->seq > last_reassem_seq ) // An initial hole. - num_missing += seq_delta(blocks->seq, last_reassem_seq); + num_missing += blocks->seq - last_reassem_seq; } - else if ( seq_delta(seq, last_reassem_seq) > 0 ) + else if ( seq > last_reassem_seq ) { // Trimming data we never delivered. if ( ! blocks ) // We won't have any accounting based on blocks // for this hole. - num_missing += seq_delta(seq, last_reassem_seq); + num_missing += seq - last_reassem_seq; } - if ( seq_delta(seq, last_reassem_seq) > 0 ) + if ( seq > last_reassem_seq ) { // We're trimming data we never delivered. Undelivered(seq); } - while ( blocks && seq_delta(blocks->upper, seq) <= 0 ) + while ( blocks && blocks->upper <= seq ) { DataBlock* b = blocks->next; - if ( b && seq_delta(b->seq, seq) <= 0 ) + if ( b && b->seq <= seq ) { if ( blocks->upper != b->seq ) - num_missing += seq_delta(b->seq, blocks->upper); + num_missing += b->seq - blocks->upper; } else { @@ -129,7 +116,7 @@ int Reassembler::TrimToSeq(int seq) // Second half of test is for acks of FINs, which // don't get entered into the sequence space. if ( blocks->upper != seq && blocks->upper != seq - 1 ) - num_missing += seq_delta(seq, blocks->upper); + num_missing += seq - blocks->upper; } delete blocks; @@ -150,7 +137,7 @@ int Reassembler::TrimToSeq(int seq) else last_block = 0; - if ( seq_delta(seq, trim_seq) > 0 ) + if ( seq > trim_seq ) // seq is further ahead in the sequence space. trim_seq = seq; @@ -169,9 +156,9 @@ void Reassembler::ClearBlocks() last_block = 0; } -int Reassembler::TotalSize() const +uint64 Reassembler::TotalSize() const { - int size = 0; + uint64 size = 0; for ( DataBlock* b = blocks; b; b = b->next ) size += b->Size(); @@ -184,18 +171,18 @@ void Reassembler::Describe(ODesc* d) const d->Add("reassembler"); } -void Reassembler::Undelivered(int up_to_seq) +void Reassembler::Undelivered(uint64 up_to_seq) { // TrimToSeq() expects this. last_reassem_seq = up_to_seq; } -DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, +DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper, const u_char* data) { if ( DEBUG_reassem ) { - DEBUG_MSG("%.6f Reassembler::AddAndCheck seq=%d, upper=%d\n", + DEBUG_MSG("%.6f Reassembler::AddAndCheck seq=%"PRIu64", upper=%"PRIu64"\n", network_time, seq, upper); } @@ -209,10 +196,10 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, // Find the first block that doesn't come completely before the // new data. - while ( b->next && seq_delta(b->upper, seq) <= 0 ) + while ( b->next && b->upper <= seq ) b = b->next; - if ( seq_delta(b->upper, seq) <= 0 ) + if ( b->upper <= seq ) { // b is the last block, and it comes completely before // the new block. @@ -222,21 +209,20 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, DataBlock* new_b = 0; - if ( seq_delta(upper, b->seq) <= 0 ) + if ( upper <= b->seq ) { // The new block comes completely before b. - new_b = new DataBlock(data, seq_delta(upper, seq), seq, - b->prev, b); + new_b = new DataBlock(data, upper - seq, seq, b->prev, b); if ( b == blocks ) blocks = new_b; return new_b; } // The blocks overlap, complain. - if ( seq_delta(seq, b->seq) < 0 ) + if ( seq < b->seq ) { // The new block has a prefix that comes before b. - int prefix_len = seq_delta(b->seq, seq); + uint64 prefix_len = b->seq - seq; new_b = new DataBlock(data, prefix_len, seq, b->prev, b); if ( b == blocks ) blocks = new_b; @@ -247,11 +233,11 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, else new_b = b; - int overlap_start = seq; - int overlap_offset = seq_delta(overlap_start, b->seq); - int new_b_len = seq_delta(upper, seq); - int b_len = seq_delta(b->upper, overlap_start); - int overlap_len = min(new_b_len, b_len); + uint64 overlap_start = seq; + uint64 overlap_offset = overlap_start - b->seq; + uint64 new_b_len = upper - seq; + uint64 b_len = b->upper - overlap_start; + uint64 overlap_len = min(new_b_len, b_len); Overlap(&b->block[overlap_offset], data, overlap_len); diff --git a/src/Reassem.h b/src/Reassem.h index 1f65059e02..7b77a628d8 100644 --- a/src/Reassem.h +++ b/src/Reassem.h @@ -8,16 +8,16 @@ class DataBlock { public: - DataBlock(const u_char* data, int size, int seq, + DataBlock(const u_char* data, uint64 size, uint64 seq, DataBlock* prev, DataBlock* next); ~DataBlock(); - int Size() const { return upper - seq; } + uint64 Size() const { return upper - seq; } DataBlock* next; // next block with higher seq # DataBlock* prev; // previous block with lower seq # - int seq, upper; + uint64 seq, upper; u_char* block; }; @@ -26,22 +26,22 @@ enum ReassemblerType { REASSEM_IP, REASSEM_TCP }; class Reassembler : public BroObj { public: - Reassembler(int init_seq, ReassemblerType arg_type); + Reassembler(uint64 init_seq, ReassemblerType arg_type); virtual ~Reassembler(); - void NewBlock(double t, int seq, int len, const u_char* data); + void NewBlock(double t, uint64 seq, uint64 len, const u_char* data); // Throws away all blocks up to seq. Returns number of bytes // if not all in-sequence, 0 if they were. - int TrimToSeq(int seq); + uint64 TrimToSeq(uint64 seq); // Delete all held blocks. void ClearBlocks(); int HasBlocks() const { return blocks != 0; } - int LastReassemSeq() const { return last_reassem_seq; } + uint64 LastReassemSeq() const { return last_reassem_seq; } - int TotalSize() const; // number of bytes buffered up + uint64 TotalSize() const; // number of bytes buffered up void Describe(ODesc* d) const; @@ -49,7 +49,7 @@ public: static Reassembler* Unserialize(UnserialInfo* info); // Sum over all data buffered in some reassembler. - static unsigned int TotalMemoryAllocation() { return total_size; } + static uint64 TotalMemoryAllocation() { return total_size; } protected: Reassembler() { } @@ -58,20 +58,20 @@ protected: friend class DataBlock; - virtual void Undelivered(int up_to_seq); + virtual void Undelivered(uint64 up_to_seq); virtual void BlockInserted(DataBlock* b) = 0; - virtual void Overlap(const u_char* b1, const u_char* b2, int n) = 0; + virtual void Overlap(const u_char* b1, const u_char* b2, uint64 n) = 0; - DataBlock* AddAndCheck(DataBlock* b, int seq, - int upper, const u_char* data); + DataBlock* AddAndCheck(DataBlock* b, uint64 seq, + uint64 upper, const u_char* data); DataBlock* blocks; DataBlock* last_block; - int last_reassem_seq; - int trim_seq; // how far we've trimmed + uint64 last_reassem_seq; + uint64 trim_seq; // how far we've trimmed - static unsigned int total_size; + static uint64 total_size; }; inline DataBlock::~DataBlock() diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index 99ec3d7c1e..675eb37fac 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -2833,6 +2833,7 @@ void RemoteSerializer::GotEvent(const char* name, double time, if ( ! current_peer ) { Error("unserialized event from unknown peer"); + delete_vals(args); return; } @@ -2882,6 +2883,7 @@ void RemoteSerializer::GotFunctionCall(const char* name, double time, if ( ! current_peer ) { Error("unserialized function from unknown peer"); + delete_vals(args); return; } diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 5e9dff0a1f..ca08388b10 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -594,6 +594,29 @@ RuleFileMagicState* RuleMatcher::InitFileMagic() const return state; } +bool RuleMatcher::AllRulePatternsMatched(const Rule* r, MatchPos matchpos, + const AcceptingMatchSet& ams) + { + DBG_LOG(DBG_RULES, "Checking rule: %s", r->id); + + // Check whether all patterns of the rule have matched. + loop_over_list(r->patterns, j) + { + if ( ams.find(r->patterns[j]->id) == ams.end() ) + return false; + + // See if depth is satisfied. + if ( matchpos > r->patterns[j]->offset + r->patterns[j]->depth ) + return false; + + // FIXME: How to check for offset ??? ### + } + + DBG_LOG(DBG_RULES, "All patterns of rule satisfied"); + + return true; + } + RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, const u_char* data, uint64 len, MIME_Matches* rval) const @@ -636,56 +659,39 @@ RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, DBG_LOG(DBG_RULES, "New pattern match found"); - AcceptingSet accepted; - int_list matchpos; + AcceptingMatchSet accepted_matches; loop_over_list(state->matchers, y) { RuleFileMagicState::Matcher* m = state->matchers[y]; - const AcceptingSet* ac = m->state->Accepted(); - - loop_over_list(*ac, k) - { - if ( ! accepted.is_member((*ac)[k]) ) - { - accepted.append((*ac)[k]); - matchpos.append((*m->state->MatchPositions())[k]); - } - } + const AcceptingMatchSet& ams = m->state->AcceptedMatches(); + accepted_matches.insert(ams.begin(), ams.end()); } // Find rules for which patterns have matched. - rule_list matched; + set rule_matches; - loop_over_list(accepted, i) + for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); + it != accepted_matches.end(); ++it ) { - Rule* r = Rule::rule_table[accepted[i] - 1]; + AcceptIdx aidx = it->first; + MatchPos mpos = it->second; - DBG_LOG(DBG_RULES, "Checking rule: %v", r->id); + Rule* r = Rule::rule_table[aidx - 1]; - loop_over_list(r->patterns, j) - { - if ( ! accepted.is_member(r->patterns[j]->id) ) - continue; - - if ( (unsigned int) matchpos[i] > - r->patterns[j]->offset + r->patterns[j]->depth ) - continue; - - DBG_LOG(DBG_RULES, "All patterns of rule satisfied"); - } - - if ( ! matched.is_member(r) ) - matched.append(r); + if ( AllRulePatternsMatched(r, mpos, accepted_matches) ) + rule_matches.insert(r); } - loop_over_list(matched, j) + for ( set::const_iterator it = rule_matches.begin(); + it != rule_matches.end(); ++it ) { - Rule* r = matched[j]; + Rule* r = *it; loop_over_list(r->actions, rai) { - const RuleActionMIME* ram = dynamic_cast(r->actions[rai]); + const RuleActionMIME* ram = + dynamic_cast(r->actions[rai]); if ( ! ram ) continue; @@ -876,66 +882,40 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, DBG_LOG(DBG_RULES, "New pattern match found"); - // Build a joined AcceptingSet. - AcceptingSet accepted; - int_list matchpos; + AcceptingMatchSet accepted_matches; - loop_over_list(state->matchers, y) + loop_over_list(state->matchers, y ) { RuleEndpointState::Matcher* m = state->matchers[y]; - const AcceptingSet* ac = m->state->Accepted(); - - loop_over_list(*ac, k) - { - if ( ! accepted.is_member((*ac)[k]) ) - { - accepted.append((*ac)[k]); - matchpos.append((*m->state->MatchPositions())[k]); - } - } + const AcceptingMatchSet& ams = m->state->AcceptedMatches(); + accepted_matches.insert(ams.begin(), ams.end()); } // Determine the rules for which all patterns have matched. // This code should be fast enough as long as there are only very few // matched patterns per connection (which is a plausible assumption). - rule_list matched; + // Find rules for which patterns have matched. + set rule_matches; - loop_over_list(accepted, i) + for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); + it != accepted_matches.end(); ++it ) { - Rule* r = Rule::rule_table[accepted[i] - 1]; + AcceptIdx aidx = it->first; + MatchPos mpos = it->second; - DBG_LOG(DBG_RULES, "Checking rule: %s", r->id); + Rule* r = Rule::rule_table[aidx - 1]; - // Check whether all patterns of the rule have matched. - loop_over_list(r->patterns, j) - { - if ( ! accepted.is_member(r->patterns[j]->id) ) - goto next_pattern; - - // See if depth is satisfied. - if ( (unsigned int) matchpos[i] > - r->patterns[j]->offset + r->patterns[j]->depth ) - goto next_pattern; - - DBG_LOG(DBG_RULES, "All patterns of rule satisfied"); - - // FIXME: How to check for offset ??? ### - } - - // If not already in the list of matching rules, add it. - if ( ! matched.is_member(r) ) - matched.append(r); - -next_pattern: - continue; + if ( AllRulePatternsMatched(r, mpos, accepted_matches) ) + rule_matches.insert(r); } // Check which of the matching rules really belong to any of our nodes. - loop_over_list(matched, j) + for ( set::const_iterator it = rule_matches.begin(); + it != rule_matches.end(); ++it ) { - Rule* r = matched[j]; + Rule* r = *it; DBG_LOG(DBG_RULES, "Accepted rule: %s", r->id); @@ -1306,7 +1286,10 @@ static Val* get_bro_val(const char* label) return 0; } - return id->ID_Val(); + Val* rval = id->ID_Val(); + Unref(id); + + return rval; } diff --git a/src/RuleMatcher.h b/src/RuleMatcher.h index 52e00f6bad..da2838cb6d 100644 --- a/src/RuleMatcher.h +++ b/src/RuleMatcher.h @@ -361,6 +361,9 @@ private: void DumpStateStats(BroFile* f, RuleHdrTest* hdr_test); + static bool AllRulePatternsMatched(const Rule* r, MatchPos matchpos, + const AcceptingMatchSet& ams); + int RE_level; bool parse_error; RuleHdrTest* root; diff --git a/src/Scope.h b/src/Scope.h index 1ef58d871c..265d624a66 100644 --- a/src/Scope.h +++ b/src/Scope.h @@ -62,6 +62,7 @@ protected: extern bool in_debug; // If no_global is true, don't search in the default "global" namespace. +// This passed ownership of a ref'ed ID to the caller. extern ID* lookup_ID(const char* name, const char* module, bool no_global = false, bool same_module_only=false); extern ID* install_ID(const char* name, const char* module_name, diff --git a/src/Serializer.h b/src/Serializer.h index af4878ccf5..543797a7af 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -125,7 +125,7 @@ protected: // This will be increased whenever there is an incompatible change // in the data format. - static const uint32 DATA_FORMAT_VERSION = 24; + static const uint32 DATA_FORMAT_VERSION = 25; ChunkedIO* io; diff --git a/src/Stats.cc b/src/Stats.cc index c4b0ed45b1..6cf9a622e1 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -160,7 +160,7 @@ void ProfileLogger::Log() file->Write(fmt("%.06f Connections expired due to inactivity: %d\n", network_time, killed_by_inactivity)); - file->Write(fmt("%.06f Total reassembler data: %dK\n", network_time, + file->Write(fmt("%.06f Total reassembler data: %"PRIu64"K\n", network_time, Reassembler::TotalMemoryAllocation() / 1024)); // Signature engine. diff --git a/src/Type.cc b/src/Type.cc index 672153d957..b840fa98e3 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1449,6 +1449,7 @@ void EnumType::CheckAndAddName(const string& module_name, const char* name, } else { + Unref(id); reporter->Error("identifier or enumerator value in enumerated type definition already exists"); SetError(); return; diff --git a/src/Val.cc b/src/Val.cc index aa9c888d49..fb7a1ce4ba 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -32,7 +32,6 @@ Val::Val(Func* f) val.func_val = f; ::Ref(val.func_val); type = f->FType()->Ref(); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -49,7 +48,6 @@ Val::Val(BroFile* f) assert(f->FType()->Tag() == TYPE_STRING); type = string_file_type->Ref(); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -190,8 +188,6 @@ bool Val::DoSerialize(SerialInfo* info) const if ( ! type->Serialize(info) ) return false; - SERIALIZE_OPTIONAL(attribs); - switch ( type->InternalType() ) { case TYPE_INTERNAL_VOID: info->s->Error("type is void"); @@ -251,9 +247,6 @@ bool Val::DoUnserialize(UnserialInfo* info) if ( ! (type = BroType::Unserialize(info)) ) return false; - UNSERIALIZE_OPTIONAL(attribs, - (RecordVal*) Val::Unserialize(info, TYPE_RECORD)); - switch ( type->InternalType() ) { case TYPE_INTERNAL_VOID: info->s->Error("type is void"); @@ -1478,13 +1471,20 @@ int TableVal::Assign(Val* index, HashKey* k, Val* new_val, Opcode op) } TableEntryVal* new_entry_val = new TableEntryVal(new_val); + HashKey k_copy(k->Key(), k->Size(), k->Hash()); TableEntryVal* old_entry_val = AsNonConstTable()->Insert(k, new_entry_val); + // If the dictionary index already existed, the insert may free up the + // memory allocated to the key bytes, so have to assume k is invalid + // from here on out. + delete k; + k = 0; + if ( subnets ) { if ( ! index ) { - Val* v = RecoverIndex(k); + Val* v = RecoverIndex(&k_copy); subnets->Insert(v, new_entry_val); Unref(v); } @@ -1496,7 +1496,7 @@ int TableVal::Assign(Val* index, HashKey* k, Val* new_val, Opcode op) { Val* rec_index = 0; if ( ! index ) - index = rec_index = RecoverIndex(k); + index = rec_index = RecoverIndex(&k_copy); if ( new_val ) { @@ -1554,7 +1554,6 @@ int TableVal::Assign(Val* index, HashKey* k, Val* new_val, Opcode op) if ( old_entry_val && attrs && attrs->FindAttr(ATTR_EXPIRE_CREATE) ) new_entry_val->SetExpireAccess(old_entry_val->ExpireAccessTime()); - delete k; if ( old_entry_val ) { old_entry_val->Unref(); diff --git a/src/Val.h b/src/Val.h index b94cb2d621..58b24a3e5d 100644 --- a/src/Val.h +++ b/src/Val.h @@ -80,7 +80,6 @@ public: { val.int_val = b; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -90,7 +89,6 @@ public: { val.int_val = bro_int_t(i); type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -100,7 +98,6 @@ public: { val.uint_val = bro_uint_t(u); type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -110,7 +107,6 @@ public: { val.int_val = i; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -120,7 +116,6 @@ public: { val.uint_val = u; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -130,7 +125,6 @@ public: { val.double_val = d; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -145,7 +139,6 @@ public: Val(BroType* t, bool type_type) // Extra arg to differentiate from protected version. { type = new TypeType(t->Ref()); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -155,7 +148,6 @@ public: { val.int_val = 0; type = base_type(TYPE_ERROR); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -364,7 +356,6 @@ protected: { val.string_val = s; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -376,7 +367,6 @@ protected: Val(TypeTag t) { type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -385,7 +375,6 @@ protected: Val(BroType* t) { type = t->Ref(); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -400,7 +389,6 @@ protected: BroValUnion val; BroType* type; - RecordVal* attribs; #ifdef DEBUG // For debugging, we keep the name of the ID to which a Val is bound. @@ -944,7 +932,6 @@ public: { val.int_val = i; type = t; - attribs = 0; } Val* SizeVal() const { return new Val(val.int_val, TYPE_INT); } diff --git a/src/Var.cc b/src/Var.cc index 52754e3265..aa45faaf41 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -385,6 +385,8 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, if ( arg_id && ! arg_id->IsGlobal() ) arg_id->Error("argument name used twice"); + Unref(arg_id); + arg_id = install_ID(arg_i->id, module_name, false, false); arg_id->SetType(arg_i->type->Ref()); } @@ -442,10 +444,13 @@ void end_func(Stmt* body, attr_list* attrs) Val* internal_val(const char* name) { ID* id = lookup_ID(name, GLOBAL_MODULE_NAME); + if ( ! id ) reporter->InternalError("internal variable %s missing", name); - return id->ID_Val(); + Val* rval = id->ID_Val(); + Unref(id); + return rval; } Val* internal_const_val(const char* name) @@ -457,13 +462,17 @@ Val* internal_const_val(const char* name) if ( ! id->IsConst() ) reporter->InternalError("internal variable %s is not constant", name); - return id->ID_Val(); + Val* rval = id->ID_Val(); + Unref(id); + return rval; } Val* opt_internal_val(const char* name) { ID* id = lookup_ID(name, GLOBAL_MODULE_NAME); - return id ? id->ID_Val() : 0; + Val* rval = id ? id->ID_Val() : 0; + Unref(id); + return rval; } double opt_internal_double(const char* name) @@ -503,6 +512,8 @@ ListVal* internal_list_val(const char* name) return 0; Val* v = id->ID_Val(); + Unref(id); + if ( v ) { if ( v->Type()->Tag() == TYPE_LIST ) @@ -528,7 +539,9 @@ BroType* internal_type(const char* name) if ( ! id ) reporter->InternalError("internal type %s missing", name); - return id->Type(); + BroType* rval = id->Type(); + Unref(id); + return rval; } Func* internal_func(const char* name) diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index b280cbb6f8..b840e1bbd4 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -203,7 +203,7 @@ void Analyzer::Done() finished = true; } -void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq, +void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { if ( skip ) @@ -250,7 +250,7 @@ void Analyzer::NextStream(int len, const u_char* data, bool is_orig) } } -void Analyzer::NextUndelivered(int seq, int len, bool is_orig) +void Analyzer::NextUndelivered(uint64 seq, int len, bool is_orig) { if ( skip ) return; @@ -287,7 +287,7 @@ void Analyzer::NextEndOfData(bool is_orig) } void Analyzer::ForwardPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { if ( output_handler ) output_handler->DeliverPacket(len, data, is_orig, seq, @@ -335,7 +335,7 @@ void Analyzer::ForwardStream(int len, const u_char* data, bool is_orig) AppendNewChildren(); } -void Analyzer::ForwardUndelivered(int seq, int len, bool is_orig) +void Analyzer::ForwardUndelivered(uint64 seq, int len, bool is_orig) { if ( output_handler ) output_handler->Undelivered(seq, len, is_orig); @@ -595,9 +595,9 @@ SupportAnalyzer* Analyzer::FirstSupportAnalyzer(bool orig) } void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { - DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", + DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %"PRIu64", %p, %d) [%s%s]", fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } @@ -609,9 +609,9 @@ void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } -void Analyzer::Undelivered(int seq, int len, bool is_orig) +void Analyzer::Undelivered(uint64 seq, int len, bool is_orig) { - DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)", + DBG_LOG(DBG_ANALYZER, "%s Undelivered(%"PRIu64", %d, %s)", fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F"); } @@ -793,7 +793,7 @@ SupportAnalyzer* SupportAnalyzer::Sibling(bool only_active) const } void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { // We do not call parent's method, as we're replacing the functionality. @@ -834,7 +834,7 @@ void SupportAnalyzer::ForwardStream(int len, const u_char* data, bool is_orig) Parent()->DeliverStream(len, data, is_orig); } -void SupportAnalyzer::ForwardUndelivered(int seq, int len, bool is_orig) +void SupportAnalyzer::ForwardUndelivered(uint64 seq, int len, bool is_orig) { // We do not call parent's method, as we're replacing the functionality. diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 578020082b..f32181b9e7 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -44,7 +44,7 @@ public: * Analyzer::DeliverPacket(). */ virtual void DeliverPacket(int len, const u_char* data, - bool orig, int seq, + bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { } @@ -59,7 +59,7 @@ public: * Hook for receiving notification of stream gaps. Parameters are the * same as for Analyzer::Undelivered(). */ - virtual void Undelivered(int seq, int len, bool orig) { } + virtual void Undelivered(uint64 seq, int len, bool orig) { } }; /** @@ -143,7 +143,7 @@ public: * @param caplen The packet's capture length, if available. */ void NextPacket(int len, const u_char* data, bool is_orig, - int seq = -1, const IP_Hdr* ip = 0, int caplen = 0); + uint64 seq = -1, const IP_Hdr* ip = 0, int caplen = 0); /** * Passes stream input to the analyzer for processing. The analyzer @@ -173,7 +173,7 @@ public: * * @param is_orig True if this is about originator-side input. */ - void NextUndelivered(int seq, int len, bool is_orig); + void NextUndelivered(uint64 seq, int len, bool is_orig); /** * Reports a message boundary. This is a generic method that can be @@ -195,7 +195,7 @@ public: * Parameters are the same as for NextPacket(). */ virtual void ForwardPacket(int len, const u_char* data, - bool orig, int seq, + bool orig, uint64 seq, const IP_Hdr* ip, int caplen); /** @@ -212,7 +212,7 @@ public: * * Parameters are the same as for NextUndelivered(). */ - virtual void ForwardUndelivered(int seq, int len, bool orig); + virtual void ForwardUndelivered(uint64 seq, int len, bool orig); /** * Forwards an end-of-data notification on to all child analyzers. @@ -227,7 +227,7 @@ public: * Parameters are the same. */ virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); /** * Hook for accessing stream input for parsing. This is called by @@ -241,7 +241,7 @@ public: * NextUndelivered() and can be overridden by derived classes. * Parameters are the same. */ - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); /** * Hook for accessing end-of-data notifications. This is called by @@ -749,7 +749,7 @@ public: * Parameters same as for Analyzer::ForwardPacket. */ virtual void ForwardPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); /** * Passes stream input to the next sibling SupportAnalyzer if any, or @@ -769,7 +769,7 @@ public: * * Parameters same as for Analyzer::ForwardPacket. */ - virtual void ForwardUndelivered(int seq, int len, bool orig); + virtual void ForwardUndelivered(uint64 seq, int len, bool orig); protected: friend class Analyzer; diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index 7c20e07b2d..ee8782956c 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -19,14 +19,15 @@ add_subdirectory(ident) add_subdirectory(interconn) add_subdirectory(irc) add_subdirectory(login) -add_subdirectory(modbus) add_subdirectory(mime) +add_subdirectory(modbus) add_subdirectory(ncp) -add_subdirectory(netflow) add_subdirectory(netbios) +add_subdirectory(netflow) add_subdirectory(ntp) add_subdirectory(pia) add_subdirectory(pop3) +add_subdirectory(radius) add_subdirectory(rpc) add_subdirectory(sip) add_subdirectory(snmp) diff --git a/src/analyzer/protocol/ayiya/AYIYA.cc b/src/analyzer/protocol/ayiya/AYIYA.cc index 070a3ef3e1..a1e00e9b38 100644 --- a/src/analyzer/protocol/ayiya/AYIYA.cc +++ b/src/analyzer/protocol/ayiya/AYIYA.cc @@ -22,7 +22,7 @@ void AYIYA_Analyzer::Done() Event(udp_session_done); } -void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/ayiya/AYIYA.h b/src/analyzer/protocol/ayiya/AYIYA.h index f5bb379cf4..2739ff2bba 100644 --- a/src/analyzer/protocol/ayiya/AYIYA.h +++ b/src/analyzer/protocol/ayiya/AYIYA.h @@ -12,7 +12,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new AYIYA_Analyzer(conn); } diff --git a/src/analyzer/protocol/backdoor/BackDoor.cc b/src/analyzer/protocol/backdoor/BackDoor.cc index a466938ff6..984b2a5dcf 100644 --- a/src/analyzer/protocol/backdoor/BackDoor.cc +++ b/src/analyzer/protocol/backdoor/BackDoor.cc @@ -46,7 +46,7 @@ void BackDoorEndpoint::FinalCheckForRlogin() } } -int BackDoorEndpoint::DataSent(double /* t */, int seq, +int BackDoorEndpoint::DataSent(double /* t */, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* /* ip */, const struct tcphdr* /* tp */) @@ -60,8 +60,8 @@ int BackDoorEndpoint::DataSent(double /* t */, int seq, if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) is_partial = 1; - int ack = endp->AckSeq() - endp->StartSeq(); - int top_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 top_seq = seq + len; if ( top_seq <= ack || top_seq <= max_top_seq ) // There is no new data in this packet. @@ -124,7 +124,7 @@ RecordVal* BackDoorEndpoint::BuildStats() return stats; } -void BackDoorEndpoint::CheckForRlogin(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForRlogin(uint64 seq, int len, const u_char* data) { if ( rlogin_checking_done ) return; @@ -177,7 +177,7 @@ void BackDoorEndpoint::CheckForRlogin(int seq, int len, const u_char* data) if ( seq < max_top_seq ) { // trim to just the new data - int delta = max_top_seq - seq; + int64 delta = max_top_seq - seq; seq += delta; data += delta; len -= delta; @@ -255,7 +255,7 @@ void BackDoorEndpoint::RloginSignatureFound(int len) endp->TCP()->ConnectionEvent(rlogin_signature_found, vl); } -void BackDoorEndpoint::CheckForTelnet(int /* seq */, int len, const u_char* data) +void BackDoorEndpoint::CheckForTelnet(uint64 /* seq */, int len, const u_char* data) { if ( len >= 3 && data[0] == TELNET_IAC && IS_TELNET_NEGOTIATION_CMD(data[1]) ) @@ -346,7 +346,7 @@ void BackDoorEndpoint::TelnetSignatureFound(int len) endp->TCP()->ConnectionEvent(telnet_signature_found, vl); } -void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForSSH(uint64 seq, int len, const u_char* data) { if ( seq == 1 && CheckForString("SSH-", data, len) && len > 4 && (data[4] == '1' || data[4] == '2') ) @@ -363,8 +363,9 @@ void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) if ( seq > max_top_seq ) { // Estimate number of packets in the sequence gap - int gap = seq - max_top_seq; - num_pkts += int((gap + DEFAULT_MTU - 1) / DEFAULT_MTU); + int64 gap = seq - max_top_seq; + if ( gap > 0 ) + num_pkts += uint64((gap + DEFAULT_MTU - 1) / DEFAULT_MTU); } ++num_pkts; @@ -388,7 +389,7 @@ void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) } } -void BackDoorEndpoint::CheckForRootBackdoor(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForRootBackdoor(uint64 seq, int len, const u_char* data) { // Check for root backdoor signature: an initial payload of // exactly "# ". @@ -397,7 +398,7 @@ void BackDoorEndpoint::CheckForRootBackdoor(int seq, int len, const u_char* data SignatureFound(root_backdoor_signature_found); } -void BackDoorEndpoint::CheckForFTP(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForFTP(uint64 seq, int len, const u_char* data) { // Check for FTP signature // @@ -429,7 +430,7 @@ void BackDoorEndpoint::CheckForFTP(int seq, int len, const u_char* data) SignatureFound(ftp_signature_found); } -void BackDoorEndpoint::CheckForNapster(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForNapster(uint64 seq, int len, const u_char* data) { // Check for Napster signature "GETfoobar" or "SENDfoobar" where // "foobar" is the Napster handle associated with the request @@ -449,7 +450,7 @@ void BackDoorEndpoint::CheckForNapster(int seq, int len, const u_char* data) SignatureFound(napster_signature_found); } -void BackDoorEndpoint::CheckForSMTP(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForSMTP(uint64 seq, int len, const u_char* data) { const char* smtp_handshake[] = { "HELO", "EHLO", 0 }; @@ -460,7 +461,7 @@ void BackDoorEndpoint::CheckForSMTP(int seq, int len, const u_char* data) SignatureFound(smtp_signature_found); } -void BackDoorEndpoint::CheckForIRC(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForIRC(uint64 seq, int len, const u_char* data) { if ( seq != 1 || is_partial ) return; @@ -475,7 +476,7 @@ void BackDoorEndpoint::CheckForIRC(int seq, int len, const u_char* data) SignatureFound(irc_signature_found); } -void BackDoorEndpoint::CheckForGnutella(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForGnutella(uint64 seq, int len, const u_char* data) { // After connecting to the server, the connecting client says: // @@ -492,13 +493,13 @@ void BackDoorEndpoint::CheckForGnutella(int seq, int len, const u_char* data) SignatureFound(gnutella_signature_found); } -void BackDoorEndpoint::CheckForGaoBot(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForGaoBot(uint64 seq, int len, const u_char* data) { if ( seq == 1 && CheckForString("220 Bot Server (Win32)", data, len) ) SignatureFound(gaobot_signature_found); } -void BackDoorEndpoint::CheckForKazaa(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForKazaa(uint64 seq, int len, const u_char* data) { // *Some*, though not all, KaZaa connections begin with: // @@ -565,7 +566,7 @@ int is_absolute_url(const u_char* data, int len) return *abs_url_sig_pos == '\0'; } -void BackDoorEndpoint::CheckForHTTP(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForHTTP(uint64 seq, int len, const u_char* data) { // According to the RFC, we should look for // ' SP SP HTTP/ CR LF' @@ -629,7 +630,7 @@ void BackDoorEndpoint::CheckForHTTP(int seq, int len, const u_char* data) } } -void BackDoorEndpoint::CheckForHTTPProxy(int /* seq */, int len, +void BackDoorEndpoint::CheckForHTTPProxy(uint64 /* seq */, int len, const u_char* data) { // Proxy ONLY accepts absolute URI's: "The absoluteURI form is @@ -713,7 +714,7 @@ void BackDoor_Analyzer::Init() } void BackDoor_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/backdoor/BackDoor.h b/src/analyzer/protocol/backdoor/BackDoor.h index 5bc8a67381..b1b95ca3f8 100644 --- a/src/analyzer/protocol/backdoor/BackDoor.h +++ b/src/analyzer/protocol/backdoor/BackDoor.h @@ -14,7 +14,7 @@ class BackDoorEndpoint { public: BackDoorEndpoint(tcp::TCP_Endpoint* e); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); RecordVal* BuildStats(); @@ -22,23 +22,23 @@ public: void FinalCheckForRlogin(); protected: - void CheckForRlogin(int seq, int len, const u_char* data); + void CheckForRlogin(uint64 seq, int len, const u_char* data); void RloginSignatureFound(int len); - void CheckForTelnet(int seq, int len, const u_char* data); + void CheckForTelnet(uint64 seq, int len, const u_char* data); void TelnetSignatureFound(int len); - void CheckForSSH(int seq, int len, const u_char* data); - void CheckForFTP(int seq, int len, const u_char* data); - void CheckForRootBackdoor(int seq, int len, const u_char* data); - void CheckForNapster(int seq, int len, const u_char* data); - void CheckForGnutella(int seq, int len, const u_char* data); - void CheckForKazaa(int seq, int len, const u_char* data); - void CheckForHTTP(int seq, int len, const u_char* data); - void CheckForHTTPProxy(int seq, int len, const u_char* data); - void CheckForSMTP(int seq, int len, const u_char* data); - void CheckForIRC(int seq, int len, const u_char* data); - void CheckForGaoBot(int seq, int len, const u_char* data); + void CheckForSSH(uint64 seq, int len, const u_char* data); + void CheckForFTP(uint64 seq, int len, const u_char* data); + void CheckForRootBackdoor(uint64 seq, int len, const u_char* data); + void CheckForNapster(uint64 seq, int len, const u_char* data); + void CheckForGnutella(uint64 seq, int len, const u_char* data); + void CheckForKazaa(uint64 seq, int len, const u_char* data); + void CheckForHTTP(uint64 seq, int len, const u_char* data); + void CheckForHTTPProxy(uint64 seq, int len, const u_char* data); + void CheckForSMTP(uint64 seq, int len, const u_char* data); + void CheckForIRC(uint64 seq, int len, const u_char* data); + void CheckForGaoBot(uint64 seq, int len, const u_char* data); void SignatureFound(EventHandlerPtr e, int do_orig = 0); @@ -48,11 +48,11 @@ protected: tcp::TCP_Endpoint* endp; int is_partial; - int max_top_seq; + uint64 max_top_seq; int rlogin_checking_done; int rlogin_num_null; - int rlogin_string_separator_pos; + uint64 rlogin_string_separator_pos; int rlogin_slash_seen; uint32 num_pkts; @@ -80,7 +80,7 @@ protected: // We support both packet and stream input, and can be instantiated // even if the TCP analyzer is not yet reassembling. virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool is_orig); void StatEvent(); diff --git a/src/analyzer/protocol/bittorrent/BitTorrent.cc b/src/analyzer/protocol/bittorrent/BitTorrent.cc index 99fd9dc132..cb6fc0945e 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrent.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrent.cc @@ -68,7 +68,7 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) +void BitTorrent_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); diff --git a/src/analyzer/protocol/bittorrent/BitTorrent.h b/src/analyzer/protocol/bittorrent/BitTorrent.h index 7739463052..2e303f4038 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrent.h +++ b/src/analyzer/protocol/bittorrent/BitTorrent.h @@ -16,7 +16,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index 98adcaa610..43ee6a2b21 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -207,7 +207,7 @@ void BitTorrentTracker_Analyzer::ServerReply(int len, const u_char* data) } } -void BitTorrentTracker_Analyzer::Undelivered(int seq, int len, bool orig) +void BitTorrentTracker_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.h b/src/analyzer/protocol/bittorrent/BitTorrentTracker.h index b041e556b7..2fa5d684cd 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.h +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.h @@ -49,7 +49,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/conn-size/ConnSize.cc b/src/analyzer/protocol/conn-size/ConnSize.cc index 227a4b1be2..5bfeb2bf90 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -36,7 +36,7 @@ void ConnSize_Analyzer::Done() Analyzer::Done(); } -void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) +void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/conn-size/ConnSize.h b/src/analyzer/protocol/conn-size/ConnSize.h index 25f096dd32..ec3b85c0d9 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.h +++ b/src/analyzer/protocol/conn-size/ConnSize.h @@ -26,7 +26,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); uint64_t orig_bytes; diff --git a/src/analyzer/protocol/dhcp/DHCP.cc b/src/analyzer/protocol/dhcp/DHCP.cc index 1fa8759fbf..78b1c6be69 100644 --- a/src/analyzer/protocol/dhcp/DHCP.cc +++ b/src/analyzer/protocol/dhcp/DHCP.cc @@ -21,7 +21,7 @@ void DHCP_Analyzer::Done() } void DHCP_Analyzer::DeliverPacket(int len, const u_char* data, - bool orig, int seq, const IP_Hdr* ip, int caplen) + bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); interp->NewData(orig, data, data + len); diff --git a/src/analyzer/protocol/dhcp/DHCP.h b/src/analyzer/protocol/dhcp/DHCP.h index a1c06e8b85..7633d71351 100644 --- a/src/analyzer/protocol/dhcp/DHCP.h +++ b/src/analyzer/protocol/dhcp/DHCP.h @@ -14,7 +14,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new DHCP_Analyzer(conn); } diff --git a/src/analyzer/protocol/dnp3/DNP3.cc b/src/analyzer/protocol/dnp3/DNP3.cc index ee90a0c74d..9d9ddf0c35 100644 --- a/src/analyzer/protocol/dnp3/DNP3.cc +++ b/src/analyzer/protocol/dnp3/DNP3.cc @@ -153,7 +153,7 @@ void DNP3_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void DNP3_Analyzer::Undelivered(int seq, int len, bool orig) +void DNP3_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/dnp3/DNP3.h b/src/analyzer/protocol/dnp3/DNP3.h index b84d3874b4..a0578808a8 100644 --- a/src/analyzer/protocol/dnp3/DNP3.h +++ b/src/analyzer/protocol/dnp3/DNP3.h @@ -14,7 +14,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index a97c7b8632..1c77fc6b51 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -835,34 +835,61 @@ int DNS_Interpreter::ParseRR_HINFO(DNS_MsgInfo* msg, return 1; } +static StringVal* extract_char_string(analyzer::Analyzer* analyzer, + const u_char*& data, int& len, int& rdlen) + { + if ( rdlen <= 0 ) + return 0; + + uint8 str_size = data[0]; + + --rdlen; + --len; + ++data; + + if ( str_size > rdlen ) + { + analyzer->Weird("DNS_TXT_char_str_past_rdlen"); + return 0; + } + + StringVal* rval = new StringVal(str_size, + reinterpret_cast(data)); + + rdlen -= str_size; + len -= str_size; + data += str_size; + + return rval; + } + int DNS_Interpreter::ParseRR_TXT(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start) { - int name_len = data[0]; - - char* name = new char[name_len]; - - memcpy(name, data+1, name_len); - - data += rdlength; - len -= rdlength; - - if ( dns_TXT_reply && ! msg->skip_event ) + if ( ! dns_TXT_reply || msg->skip_event ) { - val_list* vl = new val_list; - - vl->append(analyzer->BuildConnVal()); - vl->append(msg->BuildHdrVal()); - vl->append(msg->BuildAnswerVal()); - vl->append(new StringVal(name_len, name)); - - analyzer->ConnectionEvent(dns_TXT_reply, vl); + data += rdlength; + len -= rdlength; + return 1; } - delete [] name; + VectorVal* char_strings = new VectorVal(string_vec); + StringVal* char_string; - return 1; + while ( (char_string = extract_char_string(analyzer, data, len, rdlength)) ) + char_strings->Assign(char_strings->Size(), char_string); + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(char_strings); + + analyzer->ConnectionEvent(dns_TXT_reply, vl); + + return rdlength == 0; } void DNS_Interpreter::SendReplyOrRejectEvent(DNS_MsgInfo* msg, @@ -1146,7 +1173,7 @@ void DNS_Analyzer::Done() } void DNS_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/dns/DNS.h b/src/analyzer/protocol/dns/DNS.h index af4b8de22f..2cc1615b04 100644 --- a/src/analyzer/protocol/dns/DNS.h +++ b/src/analyzer/protocol/dns/DNS.h @@ -258,7 +258,7 @@ public: ~DNS_Analyzer(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void Init(); virtual void Done(); diff --git a/src/analyzer/protocol/dns/events.bif b/src/analyzer/protocol/dns/events.bif index 520e32fe6d..9350939a2e 100644 --- a/src/analyzer/protocol/dns/events.bif +++ b/src/analyzer/protocol/dns/events.bif @@ -367,7 +367,7 @@ event dns_MX_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string, ## ## ans: The type-independent part of the parsed answer record. ## -## str: The textual information returned by the reply. +## strs: The textual information returned by the reply. ## ## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl ## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply @@ -376,7 +376,7 @@ event dns_MX_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string, ## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply ## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout ## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%); +event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, strs: string_vec%); ## Generated for DNS replies of type *SRV*. For replies with multiple answers, ## an individual event of the corresponding type is raised for each. @@ -392,11 +392,17 @@ event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%) ## ## ans: The type-independent part of the parsed answer record. ## -## priority: Priority of the SRV response. +## target: Target of the SRV response -- the canonical hostname of the +## machine providing the service, ending in a dot. ## -## weight: Weight of the SRV response. +## priority: Priority of the SRV response -- the priority of the target +## host, lower value means more preferred. ## -## p: Port of the SRV response. +## weight: Weight of the SRV response -- a relative weight for records +## with the same priority, higher value means more preferred. +## +## p: Port of the SRV response -- the TCP or UDP port on which the +## service is to be found. ## ## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl ## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply @@ -408,8 +414,7 @@ event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%) event dns_SRV_reply%(c: connection, msg: dns_msg, ans: dns_answer, target: string, priority: count, weight: count, p: count%); ## Generated on DNS reply resource records when the type of record is not one -## that Bro knows how to parse and generate another more specific specific -## event. +## that Bro knows how to parse and generate another more specific event. ## ## c: The connection, which may be UDP or TCP depending on the type of the ## transport-layer session being analyzed. diff --git a/src/analyzer/protocol/file/File.cc b/src/analyzer/protocol/file/File.cc index 4476043721..b7e00c7fa4 100644 --- a/src/analyzer/protocol/file/File.cc +++ b/src/analyzer/protocol/file/File.cc @@ -31,12 +31,25 @@ void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig) if ( buffer_len == BUFFER_SIZE ) Identify(); } - return; + + if ( orig ) + file_id_orig = file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), + orig, file_id_orig); + else + file_id_resp = file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), + orig, file_id_resp); } -void File_Analyzer::Undelivered(int seq, int len, bool orig) +void File_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + + if ( orig ) + file_id_orig = file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig, + file_id_orig); + else + file_id_resp = file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig, + file_id_resp); } void File_Analyzer::Done() @@ -45,6 +58,16 @@ void File_Analyzer::Done() if ( buffer_len && buffer_len != BUFFER_SIZE ) Identify(); + + if ( ! file_id_orig.empty() ) + file_mgr->EndOfFile(file_id_orig); + else + file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), true); + + if ( ! file_id_resp.empty() ) + file_mgr->EndOfFile(file_id_resp); + else + file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), false); } void File_Analyzer::Identify() @@ -61,49 +84,3 @@ void File_Analyzer::Identify() vl->append(new StringVal(match)); ConnectionEvent(file_transferred, vl); } - -IRC_Data::IRC_Data(Connection* conn) - : File_Analyzer("IRC_Data", conn) - { - } - -void IRC_Data::Done() - { - File_Analyzer::Done(); - file_mgr->EndOfFile(GetAnalyzerTag(), Conn()); - } - -void IRC_Data::DeliverStream(int len, const u_char* data, bool orig) - { - File_Analyzer::DeliverStream(len, data, orig); - file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); - } - -void IRC_Data::Undelivered(int seq, int len, bool orig) - { - File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); - } - -FTP_Data::FTP_Data(Connection* conn) - : File_Analyzer("FTP_Data", conn) - { - } - -void FTP_Data::Done() - { - File_Analyzer::Done(); - file_mgr->EndOfFile(GetAnalyzerTag(), Conn()); - } - -void FTP_Data::DeliverStream(int len, const u_char* data, bool orig) - { - File_Analyzer::DeliverStream(len, data, orig); - file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); - } - -void FTP_Data::Undelivered(int seq, int len, bool orig) - { - File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); - } diff --git a/src/analyzer/protocol/file/File.h b/src/analyzer/protocol/file/File.h index 7afbd569c4..0f33b5a395 100644 --- a/src/analyzer/protocol/file/File.h +++ b/src/analyzer/protocol/file/File.h @@ -17,7 +17,7 @@ public: virtual void DeliverStream(int len, const u_char* data, bool orig); - void Undelivered(int seq, int len, bool orig); + void Undelivered(uint64 seq, int len, bool orig); // static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) // { return new File_Analyzer(conn); } @@ -28,17 +28,15 @@ protected: static const int BUFFER_SIZE = 1024; char buffer[BUFFER_SIZE]; int buffer_len; + string file_id_orig; + string file_id_resp; }; class IRC_Data : public File_Analyzer { public: - IRC_Data(Connection* conn); - - virtual void Done(); - - virtual void DeliverStream(int len, const u_char* data, bool orig); - - virtual void Undelivered(int seq, int len, bool orig); + IRC_Data(Connection* conn) + : File_Analyzer("IRC_Data", conn) + { } static Analyzer* InstantiateAnalyzer(Connection* conn) { return new IRC_Data(conn); } @@ -46,13 +44,9 @@ public: class FTP_Data : public File_Analyzer { public: - FTP_Data(Connection* conn); - - virtual void Done(); - - virtual void DeliverStream(int len, const u_char* data, bool orig); - - virtual void Undelivered(int seq, int len, bool orig); + FTP_Data(Connection* conn) + : File_Analyzer("FTP_Data", conn) + { } static Analyzer* InstantiateAnalyzer(Connection* conn) { return new FTP_Data(conn); } diff --git a/src/analyzer/protocol/gtpv1/GTPv1.cc b/src/analyzer/protocol/gtpv1/GTPv1.cc index 0a94a28554..361e602b5f 100644 --- a/src/analyzer/protocol/gtpv1/GTPv1.cc +++ b/src/analyzer/protocol/gtpv1/GTPv1.cc @@ -23,7 +23,7 @@ void GTPv1_Analyzer::Done() Event(udp_session_done); } -void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); try diff --git a/src/analyzer/protocol/gtpv1/GTPv1.h b/src/analyzer/protocol/gtpv1/GTPv1.h index b58405ea7f..eebaf1d83e 100644 --- a/src/analyzer/protocol/gtpv1/GTPv1.h +++ b/src/analyzer/protocol/gtpv1/GTPv1.h @@ -12,7 +12,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new GTPv1_Analyzer(conn); } diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index f676643b7c..02b6947b9f 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -243,10 +243,10 @@ int HTTP_Entity::Undelivered(int64_t len) return 0; if ( is_partial_content ) - file_mgr->Gap(body_length, len, + precomputed_file_id = file_mgr->Gap(body_length, len, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), - http_message->IsOrig()); + http_message->IsOrig(), precomputed_file_id); else precomputed_file_id = file_mgr->Gap(body_length, len, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), @@ -306,15 +306,15 @@ void HTTP_Entity::SubmitData(int len, const char* buf) if ( is_partial_content ) { if ( send_size && instance_length > 0 ) - file_mgr->SetSize(instance_length, + precomputed_file_id = file_mgr->SetSize(instance_length, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), - http_message->IsOrig()); + http_message->IsOrig(), precomputed_file_id); - file_mgr->DataIn(reinterpret_cast(buf), len, offset, + precomputed_file_id = file_mgr->DataIn(reinterpret_cast(buf), len, offset, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), - http_message->IsOrig()); + http_message->IsOrig(), precomputed_file_id); offset += len; } @@ -583,9 +583,16 @@ void HTTP_Message::Done(const int interrupted, const char* detail) top_level->EndOfData(); if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 ) - // multipart/byteranges may span multiple connections - file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), - MyHTTP_Analyzer()->Conn(), is_orig); + { + // multipart/byteranges may span multiple connections, so don't EOF. + HTTP_Entity* he = dynamic_cast(top_level); + + if ( he && ! he->FileID().empty() ) + file_mgr->EndOfFile(he->FileID()); + else + file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), + MyHTTP_Analyzer()->Conn(), is_orig); + } if ( http_message_done ) { @@ -663,8 +670,15 @@ void HTTP_Message::EndEntity(mime::MIME_Entity* entity) Done(); else if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 ) - file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), - MyHTTP_Analyzer()->Conn(), is_orig); + { + HTTP_Entity* he = dynamic_cast(entity); + + if ( he && ! he->FileID().empty() ) + file_mgr->EndOfFile(he->FileID()); + else + file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), + MyHTTP_Analyzer()->Conn(), is_orig); + } } void HTTP_Message::SubmitHeader(mime::MIME_Header* h) @@ -1115,11 +1129,11 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) } } -void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) +void HTTP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); - // DEBUG_MSG("Undelivered from %d: %d bytes\n", seq, length); + // DEBUG_MSG("Undelivered from %"PRIu64": %d bytes\n", seq, length); HTTP_Message* msg = is_orig ? request_message : reply_message; @@ -1131,7 +1145,7 @@ void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) { if ( msg ) msg->SubmitEvent(mime::MIME_EVENT_CONTENT_GAP, - fmt("seq=%d, len=%d", seq, len)); + fmt("seq=%"PRIu64", len=%d", seq, len)); } // Check if the content gap falls completely within a message body diff --git a/src/analyzer/protocol/http/HTTP.h b/src/analyzer/protocol/http/HTTP.h index 48a611b63b..826903d795 100644 --- a/src/analyzer/protocol/http/HTTP.h +++ b/src/analyzer/protocol/http/HTTP.h @@ -46,6 +46,7 @@ public: int64_t BodyLength() const { return body_length; } int64_t HeaderLength() const { return header_length; } void SkipBody() { deliver_body = 0; } + const string& FileID() const { return precomputed_file_id; } protected: class UncompressedOutput; @@ -161,7 +162,7 @@ public: HTTP_Analyzer(Connection* conn); ~HTTP_Analyzer(); - void Undelivered(tcp::TCP_Endpoint* sender, int seq, int len); + void Undelivered(tcp::TCP_Endpoint* sender, uint64 seq, int len); void HTTP_Header(int is_orig, mime::MIME_Header* h); void HTTP_EntityData(int is_orig, const BroString* entity_data); @@ -177,7 +178,7 @@ public: // Overriden from Analyzer. virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); // Overriden from tcp::TCP_ApplicationAnalyzer virtual void EndpointEOF(bool is_orig); diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc index 510d3b3a80..393b5536e8 100644 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -31,7 +31,7 @@ void ICMP_Analyzer::Done() } void ICMP_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, const IP_Hdr* ip, int caplen) + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { assert(ip); diff --git a/src/analyzer/protocol/icmp/ICMP.h b/src/analyzer/protocol/icmp/ICMP.h index e371f53889..116348cce6 100644 --- a/src/analyzer/protocol/icmp/ICMP.h +++ b/src/analyzer/protocol/icmp/ICMP.h @@ -29,7 +29,7 @@ protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual bool IsReuse(double t, const u_char* pkt); virtual unsigned int MemoryAllocation() const; diff --git a/src/analyzer/protocol/interconn/InterConn.cc b/src/analyzer/protocol/interconn/InterConn.cc index 4b298eaa52..eb529cbb6d 100644 --- a/src/analyzer/protocol/interconn/InterConn.cc +++ b/src/analyzer/protocol/interconn/InterConn.cc @@ -24,7 +24,7 @@ InterConnEndpoint::InterConnEndpoint(tcp::TCP_Endpoint* e) #define NORMAL_LINE_LENGTH 80 -int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, +int InterConnEndpoint::DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* /* ip */, const struct tcphdr* /* tp */) { @@ -37,8 +37,8 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) is_partial = 1; - int ack = endp->AckSeq() - endp->StartSeq(); - int top_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 top_seq = seq + len; if ( top_seq <= ack || top_seq <= max_top_seq ) // There is no new data in this packet @@ -46,7 +46,7 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, if ( seq < max_top_seq ) { // Only consider new data - int amount_seen = max_top_seq - seq; + int64 amount_seen = max_top_seq - seq; seq += amount_seen; data += amount_seen; len -= amount_seen; @@ -184,7 +184,7 @@ void InterConn_Analyzer::Init() } void InterConn_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, const IP_Hdr* ip, int caplen) + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/interconn/InterConn.h b/src/analyzer/protocol/interconn/InterConn.h index b13abecab1..a485e05082 100644 --- a/src/analyzer/protocol/interconn/InterConn.h +++ b/src/analyzer/protocol/interconn/InterConn.h @@ -13,7 +13,7 @@ class InterConnEndpoint : public BroObj { public: InterConnEndpoint(tcp::TCP_Endpoint* e); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); RecordVal* BuildStats(); @@ -25,7 +25,7 @@ protected: tcp::TCP_Endpoint* endp; double last_keystroke_time; - int max_top_seq; + uint64 max_top_seq; uint32 num_pkts; uint32 num_keystrokes_two_in_a_row; uint32 num_normal_interarrivals; @@ -56,7 +56,7 @@ protected: // We support both packet and stream input and can be put in place even // if the TCP analyzer is not yet reassembling. virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool is_orig); void StatEvent(); diff --git a/src/analyzer/protocol/mime/MIME.cc b/src/analyzer/protocol/mime/MIME.cc index f4e7d3981f..6f992c9256 100644 --- a/src/analyzer/protocol/mime/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -1044,6 +1044,7 @@ void MIME_Entity::DecodeQuotedPrintable(int len, const char* data) { DataOctet((a << 4) + b); legal = 1; + i += 2; } } diff --git a/src/analyzer/protocol/modbus/Modbus.cc b/src/analyzer/protocol/modbus/Modbus.cc index 9d216d356b..f003ad6cc5 100644 --- a/src/analyzer/protocol/modbus/Modbus.cc +++ b/src/analyzer/protocol/modbus/Modbus.cc @@ -31,7 +31,7 @@ void ModbusTCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) interp->NewData(orig, data, data + len); } -void ModbusTCP_Analyzer::Undelivered(int seq, int len, bool orig) +void ModbusTCP_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/modbus/Modbus.h b/src/analyzer/protocol/modbus/Modbus.h index 6f566be828..41448f69e3 100644 --- a/src/analyzer/protocol/modbus/Modbus.h +++ b/src/analyzer/protocol/modbus/Modbus.h @@ -14,7 +14,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/ncp/NCP.cc b/src/analyzer/protocol/ncp/NCP.cc index 75b6c9f4be..3858f0b2ad 100644 --- a/src/analyzer/protocol/ncp/NCP.cc +++ b/src/analyzer/protocol/ncp/NCP.cc @@ -211,7 +211,7 @@ void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig } } -void Contents_NCP_Analyzer::Undelivered(int seq, int len, bool orig) +void Contents_NCP_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); diff --git a/src/analyzer/protocol/ncp/NCP.h b/src/analyzer/protocol/ncp/NCP.h index 34174df74e..2e06babb8c 100644 --- a/src/analyzer/protocol/ncp/NCP.h +++ b/src/analyzer/protocol/ncp/NCP.h @@ -90,7 +90,7 @@ public: protected: virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); NCP_FrameBuffer buffer; NCP_Session* session; diff --git a/src/analyzer/protocol/netbios/NetbiosSSN.cc b/src/analyzer/protocol/netbios/NetbiosSSN.cc index 4d6ed8e1f1..d65a152b2f 100644 --- a/src/analyzer/protocol/netbios/NetbiosSSN.cc +++ b/src/analyzer/protocol/netbios/NetbiosSSN.cc @@ -513,7 +513,7 @@ void NetbiosSSN_Analyzer::ConnectionClosed(tcp::TCP_Endpoint* endpoint, } void NetbiosSSN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/netbios/NetbiosSSN.h b/src/analyzer/protocol/netbios/NetbiosSSN.h index 7c2728ef9a..7fbe967841 100644 --- a/src/analyzer/protocol/netbios/NetbiosSSN.h +++ b/src/analyzer/protocol/netbios/NetbiosSSN.h @@ -146,7 +146,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new NetbiosSSN_Analyzer(conn); } diff --git a/src/analyzer/protocol/ntp/NTP.cc b/src/analyzer/protocol/ntp/NTP.cc index b4b63d5634..5778da9a0e 100644 --- a/src/analyzer/protocol/ntp/NTP.cc +++ b/src/analyzer/protocol/ntp/NTP.cc @@ -25,7 +25,7 @@ void NTP_Analyzer::Done() Event(udp_session_done); } -void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) +void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/ntp/NTP.h b/src/analyzer/protocol/ntp/NTP.h index 201c5a8774..87255fd2e4 100644 --- a/src/analyzer/protocol/ntp/NTP.h +++ b/src/analyzer/protocol/ntp/NTP.h @@ -46,7 +46,7 @@ public: protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); int Request(const u_char* data, int len); int Reply(const u_char* data, int len); diff --git a/src/analyzer/protocol/pia/PIA.cc b/src/analyzer/protocol/pia/PIA.cc index 388d1d501d..24d4565ce1 100644 --- a/src/analyzer/protocol/pia/PIA.cc +++ b/src/analyzer/protocol/pia/PIA.cc @@ -30,7 +30,7 @@ void PIA::ClearBuffer(Buffer* buffer) buffer->size = 0; } -void PIA::AddToBuffer(Buffer* buffer, int seq, int len, const u_char* data, +void PIA::AddToBuffer(Buffer* buffer, uint64 seq, int len, const u_char* data, bool is_orig) { u_char* tmp = 0; @@ -77,7 +77,7 @@ void PIA::PIA_Done() FinishEndpointMatcher(); } -void PIA::PIA_DeliverPacket(int len, const u_char* data, bool is_orig, int seq, +void PIA::PIA_DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { if ( pkt_buffer.state == SKIPPING ) @@ -256,7 +256,7 @@ void PIA_TCP::DeliverStream(int len, const u_char* data, bool is_orig) stream_buffer.state = new_state; } -void PIA_TCP::Undelivered(int seq, int len, bool is_orig) +void PIA_TCP::Undelivered(uint64 seq, int len, bool is_orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); @@ -337,8 +337,8 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule) new tcp::TCP_Reassembler(this, tcp, tcp::TCP_Reassembler::Direct, tcp->Resp()); - int orig_seq = 0; - int resp_seq = 0; + uint64 orig_seq = 0; + uint64 resp_seq = 0; for ( DataBlock* b = pkt_buffer.head; b; b = b->next ) { diff --git a/src/analyzer/protocol/pia/PIA.h b/src/analyzer/protocol/pia/PIA.h index d8c272d219..db387769e8 100644 --- a/src/analyzer/protocol/pia/PIA.h +++ b/src/analyzer/protocol/pia/PIA.h @@ -42,7 +42,7 @@ public: protected: void PIA_Done(); void PIA_DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); enum State { INIT, BUFFERING, MATCHING_ONLY, SKIPPING } state; @@ -52,7 +52,7 @@ protected: const u_char* data; bool is_orig; int len; - int seq; + uint64 seq; DataBlock* next; }; @@ -65,7 +65,7 @@ protected: State state; }; - void AddToBuffer(Buffer* buffer, int seq, int len, + void AddToBuffer(Buffer* buffer, uint64 seq, int len, const u_char* data, bool is_orig); void AddToBuffer(Buffer* buffer, int len, const u_char* data, bool is_orig); @@ -105,7 +105,7 @@ protected: } virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); @@ -150,14 +150,14 @@ protected: } virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); } virtual void DeliverStream(int len, const u_char* data, bool is_orig); - virtual void Undelivered(int seq, int len, bool is_orig); + virtual void Undelivered(uint64 seq, int len, bool is_orig); virtual void ActivateAnalyzer(analyzer::Tag tag, const Rule* rule = 0); diff --git a/src/analyzer/protocol/pop3/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc index 1b6b4c53b6..01ecaa3344 100644 --- a/src/analyzer/protocol/pop3/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -13,6 +13,7 @@ #include "POP3.h" #include "Event.h" #include "Reporter.h" +#include "analyzer/Manager.h" #include "analyzer/protocol/login/NVT.h" #include "events.bif.h" @@ -41,15 +42,18 @@ POP3_Analyzer::POP3_Analyzer(Connection* conn) waitingForAuthentication = false; requestForMultiLine = false; multiLine = false; - backOff = false; + tls = false; lastRequiredCommand = 0; authLines = 0; mail = 0; - AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, true)); - AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, false)); + cl_orig = new tcp::ContentLine_Analyzer(conn, true); + AddSupportAnalyzer(cl_orig); + + cl_resp = new tcp::ContentLine_Analyzer(conn, false); + AddSupportAnalyzer(cl_resp); } POP3_Analyzer::~POP3_Analyzer() @@ -69,7 +73,13 @@ void POP3_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - if ( (TCP() && TCP()->IsPartial()) || backOff ) + if ( tls ) + { + ForwardStream(len, data, orig); + return; + } + + if ( (TCP() && TCP()->IsPartial()) ) return; BroString terminated_string(data, len, 1); @@ -566,7 +576,7 @@ void POP3_Analyzer::ProcessClientCmd() } break; - default: + default: reporter->AnalyzerError(this, "unknown POP3 command"); return; } @@ -701,7 +711,7 @@ void POP3_Analyzer::ProcessReply(int length, const char* line) case RETR: { int data_len = end_of_line - line; - if ( ! mail ) + if ( ! mail ) BeginData(); ProcessData(data_len, line); if ( requestForMultiLine == true ) @@ -717,8 +727,8 @@ void POP3_Analyzer::ProcessReply(int length, const char* line) break; case STLS: - backOff = true; - POP3Event(pop3_terminate, false, "Terminating due to TLS"); + tls = true; + StartTLS(); return; case QUIT: @@ -798,12 +808,29 @@ void POP3_Analyzer::ProcessReply(int length, const char* line) FinishClientCmd(); break; - default: + default: Weird("pop3_server_sending_client_commands"); break; } } +void POP3_Analyzer::StartTLS() + { + // STARTTLS was succesful. Remove support analyzers, add SSL + // analyzer, and throw event signifying the change. + RemoveSupportAnalyzer(cl_orig); + RemoveSupportAnalyzer(cl_resp); + + Analyzer* ssl = analyzer_mgr->InstantiateAnalyzer("SSL", Conn()); + if ( ssl ) + AddChildAnalyzer(ssl); + + val_list* vl = new val_list; + vl->append(BuildConnVal()); + + ConnectionEvent(pop3_starttls, vl); + } + void POP3_Analyzer::AuthSuccessfull() { if ( user.size() ) diff --git a/src/analyzer/protocol/pop3/POP3.h b/src/analyzer/protocol/pop3/POP3.h index ab535420e5..12fcfc2e57 100644 --- a/src/analyzer/protocol/pop3/POP3.h +++ b/src/analyzer/protocol/pop3/POP3.h @@ -10,6 +10,7 @@ #include #include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" #include "analyzer/protocol/login/NVT.h" #include "analyzer/protocol/mime/MIME.h" @@ -97,6 +98,7 @@ protected: void BeginData(); void ProcessData(int length, const char* line); void EndData(); + void StartTLS(); vector TokenizeLine(const string input, const char split); int ParseCmd(string cmd); @@ -108,7 +110,9 @@ protected: list cmds; private: - bool backOff; + bool tls; + tcp::ContentLine_Analyzer* cl_orig; + tcp::ContentLine_Analyzer* cl_resp; }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/pop3/events.bif b/src/analyzer/protocol/pop3/events.bif index 7692c61f6b..74cf1f6f68 100644 --- a/src/analyzer/protocol/pop3/events.bif +++ b/src/analyzer/protocol/pop3/events.bif @@ -13,7 +13,7 @@ ## arg: The argument to the command. ## ## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply -## pop3_terminate pop3_unexpected +## pop3_unexpected ## ## .. todo:: Bro's current default configuration does not activate the protocol ## analyzer that generates this event; the corresponding script has not yet @@ -37,8 +37,8 @@ event pop3_request%(c: connection, is_orig: bool, ## ## msg: The textual description the server sent along with *cmd*. ## -## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_request -## pop3_terminate pop3_unexpected +## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_request +## pop3_unexpected ## ## .. todo:: This event is receiving odd parameters, should unify. ## @@ -62,8 +62,8 @@ event pop3_reply%(c: connection, is_orig: bool, cmd: string, msg: string%); ## ## data: The data sent. ## -## .. bro:see:: pop3_login_failure pop3_login_success pop3_reply pop3_request -## pop3_terminate pop3_unexpected +## .. bro:see:: pop3_login_failure pop3_login_success pop3_reply pop3_request +## pop3_unexpected ## ## .. todo:: Bro's current default configuration does not activate the protocol ## analyzer that generates this event; the corresponding script has not yet @@ -87,7 +87,6 @@ event pop3_data%(c: connection, is_orig: bool, data: string%); ## detail: The input that triggered the event. ## ## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply pop3_request -## pop3_terminate ## ## .. todo:: Bro's current default configuration does not activate the protocol ## analyzer that generates this event; the corresponding script has not yet @@ -106,21 +105,14 @@ event pop3_unexpected%(c: connection, is_orig: bool, ## ## c: The connection. ## -## is_orig: Always false. -## -## msg: A descriptive message why processing was stopped. -## -## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply pop3_request -## pop3_unexpected -## -## .. note:: Currently, only the ``STARTLS`` command is recognized and -## triggers this. +## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply +## pop3_request pop3_unexpected ## ## .. todo:: Bro's current default configuration does not activate the protocol ## analyzer that generates this event; the corresponding script has not yet ## been ported to Bro 2.x. To still enable this event, one needs to ## register a port for it or add a DPD payload signature. -event pop3_terminate%(c: connection, is_orig: bool, msg: string%); +event pop3_starttls%(c: connection%); ## Generated for successful authentications on POP3 connections. ## @@ -136,7 +128,7 @@ event pop3_terminate%(c: connection, is_orig: bool, msg: string%); ## ## password: The password used for authentication. ## -## .. bro:see:: pop3_data pop3_login_failure pop3_reply pop3_request pop3_terminate +## .. bro:see:: pop3_data pop3_login_failure pop3_reply pop3_request ## pop3_unexpected ## ## .. todo:: Bro's current default configuration does not activate the protocol @@ -160,7 +152,7 @@ event pop3_login_success%(c: connection, is_orig: bool, ## ## password: The password attempted for authentication. ## -## .. bro:see:: pop3_data pop3_login_success pop3_reply pop3_request pop3_terminate +## .. bro:see:: pop3_data pop3_login_success pop3_reply pop3_request ## pop3_unexpected ## ## .. todo:: Bro's current default configuration does not activate the protocol diff --git a/src/analyzer/protocol/radius/CMakeLists.txt b/src/analyzer/protocol/radius/CMakeLists.txt new file mode 100644 index 0000000000..022b8a3ac0 --- /dev/null +++ b/src/analyzer/protocol/radius/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro RADIUS) + bro_plugin_cc(RADIUS.cc Plugin.cc) + bro_plugin_bif(events.bif) + bro_plugin_pac(radius.pac radius-analyzer.pac radius-protocol.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/radius/Plugin.cc b/src/analyzer/protocol/radius/Plugin.cc new file mode 100644 index 0000000000..1c31f82da5 --- /dev/null +++ b/src/analyzer/protocol/radius/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "RADIUS.h" + +BRO_PLUGIN_BEGIN(Bro, RADIUS) + BRO_PLUGIN_DESCRIPTION("RADIUS analyzer"); + BRO_PLUGIN_ANALYZER("RADIUS", RADIUS::RADIUS_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/radius/RADIUS.cc b/src/analyzer/protocol/radius/RADIUS.cc new file mode 100644 index 0000000000..f9f0d44e1a --- /dev/null +++ b/src/analyzer/protocol/radius/RADIUS.cc @@ -0,0 +1,40 @@ +// Generated by binpac_quickstart + +#include "RADIUS.h" + +#include "Reporter.h" + +#include "events.bif.h" + +using namespace analyzer::RADIUS; + +RADIUS_Analyzer::RADIUS_Analyzer(Connection* c) + : analyzer::Analyzer("RADIUS", c) + { + interp = new binpac::RADIUS::RADIUS_Conn(this); + } + +RADIUS_Analyzer::~RADIUS_Analyzer() + { + delete interp; + } + +void RADIUS_Analyzer::Done() + { + Analyzer::Done(); + } + +void RADIUS_Analyzer::DeliverPacket(int len, const u_char* data, + bool orig, uint64 seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); + } + } diff --git a/src/analyzer/protocol/radius/RADIUS.h b/src/analyzer/protocol/radius/RADIUS.h new file mode 100644 index 0000000000..0d0ec72fde --- /dev/null +++ b/src/analyzer/protocol/radius/RADIUS.h @@ -0,0 +1,34 @@ +// Generated by binpac_quickstart + +#ifndef ANALYZER_PROTOCOL_RADIUS_RADIUS_H +#define ANALYZER_PROTOCOL_RADIUS_RADIUS_H + +#include "events.bif.h" + + +#include "analyzer/protocol/udp/UDP.h" + +#include "radius_pac.h" + +namespace analyzer { namespace RADIUS { + +class RADIUS_Analyzer : public analyzer::Analyzer { +public: + RADIUS_Analyzer(Connection* conn); + virtual ~RADIUS_Analyzer(); + + // Overriden from Analyzer. + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + uint64 seq, const IP_Hdr* ip, int caplen); + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new RADIUS_Analyzer(conn); } + +protected: + binpac::RADIUS::RADIUS_Conn* interp; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/radius/events.bif b/src/analyzer/protocol/radius/events.bif new file mode 100644 index 0000000000..337d18aa9f --- /dev/null +++ b/src/analyzer/protocol/radius/events.bif @@ -0,0 +1,27 @@ +## Generated for RADIUS messages. +## +## See `Wikipedia `__ for more +## information about RADIUS. +## +## c: The connection. +## +## result: A record containing fields parsed from a RADIUS packet. +## +event radius_message%(c: connection, result: RADIUS::Message%); + +## Generated for each RADIUS attribute. +## +## See `Wikipedia `__ for more +## information about RADIUS. +## +## c: The connection. +## +## attr_type: The value of the code field (1 == User-Name, 2 == User-Password, etc.). +## +## value: The data/value bound to the attribute. +## +event radius_attribute%(c: connection, attr_type: count, value: string%); + +type RADIUS::AttributeList: vector; +type RADIUS::Attributes: table; +type RADIUS::Message: record; diff --git a/src/analyzer/protocol/radius/radius-analyzer.pac b/src/analyzer/protocol/radius/radius-analyzer.pac new file mode 100644 index 0000000000..edeb509436 --- /dev/null +++ b/src/analyzer/protocol/radius/radius-analyzer.pac @@ -0,0 +1,66 @@ + +refine flow RADIUS_Flow += { + function proc_radius_message(msg: RADIUS_PDU): bool + %{ + connection()->bro_analyzer()->ProtocolConfirmation(); + + if ( ! radius_message ) + return false; + + RecordVal* result = new RecordVal(BifType::Record::RADIUS::Message); + result->Assign(0, new Val(${msg.code}, TYPE_COUNT)); + result->Assign(1, new Val(${msg.trans_id}, TYPE_COUNT)); + result->Assign(2, bytestring_to_val(${msg.authenticator})); + + if ( ${msg.attributes}->size() ) + { + TableVal* attributes = new TableVal(BifType::Table::RADIUS::Attributes); + + for ( uint i = 0; i < ${msg.attributes}->size(); ++i ) { + Val* index = new Val(${msg.attributes[i].code}, TYPE_COUNT); + + // Do we already have a vector of attributes for this type? + Val* current = attributes->Lookup(index); + Val* val = bytestring_to_val(${msg.attributes[i].value}); + + if ( current ) + { + VectorVal* vcurrent = current->AsVectorVal(); + vcurrent->Assign(vcurrent->Size(), val); + } + + else + { + VectorVal* attribute_list = new VectorVal(BifType::Vector::RADIUS::AttributeList); + attribute_list->Assign((unsigned int)0, val); + attributes->Assign(index, attribute_list); + } + + Unref(index); + } + + result->Assign(3, attributes); + } + + BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), result); + return true; + %} + + function proc_radius_attribute(attr: RADIUS_Attribute): bool + %{ + if ( ! radius_attribute ) + return false; + + BifEvent::generate_radius_attribute(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), + ${attr.code}, bytestring_to_val(${attr.value})); + return true; + %} +}; + +refine typeattr RADIUS_PDU += &let { + proc: bool = $context.flow.proc_radius_message(this); +}; + +refine typeattr RADIUS_Attribute += &let { + proc: bool = $context.flow.proc_radius_attribute(this); +}; diff --git a/src/analyzer/protocol/radius/radius-protocol.pac b/src/analyzer/protocol/radius/radius-protocol.pac new file mode 100644 index 0000000000..9feca621f7 --- /dev/null +++ b/src/analyzer/protocol/radius/radius-protocol.pac @@ -0,0 +1,14 @@ + +type RADIUS_PDU(is_orig: bool) = record { + code: uint8; + trans_id: uint8; + length: uint16; + authenticator: bytestring &length=16; + attributes: RADIUS_Attribute(trans_id)[] &until($input.length() == 0); +} &byteorder=bigendian; + +type RADIUS_Attribute(trans_id: uint8) = record { + code: uint8; + length: uint8; + value: bytestring &length=length-2; +}; diff --git a/src/analyzer/protocol/radius/radius.pac b/src/analyzer/protocol/radius/radius.pac new file mode 100644 index 0000000000..2c3ddca969 --- /dev/null +++ b/src/analyzer/protocol/radius/radius.pac @@ -0,0 +1,30 @@ +# Analyzer for RADIUS +# - radius-protocol.pac: describes the RADIUS protocol messages +# - radius-analyzer.pac: describes the RADIUS analyzer code + +%include binpac.pac +%include bro.pac + +%extern{ + #include "events.bif.h" +%} + +analyzer RADIUS withcontext { + connection: RADIUS_Conn; + flow: RADIUS_Flow; +}; + +# Our connection consists of two flows, one in each direction. +connection RADIUS_Conn(bro_analyzer: BroAnalyzer) { + upflow = RADIUS_Flow(true); + downflow = RADIUS_Flow(false); +}; + +%include radius-protocol.pac + +# Now we define the flow: +flow RADIUS_Flow(is_orig: bool) { + datagram = RADIUS_PDU(is_orig) withcontext(connection, this); +}; + +%include radius-analyzer.pac diff --git a/src/analyzer/protocol/rpc/RPC.cc b/src/analyzer/protocol/rpc/RPC.cc index 1ffc7dd26e..38ed229a10 100644 --- a/src/analyzer/protocol/rpc/RPC.cc +++ b/src/analyzer/protocol/rpc/RPC.cc @@ -399,7 +399,7 @@ Contents_RPC::~Contents_RPC() { } -void Contents_RPC::Undelivered(int seq, int len, bool orig) +void Contents_RPC::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); NeedResync(); @@ -704,7 +704,7 @@ RPC_Analyzer::~RPC_Analyzer() } void RPC_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); len = min(len, caplen); diff --git a/src/analyzer/protocol/rpc/RPC.h b/src/analyzer/protocol/rpc/RPC.h index a705d272f6..e87f8afa95 100644 --- a/src/analyzer/protocol/rpc/RPC.h +++ b/src/analyzer/protocol/rpc/RPC.h @@ -203,7 +203,7 @@ protected: virtual void Init(); virtual bool CheckResync(int& len, const u_char*& data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void NeedResync() { resync_state = NEED_RESYNC; @@ -234,7 +234,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); void ExpireTimer(double t); diff --git a/src/analyzer/protocol/smtp/SMTP.cc b/src/analyzer/protocol/smtp/SMTP.cc index c3fb21b6a4..61ed1a4949 100644 --- a/src/analyzer/protocol/smtp/SMTP.cc +++ b/src/analyzer/protocol/smtp/SMTP.cc @@ -8,7 +8,7 @@ #include "SMTP.h" #include "Event.h" #include "Reporter.h" -#include "analyzer/protocol/tcp/ContentLine.h" +#include "analyzer/Manager.h" #include "events.bif.h" @@ -44,12 +44,12 @@ SMTP_Analyzer::SMTP_Analyzer(Connection* conn) line_after_gap = 0; mail = 0; UpdateState(first_cmd, 0); - tcp::ContentLine_Analyzer* cl_orig = new tcp::ContentLine_Analyzer(conn, true); + cl_orig = new tcp::ContentLine_Analyzer(conn, true); cl_orig->SetIsNULSensitive(true); cl_orig->SetSkipPartial(true); AddSupportAnalyzer(cl_orig); - tcp::ContentLine_Analyzer* cl_resp = new tcp::ContentLine_Analyzer(conn, false); + cl_resp = new tcp::ContentLine_Analyzer(conn, false); cl_resp->SetIsNULSensitive(true); cl_resp->SetSkipPartial(true); AddSupportAnalyzer(cl_resp); @@ -76,14 +76,14 @@ void SMTP_Analyzer::Done() EndData(); } -void SMTP_Analyzer::Undelivered(int seq, int len, bool is_orig) +void SMTP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); if ( len <= 0 ) return; - const char* buf = fmt("seq = %d, len = %d", seq, len); + const char* buf = fmt("seq = %"PRIu64", len = %d", seq, len); int buf_len = strlen(buf); Unexpected(is_orig, "content gap", buf_len, buf); @@ -118,6 +118,13 @@ void SMTP_Analyzer::DeliverStream(int length, const u_char* line, bool orig) { tcp::TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); + // If an TLS transaction has been initiated, forward to child and abort. + if ( state == SMTP_IN_TLS ) + { + ForwardStream(length, line, orig); + return; + } + // NOTE: do not use IsOrig() here, because of TURN command. int is_sender = orig_is_sender ? orig : ! orig; @@ -152,10 +159,6 @@ void SMTP_Analyzer::DeliverStream(int length, const u_char* line, bool orig) void SMTP_Analyzer::ProcessLine(int length, const char* line, bool orig) { const char* end_of_line = line + length; - if ( state == SMTP_IN_TLS ) - // Do not try to parse contents after STARTTLS/220. - return; - int cmd_len = 0; const char* cmd = ""; @@ -380,6 +383,27 @@ void SMTP_Analyzer::NewCmd(const int cmd_code) first_cmd = cmd_code; } +void SMTP_Analyzer::StartTLS() + { + // STARTTLS was succesful. Remove SMTP support analyzers, add SSL + // analyzer, and throw event signifying the change. + state = SMTP_IN_TLS; + expect_sender = expect_recver = 1; + + RemoveSupportAnalyzer(cl_orig); + RemoveSupportAnalyzer(cl_resp); + + Analyzer* ssl = analyzer_mgr->InstantiateAnalyzer("SSL", Conn()); + if ( ssl ) + AddChildAnalyzer(ssl); + + val_list* vl = new val_list; + vl->append(BuildConnVal()); + + ConnectionEvent(smtp_starttls, vl); + } + + // Here we keep a SMTP state machine and update it on each reply. // However, the purpose is NOT to check correctness of SMTP commands @@ -740,8 +764,7 @@ void SMTP_Analyzer::UpdateState(const int cmd_code, const int reply_code) break; case 220: - state = SMTP_IN_TLS; - expect_sender = expect_recver = 1; + StartTLS(); break; case 454: diff --git a/src/analyzer/protocol/smtp/SMTP.h b/src/analyzer/protocol/smtp/SMTP.h index 8caaf846b8..50ccd97d98 100644 --- a/src/analyzer/protocol/smtp/SMTP.h +++ b/src/analyzer/protocol/smtp/SMTP.h @@ -7,6 +7,7 @@ using namespace std; #include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" #include "analyzer/protocol/mime/MIME.h" #undef SMTP_CMD_DEF @@ -44,7 +45,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void ConnectionFinished(int half_finished); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); void SkipData() { skip_data = 1; } // skip delivery of data lines @@ -74,6 +75,7 @@ protected: int detail_len, const char* detail); void UnexpectedCommand(const int cmd_code, const int reply_code); void UnexpectedReply(const int cmd_code, const int reply_code); + void StartTLS(); bool orig_is_sender; int expect_sender, expect_recver; @@ -88,6 +90,10 @@ protected: // after a gap mime::MIME_Mail* mail; + +private: + tcp::ContentLine_Analyzer* cl_orig; + tcp::ContentLine_Analyzer* cl_resp; }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/smtp/events.bif b/src/analyzer/protocol/smtp/events.bif index 4a376bcbf8..cffe3ba202 100644 --- a/src/analyzer/protocol/smtp/events.bif +++ b/src/analyzer/protocol/smtp/events.bif @@ -98,3 +98,11 @@ event smtp_data%(c: connection, is_orig: bool, data: string%); ## ## .. bro:see:: smtp_data smtp_request smtp_reply event smtp_unexpected%(c: connection, is_orig: bool, msg: string, detail: string%); + +## Generated if a connection switched to using TLS using STARTTLS. After this +## event no more SMTP events will be raised for the connection. See the SSL +## analyzer for related SSL events, which will now be generated. +## +## c: The connection. +## +event smtp_starttls%(c: connection%); diff --git a/src/analyzer/protocol/snmp/SNMP.cc b/src/analyzer/protocol/snmp/SNMP.cc index bed2e3c12d..36282087fa 100644 --- a/src/analyzer/protocol/snmp/SNMP.cc +++ b/src/analyzer/protocol/snmp/SNMP.cc @@ -25,7 +25,7 @@ void SNMP_Analyzer::Done() } void SNMP_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/snmp/SNMP.h b/src/analyzer/protocol/snmp/SNMP.h index 31f4450d9b..d01704d2ae 100644 --- a/src/analyzer/protocol/snmp/SNMP.h +++ b/src/analyzer/protocol/snmp/SNMP.h @@ -16,7 +16,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SNMP_Analyzer(conn); } diff --git a/src/analyzer/protocol/snmp/events.bif b/src/analyzer/protocol/snmp/events.bif index 579ccc4640..6105552342 100644 --- a/src/analyzer/protocol/snmp/events.bif +++ b/src/analyzer/protocol/snmp/events.bif @@ -1,6 +1,6 @@ ## An SNMP ``GetRequest-PDU`` message from either :rfc:`1157` or :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -14,7 +14,7 @@ event snmp_get_request%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP ``GetNextRequest-PDU`` message from either :rfc:`1157` or ## :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -28,7 +28,7 @@ event snmp_get_next_request%(c: connection, is_orig: bool, ## An SNMP ``GetResponse-PDU`` message from :rfc:`1157` or a ## ``Response-PDU`` from :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -41,7 +41,7 @@ event snmp_response%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP ``SetRequest-PDU`` message from either :rfc:`1157` or :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -54,7 +54,7 @@ event snmp_set_request%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP ``Trap-PDU`` message from :rfc:`1157`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -67,7 +67,7 @@ event snmp_trap%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP ``GetBulkRequest-PDU`` message from :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -80,7 +80,7 @@ event snmp_get_bulk_request%(c: connection, is_orig: bool, ## An SNMP ``InformRequest-PDU`` message from :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -93,7 +93,7 @@ event snmp_inform_request%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP ``SNMPv2-Trap-PDU`` message from :rfc:`1157`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -106,7 +106,7 @@ event snmp_trapV2%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP ``Report-PDU`` message from :rfc:`3416`. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -119,7 +119,7 @@ event snmp_report%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMP PDU message of unknown type. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -133,7 +133,7 @@ event snmp_unknown_pdu%(c: connection, is_orig: bool, header: SNMP::Header, ## An SNMPv3 ``ScopedPDUData`` of unknown type (neither plaintext or ## an encrypted PDU was in the datagram). ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -146,7 +146,7 @@ event snmp_unknown_scoped_pdu%(c: connection, is_orig: bool, ## An SNMPv3 encrypted PDU message. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## @@ -156,7 +156,7 @@ event snmp_encrypted_pdu%(c: connection, is_orig: bool, header: SNMP::Header%); ## A datagram with an unknown SNMP version. ## -## c: The connection overwhich the SNMP datagram is sent. +## c: The connection over which the SNMP datagram is sent. ## ## is_orig: The endpoint which sent the SNMP datagram. ## diff --git a/src/analyzer/protocol/socks/SOCKS.cc b/src/analyzer/protocol/socks/SOCKS.cc index 76212d822b..e678528f35 100644 --- a/src/analyzer/protocol/socks/SOCKS.cc +++ b/src/analyzer/protocol/socks/SOCKS.cc @@ -86,7 +86,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void SOCKS_Analyzer::Undelivered(int seq, int len, bool orig) +void SOCKS_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/socks/SOCKS.h b/src/analyzer/protocol/socks/SOCKS.h index f005967fd8..2c72d507e6 100644 --- a/src/analyzer/protocol/socks/SOCKS.h +++ b/src/analyzer/protocol/socks/SOCKS.h @@ -23,7 +23,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 6cd2fa59f8..5e5d24888a 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -57,7 +57,7 @@ void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void SSL_Analyzer::Undelivered(int seq, int len, bool orig) +void SSL_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); had_gap = true; diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index f674d64fed..7748222dea 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -16,7 +16,7 @@ public: // Overriden from Analyzer. virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); // Overriden from tcp::TCP_ApplicationAnalyzer. virtual void EndpointEOF(bool is_orig); diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 054d9c672f..18704d25ec 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -24,8 +24,9 @@ ## standardized as part of the SSL/TLS protocol. The ## :bro:id:`SSL::cipher_desc` table maps them to descriptive names. ## -## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello -## ssl_session_ticket_handshake x509_certificate +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate ssl_handshake_message +## ssl_change_cipher_spec event ssl_client_hello%(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec%); ## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions @@ -58,7 +59,8 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client ## standardized as part of the SSL/TLS protocol. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension -## ssl_session_ticket_handshake x509_certificate +## ssl_session_ticket_handshake x509_certificate ssl_server_curve +## ssl_dh_server_params ssl_handshake_message ssl_change_cipher_spec event ssl_server_hello%(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count%); ## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS @@ -66,6 +68,8 @@ event ssl_server_hello%(c: connection, version: count, possible_ts: time, server ## information out of that as it can. This event provides access to any ## extensions either side sends as part of an extended *hello* message. ## +## Note that Bro offers more specialized events for a few extensions. +## ## c: The connection. ## ## is_orig: True if event is raised for originator side of the connection. @@ -77,9 +81,111 @@ event ssl_server_hello%(c: connection, version: count, possible_ts: time, server ## val: The raw extension value that was sent in the message. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake +## ssl_session_ticket_handshake ssl_extension_ec_point_formats +## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); +## Generated for an SSL/TLS Elliptic Curves extension. This TLS extension is +## defined in :rfc:`4492` and sent by the client in the initial handshake. It +## gives the list of elliptic curves supported by the client. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## curves: List of supported elliptic curves. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_ec_point_formats ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name ssl_server_curve +event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); + +## Generated for an SSL/TLS Supported Point Formats extension. This TLS extension +## is defined in :rfc:`4492` and sent by the client and/or server in the initial +## handshake. It gives the list of elliptic curve point formats supported by the +## client. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## point_formats: List of supported point formats. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name ssl_server_curve +event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); + +## Generated if a named curve is chosen by the server for an SSL/TLS connection. +## The curve is sent by the server in the ServerKeyExchange message as defined +## in :rfc:`4492`, in case an ECDH or ECDHE cipher suite is chosen. +## +## c: The connection. +## +## curve: The curve. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name +event ssl_server_curve%(c: connection, curve: count%); + +## Generated if a server uses a DH-anon or DHE cipher suite. This event contains +## the server DH parameters, which are sent in the ServerKeyExchange message as +## defined in :rfc:`5246`. +## +## c: The connection. +## +## p: The DH prime modulus. +## +## q: The DH generator. +## +## Ys: The server's DH public key. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_server_curve +event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%); + +## Generated for an SSL/TLS Application-Layer Protocol Negotiation extension. +## This TLS extension is defined in draft-ietf-tls-applayerprotoneg and sent in +## the initial handshake. It contains the list of client supported application +## protocols by the client or the server, respectively. +## +## At the moment it is mostly used to negotiate the use of SPDY / HTTP2-drafts. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## protocols: List of supported application layer protocols. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_ec_point_formats +## ssl_extension_server_name +event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%); + +## Generated for an SSL/TLS Server Name extension. This SSL/TLS extension is +## defined in :rfc:`3546` and sent by the client in the initial handshake. It +## contains the name of the server it is contacting. This information can be +## used by the server to choose the correct certificate for the host the client +## wants to contact. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## names: A list of server names (DNS hostnames). +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_ec_point_formats +## ssl_extension_application_layer_protocol_negotiation +event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec%); + ## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with ## an unencrypted handshake, and Bro extracts as much information out of that ## as it can. This event signals the time when an SSL/TLS has finished the @@ -138,3 +244,81 @@ event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); ## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## ssl_alert event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); + +## Generated for SSL/TLS heartbeat messages that are sent before session +## encryption starts. Generally heartbeat messages should rarely be seen in +## normal TLS traffic. Heartbeats are described in :rfc:`6520`. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## length: length of the entire heartbeat message. +## +## heartbeat_type: type of the heartbeat message. Per RFC, 1 = request, 2 = response. +## +## payload_length: length of the payload of the heartbeat message, according to +## packet field. +## +## payload: payload contained in the heartbeat message. Size can differ from +## payload_length, if payload_length and actual packet length disagree. +## +## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello +## ssl_alert ssl_encrypted_data +event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%); + +## Generated for SSL/TLS messages that are sent after session encryption +## started. +## +## Note that :bro:id:`SSL::disable_analyzer_after_detection` has to be changed +## from its default to false for this event to be generated. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## content_type: message type as reported by TLS session layer. +## +## length: length of the entire heartbeat message. +## +## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello +## ssl_alert ssl_heartbeat +event ssl_encrypted_data%(c: connection, is_orig: bool, content_type: count, length: count%); + +## This event contains the OCSP response contained in a Certificate Status Request +## message, when the client requested OCSP stapling and the server supports it. +## See description in :rfc:`6066`. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## response: OCSP data. +event ssl_stapled_ocsp%(c: connection, is_orig: bool, response: string%); + +## This event is raised for each unencrypted SSL/TLS handshake message. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## msg_type: Type of the handshake message that was seen. +## +## length: Length of the handshake message that was seen. +## +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate ssl_client_hello +## ssl_change_cipher_spec +event ssl_handshake_message%(c: connection, is_orig: bool, msg_type: count, length: count%); + +## This event is raised when a SSL/TLS ChangeCipherSpec message is encountered +## before encryption begins. Traffic will be encrypted following this message. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate ssl_client_hello +## ssl_handshake_message +event ssl_change_cipher_spec%(c: connection, is_orig: bool%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 49104fa549..64d5d78df6 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -87,45 +87,16 @@ function version_ok(vers : uint16) : bool refine connection SSL_Conn += { %member{ - int eof; + int established_; %} %init{ - eof=0; + established_ = false; %} - #%eof{ - # if ( ! eof && - # state_ != STATE_CONN_ESTABLISHED && - # state_ != STATE_TRACK_LOST && - # state_ != STATE_INITIAL ) - # bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s", - # state_label(state_).c_str())); - # ++eof; - #%} - %cleanup{ %} - function proc_change_cipher_spec(rec: SSLRecord) : bool - %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected ChangeCipherSpec from %s at state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - return true; - %} - - function proc_application_data(rec: SSLRecord) : bool - %{ - if ( state_ != STATE_CONN_ESTABLISHED && - (state_ != STATE_CLIENT_FINISHED && ! ${rec.is_orig}) ) - bro_analyzer()->ProtocolViolation(fmt("unexpected ApplicationData from %s at state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - return true; - %} - function proc_alert(rec: SSLRecord, level : int, desc : int) : bool %{ BifEvent::generate_ssl_alert(bro_analyzer(), bro_analyzer()->Conn(), @@ -217,12 +188,106 @@ refine connection SSL_Conn += { return true; %} - function proc_ssl_extension(rec: SSLRecord, type: int, data: bytestring) : bool + function proc_ssl_extension(rec: SSLRecord, type: int, sourcedata: const_bytestring) : bool %{ + // We cheat a little bit here. We want to throw this event + // for every extension we encounter, even those that are + // handled by more specialized events later. To access the + // parsed data, we use sourcedata, which contains the whole + // data blob of the extension, including headers. We skip + // over those (4 bytes). + size_t length = sourcedata.length(); + if ( length < 4 ) + { + // This should be impossible due to the binpac parser + // and protocol description + bro_analyzer()->ProtocolViolation(fmt("Impossible extension length: %lu", length)); + return true; + } + + length -= 4; + const unsigned char* data = sourcedata.begin() + 4; + if ( ssl_extension ) BifEvent::generate_ssl_extension(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, type, - new StringVal(data.length(), (const char*) data.data())); + new StringVal(length, reinterpret_cast(data))); + return true; + %} + + function proc_ec_point_formats(rec: SSLRecord, point_format_list: uint8[]) : bool + %{ + VectorVal* points = new VectorVal(internal_type("index_vec")->AsVectorType()); + + if ( point_format_list ) + { + for ( unsigned int i = 0; i < point_format_list->size(); ++i ) + points->Assign(i, new Val((*point_format_list)[i], TYPE_COUNT)); + } + + BifEvent::generate_ssl_extension_ec_point_formats(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, points); + + return true; + %} + + function proc_elliptic_curves(rec: SSLRecord, list: uint16[]) : bool + %{ + VectorVal* curves = new VectorVal(internal_type("index_vec")->AsVectorType()); + + if ( list ) + { + for ( unsigned int i = 0; i < list->size(); ++i ) + curves->Assign(i, new Val((*list)[i], TYPE_COUNT)); + } + + BifEvent::generate_ssl_extension_elliptic_curves(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, curves); + + return true; + %} + + function proc_apnl(rec: SSLRecord, protocols: ProtocolName[]) : bool + %{ + VectorVal* plist = new VectorVal(internal_type("string_vec")->AsVectorType()); + + if ( protocols ) + { + for ( unsigned int i = 0; i < protocols->size(); ++i ) + plist->Assign(i, new StringVal((*protocols)[i]->name().length(), (const char*) (*protocols)[i]->name().data())); + } + + BifEvent::generate_ssl_extension_application_layer_protocol_negotiation(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, plist); + + return true; + %} + + function proc_server_name(rec: SSLRecord, list: ServerName[]) : bool + %{ + VectorVal* servers = new VectorVal(internal_type("string_vec")->AsVectorType()); + + if ( list ) + { + for ( unsigned int i = 0, j = 0; i < list->size(); ++i ) + { + ServerName* servername = (*list)[i]; + if ( servername->name_type() != 0 ) + { + bro_analyzer()->Weird(fmt("Encountered unknown type in server name ssl extension: %d", servername->name_type())); + continue; + } + + if ( servername->host_name() ) + servers->Assign(j++, new StringVal(servername->host_name()->host_name().length(), (const char*) servername->host_name()->host_name().data())); + else + bro_analyzer()->Weird("Empty server_name extension in ssl connection"); + } + } + + BifEvent::generate_ssl_extension_server_name(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, servers); + return true; %} @@ -231,15 +296,26 @@ refine connection SSL_Conn += { if ( certificates->size() == 0 ) return true; + ODesc common; + common.AddRaw("Analyzer::ANALYZER_SSL"); + common.Add(bro_analyzer()->Conn()->StartTime()); + common.AddRaw(${rec.is_orig} ? "T" : "F", 1); + bro_analyzer()->Conn()->IDString(&common); + for ( unsigned int i = 0; i < certificates->size(); ++i ) { const bytestring& cert = (*certificates)[i]; - string fid = file_mgr->DataIn(reinterpret_cast(cert.data()), cert.length(), - bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn(), - ${rec.is_orig}); + ODesc file_handle; + file_handle.Add(common.Description()); + file_handle.Add(i); - file_mgr->EndOfFile(fid); + string file_id = file_mgr->HashHandle(file_handle.Description()); + + file_mgr->DataIn(reinterpret_cast(cert.data()), + cert.length(), bro_analyzer()->GetAnalyzerTag(), + bro_analyzer()->Conn(), ${rec.is_orig}, file_id); + file_mgr->EndOfFile(file_id); } return true; %} @@ -252,9 +328,9 @@ refine connection SSL_Conn += { return ret; %} - function proc_v3_certificate(rec: SSLRecord, cl : CertificateList) : bool + function proc_v3_certificate(rec: SSLRecord, cl : X509Certificate[]) : bool %{ - vector* certs = cl->val(); + vector* certs = cl; vector* cert_list = new vector(); std::transform(certs->begin(), certs->end(), @@ -267,11 +343,6 @@ refine connection SSL_Conn += { function proc_v2_client_master_key(rec: SSLRecord, cipher_kind: int) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected v2 client master key message from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - BifEvent::generate_ssl_established(bro_analyzer(), bro_analyzer()->Conn()); @@ -285,17 +356,6 @@ refine connection SSL_Conn += { return true; %} - function proc_handshake(hs: Handshake, is_orig: bool) : bool - %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected Handshake message %s from %s in state %s", - handshake_type_label(${hs.msg_type}).c_str(), - orig_label(is_orig).c_str(), - state_label(old_state_).c_str())); - - return true; - %} - function proc_unknown_record(rec: SSLRecord) : bool %{ bro_analyzer()->ProtocolViolation(fmt("unknown SSL record type (%d) from %s", @@ -306,25 +366,87 @@ refine connection SSL_Conn += { function proc_ciphertext_record(rec : SSLRecord) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected ciphertext record from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - - else if ( state_ == STATE_CONN_ESTABLISHED && - old_state_ == STATE_COMM_ENCRYPTED ) + if ( client_state_ == STATE_ENCRYPTED && + server_state_ == STATE_ENCRYPTED && + established_ == false ) { + established_ = true; BifEvent::generate_ssl_established(bro_analyzer(), bro_analyzer()->Conn()); } + BifEvent::generate_ssl_encrypted_data(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.content_type}, ${rec.length}); + + return true; + %} + + function proc_heartbeat(rec : SSLRecord, type: uint8, payload_length: uint16, data: bytestring) : bool + %{ + BifEvent::generate_ssl_heartbeat(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}, type, payload_length, + new StringVal(data.length(), (const char*) data.data())); + return true; + %} + + function proc_check_v2_server_hello_version(version: uint16) : bool + %{ + if ( version != SSLv20 ) + bro_analyzer()->ProtocolViolation(fmt("Invalid version in SSL server hello. Version: %d", version)); + + return true; + %} + + function proc_certificate_status(rec : SSLRecord, status_type: uint8, response: bytestring) : bool + %{ + if ( status_type == 1 ) // ocsp + { + BifEvent::generate_ssl_stapled_ocsp(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}, + new StringVal(response.length(), + (const char*) response.data())); + } + + return true; + %} + + function proc_ec_server_key_exchange(rec: SSLRecord, curve_type: uint8, curve: uint16) : bool + %{ + if ( curve_type == NAMED_CURVE ) + BifEvent::generate_ssl_server_curve(bro_analyzer(), + bro_analyzer()->Conn(), curve); + + return true; + %} + + function proc_dh_server_key_exchange(rec: SSLRecord, p: bytestring, g: bytestring, Ys: bytestring) : bool + %{ + BifEvent::generate_ssl_dh_server_params(bro_analyzer(), + bro_analyzer()->Conn(), + new StringVal(p.length(), (const char*) p.data()), + new StringVal(g.length(), (const char*) g.data()), + new StringVal(Ys.length(), (const char*) Ys.data()) + ); + + return true; + %} + + function proc_ccs(rec: SSLRecord) : bool + %{ + BifEvent::generate_ssl_change_cipher_spec(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}); + + return true; + %} + + function proc_handshake(rec: SSLRecord, msg_type: uint8, length: uint24) : bool + %{ + BifEvent::generate_ssl_handshake_message(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}, msg_type, to_int()(length)); + return true; %} -}; -refine typeattr ChangeCipherSpec += &let { - proc : bool = $context.connection.proc_change_cipher_spec(rec) - &requires(state_changed); }; refine typeattr Alert += &let { @@ -335,57 +457,49 @@ refine typeattr V2Error += &let { proc : bool = $context.connection.proc_alert(rec, -1, error_code); }; -refine typeattr ApplicationData += &let { - proc : bool = $context.connection.proc_application_data(rec); +refine typeattr Heartbeat += &let { + proc : bool = $context.connection.proc_heartbeat(rec, type, payload_length, data); }; refine typeattr ClientHello += &let { proc : bool = $context.connection.proc_client_hello(rec, client_version, gmt_unix_time, random_bytes, - session_id, csuits, 0) - &requires(state_changed); + session_id, csuits, 0); }; refine typeattr V2ClientHello += &let { proc : bool = $context.connection.proc_client_hello(rec, client_version, 0, - challenge, session_id, 0, ciphers) - &requires(state_changed); + challenge, session_id, 0, ciphers); }; refine typeattr ServerHello += &let { proc : bool = $context.connection.proc_server_hello(rec, server_version, gmt_unix_time, random_bytes, session_id, cipher_suite, 0, - compression_method) - &requires(state_changed); + compression_method); }; refine typeattr V2ServerHello += &let { proc : bool = $context.connection.proc_server_hello(rec, server_version, 0, - conn_id_data, 0, 0, ciphers, 0) - &requires(state_changed); + conn_id_data, 0, 0, ciphers, 0); + + check_v2 : bool = $context.connection.proc_check_v2_server_hello_version(server_version); cert : bool = $context.connection.proc_v2_certificate(rec, cert_data) &requires(proc); }; refine typeattr Certificate += &let { - proc : bool = $context.connection.proc_v3_certificate(rec, certificates) - &requires(state_changed); + proc : bool = $context.connection.proc_v3_certificate(rec, certificates); }; refine typeattr V2ClientMasterKey += &let { - proc : bool = $context.connection.proc_v2_client_master_key(rec, cipher_kind) - &requires(state_changed); + proc : bool = $context.connection.proc_v2_client_master_key(rec, cipher_kind); }; refine typeattr UnknownHandshake += &let { proc : bool = $context.connection.proc_unknown_handshake(hs, is_orig); }; -refine typeattr Handshake += &let { - proc : bool = $context.connection.proc_handshake(this, rec.is_orig); -}; - refine typeattr SessionTicketHandshake += &let { proc : bool = $context.connection.proc_session_ticket_handshake(this, rec.is_orig); } @@ -399,5 +513,41 @@ refine typeattr CiphertextRecord += &let { } refine typeattr SSLExtension += &let { - proc : bool = $context.connection.proc_ssl_extension(rec, type, data); + proc : bool = $context.connection.proc_ssl_extension(rec, type, sourcedata); +}; + +refine typeattr EcPointFormats += &let { + proc : bool = $context.connection.proc_ec_point_formats(rec, point_format_list); +}; + +refine typeattr EllipticCurves += &let { + proc : bool = $context.connection.proc_elliptic_curves(rec, elliptic_curve_list); +}; + +refine typeattr ApplicationLayerProtocolNegotiationExtension += &let { + proc : bool = $context.connection.proc_apnl(rec, protocol_name_list); +}; + +refine typeattr ServerNameExt += &let { + proc : bool = $context.connection.proc_server_name(rec, server_names); +}; + +refine typeattr CertificateStatus += &let { + proc : bool = $context.connection.proc_certificate_status(rec, status_type, response); +}; + +refine typeattr EcServerKeyExchange += &let { + proc : bool = $context.connection.proc_ec_server_key_exchange(rec, curve_type, curve); +}; + +refine typeattr DhServerKeyExchange += &let { + proc : bool = $context.connection.proc_dh_server_key_exchange(rec, dh_p, dh_g, dh_Ys); +}; + +refine typeattr ChangeCipherSpec += &let { + proc : bool = $context.connection.proc_ccs(rec); +}; + +refine typeattr Handshake += &let { + proc : bool = $context.connection.proc_handshake(rec, msg_type, length); }; diff --git a/src/analyzer/protocol/ssl/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac index c35fc56e85..29eb1d1fb9 100644 --- a/src/analyzer/protocol/ssl/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -12,6 +12,7 @@ enum ContentType { ALERT = 21, HANDSHAKE = 22, APPLICATION_DATA = 23, + HEARTBEAT = 24, V2_ERROR = 300, V2_CLIENT_HELLO = 301, V2_CLIENT_MASTER_KEY = 302, @@ -19,6 +20,7 @@ enum ContentType { UNKNOWN_OR_V2_ENCRYPTED = 400 }; +# If you add a new TLS version here, do not forget to also adjust the DPD signature. enum SSLVersions { UNKNOWN_VERSION = 0x0000, SSLv20 = 0x0002, @@ -27,3 +29,390 @@ enum SSLVersions { TLSv11 = 0x0302, TLSv12 = 0x0303 }; + +enum SSLExtensions { + EXT_SERVER_NAME = 0, + EXT_MAX_FRAGMENT_LENGTH = 1, + EXT_CLIENT_CERTIFICATE_URL = 2, + EXT_TRUSTED_CA_KEYS = 3, + EXT_TRUNCATED_HMAC = 4, + EXT_STATUS_REQUEST = 5, + EXT_USER_MAPPING = 6, + EXT_CLIENT_AUTHZ = 7, + EXT_SERVER_AUTHZ = 8, + EXT_CERT_TYPE = 9, + EXT_ELLIPTIC_CURVES = 10, + EXT_EC_POINT_FORMATS = 11, + EXT_SRP = 12, + EXT_SIGNATURE_ALGORITHMS = 13, + EXT_USE_SRTP = 14, + EXT_HEARTBEAT = 15, + EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16, + EXT_STATUS_REQUEST_V2 = 17, + EXT_SIGNED_CERTIFICATE_TIMESTAMP = 18, + EXT_SESSIONTICKET_TLS = 35, + EXT_EXTENDED_RANDOM = 40, + EXT_NEXT_PROTOCOL_NEGOTIATION = 13172, + EXT_ORIGIN_BOUND_CERTIFICATES = 13175, + EXT_ENCRYPTED_CLIENT_CERTIFICATES = 13180, + EXT_CHANNEL_ID = 30031, + EXT_CHANNEL_ID_NEW = 30032, + EXT_PADDING = 35655, + EXT_RENEGOTIATION_INFO = 65281 +}; + +enum ECCurveType { + EXPLICIT_PRIME = 1, + EXPLICIT_CHAR = 2, + NAMED_CURVE = 3 +}; + +enum TLSCiphers { + NO_CHOSEN_CIPHER = 0xFFFFFF, + TLS_NULL_WITH_NULL_NULL = 0x0000, + TLS_RSA_WITH_NULL_MD5 = 0x0001, + TLS_RSA_WITH_NULL_SHA = 0x0002, + TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003, + TLS_RSA_WITH_RC4_128_MD5 = 0x0004, + TLS_RSA_WITH_RC4_128_SHA = 0x0005, + TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006, + TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007, + TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008, + TLS_RSA_WITH_DES_CBC_SHA = 0x0009, + TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A, + TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B, + TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C, + TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D, + TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E, + TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F, + TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010, + TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011, + TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013, + TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014, + TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016, + TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5 = 0x0017, + TLS_DH_ANON_WITH_RC4_128_MD5 = 0x0018, + TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA = 0x0019, + TLS_DH_ANON_WITH_DES_CBC_SHA = 0x001A, + TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001B, + TLS_KRB5_WITH_DES_CBC_SHA = 0x001E, + TLS_KRB5_WITH_3DES_EDE_CBC_SHA = 0x001F, + TLS_KRB5_WITH_RC4_128_SHA = 0x0020, + TLS_KRB5_WITH_IDEA_CBC_SHA = 0x0021, + TLS_KRB5_WITH_DES_CBC_MD5 = 0x0022, + TLS_KRB5_WITH_3DES_EDE_CBC_MD5 = 0x0023, + TLS_KRB5_WITH_RC4_128_MD5 = 0x0024, + TLS_KRB5_WITH_IDEA_CBC_MD5 = 0x0025, + TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = 0x0026, + TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = 0x0027, + TLS_KRB5_EXPORT_WITH_RC4_40_SHA = 0x0028, + TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = 0x0029, + TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = 0x002A, + TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = 0x002B, + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F, + TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030, + TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033, + TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034, + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035, + TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036, + TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039, + TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A, + TLS_RSA_WITH_NULL_SHA256 = 0x003B, + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C, + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D, + TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E, + TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040, + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041, + TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042, + TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA = 0x0046, + TLS_RSA_EXPORT1024_WITH_RC4_56_MD5 = 0x0060, + TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 = 0x0061, + TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA = 0x0062, + TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = 0x0063, + TLS_RSA_EXPORT1024_WITH_RC4_56_SHA = 0x0064, + TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA = 0x0065, + TLS_DHE_DSS_WITH_RC4_128_SHA = 0x0066, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067, + TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068, + TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B, + TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C, + TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D, + # draft-ietf-tls-openpgp-keys-06 + TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD = 0x0072, + TLS_DHE_DSS_WITH_AES_128_CBC_RMD = 0x0073, + TLS_DHE_DSS_WITH_AES_256_CBC_RMD = 0x0074, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD = 0x0077, + TLS_DHE_RSA_WITH_AES_128_CBC_RMD = 0x0078, + TLS_DHE_RSA_WITH_AES_256_CBC_RMD = 0x0079, + TLS_RSA_WITH_3DES_EDE_CBC_RMD = 0x007C, + TLS_RSA_WITH_AES_128_CBC_RMD = 0x007D, + TLS_RSA_WITH_AES_256_CBC_RMD = 0x007E, + # draft-chudov-cryptopro-cptls-04 + TLS_GOSTR341094_WITH_28147_CNT_IMIT = 0x0080, + TLS_GOSTR341001_WITH_28147_CNT_IMIT = 0x0081, + TLS_GOSTR341094_WITH_NULL_GOSTR3411 = 0x0082, + TLS_GOSTR341001_WITH_NULL_GOSTR3411 = 0x0083, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084, + TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085, + TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA = 0x0089, + TLS_PSK_WITH_RC4_128_SHA = 0x008A, + TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B, + TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C, + TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D, + TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E, + TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091, + TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092, + TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093, + TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094, + TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095, + TLS_RSA_WITH_SEED_CBC_SHA = 0x0096, + TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097, + TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098, + TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099, + TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A, + TLS_DH_ANON_WITH_SEED_CBC_SHA = 0x009B, + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C, + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F, + TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0, + TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1, + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2, + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3, + TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4, + TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5, + TLS_DH_ANON_WITH_AES_128_GCM_SHA256 = 0x00A6, + TLS_DH_ANON_WITH_AES_256_GCM_SHA384 = 0x00A7, + TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8, + TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB, + TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC, + TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD, + TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE, + TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF, + TLS_PSK_WITH_NULL_SHA256 = 0x00B0, + TLS_PSK_WITH_NULL_SHA384 = 0x00B1, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3, + TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4, + TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5, + TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6, + TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7, + TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8, + TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9, + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA, + TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB, + TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0, + TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1, + TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5, + # draft-bmoeller-tls-downgrade-scsv-01 + TLS_FALLBACK_SCSV = 0x5600, + # RFC 4492 + TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005, + TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A, + TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B, + TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F, + TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010, + TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014, + TLS_ECDH_ANON_WITH_NULL_SHA = 0xC015, + TLS_ECDH_ANON_WITH_RC4_128_SHA = 0xC016, + TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA = 0xC017, + TLS_ECDH_ANON_WITH_AES_128_CBC_SHA = 0xC018, + TLS_ECDH_ANON_WITH_AES_256_CBC_SHA = 0xC019, + TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A, + TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B, + TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C, + TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D, + TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E, + TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F, + TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020, + TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021, + TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032, + TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033, + TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038, + TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039, + TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A, + TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B, + # RFC 6209 + TLS_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC03C, + TLS_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC03D, + TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC03E, + TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC03F, + TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC040, + TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC041, + TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC042, + TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC043, + TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC044, + TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC045, + TLS_DH_ANON_WITH_ARIA_128_CBC_SHA256 = 0xC046, + TLS_DH_ANON_WITH_ARIA_256_CBC_SHA384 = 0xC047, + TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC048, + TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC049, + TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC04A, + TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC04B, + TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04C, + TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04D, + TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04E, + TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04F, + TLS_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC050, + TLS_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC051, + TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC052, + TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC053, + TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC054, + TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC055, + TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC056, + TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC057, + TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC058, + TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC059, + TLS_DH_ANON_WITH_ARIA_128_GCM_SHA256 = 0xC05A, + TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384 = 0xC05B, + TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05C, + TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05D, + TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05E, + TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05F, + TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC060, + TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC061, + TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC062, + TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC063, + TLS_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC064, + TLS_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC065, + TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC066, + TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC067, + TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC068, + TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC069, + TLS_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06A, + TLS_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06B, + TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06C, + TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06D, + TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06E, + TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06F, + TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC070, + TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC071, + # RFC 6367 + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077, + TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078, + TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079, + TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A, + TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B, + TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C, + TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D, + TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E, + TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F, + TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080, + TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081, + TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082, + TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083, + TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084, + TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B, + TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C, + TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D, + TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E, + TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F, + TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090, + TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091, + TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092, + TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093, + TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094, + TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095, + TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096, + TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097, + TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098, + TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099, + TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A, + TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B, + # RFC 6655 + TLS_RSA_WITH_AES_128_CCM = 0xC09C, + TLS_RSA_WITH_AES_256_CCM = 0xC09D, + TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E, + TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F, + TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0, + TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1, + TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2, + TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3, + TLS_PSK_WITH_AES_128_CCM = 0xC0A4, + TLS_PSK_WITH_AES_256_CCM = 0xC0A5, + TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6, + TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7, + TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, + TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9, + TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA, + TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF, + # draft-agl-tls-chacha20poly1305-02 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC15 +}; diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index 9368122eaa..8e7f7a221d 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -34,26 +34,25 @@ type SSLRecord(is_orig: bool) = record { head4 : uint8; rec : RecordText(this)[] &length=length, &requires(content_type); } &length = length+5, &byteorder=bigendian, - &let { + &let { version : int = - $context.connection.determine_ssl_version(head0, head1, head2); + $context.connection.determine_ssl_record_layer(head0, head1, head2, head3, head4); content_type : int = case version of { - UNKNOWN_VERSION -> 0; SSLv20 -> head2+300; default -> head0; }; length : int = case version of { + # fail analyzer if the packet cannot be recognized as TLS. UNKNOWN_VERSION -> 0; SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3; default -> (head3 << 8) | head4; }; }; -type RecordText(rec: SSLRecord) = case $context.connection.state() of { - STATE_ABBREV_SERVER_ENCRYPTED, STATE_CLIENT_ENCRYPTED, - STATE_COMM_ENCRYPTED, STATE_CONN_ESTABLISHED +type RecordText(rec: SSLRecord) = case $context.connection.state(rec.is_orig) of { + STATE_ENCRYPTED -> ciphertext : CiphertextRecord(rec); default -> plaintext : PlaintextRecord(rec); @@ -63,6 +62,7 @@ type PlaintextRecord(rec: SSLRecord) = case rec.content_type of { CHANGE_CIPHER_SPEC -> ch_cipher : ChangeCipherSpec(rec); ALERT -> alert : Alert(rec); HANDSHAKE -> handshake : Handshake(rec); + HEARTBEAT -> heartbeat: Heartbeat(rec); APPLICATION_DATA -> app_data : ApplicationData(rec); V2_ERROR -> v2_error : V2Error(rec); V2_CLIENT_HELLO -> v2_client_hello : V2ClientHello(rec); @@ -71,75 +71,98 @@ type PlaintextRecord(rec: SSLRecord) = case rec.content_type of { default -> unknown_record : UnknownRecord(rec); }; +###################################################################### +# TLS Extensions +###################################################################### + type SSLExtension(rec: SSLRecord) = record { type: uint16; data_len: uint16; - data: bytestring &length=data_len; + + # Pretty code ahead. Deal with the fact that perhaps extensions are + # not really present and we do not want to fail because of that. + ext: case type of { + EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION -> apnl: ApplicationLayerProtocolNegotiationExtension(rec)[] &until($element == 0 || $element != 0); + EXT_ELLIPTIC_CURVES -> elliptic_curves: EllipticCurves(rec)[] &until($element == 0 || $element != 0); + EXT_EC_POINT_FORMATS -> ec_point_formats: EcPointFormats(rec)[] &until($element == 0 || $element != 0); +# EXT_STATUS_REQUEST -> status_request: StatusRequest(rec)[] &until($element == 0 || $element != 0); + EXT_SERVER_NAME -> server_name: ServerNameExt(rec)[] &until($element == 0 || $element != 0); + default -> data: bytestring &restofdata; + }; +} &length=data_len+4 &exportsourcedata; + +type ServerNameHostName() = record { + length: uint16; + host_name: bytestring &length=length; }; +type ServerName() = record { + name_type: uint8; # has to be 0 for host-name + name: case name_type of { + 0 -> host_name: ServerNameHostName; + default -> data : bytestring &restofdata &transient; # unknown name + }; +}; + +type ServerNameExt(rec: SSLRecord) = record { + length: uint16; + server_names: ServerName[] &until($input.length() == 0); +} &length=length+2; + +# Do not parse for now. Structure is correct, but only contains asn.1 data that we would not use further. +#type OcspStatusRequest(rec: SSLRecord) = record { +# responder_id_list_length: uint16; +# responder_id_list: bytestring &length=responder_id_list_length; +# request_extensions_length: uint16; +# request_extensions: bytestring &length=request_extensions_length; +#}; +# +#type StatusRequest(rec: SSLRecord) = record { +# status_type: uint8; # 1 -> ocsp +# req: case status_type of { +# 1 -> ocsp_status_request: OcspStatusRequest(rec); +# default -> data : bytestring &restofdata &transient; # unknown +# }; +#}; + +type EcPointFormats(rec: SSLRecord) = record { + length: uint8; + point_format_list: uint8[length]; +}; + +type EllipticCurves(rec: SSLRecord) = record { + length: uint16; + elliptic_curve_list: uint16[length/2]; +}; + +type ProtocolName() = record { + length: uint8; + name: bytestring &length=length; +}; + +type ApplicationLayerProtocolNegotiationExtension(rec: SSLRecord) = record { + length: uint16; + protocol_name_list: ProtocolName[] &until($input.length() == 0); +} &length=length+2; + ###################################################################### -# state management according to Section 7.3. in spec +# Encryption Tracking ###################################################################### enum AnalyzerState { - STATE_INITIAL, - STATE_CLIENT_HELLO_RCVD, - STATE_IN_SERVER_HELLO, - STATE_SERVER_HELLO_DONE, - STATE_CLIENT_CERT, - STATE_CLIENT_KEY_WITH_CERT, - STATE_CLIENT_KEY_NO_CERT, - STATE_CLIENT_CERT_VERIFIED, - STATE_CLIENT_ENCRYPTED, - STATE_CLIENT_FINISHED, - STATE_ABBREV_SERVER_ENCRYPTED, - STATE_ABBREV_SERVER_FINISHED, - STATE_COMM_ENCRYPTED, - STATE_CONN_ESTABLISHED, - STATE_V2_CL_MASTER_KEY_EXPECTED, - - STATE_TRACK_LOST, - STATE_ANY + STATE_CLEAR, + STATE_ENCRYPTED }; %code{ string state_label(int state_nr) { switch ( state_nr ) { - case STATE_INITIAL: - return string("INITIAL"); - case STATE_CLIENT_HELLO_RCVD: - return string("CLIENT_HELLO_RCVD"); - case STATE_IN_SERVER_HELLO: - return string("IN_SERVER_HELLO"); - case STATE_SERVER_HELLO_DONE: - return string("SERVER_HELLO_DONE"); - case STATE_CLIENT_CERT: - return string("CLIENT_CERT"); - case STATE_CLIENT_KEY_WITH_CERT: - return string("CLIENT_KEY_WITH_CERT"); - case STATE_CLIENT_KEY_NO_CERT: - return string("CLIENT_KEY_NO_CERT"); - case STATE_CLIENT_CERT_VERIFIED: - return string("CLIENT_CERT_VERIFIED"); - case STATE_CLIENT_ENCRYPTED: - return string("CLIENT_ENCRYPTED"); - case STATE_CLIENT_FINISHED: - return string("CLIENT_FINISHED"); - case STATE_ABBREV_SERVER_ENCRYPTED: - return string("ABBREV_SERVER_ENCRYPTED"); - case STATE_ABBREV_SERVER_FINISHED: - return string("ABBREV_SERVER_FINISHED"); - case STATE_COMM_ENCRYPTED: - return string("COMM_ENCRYPTED"); - case STATE_CONN_ESTABLISHED: - return string("CONN_ESTABLISHED"); - case STATE_V2_CL_MASTER_KEY_EXPECTED: - return string("STATE_V2_CL_MASTER_KEY_EXPECTED"); - case STATE_TRACK_LOST: - return string("TRACK_LOST"); - case STATE_ANY: - return string("ANY"); + case STATE_CLEAR: + return string("CLEAR"); + + case STATE_ENCRYPTED: + return string("ENCRYPTED"); default: return string(fmt("UNKNOWN (%d)", state_nr)); @@ -176,21 +199,7 @@ type ChangeCipherSpec(rec: SSLRecord) = record { type : uint8; } &length = 1, &let { state_changed : bool = - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_COMM_ENCRYPTED, rec.is_orig, false) || - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_ABBREV_SERVER_ENCRYPTED, rec.is_orig, false) || - $context.connection.transition(STATE_CLIENT_KEY_NO_CERT, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT_VERIFIED, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_KEY_WITH_CERT, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_ABBREV_SERVER_FINISHED, - STATE_COMM_ENCRYPTED, rec.is_orig, true) || - $context.connection.lost_track(); + $context.connection.startEncryption(rec.is_orig); }; @@ -209,7 +218,7 @@ type Alert(rec: SSLRecord) = record { ###################################################################### type V2Error(rec: SSLRecord) = record { - data: bytestring &restofdata &transient; + data : bytestring &restofdata &transient; } &let { error_code : uint16 = ((rec.head3 << 8) | rec.head4); }; @@ -226,17 +235,21 @@ type ApplicationData(rec: SSLRecord) = record { }; ###################################################################### -# Handshake Protocol (7.4.) +# V3 Heartbeat ###################################################################### +type Heartbeat(rec: SSLRecord) = record { + type : uint8; + payload_length : uint16; + data : bytestring &restofdata; +}; + ###################################################################### # V3 Hello Request (7.4.1.1.) ###################################################################### # Hello Request is empty -type HelloRequest(rec: SSLRecord) = empty &let { - hr: bool = $context.connection.set_hello_requested(true); -}; +type HelloRequest(rec: SSLRecord) = empty; ###################################################################### @@ -257,16 +270,8 @@ type ClientHello(rec: SSLRecord) = record { # of the following fields. ext_len: uint16[] &until($element == 0 || $element != 0); extensions : SSLExtension(rec)[] &until($input.length() == 0); -} &let { - state_changed : bool = - $context.connection.transition(STATE_INITIAL, - STATE_CLIENT_HELLO_RCVD, rec.is_orig, true) || - ($context.connection.hello_requested() && - $context.connection.transition(STATE_ANY, STATE_CLIENT_HELLO_RCVD, rec.is_orig, true)) || - $context.connection.lost_track(); }; - ###################################################################### # V2 Client Hello (SSLv2 2.5.) ###################################################################### @@ -279,13 +284,6 @@ type V2ClientHello(rec: SSLRecord) = record { session_id : uint8[session_len]; challenge : bytestring &length = chal_len; } &length = 6 + csuit_len + session_len + chal_len, &let { - state_changed : bool = - $context.connection.transition(STATE_INITIAL, - STATE_CLIENT_HELLO_RCVD, rec.is_orig, true) || - ($context.connection.hello_requested() && - $context.connection.transition(STATE_ANY, STATE_CLIENT_HELLO_RCVD, rec.is_orig, true)) || - $context.connection.lost_track(); - client_version : int = rec.version; }; @@ -307,13 +305,10 @@ type ServerHello(rec: SSLRecord) = record { ext_len: uint16[] &until($element == 0 || $element != 0); extensions : SSLExtension(rec)[] &until($input.length() == 0); } &let { - state_changed : bool = - $context.connection.transition(STATE_CLIENT_HELLO_RCVD, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.lost_track(); + cipher_set : bool = + $context.connection.set_cipher(cipher_suite[0]); }; - ###################################################################### # V2 Server Hello (SSLv2 2.6.) ###################################################################### @@ -329,14 +324,6 @@ type V2ServerHello(rec: SSLRecord) = record { ciphers : uint24[ciph_len/3]; conn_id_data : bytestring &length = conn_id_len; } &let { - state_changed : bool = - (session_id_hit > 0 ? - $context.connection.transition(STATE_CLIENT_HELLO_RCVD, - STATE_CONN_ESTABLISHED, rec.is_orig, false) : - $context.connection.transition(STATE_CLIENT_HELLO_RCVD, - STATE_V2_CL_MASTER_KEY_EXPECTED, rec.is_orig, false)) || - $context.connection.lost_track(); - session_id_hit : uint8 = rec.head3; cert_type : uint8 = rec.head4; }; @@ -351,33 +338,250 @@ type X509Certificate = record { certificate : bytestring &length = to_int()(length); }; -type CertificateList = X509Certificate[] &until($input.length() == 0); - type Certificate(rec: SSLRecord) = record { length : uint24; - certificates : CertificateList &length = to_int()(length); -} &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.transition(STATE_SERVER_HELLO_DONE, - STATE_CLIENT_CERT, rec.is_orig, true) || - $context.connection.lost_track(); -}; + certificates : X509Certificate[] &until($input.length() == 0); +} &length = to_int()(length)+3; +# OCSP Stapling + +type CertificateStatus(rec: SSLRecord) = record { + status_type: uint8; # 1 = ocsp, everything else is undefined + length : uint24; + response: bytestring &restofdata; +}; ###################################################################### # V3 Server Key Exchange Message (7.4.3.) ###################################################################### -# For now ignore details; just eat up complete message -type ServerKeyExchange(rec: SSLRecord) = record { - key : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.lost_track(); +# Usually, the server key exchange does not contain any information +# that we are interested in. +# +# The exception is when we are using an ECDHE, DHE or DH-Anon suite. +# In this case, we can extract information about the chosen cipher from +# here. +type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher() of { + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ANON_WITH_NULL_SHA, + TLS_ECDH_ANON_WITH_RC4_128_SHA, + TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ANON_WITH_AES_128_CBC_SHA, + TLS_ECDH_ANON_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_RC4_128_SHA, + TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_PSK_WITH_NULL_SHA, + TLS_ECDHE_PSK_WITH_NULL_SHA256, + TLS_ECDHE_PSK_WITH_NULL_SHA384, + TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + -> ec_server_key_exchange : EcServerKeyExchange(rec); + + # DHE suites + TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, + TLS_DHE_DSS_WITH_DES_CBC_SHA, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, + TLS_DHE_RSA_WITH_DES_CBC_SHA, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + TLS_DHE_DSS_WITH_RC4_128_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD, + TLS_DHE_DSS_WITH_AES_128_CBC_RMD, + TLS_DHE_DSS_WITH_AES_256_CBC_RMD, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD, + TLS_DHE_RSA_WITH_AES_128_CBC_RMD, + TLS_DHE_RSA_WITH_AES_256_CBC_RMD, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS_DHE_PSK_WITH_RC4_128_SHA, + TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_SEED_CBC_SHA, + TLS_DHE_RSA_WITH_SEED_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + TLS_DHE_PSK_WITH_NULL_SHA256, + TLS_DHE_PSK_WITH_NULL_SHA384, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256, + TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, + TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, + TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, + TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256, + TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384, + TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, + TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, + TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, + TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, + TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_AES_128_CCM, + TLS_DHE_RSA_WITH_AES_256_CCM, + TLS_DHE_RSA_WITH_AES_128_CCM_8, + TLS_DHE_RSA_WITH_AES_256_CCM_8, + TLS_DHE_PSK_WITH_AES_128_CCM, + TLS_DHE_PSK_WITH_AES_256_CCM, + TLS_PSK_DHE_WITH_AES_128_CCM_8, + TLS_PSK_DHE_WITH_AES_256_CCM_8, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + # DH-anon suites + TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5, + TLS_DH_ANON_WITH_RC4_128_MD5, + TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA, + TLS_DH_ANON_WITH_DES_CBC_SHA, + TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_CBC_SHA, + TLS_DH_ANON_WITH_AES_256_CBC_SHA, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_CBC_SHA256, + TLS_DH_ANON_WITH_AES_256_CBC_SHA256, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA, + TLS_DH_ANON_WITH_SEED_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_GCM_SHA256, + TLS_DH_ANON_WITH_AES_256_GCM_SHA384, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DH_ANON_WITH_ARIA_128_CBC_SHA256, + TLS_DH_ANON_WITH_ARIA_256_CBC_SHA384, + TLS_DH_ANON_WITH_ARIA_128_GCM_SHA256, + TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384, + TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384 + # DH non-anon suites do not send a ServerKeyExchange + -> dh_server_key_exchange : DhServerKeyExchange(rec); + + default + -> key : bytestring &restofdata &transient; +}; + +# For the moment, we really only are interested in the curve name. If it +# is not set (if the server sends explicit parameters), we do not bother. +# We also do not parse the actual signature data following the named curve. +type EcServerKeyExchange(rec: SSLRecord) = record { + curve_type: uint8; + curve: uint16; # only if curve_type = 3 (NAMED_CURVE) + data: bytestring &restofdata &transient; +}; + +# For both, dh_anon and dhe the ServerKeyExchange starts with a ServerDHParams +# structure. After that, they start to differ, but we do not care about that. +type DhServerKeyExchange(rec: SSLRecord) = record { + dh_p_length: uint16; + dh_p: bytestring &length=dh_p_length; + dh_g_length: uint16; + dh_g: bytestring &length=dh_g_length; + dh_Ys_length: uint16; + dh_Ys: bytestring &length=dh_Ys_length; + data: bytestring &restofdata &transient; }; @@ -388,11 +592,6 @@ type ServerKeyExchange(rec: SSLRecord) = record { # For now, ignore Certificate Request Details; just eat up message. type CertificateRequest(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.lost_track(); }; @@ -401,12 +600,7 @@ type CertificateRequest(rec: SSLRecord) = record { ###################################################################### # Server Hello Done is empty -type ServerHelloDone(rec: SSLRecord) = empty &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_SERVER_HELLO_DONE, rec.is_orig, false) || - $context.connection.lost_track(); -}; +type ServerHelloDone(rec: SSLRecord) = empty; ###################################################################### @@ -425,15 +619,6 @@ type ServerHelloDone(rec: SSLRecord) = empty &let { # encrypted anyway); just eat up message. type ClientKeyExchange(rec: SSLRecord) = record { key : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_SERVER_HELLO_DONE, - STATE_CLIENT_KEY_NO_CERT, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT, - STATE_CLIENT_KEY_WITH_CERT, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT, - STATE_CLIENT_KEY_WITH_CERT, rec.is_orig, true) || - $context.connection.lost_track(); }; ###################################################################### @@ -449,12 +634,10 @@ type V2ClientMasterKey(rec: SSLRecord) = record { en_key_data : bytestring &length = en_key_len &transient; key_arg_data : bytestring &length = key_arg_len &transient; } &length = 7 + cl_key_len + en_key_len + key_arg_len, &let { - state_changed : bool = - $context.connection.transition(STATE_V2_CL_MASTER_KEY_EXPECTED, - STATE_CONN_ESTABLISHED, rec.is_orig, true) || - $context.connection.lost_track(); - cipher_kind : int = (((rec.head3 << 16) | (rec.head4 << 8)) | cipher_kind_8); + # encryption starts for both sides after this message. + state_changed_client : bool = $context.connection.startEncryption(true); + state_changed_server : bool = $context.connection.startEncryption(false); }; @@ -465,11 +648,6 @@ type V2ClientMasterKey(rec: SSLRecord) = record { # For now, ignore Certificate Verify; just eat up the message. type CertificateVerify(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_CLIENT_KEY_WITH_CERT, - STATE_CLIENT_CERT_VERIFIED, rec.is_orig, true) || - $context.connection.lost_track(); }; @@ -481,13 +659,6 @@ type CertificateVerify(rec: SSLRecord) = record { # so we will not be able to read those messages. type Finished(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_SERVER_HELLO_DONE, - STATE_COMM_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_COMM_ENCRYPTED, rec.is_orig, false) || - $context.connection.lost_track(); }; type SessionTicketHandshake(rec: SSLRecord) = record { @@ -499,10 +670,8 @@ type SessionTicketHandshake(rec: SSLRecord) = record { # V3 Handshake Protocol (7.) ###################################################################### -type UnknownHandshake(hs: Handshake, is_orig: bool) = record { +type UnknownHandshake(hs: Handshake, is_orig: bool) = record { data : bytestring &restofdata &transient; -} &let { - state_changed : bool = $context.connection.lost_track(); }; type Handshake(rec: SSLRecord) = record { @@ -522,7 +691,7 @@ type Handshake(rec: SSLRecord) = record { CLIENT_KEY_EXCHANGE -> client_key_exchange : ClientKeyExchange(rec); FINISHED -> finished : Finished(rec); CERTIFICATE_URL -> certificate_url : bytestring &restofdata &transient; - CERTIFICATE_STATUS -> certificate_status : bytestring &restofdata &transient; + CERTIFICATE_STATUS -> certificate_status : CertificateStatus(rec); default -> unknown_handshake : UnknownHandshake(this, rec.is_orig); } &length = to_int()(length); }; @@ -532,33 +701,12 @@ type Handshake(rec: SSLRecord) = record { # Fragmentation (6.2.1.) ###################################################################### -type UnknownRecord(rec: SSLRecord) = record { +type UnknownRecord(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = $context.connection.lost_track(); }; type CiphertextRecord(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_CLIENT_FINISHED, rec.is_orig, false) || - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_CLIENT_FINISHED, rec.is_orig, true) || - $context.connection.transition(STATE_ABBREV_SERVER_ENCRYPTED, - STATE_ABBREV_SERVER_FINISHED, rec.is_orig, false) || - $context.connection.transition(STATE_CLIENT_ENCRYPTED, - STATE_CLIENT_FINISHED, rec.is_orig, true) || - $context.connection.transition(STATE_COMM_ENCRYPTED, - STATE_CONN_ESTABLISHED, rec.is_orig, false) || - $context.connection.transition(STATE_COMM_ENCRYPTED, - STATE_CONN_ESTABLISHED, rec.is_orig, true) || - $context.connection.transition(STATE_CONN_ESTABLISHED, - STATE_CONN_ESTABLISHED, rec.is_orig, false) || - $context.connection.transition(STATE_CONN_ESTABLISHED, - STATE_CONN_ESTABLISHED, rec.is_orig, true) || - $context.connection.lost_track(); }; @@ -578,67 +726,111 @@ type SSLPDU(is_orig: bool) = record { refine connection SSL_Conn += { %member{ - int state_; - int old_state_; - bool hello_requested_; + int client_state_; + int server_state_; + int record_layer_version_; + uint32 chosen_cipher_; %} %init{ - state_ = STATE_INITIAL; - old_state_ = STATE_INITIAL; - hello_requested_ = false; + server_state_ = STATE_CLEAR; + client_state_ = STATE_CLEAR; + record_layer_version_ = UNKNOWN_VERSION; + chosen_cipher_ = NO_CHOSEN_CIPHER; %} - function determine_ssl_version(head0 : uint8, head1 : uint8, - head2 : uint8) : int + function chosen_cipher() : int %{ return chosen_cipher_; %} + + function set_cipher(cipher: uint32) : bool %{ - if ( head0 >= 20 && head0 <= 23 && - head1 == 0x03 && head2 <= 0x03 ) - // This is most probably SSL version 3. - return (head1 << 8) | head2; - - else if ( head0 >= 128 && head2 < 5 && head2 != 3 ) - // Not very strong evidence, but we suspect - // this to be SSLv2. - return SSLv20; - - else - return UNKNOWN_VERSION; - %} - - function state() : int %{ return state_; %} - function old_state() : int %{ return old_state_; %} - - function transition(olds : AnalyzerState, news : AnalyzerState, - current_record_is_orig : bool, is_orig : bool) : bool - %{ - if ( (olds != STATE_ANY && olds != state_) || - current_record_is_orig != is_orig ) - return false; - - old_state_ = state_; - state_ = news; - - //printf("transitioning from %s to %s\n", state_label(old_state()).c_str(), state_label(state()).c_str()); + chosen_cipher_ = cipher; return true; %} - function lost_track() : bool + function determine_ssl_record_layer(head0 : uint8, head1 : uint8, + head2 : uint8, head3: uint8, head4: uint8) : int %{ - state_ = STATE_TRACK_LOST; - return false; + // re-check record layer version to be sure that we still are synchronized with + // the data stream + if ( record_layer_version_ != UNKNOWN_VERSION && record_layer_version_ != SSLv20 ) + { + uint16 version = (head1<<8) | head2; + if ( version != SSLv30 && version != TLSv10 && + version != TLSv11 && version != TLSv12 ) + { + bro_analyzer()->ProtocolViolation(fmt("Invalid version late in TLS connection. Packet reported version: %d", version)); + return UNKNOWN_VERSION; + } + } + + if ( record_layer_version_ != UNKNOWN_VERSION ) + return record_layer_version_; + + if ( head0 & 0x80 ) + { + if ( head2 == 0x01 ) // SSLv2 client hello. + { + uint16 version = (head3 << 8) | head4; + if ( version != SSLv20 && version != SSLv30 && version != TLSv10 && + version != TLSv11 && version != TLSv12 ) + { + bro_analyzer()->ProtocolViolation(fmt("Invalid version in SSL client hello. Version: %d", version)); + return UNKNOWN_VERSION; + } + + else + return SSLv20; + } + + else if ( head2 == 0x04 ) // SSLv2 server hello. This connection will continue using SSLv2. + { + record_layer_version_ = SSLv20; + return SSLv20; + } + + else // this is not SSL or TLS. + { + bro_analyzer()->ProtocolViolation(fmt("Invalid headers in SSL connection. Head1: %d, head2: %d, head3: %d", head1, head2, head3)); + return UNKNOWN_VERSION; + } + } + + uint16 version = (head1<<8) | head2; + if ( version != SSLv30 && version != TLSv10 && + version != TLSv11 && version != TLSv12 ) + { + bro_analyzer()->ProtocolViolation(fmt("Invalid version in TLS connection. Version: %d", version)); + return UNKNOWN_VERSION; + } + + if ( head0 >=20 && head0 <= 30 ) + { // ok, set record layer version, this never can be downgraded to v2 + record_layer_version_ = version; + return version; + } + + bro_analyzer()->ProtocolViolation(fmt("Invalid type in TLS connection. Version: %d, Type: %d", version, head0)); + return UNKNOWN_VERSION; %} - function hello_requested() : bool + function client_state() : int %{ return client_state_; %} + + function server_state() : int %{ return client_state_; %} + + function state(is_orig: bool) : int %{ - bool ret = hello_requested_; - hello_requested_ = false; - return ret; + if ( is_orig ) + return client_state_; + else + return server_state_; %} - function set_hello_requested(val : bool) : bool + function startEncryption(is_orig: bool) : bool %{ - hello_requested_ = val; - return val; + if ( is_orig ) + client_state_ = STATE_ENCRYPTED; + else + server_state_ = STATE_ENCRYPTED; + return true; %} }; diff --git a/src/analyzer/protocol/stepping-stone/SteppingStone.cc b/src/analyzer/protocol/stepping-stone/SteppingStone.cc index 09a7444213..b6473dcf6e 100644 --- a/src/analyzer/protocol/stepping-stone/SteppingStone.cc +++ b/src/analyzer/protocol/stepping-stone/SteppingStone.cc @@ -63,7 +63,7 @@ void SteppingStoneEndpoint::Done() Event(stp_remove_endp, stp_id); } -int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen, +int SteppingStoneEndpoint::DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* /* ip */, const struct tcphdr* tp) { @@ -90,8 +90,8 @@ int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen, break; } - int ack = endp->AckSeq() - endp->StartSeq(); - int top_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 top_seq = seq + len; if ( top_seq <= ack || top_seq <= stp_max_top_seq ) // There is no new data in this packet @@ -179,7 +179,7 @@ void SteppingStone_Analyzer::Init() } void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, diff --git a/src/analyzer/protocol/stepping-stone/SteppingStone.h b/src/analyzer/protocol/stepping-stone/SteppingStone.h index 1471c08a3b..518cd64a21 100644 --- a/src/analyzer/protocol/stepping-stone/SteppingStone.h +++ b/src/analyzer/protocol/stepping-stone/SteppingStone.h @@ -22,7 +22,7 @@ public: ~SteppingStoneEndpoint(); void Done(); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); protected: @@ -30,7 +30,7 @@ protected: void CreateEndpEvent(int is_orig); tcp::TCP_Endpoint* endp; - int stp_max_top_seq; + uint64 stp_max_top_seq; double stp_last_time; double stp_resume_time; SteppingStoneManager* stp_manager; @@ -60,7 +60,7 @@ protected: // We support both packet and stream input and can be put in place even // if the TCP analyzer is not yet reassebmling. virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool is_orig); int orig_stream_pos; diff --git a/src/analyzer/protocol/syslog/Syslog.cc b/src/analyzer/protocol/syslog/Syslog.cc index 2b783afc64..5e5ce907e6 100644 --- a/src/analyzer/protocol/syslog/Syslog.cc +++ b/src/analyzer/protocol/syslog/Syslog.cc @@ -28,7 +28,7 @@ void Syslog_Analyzer::Done() Event(udp_session_done); } -void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); interp->NewData(orig, data, data + len); @@ -88,7 +88,7 @@ void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int // interp->NewData(orig, data, data + len); // } -//void Syslog_tcp::TCP_Analyzer::Undelivered(int seq, int len, bool orig) +//void Syslog_tcp::TCP_Analyzer::Undelivered(uint64 seq, int len, bool orig) // { // tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); // interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/syslog/Syslog.h b/src/analyzer/protocol/syslog/Syslog.h index 355863e36e..619ddb39ba 100644 --- a/src/analyzer/protocol/syslog/Syslog.h +++ b/src/analyzer/protocol/syslog/Syslog.h @@ -16,7 +16,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Syslog_Analyzer(conn); } @@ -38,7 +38,7 @@ protected: // // virtual void Done(); // virtual void DeliverStream(int len, const u_char* data, bool orig); -// virtual void Undelivered(int seq, int len, bool orig); +// virtual void Undelivered(uint64 seq, int len, bool orig); // virtual void EndpointEOF(tcp::TCP_Reassembler* endp); // // static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/tcp/ContentLine.cc b/src/analyzer/protocol/tcp/ContentLine.cc index 63a3c07f00..72314dd45d 100644 --- a/src/analyzer/protocol/tcp/ContentLine.cc +++ b/src/analyzer/protocol/tcp/ContentLine.cc @@ -109,7 +109,7 @@ void ContentLine_Analyzer::DeliverStream(int len, const u_char* data, seq += len; } -void ContentLine_Analyzer::Undelivered(int seq, int len, bool orig) +void ContentLine_Analyzer::Undelivered(uint64 seq, int len, bool orig) { ForwardUndelivered(seq, len, orig); } diff --git a/src/analyzer/protocol/tcp/ContentLine.h b/src/analyzer/protocol/tcp/ContentLine.h index ecc1347984..93c473c47c 100644 --- a/src/analyzer/protocol/tcp/ContentLine.h +++ b/src/analyzer/protocol/tcp/ContentLine.h @@ -53,14 +53,14 @@ public: void SkipBytesAfterThisLine(int64_t length); void SkipBytes(int64_t length); - bool IsSkippedContents(int64_t seq, int64_t length) + bool IsSkippedContents(uint64_t seq, int64_t length) { return seq + length <= seq_to_skip; } protected: ContentLine_Analyzer(const char* name, Connection* conn, bool orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); class State; @@ -71,19 +71,19 @@ protected: void CheckNUL(); // Returns the sequence number delivered so far. - int64_t SeqDelivered() const { return seq_delivered_in_lines; } + uint64_t SeqDelivered() const { return seq_delivered_in_lines; } u_char* buf; // where we build up the body of the request int offset; // where we are in buf int buf_len; // how big buf is, total unsigned int last_char; // last (non-option) character scanned - int64_t seq; // last seq number - int64_t seq_to_skip; + uint64_t seq; // last seq number + uint64_t seq_to_skip; // Seq delivered up to through NewLine() -- it is adjusted // *before* NewLine() is called. - int64_t seq_delivered_in_lines; + uint64_t seq_delivered_in_lines; // Number of bytes to be skipped after this line. See // comments in SkipBytesAfterThisLine(). diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index c422d01f32..f9fb0fb2b7 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -36,1088 +36,8 @@ namespace { // local namespace static const int ORIG = 1; static const int RESP = 2; -TCP_Analyzer::TCP_Analyzer(Connection* conn) -: TransportLayerAnalyzer("TCP", conn) - { - // Set a timer to eventually time out this connection. - ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer, - network_time + tcp_SYN_timeout, 0, - TIMER_TCP_EXPIRE); - - deferred_gen_event = close_deferred = 0; - - seen_first_ACK = 0; - is_active = 1; - finished = 0; - reassembling = 0; - first_packet_seen = 0; - is_partial = 0; - - orig = new TCP_Endpoint(this, 1); - resp = new TCP_Endpoint(this, 0); - - orig->SetPeer(resp); - resp->SetPeer(orig); - } - -TCP_Analyzer::~TCP_Analyzer() - { - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - delete *i; - - delete orig; - delete resp; - } - -void TCP_Analyzer::Init() - { - Analyzer::Init(); - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->Init(); - } - -void TCP_Analyzer::Done() - { - Analyzer::Done(); - - if ( connection_pending && is_active && ! BothClosed() ) - Event(connection_pending); - - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->Done(); - - orig->Done(); - resp->Done(); - - finished = 1; - } - -void TCP_Analyzer::EnableReassembly() - { - SetReassembler(new TCP_Reassembler(this, this, - TCP_Reassembler::Forward, orig), - new TCP_Reassembler(this, this, - TCP_Reassembler::Forward, resp)); - - reassembling = 1; - - if ( new_connection_contents ) - Event(new_connection_contents); - } - -void TCP_Analyzer::SetReassembler(TCP_Reassembler* rorig, - TCP_Reassembler* rresp) - { - orig->AddReassembler(rorig); - rorig->SetDstAnalyzer(this); - resp->AddReassembler(rresp); - rresp->SetDstAnalyzer(this); - - reassembling = 1; - - if ( new_connection_contents ) - Event(new_connection_contents); - } - -const struct tcphdr* TCP_Analyzer::ExtractTCP_Header(const u_char*& data, - int& len, int& caplen) - { - const struct tcphdr* tp = (const struct tcphdr*) data; - uint32 tcp_hdr_len = tp->th_off * 4; - - if ( tcp_hdr_len < sizeof(struct tcphdr) ) - { - Weird("bad_TCP_header_len"); - return 0; - } - - if ( tcp_hdr_len > uint32(len) || - sizeof(struct tcphdr) > uint32(caplen) ) - { - // This can happen even with the above test, due to TCP - // options. - Weird("truncated_header"); - return 0; - } - - len -= tcp_hdr_len; // remove TCP header - caplen -= tcp_hdr_len; - data += tcp_hdr_len; - - return tp; - } - -bool TCP_Analyzer::ValidateChecksum(const struct tcphdr* tp, - TCP_Endpoint* endpoint, int len, int caplen) - { - if ( ! ignore_checksums && caplen >= len && - ! endpoint->ValidChecksum(tp, len) ) - { - Weird("bad_TCP_checksum"); - endpoint->CheckHistory(HIST_CORRUPT_PKT, 'C'); - return false; - } - else - return true; - } - -void TCP_Analyzer::CheckFlagCombos(TCP_Flags flags, TCP_Endpoint* endpoint, - uint32 base_seq, int len, int dst_port) - { - bool is_orig = endpoint->IsOrig(); - - if ( is_orig && ! (first_packet_seen & ORIG) ) - is_partial = ! flags.SYN() || flags.ACK(); - - if ( ! is_orig && ! (first_packet_seen & RESP) && ! is_partial ) - is_partial = ! flags.SYN(); - - int bits_set = (flags.SYN() ? 1 : 0) + (flags.FIN() ? 1 : 0) + - (flags.RST() ? 1 : 0); - if ( bits_set > 1 ) - { - if ( flags.FIN() && flags.RST() ) - endpoint->CheckHistory(HIST_FIN_RST_PKT, 'I'); - else - endpoint->CheckHistory(HIST_MULTI_FLAG_PKT, 'Q'); - } - - else if ( bits_set == 1 ) - { - if ( flags.SYN() ) - { - char code = flags.ACK() ? 'H' : 'S'; - - if ( endpoint->CheckHistory(HIST_SYN_PKT, code) && - base_seq != endpoint->hist_last_SYN ) - endpoint->AddHistory(code); - - endpoint->hist_last_SYN = base_seq; - } - - if ( flags.FIN() ) - { - // For FIN's, the sequence number comes at the - // end of (any data in) the packet, not the - // beginning as for SYNs and RSTs. - if ( endpoint->CheckHistory(HIST_FIN_PKT, 'F') && - base_seq + len != endpoint->hist_last_FIN ) - endpoint->AddHistory('F'); - - endpoint->hist_last_FIN = base_seq + len; - } - - if ( flags.RST() ) - { - if ( endpoint->CheckHistory(HIST_RST_PKT, 'R') && - base_seq != endpoint->hist_last_RST ) - endpoint->AddHistory('R'); - - endpoint->hist_last_RST = base_seq; - } - } - - else - { // bits_set == 0 - if ( len ) - endpoint->CheckHistory(HIST_DATA_PKT, 'D'); - - else if ( flags.ACK() ) - endpoint->CheckHistory(HIST_ACK_PKT, 'A'); - } - } - -void TCP_Analyzer::UpdateWindow(TCP_Endpoint* endpoint, unsigned int window, - uint32 base_seq, uint32 ack_seq, - TCP_Flags flags) - { - // Note, the offered window on an initial SYN is unscaled, even - // if the SYN includes scaling, so we need to do the following - // test *before* updating the scaling information below. (Hmmm, - // how does this work for windows on SYN/ACKs? ###) - int scale = endpoint->window_scale; - window = window << scale; - - // Don't analyze window values off of SYNs, they're sometimes - // immediately rescinded. - if ( ! flags.SYN() ) - { - // ### Decide whether to accept new window based on Active - // Mapping policy. - if ( int(base_seq - endpoint->window_seq) >= 0 && - int(ack_seq - endpoint->window_ack_seq) >= 0 ) - { - uint32 new_edge = ack_seq + window; - uint32 old_edge = endpoint->window_ack_seq + endpoint->window; - int advance = new_edge - old_edge; - - if ( advance < 0 ) - { - // A window recision. We don't report these - // for FINs or RSTs, or if the connection - // has already been partially closed, since - // such recisions occur frequently in practice, - // probably as the receiver loses buffer memory - // due to its process going away. - // - // We also, for window scaling, allow a bit - // of slop ###. This is because sometimes - // there will be an apparent recision due - // to the granularity of the scaling. - if ( ! flags.FIN() && ! flags.RST() && - endpoint->state != TCP_ENDPOINT_CLOSED && - endpoint->state != TCP_ENDPOINT_RESET && - (-advance) >= (1 << scale) ) - Weird("window_recision"); - } - - endpoint->window = window; - endpoint->window_ack_seq = ack_seq; - endpoint->window_seq = base_seq; - } - } - } - -void TCP_Analyzer::ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags) - { - int len = seq_len; - - ++seq_len; // SYN consumes a byte of sequence space - - if ( flags.RST() ) - Weird("TCP_christmas"); - - if ( flags.URG() ) - Weird("baroque_SYN"); - - if ( len > 0 ) - // T/TCP definitely complicates this. - Weird("SYN_with_data"); - - RecordVal* SYN_vals = BuildSYNPacketVal(is_orig, ip, tp)->AsRecordVal(); - - // ### In the following, we could be fooled by an - // inconsistent SYN retransmission. Where's a normalizer - // when you need one? - - // ### We know that field 5 is the window scaling .... - int scale = int(SYN_vals->Lookup(5)->CoerceToInt()); - - if ( scale < 0 ) - { // no window scaling option - if ( flags.ACK() ) - { // window scaling not negotiated - endpoint->window_scale = 0; - peer->window_scale = 0; - } - else - // We're not offering window scaling. - // Ideally, we'd remember this fact so that - // if the SYN/ACK *does* include window - // scaling, we know it won't be negotiated. - // But it's a pain to track that, and hard - // to see how an adversarial responder could - // use it to evade. Also, if we *do* want - // to track it, we could do so using - // connection_SYN_packet. - endpoint->window_scale = 0; - } - else - { - endpoint->window_scale = scale; - endpoint->window_seq = base_seq; - endpoint->window_ack_seq = ack_seq; - - peer->window_seq = ack_seq; - peer->window_ack_seq = base_seq; - } - - if ( connection_SYN_packet ) - { - val_list* vl = new val_list; - vl->append(BuildConnVal()); - vl->append(SYN_vals); - ConnectionEvent(connection_SYN_packet, vl); - } - else - Unref(SYN_vals); - - // Passive fingerprinting. - // - // is_orig will be removed once we can do SYN-ACK fingerprinting. - if ( OS_version_found && is_orig ) - { - AddrVal src_addr_val(orig_addr); - if ( generate_OS_version_event->Size() == 0 || - generate_OS_version_event->Lookup(&src_addr_val) ) - { - RecordVal* OS_val = - BuildOSVal(is_orig, ip, tp, tcp_hdr_len); - if ( OS_val ) - { // found new OS version - val_list* vl = new val_list; - vl->append(BuildConnVal()); - vl->append(new AddrVal(orig_addr)); - vl->append(OS_val); - ConnectionEvent(OS_version_found, vl); - } - } - } - } - -void TCP_Analyzer::ProcessFIN(double t, TCP_Endpoint* endpoint, - int& seq_len, uint32 base_seq) - { - ++seq_len; // FIN consumes a byte of sequence space. - ++endpoint->FIN_cnt; // remember that we've seen a FIN - - if ( t < endpoint->last_time + tcp_storm_interarrival_thresh && - endpoint->FIN_cnt == tcp_storm_thresh ) - Weird("FIN_storm"); - - // Remember the relative seq in FIN_seq. - endpoint->FIN_seq = base_seq - endpoint->StartSeq() + seq_len; - } - -void TCP_Analyzer::ProcessRST(double t, TCP_Endpoint* endpoint, - const IP_Hdr* ip, uint32 base_seq, - int len, int& seq_len) - { - if ( t < endpoint->last_time + tcp_storm_interarrival_thresh && - ++endpoint->RST_cnt == tcp_storm_thresh ) - Weird("RST_storm"); - - else if ( endpoint->RST_cnt == 0 ) - ++endpoint->RST_cnt; // Remember we've seen a RST - - if ( len > 0 ) - { - // This now happens often enough that it's - // not in the least interesting. - // Weird("RST_with_data"); - - // Don't include the data in the computation of - // the sequence space for this connection, as - // it's not in fact part of the TCP stream. - seq_len = 0; - } - - PacketWithRST(); - } - -void TCP_Analyzer::ProcessFlags(double t, - const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags) - { - if ( flags.SYN() ) - ProcessSYN(ip, tp, tcp_hdr_len, seq_len, endpoint, peer, - base_seq, ack_seq, orig_addr, is_orig, flags); - - if ( flags.FIN() ) - ProcessFIN(t, endpoint, seq_len, base_seq); - - if ( flags.RST() ) - ProcessRST(t, endpoint, ip, base_seq, len, seq_len); - - if ( flags.ACK() ) - ProcessACK(endpoint, peer, ack_seq, is_orig, flags); - } - -void TCP_Analyzer::TransitionFromInactive(double t, TCP_Endpoint* endpoint, - uint32 base_seq, - uint32 last_seq, int SYN) - { - if ( SYN ) - { - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq; - endpoint->InitAckSeq(base_seq); - endpoint->InitStartSeq(base_seq); - } - else - { - // This is a partial connection - set up the - // initial sequence numbers as though we saw - // a SYN, to keep the relative byte numbering - // consistent. - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq - 1; - endpoint->InitAckSeq(base_seq - 1); - endpoint->InitStartSeq(base_seq - 1); - } - - // ## endpoint->last_seq = last_seq; - endpoint->InitLastSeq(last_seq); - endpoint->start_time = t; - } - -int TCP_Analyzer::UpdateLastSeq(TCP_Endpoint* endpoint, uint32 last_seq, - TCP_Flags flags) - { - int delta_last = seq_delta(last_seq, endpoint->LastSeq()); - - if ( (flags.SYN() || flags.RST()) && - (delta_last > TOO_LARGE_SEQ_DELTA || - delta_last < -TOO_LARGE_SEQ_DELTA) ) - // ### perhaps trust RST seq #'s if initial and not too - // outlandish, but not if they're coming after the other - // side has sent a FIN - trust the FIN ack instead - ; - - else if ( flags.FIN() && - endpoint->LastSeq() == endpoint->StartSeq() + 1 ) - // Update last_seq based on the FIN even if delta_last < 0. - // This is to accommodate > 2 GB connections for which - // we've only seen the SYN and the FIN (hence the check - // for last_seq == start_seq + 1). - endpoint->UpdateLastSeq(last_seq); - - else if ( endpoint->state == TCP_ENDPOINT_RESET ) - // don't trust any subsequent sequence numbers - ; - - else if ( delta_last > 0 ) - // ### check for large jumps here. - // ## endpoint->last_seq = last_seq; - endpoint->UpdateLastSeq(last_seq); - - else if ( delta_last <= 0 ) - { // ### ++retransmit, unless this is a pure ack - } - - return delta_last; - } - -void TCP_Analyzer::ProcessACK(TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 ack_seq, int is_orig, - TCP_Flags flags) - { - if ( is_orig && ! seen_first_ACK && - (endpoint->state == TCP_ENDPOINT_ESTABLISHED || - endpoint->state == TCP_ENDPOINT_SYN_SENT) ) - { - seen_first_ACK = 1; - Event(connection_first_ACK); - } - - if ( peer->state == TCP_ENDPOINT_INACTIVE ) - { - if ( ! flags.SYN() && ! flags.FIN() && ! flags.RST() ) - { - if ( endpoint->state == TCP_ENDPOINT_SYN_SENT || - endpoint->state == TCP_ENDPOINT_SYN_ACK_SENT || - endpoint->state == TCP_ENDPOINT_ESTABLISHED ) - { - // We've already sent a SYN, but that - // hasn't roused the other end, yet we're - // ack'ing their data. - - if ( ! Conn()->DidWeird() ) - Weird("possible_split_routing"); - } - } - - // Start the sequence numbering as if there was an initial - // SYN, so the relative numbering of subsequent data packets - // stays consistent. - // ## peer->start_seq = peer->AckSeq() = peer->last_seq = - // ## ack_seq - 1; - peer->InitStartSeq(ack_seq - 1); - peer->InitAckSeq(ack_seq - 1); - peer->InitLastSeq(ack_seq - 1); - } - - else if ( ! flags.RST() ) - { // don't trust ack's in RST packets - int delta_ack = seq_delta(ack_seq, peer->AckSeq()); - if ( ack_seq == 0 && delta_ack > TOO_LARGE_SEQ_DELTA ) - // More likely that this is a broken ack than a - // large connection that happens to land on 0 in the - // sequence space. - ; - - else if ( delta_ack > 0 ) - peer->UpdateAckSeq(ack_seq); - } - - peer->AckReceived(ack_seq - peer->StartSeq()); - } - -void TCP_Analyzer::UpdateInactiveState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - int len, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - if ( flags.SYN() ) - { - if ( is_orig ) - { - if ( flags.ACK() ) - { - Weird("connection_originator_SYN_ack"); - endpoint->SetState(TCP_ENDPOINT_SYN_ACK_SENT); - } - else - endpoint->SetState(TCP_ENDPOINT_SYN_SENT); - - if ( tcp_attempt_delay ) - ADD_ANALYZER_TIMER(&TCP_Analyzer::AttemptTimer, - t + tcp_attempt_delay, 1, - TIMER_TCP_ATTEMPT); - } - else - { - if ( flags.ACK() ) - { - if ( peer->state != TCP_ENDPOINT_INACTIVE && - peer->state != TCP_ENDPOINT_PARTIAL && - ! seq_between(ack_seq, peer->StartSeq(), peer->LastSeq()) ) - Weird("bad_SYN_ack"); - } - - else if ( peer->state == TCP_ENDPOINT_SYN_ACK_SENT && - base_seq == endpoint->StartSeq() ) - { - // This is a SYN/SYN-ACK reversal, - // per the discussion in IsReuse. - // Flip the endpoints and establish - // the connection. - is_partial = 0; - Conn()->FlipRoles(); - peer->SetState(TCP_ENDPOINT_ESTABLISHED); - } - - else - Weird("simultaneous_open"); - - if ( peer->state == TCP_ENDPOINT_SYN_SENT ) - peer->SetState(TCP_ENDPOINT_ESTABLISHED); - else if ( peer->state == TCP_ENDPOINT_INACTIVE ) - { - // If we were to ignore SYNs and - // only instantiate state on SYN - // acks, then we'd do: - // peer->SetState(TCP_ENDPOINT_ESTABLISHED); - // here. - Weird("unsolicited_SYN_response"); - } - - endpoint->SetState(TCP_ENDPOINT_ESTABLISHED); - - if ( peer->state != TCP_ENDPOINT_PARTIAL ) - { - Event(connection_established); - Conn()->EnableStatusUpdateTimer(); - } - } - } - - if ( flags.FIN() ) - { - endpoint->SetState(TCP_ENDPOINT_CLOSED); - do_close = gen_event = 1; - if ( peer->state != TCP_ENDPOINT_PARTIAL && ! flags.SYN() ) - Weird("spontaneous_FIN"); - } - - if ( flags.RST() ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - - int is_reject = 0; - - if ( is_orig ) - { - // If our peer is established then we saw - // a SYN-ack but not SYN - so a reverse - // scan, and we should treat this as a - // reject. - if ( peer->state == TCP_ENDPOINT_ESTABLISHED ) - is_reject = 1; - } - - else if ( peer->state == TCP_ENDPOINT_SYN_SENT || - peer->state == TCP_ENDPOINT_SYN_ACK_SENT ) - // We're rejecting an initial SYN. - is_reject = 1; - - do_close = 1; - gen_event = ! is_reject; - - if ( is_reject ) - Event(connection_rejected); - - else if ( peer->state == TCP_ENDPOINT_INACTIVE ) - Weird("spontaneous_RST"); - } - - if ( endpoint->state == TCP_ENDPOINT_INACTIVE ) - { // No control flags to change the state. - if ( ! is_orig && len == 0 && - orig->state == TCP_ENDPOINT_SYN_SENT ) - // Some eccentric TCP's will ack an initial - // SYN prior to sending a SYN reply (hello, - // ftp.microsoft.com). For those, don't - // consider the ack as forming a partial - // connection. - ; - else - { - endpoint->SetState(TCP_ENDPOINT_PARTIAL); - Conn()->EnableStatusUpdateTimer(); - - if ( peer->state == TCP_ENDPOINT_PARTIAL ) - // We've seen both sides of a partial - // connection, report it. - Event(partial_connection); - } - } - } - -void TCP_Analyzer::UpdateSYN_SentState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int len, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - if ( flags.SYN() ) - { - if ( is_orig ) - { - if ( flags.ACK() && ! flags.FIN() && ! flags.RST() && - endpoint->state != TCP_ENDPOINT_SYN_ACK_SENT ) - Weird("repeated_SYN_with_ack"); - } - else - { - if ( ! flags.ACK() && - endpoint->state != TCP_ENDPOINT_SYN_SENT ) - Weird("repeated_SYN_reply_wo_ack"); - } - - if ( base_seq != endpoint->StartSeq() ) - { - Weird("SYN_seq_jump"); - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq; - // ## endpoint->last_seq = last_seq; - endpoint->InitStartSeq(base_seq); - endpoint->InitAckSeq(base_seq); - endpoint->InitLastSeq(last_seq); - } - } - - if ( flags.FIN() ) - { - if ( peer->state == TCP_ENDPOINT_INACTIVE || - peer->state == TCP_ENDPOINT_SYN_SENT ) - Weird("inappropriate_FIN"); - - endpoint->SetState(TCP_ENDPOINT_CLOSED); - do_close = gen_event = 1; - } - - if ( flags.RST() ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - ConnectionReset(); - do_close = 1; - } - - else if ( len > 0 ) - Weird("data_before_established"); - } - -void TCP_Analyzer::UpdateEstablishedState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - if ( flags.SYN() ) - { - if ( endpoint->state == TCP_ENDPOINT_PARTIAL && - peer->state == TCP_ENDPOINT_INACTIVE && ! flags.ACK() ) - { - Weird("SYN_after_partial"); - endpoint->SetState(TCP_ENDPOINT_SYN_SENT); - } - - if ( endpoint->Size() > 0 ) - Weird("SYN_inside_connection"); - - if ( base_seq != endpoint->StartSeq() ) - Weird("SYN_seq_jump"); - - // Make a guess that somehow the connection didn't - // get established, and this SYN will be the - // one that actually sets it up. - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq; - // ## endpoint->last_seq = last_seq; - endpoint->InitStartSeq(base_seq); - endpoint->InitAckSeq(base_seq); - endpoint->InitLastSeq(last_seq); - } - - if ( flags.FIN() && ! flags.RST() ) // ### - { // should check sequence/ack numbers here ### - endpoint->SetState(TCP_ENDPOINT_CLOSED); - - if ( peer->state == TCP_ENDPOINT_RESET && - peer->prev_state == TCP_ENDPOINT_CLOSED ) - // The peer sent a FIN followed by a RST. - // Turn it back into CLOSED state, because - // this was actually normal termination. - peer->SetState(TCP_ENDPOINT_CLOSED); - - do_close = gen_event = 1; - } - - if ( flags.RST() ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - do_close = 1; - - if ( peer->state != TCP_ENDPOINT_RESET || - peer->prev_state != TCP_ENDPOINT_ESTABLISHED ) - ConnectionReset(); - } - } - -void TCP_Analyzer::UpdateClosedState(double t, TCP_Endpoint* endpoint, - int delta_last, TCP_Flags flags, int& do_close) - { - if ( flags.SYN() ) - Weird("SYN_after_close"); - - if ( flags.FIN() && delta_last > 0 ) - // Probably should also complain on FIN recision. - // That requires an extra state variable to avoid - // generating slews of weird's when a TCP gets - // seriously confused (this from experience). - Weird("FIN_advanced_last_seq"); - - // Previously, our state was CLOSED, since we sent a FIN. - // If our peer was also closed, then don't change our state - // now on a RST, since this connection has already seen a FIN - // exchange. - if ( flags.RST() && endpoint->peer->state != TCP_ENDPOINT_CLOSED ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - - if ( ! endpoint->did_close ) - // RST after FIN. - do_close = 1; - - if ( connection_reset ) - ADD_ANALYZER_TIMER(&TCP_Analyzer::ResetTimer, - t + tcp_reset_delay, 1, - TIMER_TCP_RESET); - } - } - -void TCP_Analyzer::UpdateResetState(int len, TCP_Flags flags, - TCP_Endpoint* endpoint, uint32 base_seq, - uint32 last_seq) - { - if ( flags.SYN() ) - { - Weird("SYN_after_reset"); - - if ( endpoint->prev_state == TCP_ENDPOINT_INACTIVE ) - { - // Seq. numbers were initialized by a RST packet from this endpoint, - // but now that a SYN is seen from it, that could mean the earlier - // RST was spoofed/injected, so re-initialize. This mostly just - // helps prevent misrepresentations of payload sizes that are based - // on bad initial sequence values. - endpoint->InitStartSeq(base_seq); - endpoint->InitAckSeq(base_seq); - endpoint->InitLastSeq(last_seq); - } - } - - if ( flags.FIN() ) - Weird("FIN_after_reset"); - - if ( len > 0 && ! flags.RST() ) - Weird("data_after_reset"); - } - -void TCP_Analyzer::UpdateStateMachine(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, uint32 last_seq, - int len, int delta_last, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - do_close = 0; // whether to report the connection as closed - gen_event = 0; // if so, whether to generate an event - - switch ( endpoint->state ) { - - case TCP_ENDPOINT_INACTIVE: - UpdateInactiveState(t, endpoint, peer, base_seq, ack_seq, - len, is_orig, flags, - do_close, gen_event); - break; - - case TCP_ENDPOINT_SYN_SENT: - case TCP_ENDPOINT_SYN_ACK_SENT: - UpdateSYN_SentState(t, endpoint, peer, base_seq, last_seq, - len, is_orig, flags, - do_close, gen_event); - break; - - case TCP_ENDPOINT_ESTABLISHED: - case TCP_ENDPOINT_PARTIAL: - UpdateEstablishedState(t, endpoint, peer, base_seq, last_seq, - is_orig, flags, do_close, gen_event); - break; - - case TCP_ENDPOINT_CLOSED: - UpdateClosedState(t, endpoint, delta_last, flags, do_close); - break; - - case TCP_ENDPOINT_RESET: - UpdateResetState(len, flags, endpoint, base_seq, last_seq); - break; - } - } - -void TCP_Analyzer::GeneratePacketEvent(TCP_Endpoint* endpoint, - TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const u_char* data, int len, int caplen, - int is_orig, TCP_Flags flags) - { - char tcp_flags[256]; - int tcp_flag_len = 0; - - if ( flags.SYN() ) tcp_flags[tcp_flag_len++] = 'S'; - if ( flags.FIN() ) tcp_flags[tcp_flag_len++] = 'F'; - if ( flags.RST() ) tcp_flags[tcp_flag_len++] = 'R'; - if ( flags.ACK() ) tcp_flags[tcp_flag_len++] = 'A'; - if ( flags.PUSH() ) tcp_flags[tcp_flag_len++] = 'P'; - if ( flags.URG() ) tcp_flags[tcp_flag_len++] = 'U'; - - tcp_flags[tcp_flag_len] = '\0'; - - val_list* vl = new val_list(); - - vl->append(BuildConnVal()); - vl->append(new Val(is_orig, TYPE_BOOL)); - vl->append(new StringVal(tcp_flags)); - vl->append(new Val(base_seq - endpoint->StartSeq(), TYPE_COUNT)); - vl->append(new Val(flags.ACK() ? - ack_seq - peer->StartSeq() : 0, TYPE_COUNT)); - vl->append(new Val(len, TYPE_COUNT)); - - // We need the min() here because Ethernet padding can lead to - // caplen > len. - vl->append(new StringVal(min(caplen, len), (const char*) data)); - - ConnectionEvent(tcp_packet, vl); - } - -int TCP_Analyzer::DeliverData(double t, const u_char* data, int len, int caplen, - const IP_Hdr* ip, const struct tcphdr* tp, - TCP_Endpoint* endpoint, uint32 base_seq, - int is_orig, TCP_Flags flags) - { - int data_seq = base_seq - endpoint->StartSeq(); - if ( flags.SYN() ) - ++data_seq; // skip over SYN octet - - int need_contents = endpoint->DataSent(t, data_seq, - len, caplen, data, ip, tp); - - return need_contents; - } - -void TCP_Analyzer::CheckRecording(int need_contents, TCP_Flags flags) - { - bool record_current_content = need_contents || Conn()->RecordContents(); - bool record_current_packet = - Conn()->RecordPackets() || - flags.SYN() || flags.FIN() || flags.RST(); - - Conn()->SetRecordCurrentContent(record_current_content); - Conn()->SetRecordCurrentPacket(record_current_packet); - } - -void TCP_Analyzer::CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip) - { - if ( is_orig && ! (first_packet_seen & ORIG) ) - { - pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); - if ( pia ) - pia->FirstPacket(is_orig, ip); - first_packet_seen |= ORIG; - } - - if ( ! is_orig && ! (first_packet_seen & RESP) ) - { - pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); - if ( pia ) - pia->FirstPacket(is_orig, ip); - first_packet_seen |= RESP; - } - } - -void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) - { - TransportLayerAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - - const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen); - if ( ! tp ) - return; - - // We need the min() here because Ethernet frame padding can lead to - // caplen > len. - if ( packet_contents ) - PacketContents(data, min(len, caplen)); - - TCP_Endpoint* endpoint = is_orig ? orig : resp; - TCP_Endpoint* peer = endpoint->peer; - - if ( ! ValidateChecksum(tp, endpoint, len, caplen) ) - return; - - TCP_Flags flags(tp); - - uint32 base_seq = ntohl(tp->th_seq); - uint32 ack_seq = ntohl(tp->th_ack); - - CheckFlagCombos(flags, endpoint, base_seq, len, ntohs(tp->th_dport)); - - UpdateWindow(endpoint, ntohs(tp->th_win), base_seq, ack_seq, flags); - - double t = current_timestamp; - - if ( ! orig->did_close || ! resp->did_close ) - Conn()->SetLastTime(t); - - const IPAddr orig_addr = Conn()->OrigAddr(); - - uint32 tcp_hdr_len = data - (const u_char*) tp; - - int seq_len = len; // length in terms of sequence space - - ProcessFlags(t, ip, tp, tcp_hdr_len, len, seq_len, endpoint, peer, base_seq, - ack_seq, orig_addr, is_orig, flags); - - uint32 last_seq = base_seq + seq_len; - - if ( endpoint->state == TCP_ENDPOINT_INACTIVE ) - TransitionFromInactive(t, endpoint, base_seq, last_seq, - flags.SYN()); - - int delta_last = UpdateLastSeq(endpoint, last_seq, flags); - - endpoint->last_time = t; - - int do_close; - int gen_event; - UpdateStateMachine(t, endpoint, peer, base_seq, ack_seq, last_seq, - len, delta_last, is_orig, flags, - do_close, gen_event); - - if ( tcp_packet ) - GeneratePacketEvent(endpoint, peer, base_seq, ack_seq, - data, len, caplen, is_orig, flags); - - if ( tcp_option && tcp_hdr_len > sizeof(*tp) && - tcp_hdr_len <= uint32(caplen) ) - ParseTCPOptions(tp, TCPOptionEvent, this, is_orig, 0); - - if ( DEBUG_tcp_data_sent ) - { - DEBUG_MSG("%.6f before DataSent: len=%d caplen=%d skip=%d\n", - network_time, len, caplen, Skipping()); - } - - int need_contents = 0; - if ( len > 0 && (caplen >= len || packet_children.size()) && - ! flags.RST() && ! Skipping() ) - need_contents = DeliverData(t, data, len, caplen, ip, tp, - endpoint, base_seq, - is_orig, flags); - - endpoint->CheckEOF(); - - if ( do_close ) - { - // We need to postpone doing this until after we process - // DataSent, so we don't generate a connection_finished event - // until after data perhaps included with the FIN is processed. - ConnectionClosed(endpoint, peer, gen_event); - } - - CheckRecording(need_contents, flags); - - // Handle child_packet analyzers. Note: This happens *after* the - // packet has been processed and the TCP state updated. - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->NextPacket(len, data, is_orig, - base_seq - endpoint->StartSeq(), ip, caplen); - - if ( ! reassembling ) - ForwardPacket(len, data, is_orig, - base_seq - endpoint->StartSeq(), ip, caplen); - - CheckPIA_FirstPacket(is_orig, ip); - } - -void TCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) - { - Analyzer::DeliverStream(len, data, orig); - } - -void TCP_Analyzer::Undelivered(int seq, int len, bool is_orig) - { - Analyzer::Undelivered(seq, len, orig); - } - -void TCP_Analyzer::FlipRoles() - { - Analyzer::FlipRoles(); - - sessions->tcp_stats.FlipState(orig->state, resp->state); - TCP_Endpoint* tmp_ep = resp; - resp = orig; - orig = tmp_ep; - orig->is_orig = !orig->is_orig; - resp->is_orig = !resp->is_orig; - } - -void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val) - { - RecordVal *orig_endp_val = conn_val->Lookup("orig")->AsRecordVal(); - RecordVal *resp_endp_val = conn_val->Lookup("resp")->AsRecordVal(); - - orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT)); - orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT)); - resp_endp_val->Assign(0, new Val(resp->Size(), TYPE_COUNT)); - resp_endp_val->Assign(1, new Val(int(resp->state), TYPE_COUNT)); - - // Call children's UpdateConnVal - Analyzer::UpdateConnVal(conn_val); - - // Have to do packet_children ourselves. - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->UpdateConnVal(conn_val); - } - -Val* TCP_Analyzer::BuildSYNPacketVal(int is_orig, const IP_Hdr* ip, - const struct tcphdr* tcp) +static RecordVal* build_syn_packet_val(int is_orig, const IP_Hdr* ip, + const struct tcphdr* tcp) { int winscale = -1; int MSS = 0; @@ -1195,8 +115,8 @@ Val* TCP_Analyzer::BuildSYNPacketVal(int is_orig, const IP_Hdr* ip, return v; } -RecordVal* TCP_Analyzer::BuildOSVal(int is_orig, const IP_Hdr* ip, - const struct tcphdr* tcp, uint32 tcp_hdr_len) +static RecordVal* build_os_val(int is_orig, const IP_Hdr* ip, + const struct tcphdr* tcp, uint32 tcp_hdr_len) { if ( ! is_orig ) // Later we might use SYN-ACK fingerprinting here. @@ -1361,6 +281,1134 @@ RecordVal* TCP_Analyzer::BuildOSVal(int is_orig, const IP_Hdr* ip, return 0; } + +static void passive_fingerprint(TCP_Analyzer* tcp, bool is_orig, + const IP_Hdr* ip, const struct tcphdr* tp, + uint32 tcp_hdr_len) + { + // is_orig will be removed once we can do SYN-ACK fingerprinting + if ( OS_version_found && is_orig ) + { + const IPAddr& orig_addr = tcp->Conn()->OrigAddr(); + AddrVal* src_addr_val = new AddrVal(orig_addr); + + if ( generate_OS_version_event->Size() == 0 || + generate_OS_version_event->Lookup(src_addr_val) ) + { + RecordVal* OS_val = build_os_val(is_orig, ip, tp, tcp_hdr_len); + + if ( OS_val ) + { // found new OS version + val_list* vl = new val_list; + vl->append(tcp->BuildConnVal()); + vl->append(src_addr_val->Ref()); + vl->append(OS_val); + tcp->ConnectionEvent(OS_version_found, vl); + } + } + + Unref(src_addr_val); + } + } + +TCP_Analyzer::TCP_Analyzer(Connection* conn) +: TransportLayerAnalyzer("TCP", conn) + { + // Set a timer to eventually time out this connection. + ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer, + network_time + tcp_SYN_timeout, 0, + TIMER_TCP_EXPIRE); + + deferred_gen_event = close_deferred = 0; + + seen_first_ACK = 0; + is_active = 1; + finished = 0; + reassembling = 0; + first_packet_seen = 0; + is_partial = 0; + + orig = new TCP_Endpoint(this, 1); + resp = new TCP_Endpoint(this, 0); + + orig->SetPeer(resp); + resp->SetPeer(orig); + } + +TCP_Analyzer::~TCP_Analyzer() + { + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + delete *i; + + delete orig; + delete resp; + } + +void TCP_Analyzer::Init() + { + Analyzer::Init(); + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->Init(); + } + +void TCP_Analyzer::Done() + { + Analyzer::Done(); + + if ( connection_pending && is_active && ! BothClosed() ) + Event(connection_pending); + + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->Done(); + + orig->Done(); + resp->Done(); + + finished = 1; + } + +void TCP_Analyzer::EnableReassembly() + { + SetReassembler(new TCP_Reassembler(this, this, + TCP_Reassembler::Forward, orig), + new TCP_Reassembler(this, this, + TCP_Reassembler::Forward, resp)); + + reassembling = 1; + + if ( new_connection_contents ) + Event(new_connection_contents); + } + +void TCP_Analyzer::SetReassembler(TCP_Reassembler* rorig, + TCP_Reassembler* rresp) + { + orig->AddReassembler(rorig); + rorig->SetDstAnalyzer(this); + resp->AddReassembler(rresp); + rresp->SetDstAnalyzer(this); + + reassembling = 1; + + if ( new_connection_contents ) + Event(new_connection_contents); + } + +const struct tcphdr* TCP_Analyzer::ExtractTCP_Header(const u_char*& data, + int& len, int& caplen) + { + const struct tcphdr* tp = (const struct tcphdr*) data; + uint32 tcp_hdr_len = tp->th_off * 4; + + if ( tcp_hdr_len < sizeof(struct tcphdr) ) + { + Weird("bad_TCP_header_len"); + return 0; + } + + if ( tcp_hdr_len > uint32(len) || + sizeof(struct tcphdr) > uint32(caplen) ) + { + // This can happen even with the above test, due to TCP + // options. + Weird("truncated_header"); + return 0; + } + + len -= tcp_hdr_len; // remove TCP header + caplen -= tcp_hdr_len; + data += tcp_hdr_len; + + return tp; + } + +bool TCP_Analyzer::ValidateChecksum(const struct tcphdr* tp, + TCP_Endpoint* endpoint, int len, int caplen) + { + if ( ! ignore_checksums && caplen >= len && + ! endpoint->ValidChecksum(tp, len) ) + { + Weird("bad_TCP_checksum"); + endpoint->CheckHistory(HIST_CORRUPT_PKT, 'C'); + return false; + } + else + return true; + } + +void TCP_Analyzer::SetPartialStatus(TCP_Flags flags, bool is_orig) + { + if ( is_orig ) + { + if ( ! (first_packet_seen & ORIG) ) + is_partial = ! flags.SYN() || flags.ACK(); + } + else + { + if ( ! (first_packet_seen & RESP) && ! is_partial ) + is_partial = ! flags.SYN(); + } + } + +static void update_history(TCP_Flags flags, TCP_Endpoint* endpoint, + uint64 rel_seq, int len) + { + int bits_set = (flags.SYN() ? 1 : 0) + (flags.FIN() ? 1 : 0) + + (flags.RST() ? 1 : 0); + if ( bits_set > 1 ) + { + if ( flags.FIN() && flags.RST() ) + endpoint->CheckHistory(HIST_FIN_RST_PKT, 'I'); + else + endpoint->CheckHistory(HIST_MULTI_FLAG_PKT, 'Q'); + } + + else if ( bits_set == 1 ) + { + if ( flags.SYN() ) + { + char code = flags.ACK() ? 'H' : 'S'; + + if ( endpoint->CheckHistory(HIST_SYN_PKT, code) && + rel_seq != endpoint->hist_last_SYN ) + endpoint->AddHistory(code); + + endpoint->hist_last_SYN = rel_seq; + } + + if ( flags.FIN() ) + { + // For FIN's, the sequence number comes at the + // end of (any data in) the packet, not the + // beginning as for SYNs and RSTs. + if ( endpoint->CheckHistory(HIST_FIN_PKT, 'F') && + rel_seq + len != endpoint->hist_last_FIN ) + endpoint->AddHistory('F'); + + endpoint->hist_last_FIN = rel_seq + len; + } + + if ( flags.RST() ) + { + if ( endpoint->CheckHistory(HIST_RST_PKT, 'R') && + rel_seq != endpoint->hist_last_RST ) + endpoint->AddHistory('R'); + + endpoint->hist_last_RST = rel_seq; + } + } + + else + { // bits_set == 0 + if ( len ) + endpoint->CheckHistory(HIST_DATA_PKT, 'D'); + + else if ( flags.ACK() ) + endpoint->CheckHistory(HIST_ACK_PKT, 'A'); + } + } + +static void init_window(TCP_Endpoint* endpoint, TCP_Endpoint* peer, + TCP_Flags flags, bro_int_t scale, uint32 base_seq, + uint32 ack_seq) + { + // ### In the following, we could be fooled by an + // inconsistent SYN retransmission. Where's a normalizer + // when you need one? + + if ( scale < 0 ) + { // no window scaling option + if ( flags.ACK() ) + { // window scaling not negotiated + endpoint->window_scale = 0; + peer->window_scale = 0; + } + else + // We're not offering window scaling. + // Ideally, we'd remember this fact so that + // if the SYN/ACK *does* include window + // scaling, we know it won't be negotiated. + // But it's a pain to track that, and hard + // to see how an adversarial responder could + // use it to evade. Also, if we *do* want + // to track it, we could do so using + // connection_SYN_packet. + endpoint->window_scale = 0; + } + else + { + endpoint->window_scale = scale; + endpoint->window_seq = base_seq; + endpoint->window_ack_seq = ack_seq; + + peer->window_seq = ack_seq; + peer->window_ack_seq = base_seq; + } + } + +static void update_window(TCP_Endpoint* endpoint, unsigned int window, + uint32 base_seq, uint32 ack_seq, TCP_Flags flags) + { + // Note, the offered window on an initial SYN is unscaled, even + // if the SYN includes scaling, so we need to do the following + // test *before* updating the scaling information below. (Hmmm, + // how does this work for windows on SYN/ACKs? ###) + int scale = endpoint->window_scale; + window = window << scale; + + // Don't analyze window values off of SYNs, they're sometimes + // immediately rescinded. + if ( ! flags.SYN() ) + { + // ### Decide whether to accept new window based on Active + // Mapping policy. + if ( seq_delta(base_seq, endpoint->window_seq) >= 0 && + seq_delta(ack_seq, endpoint->window_ack_seq) >= 0 ) + { + uint32 new_edge = ack_seq + window; + uint32 old_edge = endpoint->window_ack_seq + endpoint->window; + int32 advance = seq_delta(new_edge, old_edge); + + if ( advance < 0 ) + { + // A window recision. We don't report these + // for FINs or RSTs, or if the connection + // has already been partially closed, since + // such recisions occur frequently in practice, + // probably as the receiver loses buffer memory + // due to its process going away. + // + // We also, for window scaling, allow a bit + // of slop ###. This is because sometimes + // there will be an apparent recision due + // to the granularity of the scaling. + if ( ! flags.FIN() && ! flags.RST() && + endpoint->state != TCP_ENDPOINT_CLOSED && + endpoint->state != TCP_ENDPOINT_RESET && + (-advance) >= (1 << scale) ) + endpoint->Conn()->Weird("window_recision"); + } + + endpoint->window = window; + endpoint->window_ack_seq = ack_seq; + endpoint->window_seq = base_seq; + } + } + } + +static void syn_weirds(TCP_Flags flags, TCP_Endpoint* endpoint, int data_len) + { + if ( flags.RST() ) + endpoint->Conn()->Weird("TCP_christmas"); + + if ( flags.URG() ) + endpoint->Conn()->Weird("baroque_SYN"); + + if ( data_len > 0 ) + // Not technically wrong according to RFC 793, but the other side + // would be forced to buffer data until the handshake succeeds, and + // that could be bad in some cases, e.g. SYN floods. + // T/TCP definitely complicates this. + endpoint->Conn()->Weird("SYN_with_data"); + } + +void TCP_Analyzer::UpdateInactiveState(double t, + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + uint32 base_seq, uint32 ack_seq, + int len, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event) + { + if ( flags.SYN() ) + { + if ( is_orig ) + { + if ( flags.ACK() ) + { + Weird("connection_originator_SYN_ack"); + endpoint->SetState(TCP_ENDPOINT_SYN_ACK_SENT); + } + else + endpoint->SetState(TCP_ENDPOINT_SYN_SENT); + + if ( tcp_attempt_delay ) + ADD_ANALYZER_TIMER(&TCP_Analyzer::AttemptTimer, + t + tcp_attempt_delay, 1, + TIMER_TCP_ATTEMPT); + } + else + { + if ( flags.ACK() ) + { + if ( peer->state != TCP_ENDPOINT_INACTIVE && + peer->state != TCP_ENDPOINT_PARTIAL && + ! seq_between(ack_seq, peer->StartSeq(), peer->LastSeq()) ) + Weird("bad_SYN_ack"); + } + + else if ( peer->state == TCP_ENDPOINT_SYN_ACK_SENT && + base_seq == endpoint->StartSeq() ) + { + // This is a SYN/SYN-ACK reversal, + // per the discussion in IsReuse. + // Flip the endpoints and establish + // the connection. + is_partial = 0; + Conn()->FlipRoles(); + peer->SetState(TCP_ENDPOINT_ESTABLISHED); + } + + else + Weird("simultaneous_open"); + + if ( peer->state == TCP_ENDPOINT_SYN_SENT ) + peer->SetState(TCP_ENDPOINT_ESTABLISHED); + else if ( peer->state == TCP_ENDPOINT_INACTIVE ) + { + // If we were to ignore SYNs and + // only instantiate state on SYN + // acks, then we'd do: + // peer->SetState(TCP_ENDPOINT_ESTABLISHED); + // here. + Weird("unsolicited_SYN_response"); + } + + endpoint->SetState(TCP_ENDPOINT_ESTABLISHED); + + if ( peer->state != TCP_ENDPOINT_PARTIAL ) + { + Event(connection_established); + Conn()->EnableStatusUpdateTimer(); + } + } + } + + if ( flags.FIN() ) + { + endpoint->SetState(TCP_ENDPOINT_CLOSED); + do_close = gen_event = 1; + if ( peer->state != TCP_ENDPOINT_PARTIAL && ! flags.SYN() ) + Weird("spontaneous_FIN"); + } + + if ( flags.RST() ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + + int is_reject = 0; + + if ( is_orig ) + { + // If our peer is established then we saw + // a SYN-ack but not SYN - so a reverse + // scan, and we should treat this as a + // reject. + if ( peer->state == TCP_ENDPOINT_ESTABLISHED ) + is_reject = 1; + } + + else if ( peer->state == TCP_ENDPOINT_SYN_SENT || + peer->state == TCP_ENDPOINT_SYN_ACK_SENT ) + // We're rejecting an initial SYN. + is_reject = 1; + + do_close = 1; + gen_event = ! is_reject; + + if ( is_reject ) + Event(connection_rejected); + + else if ( peer->state == TCP_ENDPOINT_INACTIVE ) + Weird("spontaneous_RST"); + } + + if ( endpoint->state == TCP_ENDPOINT_INACTIVE ) + { // No control flags to change the state. + if ( ! is_orig && len == 0 && + orig->state == TCP_ENDPOINT_SYN_SENT ) + // Some eccentric TCP's will ack an initial + // SYN prior to sending a SYN reply (hello, + // ftp.microsoft.com). For those, don't + // consider the ack as forming a partial + // connection. + ; + else + { + endpoint->SetState(TCP_ENDPOINT_PARTIAL); + Conn()->EnableStatusUpdateTimer(); + + if ( peer->state == TCP_ENDPOINT_PARTIAL ) + // We've seen both sides of a partial + // connection, report it. + Event(partial_connection); + } + } + } + +void TCP_Analyzer::UpdateSYN_SentState(TCP_Endpoint* endpoint, TCP_Endpoint* peer, + int len, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event) + { + if ( flags.SYN() ) + { + if ( is_orig ) + { + if ( flags.ACK() && ! flags.FIN() && ! flags.RST() && + endpoint->state != TCP_ENDPOINT_SYN_ACK_SENT ) + Weird("repeated_SYN_with_ack"); + } + else + { + if ( ! flags.ACK() && + endpoint->state != TCP_ENDPOINT_SYN_SENT ) + Weird("repeated_SYN_reply_wo_ack"); + } + } + + if ( flags.FIN() ) + { + if ( peer->state == TCP_ENDPOINT_INACTIVE || + peer->state == TCP_ENDPOINT_SYN_SENT ) + Weird("inappropriate_FIN"); + + endpoint->SetState(TCP_ENDPOINT_CLOSED); + do_close = gen_event = 1; + } + + if ( flags.RST() ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + ConnectionReset(); + do_close = 1; + } + + else if ( len > 0 ) + Weird("data_before_established"); + } + +void TCP_Analyzer::UpdateEstablishedState( + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + TCP_Flags flags, int& do_close, int& gen_event) + { + if ( flags.SYN() ) + { + if ( endpoint->state == TCP_ENDPOINT_PARTIAL && + peer->state == TCP_ENDPOINT_INACTIVE && ! flags.ACK() ) + { + Weird("SYN_after_partial"); + endpoint->SetState(TCP_ENDPOINT_SYN_SENT); + } + } + + if ( flags.FIN() && ! flags.RST() ) // ### + { // should check sequence/ack numbers here ### + endpoint->SetState(TCP_ENDPOINT_CLOSED); + + if ( peer->state == TCP_ENDPOINT_RESET && + peer->prev_state == TCP_ENDPOINT_CLOSED ) + // The peer sent a FIN followed by a RST. + // Turn it back into CLOSED state, because + // this was actually normal termination. + peer->SetState(TCP_ENDPOINT_CLOSED); + + do_close = gen_event = 1; + } + + if ( flags.RST() ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + do_close = 1; + + if ( peer->state != TCP_ENDPOINT_RESET || + peer->prev_state != TCP_ENDPOINT_ESTABLISHED ) + ConnectionReset(); + } + } + +void TCP_Analyzer::UpdateClosedState(double t, TCP_Endpoint* endpoint, + int32 delta_last, TCP_Flags flags, int& do_close) + { + if ( flags.SYN() ) + Weird("SYN_after_close"); + + if ( flags.FIN() && delta_last > 0 ) + // Probably should also complain on FIN recision. + // That requires an extra state variable to avoid + // generating slews of weird's when a TCP gets + // seriously confused (this from experience). + Weird("FIN_advanced_last_seq"); + + // Previously, our state was CLOSED, since we sent a FIN. + // If our peer was also closed, then don't change our state + // now on a RST, since this connection has already seen a FIN + // exchange. + if ( flags.RST() && endpoint->peer->state != TCP_ENDPOINT_CLOSED ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + + if ( ! endpoint->did_close ) + // RST after FIN. + do_close = 1; + + if ( connection_reset ) + ADD_ANALYZER_TIMER(&TCP_Analyzer::ResetTimer, + t + tcp_reset_delay, 1, + TIMER_TCP_RESET); + } + } + +void TCP_Analyzer::UpdateResetState(int len, TCP_Flags flags) + { + if ( flags.SYN() ) + Weird("SYN_after_reset"); + + if ( flags.FIN() ) + Weird("FIN_after_reset"); + + if ( len > 0 && ! flags.RST() ) + Weird("data_after_reset"); + } + +void TCP_Analyzer::UpdateStateMachine(double t, + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + uint32 base_seq, uint32 ack_seq, + int len, int32 delta_last, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event) + { + do_close = 0; // whether to report the connection as closed + gen_event = 0; // if so, whether to generate an event + + switch ( endpoint->state ) { + + case TCP_ENDPOINT_INACTIVE: + UpdateInactiveState(t, endpoint, peer, base_seq, ack_seq, + len, is_orig, flags, + do_close, gen_event); + break; + + case TCP_ENDPOINT_SYN_SENT: + case TCP_ENDPOINT_SYN_ACK_SENT: + UpdateSYN_SentState(endpoint, peer, len, is_orig, flags, do_close, + gen_event); + break; + + case TCP_ENDPOINT_ESTABLISHED: + case TCP_ENDPOINT_PARTIAL: + UpdateEstablishedState(endpoint, peer, flags, do_close, gen_event); + break; + + case TCP_ENDPOINT_CLOSED: + UpdateClosedState(t, endpoint, delta_last, flags, do_close); + break; + + case TCP_ENDPOINT_RESET: + UpdateResetState(len, flags); + break; + } + } + +void TCP_Analyzer::GeneratePacketEvent( + uint64 rel_seq, uint64 rel_ack, + const u_char* data, int len, int caplen, + int is_orig, TCP_Flags flags) + { + char tcp_flags[256]; + int tcp_flag_len = 0; + + if ( flags.SYN() ) tcp_flags[tcp_flag_len++] = 'S'; + if ( flags.FIN() ) tcp_flags[tcp_flag_len++] = 'F'; + if ( flags.RST() ) tcp_flags[tcp_flag_len++] = 'R'; + if ( flags.ACK() ) tcp_flags[tcp_flag_len++] = 'A'; + if ( flags.PUSH() ) tcp_flags[tcp_flag_len++] = 'P'; + if ( flags.URG() ) tcp_flags[tcp_flag_len++] = 'U'; + + tcp_flags[tcp_flag_len] = '\0'; + + val_list* vl = new val_list(); + + vl->append(BuildConnVal()); + vl->append(new Val(is_orig, TYPE_BOOL)); + vl->append(new StringVal(tcp_flags)); + vl->append(new Val(rel_seq, TYPE_COUNT)); + vl->append(new Val(flags.ACK() ? rel_ack : 0, TYPE_COUNT)); + vl->append(new Val(len, TYPE_COUNT)); + + // We need the min() here because Ethernet padding can lead to + // caplen > len. + vl->append(new StringVal(min(caplen, len), (const char*) data)); + + ConnectionEvent(tcp_packet, vl); + } + +int TCP_Analyzer::DeliverData(double t, const u_char* data, int len, int caplen, + const IP_Hdr* ip, const struct tcphdr* tp, + TCP_Endpoint* endpoint, uint64 rel_data_seq, + int is_orig, TCP_Flags flags) + { + return endpoint->DataSent(t, rel_data_seq, len, caplen, data, ip, tp); + } + +void TCP_Analyzer::CheckRecording(int need_contents, TCP_Flags flags) + { + bool record_current_content = need_contents || Conn()->RecordContents(); + bool record_current_packet = + Conn()->RecordPackets() || + flags.SYN() || flags.FIN() || flags.RST(); + + Conn()->SetRecordCurrentContent(record_current_content); + Conn()->SetRecordCurrentPacket(record_current_packet); + } + +void TCP_Analyzer::CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip) + { + if ( is_orig && ! (first_packet_seen & ORIG) ) + { + pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); + if ( pia ) + pia->FirstPacket(is_orig, ip); + first_packet_seen |= ORIG; + } + + if ( ! is_orig && ! (first_packet_seen & RESP) ) + { + pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); + if ( pia ) + pia->FirstPacket(is_orig, ip); + first_packet_seen |= RESP; + } + } + +static uint64 get_relative_seq(const TCP_Endpoint* endpoint, + uint32 cur_base, uint32 last, uint32 wraps, + bool* underflow = 0) + { + int32 delta = seq_delta(cur_base, last); + + if ( delta < 0 ) + { + if ( wraps && cur_base > last ) + // Seems to be a part of a previous 32-bit sequence space. + --wraps; + } + + else if ( delta > 0 ) + { + if ( cur_base < last ) + // The sequence space wrapped around. + ++wraps; + } + + if ( wraps == 0 ) + { + delta = seq_delta(cur_base, endpoint->StartSeq()); + + if ( underflow && delta < 0 ) + *underflow = true; + + return delta; + } + + return endpoint->ToRelativeSeqSpace(cur_base, wraps); + } + +static int get_segment_len(int payload_len, TCP_Flags flags) + { + int seg_len = payload_len; + + if ( flags.SYN() ) + // SYN consumes a byte of sequence space. + ++seg_len; + + if ( flags.FIN() ) + // FIN consumes a bytes of sequence space. + ++seg_len; + + if ( flags.RST() ) + // Don't include the data in the computation of + // the sequence space for this connection, as + // it's not in fact part of the TCP stream. + seg_len -= payload_len; + + return seg_len; + } + +static void init_endpoint(TCP_Endpoint* endpoint, TCP_Flags flags, + uint32 first_seg_seq, uint32 last_seq, double t) + { + switch ( endpoint->state ) { + case TCP_ENDPOINT_INACTIVE: + if ( flags.SYN() ) + { + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitStartSeq(first_seg_seq); + } + else + { + // This is a partial connection - set up the initial sequence + // numbers as though we saw a SYN, to keep the relative byte + // numbering consistent. + endpoint->InitAckSeq(first_seg_seq - 1); + endpoint->InitStartSeq(first_seg_seq - 1); + } + + endpoint->InitLastSeq(last_seq); + endpoint->start_time = t; + break; + + case TCP_ENDPOINT_SYN_SENT: + case TCP_ENDPOINT_SYN_ACK_SENT: + if ( flags.SYN() && first_seg_seq != endpoint->StartSeq() ) + { + endpoint->Conn()->Weird("SYN_seq_jump"); + endpoint->InitStartSeq(first_seg_seq); + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitLastSeq(last_seq); + } + break; + + case TCP_ENDPOINT_ESTABLISHED: + case TCP_ENDPOINT_PARTIAL: + if ( flags.SYN() ) + { + if ( endpoint->Size() > 0 ) + endpoint->Conn()->Weird("SYN_inside_connection"); + + if ( first_seg_seq != endpoint->StartSeq() ) + endpoint->Conn()->Weird("SYN_seq_jump"); + + // Make a guess that somehow the connection didn't get established, + // and this SYN will be the one that actually sets it up. + endpoint->InitStartSeq(first_seg_seq); + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitLastSeq(last_seq); + } + break; + + case TCP_ENDPOINT_RESET: + if ( flags.SYN() ) + { + if ( endpoint->prev_state == TCP_ENDPOINT_INACTIVE ) + { + // Seq. numbers were initialized by a RST packet from this + // endpoint, but now that a SYN is seen from it, that could mean + // the earlier RST was spoofed/injected, so re-initialize. This + // mostly just helps prevent misrepresentations of payload sizes + // that are based on bad initial sequence values. + endpoint->InitStartSeq(first_seg_seq); + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitLastSeq(last_seq); + } + } + break; + + default: + break; + } + } + +static void init_peer(TCP_Endpoint* peer, TCP_Endpoint* endpoint, + TCP_Flags flags, uint32 ack_seq) + { + if ( ! flags.SYN() && ! flags.FIN() && ! flags.RST() ) + { + if ( endpoint->state == TCP_ENDPOINT_SYN_SENT || + endpoint->state == TCP_ENDPOINT_SYN_ACK_SENT || + endpoint->state == TCP_ENDPOINT_ESTABLISHED ) + { + // We've already sent a SYN, but that + // hasn't roused the other end, yet we're + // ack'ing their data. + + if ( ! endpoint->Conn()->DidWeird() ) + endpoint->Conn()->Weird("possible_split_routing"); + } + } + + // Start the sequence numbering as if there was an initial + // SYN, so the relative numbering of subsequent data packets + // stays consistent. + peer->InitStartSeq(ack_seq - 1); + peer->InitAckSeq(ack_seq - 1); + peer->InitLastSeq(ack_seq - 1); + } + +static void update_ack_seq(TCP_Endpoint* endpoint, uint32 ack_seq) + { + int32 delta_ack = seq_delta(ack_seq, endpoint->AckSeq()); + + if ( ack_seq == 0 && delta_ack > TOO_LARGE_SEQ_DELTA ) + // More likely that this is a broken ack than a + // large connection that happens to land on 0 in the + // sequence space. + ; + else if ( delta_ack > 0 ) + endpoint->UpdateAckSeq(ack_seq); + } + +// Returns the difference between last_seq and the last sequence +// seen by the endpoint (may be negative). +static int32 update_last_seq(TCP_Endpoint* endpoint, uint32 last_seq, + TCP_Flags flags) + { + int32 delta_last = seq_delta(last_seq, endpoint->LastSeq()); + + if ( (flags.SYN() || flags.RST()) && + (delta_last > TOO_LARGE_SEQ_DELTA || + delta_last < -TOO_LARGE_SEQ_DELTA) ) + // ### perhaps trust RST seq #'s if initial and not too + // outlandish, but not if they're coming after the other + // side has sent a FIN - trust the FIN ack instead + ; + + else if ( flags.FIN() && + endpoint->LastSeq() == endpoint->StartSeq() + 1 ) + // Update last_seq based on the FIN even if delta_last < 0. + // This is to accommodate > 2 GB connections for which + // we've only seen the SYN and the FIN (hence the check + // for last_seq == start_seq + 1). + endpoint->UpdateLastSeq(last_seq); + + else if ( endpoint->state == TCP_ENDPOINT_RESET ) + // don't trust any subsequent sequence numbers + ; + + else if ( delta_last > 0 ) + // ### check for large jumps here. + // ## endpoint->last_seq = last_seq; + endpoint->UpdateLastSeq(last_seq); + + else if ( delta_last <= 0 ) + { // ### ++retransmit, unless this is a pure ack + } + + return delta_last; + } + +void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, + uint64 seq, const IP_Hdr* ip, int caplen) + { + TransportLayerAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + + const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen); + if ( ! tp ) + return; + + // We need the min() here because Ethernet frame padding can lead to + // caplen > len. + if ( packet_contents ) + PacketContents(data, min(len, caplen)); + + TCP_Endpoint* endpoint = is_orig ? orig : resp; + TCP_Endpoint* peer = endpoint->peer; + + if ( ! ValidateChecksum(tp, endpoint, len, caplen) ) + return; + + uint32 tcp_hdr_len = data - (const u_char*) tp; + TCP_Flags flags(tp); + SetPartialStatus(flags, endpoint->IsOrig()); + + uint32 base_seq = ntohl(tp->th_seq); + uint32 ack_seq = ntohl(tp->th_ack); + + int seg_len = get_segment_len(len, flags); + uint32 seq_one_past_segment = base_seq + seg_len; + + init_endpoint(endpoint, flags, base_seq, seq_one_past_segment, + current_timestamp); + + bool seq_underflow = false; + uint64 rel_seq = get_relative_seq(endpoint, base_seq, endpoint->LastSeq(), + endpoint->SeqWraps(), &seq_underflow); + + if ( seq_underflow && ! flags.RST() ) + // Can't tell if if this is a retransmit/out-of-order or something + // before the sequence Bro initialized the endpoint at or the TCP is + // just broken and sending garbage sequences. In either case, some + // standard analysis doesn't apply (e.g. reassembly). + Weird("TCP_seq_underflow_or_misorder"); + + update_history(flags, endpoint, rel_seq, len); + update_window(endpoint, ntohs(tp->th_win), base_seq, ack_seq, flags); + + if ( ! orig->did_close || ! resp->did_close ) + Conn()->SetLastTime(current_timestamp); + + if ( flags.SYN() ) + { + syn_weirds(flags, endpoint, len); + RecordVal* SYN_vals = build_syn_packet_val(is_orig, ip, tp); + init_window(endpoint, peer, flags, SYN_vals->Lookup(5)->CoerceToInt(), + base_seq, ack_seq); + + if ( connection_SYN_packet ) + { + val_list* vl = new val_list; + vl->append(BuildConnVal()); + vl->append(SYN_vals->Ref()); + ConnectionEvent(connection_SYN_packet, vl); + } + + passive_fingerprint(this, is_orig, ip, tp, tcp_hdr_len); + + Unref(SYN_vals); + } + + if ( flags.FIN() ) + { + ++endpoint->FIN_cnt; + + if ( endpoint->FIN_cnt >= tcp_storm_thresh && current_timestamp < + endpoint->last_time + tcp_storm_interarrival_thresh ) + Weird("FIN_storm"); + + endpoint->FIN_seq = rel_seq + seg_len; + } + + if ( flags.RST() ) + { + ++endpoint->RST_cnt; + + if ( endpoint->RST_cnt >= tcp_storm_thresh && current_timestamp < + endpoint->last_time + tcp_storm_interarrival_thresh ) + Weird("RST_storm"); + + // This now happens often enough that it's + // not in the least interesting. + //if ( len > 0 ) + // Weird("RST_with_data"); + + PacketWithRST(); + } + + uint64 rel_ack = 0; + + if ( flags.ACK() ) + { + if ( is_orig && ! seen_first_ACK && + (endpoint->state == TCP_ENDPOINT_ESTABLISHED || + endpoint->state == TCP_ENDPOINT_SYN_SENT) ) + { + seen_first_ACK = 1; + Event(connection_first_ACK); + } + + if ( peer->state == TCP_ENDPOINT_INACTIVE ) + { + rel_ack = 1; + init_peer(peer, endpoint, flags, ack_seq); + } + else + { + bool ack_underflow = false; + rel_ack = get_relative_seq(peer, ack_seq, peer->AckSeq(), + peer->AckWraps(), &ack_underflow); + + if ( ack_underflow ) + { + rel_ack = 0; + Weird("TCP_ack_underflow_or_misorder"); + } + else if ( ! flags.RST() ) + // Don't trust ack's in RSt packets. + update_ack_seq(peer, ack_seq); + } + + peer->AckReceived(rel_ack); + } + + int32 delta_last = update_last_seq(endpoint, seq_one_past_segment, flags); + endpoint->last_time = current_timestamp; + + int do_close; + int gen_event; + UpdateStateMachine(current_timestamp, endpoint, peer, base_seq, ack_seq, + len, delta_last, is_orig, flags, do_close, gen_event); + + if ( tcp_packet ) + GeneratePacketEvent(rel_seq, rel_ack, data, len, caplen, is_orig, + flags); + + if ( tcp_option && tcp_hdr_len > sizeof(*tp) && + tcp_hdr_len <= uint32(caplen) ) + ParseTCPOptions(tp, TCPOptionEvent, this, is_orig, 0); + + if ( DEBUG_tcp_data_sent ) + { + DEBUG_MSG("%.6f before DataSent: len=%d caplen=%d skip=%d\n", + network_time, len, caplen, Skipping()); + } + + uint64 rel_data_seq = flags.SYN() ? rel_seq + 1 : rel_seq; + + int need_contents = 0; + if ( len > 0 && (caplen >= len || packet_children.size()) && + ! flags.RST() && ! Skipping() && ! seq_underflow ) + need_contents = DeliverData(current_timestamp, data, len, caplen, ip, + tp, endpoint, rel_data_seq, is_orig, flags); + + endpoint->CheckEOF(); + + if ( do_close ) + { + // We need to postpone doing this until after we process + // DataSent, so we don't generate a connection_finished event + // until after data perhaps included with the FIN is processed. + ConnectionClosed(endpoint, peer, gen_event); + } + + CheckRecording(need_contents, flags); + + // Handle child_packet analyzers. Note: This happens *after* the + // packet has been processed and the TCP state updated. + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->NextPacket(len, data, is_orig, rel_data_seq, ip, caplen); + + if ( ! reassembling ) + ForwardPacket(len, data, is_orig, rel_data_seq, ip, caplen); + + CheckPIA_FirstPacket(is_orig, ip); + } + +void TCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) + { + Analyzer::DeliverStream(len, data, orig); + } + +void TCP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig) + { + Analyzer::Undelivered(seq, len, orig); + } + +void TCP_Analyzer::FlipRoles() + { + Analyzer::FlipRoles(); + + sessions->tcp_stats.FlipState(orig->state, resp->state); + TCP_Endpoint* tmp_ep = resp; + resp = orig; + orig = tmp_ep; + orig->is_orig = !orig->is_orig; + resp->is_orig = !resp->is_orig; + } + +void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val) + { + RecordVal *orig_endp_val = conn_val->Lookup("orig")->AsRecordVal(); + RecordVal *resp_endp_val = conn_val->Lookup("resp")->AsRecordVal(); + + orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT)); + orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT)); + resp_endp_val->Assign(0, new Val(resp->Size(), TYPE_COUNT)); + resp_endp_val->Assign(1, new Val(int(resp->state), TYPE_COUNT)); + + // Call children's UpdateConnVal + Analyzer::UpdateConnVal(conn_val); + + // Have to do packet_children ourselves. + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->UpdateConnVal(conn_val); + } + int TCP_Analyzer::ParseTCPOptions(const struct tcphdr* tcp, proc_tcp_option_t proc, TCP_Analyzer* analyzer, @@ -1849,11 +1897,11 @@ void TCP_ApplicationAnalyzer::ProtocolViolation(const char* reason, } void TCP_ApplicationAnalyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); - DBG_LOG(DBG_ANALYZER, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", + DBG_LOG(DBG_ANALYZER, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %"PRIu64", %p, %d) [%s%s]", len, is_orig ? "T" : "F", seq, ip, caplen, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } @@ -1930,7 +1978,7 @@ int endian_flip(int n) return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); } -int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, +int TCPStats_Endpoint::DataSent(double /* t */, uint64 seq, int len, int caplen, const u_char* /* data */, const IP_Hdr* ip, const struct tcphdr* /* tp */) { @@ -1990,14 +2038,14 @@ int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, ++num_in_order; - int top_seq = seq + len; + uint64 top_seq = seq + len; - int data_in_flight = endp->LastSeq() - endp->AckSeq(); + int32 data_in_flight = seq_delta(endp->LastSeq(), endp->AckSeq()); if ( data_in_flight < 0 ) data_in_flight = 0; - int seq_delta = top_seq - max_top_seq; - if ( seq_delta <= 0 ) + int64 sequence_delta = top_seq - max_top_seq; + if ( sequence_delta <= 0 ) { if ( ! BifConst::ignore_keep_alive_rexmit || len > 1 || data_in_flight > 0 ) { @@ -2005,7 +2053,7 @@ int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, num_rxmit_bytes += len; } - DEBUG_MSG("%.6f rexmit %d + %d <= %d data_in_flight = %d\n", + DEBUG_MSG("%.6f rexmit %"PRIu64" + %d <= %"PRIu64" data_in_flight = %d\n", network_time, seq, len, max_top_seq, data_in_flight); if ( tcp_rexmit ) @@ -2073,7 +2121,7 @@ void TCPStats_Analyzer::Done() ConnectionEvent(conn_stats, vl); } -void TCPStats_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) +void TCPStats_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/tcp/TCP.h b/src/analyzer/protocol/tcp/TCP.h index b2649b4ab8..ab3836d2ea 100644 --- a/src/analyzer/protocol/tcp/TCP.h +++ b/src/analyzer/protocol/tcp/TCP.h @@ -102,9 +102,9 @@ protected: // Analyzer interface. virtual void Init(); virtual void Done(); - virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); + virtual void DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void FlipRoles(); virtual bool IsReuse(double t, const u_char* pkt); @@ -119,42 +119,7 @@ protected: bool ValidateChecksum(const struct tcphdr* tp, TCP_Endpoint* endpoint, int len, int caplen); - // Update analysis based on flag combinations. The endpoint, base_seq - // and len are needed for tracking various history information. - // dst_port is needed for trimming of FIN packets. - void CheckFlagCombos(TCP_Flags flags, TCP_Endpoint* endpoint, - uint32 base_seq, int len, int dst_port); - - void UpdateWindow(TCP_Endpoint* endpoint, unsigned int window, - uint32 base_seq, uint32 ack_seq, - TCP_Flags flags); - - void ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags); - - void ProcessFIN(double t, TCP_Endpoint* endpoint, int& seq_len, - uint32 base_seq); - - void ProcessRST(double t, TCP_Endpoint* endpoint, const IP_Hdr* ip, - uint32 base_seq, int len, int& seq_len); - - void ProcessACK(TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 ack_seq, int is_orig, TCP_Flags flags); - - void ProcessFlags(double t, const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags); - - void TransitionFromInactive(double t, TCP_Endpoint* endpoint, - uint32 base_seq, uint32 last_seq, - int SYN); + void SetPartialStatus(TCP_Flags flags, bool is_orig); // Update the state machine of the TCPs based on the activity. This // includes our pseudo-states such as TCP_ENDPOINT_PARTIAL. @@ -164,8 +129,8 @@ protected: // this fact. void UpdateStateMachine(double t, TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, uint32 last_seq, - int len, int delta_last, int is_orig, TCP_Flags flags, + uint32 base_seq, uint32 ack_seq, + int len, int32 delta_last, int is_orig, TCP_Flags flags, int& do_close, int& gen_event); void UpdateInactiveState(double t, @@ -174,43 +139,31 @@ protected: int len, int is_orig, TCP_Flags flags, int& do_close, int& gen_event); - void UpdateSYN_SentState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int len, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event); + void UpdateSYN_SentState(TCP_Endpoint* endpoint, TCP_Endpoint* peer, + int len, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event); - void UpdateEstablishedState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int is_orig, TCP_Flags flags, - int& do_close, int& gen_event); + void UpdateEstablishedState(TCP_Endpoint* endpoint, TCP_Endpoint* peer, + TCP_Flags flags, int& do_close, int& gen_event); void UpdateClosedState(double t, TCP_Endpoint* endpoint, - int delta_last, TCP_Flags flags, + int32 delta_last, TCP_Flags flags, int& do_close); - void UpdateResetState(int len, TCP_Flags flags, TCP_Endpoint* endpoint, - uint32 base_seq, uint32 last_seq); + void UpdateResetState(int len, TCP_Flags flags); - void GeneratePacketEvent(TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const u_char* data, int len, int caplen, - int is_orig, TCP_Flags flags); + void GeneratePacketEvent(uint64 rel_seq, uint64 rel_ack, + const u_char* data, int len, int caplen, + int is_orig, TCP_Flags flags); int DeliverData(double t, const u_char* data, int len, int caplen, const IP_Hdr* ip, const struct tcphdr* tp, - TCP_Endpoint* endpoint, uint32 base_seq, + TCP_Endpoint* endpoint, uint64 rel_data_seq, int is_orig, TCP_Flags flags); void CheckRecording(int need_contents, TCP_Flags flags); void CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip); - // Returns the difference between last_seq and the last sequence - // seen by the endpoint (may be negative). - int UpdateLastSeq(TCP_Endpoint* endpoint, uint32 last_seq, - TCP_Flags flags); - friend class ConnectionTimer; void AttemptTimer(double t); void PartialCloseTimer(double t); @@ -228,12 +181,6 @@ protected: void SetReassembler(tcp::TCP_Reassembler* rorig, tcp::TCP_Reassembler* rresp); - Val* BuildSYNPacketVal(int is_orig, - const IP_Hdr* ip, const struct tcphdr* tcp); - - RecordVal* BuildOSVal(int is_orig, const IP_Hdr* ip, - const struct tcphdr* tcp, uint32 tcp_hdr_len); - // Needs to be static because it's passed as a pointer-to-function // rather than pointer-to-member-function. static int TCPOptionEvent(unsigned int opt, unsigned int optlen, @@ -304,7 +251,7 @@ public: virtual void PacketWithRST(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void Init(); // This suppresses violations if the TCP connection wasn't @@ -341,7 +288,7 @@ class TCPStats_Endpoint { public: TCPStats_Endpoint(TCP_Endpoint* endp); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); RecordVal* BuildStats(); @@ -354,7 +301,7 @@ protected: int num_in_order; int num_OO; int num_repl; - int max_top_seq; + uint64 max_top_seq; int last_id; int endian_type; }; @@ -372,7 +319,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); TCPStats_Endpoint* orig_stats; TCPStats_Endpoint* resp_stats; diff --git a/src/analyzer/protocol/tcp/TCP_Endpoint.cc b/src/analyzer/protocol/tcp/TCP_Endpoint.cc index ad642a46e3..2e8d6e593b 100644 --- a/src/analyzer/protocol/tcp/TCP_Endpoint.cc +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.cc @@ -20,7 +20,7 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) peer = 0; start_time = last_time = 0.0; start_seq = last_seq = ack_seq = 0; - last_seq_high = ack_seq_high = 0; + seq_wraps = ack_wraps = 0; window = 0; window_scale = 0; window_seq = window_ack_seq = 0; @@ -108,7 +108,8 @@ void TCP_Endpoint::CheckEOF() contents_processor->CheckEOF(); } -void TCP_Endpoint::SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) +void TCP_Endpoint::SizeBufferedData(uint64& waiting_on_hole, + uint64& waiting_on_ack) { if ( contents_processor ) contents_processor->SizeBufferedData(waiting_on_hole, waiting_on_ack); @@ -159,7 +160,7 @@ void TCP_Endpoint::SetState(EndpointState new_state) } } -bro_int_t TCP_Endpoint::Size() const +uint64 TCP_Endpoint::Size() const { if ( prev_state == TCP_ENDPOINT_SYN_SENT && state == TCP_ENDPOINT_RESET && peer->state == TCP_ENDPOINT_INACTIVE && ! NoDataAcked() ) @@ -168,14 +169,18 @@ bro_int_t TCP_Endpoint::Size() const // and there was never a chance for this endpoint to send data anyway. return 0; - bro_int_t size; + uint64 size; + uint64 last_seq_64 = ToFullSeqSpace(LastSeq(), SeqWraps()); + uint64 ack_seq_64 = ToFullSeqSpace(AckSeq(), AckWraps()); - uint64 last_seq_64 = (uint64(last_seq_high) << 32) | last_seq; - uint64 ack_seq_64 = (uint64(ack_seq_high) << 32) | ack_seq; + // Going straight to relative sequence numbers and comparing those might + // make more sense, but there's some cases (e.g. due to RSTs) where + // last_seq might not be initialized to a trustworthy value such that + // rel_seq > rel_ack, but last_seq_64 < start_seq, which is obviously wrong. if ( last_seq_64 > ack_seq_64 ) - size = last_seq_64 - start_seq; + size = last_seq_64 - StartSeqI64(); else - size = ack_seq_64 - start_seq; + size = ack_seq_64 - StartSeqI64(); // Don't include SYN octet in sequence space. For partial connections // (no SYN seen), we're still careful to adjust start_seq as though @@ -190,7 +195,7 @@ bro_int_t TCP_Endpoint::Size() const return size; } -int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, +int TCP_Endpoint::DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp) { @@ -205,7 +210,7 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, if ( contents_file && ! contents_processor && seq + len > contents_start_seq ) { - int under_seq = contents_start_seq - seq; + int64 under_seq = contents_start_seq - seq; if ( under_seq > 0 ) { seq += under_seq; @@ -236,7 +241,7 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, return status; } -void TCP_Endpoint::AckReceived(int seq) +void TCP_Endpoint::AckReceived(uint64 seq) { if ( contents_processor ) contents_processor->AckReceived(seq); @@ -246,7 +251,7 @@ void TCP_Endpoint::SetContentsFile(BroFile* f) { Ref(f); contents_file = f; - contents_start_seq = last_seq - start_seq; + contents_start_seq = ToRelativeSeqSpace(last_seq, seq_wraps); if ( contents_start_seq == 0 ) contents_start_seq = 1; // skip SYN diff --git a/src/analyzer/protocol/tcp/TCP_Endpoint.h b/src/analyzer/protocol/tcp/TCP_Endpoint.h index 31e239225b..96cc497421 100644 --- a/src/analyzer/protocol/tcp/TCP_Endpoint.h +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.h @@ -38,32 +38,94 @@ public: EndpointState State() const { return state; } void SetState(EndpointState new_state); - bro_int_t Size() const; + uint64 Size() const; int IsActive() const { return state != TCP_ENDPOINT_INACTIVE && ! did_close; } double StartTime() const { return start_time; } double LastTime() const { return last_time; } - uint32 StartSeq() const { return start_seq; } + /** + * @return The starting TCP sequence number for this endpoint. + */ + uint32 StartSeq() const { return static_cast(start_seq); } + + /** + * @return The starting TCP sequence number for this endpoint, in terms + * of a signed sequence space, which may account for initial + * sequence space wraparounds (underflow/overflow). + */ + int64 StartSeqI64() const { return start_seq; } + + /** + * @return The sequence number after the last TCP sequence number seen + * from this endpoint. + */ uint32 LastSeq() const { return last_seq; } + + /** + * @return The last TCP acknowledgement number seen from this endpoint. + */ uint32 AckSeq() const { return ack_seq; } - void InitStartSeq(uint32 seq) { start_seq = seq; } + /** + * @return The number of times the TCP sequence has wrapped around + * for this endpoint (i.e. overflowed a uint32). + */ + uint32 SeqWraps() const { return seq_wraps; } + + /** + * @return The number of times the TCP acknowledgement sequence has + * wrapped around for this endpoint (i.e. overflowed a uint32). + */ + uint32 AckWraps() const { return ack_wraps; } + + /** + * @param wraps Number of times a 32-bit sequence space has wrapped. + * @return A 64-bit sequence space number it would take to overflow + * a 32-bit sequence space \a wraps number of times. + */ + static uint64 ToFullSeqSpace(uint32 wraps) + { return (uint64(wraps) << 32); } + + /** + * @param tcp_seq_num A 32-bit TCP sequence space number. + * @param wraparounds Number of times a 32-bit sequence space has wrapped. + * @return \a tcp_seq_num expanded out in to a 64-bit sequence space, + * accounting for the number of times the 32-bit space overflowed. + */ + static uint64 ToFullSeqSpace(uint32 tcp_seq_num, uint32 wraparounds) + { return ToFullSeqSpace(wraparounds) + tcp_seq_num; } + + /** + * @param tcp_seq_num A 32-bit TCP sequence space number. + * @param wraparounds Number of times a 32-bit sequence space has wrapped. + * @return \a tcp_seq_num expanded out in to a 64-bit sequence space, + * accounting for the number of times the 32-bit space overflowed + * and relative to the starting sequence number for this endpoint. + */ + uint64 ToRelativeSeqSpace(uint32 tcp_seq_num, uint32 wraparounds) const + { + return ToFullSeqSpace(tcp_seq_num, wraparounds) - StartSeqI64(); + } + + void InitStartSeq(int64 seq) { start_seq = seq; } void InitLastSeq(uint32 seq) { last_seq = seq; } void InitAckSeq(uint32 seq) { ack_seq = seq; } void UpdateLastSeq(uint32 seq) { if ( seq < last_seq ) - ++last_seq_high; + ++seq_wraps; + last_seq = seq; } void UpdateAckSeq(uint32 seq) { if ( seq < ack_seq ) - ++ack_seq_high; + ++ack_wraps; + ack_seq = seq; } @@ -71,7 +133,11 @@ public: // We allow for possibly one octet being ack'd in the case of // an initial SYN exchange. int NoDataAcked() const - { return ack_seq == start_seq || ack_seq == start_seq + 1; } + { + uint64 ack = ToFullSeqSpace(ack_seq, ack_wraps); + uint64 start = static_cast(StartSeqI64()); + return ack == start || ack == start + 1; + } Connection* Conn() const; @@ -96,16 +162,16 @@ public: // // If we're not processing contents, then naturally each of // these is empty. - void SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack); + void SizeBufferedData(uint64& waiting_on_hole, uint64& waiting_on_ack); int ValidChecksum(const struct tcphdr* tp, int len) const; // Returns true if the data was used (and hence should be recorded // in the save file), false otherwise. - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); - void AckReceived(int seq); + void AckReceived(uint64 seq); void SetContentsFile(BroFile* f); BroFile* GetContentsFile() const { return contents_file; } @@ -139,20 +205,25 @@ public: int window_scale; // from the TCP option uint32 window_ack_seq; // at which ack_seq number did we record 'window' uint32 window_seq; // at which sending sequence number did we record 'window' - int contents_start_seq; // relative seq # where contents file starts - int FIN_seq; // relative seq # to start_seq + uint64 contents_start_seq; // relative seq # where contents file starts + uint64 FIN_seq; // relative seq # to start_seq int SYN_cnt, FIN_cnt, RST_cnt; int did_close; // whether we've reported it closing int is_orig; - // Sequence numbers associated with last control packets. + // Relative sequence numbers associated with last control packets. // Used to determine whether ones seen again are interesting, // for tracking history. - uint32 hist_last_SYN, hist_last_FIN, hist_last_RST; + uint64 hist_last_SYN, hist_last_FIN, hist_last_RST; protected: - uint32 start_seq, last_seq, ack_seq; // in host order - uint32 last_seq_high, ack_seq_high; + int64 start_seq; // Initial TCP sequence number in host order. + // Signed 64-bit to detect initial sequence wrapping. + // Use StartSeq() accessor if need it in terms of + // an absolute TCP sequence number. + uint32 last_seq, ack_seq; // in host order + uint32 seq_wraps, ack_wraps; // Number of times 32-bit TCP sequence space + // has wrapped around (overflowed). }; #define ENDIAN_UNKNOWN 0 diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc index da8dd857fd..053e8c8f60 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -14,11 +14,6 @@ using namespace analyzer::tcp; // Note, sequence numbers are relative. I.e., they start with 1. -// TODO: The Reassembler should start using 64 bit ints for keeping track of -// sequence numbers; currently they become negative once 2GB are exceeded. -// -// See #348 for more information. - const bool DEBUG_tcp_contents = false; const bool DEBUG_tcp_connection_close = false; const bool DEBUG_tcp_match_undelivered = false; @@ -44,9 +39,7 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer, deliver_tcp_contents = 0; skip_deliveries = 0; did_EOF = 0; -#ifdef ENABLE_SEQ_TO_SKIP seq_to_skip = 0; -#endif in_delivery = false; if ( tcp_contents ) @@ -73,12 +66,11 @@ TCP_Reassembler::~TCP_Reassembler() void TCP_Reassembler::Done() { - MatchUndelivered(-1); + MatchUndelivered(-1, true); if ( record_contents_file ) { // Record any undelivered data. - if ( blocks && - seq_delta(last_reassem_seq, last_block->upper) < 0 ) + if ( blocks && last_reassem_seq < last_block->upper ) RecordToSeq(last_reassem_seq, last_block->upper, record_contents_file); @@ -86,13 +78,13 @@ void TCP_Reassembler::Done() } } -void TCP_Reassembler::SizeBufferedData(int& waiting_on_hole, - int& waiting_on_ack) const +void TCP_Reassembler::SizeBufferedData(uint64& waiting_on_hole, + uint64& waiting_on_ack) const { waiting_on_hole = waiting_on_ack = 0; for ( DataBlock* b = blocks; b; b = b->next ) { - if ( seq_delta(b->seq, last_reassem_seq) <= 0 ) + if ( b->seq <= last_reassem_seq ) // We must have delivered this block, but // haven't yet trimmed it. waiting_on_ack += b->Size(); @@ -126,7 +118,7 @@ void TCP_Reassembler::SetContentsFile(BroFile* f) } -void TCP_Reassembler::Undelivered(int up_to_seq) +void TCP_Reassembler::Undelivered(uint64 up_to_seq) { TCP_Endpoint* endpoint = endp; TCP_Endpoint* peer = endpoint->peer; @@ -142,13 +134,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq) // was a keep-alive. So, in either case, just ignore it. // TODO: Don't we need to update last_reassm_seq ???? - if ( up_to_seq >=0 ) - // Since seq are currently only 32 bit signed - // integers, they will become negative if a - // connection has more than 2GB of data. Remove the - // above if and always return here, once we're using - // 64 bit ints - return; + return; } #if 0 @@ -156,15 +142,14 @@ void TCP_Reassembler::Undelivered(int up_to_seq) { // Make sure we're not worrying about undelivered // FIN control octets! - int FIN_seq = endpoint->FIN_seq - endpoint->start_seq; - if ( seq_delta(up_to_seq, FIN_seq) >= 0 ) - up_to_seq = FIN_seq - 1; + if ( up_to_seq >= endpoint->FIN_seq ) + up_to_seq = endpoint->FIN_seq - 1; } #endif if ( DEBUG_tcp_contents ) { - DEBUG_MSG("%.6f Undelivered: IsOrig()=%d up_to_seq=%d, last_reassm=%d, " + DEBUG_MSG("%.6f Undelivered: IsOrig()=%d up_to_seq=%"PRIu64", last_reassm=%"PRIu64", " "endp: FIN_cnt=%d, RST_cnt=%d, " "peer: FIN_cnt=%d, RST_cnt=%d\n", network_time, IsOrig(), up_to_seq, last_reassem_seq, @@ -172,7 +157,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq) peer->FIN_cnt, peer->RST_cnt); } - if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 ) + if ( up_to_seq <= last_reassem_seq ) // This should never happen. (Reassembler::TrimToSeq has the only call // to this method and only if this condition is not true). reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered"); @@ -195,10 +180,10 @@ void TCP_Reassembler::Undelivered(int up_to_seq) { if ( DEBUG_tcp_contents ) { - DEBUG_MSG("%.6f Undelivered: IsOrig()=%d, seq=%d, len=%d, " + DEBUG_MSG("%.6f Undelivered: IsOrig()=%d, seq=%"PRIu64", len=%"PRIu64", " "skip_deliveries=%d\n", network_time, IsOrig(), last_reassem_seq, - seq_delta(up_to_seq, last_reassem_seq), + up_to_seq - last_reassem_seq, skip_deliveries); } @@ -210,8 +195,8 @@ void TCP_Reassembler::Undelivered(int up_to_seq) // packet, but it's undelievered because it's out of // sequence. - int seq = last_reassem_seq; - int len = seq_delta(up_to_seq, last_reassem_seq); + uint64 seq = last_reassem_seq; + uint64 len = up_to_seq - last_reassem_seq; // Only report on content gaps for connections that // are in a cleanly established state. In other @@ -255,19 +240,19 @@ void TCP_Reassembler::Undelivered(int up_to_seq) RecordToSeq(last_reassem_seq, up_to_seq, record_contents_file); if ( tcp_match_undelivered ) - MatchUndelivered(up_to_seq); + MatchUndelivered(up_to_seq, false); // But we need to re-adjust last_reassem_seq in either case. last_reassem_seq = up_to_seq; // we've done our best ... } -void TCP_Reassembler::MatchUndelivered(int up_to_seq) +void TCP_Reassembler::MatchUndelivered(uint64 up_to_seq, bool use_last_upper) { if ( ! blocks || ! rule_matcher ) return; ASSERT(last_block); - if ( up_to_seq == -1 ) + if ( use_last_upper ) up_to_seq = last_block->upper; // ### Note: the original code did not check whether blocks have @@ -277,36 +262,35 @@ void TCP_Reassembler::MatchUndelivered(int up_to_seq) // We are to match any undelivered data, from last_reassem_seq to // min(last_block->upper, up_to_seq). // Is there such data? - if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 || - seq_delta(last_block->upper, last_reassem_seq) <= 0 ) + if ( up_to_seq <= last_reassem_seq || + last_block->upper <= last_reassem_seq ) return; // Skip blocks that are already delivered (but not ACK'ed). // Question: shall we instead keep a pointer to the first undelivered // block? DataBlock* b; - for ( b = blocks; b && seq_delta(b->upper, last_reassem_seq) <= 0; - b = b->next ) + for ( b = blocks; b && b->upper <= last_reassem_seq; b = b->next ) tcp_analyzer->Conn()->Match(Rule::PAYLOAD, b->block, b->Size(), false, false, IsOrig(), false); ASSERT(b); } -void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f) +void TCP_Reassembler::RecordToSeq(uint64 start_seq, uint64 stop_seq, BroFile* f) { DataBlock* b = blocks; // Skip over blocks up to the start seq. - while ( b && seq_delta(b->upper, start_seq) <= 0 ) + while ( b && b->upper <= start_seq ) b = b->next; if ( ! b ) return; - int last_seq = start_seq; - while ( b && seq_delta(b->upper, stop_seq) <= 0 ) + uint64 last_seq = start_seq; + while ( b && b->upper <= stop_seq ) { - if ( seq_delta(b->seq, last_seq) > 0 ) + if ( b->seq > last_seq ) RecordGap(last_seq, b->seq, f); RecordBlock(b, f); @@ -316,7 +300,7 @@ void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f) if ( b ) // Check for final gap. - if ( seq_delta(last_seq, stop_seq) < 0 ) + if ( last_seq < stop_seq ) RecordGap(last_seq, stop_seq, f); } @@ -337,9 +321,9 @@ void TCP_Reassembler::RecordBlock(DataBlock* b, BroFile* f) } } -void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f) +void TCP_Reassembler::RecordGap(uint64 start_seq, uint64 upper_seq, BroFile* f) { - if ( f->Write(fmt("\n<>\n", seq_delta(upper_seq, start_seq))) ) + if ( f->Write(fmt("\n<>\n", upper_seq - start_seq)) ) return; reporter->Error("TCP_Reassembler contents gap write failed"); @@ -356,8 +340,8 @@ void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f) void TCP_Reassembler::BlockInserted(DataBlock* start_block) { - if ( seq_delta(start_block->seq, last_reassem_seq) > 0 || - seq_delta(start_block->upper, last_reassem_seq) <= 0 ) + if ( start_block->seq > last_reassem_seq || + start_block->upper <= last_reassem_seq ) return; // We've filled a leading hole. Deliver as much as possible. @@ -367,12 +351,12 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block) // loop we have to take care not to deliver already-delivered // data. for ( DataBlock* b = start_block; - b && seq_delta(b->seq, last_reassem_seq) <= 0; b = b->next ) + b && b->seq <= last_reassem_seq; b = b->next ) { if ( b->seq == last_reassem_seq ) { // New stuff. - int len = b->Size(); - int seq = last_reassem_seq; + uint64 len = b->Size(); + uint64 seq = last_reassem_seq; last_reassem_seq += len; @@ -392,7 +376,7 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block) TrimToSeq(last_reassem_seq); else if ( e->NoDataAcked() && tcp_max_initial_window && - e->Size() > tcp_max_initial_window ) + e->Size() > static_cast(tcp_max_initial_window) ) // We've sent quite a bit of data, yet none of it has // been acked. Presume that we're not seeing the peer's // acks (perhaps due to filtering or split routing) and @@ -406,10 +390,10 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block) // TCP_Connection::NextPacket. } -void TCP_Reassembler::Overlap(const u_char* b1, const u_char* b2, int n) +void TCP_Reassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n) { if ( DEBUG_tcp_contents ) - DEBUG_MSG("%.6f TCP contents overlap: %d IsOrig()=%d\n", network_time, n, IsOrig()); + DEBUG_MSG("%.6f TCP contents overlap: %"PRIu64" IsOrig()=%d\n", network_time, n, IsOrig()); if ( rexmit_inconsistency && memcmp((const void*) b1, (const void*) b2, n) && @@ -438,7 +422,7 @@ bool TCP_Reassembler::DoUnserialize(UnserialInfo* info) return false; // Cannot be reached. } -void TCP_Reassembler::Deliver(int seq, int len, const u_char* data) +void TCP_Reassembler::Deliver(uint64 seq, int len, const u_char* data) { if ( type == Direct ) dst_analyzer->NextStream(len, data, IsOrig()); @@ -446,24 +430,24 @@ void TCP_Reassembler::Deliver(int seq, int len, const u_char* data) dst_analyzer->ForwardStream(len, data, IsOrig()); } -int TCP_Reassembler::DataSent(double t, int seq, int len, +int TCP_Reassembler::DataSent(double t, uint64 seq, int len, const u_char* data, bool replaying) { - int ack = seq_delta(endp->AckSeq(), endp->StartSeq()); - int upper_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 upper_seq = seq + len; if ( DEBUG_tcp_contents ) { - DEBUG_MSG("%.6f DataSent: IsOrig()=%d seq=%d upper=%d ack=%d\n", + DEBUG_MSG("%.6f DataSent: IsOrig()=%d seq=%"PRIu64" upper=%"PRIu64" ack=%"PRIu64"\n", network_time, IsOrig(), seq, upper_seq, ack); } if ( skip_deliveries ) return 0; - if ( seq_delta(seq, ack) < 0 && ! replaying ) + if ( seq < ack && ! replaying ) { - if ( seq_delta(upper_seq, ack) <= 0 ) + if ( upper_seq <= ack ) // We've already delivered this and it's been acked. return 0; @@ -472,7 +456,7 @@ int TCP_Reassembler::DataSent(double t, int seq, int len, // packet held [a, a+b) and this packet holds [a, a+c) for c>b // (which some TCP's will do when retransmitting). Trim the // packet to just the unacked data. - int amount_acked = seq_delta(ack, seq); + uint64 amount_acked = ack - seq; seq += amount_acked; data += amount_acked; len -= amount_acked; @@ -481,7 +465,7 @@ int TCP_Reassembler::DataSent(double t, int seq, int len, NewBlock(t, seq, len, data); if ( Endpoint()->NoDataAcked() && tcp_max_above_hole_without_any_acks && - NumUndeliveredBytes() > tcp_max_above_hole_without_any_acks ) + NumUndeliveredBytes() > static_cast(tcp_max_above_hole_without_any_acks) ) { tcp_analyzer->Weird("above_hole_data_without_any_acks"); ClearBlocks(); @@ -489,7 +473,7 @@ int TCP_Reassembler::DataSent(double t, int seq, int len, } if ( tcp_excessive_data_without_further_acks && - NumUndeliveredBytes() > tcp_excessive_data_without_further_acks ) + NumUndeliveredBytes() > static_cast(tcp_excessive_data_without_further_acks) ) { tcp_analyzer->Weird("excessive_data_without_further_acks"); ClearBlocks(); @@ -500,16 +484,13 @@ int TCP_Reassembler::DataSent(double t, int seq, int len, } -void TCP_Reassembler::AckReceived(int seq) +void TCP_Reassembler::AckReceived(uint64 seq) { - if ( endp->FIN_cnt > 0 && seq_delta(seq, endp->FIN_seq) >= 0 ) - // TrimToSeq: FIN_seq - 1 + if ( endp->FIN_cnt > 0 && seq >= endp->FIN_seq ) seq = endp->FIN_seq - 1; - int bytes_covered = seq_delta(seq, trim_seq); - - if ( bytes_covered <= 0 ) - // Zero, or negative in sequence-space terms. Nothing to do. + if ( seq <= trim_seq ) + // Nothing to do. return; bool test_active = ! skip_deliveries && ! tcp_analyzer->Skipping() && @@ -517,12 +498,12 @@ void TCP_Reassembler::AckReceived(int seq) (endp->state == TCP_ENDPOINT_ESTABLISHED && endp->peer->state == TCP_ENDPOINT_ESTABLISHED ) ); - int num_missing = TrimToSeq(seq); + uint64 num_missing = TrimToSeq(seq); if ( test_active ) { ++tot_ack_events; - tot_ack_bytes += bytes_covered; + tot_ack_bytes += seq - trim_seq; if ( num_missing > 0 ) { @@ -602,20 +583,18 @@ void TCP_Reassembler::CheckEOF() // Deliver, DeliverBlock is not virtual, and this allows us to insert // operations that apply to all connections using TCP_Contents. -void TCP_Reassembler::DeliverBlock(int seq, int len, const u_char* data) +void TCP_Reassembler::DeliverBlock(uint64 seq, int len, const u_char* data) { -#ifdef ENABLE_SEQ_TO_SKIP - if ( seq_delta(seq + len, seq_to_skip) <= 0 ) + if ( seq + len <= seq_to_skip ) return; - if ( seq_delta(seq, seq_to_skip) < 0 ) + if ( seq < seq_to_skip ) { - int to_skip = seq_delta(seq_to_skip, seq); + uint64 to_skip = seq_to_skip - seq; len -= to_skip; data += to_skip; seq = seq_to_skip; } -#endif if ( deliver_tcp_contents ) { @@ -640,23 +619,21 @@ void TCP_Reassembler::DeliverBlock(int seq, int len, const u_char* data) in_delivery = true; Deliver(seq, len, data); in_delivery = false; -#ifdef ENABLE_SEQ_TO_SKIP - if ( seq_delta(seq + len, seq_to_skip) < 0 ) + + if ( seq + len < seq_to_skip ) SkipToSeq(seq_to_skip); -#endif + } -#ifdef ENABLE_SEQ_TO_SKIP -void TCP_Reassembler::SkipToSeq(int seq) +void TCP_Reassembler::SkipToSeq(uint64 seq) { - if ( seq_delta(seq, seq_to_skip) > 0 ) + if ( seq > seq_to_skip ) { seq_to_skip = seq; if ( ! in_delivery ) TrimToSeq(seq); } } -#endif int TCP_Reassembler::DataPending() const { @@ -665,20 +642,28 @@ int TCP_Reassembler::DataPending() const if ( skip_deliveries ) return 0; - uint32 delivered_seq = Endpoint()->StartSeq() + DataSeq(); + uint64 delivered_seq = Endpoint()->StartSeqI64() + DataSeq(); + uint64 last_seq = TCP_Endpoint::ToFullSeqSpace(Endpoint()->LastSeq(), + Endpoint()->SeqWraps()); + + if ( last_seq < delivered_seq ) + return 0; // Q. Can we say that? - // ASSERT(delivered_seq <= Endpoint()->LastSeq()); + // ASSERT(delivered_seq <= last_seq); // - // A. Yes, but only if we express it with 64-bit comparison - // to handle sequence wrapping around. (Or perhaps seq_delta - // is enough here?) + // A. That should be true if endpoints are always initialized w/ + // trustworthy sequence numbers, though it seems that may not currently + // be the case. e.g. a RST packet may end up initializing the endpoint. + // In that case, maybe there's not any "right" way to initialize it, so + // the check for last_seq < delivered_seq sort of serves as a check for + // endpoints that weren't initialized w/ meaningful sequence numbers. // We've delivered everything if we're up to the penultimate // sequence number (since a FIN consumes an octet in the // sequence space), or right at it (because a RST does not). - if ( delivered_seq != Endpoint()->LastSeq() - 1 && - delivered_seq != Endpoint()->LastSeq() ) + if ( delivered_seq != last_seq - 1 && + delivered_seq != last_seq ) return 1; // If we've sent RST, then we can't send ACKs any more. diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.h b/src/analyzer/protocol/tcp/TCP_Reassembler.h index e3dcf82a1b..3dfe75bf10 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.h +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.h @@ -4,13 +4,6 @@ #include "Reassem.h" #include "TCP_Endpoint.h" -// The skip_to_seq feature does not work correctly with connections >2GB due -// to use of 32 bit signed ints (see comments in TCP_Reassembler.cc) Since -// it's not used by any analyzer or policy script we disable it. Could be -// added back in once we start using 64bit integers. -// -// #define ENABLE_SEQ_TO_SKIP - class BroFile; class Connection; @@ -48,12 +41,12 @@ public: // // If we're not processing contents, then naturally each of // these is empty. - void SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) const; + void SizeBufferedData(uint64& waiting_on_hole, uint64& waiting_on_ack) const; // How much data is pending delivery since it's not yet reassembled. // Includes the data due to holes (so this value is a bit different // from waiting_on_hole above; and is computed in a different fashion). - int NumUndeliveredBytes() const + uint64 NumUndeliveredBytes() const { if ( last_block ) return last_block->upper - last_reassem_seq; @@ -64,19 +57,15 @@ public: void SetContentsFile(BroFile* f); BroFile* GetContentsFile() const { return record_contents_file; } - void MatchUndelivered(int up_to_seq = -1); + void MatchUndelivered(uint64 up_to_seq, bool use_last_upper); -#ifdef ENABLE_SEQ_TO_SKIP // Skip up to seq, as if there's a content gap. // Can be used to skip HTTP data for performance considerations. - void SkipToSeq(int seq); -} } // namespace analyzer::* + void SkipToSeq(uint64 seq); -#endif - - int DataSent(double t, int seq, int len, const u_char* data, + int DataSent(double t, uint64 seq, int len, const u_char* data, bool replaying=true); - void AckReceived(int seq); + void AckReceived(uint64 seq); // Checks if we have delivered all contents that we can possibly // deliver for this endpoint. Calls TCP_Analyzer::EndpointEOF() @@ -86,35 +75,32 @@ public: int HasUndeliveredData() const { return HasBlocks(); } int HadGap() const { return had_gap; } int DataPending() const; - int DataSeq() const { return LastReassemSeq(); } + uint64 DataSeq() const { return LastReassemSeq(); } - void DeliverBlock(int seq, int len, const u_char* data); - virtual void Deliver(int seq, int len, const u_char* data); + void DeliverBlock(uint64 seq, int len, const u_char* data); + virtual void Deliver(uint64 seq, int len, const u_char* data); TCP_Endpoint* Endpoint() { return endp; } const TCP_Endpoint* Endpoint() const { return endp; } int IsOrig() const { return endp->IsOrig(); } -#ifdef ENABLE_SEQ_TO_SKIP - bool IsSkippedContents(int seq, int length) const - { return seq + length <= seq_to_skip; } -} } // namespace analyzer::* -#endif + bool IsSkippedContents(uint64 seq, int length) const + { return seq + length <= seq_to_skip; } private: TCP_Reassembler() { } DECLARE_SERIAL(TCP_Reassembler); - void Undelivered(int up_to_seq); + void Undelivered(uint64 up_to_seq); - void RecordToSeq(int start_seq, int stop_seq, BroFile* f); + void RecordToSeq(uint64 start_seq, uint64 stop_seq, BroFile* f); void RecordBlock(DataBlock* b, BroFile* f); - void RecordGap(int start_seq, int upper_seq, BroFile* f); + void RecordGap(uint64 start_seq, uint64 upper_seq, BroFile* f); void BlockInserted(DataBlock* b); - void Overlap(const u_char* b1, const u_char* b2, int n); + void Overlap(const u_char* b1, const u_char* b2, uint64 n); TCP_Endpoint* endp; @@ -123,9 +109,8 @@ private: unsigned int did_EOF:1; unsigned int skip_deliveries:1; -#ifdef ENABLE_SEQ_TO_SKIP - int seq_to_skip; -#endif + uint64 seq_to_skip; + bool in_delivery; BroFile* record_contents_file; // file on which to reassemble contents diff --git a/src/analyzer/protocol/tcp/events.bif b/src/analyzer/protocol/tcp/events.bif index cac18bfa3e..f52fadaebb 100644 --- a/src/analyzer/protocol/tcp/events.bif +++ b/src/analyzer/protocol/tcp/events.bif @@ -223,9 +223,10 @@ event connection_EOF%(c: connection, is_orig: bool%); ## corresponds to one set flag, as follows: ``S`` -> SYN; ``F`` -> FIN; ## ``R`` -> RST; ``A`` -> ACK; ``P`` -> PUSH. ## -## seq: The packet's TCP sequence number. +## seq: The packet's relative TCP sequence number. ## -## ack: The packet's ACK number. +## ack: If the ACK flag is set for the packet, the packet's relative ACK +## number, else zero. ## ## len: The length of the TCP payload, as specified in the packet header. ## diff --git a/src/analyzer/protocol/teredo/Teredo.cc b/src/analyzer/protocol/teredo/Teredo.cc index d81f90d840..400f38839e 100644 --- a/src/analyzer/protocol/teredo/Teredo.cc +++ b/src/analyzer/protocol/teredo/Teredo.cc @@ -140,7 +140,7 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const } void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/teredo/Teredo.h b/src/analyzer/protocol/teredo/Teredo.h index 0da007187d..68dfb8bb73 100644 --- a/src/analyzer/protocol/teredo/Teredo.h +++ b/src/analyzer/protocol/teredo/Teredo.h @@ -19,7 +19,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Teredo_Analyzer(conn); } diff --git a/src/analyzer/protocol/udp/UDP.cc b/src/analyzer/protocol/udp/UDP.cc index 4c26ae5d99..36d5831a6a 100644 --- a/src/analyzer/protocol/udp/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -38,7 +38,7 @@ void UDP_Analyzer::Done() } void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { assert(ip); diff --git a/src/analyzer/protocol/udp/UDP.h b/src/analyzer/protocol/udp/UDP.h index bcfee401b0..792f83de8a 100644 --- a/src/analyzer/protocol/udp/UDP.h +++ b/src/analyzer/protocol/udp/UDP.h @@ -28,7 +28,7 @@ public: protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual bool IsReuse(double t, const u_char* pkt); virtual unsigned int MemoryAllocation() const; diff --git a/src/event.bif b/src/event.bif index 7e49378fcc..4006888eab 100644 --- a/src/event.bif +++ b/src/event.bif @@ -360,9 +360,9 @@ event content_gap%(c: connection, is_orig: bool, seq: count, length: count%); ## ## .. note:: ## -## Bro comes with a script :doc:`/scripts/policy/misc/capture-loss.bro` that uses -## this event to estimate packet loss and report when a predefined threshold -## is exceeded. +## Bro comes with a script :doc:`/scripts/policy/misc/capture-loss.bro` that +## uses this event to estimate packet loss and report when a predefined +## threshold is exceeded. event gap_report%(dt: interval, info: gap_info%); ## Generated when a protocol analyzer confirms that a connection is indeed @@ -1011,8 +1011,8 @@ event dns_mapping_lost_name%(dm: dns_mapping%); ## dns_mapping_valid event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr_set%); -## A meta event generated for events that Bro raises. This will report all events -## for which at least one handler is defined. +## A meta event generated for events that Bro raises. This will report all +## events for which at least one handler is defined. ## ## Note that handling this meta event is expensive and should be limited to ## debugging purposes. diff --git a/src/file_analysis/File.cc b/src/file_analysis/File.cc index e8a7ea15ee..2772b55418 100644 --- a/src/file_analysis/File.cc +++ b/src/file_analysis/File.cc @@ -283,6 +283,7 @@ bool File::BufferBOF(const u_char* data, uint64 len) bool File::DetectMIME(const u_char* data, uint64 len) { RuleMatcher::MIME_Matches matches; + len = min(len, LookupFieldDefaultCount(bof_buffer_size_idx)); file_mgr->DetectMIME(data, len, &matches); if ( matches.empty() ) diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 5ff7bd7186..3a7b799094 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -27,7 +27,22 @@ Manager::Manager() Manager::~Manager() { - Terminate(); + // Have to assume that too much of Bro has been shutdown by this point + // to do anything more than reclaim memory. + + File* f; + bool* b; + + IterCookie* it = id_map.InitForIteration(); + + while ( (f = id_map.NextEntry(it)) ) + delete f; + + it = ignored.InitForIteration(); + + while( (b = ignored.NextEntry(it)) ) + delete b; + delete magic_state; } @@ -54,11 +69,20 @@ void Manager::Terminate() { vector keys; - for ( IDMap::iterator it = id_map.begin(); it != id_map.end(); ++it ) - keys.push_back(it->first); + IterCookie* it = id_map.InitForIteration(); + HashKey* key; + + while ( id_map.NextEntry(key, it) ) + { + keys.push_back(string(static_cast(key->Key()), + key->Size())); + delete key; + } for ( size_t i = 0; i < keys.size(); ++i ) Timeout(keys[i], true); + + mgr.Drain(); } string Manager::HashHandle(const string& handle) const @@ -249,11 +273,12 @@ File* Manager::GetFile(const string& file_id, Connection* conn, if ( IsIgnored(file_id) ) return 0; - File* rval = id_map[file_id]; + File* rval = id_map.Lookup(file_id.c_str()); if ( ! rval ) { - rval = id_map[file_id] = new File(file_id, conn, tag, is_orig); + rval = new File(file_id, conn, tag, is_orig); + id_map.Insert(file_id.c_str(), rval); rval->ScheduleInactivityTimer(); if ( IsIgnored(file_id) ) @@ -272,12 +297,7 @@ File* Manager::GetFile(const string& file_id, Connection* conn, File* Manager::LookupFile(const string& file_id) const { - IDMap::const_iterator it = id_map.find(file_id); - - if ( it == id_map.end() ) - return 0; - - return it->second; + return id_map.Lookup(file_id.c_str()); } void Manager::Timeout(const string& file_id, bool is_terminating) @@ -308,37 +328,38 @@ void Manager::Timeout(const string& file_id, bool is_terminating) bool Manager::IgnoreFile(const string& file_id) { - if ( id_map.find(file_id) == id_map.end() ) + if ( ! id_map.Lookup(file_id.c_str()) ) return false; DBG_LOG(DBG_FILE_ANALYSIS, "Ignore FileID %s", file_id.c_str()); - ignored.insert(file_id); - + delete ignored.Insert(file_id.c_str(), new bool); return true; } bool Manager::RemoveFile(const string& file_id) { - IDMap::iterator it = id_map.find(file_id); + HashKey key(file_id.c_str()); + // Can't remove from the dictionary/map right away as invoking EndOfFile + // may cause some events to be executed which actually depend on the file + // still being in the dictionary/map. + File* f = static_cast(id_map.Lookup(&key)); - if ( it == id_map.end() ) + if ( ! f ) return false; DBG_LOG(DBG_FILE_ANALYSIS, "Remove FileID %s", file_id.c_str()); - it->second->EndOfFile(); - - delete it->second; - id_map.erase(file_id); - ignored.erase(file_id); - + f->EndOfFile(); + delete f; + id_map.Remove(&key); + delete static_cast(ignored.Remove(&key)); return true; } bool Manager::IsIgnored(const string& file_id) { - return ignored.find(file_id) != ignored.end(); + return ignored.Lookup(file_id.c_str()) != 0; } string Manager::GetFileID(analyzer::Tag tag, Connection* c, bool is_orig) diff --git a/src/file_analysis/Manager.h b/src/file_analysis/Manager.h index bb6aaab971..2137e81389 100644 --- a/src/file_analysis/Manager.h +++ b/src/file_analysis/Manager.h @@ -4,10 +4,9 @@ #define FILE_ANALYSIS_MANAGER_H #include -#include -#include #include +#include "Dict.h" #include "Net.h" #include "Conn.h" #include "Val.h" @@ -27,6 +26,9 @@ namespace file_analysis { +declare(PDict,bool); +declare(PDict,File); + /** * Main entry point for interacting with file analysis. */ @@ -288,8 +290,8 @@ public: protected: friend class FileTimer; - typedef set IDSet; - typedef map IDMap; + typedef PDict(bool) IDSet; + typedef PDict(File) IDMap; /** * Create a new file to be analyzed or retrieve an existing one. @@ -361,8 +363,8 @@ protected: private: - IDMap id_map; /**< Map file ID to file_analysis::File records. */ - IDSet ignored; /**< Ignored files. Will be finally removed on EOF. */ + PDict(File) id_map; /**< Map file ID to file_analysis::File records. */ + PDict(bool) ignored; /**< Ignored files. Will be finally removed on EOF. */ string current_file_id; /**< Hash of what get_file_handle event sets. */ RuleFileMagicState* magic_state; /**< File magic signature match state. */ diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index 86f13f8760..78b6bdd645 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -46,7 +46,7 @@ bool file_analysis::X509::EndOfFile() ::X509* ssl_cert = d2i_X509(NULL, &cert_char, cert_data.size()); if ( ! ssl_cert ) { - reporter->Error("Could not parse X509 certificate (fuid %s)", GetFile()->GetID().c_str()); + reporter->Weird(fmt("Could not parse X509 certificate (fuid %s)", GetFile()->GetID().c_str())); return false; } @@ -88,7 +88,7 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val) { ::X509* ssl_cert = cert_val->GetCertificate(); - char buf[256]; // we need a buffer for some of the openssl functions + char buf[2048]; // we need a buffer for some of the openssl functions memset(buf, 0, sizeof(buf)); RecordVal* pX509Cert = new RecordVal(BifType::Record::X509::Certificate); @@ -96,14 +96,16 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val) pX509Cert->Assign(0, new Val((uint64) X509_get_version(ssl_cert) + 1, TYPE_COUNT)); i2a_ASN1_INTEGER(bio, X509_get_serialNumber(ssl_cert)); - int len = BIO_read(bio, &(*buf), sizeof(buf)); + int len = BIO_read(bio, buf, sizeof(buf)); pX509Cert->Assign(1, new StringVal(len, buf)); + BIO_reset(bio); X509_NAME_print_ex(bio, X509_get_subject_name(ssl_cert), 0, XN_FLAG_RFC2253); - len = BIO_gets(bio, &(*buf), sizeof(buf)); + len = BIO_gets(bio, buf, sizeof(buf)); pX509Cert->Assign(2, new StringVal(len, buf)); + BIO_reset(bio); X509_NAME_print_ex(bio, X509_get_issuer_name(ssl_cert), 0, XN_FLAG_RFC2253); - len = BIO_gets(bio, &(*buf), sizeof(buf)); + len = BIO_gets(bio, buf, sizeof(buf)); pX509Cert->Assign(3, new StringVal(len, buf)); BIO_free(bio); @@ -153,12 +155,55 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val) unsigned int length = KeyLength(pkey); if ( length > 0 ) pX509Cert->Assign(9, new Val(length, TYPE_COUNT)); + + EVP_PKEY_free(pkey); } return pX509Cert; } +StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio) + { + BIO_flush(bio); + ERR_clear_error(); + int length = BIO_pending(bio); + + if ( ERR_peek_error() != 0 ) + { + char tmp[120]; + ERR_error_string_n(ERR_get_error(), tmp, sizeof(tmp)); + reporter->Weird(fmt("X509::GetExtensionFromBIO: %s", tmp)); + BIO_free_all(bio); + return 0; + } + + if ( length == 0 ) + { + BIO_free_all(bio); + return new StringVal(""); + } + + char* buffer = (char*) malloc(length); + + if ( ! buffer ) + { + // Just emit an error here and try to continue instead of aborting + // because it's unclear the length value is very reliable. + reporter->Error("X509::GetExtensionFromBIO malloc(%d) failed", length); + BIO_free_all(bio); + return 0; + } + + BIO_read(bio, (void*) buffer, length); + StringVal* ext_val = new StringVal(length, buffer); + + free(buffer); + BIO_free_all(bio); + + return ext_val; + } + void file_analysis::X509::ParseExtension(X509_EXTENSION* ex) { char name[256]; @@ -178,16 +223,10 @@ void file_analysis::X509::ParseExtension(X509_EXTENSION* ex) if( ! X509V3_EXT_print(bio, ex, 0, 0)) M_ASN1_OCTET_STRING_print(bio,ex->value); - BIO_flush(bio); - int length = BIO_pending(bio); + StringVal* ext_val = GetExtensionFromBIO(bio); - // Use OPENSSL_malloc here. Using new or anything else can lead - // to interesting, hard to debug segfaults. - char *buffer = (char*) OPENSSL_malloc(length); - BIO_read(bio, (void*)buffer, length); - StringVal* ext_val = new StringVal(length, buffer); - OPENSSL_free(buffer); - BIO_free_all(bio); + if ( ! ext_val ) + ext_val = new StringVal(0, ""); RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension); pX509Ext->Assign(0, new StringVal(name)); @@ -238,10 +277,11 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex) vl->append(pBasicConstraint); mgr.QueueEvent(x509_ext_basic_constraints, vl); + BASIC_CONSTRAINTS_free(constr); } else - reporter->Error("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str()); + reporter->Weird(fmt("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str())); } void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) @@ -251,7 +291,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) GENERAL_NAMES *altname = (GENERAL_NAMES*)X509V3_EXT_d2i(ext); if ( ! altname ) { - reporter->Error("Could not parse subject alternative names. fuid %s", GetFile()->GetID().c_str()); + reporter->Weird(fmt("Could not parse subject alternative names. fuid %s", GetFile()->GetID().c_str())); return; } @@ -271,7 +311,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) { if ( ASN1_STRING_type(gen->d.ia5) != V_ASN1_IA5STRING ) { - reporter->Error("DNS-field does not contain an IA5String. fuid %s", GetFile()->GetID().c_str()); + reporter->Weird(fmt("DNS-field does not contain an IA5String. fuid %s", GetFile()->GetID().c_str())); continue; } @@ -318,7 +358,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) else { - reporter->Error("Weird IP address length %d in subject alternative name. fuid %s", gen->d.ip->length, GetFile()->GetID().c_str()); + reporter->Weird(fmt("Weird IP address length %d in subject alternative name. fuid %s", gen->d.ip->length, GetFile()->GetID().c_str())); continue; } } @@ -352,6 +392,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) vl->append(GetFile()->GetVal()->Ref()); vl->append(sanExt); mgr.QueueEvent(x509_ext_subject_alternative_name, vl); + GENERAL_NAMES_free(altname); } StringVal* file_analysis::X509::KeyCurve(EVP_PKEY *key) @@ -407,13 +448,20 @@ unsigned int file_analysis::X509::KeyLength(EVP_PKEY *key) return 0; const EC_GROUP *group = EC_KEY_get0_group(key->pkey.ec); + if ( ! group ) + { // unknown ex-group + BN_free(ec_order); return 0; + } if ( ! EC_GROUP_get_order(group, ec_order, NULL) ) + { // could not get ec-group-order + BN_free(ec_order); return 0; + } unsigned int length = BN_num_bits(ec_order); BN_free(ec_order); diff --git a/src/file_analysis/analyzer/x509/X509.h b/src/file_analysis/analyzer/x509/X509.h index 8667d870b1..bd4c8fc7a5 100644 --- a/src/file_analysis/analyzer/x509/X509.h +++ b/src/file_analysis/analyzer/x509/X509.h @@ -37,6 +37,17 @@ public: static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file) { return new X509(args, file); } + /** + * Retrieve an X509 extension value from an OpenSSL BIO to which it was + * written. + * + * @param bio the OpenSSL BIO to read. It will be freed by the function, + * including when an error occurs. + * + * @return The X509 extension value. + */ + static StringVal* GetExtensionFromBIO(BIO* bio); + protected: X509(RecordVal* args, File* file); diff --git a/src/file_analysis/analyzer/x509/events.bif b/src/file_analysis/analyzer/x509/events.bif index a6db8fac44..fcdeaa31d1 100644 --- a/src/file_analysis/analyzer/x509/events.bif +++ b/src/file_analysis/analyzer/x509/events.bif @@ -43,9 +43,9 @@ event x509_extension%(f: fa_file, ext: X509::Extension%); event x509_ext_basic_constraints%(f: fa_file, ext: X509::BasicConstraints%); ## Generated for the X509 subject alternative name extension seen in a certificate. -## This extension can be used to allow additional entities to be bound to the subject -## of the certificate. Usually it is used to specify one or multiple DNS names for -## which a certificate is valid. +## This extension can be used to allow additional entities to be bound to the +## subject of the certificate. Usually it is used to specify one or multiple DNS +## names for which a certificate is valid. ## ## f: The file. ## diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index 00042d860a..9a8a8e78b7 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -5,6 +5,7 @@ #include #include #include +#include // This is the indexed map of X509 certificate stores. static map x509_stores; @@ -24,23 +25,92 @@ X509* d2i_X509_(X509** px, const u_char** in, int len) } // construct an error record -RecordVal* x509_error_record(uint64_t num, const char* reason) +RecordVal* x509_result_record(uint64_t num, const char* reason, Val* chainVector = 0) { RecordVal* rrecord = new RecordVal(BifType::Record::X509::Result); - rrecord->Assign(0, new Val(num, TYPE_COUNT)); + rrecord->Assign(0, new Val(num, TYPE_INT)); rrecord->Assign(1, new StringVal(reason)); + if ( chainVector ) + rrecord->Assign(2, chainVector); return rrecord; } +X509_STORE* x509_get_root_store(TableVal* root_certs) + { + // If this certificate store was built previously, just reuse the old one. + if ( x509_stores.count(root_certs) > 0 ) + return x509_stores[root_certs]; + + X509_STORE* ctx = X509_STORE_new(); + ListVal* idxs = root_certs->ConvertToPureList(); + + // Build the validation store + for ( int i = 0; i < idxs->Length(); ++i ) + { + Val* key = idxs->Index(i); + StringVal *sv = root_certs->Lookup(key)->AsStringVal(); + assert(sv); + const uint8* data = sv->Bytes(); + X509* x = d2i_X509_(NULL, &data, sv->Len()); + if ( ! x ) + { + builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_get_error(),NULL))); + return 0; + } + + X509_STORE_add_cert(ctx, x); + X509_free(x); + } + + delete idxs; + + // Save the newly constructed certificate store into the cacheing map. + x509_stores[root_certs] = ctx; + + return ctx; + } + +// get all cretificates starting at the second one (assuming the first one is the host certificate) +STACK_OF(X509)* x509_get_untrusted_stack(VectorVal* certs_vec) + { + STACK_OF(X509)* untrusted_certs = sk_X509_new_null(); + if ( ! untrusted_certs ) + { + builtin_error(fmt("Untrusted certificate stack initialization error: %s", ERR_error_string(ERR_get_error(),NULL))); + return 0; + } + + for ( int i = 1; i < (int) certs_vec->Size(); ++i ) // start at 1 - 0 is host cert + { + Val *sv = certs_vec->Lookup(i); + + if ( ! sv ) + continue; + + // Fixme: check type + X509* x = ((file_analysis::X509Val*) sv)->GetCertificate(); + if ( ! x ) + { + sk_X509_free(untrusted_certs); + builtin_error(fmt("No certificate in opaque in stack")); + return 0; + } + + sk_X509_push(untrusted_certs, x); + } + + return untrusted_certs; + } + %%} ## Parses a certificate into an X509::Certificate structure. ## -## cert: The X509 certificicate opaque handle +## cert: The X509 certificate opaque handle. ## -## Returns: A X509::Certificate structure +## Returns: A X509::Certificate structure. ## ## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints ## x509_ext_subject_alternative_name x509_verify @@ -55,13 +125,13 @@ function x509_parse%(cert: opaque of x509%): X509::Certificate ## Returns the string form of a certificate. ## -## cert: The X509 certificate opaque handle +## cert: The X509 certificate opaque handle. ## ## pem: A boolean that specifies if the certificate is returned ## in pem-form (true), or as the raw ASN1 encoded binary ## (false). ## -## Returns: X509 certificate as a string +## Returns: X509 certificate as a string. ## ## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints ## x509_ext_subject_alternative_name x509_parse x509_verify @@ -78,18 +148,230 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F else i2d_X509_bio(bio, h->GetCertificate()); - BIO_flush(bio); - int length = BIO_pending(bio); - // use OPENSS_malloc here. Otherwhise, interesting problems will happen. - char *buffer = (char*) OPENSSL_malloc(length); - BIO_read(bio, (void*) buffer, length); - StringVal* ext_val = new StringVal(length, buffer); - OPENSSL_free(buffer); - BIO_free_all(bio); + StringVal* ext_val = file_analysis::X509::GetExtensionFromBIO(bio); + + if ( ! ext_val ) + ext_val = new StringVal(""); return ext_val; %} +## Verifies an OCSP reply. +## +## certs: Specifies the certificate chain to use. Server certificate first. +## +## ocsp_reply: the ocsp reply to validate. +## +## root_certs: A list of root certificates to validate the certificate chain. +## +## verify_time: Time for the validity check of the certificates. +## +## Returns: A record of type X509::Result containing the result code of the +## verify operation. +## +## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints +## x509_ext_subject_alternative_name x509_parse +## x509_get_certificate_string x509_verify +function x509_ocsp_verify%(certs: x509_opaque_vector, ocsp_reply: string, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result + %{ + RecordVal* rval = 0; + X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal()); + if ( ! ctx ) + return x509_result_record(-1, "Problem initializing root store"); + + + VectorVal *certs_vec = certs->AsVectorVal(); + if ( certs_vec->Size() < 1 ) + { + reporter->Error("No certificates given in vector"); + return x509_result_record(-1, "no certificates"); + } + + // host certificate + unsigned int index = 0; // to prevent overloading to 0pointer + Val *sv = certs_vec->Lookup(index); + if ( ! sv ) + { + builtin_error("undefined value in certificate vector"); + return x509_result_record(-1, "undefined value in certificate vector"); + } + + file_analysis::X509Val* cert_handle = (file_analysis::X509Val*) sv; + + X509* cert = cert_handle->GetCertificate(); + if ( ! cert ) + { + builtin_error(fmt("No certificate in opaque")); + return x509_result_record(-1, "No certificate in opaque"); + } + + const unsigned char* start = ocsp_reply->Bytes(); + + STACK_OF(X509)* untrusted_certs = x509_get_untrusted_stack(certs_vec); + if ( ! untrusted_certs ) + return x509_result_record(-1, "Problem initializing list of untrusted certificates"); + + // from here, always goto cleanup. Initialize all other required variables... + time_t vtime = (time_t) verify_time; + OCSP_BASICRESP *basic = 0; + OCSP_SINGLERESP *single = 0; + X509_STORE_CTX *csc = 0; + OCSP_CERTID *certid = 0; + int status = -1; + int out = -1; + int result = -1; + X509* issuer_certificate = 0; + OCSP_RESPONSE *resp = d2i_OCSP_RESPONSE(NULL, &start, ocsp_reply->Len()); + if ( ! resp ) + { + rval = x509_result_record(-1, "Could not parse OCSP response"); + goto x509_ocsp_cleanup; + } + + status = OCSP_response_status(resp); + if ( status != OCSP_RESPONSE_STATUS_SUCCESSFUL ) + { + rval = x509_result_record(-2, OCSP_response_status_str(status)); + goto x509_ocsp_cleanup; + } + + basic = OCSP_response_get1_basic(resp); + if ( ! basic ) + { + rval = x509_result_record(-1, "Could not parse OCSP response"); + goto x509_ocsp_cleanup; + } + + + // the following code took me _forever_ to get right. + // The OCSP_basic_verify command takes a list of certificates. However (which is not immediately + // visible or understandable), those are only used to find the signer certificate. They are _not_ + // used for chain building during the actual verification (this would be stupid). But - if we sneakily + // inject the certificates in the certificate list of the OCSP reply, they actually are used during + // the lookup. + // Yay. + issuer_certificate = 0; + for ( int i = 0; i < sk_X509_num(untrusted_certs); i++) + { + sk_X509_push(basic->certs, X509_dup(sk_X509_value(untrusted_certs, i))); + + if ( X509_NAME_cmp(X509_get_issuer_name(cert), X509_get_subject_name(sk_X509_value(untrusted_certs, i))) ) + issuer_certificate = sk_X509_value(untrusted_certs, i); + } + + // Because we actually want to be able to give nice error messages that show why we were + // not able to verify the OCSP response - do our own verification logic first. + csc = X509_STORE_CTX_new(); + X509_STORE_CTX_init(csc, ctx, sk_X509_value(basic->certs, 0), basic->certs); + X509_STORE_CTX_set_time(csc, 0, (time_t) verify_time); + X509_STORE_CTX_set_purpose(csc, X509_PURPOSE_OCSP_HELPER); + + result = X509_verify_cert(csc); + if ( result != 1 ) + { + const char *reason = X509_verify_cert_error_string((*csc).error); + rval = x509_result_record(result, X509_verify_cert_error_string((*csc).error)); + goto x509_ocsp_cleanup; + } + + out = OCSP_basic_verify(basic, NULL, ctx, 0); + if ( result < 1 ) + { + rval = x509_result_record(out, ERR_error_string(ERR_get_error(),NULL)); + goto x509_ocsp_cleanup; + } + + + // ok, now we verified the OCSP response. This means that we have a valid chain tying it + // to a root that we trust and that the signature also hopefully is valid. This does not yet + // mean that the ocsp response actually matches the certificate the server send us or that + // the OCSP response even says that the certificate is valid. + + // let's start this out by checking that the response is actually for the certificate we want + // to validate and not for something completely unrelated that the server is trying to trick us + // into accepting. + + if ( issuer_certificate ) + certid = OCSP_cert_to_id(NULL, cert, issuer_certificate); + else + { + // issuer not in list sent by server, check store + X509_OBJECT obj; + int lookup = X509_STORE_get_by_subject(csc, X509_LU_X509, X509_get_subject_name(cert), &obj); + if ( lookup <= 0) + { + rval = x509_result_record(lookup, "Could not find issuer of host certificate"); + goto x509_ocsp_cleanup; + } + + certid = OCSP_cert_to_id(NULL, cert, obj.data.x509); + } + + + if ( ! certid ) + { + rval = x509_result_record(-1, "Certificate ID construction failed"); + goto x509_ocsp_cleanup; + } + + // for now, assume we have one reply... + single = sk_OCSP_SINGLERESP_value(basic->tbsResponseData->responses, 0); + if ( ! single ) + { + rval = x509_result_record(-1, "Could not lookup OCSP response information"); + goto x509_ocsp_cleanup; + } + + if ( ! OCSP_id_cmp(certid, single->certId) ) + return x509_result_record(-1, "OCSP reply is not for host certificate"); + + // next - check freshness of proof... + if ( ! ASN1_GENERALIZEDTIME_check(single->thisUpdate) || ! ASN1_GENERALIZEDTIME_check(single->nextUpdate) ) + { + rval = x509_result_record(-1, "OCSP reply contains invalid dates"); + goto x509_ocsp_cleanup; + } + + // now - nearly done. Check freshness and status code. + // There is a function to check the freshness of the ocsp reply in the ocsp code of OpenSSL. But - it only + // supports comparing it against the current time, not against arbitrary times. Hence it is kind of unusable + // for us... + // Well, we will do it manually. + + + if ( X509_cmp_time(single->thisUpdate, &vtime) > 0 ) + rval = x509_result_record(-1, "OCSP reply specifies time in future"); + else if ( X509_cmp_time(single->nextUpdate, &vtime) < 0 ) + rval = x509_result_record(-1, "OCSP reply expired"); + else if ( single->certStatus->type != V_OCSP_CERTSTATUS_GOOD ) + rval = x509_result_record(-1, OCSP_cert_status_str(single->certStatus->type)); + + // if we have no error so far, we are done. + if ( !rval ) + rval = x509_result_record(1, OCSP_cert_status_str(single->certStatus->type)); + +x509_ocsp_cleanup: + + if ( untrusted_certs ) + sk_X509_free(untrusted_certs); + + if ( resp ) + OCSP_RESPONSE_free(resp); + + if ( basic ) + OCSP_BASICRESP_free(basic); + + if ( csc ) + { + X509_STORE_CTX_cleanup(csc); + X509_STORE_CTX_free(csc); + } + + if ( certid ) + OCSP_CERTID_free(certid); + + return rval; + %} ## Verifies a certificate. ## @@ -97,26 +379,29 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F ## the given certificate against the root store given in *root_certs*. ## The host certificate has to be at index 0. ## -## root_certs: A list of root certificates to validate the certificate chain +## root_certs: A list of root certificates to validate the certificate chain. ## ## verify_time: Time for the validity check of the certificates. ## -## Returns: A record of type X509::Result containing the result code of the verify -## operation. In case of success also returns the full certificate chain. +## Returns: A record of type X509::Result containing the result code of the +## verify operation. In case of success also returns the full +## certificate chain. ## ## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints ## x509_ext_subject_alternative_name x509_parse -## x509_get_certificate_string +## x509_get_certificate_string x509_ocsp_verify function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result %{ - X509_STORE* ctx = 0; - int i = 0; + X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal()); + if ( ! ctx ) + return x509_result_record(-1, "Problem initializing root store"); + VectorVal *certs_vec = certs->AsVectorVal(); - if ( certs_vec->Size() < 1 ) + if ( ! certs_vec || certs_vec->Size() < 1 ) { reporter->Error("No certificates given in vector"); - return x509_error_record(-1, "no certificates"); + return x509_result_record(-1, "no certificates"); } // host certificate @@ -125,71 +410,20 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str if ( !sv ) { builtin_error("undefined value in certificate vector"); - return x509_error_record(-1, "undefined value in certificate vector"); + return x509_result_record(-1, "undefined value in certificate vector"); } - file_analysis::X509Val* cert_handle = (file_analysis::X509Val*) sv; - // If this certificate store was built previously, just reuse the old one. - if ( x509_stores.count(root_certs) > 0 ) - ctx = x509_stores[root_certs]; - - if ( ! ctx ) // lookup to see if we have this one built already! - { - ctx = X509_STORE_new(); - TableVal* root_certs2 = root_certs->AsTableVal(); - ListVal* idxs = root_certs2->ConvertToPureList(); - - // Build the validation store - for ( i = 0; i < idxs->Length(); ++i ) - { - Val* key = idxs->Index(i); - StringVal *sv = root_certs2->Lookup(key)->AsStringVal(); - const uint8* data = sv->Bytes(); - X509* x = d2i_X509_(NULL, &data, sv->Len()); - if ( ! x ) - { - builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); - return x509_error_record((uint64) ERR_get_error(), ERR_error_string(ERR_peek_last_error(),NULL)); - } - - X509_STORE_add_cert(ctx, x); - } - - delete idxs; - - // Save the newly constructed certificate store into the cacheing map. - x509_stores[root_certs] = ctx; - } - X509* cert = cert_handle->GetCertificate(); if ( ! cert ) { builtin_error(fmt("No certificate in opaque")); - return x509_error_record(-1, "No certificate in opaque"); + return x509_result_record(-1, "No certificate in opaque"); } - STACK_OF(X509)* untrusted_certs = sk_X509_new_null(); + STACK_OF(X509)* untrusted_certs = x509_get_untrusted_stack(certs_vec); if ( ! untrusted_certs ) - { - builtin_error(fmt("Untrusted certificate stack initialization error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); - return x509_error_record((uint64) ERR_get_error(), ERR_error_string(ERR_peek_last_error(),NULL)); - } - - for ( i = 1; i < (int) certs_vec->Size(); ++i ) // start at 1 - 0 is host cert - { - Val *sv = certs_vec->Lookup(i); - // Fixme: check type - X509* x = ((file_analysis::X509Val*) sv)->GetCertificate(); - if ( ! x ) - { - sk_X509_pop(untrusted_certs); - builtin_error(fmt("No certificate in opaque in stack")); - return x509_error_record(-1, "No certificate in opaque"); - } - - sk_X509_push(untrusted_certs, x); - } + return x509_result_record(-1, "Problem initializing list of untrusted certificates"); X509_STORE_CTX csc; X509_STORE_CTX_init(&csc, ctx, cert, untrusted_certs); @@ -207,6 +441,7 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str if ( ! chain ) { reporter->Error("Encountered valid chain that could not be resolved"); + sk_X509_pop_free(chain, X509_free); goto x509_verify_chainerror; } @@ -216,30 +451,28 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str for ( int i = 0; i < num_certs; i++ ) { X509* currcert = sk_X509_value(chain, i); - if ( !currcert ) + + if ( currcert ) + // X509Val takes ownership of currcert. + chainVector->Assign(i, new file_analysis::X509Val(currcert)); + else { - reporter->InternalError("OpenSSL returned null certificate"); + reporter->InternalWarning("OpenSSL returned null certificate"); + sk_X509_pop_free(chain, X509_free); goto x509_verify_chainerror; } - - chainVector->Assign(i, new file_analysis::X509Val(currcert)); // X509Val takes ownership } + + sk_X509_free(chain); } x509_verify_chainerror: X509_STORE_CTX_cleanup(&csc); - if ( untrusted_certs ) - sk_X509_pop(untrusted_certs); + sk_X509_free(untrusted_certs); - RecordVal* rrecord = new RecordVal(BifType::Record::X509::Result); - - rrecord->Assign(0, new Val((uint64) csc.error, TYPE_COUNT)); - rrecord->Assign(1, new StringVal(X509_verify_cert_error_string(csc.error))); - - if ( chainVector ) - rrecord->Assign(2, chainVector); + RecordVal* rrecord = x509_result_record(csc.error, X509_verify_cert_error_string(csc.error), chainVector); return rrecord; %} diff --git a/src/input/readers/Raw.cc b/src/input/readers/Raw.cc index 53469335a2..11976e2a11 100644 --- a/src/input/readers/Raw.cc +++ b/src/input/readers/Raw.cc @@ -67,12 +67,9 @@ void Raw::DoClose() if ( file != 0 ) CloseInput(); - if ( buf != 0 ) - { - // we still have output that has not been flushed. Throw away. - delete buf; - buf = 0; - } + // Just throw away output that has not been flushed. + delete [] buf; + buf = 0; if ( execute && childpid > 0 && kill(childpid, 0) == 0 ) { diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 8d833ddbc6..55e0fddb5a 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -537,17 +537,19 @@ bool Manager::TraverseRecord(Stream* stream, Filter* filter, RecordType* rt, filter->indices.push_back(new_indices); - filter->fields = (threading::Field**) + void* tmp = realloc(filter->fields, - sizeof(threading::Field*) * ++filter->num_fields); + sizeof(threading::Field*) * (filter->num_fields + 1)); - if ( ! filter->fields ) + if ( ! tmp ) { - --filter->num_fields; reporter->Error("out of memory in add_filter"); return false; } + ++filter->num_fields; + filter->fields = (threading::Field**) tmp; + TypeTag st = TYPE_VOID; if ( t->Tag() == TYPE_TABLE ) diff --git a/src/logging/writers/Ascii.cc b/src/logging/writers/Ascii.cc index 43ffe47308..fe79089b04 100644 --- a/src/logging/writers/Ascii.cc +++ b/src/logging/writers/Ascii.cc @@ -335,10 +335,10 @@ bool Ascii::DoWrite(int num_fields, const Field* const * fields, if ( strncmp(bytes, meta_prefix.data(), meta_prefix.size()) == 0 ) { // It would so escape the first character. - char buf[16]; - snprintf(buf, sizeof(buf), "\\x%02x", bytes[0]); + char hex[4] = {'\\', 'x', '0', '0'}; + bytetohex(bytes[0], hex + 2); - if ( ! safe_write(fd, buf, strlen(buf)) ) + if ( ! safe_write(fd, hex, 4) ) goto write_error; ++bytes; diff --git a/src/main.cc b/src/main.cc index cf1f82b1eb..68f1d46547 100644 --- a/src/main.cc +++ b/src/main.cc @@ -379,10 +379,10 @@ void terminate_bro() delete secondary_path; delete remote_serializer; delete analyzer_mgr; + delete file_mgr; delete log_mgr; delete plugin_mgr; delete thread_mgr; - delete file_mgr; delete reporter; reporter = 0; @@ -1174,6 +1174,10 @@ int main(int argc, char** argv) sqlite3_shutdown(); + ERR_free_strings(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + // Close files after net_delete(), because net_delete() // might write to connection content files. BroFile::CloseCachedFiles(); diff --git a/src/net_util.h b/src/net_util.h index e5dbbcdae2..0f34335267 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -119,7 +119,7 @@ struct ip6_rthdr { // True if sequence # a is between b and c (b <= a <= c). It must be true // that b <= c in the sequence space. -inline int seq_between(uint32 a, uint32 b, uint32 c) +inline bool seq_between(uint32 a, uint32 b, uint32 c) { if ( b <= c ) return a >= b && a <= c; @@ -128,9 +128,9 @@ inline int seq_between(uint32 a, uint32 b, uint32 c) } // Returns a - b, adjusted for sequence wraparound. -inline int seq_delta(uint32 a, uint32 b) +inline int32 seq_delta(uint32 a, uint32 b) { - return int(a-b); + return a - b; } class IPAddr; diff --git a/src/probabilistic/Hasher.cc b/src/probabilistic/Hasher.cc index 1f5f0910ba..0f209bfb5b 100644 --- a/src/probabilistic/Hasher.cc +++ b/src/probabilistic/Hasher.cc @@ -108,7 +108,7 @@ Hasher::digest UHF::hash(const void* x, size_t n) const MD5(d, 16, d); - return d[0]; + return *reinterpret_cast(d); } DefaultHasher::DefaultHasher(size_t k, size_t seed) diff --git a/src/probabilistic/bloom-filter.bif b/src/probabilistic/bloom-filter.bif index 26865f160d..3e6b89fa4f 100644 --- a/src/probabilistic/bloom-filter.bif +++ b/src/probabilistic/bloom-filter.bif @@ -44,7 +44,7 @@ function bloomfilter_basic_init%(fp: double, capacity: count, size_t optimal_k = BasicBloomFilter::K(cells, capacity); size_t seed = Hasher::MakeSeed(name->Len() > 0 ? name->Bytes() : 0, name->Len()); - const Hasher* h = new DefaultHasher(optimal_k, seed); + const Hasher* h = new DoubleHasher(optimal_k, seed); return new BloomFilterVal(new BasicBloomFilter(h, cells)); %} @@ -84,7 +84,7 @@ function bloomfilter_basic_init2%(k: count, cells: count, size_t seed = Hasher::MakeSeed(name->Len() > 0 ? name->Bytes() : 0, name->Len()); - const Hasher* h = new DefaultHasher(k, seed); + const Hasher* h = new DoubleHasher(k, seed); return new BloomFilterVal(new BasicBloomFilter(h, cells)); %} diff --git a/src/scan.l b/src/scan.l index 18233fb58a..7de38cbfbc 100644 --- a/src/scan.l +++ b/src/scan.l @@ -606,22 +606,30 @@ void do_atifdef(const char* id) { ++current_depth; - if ( ! lookup_ID(id, current_module.c_str()) ) + ID* i; + + if ( ! (i = lookup_ID(id, current_module.c_str())) ) { if_stack.append(current_depth); BEGIN(IGNORE); } + + Unref(i); } void do_atifndef(const char *id) { ++current_depth; - if ( lookup_ID(id, current_module.c_str()) ) + ID* i; + + if ( (i = lookup_ID(id, current_module.c_str())) ) { if_stack.append(current_depth); BEGIN(IGNORE); } + + Unref(i); } void do_atelse() diff --git a/src/threading/BasicThread.cc b/src/threading/BasicThread.cc index 7f5dbfc56b..ffee21bc16 100644 --- a/src/threading/BasicThread.cc +++ b/src/threading/BasicThread.cc @@ -24,7 +24,7 @@ BasicThread::BasicThread() pthread = 0; buf_len = STD_FMT_BUF_LEN; - buf = (char*) malloc(buf_len); + buf = (char*) safe_malloc(buf_len); strerr_buffer = 0; diff --git a/src/threading/formatters/Ascii.cc b/src/threading/formatters/Ascii.cc index 3120549f13..6c114ff3fd 100644 --- a/src/threading/formatters/Ascii.cc +++ b/src/threading/formatters/Ascii.cc @@ -122,10 +122,8 @@ bool Ascii::Describe(ODesc* desc, threading::Value* val, const string& name) con // place-holder we use for unset optional fields. We // escape the first character so that the output // won't be ambigious. - static const char hex_chars[] = "0123456789abcdef"; - char hex[6] = "\\x00"; - hex[2] = hex_chars[((*data) & 0xf0) >> 4]; - hex[3] = hex_chars[(*data) & 0x0f]; + char hex[4] = {'\\', 'x', '0', '0'}; + bytetohex(*data, hex + 2); desc->AddRaw(hex, 4); ++data; diff --git a/src/threading/formatters/JSON.cc b/src/threading/formatters/JSON.cc index 17712e8d53..472023e0f8 100644 --- a/src/threading/formatters/JSON.cc +++ b/src/threading/formatters/JSON.cc @@ -160,10 +160,11 @@ bool JSON::Describe(ODesc* desc, Value* val, const string& name) const // 2byte Unicode escape special characters. if ( c < 32 || c > 126 || c == '\n' || c == '"' || c == '\'' || c == '\\' || c == '&' ) { - static const char hex_chars[] = "0123456789abcdef"; desc->AddRaw("\\u00", 4); - desc->AddRaw(&hex_chars[(c & 0xf0) >> 4], 1); - desc->AddRaw(&hex_chars[c & 0x0f], 1); + char hex[2] = {'0', '0'}; + bytetohex(c, hex); + desc->AddRaw(hex, 1); + desc->AddRaw(hex + 1, 1); } else desc->AddRaw(&c, 1); diff --git a/src/util.cc b/src/util.cc index 434783a340..f5bbe9cf96 100644 --- a/src/util.cc +++ b/src/util.cc @@ -120,31 +120,41 @@ std::string get_unescaped_string(const std::string& arg_str) * Takes a string, escapes characters into equivalent hex codes (\x##), and * returns a string containing all escaped values. * + * @param d an ODesc object to store the escaped hex version of the string, + * if null one will be allocated and returned from the function. * @param str string to escape * @param escape_all If true, all characters are escaped. If false, only * characters are escaped that are either whitespace or not printable in * ASCII. - * @return A std::string containing a list of escaped hex values of the form - * \x## */ -std::string get_escaped_string(const std::string& str, bool escape_all) + * @return A ODesc object containing a list of escaped hex values of the form + * \x##, which may be newly allocated if \a d was a null pointer. */ +ODesc* get_escaped_string(ODesc* d, const char* str, size_t len, + bool escape_all) { - char tbuf[16]; - string esc = ""; + if ( ! d ) + d = new ODesc(); - for ( size_t i = 0; i < str.length(); ++i ) + for ( size_t i = 0; i < len; ++i ) { char c = str[i]; if ( escape_all || isspace(c) || ! isascii(c) || ! isprint(c) ) { - snprintf(tbuf, sizeof(tbuf), "\\x%02x", str[i]); - esc += tbuf; + char hex[4] = {'\\', 'x', '0', '0' }; + bytetohex(c, hex + 2); + d->AddRaw(hex, 4); } else - esc += c; + d->AddRaw(&c, 1); } - return esc; + return d; + } + +std::string get_escaped_string(const char* str, size_t len, bool escape_all) + { + ODesc d; + return get_escaped_string(&d, str, len, escape_all)->Description(); } char* copy_string(const char* s) @@ -558,7 +568,7 @@ const char* fmt(const char* format, ...) static unsigned int buf_len = 1024; if ( ! buf ) - buf = (char*) malloc(buf_len); + buf = (char*) safe_malloc(buf_len); va_list al; va_start(al, format); @@ -568,7 +578,7 @@ const char* fmt(const char* format, ...) if ( (unsigned int) n >= buf_len ) { // Not enough room, grow the buffer. buf_len = n + 32; - buf = (char*) realloc(buf, buf_len); + buf = (char*) safe_realloc(buf, buf_len); // Is it portable to restart? va_start(al, format); diff --git a/src/util.h b/src/util.h index aebc8bbc43..c6b657b7a8 100644 --- a/src/util.h +++ b/src/util.h @@ -102,8 +102,25 @@ void delete_each(T* t) std::string extract_ip(const std::string& i); std::string extract_ip_and_len(const std::string& i, int* len); +inline void bytetohex(unsigned char byte, char* hex_out) + { + static const char hex_chars[] = "0123456789abcdef"; + hex_out[0] = hex_chars[(byte & 0xf0) >> 4]; + hex_out[1] = hex_chars[byte & 0x0f]; + } + std::string get_unescaped_string(const std::string& str); -std::string get_escaped_string(const std::string& str, bool escape_all); + +class ODesc; + +ODesc* get_escaped_string(ODesc* d, const char* str, size_t len, + bool escape_all); +std::string get_escaped_string(const char* str, size_t len, bool escape_all); + +inline std::string get_escaped_string(const std::string& str, bool escape_all) + { + return get_escaped_string(str.data(), str.length(), escape_all); + } std::vector* tokenize_string(std::string input, const std::string& delim, diff --git a/testing/btest/Baseline/BiFs.count_to_addr/out b/testing/btest/Baseline/BiFs.count_to_addr/out deleted file mode 100644 index 1254fd94f1..0000000000 --- a/testing/btest/Baseline/BiFs.count_to_addr/out +++ /dev/null @@ -1,4 +0,0 @@ -0.0.0.1 -48.21.133.122 -255.255.255.255 -0.0.0.0 diff --git a/testing/btest/Baseline/core.ipv6-frag/dns.log b/testing/btest/Baseline/core.ipv6-frag/dns.log index 69aec7e222..5eede0a0e4 100644 --- a/testing/btest/Baseline/core.ipv6-frag/dns.log +++ b/testing/btest/Baseline/core.ipv6-frag/dns.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path dns -#open 2013-08-26-19-02-10 +#open 2014-04-24-20-25-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected #types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool -1331084278.438444 CXWv6p3arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000 F -1331084293.592245 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000 F +1331084278.438444 CXWv6p3arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 TXT 33 This TXT record should be ignored TXT 21 As it is just padding TXT 136 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1.000000 F +1331084293.592245 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 TXT 33 This TXT record should be ignored TXT 21 As it is just padding TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 192 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1.000000 F 1331084298.593081 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT - - F F T F 0 - - F -#close 2013-08-26-19-02-10 +#close 2014-04-24-20-25-20 diff --git a/testing/btest/Baseline/core.print-bpf-filters/output2 b/testing/btest/Baseline/core.print-bpf-filters/output2 index f2825e6cb8..a803d83b91 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/output2 +++ b/testing/btest/Baseline/core.print-bpf-filters/output2 @@ -2,6 +2,7 @@ 1 137 1 161 1 162 +1 1812 1 20000 1 21 1 2123 @@ -41,8 +42,8 @@ 1 992 1 993 1 995 -45 and -44 or -45 port +46 and +45 or +46 port 32 tcp -13 udp +14 udp diff --git a/testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log b/testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log new file mode 100644 index 0000000000..c76f4dd03b --- /dev/null +++ b/testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2014-04-09-16-44-53 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count set[string] +1395939406.175845 CjhGID4nQcgTWjvg4c 192.168.56.1 59763 192.168.56.101 63988 tcp ftp-data 0.001676 0 270 SF - 0 ShAdfFa 5 272 4 486 (empty) +1395939411.361078 CCvvfg3TEfuqmmG4bh 192.168.56.1 59764 192.168.56.101 37150 tcp ftp-data 150.496065 0 5416666670 SF - 4675708816 ShAdfFa 13 688 12 24454 (empty) +1395939399.984671 CXWv6p3arKYeMETxOg 192.168.56.1 59762 192.168.56.101 21 tcp ftp 169.634297 104 1041 SF - 0 ShAdDaFf 31 1728 18 1985 (empty) +#close 2014-04-09-16-44-54 diff --git a/testing/btest/Baseline/core.tcp.large-file-reassembly/files.log b/testing/btest/Baseline/core.tcp.large-file-reassembly/files.log new file mode 100644 index 0000000000..b8b9bf9db1 --- /dev/null +++ b/testing/btest/Baseline/core.tcp.large-file-reassembly/files.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path files +#open 2014-04-09-16-44-53 +#fields ts fuid tx_hosts rx_hosts conn_uids source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256 extracted +#types time string set[addr] set[addr] set[string] string count set[string] string string interval bool bool count count count count bool string string string string string +1395939406.177079 FAb5m22Dhe2Zi95anf 192.168.56.101 192.168.56.1 CjhGID4nQcgTWjvg4c FTP_DATA 0 DATA_EVENT text/plain - 0.000000 - F 270 - 0 0 F - - - - - +1395939411.364462 FhI0ao2FNTjabdfSBd 192.168.56.101 192.168.56.1 CCvvfg3TEfuqmmG4bh FTP_DATA 0 DATA_EVENT text/plain - 150.490904 - F 23822 - 5416642848 0 F - - - - - +#close 2014-04-09-16-44-54 diff --git a/testing/btest/Baseline/core.tcp.large-file-reassembly/out b/testing/btest/Baseline/core.tcp.large-file-reassembly/out new file mode 100644 index 0000000000..dd3960bdb7 --- /dev/null +++ b/testing/btest/Baseline/core.tcp.large-file-reassembly/out @@ -0,0 +1,11 @@ +file_chunk, 270, 0, drwxr-xr-x 3 0 0 4096 Mar 27 11:55 .^M^Jdrwxr-xr-x 3 0 0 4096 Mar 27 11:55 ..^M^Jdrwxr-xr-x 2 0 0 4096 Mar 27 11:43 pub^M^J-rw-rw-r-- 1 1000 1000 5416666670 Mar 27 11:52 rand.txt^M^J +file_chunk, 14480, 0, TCf8ZQLH67eBQks8SjFaumquAt7f9eg6GNvyLgvdbRl4QShP5o47kdBupR8IxbCz^JZ1sR200ZDSWX1TeH7UVjxBg+eQ8YpmUbnjqePKMUBbb0uq6tDGYGauJiZnSHVNez^JVZmm+pCPVdIGyWe27Xgub9s8PyDBjVD3amDxvoFb8ad86eTDcrzuPZ0/iFP4CnDY^JHFLAvEbvgBVuKTmveyUjmis9nRgvjaeoHhBV7/XtC6fP9ayGCHqJIYs7pGHEm0hi^Ji95bgfyFCEB2hBvwGGNQStTigpE89eURtsmxnK+I3Hxk+dyBQjQ6hTxQlwmqZuto^J/ZMEv8KCfrZUtTh4s3l621DN7wRiUbgltFXAIoaWwc5YACR65582L9aEX86XVNXt^J8IfLL0klmNgaRO49b1He7exMUA0UCUY9DFdFfqyt2hMoPJqEfm4nRH0x/xQs5x/G^Jq5K+JPJtkyxvqI7AwMSRaN+k7ez12fZCwzpPIU8taS++y0op+kmXsPaTSJpPe8Ev^Js1XyutkfH5OPmrt413q80e4UTlV73zGs8XMBO+VL+Jb+0IUNnmiyWzqIuYokI9RS^JCdLbWCdLGGb6+k76rY4oIDnUbAP7YCDdr2s3QZ9aLMNaSpuyKY19WNzNbw8cI81O^JIuTY6C3NzXMItjWriqAzmMl2AXztrPZZ2GFhyUy1Hwf4DufBEVeDMvhVd+WlfzVn^JlRdy8Os5X0ULPhFDmej+1igX/AD9a2Yf26vqak8AUvLbJciJWFZp17sZYXus6zos^JR17iUaq63Mfl0dk6wnktVLIGt6EHBYb/oJ65ZGLMuFSDqv+NvVhuyNd/IIR4tUKO^JqNVH/+FHHqjbpZQvFHSTqOGA62rb1AecBRnliYKjRTsg7u4/HI+v/jwPnp89pntJ^JkztVIkc7VVG0GhvgnKFjmV+bVddG3UpB3juIVMJwcFOFnQNzF0hm7oDdfEYXEUht^JW/TCpIox9O+VQknCTo4iZcZOOXGkEYRc11C+P2WPk46b2OER/l8agJPG9qS6Yf35^J+ljLAVFNgW12iqiqCYmfQM6z1l+6RIo/DlDSALbhYjTV9CG02WwyQiG4WpkAHnx+^JiaSwwrKYCklvFoUtisVGfV19rTo1HGGG2FFo5oCY4BPmbIQWidTXJtA1JkHsni5R^JPlG8elgJkTJJKkzdwAh5V0UL+m1y2zH+NyQHFzj9zunB0g5QEmuYMt18TvXy7D/W^JkgJbWGvDCKY36ZKVhWTTqsgQ2xecH+vKBaCF4IofA0joodZzBv9GH6UOSkhTML57^J5BRbLoPr3IqbTAx7PFlixb+fIur2UeUo+RYZeDudo7HmvLBnsGFw0K9rBVNg1D8C^JwcO4lpwxZEPsLeqKChpHpQugpkfSnC9B2/Oywoep2FAI2OL4zL9nOWb+QnE8kibe^JmZVCAm6p2qnr1nfKMUP2YWKbTeyowi6dlS9SfQdzc5+a1Asg/+S8ZWOPDJGauS6h^JNrfV2HRoHwYmpqvxN3/8A7vkF+rPgx1yeGHK0mDVn4F2ke1E+r5e1F9IZzM90EkR^JFX1hEcNcqzPX/rerGjD6WNBDdoAvmsth8mrcsIf0iq/yvNblB9R4Vg1+bxHYOXYf^JE70vkvtaSmWCQ5gi19SYK01XR42Jnu+cnUtuCr3P2relXC5TjBqz3V2CO3St9tX/^J8sdKZWDc/kHAQ5uVZAIonoVp6Ffeu2Zz3B0NFjJj9hyJtLIJ+Qg2Bru0YeplIIQz^Jw8WXZ3xHw7nN2pIMRMkef8pAoonGsrUySUhhSjEMZCYDXvWpTSrOwm+LRsyJ9czy^J4kUBxgoiCdxGi0NpljEzvrj27ElBmqa2E/bOoK39ff89GSBvXeHw6NVrrDZhEFrU^JfnALNwjCGdxCrkPm2sw03cdsPRVO0yQppyYbT8MhWuzlq31VGps+EiwfpU+jHsw2^J7CuI4qC/n6yui5irPTV+GJmS900rfqCDab+PW6XJ82rGAN1lvV7+lz/x3lGcFCux^JUudDhQANxzHwTQGmwJeR4Fk+PGTAvQoWfgN+21hgPgIW4Yug1uKtL5IOK2rRVMTf^JljjxQ8FlEfZLdLZgiOOHnpioRz4n/SbcSMw15i9GHMmHE3wOmV7En11vBFPmUcYb^J+d2UaodnxE6psPmSfawBFI6TNT9fKaZchANali9OdFieh79e/7mox79DrzX4tuQT^JNLs1nj0jb+4Tm+LNqkJ5cvDkyFds0FbBd3CblDHNtdkIcSVj3TpkYz1wwYYogt7r^JV6wVmRQ09dhDmRSM8kVinGhVudTpBRH6+F922anxF9exYYKfYi7M/ODjuQLRCK7R^JwSNg7BDBVXt/Q31ryukAzcE5UtCk0LSlci02B1taq2Bp1ChFDpSzaqeshwgCQvYJ^JVLBPFdy21eqa8IQwXZ3wU2TEiGgJIv3k6M07uSDMCJF8/IPf7KmmOy/dotWXWSCe^J9FqYiGMYW5KRrTZnknhS2JYhC4iIHqlGYFYd5cSm3dtx6m1Y4hmqE4+JWRDK2I/s^JCkDbfOvU8UwES3k4tHORdqDn/b54EdEbnG06hfcg2B5FEg7cr90Qjdh838ldIcwG^JI0k9UewaVjjPL1dG585WFMQa3bZChzNN25kRGMQP24BGvA8wuKDseza7rn1dmrYw^JCRSsA2U7gNy96DKQFQX6Ga9uT9OCW+Ukvq2sejhL5cgiqZ6xZpV3WCFlFEjHEZDU^J/Jcaes5cbbkWLHe9PXwlLeCArWkwsrwhM/zS2vWN9xnvPzyYAaDqSlOPNeyBYW0t^JwEca4eu9Kg7dLNrZ8S6tEECdpor+9EAU6T8o60s20nUzmqG96yWhdl1mns+IHW8N^JwJ9u1uYlEKoAHPVdYY6MnWToAxH5KI1OaEfJ4He929/QGkIso6gRRyWlF2shqR+W^Jx74nIGsLeou4Ao8WGVjV0aa1qZiNw5KSB5QB5UuKlmTWG/gdk1APdsmudyg+Vc1T^JAXLdMwj7uvngrIZxFxqipXnWB7FPC4yzeiPu8qOoestmuqkhkD0FPCW5QFhk965F^Jxm9fqwgJPsjBTC5YTB2LOfTO5ZYdJiPYQmETOOe4a9ztL6HwQ2Y/zxc7GD4AbwQp^JM/AbXtIaCYgNkeG9vkJaLn6byDwdmJUZGHHNVjZca8wV6+YlboGrAYrJbX+ndyqH^JKquD7o1PkJTO+4H04lDmYquf/fRembQ51YGyVQaNqbLF1mbyfVd/lc+JJICTVT/o^Ju4+9yTKOhJG2Gb1DmBG+jOIuZkGv6m9CqZYfKTtDv9zwkUeNHMGcAX6n+TPc2WPI^JsBSKIdYnzlvRCMI9BJAWoNej5yQzzfCPlXd15Og+SK0mfM8+44iDRv/051rLVhcI^JCxQpRjq/NdINYF+WwwDoN4VlpPXLZkw1+qYoSHdstDiHv7uhRgP+cEbZXH8mDpe1^Jkj47aUHCLiGP8u1UgRXGH8A0jFp5yPEFU3SBePIehSZZynNB8u04mRpXc1kIlubA^JqnhGKpscdIZnO7KB7pQA2qF+s1I45amehPIBDBzbaGkMJe2Esqphgh3Rk695uPDm^JQM7JjrfhBTlNXxoxC48WdbI9+xzhTavuwP4BhUNADgDel9vxs+HkT1rLR907NaN1^JxWJdo2bsRFNdftSKf2XCthor9VHwOmyU0XI2yeVSxu9hdA1jK4M4C7fmRrQrwuoO^JS6fTlgbMeTey2ZHrJO/iDT+9sGfgT/oGDXYzZrbaFbiBRj5HLweXE+rAyIG77yUY^JZEqkeh1BA1KHSxqhXmkrYr+ambErzrQHIr6fTujmPVc5W1kIZEAhMdLDJ8U/C1dL^JjqjEA/VyjJr8A2gELABBiATb5ro485x/GdUHgOam0sYpHqG4wmsxnM8iVuxbwlS5^JC9z/MjVvBoLl83/YZjG1jfRLkaX6wzWXuSeybIDk7TilDwAdeFAbUfgEqH5xnXND^JPHnSaA8yOxba7kpuRDWJebGb2GPxiP6u0Wk8iXd3jnSJdE3+b69SXzgM82Wht6NH^JFkBEQWf8hDu0pAhxxU32yPCrLoRxCpl/K/p1cL01xtzDbj5Ncfhg5TbYYUyRw2UN^JSHQ46bN/ozKIQ02T+bhA7Z4BVjVw3Fens8jbZX+Z5ClnEiY5q4g+hR6estFTli3z^J0bQBij3OB0yseeOCcyLt9ZpepxQwgO6BNvecNuNtBwEq/xCx7ESzX3N7dVZAjWKE^JdyjbFMIPKMfIMlfU7wvuaxiyWkbVsBcPDPcyLja3qzO85GZgh0Uln+mCModfqZc/^JcplyVPYQBIFXAViGIFZONpAOWC29fy4j0uRsNYKKhRv6fSZzVNbVgeljKFwTCAXu^J8CtcxnpNOTYXuGZbgISo6oHxCy+fIK1Q14eaZepMWWYT22kWR7FlN4BOLcj50K/Z^JBxpcOexNb0QreketOWPWfHflY9YxB07ykX6djOH9ZOlITbZ0c2BMxfJxOaaNbidn^JX1Vka0i06Sk2iFw2MmxHJm5zwN6Ln4S9hCrwaPCDkmXOCoN0pr1jt9teBBA/LkDG^Jn+rp2U4CwSAtJy690+HlZ+Ni/m5QkchnSsGuYXeBE7feao+dBTJ5hyFpMKjjyOS3^Jf+vZkyNxOzgugBnQ5e0suK46y5GhpbrmNIbP8lJn04B6CFe/lidABVS50GK5LqCD^JtdtAyr+6LD0PCJU2pJeqwePqlbQmA5XZxOW1vJVNQJ4EEJfcJj8Ha2hynAOQaiT/^JAXtlD22EXutFfFgFBgkFJZ35+nO4TuSIawad8xkIBnpMX87wpp4nVi3aWd4sMr0o^JyXWSHcd3Y+izqfXH/6BqlUeXNGQjLlj7biMCosz3iFBRhOvUK1a5r90ZcVy+8+Ty^J4qT52tO7+bQOngxBiwqpnvKAONsxFFHWgR7/LjYbYKtgtq+1ibACiaSzQg+IVFP3^J1V7aZb9fZP0YBvbhv4JxdTXxFfJ4knugi+5mmm1PIyznXWnsWOEbYEnZV4dZIq5M^JQqBIYxrS+aWnUyE8DTsXqDUwVL/rBjbhK/1RxNT+mzHG7Q/phD3y2d8ysHlmAWfl^JDGZbZ8+Plpm7uhj/fK6b6FqYO9qJYoTSesyEsZ0Pfjb7uMrYjSbRyRg6yTuV3Qe+^Jjz+g9Nj63cFMlXVlvaBZgwu8giF/SmdkTM48IVc8BkeMJlPg0fnqcEbEgnMrYBsG^Jv8FdEUWTWvzoDFCiQRFrSnPF8GIBcwgrxN7wGqWexfQlzQsQ9XbJlACIwKMLzh2t^JQTr0zs9g8yAk9SQMahWtYJG4IPdAI0mH9dBSYzt0ATxtBe3NpAhrewtcNqTBnII5^JhUcSoygg4JGCBjxZpxle7/anr4CBduMHcAiL9JFCcWb/cg8uwFPm8p+Ddsz+e3ir^J5WZPHa8uXRupG0ZIY3kQXebizwq6aULjDSFy+ggEWHlkGHIAUYpvKXmCiQAWiKiP^JeBSIUBicoJSDOkf0xo1pvC+yKnjlYXhJob3YxuiKoYH6guAz/OSu0Yr/Y+w8fY2r^JmvpnxCwaLbjmYG/ihbaXtiic6xXYjb+OQKfrRywvDQ28UKoLj7lZ0rZfBPPjqGvv^J/qFSiqKvgDua36DPiFy6UO4D2747V7uZoXtWJQEmSEJZOC1NEbyhztzIksHVcT8Z^JKVIHWPyVa69yvmKpIGgEqE92sEvgrKpbeH3xJEekHPkDpCtojjVGJ1Vm2/OrNitV^JMWha/HsUn6obKV7MYIgSIH2BQfs01araaHR54nKL1PmwHvTnYKo7BY3IKxFsDVq/^J/QQWyib6DNqYagd8+jz8tgG3m8/RX0ZO3V8wLgpPNXgXruBIdaqimwPYu6Msstuc^Jj9tPBWiX8XVhrrtoTg7bV2L9rlOdVY10amL4qfcFFjtlbce25vXRwr+DO2En/lqR^JDUngzYLwMTCCb5fEQPPIh/3/paYE+4T1eYQE5WoIO7OLaryzHXqWR1TfWEKAm2gx^JZvlf1Gtwlnuy+Qi8s7TG2/uGg6GqlS3DnL1ryzntYO+7J41qJw3u3Kiv+AhO23eZ^JgUhR5E9InJ4kPQ+g5TyB0l/nAIS4ztOXvAgXDOa0YnkJYlHEJry/UlRGCijyrDr+^Jlumbv8YtfhzX3Px3ufUYVxhW+utGUI24AVKpUf4FjlX7ClDulSGVdE8AxHNZHK00^JpjAPL1SigMdn7Y8xym+NG7XIcHadTc0HW4U45wAZBICwE5Q60vzCbNIEqy8luyAJ^JaTMiI9W9rL0Pf7mkoSZhmfdzdQ2+CV+m0I4EapkS2kBUGOUdyVm51lmsFLGsAtnb^JRlKhBOnSB9tnLy7u2bXqju6c+BW97DLB1mApXC149/KBbsVpxxC8B/WKmDMnFwgk^JGuRP7bMBxZTamnBUFoFazFFUf/JvhG/8ZRn3bn9zcpBVmK65p/6aua5oIEF8lHQJ^Jj69dCO2JnECvpuuLmPzX0KITgnsXec0jKMbkujHsSB1q0WzO4roQCP33d7QhWbb9^J93xNd8S7vWs+jENQ/d+Sab4bIsEAZzjzRhBd6Z2Y+2e0lL4225SjTlQV0rTK4hbI^JV26RP3ooaA2cl0dMZ4n7L+kMKh83wRvHxV0oD218YzsVZZk7azUr+6L4KvzOU6Xf^JFQDP05ykX6k3Ix7Xg+aoIUvThAU0hyYxn2aEcZtQqVtJ45FYym9/8mdeBbNlmI++^JZK1fC7vylUhO9comEAUWcAeIETXwnb2O0syp6ArLVPuTPF07OdpqY9g5ooje/vGA^JCOCF3OCghSfV4HmgHaMDbxV040bMyUrFwX+33QKg6H8tZr9H3FHoKSrn6D8viKyf^Jw1iA2H8fb8HSN2hHjlUFJZEvaYTnUWWmXTzwcNsAJGwpdilBZCB+kfTpHuc0j7TS^JbzbMh7eZRLBrPH/B8PGv3s+vG02KwKrBPRN8saDMRFlp3Y+dfYlycpVLkbYTiP0D^JdadaY/6GaX4dYrGNhHS0uZwcwUjSmaOniwgmEPyjwPmAN9DdNYR/d9cd3eRYEXor^JyJYEPiSt3OLT3Qn5+L9+dKnIaJs0CqjItKgoNAvmEACxdGui2T1G+TOVSupPlHwX^JYJaiMo99b0u5WfPefYXPLAO6yBXu1lKvLSPbyyd8epZY2i5Y+/arhEp99fJPt8Ja^Jfy9Kl1XWi2nDaDFhuV+26wGK/hasMdgkl4MpFR1SaZOTIHnjOI8j7DqqdZ3yE3xz^Jzvh+NYohCU4K6WD7nkkQydb3ddMHd12fdJvI0YRw/QmsRQ5N3BLMVhPYFhHuVHan^JHeyfnIKzmS9uaDiuSkx7c7or7fyLP93uDjs1w7DoMn1/oWWV8A+k/wNcw+TCybkd^J9ZZbX/5hBy+jdc4UuRt57B2cm/HWuVaM3zZngz9k01iy8R3xik+D8Kd4bfpO3Rfx^J/u3qB973X46IX9YkRi0nfRM+PGYvC62FaUArk7h5vxEuSuG6hDF2AtIfdsWSQv31^J5hL6I9IxT5vbhRK+h15V3rdTDcN6MlF6mwN72cLPsylxfR9jpUVW2ab+gL6/v7rn^JHgZeyYV9CpIBEelHIY9TMqCY8GeGQno8K9vvwugx2ky1yGoZ8fCrLZy4umRd9wGE^JIoqdDAlWqIpvqf675V4Db5s/y7uv5p7CMNCWh/APdpWvzlWQ2XgVQtecl6sAhB6J^Jh9XbFWh4dVAC/ftbzd1nxuqDNUBDZYR6WniWIuPZIDsv+mcxrqA/8uSDAKfCT+VQ^JZIy9aMLfli23hZOlayfOTzBrl4/cDgnw3fWMVB8WZEdj2GQqeGZu3upC4QdR0c2Y^JKDdkAh2ekhJEiNA9L2DnZXtxXcgKA4x6Ok1AXY2SIRpTN4UED2CWnqqA54Cg0s66^JpIWUZZrK2t+wKumRXkszD8+s0tpgqjCCjHLagzIB2jphatxseHVe/RE+Sp+Ooo6t^JKqJn7fFIL81GA4SB/qwinU0jV2pyW9naCTO7clu1d4BTAE2Kz9q54zp37BlKmcTF^JloBrygICa/NvtyinA4nqkGJKO75Q15eDEXhzW8PUMxZkNJzqUHY8QkifKkVmYp2k^J4VSZ7VObaui3sH8mc+uh0i2vlXNHJMOrt4taJ0SyWbryPXP3wxDxzo2gbyTlqPDF^J2JBSRPIGTTf4WeeN51j7ZrQK8zYktg1urhtBYABHdeSz3aIoE2qTR9U5lvNB/bCN^JwPN5Elb/grlAyD/d4k+d8Vy9GgKNq1nqtjI2uGqf4x69CSn7HH2Bfe6MUx0L70da^Jd07M4tkaFBMbOwen7rnP2T3nqmrikYWyyS1GXjW9Ts6UPF3O4UpL0ZaUsTwv2+F5^Jzc/IFns7Udyys8+sJnRg0EaFN/VnOk943VTWidbN6ezorOF5dBAPloXhcBaRs5jB^JeDta11oVC4PmOo55lwKMAMG8kyTps+tFFLJl+uXiYTj+pTayYPEk6d/zWp/wB/3S^J40VLs00fF+OeaguQ2bElfnXK9+HP0Hyusa77YpetVmIYAoOuySVcjsa5xS6MncIU^JEQdNnDhiN/MWKikaLzcaF7KTKtkaYzrs/Wx29n/eb+53xKKU5qwPCFQuGzwbcUST^JbbnMA0ucEYthm2//t2drRFQJc5vdUjr5wyjrAH00c1OLovXW+jsdvpQjYOBwG/OI^JlWOdt+aDoxwdz4mn9QXG3+9UjDpIYPj4XehovH++hWJj0fdiySNKaacOoNwVV6ty^Jl6MkknvVhYIPG5l29n2voBSYzMoBZmOvU1D9wG7y4rwPDC9K+5cIGk1Q7U3FzvBG^J2oOBgdrBa8VXwAZkC+PIHhgmEqRHvzAIhRLfzgNTwSXeeu8gHck8CD+lBWkayV1g^JKvsGRgQ8h89RRHo6Ky0L8XoCsOsEyb+m4Zsq6YeCceNV7DFCFw+GEzVvtLSYtFtr^JF08tKhpYZOEMSqPv9SUbcL/HtVl1+FRnTUe5UxDXrwVX16RvPaqFs15nJfFLqgDm^J3WFjmi7W4aIgSQUBUlEue34hTWPRpauluaAuKStu3xNoNm9aKfo24cPJsQdCIiMD^JuRL3FqyjNfZKo82X/OKqt0EYfK3w9ys7t0ewAO59Bm4eokdARepljfbHXy4X8+/O^JF5aguc6m74jgVoEPxdffprU4T7vXwVO8k3FmZ7+JrBsPRI4hTwVqRevgIoPYBpxe^JngSfxNNFscFYjbRIPcMlauvnwkrVnD48VZnsOpNszl/FbCNfolM19WCdLHCiIUPB^JiJA+ozEbiijt92F4hv+ALQksEzrgbrr48t1/YOK3WvZJrFNhKoQKpQ3JTWMnMoke^JOHel5uQez/iUSwNLxlnFaBRptfUgugdb6i5NkWxudWYAWJSoxHwQMUuE9NpTG3ha^JiFEPCIzX1FqXkZCnGyTdWc1WQwthefC3atUR2dSR0MeGhAbVpDputwB6gJB263mX^Jh0J9Gd1G8/6g93fM7AXHC3K67phaLmLHG2NkNH6Q2HnOw7BkRuhYuWhG9/v15ih1^JuhoMnEHvgnDke4C5FxpV6A3T0XaGJjfqre/4MAHELmXfSd+RlF5FR7ZnWNjPTL9l^JlnsqEXQ+DpsHFWfo0SU5tC5PBM//ZwozP45FOVxKEjk4z59tGZwg7wgJEZfEzjTb^JQotqYrFWpa8LwueJPbsPnFTOGDtIVPzg12Gg0s5mNTXv3LgyZjJ5Ot1aQUOeoMEd^JaYK3G9a92Hq/6ugfvlqtOe7uV2NJp3K6Kav5RI7di1K+4Hl6T6ohq0BEo1JU+BHT^JyWPSVqkrNIAYA/ShG3ipO8cV6MUcnlRzBgYvn7/fWpeAbDkXDNxYxmfmTIgUwMm1^JzUgAj8KNEjGc7NRIkIhD/taYl/H0dbBbGdlhzGQMu9a1xQ2w+3wQBo2cLywAAf+A^JsbQvkP3L7+8DJ8Ai76GSuA238Coj/k2WFLvGJCG53kNxydjZT9Q9NhP0/bwUObaI^J0Hw2mXfxhBn6+qNJN+hwktzS4zrgq8nbdLtPRvBYYbubYASw1ZUWfJy6GxmiT3OA^JOuGA4C+siVqQRpTAW4AyzNEwNgjw5Apxq790EwMC8lZhdmSbAdRvI4LUgZFKU7sq^JOGKF46fAxsgVcJI7JgpRB4LX7jOrSiqHj6BptA1fHndIrQ/6XTOzsC3JTnKKIXBC^JXAp3HO9zAas7llLvSRDmVR0NfBpjNwCeIFxp4bY3eYHKxruGylwelY87G73UoTmp^J7BpfYuOtdFXi+MfWzSd4hQsoxBiLbDbXL+OSMI2aegXGtMJMGt7NL0QYqqO0d+z+^JnvezoFA7xnqZou/M3Zjo/VABy/m1HBMdTU5g6G4WD+8aw+TDfvPK+Op4Lb7MuyxE^JSmPBxPaHEQYmCKMzOwGQEI/AH0mM5UTOLpfurfQ/FaQthUuPfL1sraZBV1uxWWZ+^JunTkttIUWlX1CF7AqN6o92QF4MpjZwn6dtU/WLmDm/j64CjlRifNP3hPL7xDXR4O^JfFU3aFO1AjB0Md0d4OnbtiBHd3xVtg9o2noglEdSEoboBz8ikZa1kq5vu3kgqAVQ^Jz/w+zhw49o9GDo583jLECbxOIrfMgxnv2RND/Etoc9XOY3U6d2C55GTzN5CwvG8y^JmObnT77IkD8PHKb7B4+zO40GWfsGdc1JwJ8VuetrEZKqxpyf3TtgPQ8gWkJt7zt5^JWjoZhrHI7opFo3uFDC23dOmVBPQkXzC8IyYcRT1B/Wh7um3X+ZXdUTyq1e60sC8A^JRNRy+Nd2OQkEH5BiCmunb+kvfdx739i5dLQWrIgvDFJPmfbUhyuyqDboxTMedNpn^JbebTEbrFJFxCwOLREtTWMaXorDnEd9X0YrxkkljwYUweiZIgOZu7QALj4G0an8EZ^J+i88NMdD+KONWySuZL8UGpuWMqOG5qpt8oMAXuNZgjnGu+dPmQ7PiTIftkIldgA0^J/mzOt31RkN/+YuL9sEHXfZPCATwqRJoWfTHYKRLjyvnKK8UclTAiwkgehUD8dpJK^J/f0kzIA0AaNotwMIY2S8h+2wAsDpTUmg+47izIoAiylX2Ek0kMLY/cMQp/pZJII+^JnSqLkbbJC1iJTkzzkA4Sq9BEwYHX+AQACfR1XSi5fQ1cwFl4oIftsFhUnrW1yIkD^JkqnvkFP21puNq/Cb8uKJD+qRTpePrke3+Q5cndY0nPI9S2PABdmPOPABA380EjtN^Jva499Dxgcuozj7C42DVdthSiedF1V/MZgWTG6CCdDZijf0/dEkxpMFDrdCm9gr9/^J0BzznU1hXXrug0xIlZ81W935KgcSwzT62vp1EAT5L8vZN57Oog8VTVTmTPKnOSo4^J/1YPJnTYkvBoW1YeHBSvJaik6g9lqtqUsb+aup5QoY2SKM/WMZIpHz0OUsidZywA^JX2GgunrW8R2jgYqi7icCt6soC0a/M1AeT2g6zAaGD8TI5gRZWmrGvqKZXFK1zkP1^J+1ri6w2Bothzg8tz1eG7Uuyu/jHP0ENz4DlfTawIRot55VHPh4dNiv2akdza0LUs^J7rdoa+ZIevf2jyvC7YZP46i3V4OHhdh8u8DLJFTpK4yzSSaFNpFJ0hurpyqwAtf5^JoB70MY69lVZwhuCn7249QbGZ7vc9aCBtWP9sx2kUHQG9l/WQ5VSrrsfcJqnw9AzY^JePk/Yv0O0LFIuHL8ZjkSNVfvaC59Fi7cRqJ7PKZDbFQz3cMfyaGs9NBE73EDv7lF^JOCCh8G/Ocg3EWzBkin6mnrvOy1hu4EDD7yQqeVS0+xHQPZICr9X0SKGXXUyvn4eL^J89+8cIACBlOecMs3pnrhlLIla790gySCmCybrwXtAfN1byomJL2wsQqcLeXiLAwJ^JgGXKTjJZXgRTq8qFjrqw1JBuqYo/BMuOAO8P175zbX97Nn5uy4YE15aBG/5GsDhn^JhhVhncMJUyJNyhj//PSDPvXWbDWD5TG58PZih6mhadE3Do6eRPfVVx8OlOsfLiHg^JHa7+s1aX/bX9+Ibng4khoSjNGYIIg3dmF+EZ0MUEfxmV2OxItlPCcxvK7850S3C5^JcOuJHqzzbJdz7J1/hAFs8z0w2ndIFNdf23jWZ/BsfaHhyjel2KEnrTpSVqSiOi3Z^JYxIiHk2EH+0VAlcmtbfFSreDi+1E+Mi1O3DMUoNZJpiPwJxGjPaBdM6yRACrByy8^JY4YRH1VBJ6zZcIiKjjP08csRizu1nfKOsalhmaMpPGCvPkDvKFIp2BJxDcpMU/Cc^JyyDmV57jx7BH3txuyIw/TQIDuQ/As0+37GW1t+n0hyuaG3LjjZRPM1oqR0svvmU2^JiuXx2lkuwcKcrvKcXYiueacKdkizP3SirDTsDsTejrbGLkIoFWg11vNl/AZ7KW8F^J3s6EwVAdSaVTn6kb9TE0045O1bTuu8DHbDbGJnA7u+4am7ToX0iSo1yaOOIEzhA7^JYvVoTDFsfKSdLtHNEO/wlXoYHBuOAQw093Z+2GAyWfq5y/qT7vh5FYL2WbF6g8xc^Jta6ebB9Rqno1xC2BTwgwJ6VPzpFS3r8ArWdelq/0GCHIj/6x/2AfXQX+mvbE77gE^JMEHB2Qo+tZQCIqAnNNuaAjbBHuvLSy3c+sNYnvJoyzQ5yK8+gdtbJethaaWXk7jI^J4PU0t1LamlEWGZMKISK3zn8pfQAdh+ozYprnaQsqYjSBUsb3SAsI1CgVMSd/p4iW^JZdeA2vt35dsm3JaJNIrbk82AP12PH1DQW84zEee4+ljsUmnNnocNAyTqfkjTdRCZ^Jm5m2kTijKb+72KH5qnMRIMJHOZJ1etLLWGxGPwQ6ZcIW1qSkisv3HjjTkKGaHiyQ^JCBViKUVCZ70DAtEhdxnt4We4AqkHLF/HQKkKixTiQyYmmuHGr0NqOaNxcG05tPZ+^J4mBbI97OnVszlYi3XYIvd2gll/+KCrun3yURvzVML6RrnqPwnGeLyGoFpqvvUSji^JVi0S6tgNKEA1644bmTuWP9zszpKVNRH8mbgVMpxNN+830CbqiBZosE4TuP36D2Ug^JLq265sflRY62rzGEI/EsJ2L47t7waTIQk3sxIzR70mZlJqchH6VhnfTk6S2Xgrv9^J6cMZxvVtAeSCsXAi5J9wgdso8z07jgRvzPG5Lzx6ILVEKE2sJQdxaleHFAjY/fXG^Jdb4vLk3NELU4zh4iNgB77XshiNeeCoYp3a9TipOrHCPj5txwICaUeaE42auHkdjb^JQSBABJwLOd+bXZWuQpFqZ8j9OjXC6q1HZi13VVreLhsD2yiUjhQn00V3d8gEfPFv^J045cUboZlWsU110UV/7OLDke2Vvd/gTp9EAb62EPAR7W8kRA2gfYbxoa0LqB1zK4^J9H6Dbir4dd7WOx+CfQD/LbRVWUBgL8E5Kt3WhAFkb1Rtnzs0fVAijk/bauFIadLT^J5wKK6nfjv73wYAKbwkw6+Rmo5Ki86YjF5VgFbjtYwcUvN9xabNl7xh9rtdtyq/4b^JkhzC/jwyg5pvg7p8v/q8Mbm7wY9Xv0fZxYaLin+tcq150yNycwmxoO4oyEXLx8NK^JTrmZKIGbJ1MiFmh/AuB1kMoZbDy37kvOs0yJjl0fA2SuSlulkFzWekmuLnVfbZJF^JvhLRPdpM5OY55IY62ICkRAnCX+j9/i5jx0BSSfmB4Yhh63szrF6slKZfITssSAkp^JhdaAyfAhBTu/APBF2GgEh4BiL2fpK8a4LFZtSZWIqwHa4bmWjyjRJBuvK7GjbLeg^JDnCuPPdNOwfPeuhW2B8h7FM8rEhwtJIysP62lpNuIeD876yB2uCsYYvnIx6Sx3qX^JhX+2xkF5p5vh6sM8WnnZqbVN9lI/5ru/sghlopPt/mUMuYcR73ja9odPtYCYbZTa^JK/oCCS3lu6BFmyCsHOUgn7Dn8mGsorOdzfa/W6/Es4AgtqPS3VynrTgt/nKUULi0^Jez0yIkIOHqYkl6DrmJIOXrwwxqMgSrTe0vvrOdTifQaDF/MTgfHp1+xuEpi3Xgzz^J8gKRAPIgMJkm44YPlBRRfYTzrFYPGJxeMe4CnL6NgcN6TCE7Y0aOvpbgBw6/JZd9^JqC1sLRbKuUkkRzzN0T6LcHX95RCcL/9Lp1RKqaoQnX0wZhskLkGz3/L9rDDtLeAM^JhTYExb6VAciL9a9oeOTJDXjJ2MQGjUVAHjouLLtFJLdmrqpc+tUFB2L5IW/ZgP1u^JHcmlIa2m5lxxcFHdYRo8FVtM8avDhunvmtMaYL0LBP1HmHr8xl42ICSqASRPUw8t^JE0siS+GwIdM/F2X2NH0sz/leTvVVl2iD7suRUHVk0vHa5+lypZcCSQ9qvp7mXIfs^JmOfwRNn8VT4UHRi1gjsEwXEUyLXPxOAq7MlO714gWtZYWiXJXnDVPL88Tai1eMz3^JVrzkpFUTW5DtNiRRM4DbZMtjcv0J+tunLbrHvVRaVYKnuwZlFL+6X+Cr0BzmkOoL^Jxm+8Gf8+Iih859+rRj8/T7lPV+S87zQAUcXXTiEvJrl86DJ9Kl +file_chunk, 752, 380370192, GsvqfXiJ4np0khHUmapJNPmJQKa0luEG6FpCzgp0Dyl47QbUHksinrhMu^Jo8584ANcgv0sVUAruYbHZKqWHF1iaF33J5moGutRzOir5TpCwsYtUJTItLPqAigi^JUZIpKxPbO1Qu7ogRR+m96RRQWPGMM0gtauwU8a4i920bBrETqumRuEBs11GgfVBH^JZAc44gk8Dg0YmuX2XnxxWHxqQkVbpHoDLGzeFh/3DkQ9xmAFWktrZHoefkUFgJ68^J1JG8ovCJUheKpSkhI7xcm/OLvfXpVZMatajQGo+4pCA28fQ7SlO0NJuQQUB1Dl9H^JYKuqg6sXuXE3n2BtmQW3LMUG4EIA7bplb0Njb2sCxh/XjApgMVQXzzAmhwuz4o4k^JiaecwnEheh8CLnv8JWMshGw1zDgidP5HbJ3siVD1QhFGmMvkX/ZM7bo7zMZfpRbE^JMdVIb5jJBGUXl1lCol3qbMnSoHNhOo7doGEFhTuVvXK8lP/bmlssoH8aGc52bjws^JYZXn2kVUhUV7d4TJzPhByjKFHg1mY4WZVwRUG2TbgOiy74z5brEhU5/he3helhy8^JqXMSQKGZlMqbHByHDEjBYpR2PqebUuuDPNpkmZ2nNG4NAVOa0gvDcrocMsCEbW8F^JXp2Bmrxj4idyuqruml/tmhYEm1JSPqnAtJCvldK/Ksu7WSMXDYZSitG+2Q4n0L6V^Ju62Pt8j5vMU0RRCbqq3ETqSUEqasL96nHQys/ppzaraC +file_chunk, 752, 380763408, gXdxRZzzH8TAPLeCpKo4lkFco7^JVvkx0JG2M4OVAYmaExT9D1KAHw2PxHnIgNUBq1jHnyj9VEq9r4q3ImdsoysEswws^JNzUDy0dboVl7ZetTP6iOLaeghpKUezHDfHFdgQJK0M7l0GTps9dKqumA6vb8zElx^Jf7tgGXKbPgGXirMekktHzJmb0egVOxwdxRihS5KggKG4u8uNGqq/0vcIZuQCBvVZ^JDCUdJG8s0L9aqifuzQ+3y/4v0l+qQ3daY20plf/KWhbp9T3QBCiutmbMSnIQoK/H^JZ7yqa1h2w1aSgSOStv2tWtCcjjgmBI8acLZ/D6/LZAgF9ZdEfSnK9+39yw9vHg9W^J2IpsFzmtD+CyQ1eVrarHiGL0cDd9kKPE45czXjT96cjk40+SgN/08efxvRvOZpV4^JMvW3fHpSFS8UQecdE+NKyPqf9zEMd/8UBwzKD6PQHJ8HpCLIFdy+wsbwU4+yRJBC^JTdEOlDT8j+laAmErlQw8Mgf5KcPx1hBIqecPaZqfpz5r6LmCXYbZQVW8E318CJfF^J7vGlrZLQh/x6/0oOICTUqd/CaPGhXDrrS2MRGbCEG5N/n/qIQUyyBJoXbPp1AAwG^J8OlwvOcAQWh0AJoXwI4bFF3lqIsBvLwVOL20uRIqsAfmxle6nfwSKAT8FDnqyAng^JBsPh4X3wUmOKuqG9cZhc5544WG1Ec8WRKmEB8ru24k3Lw0GsFPYNLpmbrYPofVlh^JXbH69HCe18 +file_chunk, 752, 2293234960, bE5SAPMll^Jaib84k6IRyHiKCbCiaAZVHGn7mK06uxYUbD7bZSfWLRVOrJpAwF7KCprFfMglIo0^JwCSYXGRoYX87FbYLtOCxuc/rFQE3JjNQMmNbTjxQv69xmpCQ6VWs8ePj3n9hDuAC^JBLq/iJ2h6hKeLUfcpblaJ4+2hHO+Bfr1PX6juuATkCex1QMCAr0ykNuXrirTvGm9^JHFjQyOKV1Mk5srxRXf0o9CZDnw0h02cDV1Zm/MzpnmA1uRy4mNBGXmR4tXn6Jype^JCwrONyUP6jDaRQDeqLnniEKnZrPvu+33rAdFK+1TRzr//gnudo2nj6ehzw5GavxS^JOYOjpXTQKo3sXtDuO0XKtGlQMN7cdV95tkXEpyatfdjFs57BBXyih/w50WfNRlJ9^JvDcC21ht9AuYP/7/N1sSAZ8O5icTEqiLox1gm/s7CJR38nN695+0aGRrI2zdnZJD^JffR7ha8uqFsfJbJSIBrqHXsSleF8hjqlVTXyGpd/yo96KsYk1qKsIdgkMVT+cMuf^JjFwxhTW+BH8s+K00eNzpjIUzJY8fUOusUYbWNlvRHZVzs1zKUzJiWNmKSEQkAVnx^Jp+wWj5yQKPJyIwJUR2DcGzkXES8udDbfstiPqRHeAUcm3otjWQzn78jdQ/trYq03^Jh/yu+wuWsMazmSoDY5kEXCYLovRX8zBfPsT0/yx4Jk9eTdo1AY10E7mMFOufZ31O^JNSZ5clGw/3oyPNw0Dthl6RJGRMl +file_chunk, 752, 2338716944, rKkq7+/L7WcTv1pXM2kK^JARYWqoQyfEpftTMC+UdQgVQxklO0zOYQwIOF3I50JNSycpqO6QWEVCr/yNarcSQC^JALVtH/fJKp76r/825GduosjDFDlYyohREwQqqvYlnXszy6DeIVN3Fpb+ChkwvNmw^J1XVj74VT8QQH2g1fbwQsjL4QOw/xLqgZtq/3SiDLvOsnrpvuN5oQcUdV+1g12I1N^JJCznvVYVUTBnNWV1wNFecvuBxGYRETJE1aRHFimjFAezAVSW+FcwwHhcXY/8mpNN^JJieshkOjYKeUjhla2fDXH7OY1aS0T/bqBUqkdVTjkm0C3E6NlUGUA5t31I4jqEb5^JbNwrKpLJqCjpr/uRs+e9ef1mais77rMwxMxu3zOgI0+Wl7oEt4HXPMbLw7FlXByH^JPm3D3f0Vm/rsfABU7nPH8EOfR0Ad5WY4Ul+K8HGgFL5EpWgagrAxIm8ZMba0G37O^Jyt0CBAy0FJvTMCaIuFlL1VshcatltJqKgVoClur2gn8mnsMEKMsgLNE57G/v75aa^JK2G1EuFFg8F27Ry8WPFJhdnMBno5NIlBlp4a+GNnoyYypvSiyCH6ep0mmHCkInjI^Js25AU8PJzVK5fgJgZITJcS2ID4bQCFy4mVn4MtlPAQOGbZ4f1mNHWKXEj/arz9jx^J2LnF9I9OfP2SIUNuGr6EnZ1JO1ycPFh5Pmd7Cpl1MO9APB2RpwZ7FwAuwfNzRtHv^Jsgutwr6ceMsddeT9 +file_chunk, 752, 4260756752, 4Qr21M3p5vrxpuLqal1FrU4X8z1+r05kDvqcs1RzecdzoBp/FCMU^JykfOgs1BNZU6UypSW2vwOxaQFJSTb90OAdX6hpyTSRT+k1RaGwGdWgn7OdFgdizP^J4Qo6W9abCfi+6BnzHkxxSFTQfd9AFWZ1LlPw5+NjUXfxdi/jGLtDIopnKAE8LshA^J108MLfjjWwlcqs4v1XJHGfjCaauVsrRdes8uhXfiCZgUL0KOKvwHvBy2TKLDb3ZY^JAeJxEBZlgadEjxXjyQZ4BcvU1Gwa2TaIfKsM/2mCTiCIqBo3Mw5tVHkDvEBGKUdS^JvY8E9bpKp26Y2ejYdVk8JSt58wDHzNBeO7ocmzBn3s2fQNbiwX3I+eeJjkogqKTa^JjQSAGi+bUGKWE9dZyDkMZd7NnvLhxO2gEoRlYYjVuDDeDbXvBtLHDa6puLcO1p0Q^JHIkzRmtMTV5SVPhXjQCJyps/bp5v/HzViCLRfXiL0+nDDVesaVbhko71aICGI9Pn^JsvSR7E4qvDdzOppjmWKkau8QcuhLKlzUpyEI1SNAGzrSqL2OuHqdUK5ypuL8RZmm^JXGGDmJ27yMYNjgr3aTJ13eJLH/MQvLAIBys7GKM9BZ0UJW8W4KpbDFRRJieo/62U^JWtkGoNw6dRiCdkuHkWRs40aKc1yhDaoMxY9BHpMtUuxid9Qu9MCiAs33JHLzc+so^JBeFtAtKFW1VSSe31oO9fUfgGucj9BP3QpaqFA0t30TazwxUj3 +file_chunk, 2896, 4303090112, yZg/LJ/GpmwgXe+ESFWIDa^JxR4TdIMTekg4qqCL5PpNJ6DHfkkdsjsQ9zqkWNtrc/GpqBPClN8IwD4qThUGd+tI^JTe38v0hZWuuNnOjY9eJO747wIiPqy15oBYpstGeIdESgUFr9/xg82fGjalkY2ZVQ^JJAlH0xNX+TF5QIn9BUMnxn6OCA0DkQYqybz2eq82jB7ZEnGLdDvB8WeaQIjxBuVx^JDAiCwzjC2jpO+wNYCorVym4VFti4AgGYghyLmyAicit9NqPTMsaD2BbRpb/qHg0P^JdX53dFZe0qlqsrA15n3KCuLiw5YXEFUmUQuAN0dAOqlzOTOPpNmJakHF3TqIXvw6^JV/qERQeuiNPwnBZWrZvpTjO50VatjcUizhJRwTiQjbQ7+mqgHxiEa9abpzqlTN2I^JW/uUssi0jaVeFdL3MHZYHltusyTx0F4iH+KGJ1n7YRefPAI5klNZu3XmTQsQafkF^J1DMVbqcJT+aLdlz2hWMy1R0BfV2XMrO2/XhG2nOScnRzS8Z7EmAgqZmzFfF+nqyP^J9UCd39Si6aUrss3N0oCJ/44F3T55uSHYf2LCgoaaiR5IML5tk9mHVRyTile5iF3P^JNPwMnlSeka31pzsqLRiWIAvKqk5yZJ1v290/Aff0SSIxKggtVMBq3YmJeRb6LrkJ^JjkYC41zT+lvvvMRBJCFOOXBgesIBHq7pOKBKPY/xAcN/e+AQqHLlY/OGMT6+GK9v^JGXN4TvdRLBYHZQqyk2ITYWD5iQqweeZ2UmjB3Is3lDKtnlO6qbWvvYmYPoXDrNI5^JhRX0gaiVC5LyZZ9NheeAgb5ZTqYUcvNCxM7BFV7gJMFXc8gT7A0FG3YbkV9Y4D7v^J3NduhJG8kgS814/l3Il9K3jc12uv8V25orXa4lDXTbTu8WanSYUkg4cLjqfKD5Vh^Jly0ZTpYeNx1NdO8FoSGJhqI0BC/p2NyjzmTh3mrGk6tnfHuqXAMH5tIt/EC10MmP^JE2WTu0XrNk7I9bWBRRNWx+ysP1CJUd5GbYOcQpFHBfG+9ApIf3LjxSLU00/b7Ui2^Jz/92JI8T6X4TdKxA7DY10IJg6KJBsUAUJ9Co6Fxr9+9OIo0bdj1IcD5+w/qB7xzJ^JNC3dgXc86uEDpvICZS2vIeCZTrc9vgxBxpftsdVNn1nDYlalXZeNsAmDiy3QJ/wO^JPS3Li40x0KtDWbxMzgflfzuyMZQBFSNeQ7CXFh9mJMJQkuAtHN+yAEqJJKaYV1bt^JJM2jAeKb64mN31lIzTnkJEGWcvLNS0uiZKJQrm0lqsentMitzc/+U0gSxzsfbqmW^J187RzZAsNlfWnLN7miAPsdxas2JGGrmHzjaUkL7U+YJdAToYlxjMTnZgztt9LJxA^JSprIv68hyNVF+4+fpL7QER9EOmgQOIxjlxCx75SDd5g3CWJkVbXl8uU6G+j02j+Y^JcOXNTTwX2ptbc/79Kw9iDMV9YkAZtP8BD0Any1Fqh/IMx4QcMXEx46yDV2ji7umH^J1SO686Lv9zGXYb+ApuY6PVuICTJrWLIZBE48otTKBXTJ27wGiEf28Z7bh74P06Qv^JXMTUryBMDg9JrcCGTvelIZO+DbMMMN72Mh/lXBAOLIkfh9WvgqyMIH1kfg0H3AwN^JB9b689RpbK0N+xhfV/aIqGp3a1KbXqPA/h85vUI1aLXPreBN9gyTKe5K0HXw3Edo^JqMcB6m//PN72r6epmEMgdthZs5GtNcQBx2GbOonY1sot6ZA41GR4hfl+EJPc81uY^J55uCcANhvaaIl+V7GCjV414dNq89TzNFHF1sG3ifM5ePRhFHVnsE8HgoE3hsMhqH^J87vMDghqNZi7+tGPNjZvZGVtB+RL8ltGhUSuoE9OjU9S96T14TZT8ksIo2jb6+Tq^J6Vo3Y3vKc6krHH93OKiXN0hwqPupBD6xo/23Ivnk1qu4xAZ2fnR1Ob0BKcPCrNdi^JREI++RJzxugNvbGOf2LIdoI/2yChB5i4tg3qYRRRagUpNohIxW5eJy5ugiCwOH6d^JuPmvLXUzs3J0HWdCVpmgURIP4omxgUkLYeJNp4CmeTAUr6uVrqzRCDYPOYrCT4tB^JYL6uyxhmOfwL5/YuVtsCcKjX8nGvOIHdtiMolPpeH8qdv0zp9kY+h8eTE/WGh5HF^JA4VLUCH5d8qok38Q2Xvtiji0QrKr4j+P5Vhp8YbKLwFEqs3+NvA1iEx/RQhTvPO+^JHCdnaCc0vIaAp3jR88OrMDhHyKePPMk6shiWiFM4atdQesswq11pHaUrUoATZGm+^JG4IsH5+DZVk+ztcDnA2+f1+FKDFHloA7VWMiuccer4ZHFqaB1WGpTOMTBF0xhBYo^JmhRBLM+O3SJ3+I3FwbmE4mPnh8PMalte/qm9IFtDIhVdoo5+lS4tarJTPwazW+cs^JAIxETVWHanH/QOtyEdrnufA+kcj9DLRA0IUQLySOYCGQ3ZZsHyyEDV/9IWOjpARW^JDObwlGFQk2mWcH4/CdOl0ZQajrk2hWbwDuFx+RVy84JapHNIAFgH48u+bn+hgf3V^JVX1bUYtRpwrBEEBwD9rQJ6iMmeqg2B/Ih9RxPBq3wyvbhzk/VVCaUq3c+XLz+6B/^JwaUQeYEQ32U8XkaKbWsXxrcKZvZ70oYLGU1+mHLV/Lc/vwch4nAJmtRYRrZ8hXgx^J7CRciM9baxlkZ8zAaRXcGW2Gbl8m//oHERz8/8j7YpbkY3Y0qfeIqNoQyHieLPc+^JWwUfKskpxIgL7MhKlDs1fmJe6X6o3KW11JZqldPwKL6WGK5P4OS2fULClB9MD605^JNpjTRR0NBoNpKKr6UApGAqwfZmc+7oGZHVBw41tiCKuAavQydcOtOg7Xj84i26J1^JBppraxJIvxoJ3 +file_chunk, 752, 4675468560, +DcPcn4qO^JffnlMfb0kLM2x5RyTcNksyV29GDPpFDXWpehoJ56Wt8CMltAlRzSEEPAjWTISMvB^JgYHW2wKs9VHgQ4x2pxmnLTGmMKS49QFadEaILpCb7Vbi+EnWeDwitcBjWI2GrSMq^JYvex9t0vSEt1BrebNcumhwZ4fEjJ8+aci+ZW/r6ZVd7NMrSKMYpMTp1YxTqbp4xJ^JoogVMhE9enlaPiI39lS6mcjK9PZoY2nxTAjxD+vmsFrToCFtxp0aMcJzLsbjhQ7E^JTJX+jYH9mwJiX+mjghmb1npCkjCCZkl04m2cQwYN6xtyXRniEQwpKNK5KCcbfIPb^JYXDXWKvy61KJQli/DtUjh9rhBLVGrn70CCuoCHxnYSlmq6Np3BBDt1PIGYxnhCak^J31ueqgP7CVDs+2/Hh7t4syiABQmA+Xvw3E+Zd9zPp+TjZoux7nPxFUx/rm3YFj5T^JvjlF+AruGVrzTVRmpKSY01wo1Nxv+pSpHg0GukvDnRqFHGSamlyxDrgx3orpqj3e^JD4Pg4voGdHLoVkTF+HXNjUZq8UGKz95B4Tvrpy5Ll9NwX3DD0wDG1RDJLw618W6U^JLThJEdnZcI6460SCpiqKhVXZo9vL0f2dYc+nswEjtgkFnUPQMvp2fK9XVEozQNiQ^JKAjg0dXTDJ2K4mSxc6UlXqLpYgomE9vX0dEq1i6b9IktZi9WckHR4nfV9F4Zd9bI^JgQbfa6KTmdmTrHM4+jtC5dZBDtV +file_chunk, 752, 4675730704, QvDDMBnvKD^Jf6O7XhaaVuulyRhTZPY7oJjJJXSEq/UK6XMmMRzTuPVwjK5hL8H8MvA9T5NPDNDN^J6awIHAtx9vRxa+fNXhfoE8roipZABMXCD510gRsS/yxmYat/2XSUVuwVcVfmLcUB^JGEIYmzbGTxPB9TfPccJVsKAD35jzeyTGsQjaW4B9I1cykWedRhvEd8AeL0O+vBCJ^JxUIWFEHet3dbQvasUZ30o0hMbgOiserhgO4tQ56U66e+Vl/VZUX+DpmxtTYTiVn5^JpVZfYQaoTUpzjAi9t8Iy3YJRwlQRgZHcnzmcDYNuvo4InrEHS1xZC6WcbenTIpSW^JkCGI7fhCLMabTW0FQ5AaSTFKXP7O9+nxdqdup0XJT8Twtuz8l6Mn4PkgqOn0A+bc^JQbtonpY5uIQwVCiAcYjpKAhGV+D1B3TDI5q2+Aj6WPQ9Bfi/pqfv3fBK5ihgY9LS^JW8jZEJCJduoEdsDyatqtSK3UOtftqPWVptW5JfuajYR3CPl84Xk4K1/cQxx5nAKi^JRGpvr0SVoJsS9HRSsoMlJB42Md0SVY0nwp3MO1gcOvKCA5SBI/KXIu0HQ3YpxT39^JV/sR/QjJZvj3u0hFehggRQVo25pQhq4RdCt2edeBwYoxmcJDhnOZD+nEYax8GRUu^JfrkPGVECNPqfzEePAZSv/8nW7ZHXz2+Cted/eRd0Y6qKO4KysL+kjDy2SX8ayrmA^JGlc8VABynj/sshoQi5/nz8nq7S +file_chunk, 1182, 5416665488, w7c/SP4xbc2p6HIRdJLpymJYcB8aLuc^JltM7qmD7UWqSwePzdNZkOYSY0/p2PiZikeQ4wn1fZW+24gY3Dr+oghOLSyl9RIc1^JgO1jwi/vDVySgarwx2QcGsqac32ow212k0FzWuHSsI5SY3e9Cxb279S79PH23+NC^Jrs3mJw0arb7RYD4ZYIrtnnrSHncN944NEmooPcHD/y10bpQFlvIDO5dPX5SC7ryP^JAHOAkFGnlbNJasU9jjuGbl5KfwAG+lm/WyBS3Qzs/jZKEm8xcba1t+4Tmy4HPfIH^JQycTiGZvabxgg34ZrUkRS/VRyNs5DYEl08BsJFJ4ErXqMxqIgqndmqmFCMWRbqm3^JW1SyJLU1BpESS7O/WtdE0h52qeMibJCuMmSLZ6Ji3ObkDuWnJyQOD6DiywAOd4MK^JRAKw6c/G6daqMCLAR8iYNbKv5vizBN0xq38jnjN78n2L+Q0cHigtBVYOb6g/tOod^JsLW0MZnv2UQ+GkD7mz0FgctEtk7LnEGwwFrOOHFTZWJ69Z670dS9KVIVNLVom+wU^JM2bjpD82xE3kLHtZ/VZ/p5UzZkhFZTMqHisrXqcE2hs3StrJj50t49UK+JeBmNSV^JH9rY7uihuKU1BQrSxgXtgW6HZ2st2VMNWsAFyXDtWAO6PrmSF6L+D811cXHCGZx2^JqmEH4/fh3Qyz4wWp+2qJgdfqlvIR9glBAvF/612vO7ig4LN3+g7LLaXy/gtujFki^J9Dnfq/yKN4IzQspkrRJEd/Zitw4HMnO40iTvk/qmfq0lvfCaJkLNlVqD19XJCPrt^J4gvtRiwNs9QfQht7lhUp/Wnt++6jJ7xrHqmqOMvd7oBX9H7VtZwAN/5tOhznLs9a^JqcBtokxx9c2lWCtgLnOHdNssIC5WcBfQqCnfCPrnq2A1QVGFoIkFin+RmvgdpC0x^JTJHK1ceRTrnNb6VBcmXnraSn5QZTIZ5F+SQ2rgqTNfofokJtEKAt8fUVrHZ81emS^Jf3sbH8UPfa9Xj0jmZmcjRRggrJ1yu0RsxUlxg5siQ2Fy5i3vAb0ZZ5ItWdIt8Jwt^JJFX0FWYGmphyo0Nwj/XP27NaqTwSOmo6xAfoyU7z/28U3k/qEbtLpn5xzVHk6Dny^JP0XGw4JttE7CmvwEi057FGGBu4pUYERfRNu7o+THlsQ=^J diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index c25c854779..8128554281 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-04-08-22-38-18 +#open 2014-05-15-14-10-48 #fields name #types string scripts/base/init-bare.bro @@ -38,15 +38,16 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_IRC.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.functions.bif.bro - build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_MIME.events.bif.bro + build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_NCP.events.bif.bro - build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.functions.bif.bro + build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NTP.events.bif.bro build/scripts/base/bif/plugins/Bro_PIA.events.bif.bro build/scripts/base/bif/plugins/Bro_POP3.events.bif.bro + build/scripts/base/bif/plugins/Bro_RADIUS.events.bif.bro build/scripts/base/bif/plugins/Bro_RPC.events.bif.bro build/scripts/base/bif/plugins/Bro_SNMP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro @@ -106,4 +107,4 @@ scripts/base/init-bare.bro build/scripts/base/bif/broxygen.bif.bro scripts/policy/misc/loaded-scripts.bro scripts/base/utils/paths.bro -#close 2014-04-08-22-38-18 +#close 2014-05-15-14-10-48 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 488b74e111..03c299141c 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-04-08-22-38-27 +#open 2014-05-15-14-12-26 #fields name #types string scripts/base/init-bare.bro @@ -38,15 +38,16 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_IRC.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.functions.bif.bro - build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_MIME.events.bif.bro + build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_NCP.events.bif.bro - build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.functions.bif.bro + build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NTP.events.bif.bro build/scripts/base/bif/plugins/Bro_PIA.events.bif.bro build/scripts/base/bif/plugins/Bro_POP3.events.bif.bro + build/scripts/base/bif/plugins/Bro_RADIUS.events.bif.bro build/scripts/base/bif/plugins/Bro_RPC.events.bif.bro build/scripts/base/bif/plugins/Bro_SNMP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro @@ -210,6 +211,9 @@ scripts/base/init-default.bro scripts/base/protocols/modbus/consts.bro scripts/base/protocols/modbus/main.bro scripts/base/protocols/pop3/__load__.bro + scripts/base/protocols/radius/__load__.bro + scripts/base/protocols/radius/main.bro + scripts/base/protocols/radius/consts.bro scripts/base/protocols/snmp/__load__.bro scripts/base/protocols/snmp/main.bro scripts/base/protocols/smtp/__load__.bro @@ -232,4 +236,4 @@ scripts/base/init-default.bro scripts/base/misc/find-checksum-offloading.bro scripts/base/misc/find-filtered-trace.bro scripts/policy/misc/loaded-scripts.bro -#close 2014-04-08-22-38-27 +#close 2014-05-15-14-12-26 diff --git a/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_01_bro/output b/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_01_bro/output index 0202fa3a28..7a0eaf5cb4 100644 --- a/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_01_bro/output +++ b/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_01_bro/output @@ -6,7 +6,6 @@ framework_notice_shortcuts_01.bro @load base/protocols/ssh/ redef Notice::emailed_types += { - SSH::Interesting_Hostname_Login, - SSH::Login + SSH::Interesting_Hostname_Login }; diff --git a/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_02_bro/output b/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_02_bro/output index 266a2e1fbb..0e92c5ea32 100644 --- a/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_02_bro/output +++ b/testing/btest/Baseline/doc.sphinx.include-doc_scripting_framework_notice_shortcuts_02_bro/output @@ -7,5 +7,4 @@ framework_notice_shortcuts_02.bro redef Notice::type_suppression_intervals += { [SSH::Interesting_Hostname_Login] = 1day, - [SSH::Login] = 12hrs, }; diff --git a/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro/output b/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro/output index 709fea1fba..bcf6ccd309 100644 --- a/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro/output +++ b/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro/output @@ -39,28 +39,37 @@ export { const notice_threshold = 10 &redef; } -event file_hash(f: fa_file, kind: string, hash: string) +function do_mhr_lookup(hash: string, fi: Notice::FileInfo) { - if ( kind == "sha1" && f?$mime_type && match_file_types in f$mime_type ) + local hash_domain = fmt("%s.malware.hash.cymru.com", hash); + + when ( local MHR_result = lookup_hostname_txt(hash_domain) ) { - local hash_domain = fmt("%s.malware.hash.cymru.com", hash); - when ( local MHR_result = lookup_hostname_txt(hash_domain) ) + # Data is returned as " " + local MHR_answer = split1(MHR_result, / /); + + if ( |MHR_answer| == 2 ) { - # Data is returned as " " - local MHR_answer = split1(MHR_result, / /); - if ( |MHR_answer| == 2 ) + local mhr_detect_rate = to_count(MHR_answer[2]); + + if ( mhr_detect_rate >= notice_threshold ) { local mhr_first_detected = double_to_time(to_double(MHR_answer[1])); - local mhr_detect_rate = to_count(MHR_answer[2]); - local readable_first_detected = strftime("%Y-%m-%d %H:%M:%S", mhr_first_detected); - if ( mhr_detect_rate >= notice_threshold ) - { - local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected); - local virustotal_url = fmt(match_sub_url, hash); - NOTICE([$note=Match, $msg=message, $sub=virustotal_url, $f=f]); - } + local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected); + local virustotal_url = fmt(match_sub_url, hash); + # We don't have the full fa_file record here in order to + # avoid the "when" statement cloning it (expensive!). + local n: Notice::Info = Notice::Info($note=Match, $msg=message, $sub=virustotal_url); + Notice::populate_file_info2(fi, n); + NOTICE(n); } } } } + +event file_hash(f: fa_file, kind: string, hash: string) + { + if ( kind == "sha1" && f?$mime_type && match_file_types in f$mime_type ) + do_mhr_lookup(hash, Notice::create_file_info(f)); + } diff --git a/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro@4/output b/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro@4/output index 31b94783d9..be9619fa1c 100644 --- a/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro@4/output +++ b/testing/btest/Baseline/doc.sphinx.include-scripts_policy_frameworks_files_detect-MHR_bro@4/output @@ -2,28 +2,37 @@ detect-MHR.bro -event file_hash(f: fa_file, kind: string, hash: string) +function do_mhr_lookup(hash: string, fi: Notice::FileInfo) { - if ( kind == "sha1" && f?$mime_type && match_file_types in f$mime_type ) + local hash_domain = fmt("%s.malware.hash.cymru.com", hash); + + when ( local MHR_result = lookup_hostname_txt(hash_domain) ) { - local hash_domain = fmt("%s.malware.hash.cymru.com", hash); - when ( local MHR_result = lookup_hostname_txt(hash_domain) ) + # Data is returned as " " + local MHR_answer = split1(MHR_result, / /); + + if ( |MHR_answer| == 2 ) { - # Data is returned as " " - local MHR_answer = split1(MHR_result, / /); - if ( |MHR_answer| == 2 ) + local mhr_detect_rate = to_count(MHR_answer[2]); + + if ( mhr_detect_rate >= notice_threshold ) { local mhr_first_detected = double_to_time(to_double(MHR_answer[1])); - local mhr_detect_rate = to_count(MHR_answer[2]); - local readable_first_detected = strftime("%Y-%m-%d %H:%M:%S", mhr_first_detected); - if ( mhr_detect_rate >= notice_threshold ) - { - local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected); - local virustotal_url = fmt(match_sub_url, hash); - NOTICE([$note=Match, $msg=message, $sub=virustotal_url, $f=f]); - } + local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected); + local virustotal_url = fmt(match_sub_url, hash); + # We don't have the full fa_file record here in order to + # avoid the "when" statement cloning it (expensive!). + local n: Notice::Info = Notice::Info($note=Match, $msg=message, $sub=virustotal_url); + Notice::populate_file_info2(fi, n); + NOTICE(n); } } } } + +event file_hash(f: fa_file, kind: string, hash: string) + { + if ( kind == "sha1" && f?$mime_type && match_file_types in f$mime_type ) + do_mhr_lookup(hash, Notice::create_file_info(f)); + } diff --git a/testing/btest/Baseline/doc.sphinx.include-scripts_policy_protocols_ssl_expiring-certs_bro/output b/testing/btest/Baseline/doc.sphinx.include-scripts_policy_protocols_ssl_expiring-certs_bro/output index aff7dffff7..cc2d8817bd 100644 --- a/testing/btest/Baseline/doc.sphinx.include-scripts_policy_protocols_ssl_expiring-certs_bro/output +++ b/testing/btest/Baseline/doc.sphinx.include-scripts_policy_protocols_ssl_expiring-certs_bro/output @@ -5,4 +5,5 @@ expiring-certs.bro NOTICE([$note=Certificate_Expires_Soon, $msg=fmt("Certificate %s is going to expire at %T", cert$subject, cert$not_valid_after), $conn=c, $suppress_for=1day, - $identifier=cat(c$id$resp_h, c$id$resp_p, c$ssl$cert_hash)]); + $identifier=cat(c$id$resp_h, c$id$resp_p, hash), + $fuid=fuid]); diff --git a/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 b/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 index 3cd6a49e11..3d6b9dffad 100644 --- a/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 +++ b/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 @@ -16,15 +16,15 @@ #empty_field (empty) #unset_field - #path mime_metrics - #open 2014-03-06-17-30-44 + #open 2014-04-21-21-34-08 #fields ts ts_delta mtype uniq_hosts hits bytes #types time interval string count count count - 1389719059.311698 300.000000 text/html 1 4 53070 + 1389719059.311698 300.000000 text/html 1 3 47335 1389719059.311698 300.000000 image/jpeg 1 1 186859 1389719059.311698 300.000000 application/pgp-signature 1 1 836 - 1389719059.311698 300.000000 text/plain 1 12 113982 + 1389719059.311698 300.000000 text/plain 1 13 119717 1389719059.311698 300.000000 image/gif 1 1 172 1389719059.311698 300.000000 image/png 1 9 82176 1389719059.311698 300.000000 image/x-icon 1 2 2300 - #close 2014-03-06-17-30-44 + #close 2014-04-21-21-34-08 diff --git a/testing/btest/Baseline/language.record-bad-ctor2/out b/testing/btest/Baseline/language.record-bad-ctor2/out new file mode 100644 index 0000000000..d5ce540dd8 --- /dev/null +++ b/testing/btest/Baseline/language.record-bad-ctor2/out @@ -0,0 +1 @@ +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.record-bad-ctor2/record-bad-ctor2.bro, line 14: bad type in record constructor ([[$cmd=echo hi]] and [$cmd=echo hi]) diff --git a/testing/btest/Baseline/language.redef-same-prefixtable-idx/out b/testing/btest/Baseline/language.redef-same-prefixtable-idx/out new file mode 100644 index 0000000000..aa6f21177a --- /dev/null +++ b/testing/btest/Baseline/language.redef-same-prefixtable-idx/out @@ -0,0 +1,4 @@ +{ +[3.0.0.0/8] = 2.0.0.0/8 +} +2.0.0.0/8 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out index 57f1f97b9c..1d54e9a2ac 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out @@ -20,12 +20,12 @@ MIME_TYPE text/html FILE_OVER_NEW_CONNECTION FILE_STATE_REMOVE -file #1, 1918, 0 +file #1, 1868, 0 [orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp] source: SMTP -MD5: d194c6359c85bb88b54caee18b1e9b44 -SHA1: e54af6c6616525611364b80bd6557a7ea21dae94 -SHA256: b9556e92ddbe52379b64804136f830d111cafe7fcd78e54817fe40f3bc24268d +MD5: afd68ae5c63caf6050dc5440bd72c5dd +SHA1: a4825db9a78b6c631f3c97d363be47faf65e8386 +SHA256: 8d9e5bb6072fbbf5b4a5fabe89ede8c8c54915efe33704fe71420d50438f5f81 FILE_NEW file #2, 0, 0 FILE_BOF_BUFFER @@ -34,9 +34,9 @@ MIME_TYPE text/plain FILE_OVER_NEW_CONNECTION FILE_STATE_REMOVE -file #2, 10823, 0 +file #2, 10809, 0 [orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp] source: SMTP -MD5: a968bb0f9f9d95835b2e74c845877e87 -SHA1: 43bf1cea1cd4b7d15243e15611859aa49d515665 -SHA256: d5c4e7248840932b9d74ea2f3b3ae142c723a863abf5fd0599f9dd1171697e12 +MD5: 30a60389acc290515651391154ba1b33 +SHA1: 5d3e96afdef531571b685aa2a3729e6fe635e413 +SHA256: 6ea20e4b4f218a715ddfd0c27a92def1020a47a1c2cc6971a6710746efabf868 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile1 b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile1 index 0b9186c58e..befde863a6 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile1 +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile1 @@ -1,8 +1,8 @@ - + - - + + - + -
+
-

Hello

+

Hello

-

 

+

 

-

I send u smtp pcap file

+

I send u smtp pcap file

-

Find the attachment

+

Find the attachment

-

 

+

 

-

GPS

+

GPS

diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile2 b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile2 index 9eb3055735..6af5f49a43 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile2 +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/thefile2 @@ -20,9 +20,9 @@ Version 4.9.8.7 * Added support for GCC > 3.2 * Debug variables are now resent during next debug session * Watched Variables not in correct context are now kept and updated when it is needed -* Added new compiler/linker options: 20 +* Added new compiler/linker options: - Strip executable - - Generate instructions for a specific machine (i386, i486, i586, i686, pentium, pentium-mmx, pentiumpro, pentium2, pentium3, pentium4, 20 + - Generate instructions for a specific machine (i386, i486, i586, i686, pentium, pentium-mmx, pentiumpro, pentium2, pentium3, pentium4, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-4, athlon-xp, athlon-mp, winchip-c6, winchip2, k8, c3 and c3-2) - Enable use of processor specific built-in functions (mmmx, sse, sse2, pni, 3dnow) * "Default" button in Compiler Options is back @@ -42,16 +42,16 @@ Version 4.9.8.4 * Bug fixes Version 4.9.8.3 -* On Dev-C++ first time configuration dialog, a code completion cache of all the standard 20 +* On Dev-C++ first time configuration dialog, a code completion cache of all the standard include files can now be generated. * Improved WebUpdate module * Many bug fixes Version 4.9.8.2 * New debug feature for DLLs: attach to a running process -* New project option: Use custom Makefile. 20 +* New project option: Use custom Makefile. * New WebUpdater module. -* Allow user to specify an alternate configuration file in Environment Options 20 +* Allow user to specify an alternate configuration file in Environment Options (still can be overriden by using "-c" command line parameter). * Lots of bug fixes. @@ -150,7 +150,7 @@ Version 4.9.6.9 * Implemented "compiler sets" infrastructure to switch between different compilers easily (e.g. gcc-2.95 and gcc-3.2) * Added "Files" tab in CVS form to allow selection of more than one file for the requested CVS action - 20 + Version 4.9.6.8 * support for DLL application hosting, for debugging and executing DLLs under Dev-C++. * New class browser option: "Show inherited members" @@ -248,7 +248,7 @@ Version 4.9.5.0 (5.0 beta 5): * Folders in Project and Class Browser * Send custom commands to GDB * Makefile can now be customized. -* Modified the behaviour of the -c param : 20 +* Modified the behaviour of the -c param : -c * Saving of custom syntax parameter group * Possibility of changing compilers and tools filename. diff --git a/testing/btest/Baseline/scripts.base.protocols.dns.multiple-txt-strings/dns.log b/testing/btest/Baseline/scripts.base.protocols.dns.multiple-txt-strings/dns.log new file mode 100644 index 0000000000..ba73d16c82 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.dns.multiple-txt-strings/dns.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dns +#open 2014-04-24-23-33-57 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected +#types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool +1398382067.286885 CXWv6p3arKYeMETxOg 192.150.187.50 51946 68.142.255.16 53 udp 28079 - - - - - 0 NOERROR T F F F 0 fa14._domainkey.flickr.com,fa14._domainkey.yahoo.com,TXT 127 k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPdPfyJM2R2GqMyZM1flTzFeDIU+e7KmiKRw5yz3Xht+cgEIiHmm5lIGBuWCc5rtiy0CcxePpqccPKjn TXT 98 HSrDI23PU+HOuqJ6ergE1IOsL6LOEgG6YT53vMb8Z6UiBSsYPlrDEC+8CUIkTLMLXJauRK5bNRKV1ATGzGFpf3TjZtWwIDAQAB 900.000000,900.000000,7200.000000 F +#close 2014-04-24-23-33-57 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log index 3b04596f6f..5fb15d53ae 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-45-24 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1348168976.508038 CXWv6p3arKYeMETxOg 192.168.57.103 60108 192.168.57.101 2811 TLSv10 TLS_RSA_WITH_AES_256_CBC_SHA - - - T FBtbj87tgpyeDSj31,F8TfgZ31c1dFu8Kt2k FVNYOh2BeQBb7MpCPe,FwjBou1e5DbpE0eOgk,FbYQmk4x4M4Bx3PZme CN=host/alpha,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Globus Simple CA,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid -1348168976.551422 CjhGID4nQcgTWjvg4c 192.168.57.103 35391 192.168.57.101 55968 TLSv10 TLS_RSA_WITH_NULL_SHA - - - T F4SSqN31HDIrrH5Q8h,FJHp5Pf6VLQsRQK3,FHACqa3dX9BXRV2av,FNnDVT1NURRWeoLLN3 FFWYVj4BcvQb35WIaf,Fj16G835fnJgnVlKU6,FGONoc1Nj0Ka5zlxDa CN=932373381,CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid -#close 2014-03-13-20-45-24 +#open 2014-04-26-16-44-47 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1348168976.508038 CXWv6p3arKYeMETxOg 192.168.57.103 60108 192.168.57.101 2811 TLSv10 TLS_RSA_WITH_AES_256_CBC_SHA - - - - T FBtbj87tgpyeDSj31,F8TfgZ31c1dFu8Kt2k FVNYOh2BeQBb7MpCPe,FwjBou1e5DbpE0eOgk,FbYQmk4x4M4Bx3PZme CN=host/alpha,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Globus Simple CA,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid +1348168976.551422 CjhGID4nQcgTWjvg4c 192.168.57.103 35391 192.168.57.101 55968 TLSv10 TLS_RSA_WITH_NULL_SHA - - - - T F4SSqN31HDIrrH5Q8h,FJHp5Pf6VLQsRQK3,FHACqa3dX9BXRV2av,FNnDVT1NURRWeoLLN3 FFWYVj4BcvQb35WIaf,Fj16G835fnJgnVlKU6,FGONoc1Nj0Ka5zlxDa CN=932373381,CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid +#close 2014-04-26-16-44-47 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-connect/smtp.log b/testing/btest/Baseline/scripts.base.protocols.http.http-connect/smtp.log index 27791f873d..6a22c5d57f 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-connect/smtp.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-connect/smtp.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path smtp -#open 2014-04-01-23-15-59 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth helo mailfrom rcptto date from to reply_to msg_id in_reply_to subject x_originating_ip first_received second_received last_reply path user_agent fuids -#types time string addr port addr port count string string set[string] string string set[string] string string string string addr string string string vector[addr] string vector[string] -1078232255.642953 CXWv6p3arKYeMETxOg 79.26.245.236 3378 254.228.86.79 8240 1 208.191.73.21 Tue, 2 Mar 2004 13:57:49 +0100 Sybille Ostermann thenightwatch@t-online.de - - - Hier sind die dicken Girls hemmungloser denn je.. grcu - from mail.iosphere.net (mail.iosphere.net [216.58.97.33]) by mail.netsync.net with esmtp; Mrz, 02 2004 12:55:34 -0700 - 250 Message accepted. 254.228.86.79,79.26.245.236,216.58.97.33 Microsoft Outlook Build 10.0.2616 FVS9k93PUgScEUCOjd -#close 2014-04-01-23-15-59 +#open 2014-05-15-17-52-02 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth helo mailfrom rcptto date from to reply_to msg_id in_reply_to subject x_originating_ip first_received second_received last_reply path user_agent tls fuids +#types time string addr port addr port count string string set[string] string string set[string] string string string string addr string string string vector[addr] string bool vector[string] +1078232255.642953 CXWv6p3arKYeMETxOg 79.26.245.236 3378 254.228.86.79 8240 1 208.191.73.21 Tue, 2 Mar 2004 13:57:49 +0100 Sybille Ostermann thenightwatch@t-online.de - - - Hier sind die dicken Girls hemmungloser denn je.. grcu - from mail.iosphere.net (mail.iosphere.net [216.58.97.33]) by mail.netsync.net with esmtp; Mrz, 02 2004 12:55:34 -0700 - 250 Message accepted. 254.228.86.79,79.26.245.236,216.58.97.33 Microsoft Outlook Build 10.0.2616 F FVS9k93PUgScEUCOjd +#close 2014-05-15-17-52-02 diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log b/testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log new file mode 100644 index 0000000000..411e57f8ee --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2014-05-01-19-07-07 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count set[string] +1311189318.898709 CjhGID4nQcgTWjvg4c 192.168.1.77 57655 209.197.168.151 1024 tcp irc-dcc-data 2.256935 124 42208 SF - 0 ShAdDaFf 28 1592 43 44452 (empty) +1311189164.064603 CXWv6p3arKYeMETxOg 192.168.1.77 57640 66.198.80.67 6667 tcp irc 178.237017 453 25404 S3 - 0 ShADdaf 63 3761 52 28194 (empty) +#close 2014-05-01-19-07-07 diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log b/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log index 57fa59a1ef..d387f9682b 100644 --- a/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log @@ -3,9 +3,11 @@ #empty_field (empty) #unset_field - #path weird -#open 2013-08-26-19-36-36 +#open 2014-04-07-19-37-09 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1153491909.414066 - - - - - truncated_IP - F bro 1153491912.529443 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 binpac exception: out_of_bound: WriteSingleRegisterRequest: 4 > 0 - F bro -#close 2013-08-26-19-36-36 +1153491920.661039 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 TCP_ack_underflow_or_misorder - F bro +1153491929.715910 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 TCP_seq_underflow_or_misorder - F bro +#close 2014-04-07-19-37-09 diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.starttls/ssl.log b/testing/btest/Baseline/scripts.base.protocols.pop3.starttls/ssl.log new file mode 100644 index 0000000000..1eab1092ed --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.starttls/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2014-05-15-17-23-07 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1400173552.424910 CXWv6p3arKYeMETxOg 192.168.4.149 54775 192.168.4.149 110 TLSv12 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - - - - T FEdAw24VSam39HNlY5 (empty) emailAddress=postmaster@lilawelt.de,CN=chimaera.lilawelt.de,OU=Servers,O=Lilawelt,L=Munich,C=DE emailAddress=postmaster@lilawelt.de,CN=Lilawelt,OU=Lilawelt CA,O=Lilawelt,L=Munich,C=DE - - +#close 2014-05-15-17-23-07 diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.starttls/x509.log b/testing/btest/Baseline/scripts.base.protocols.pop3.starttls/x509.log new file mode 100644 index 0000000000..18194ddb9f --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.starttls/x509.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path x509 +#open 2014-05-15-17-23-07 +#fields ts id certificate.version certificate.serial certificate.subject certificate.issuer certificate.not_valid_before certificate.not_valid_after certificate.key_alg certificate.sig_alg certificate.key_type certificate.key_length certificate.exponent certificate.curve san.dns san.uri san.email san.ip basic_constraints.ca basic_constraints.path_len +#types time string count string string string time time string string string count string string vector[string] vector[string] vector[string] vector[addr] bool count +1400173552.426860 FEdAw24VSam39HNlY5 3 01 emailAddress=postmaster@lilawelt.de,CN=chimaera.lilawelt.de,OU=Servers,O=Lilawelt,L=Munich,C=DE emailAddress=postmaster@lilawelt.de,CN=Lilawelt,OU=Lilawelt CA,O=Lilawelt,L=Munich,C=DE 1178385788.000000 1493745788.000000 rsaEncryption md5WithRSAEncryption rsa 2048 65537 - - - - - F - +#close 2014-05-15-17-23-07 diff --git a/testing/btest/Baseline/scripts.base.protocols.radius.auth/radius.log b/testing/btest/Baseline/scripts.base.protocols.radius.auth/radius.log new file mode 100644 index 0000000000..55e85cd1eb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.radius.auth/radius.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path radius +#open 2014-05-15-15-24-25 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p username mac remote_ip connect_info result +#types time string addr port addr port string string addr string string +1217631137.916736 CXWv6p3arKYeMETxOg 10.0.0.1 1645 10.0.0.100 1812 John.McGuirk 00:14:22:e9:54:5e - - success +#close 2014-05-15-15-24-25 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.basic/smtp.log b/testing/btest/Baseline/scripts.base.protocols.smtp.basic/smtp.log index 0fcd5e98f6..23d1d05d1e 100644 --- a/testing/btest/Baseline/scripts.base.protocols.smtp.basic/smtp.log +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.basic/smtp.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path smtp -#open 2014-04-01-23-16-17 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth helo mailfrom rcptto date from to reply_to msg_id in_reply_to subject x_originating_ip first_received second_received last_reply path user_agent fuids -#types time string addr port addr port count string string set[string] string string set[string] string string string string addr string string string vector[addr] string vector[string] -1254722768.219663 CjhGID4nQcgTWjvg4c 10.10.1.4 1470 74.53.140.153 25 1 GP Mon, 5 Oct 2009 11:36:07 +0530 "Gurpartap Singh" - <000301ca4581$ef9e57f0$cedb07d0$@in> - SMTP - - - 250 OK id=1Mugho-0003Dg-Un 74.53.140.153,10.10.1.4 Microsoft Office Outlook 12.0 Fel9gs4OtNEV6gUJZ5,Ft4M3f2yMvLlmwtbq9,FL9Y0d45OI4LpS6fmh -#close 2014-04-01-23-16-17 +#open 2014-05-15-17-52-20 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth helo mailfrom rcptto date from to reply_to msg_id in_reply_to subject x_originating_ip first_received second_received last_reply path user_agent tls fuids +#types time string addr port addr port count string string set[string] string string set[string] string string string string addr string string string vector[addr] string bool vector[string] +1254722768.219663 CjhGID4nQcgTWjvg4c 10.10.1.4 1470 74.53.140.153 25 1 GP Mon, 5 Oct 2009 11:36:07 +0530 "Gurpartap Singh" - <000301ca4581$ef9e57f0$cedb07d0$@in> - SMTP - - - 250 OK id=1Mugho-0003Dg-Un 74.53.140.153,10.10.1.4 Microsoft Office Outlook 12.0 F Fel9gs4OtNEV6gUJZ5,Ft4M3f2yMvLlmwtbq9,FL9Y0d45OI4LpS6fmh +#close 2014-05-15-17-52-20 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.one-side/smtp.log b/testing/btest/Baseline/scripts.base.protocols.smtp.one-side/smtp.log new file mode 100644 index 0000000000..0bdb7bf69a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.one-side/smtp.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path smtp +#open 2014-06-11-00-56-57 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth helo mailfrom rcptto date from to reply_to msg_id in_reply_to subject x_originating_ip first_received second_received last_reply path user_agent tls fuids +#types time string addr port addr port count string string set[string] string string set[string] string string string string addr string string string vector[addr] string bool vector[string] +1402446189.935267 CXWv6p3arKYeMETxOg 192.150.187.22 57722 192.150.186.11 25 1 enzo.icir.org - robin@icir.org robin@icir.org - - - Hello1! - - - - 192.150.186.11,192.150.187.22 - F (empty) +1402446189.993233 CXWv6p3arKYeMETxOg 192.150.187.22 57722 192.150.186.11 25 1 enzo.icir.org - robin@icir.org rsommer@lbl.gov - - - Hello2! - - - - 192.150.186.11,192.150.187.22 - F (empty) +#close 2014-06-11-00-56-57 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/smtp.log b/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/smtp.log new file mode 100644 index 0000000000..a8f2a95678 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/smtp.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path smtp +#open 2014-05-15-17-52-23 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth helo mailfrom rcptto date from to reply_to msg_id in_reply_to subject x_originating_ip first_received second_received last_reply path user_agent tls fuids +#types time string addr port addr port count string string set[string] string string set[string] string string string string addr string string string vector[addr] string bool vector[string] +1400168396.898137 CXWv6p3arKYeMETxOg 192.168.4.149 54170 74.125.142.26 25 1 openssl.client.net - - - - - - - - - - - - 220 2.0.0 Ready to start TLS 74.125.142.26,192.168.4.149 - T (empty) +#close 2014-05-15-17-52-23 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/ssl.log b/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/ssl.log new file mode 100644 index 0000000000..cec018c589 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2014-05-15-16-56-36 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1400168397.019290 CXWv6p3arKYeMETxOg 192.168.4.149 54170 74.125.142.26 25 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 secp256r1 - - - T FUE0dj3SWjQASC0bk3,FbPkr51wrSMIUT5Hib,FVW1o23Jjs8yenOhzb (empty) CN=mx.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +#close 2014-05-15-16-56-36 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/x509.log b/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/x509.log new file mode 100644 index 0000000000..304728aeaa --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.starttls/x509.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path x509 +#open 2014-05-15-16-56-36 +#fields ts id certificate.version certificate.serial certificate.subject certificate.issuer certificate.not_valid_before certificate.not_valid_after certificate.key_alg certificate.sig_alg certificate.key_type certificate.key_length certificate.exponent certificate.curve san.dns san.uri san.email san.ip basic_constraints.ca basic_constraints.path_len +#types time string count string string string time time string string string count string string vector[string] vector[string] vector[string] vector[addr] bool count +1400168397.069811 FUE0dj3SWjQASC0bk3 3 325D8297987D50B0 CN=mx.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US 1378726355.000000 1410262355.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - aspmx.l.google.com,alt1.aspmx.l.google.com,alt2.aspmx.l.google.com,alt3.aspmx.l.google.com,alt4.aspmx.l.google.com,gmail-smtp-in.l.google.com,alt1.gmail-smtp-in.l.google.com,alt2.gmail-smtp-in.l.google.com,alt3.gmail-smtp-in.l.google.com,alt4.gmail-smtp-in.l.google.com,gmr-smtp-in.l.google.com,alt1.gmr-smtp-in.l.google.com,alt2.gmr-smtp-in.l.google.com,alt3.gmr-smtp-in.l.google.com,alt4.gmr-smtp-in.l.google.com,mx.google.com,aspmx2.googlemail.com,aspmx3.googlemail.com,aspmx4.googlemail.com,aspmx5.googlemail.com - - - F - +1400168397.069811 FbPkr51wrSMIUT5Hib 3 023A69 CN=Google Internet Authority G2,O=Google Inc,C=US CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US 1365174955.000000 1428160555.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - - - - - T 0 +1400168397.069811 FVW1o23Jjs8yenOhzb 3 12BBE6 CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US OU=Equifax Secure Certificate Authority,O=Equifax,C=US 1021953600.000000 1534824000.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - - - - - T - +#close 2014-05-15-16-56-36 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log index 455d8606e8..7834e74868 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-45-46 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1335538392.319381 CXWv6p3arKYeMETxOg 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA ssl.gstatic.com - - T F6wfNWn8LR755SYo7,FJl60T1mOolaez9T0h (empty) CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US - - -#close 2014-03-13-20-45-46 +#open 2014-04-26-16-45-01 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1335538392.319381 CXWv6p3arKYeMETxOg 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA secp256r1 ssl.gstatic.com - - T F6wfNWn8LR755SYo7,FJl60T1mOolaez9T0h (empty) CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US - - +#close 2014-04-26-16-45-01 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout new file mode 100644 index 0000000000..c2cc676ec1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout @@ -0,0 +1 @@ +key length in bits, 1024 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log new file mode 100644 index 0000000000..652f3b3df7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2014-04-27-00-52-03 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1398558136.319509 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 TLSv12 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - - - - T F6fLv13PBYz8MNqx68,F8cTDl1penwXxGu4K7 (empty) emailAddress=denicadmmail@arcor.de,CN=www.lilawelt.net,C=US CN=StartCom Class 1 Primary Intermediate Server CA,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL - - +#close 2014-04-27-00-52-03 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log new file mode 100644 index 0000000000..66ea42be70 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2014-04-26-16-39-57 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1398529018.678827 CXWv6p3arKYeMETxOg 192.168.18.50 56981 74.125.239.97 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA secp256r1 - - - T FDy6ve1m58lwPRfhE9,FnGjwc1EVGk5x0WZk5,F2T07R1XZFCmeWafv2 (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +#close 2014-04-26-16-39-57 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log new file mode 100644 index 0000000000..e8813fb60a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path x509 +#open 2014-04-26-16-39-57 +#fields ts id certificate.version certificate.serial certificate.subject certificate.issuer certificate.not_valid_before certificate.not_valid_after certificate.key_alg certificate.sig_alg certificate.key_type certificate.key_length certificate.exponent certificate.curve san.dns san.uri san.email san.ip basic_constraints.ca basic_constraints.path_len +#types time string count string string string time time string string string count string string vector[string] vector[string] vector[string] vector[addr] bool count +1398529018.711296 FDy6ve1m58lwPRfhE9 3 1E58FDC12DE4C703 CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US 1397045108.000000 1404777600.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - *.google.com,*.android.com,*.appengine.google.com,*.cloud.google.com,*.google-analytics.com,*.google.ca,*.google.cl,*.google.co.in,*.google.co.jp,*.google.co.uk,*.google.com.ar,*.google.com.au,*.google.com.br,*.google.com.co,*.google.com.mx,*.google.com.tr,*.google.com.vn,*.google.de,*.google.es,*.google.fr,*.google.hu,*.google.it,*.google.nl,*.google.pl,*.google.pt,*.googleapis.cn,*.googlecommerce.com,*.googlevideo.com,*.gstatic.com,*.gvt1.com,*.urchin.com,*.url.google.com,*.youtube-nocookie.com,*.youtube.com,*.youtubeeducation.com,*.ytimg.com,android.com,g.co,goo.gl,google-analytics.com,google.com,googlecommerce.com,urchin.com,youtu.be,youtube.com,youtubeeducation.com - - - F - +1398529018.711296 FnGjwc1EVGk5x0WZk5 3 023A69 CN=Google Internet Authority G2,O=Google Inc,C=US CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US 1365174955.000000 1428160555.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - - - - - T 0 +1398529018.711296 F2T07R1XZFCmeWafv2 3 12BBE6 CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US OU=Equifax Secure Certificate Authority,O=Equifax,C=US 1021953600.000000 1534824000.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - - - - - T - +#close 2014-04-26-16-39-57 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout new file mode 100644 index 0000000000..c7e3a43cbe --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout @@ -0,0 +1,45 @@ +Handshake, 192.168.1.105, 74.125.224.79, T, 1, 169 +Handshake, 192.168.1.105, 74.125.224.79, F, 2, 81 +Handshake, 192.168.1.105, 74.125.224.79, F, 11, 1620 +Handshake, 192.168.1.105, 74.125.224.79, F, 12, 199 +Handshake, 192.168.1.105, 74.125.224.79, F, 14, 0 +Handshake, 192.168.1.105, 74.125.224.79, T, 16, 66 +CCS, 192.168.1.105, 74.125.224.79, T +Encrypted data, 192.168.1.105, 74.125.224.79, T, 22, 72 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 48 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 387 +Handshake, 192.168.1.105, 74.125.224.79, F, 4, 170 +CCS, 192.168.1.105, 74.125.224.79, F +Established, 192.168.1.105, 74.125.224.79 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 22, 36 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 40 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 248 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 161 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 33 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 148 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 46 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 135 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 59 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 245 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 32 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 32 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 92 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 75 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 32 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 32 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout new file mode 100644 index 0000000000..527e63f4b9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout @@ -0,0 +1,2 @@ +F, 1995 +[result=1, result_string=good, chain_certs=] diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log index 88f3c2126e..082106e89e 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-46-30 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1393957586.786031 CXWv6p3arKYeMETxOg 192.168.4.149 53525 74.125.239.37 443 - - - - handshake_failure F - - - - - - -#close 2014-03-13-20-46-30 +#open 2014-04-26-16-45-16 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1393957586.786031 CXWv6p3arKYeMETxOg 192.168.4.149 53525 74.125.239.37 443 - - - - - handshake_failure F - - - - - - +#close 2014-04-26-16-45-16 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log index 0bb8b5810d..ab1345d0cc 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-46-09 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1357328848.549370 CXWv6p3arKYeMETxOg 10.0.0.80 56637 68.233.76.12 443 TLSv12 TLS_RSA_WITH_RC4_128_MD5 - - - T FlnQzb2dJK4p9jXwmd,FaDzX22O4j3kFF6Jqg,F9Tsjm3OdCmGGw43Yh (empty) CN=*.taleo.net,OU=Comodo PremiumSSL Wildcard,OU=Web,O=Taleo Inc.,street=4140 Dublin Boulevard,street=Suite 400,L=Dublin,ST=CA,postalCode=94568,C=US CN=COMODO High-Assurance Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - -#close 2014-03-13-20-46-09 +#open 2014-04-26-16-45-09 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1357328848.549370 CXWv6p3arKYeMETxOg 10.0.0.80 56637 68.233.76.12 443 TLSv12 TLS_RSA_WITH_RC4_128_MD5 - - - - T FlnQzb2dJK4p9jXwmd,FaDzX22O4j3kFF6Jqg,F9Tsjm3OdCmGGw43Yh (empty) CN=*.taleo.net,OU=Comodo PremiumSSL Wildcard,OU=Web,O=Taleo Inc.,street=4140 Dublin Boulevard,street=Suite 400,L=Dublin,ST=CA,postalCode=94568,C=US CN=COMODO High-Assurance Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - +#close 2014-04-26-16-45-09 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout new file mode 100644 index 0000000000..8305175edb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout @@ -0,0 +1,13 @@ +server_name, 192.168.4.149, 74.125.239.152, [google.de] +Curves, 192.168.4.149, 74.125.239.152 +secp256r1 +secp384r1 +secp521r1 +Point formats, 192.168.4.149, 74.125.239.152, T +uncompressed +ALPN, 192.168.4.149, 74.125.239.152, [spdy/3, spdy/3.1, http/1.1] +Point formats, 192.168.4.149, 74.125.239.152, F +uncompressed +ansiX962_compressed_prime +ansiX962_compressed_char2 +ALPN, 192.168.4.149, 74.125.239.152, [spdy/3.1] diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log index 9f61bfbd3b..b8f576e497 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log @@ -1,62 +1,62 @@ 0.000000 bro_init 0.000000 filter_change_tracking 1254722767.492060 protocol_confirmation - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] atype: enum = Analyzer::ANALYZER_DNS [2] aid: count = 3 1254722767.492060 ChecksumOffloading::check 1254722767.492060 filter_change_tracking 1254722767.492060 new_connection - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] 1254722767.492060 dns_message - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] is_orig: bool = T [2] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=F, AA=F, TC=F, RD=T, RA=F, Z=0, num_queries=1, num_answers=0, num_auth=0, num_addl=0] [3] len: count = 34 1254722767.492060 dns_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=F, AA=F, TC=F, RD=T, RA=F, Z=0, num_queries=1, num_answers=0, num_auth=0, num_addl=0] [2] query: string = mail.patriots.in [3] qtype: count = 1 [4] qclass: count = 1 1254722767.492060 dns_end - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=F, AA=F, TC=F, RD=T, RA=F, Z=0, num_queries=1, num_answers=0, num_auth=0, num_addl=0] 1254722767.526085 dns_message - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] is_orig: bool = F [2] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] [3] len: count = 100 1254722767.526085 dns_CNAME_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] [2] ans: dns_answer = [answer_type=1, query=mail.patriots.in, qtype=5, qclass=1, TTL=3.0 hrs 27.0 secs] [3] name: string = patriots.in 1254722767.526085 dns_A_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in], TTLs=[3.0 hrs 27.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in], TTLs=[3.0 hrs 27.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] [2] ans: dns_answer = [answer_type=1, query=patriots.in, qtype=1, qclass=1, TTL=3.0 hrs 28.0 secs] [3] a: addr = 74.53.140.153 1254722767.526085 dns_end - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in, 74.53.140.153], TTLs=[3.0 hrs 27.0 secs, 3.0 hrs 28.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in, 74.53.140.153], TTLs=[3.0 hrs 27.0 secs, 3.0 hrs 28.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] 1254722767.529046 new_connection - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.0, service={^J^J}, addl=, hot=0, history=, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.0, service={^J^J}, addl=, hot=0, history=, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] 1254722767.875996 connection_established - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.34695, service={^J^J}, addl=, hot=0, history=Sh, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.34695, service={^J^J}, addl=, hot=0, history=Sh, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] 1254722768.219663 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > @@ -64,7 +64,7 @@ [5] cont_resp: bool = T 1254722768.219663 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 xc90.websitewelcome.com ESMTP Exim 4.69 #1 Mon, 05 Oct 2009 01:05:54 -0500 , path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 xc90.websitewelcome.com ESMTP Exim 4.69 #1 Mon, 05 Oct 2009 01:05:54 -0500 , path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > @@ -72,7 +72,7 @@ [5] cont_resp: bool = T 1254722768.219663 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 We do not authorize the use of this system to transport unsolicited, , path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 We do not authorize the use of this system to transport unsolicited, , path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > @@ -80,18 +80,18 @@ [5] cont_resp: bool = F 1254722768.224809 protocol_confirmation - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] atype: enum = Analyzer::ANALYZER_SMTP [2] aid: count = 7 1254722768.224809 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = EHLO [3] arg: string = GP 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -99,7 +99,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 xc90.websitewelcome.com Hello GP [122.162.143.157], path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 xc90.websitewelcome.com Hello GP [122.162.143.157], path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -107,7 +107,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 SIZE 52428800, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 SIZE 52428800, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -115,7 +115,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 PIPELINING, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 PIPELINING, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -123,7 +123,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 AUTH PLAIN LOGIN, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 AUTH PLAIN LOGIN, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -131,7 +131,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 STARTTLS, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 STARTTLS, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -139,13 +139,13 @@ [5] cont_resp: bool = F 1254722768.568729 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.039683, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.039683, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = AUTH [3] arg: string = LOGIN 1254722768.911081 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.382035, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.382035, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 334 [3] cmd: string = AUTH @@ -153,13 +153,13 @@ [5] cont_resp: bool = F 1254722768.911655 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.382609, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.382609, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = ** [3] arg: string = Z3VycGFydGFwQHBhdHJpb3RzLmlu 1254722769.253544 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.724498, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.724498, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 334 [3] cmd: string = AUTH_ANSWER @@ -167,13 +167,13 @@ [5] cont_resp: bool = F 1254722769.254118 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=1.725072, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=1.725072, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = ** [3] arg: string = cHVuamFiQDEyMw== 1254722769.613798 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=2.084752, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=2.084752, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 235 [3] cmd: string = AUTH_ANSWER @@ -181,13 +181,13 @@ [5] cont_resp: bool = F 1254722769.614414 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.085368, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.085368, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = MAIL [3] arg: string = FROM: 1254722769.956765 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.427719, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.427719, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = MAIL @@ -195,13 +195,13 @@ [5] cont_resp: bool = F 1254722769.957250 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.428204, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.428204, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = RCPT [3] arg: string = TO: 1254722770.319708 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.790662, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.790662, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = RCPT @@ -209,16 +209,16 @@ [5] cont_resp: bool = F 1254722770.320203 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = DATA [3] arg: string = 1254722770.320203 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] 1254722770.661679 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=3.132633, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=3.132633, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 354 [3] cmd: string = DATA @@ -226,286 +226,286 @@ [5] cont_resp: bool = F 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=FROM, value="Gurpartap Singh" ] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=TO, value=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=SUBJECT, value=SMTP] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=DATE, value=Mon, 5 Oct 2009 11:36:07 +0530] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=MESSAGE-ID, value=<000301ca4581$ef9e57f0$cedb07d0$@in>] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=MIME-VERSION, value=1.0] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=multipart/mixed;^Iboundary="----=_NextPart_000_0004_01CA45B0.095693F0"] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=X-MAILER, value=Microsoft Office Outlook 12.0] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=THREAD-INDEX, value=AcpFgem9BvjjZEDeR1Kh8i+hUyVo0A==] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-LANGUAGE, value=en-us] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=X-CR-HASHEDPUZZLE, value=SeA= AAR2 ADaH BpiO C4G1 D1gW FNB1 FPkR Fn+W HFCP HnYJ JO7s Kum6 KytW LFcI LjUt;1;cgBhAGoAXwBkAGUAbwBsADIAMAAwADIAaQBuAEAAeQBhAGgAbwBvAC4AYwBvAC4AaQBuAA==;Sosha1_v1;7;{CAA37F59-1850-45C7-8540-AA27696B5398};ZwB1AHIAcABhAHIAdABhAHAAQABwAGEAdAByAGkAbwB0AHMALgBpAG4A;Mon, 05 Oct 2009 06:06:01 GMT;UwBNAFQAUAA=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=X-CR-PUZZLEID, value={CAA37F59-1850-45C7-8540-AA27696B5398}] 1254722770.692743 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=multipart/alternative;^Iboundary="----=_NextPart_001_0005_01CA45B0.095693F0"] 1254722770.692743 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=text/plain;^Icharset="us-ascii"] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TRANSFER-ENCODING, value=7bit] 1254722770.692743 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692743 mime_end_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] 1254722770.692743 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = T 1254722770.692743 file_new - [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=, u2_events=] + [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=, u2_events=] 1254722770.692743 file_over_new_connection - [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^J}, rx_hosts={^J^J}, conn_uids={^J^J}, source=SMTP, depth=0, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^J}, rx_hosts={^J^J}, conn_uids={^J^J}, source=SMTP, depth=0, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692743 file_state_remove - [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=79, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^I74.53.140.153^J}, rx_hosts={^J^I10.10.1.4^J}, conn_uids={^J^ICjhGID4nQcgTWjvg4c^J}, source=SMTP, depth=3, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] + [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=79, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^I74.53.140.153^J}, rx_hosts={^J^I10.10.1.4^J}, conn_uids={^J^ICjhGID4nQcgTWjvg4c^J}, source=SMTP, depth=3, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] 1254722770.692743 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692743 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=text/html;^Icharset="us-ascii"] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TRANSFER-ENCODING, value=quoted-printable] 1254722770.692786 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=3070, state=4, num_pkts=10, num_bytes_ip=2018, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.16374, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=3070, state=4, num_pkts=10, num_bytes_ip=2018, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.16374, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, tls=F, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692786 file_new - [0] f: fa_file = [id=Ft4M3f2yMvLlmwtbq9, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=3070, state=4, num_pkts=10, num_bytes_ip=2018, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.16374, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=]^J}, last_active=1254722770.692786, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=^M^J^M^J^M^J^M^J^M^J