├── CHANGES ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── VERSION ├── cmake ├── FindRabbitmqc.cmake ├── Findamqpcpp.cmake └── LibFindMacros.cmake ├── configure ├── configure.plugin ├── scripts ├── PS │ └── amqp │ │ └── __load__.bro ├── __load__.bro └── init.bro ├── src ├── Plugin.cc ├── Plugin.h ├── amqp.bif ├── amqp.cc ├── amqp.h ├── message_bus.cc └── message_bus.h └── tests ├── Makefile ├── Scripts └── get-bro-env ├── amqp ├── show-plugin.bro └── test_plugin.bro └── btest.cfg /CHANGES: -------------------------------------------------------------------------------- 1 | 1.0 - Aaron Eppert - Initial Release 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 2.8) 3 | 4 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 5 | 6 | project(Plugin) 7 | 8 | include(BroPlugin) 9 | 10 | # 11 | # rabbitmq-c 12 | # 13 | set(Rabbitmqc_DIR ../../common/rabbitmq-c/install/) 14 | find_package(Rabbitmqc REQUIRED) 15 | set(LIBS ${LIBS} Rabbitmqc_LIBRARIES) 16 | include_directories(BEFORE ${Rabbitmqc_INCLUDE_DIR}) 17 | message(STATUS "Found RabbitMQ library: ${Rabbitmqc_LIBRARIES}") 18 | 19 | # 20 | # amqpcpp 21 | # 22 | set(amqpcpp_DIR ../../common/amqpcpp/install/) 23 | find_package(amqpcpp REQUIRED) 24 | set(LIBS ${LIBS} amqpcpp_LIBRARIES) 25 | include_directories(BEFORE ${amqpcpp_INCLUDE_DIR}) 26 | set(INCLUDES ${INCLUDES} ${amqpcpp_INCLUDE_DIR}) 27 | message(STATUS "Found RabbitMQ library: ${amqpcpp_LIBRARIES}") 28 | 29 | 30 | if (amqpcpp_FOUND) 31 | bro_plugin_begin(PS amqp) 32 | bro_plugin_cc(src/Plugin.cc src/amqp.cc src/message_bus.cc) 33 | bro_plugin_bif(src/amqp.bif) 34 | bro_plugin_dist_files(README CHANGES COPYING VERSION) 35 | bro_plugin_link_library (${amqpcpp_LIBRARIES}) 36 | bro_plugin_link_library (${Rabbitmqc_LIBRARIES}) 37 | bro_plugin_end() 38 | else () 39 | message(FATAL_ERROR "amqpcpp not found.") 40 | endif () 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Convenience Makefile providing a few common top-level targets. 3 | # 4 | 5 | cmake_build_dir=build 6 | arch=`uname -s | tr A-Z a-z`-`uname -m` 7 | 8 | all: build-it 9 | 10 | build-it: 11 | @test -e $(cmake_build_dir)/config.status || ./configure 12 | -@test -e $(cmake_build_dir)/CMakeCache.txt && \ 13 | test $(cmake_build_dir)/CMakeCache.txt -ot `cat $(cmake_build_dir)/CMakeCache.txt | grep BRO_DIST | cut -d '=' -f 2`/build/CMakeCache.txt && \ 14 | echo Updating stale CMake cache && \ 15 | touch $(cmake_build_dir)/CMakeCache.txt 16 | 17 | ( cd $(cmake_build_dir) && make ) 18 | 19 | install: 20 | ( cd $(cmake_build_dir) && make install ) 21 | 22 | clean: 23 | ( cd $(cmake_build_dir) && make clean ) 24 | 25 | distclean: 26 | rm -rf $(cmake_build_dir) 27 | 28 | test: 29 | make -C tests 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![PacketSled Logo](https://packetsled.com/wp-content/themes/freshbiz/img/packetsled-logo.png) 2 | # PS::amqp - Bro Writer Plugin to Stream Data to an AMQP Server 3 | 4 | 5 | ## Introduction 6 | PS::amp is a plugin that provides support for writing data to an ``AMQP`` server. 7 | This plugin provides support the ``AMQP Protocol,`` specifically ``RabbitMQ.`` 8 | 9 | 10 | ## Prerequisites 11 | 12 | 1. AMQPCPP - ``https://github.com/akalend/amqpcpp`` 13 | 1. RabbitMQ-C - ``https://github.com/alanxz/rabbitmq-c`` 14 | 15 | 16 | ## Compilation and Installation 17 | 18 | cd /bro_amqp_plugin 19 | ./configure --bro-dist=$PATH_TO_SRC_TREE_FOR/bro 20 | make -j10 21 | make install 22 | 23 | ## Usage 24 | 25 | Using PS::amqp requires instantiating a Bro Log Filter as shown below. From there, a write to the created log will cause the plugin to send the data to the AMQP server. 26 | 27 | **Note**: "password" and "username" are in the appropriate order per the underlying libraries being used. 28 | 29 | ```bro 30 | event bro_init() { 31 | local filter: Log::Filter = [ 32 | $name="amqp", 33 | $config=table(["connstr"] = "password:username@localhost:5672", 34 | ["exchange"] = "our.direct", 35 | ["queue"] = "queue"), 36 | $writer=Log::WRITER_AMQP 37 | ]; 38 | 39 | Log::create_stream(amqp_test::LOG, [$columns=Info, $ev=log_amqp_test]); 40 | Log::add_filter(amqp_test::LOG, filter); 41 | Log::remove_filter(amqp_test::LOG, "default"); 42 | } 43 | ``` 44 | 45 | ## License 46 | 47 | GPL 48 | 49 | Copyright (c) 2015, Packetsled. All rights reserved. 50 | 51 | PS::amqp is free software: you can redistribute it and/or modify 52 | it under the terms of the GNU General Public License as published by 53 | the Free Software Foundation, either version 3 of the License, or 54 | (at your option) any later version. 55 | 56 | PS::amqp is distributed in the hope that it will be useful, 57 | but WITHOUT ANY WARRANTY; without even the implied warranty of 58 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 59 | GNU General Public License for more details. 60 | 61 | You should have received a copy of the GNU General Public License 62 | along with PS::amqp. If not, see . 63 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.0 2 | -------------------------------------------------------------------------------- /cmake/FindRabbitmqc.cmake: -------------------------------------------------------------------------------- 1 | #Find the Rabbitmq C library 2 | 3 | INCLUDE(LibFindMacros) 4 | 5 | # Find the include directories 6 | FIND_PATH(Rabbitmqc_INCLUDE_DIR 7 | NAMES amqp.h 8 | HINTS ${Rabbitmqc_DIR}/include 9 | ) 10 | 11 | FIND_LIBRARY(Rabbitmqc_LIBRARY 12 | NAMES rabbitmq 13 | HINTS ${Rabbitmqc_DIR}/lib 14 | ) 15 | 16 | SET(Rabbitmqc_PROCESS_INCLUDES Rabbitmqc_INCLUDE_DIR) 17 | SET(Rabbitmqc_PROCESS_LIBS Rabbitmqc_LIBRARY) 18 | 19 | LIBFIND_PROCESS(Rabbitmqc) 20 | 21 | find_file(_Rabbitmqc_SSL_HEADER 22 | NAMES amqp_ssl_socket.h 23 | PATHS ${Rabbitmqc_INCLUDE_DIR} 24 | NO_DEFAULT_PATH 25 | ) 26 | 27 | string(COMPARE NOTEQUAL "${_Rabbitmqc_SSL_HEADER}" 28 | "_Rabbitmqc_SSL_HEADER-NOTFOUND" _rmqc_ssl_enabled) 29 | 30 | set(Rabbitmqc_SSL_ENABLED ${_rmqc_ssl_enabled} CACHE BOOL 31 | "Rabbitmqc is SSL Enabled" FORCE) 32 | mark_as_advanced(_Rabbitmqc_SSL_HEADER Rabbitmqc_SSL_ENABLED) 33 | -------------------------------------------------------------------------------- /cmake/Findamqpcpp.cmake: -------------------------------------------------------------------------------- 1 | #Find the amqpcpp C++ library 2 | 3 | INCLUDE(LibFindMacros) 4 | 5 | # Find the include directories 6 | FIND_PATH(amqpcpp_INCLUDE_DIR 7 | NAMES AMQPcpp.h 8 | HINTS ${amqpcpp_DIR}/include 9 | ) 10 | 11 | FIND_LIBRARY(amqpcpp_LIBRARY 12 | NAMES amqpcpp 13 | HINTS ${amqpcpp_DIR}/lib 14 | ) 15 | 16 | SET(amqpcpp_PROCESS_INCLUDES amqpcpp_INCLUDE_DIR) 17 | SET(amqpcpp_PROCESS_LIBS amqpcpp_LIBRARY) 18 | 19 | LIBFIND_PROCESS(amqpcpp) 20 | 21 | -------------------------------------------------------------------------------- /cmake/LibFindMacros.cmake: -------------------------------------------------------------------------------- 1 | # Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments 2 | # used for the current package. For this to work, the first parameter must be the 3 | # prefix of the current package, then the prefix of the new package etc, which are 4 | # passed to find_package. 5 | macro (libfind_package PREFIX) 6 | set (LIBFIND_PACKAGE_ARGS ${ARGN}) 7 | if (${PREFIX}_FIND_QUIETLY) 8 | set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET) 9 | endif (${PREFIX}_FIND_QUIETLY) 10 | if (${PREFIX}_FIND_REQUIRED) 11 | set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED) 12 | endif (${PREFIX}_FIND_REQUIRED) 13 | find_package(${LIBFIND_PACKAGE_ARGS}) 14 | endmacro (libfind_package) 15 | 16 | # CMake developers made the UsePkgConfig system deprecated in the same release (2.6) 17 | # where they added pkg_check_modules. Consequently I need to support both in my scripts 18 | # to avoid those deprecated warnings. Here's a helper that does just that. 19 | # Works identically to pkg_check_modules, except that no checks are needed prior to use. 20 | macro (libfind_pkg_check_modules PREFIX PKGNAME) 21 | if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 22 | include(UsePkgConfig) 23 | pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS) 24 | else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 25 | find_package(PkgConfig) 26 | if (PKG_CONFIG_FOUND) 27 | pkg_check_modules(${PREFIX} ${PKGNAME}) 28 | endif (PKG_CONFIG_FOUND) 29 | endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 30 | endmacro (libfind_pkg_check_modules) 31 | 32 | # Do the final processing once the paths have been detected. 33 | # If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain 34 | # all the variables, each of which contain one include directory. 35 | # Ditto for ${PREFIX}_PROCESS_LIBS and library files. 36 | # Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. 37 | # Also handles errors in case library detection was required, etc. 38 | macro (libfind_process PREFIX) 39 | # Skip processing if already processed during this run 40 | if (NOT ${PREFIX}_FOUND) 41 | # Start with the assumption that the library was found 42 | set (${PREFIX}_FOUND TRUE) 43 | 44 | # Process all includes and set _FOUND to false if any are missing 45 | foreach (i ${${PREFIX}_PROCESS_INCLUDES}) 46 | if (${i}) 47 | set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}}) 48 | mark_as_advanced(${i}) 49 | else (${i}) 50 | set (${PREFIX}_FOUND FALSE) 51 | endif (${i}) 52 | endforeach (i) 53 | 54 | # Process all libraries and set _FOUND to false if any are missing 55 | foreach (i ${${PREFIX}_PROCESS_LIBS}) 56 | if (${i}) 57 | set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}}) 58 | mark_as_advanced(${i}) 59 | else (${i}) 60 | set (${PREFIX}_FOUND FALSE) 61 | endif (${i}) 62 | endforeach (i) 63 | 64 | # Print message and/or exit on fatal error 65 | if (${PREFIX}_FOUND) 66 | if (NOT ${PREFIX}_FIND_QUIETLY) 67 | message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}") 68 | endif (NOT ${PREFIX}_FIND_QUIETLY) 69 | else (${PREFIX}_FOUND) 70 | if (${PREFIX}_FIND_REQUIRED) 71 | foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS}) 72 | message("${i}=${${i}}") 73 | endforeach (i) 74 | message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.") 75 | endif (${PREFIX}_FIND_REQUIRED) 76 | endif (${PREFIX}_FOUND) 77 | endif (NOT ${PREFIX}_FOUND) 78 | endmacro (libfind_process) 79 | 80 | macro(libfind_library PREFIX basename) 81 | set(TMP "") 82 | if(MSVC80) 83 | set(TMP -vc80) 84 | endif(MSVC80) 85 | if(MSVC90) 86 | set(TMP -vc90) 87 | endif(MSVC90) 88 | set(${PREFIX}_LIBNAMES ${basename}${TMP}) 89 | if(${ARGC} GREATER 2) 90 | set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2}) 91 | string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES}) 92 | set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP}) 93 | endif(${ARGC} GREATER 2) 94 | find_library(${PREFIX}_LIBRARY 95 | NAMES ${${PREFIX}_LIBNAMES} 96 | PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS} 97 | ) 98 | endmacro(libfind_library) 99 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Wrapper for viewing/setting options that the plugin's CMake 4 | # scripts will recognize. 5 | # 6 | # Don't edit this. Edit configure.plugin to add plugin-specific options. 7 | # 8 | 9 | set -e 10 | command="$0 $*" 11 | 12 | if [ -e `dirname $0`/configure.plugin ]; then 13 | # Include custom additions. 14 | . `dirname $0`/configure.plugin 15 | fi 16 | 17 | # Check for `cmake` command. 18 | type cmake > /dev/null 2>&1 || { 19 | echo "\ 20 | This package requires CMake, please install it first, then you may 21 | use this configure script to access CMake equivalent functionality.\ 22 | " >&2; 23 | exit 1; 24 | } 25 | 26 | usage() { 27 | 28 | cat 1>&2 </dev/null 2>&1; then 37 | plugin_usage 1>&2 38 | fi 39 | 40 | echo 41 | 42 | exit 1 43 | } 44 | 45 | # Function to append a CMake cache entry definition to the 46 | # CMakeCacheEntries variable 47 | # $1 is the cache entry variable name 48 | # $2 is the cache entry variable type 49 | # $3 is the cache entry variable value 50 | append_cache_entry () { 51 | CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3" 52 | } 53 | 54 | # set defaults 55 | builddir=build 56 | brodist=`cd ../../.. && pwd` 57 | installroot="default" 58 | CMakeCacheEntries="" 59 | 60 | while [ $# -ne 0 ]; do 61 | case "$1" in 62 | -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; 63 | *) optarg= ;; 64 | esac 65 | 66 | case "$1" in 67 | --help|-h) 68 | usage 69 | ;; 70 | 71 | --bro-dist=*) 72 | brodist=`cd $optarg && pwd` 73 | ;; 74 | 75 | --install-root=*) 76 | installroot=$optarg 77 | ;; 78 | 79 | *) 80 | if type -t plugin_option >/dev/null 2>&1; then 81 | plugin_option $1 && shift && continue; 82 | fi 83 | 84 | echo "Invalid option '$1'. Try $0 --help to see available options." 85 | exit 1 86 | ;; 87 | esac 88 | shift 89 | done 90 | 91 | if [ ! -e "$brodist/bro-path-dev.in" ]; then 92 | echo "Cannot determine Bro source directory, use --bro-dist=DIR." 93 | exit 1 94 | fi 95 | 96 | append_cache_entry BRO_DIST PATH $brodist 97 | append_cache_entry CMAKE_MODULE_PATH PATH $brodist/cmake 98 | 99 | if [ "$installroot" != "default" ]; then 100 | mkdir -p $installroot 101 | append_cache_entry BRO_PLUGIN_INSTALL_ROOT PATH $installroot 102 | fi 103 | 104 | echo "Build Directory : $builddir" 105 | echo "Bro Source Directory : $brodist" 106 | 107 | mkdir -p $builddir 108 | cd $builddir 109 | 110 | cmake $CMakeCacheEntries .. 111 | 112 | echo "# This is the command used to configure this build" > config.status 113 | echo $command >> config.status 114 | chmod u+x config.status 115 | -------------------------------------------------------------------------------- /configure.plugin: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Hooks to add custom options to the configure script. 4 | # 5 | 6 | plugin_usage() 7 | { 8 | : # Do nothing 9 | # cat <//__load__.bro instead. 8 | # 9 | 10 | @load ./init.bro 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /scripts/init.bro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mixmodeai/bro_amqp_plugin/48000a56936a66557e7b431a3b1fbad0e269ec8f/scripts/init.bro -------------------------------------------------------------------------------- /src/Plugin.cc: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of bro_amqp_plugin. 3 | 4 | Copyright (c) 2015, Packetsled. All rights reserved. 5 | 6 | tcplog is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | tcplog is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with tcplog. If not, see . 18 | 19 | */ 20 | // Aaron Eppert - PacketSled - 2015 21 | 22 | #include 23 | #include 24 | #include "Plugin.h" 25 | #include "message_bus.h" 26 | 27 | namespace plugin { 28 | namespace PS_amqp { 29 | Plugin plugin; 30 | } 31 | } 32 | 33 | Plugin::Plugin() { 34 | } 35 | 36 | Plugin::~Plugin() { 37 | 38 | } 39 | 40 | void Plugin::InitPostScript() { 41 | ::plugin::Plugin::InitPostScript(); 42 | } 43 | 44 | void Plugin::Done() { 45 | ::plugin::Plugin::Done(); 46 | } 47 | 48 | WriterBackend* Plugin::Instantiate(WriterFrontend* frontend) { 49 | //std::cout << "AMQP - Plugin::Instantiate(" << frontend << ")" << std::endl; 50 | 51 | return new ::logging::writer::amqp(frontend); 52 | } 53 | 54 | plugin::Configuration Plugin::Configure() { 55 | AddComponent(new ::logging::Component("amqp", Plugin::Instantiate)); 56 | 57 | plugin::Configuration config; 58 | config.name = "PS::amqp"; 59 | config.description = "PacketSled AMQP Plug-in for Bro"; 60 | config.version.major = 1; 61 | config.version.minor = 0; 62 | return config; 63 | } 64 | -------------------------------------------------------------------------------- /src/Plugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of bro_amqp_plugin. 3 | 4 | Copyright (c) 2015, Packetsled. All rights reserved. 5 | 6 | tcplog is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | tcplog is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with tcplog. If not, see . 18 | 19 | */ 20 | // Aaron Eppert - PacketSled - 2015 21 | #ifndef BRO_PLUGIN_PS_AMQP 22 | #define BRO_PLUGIN_PS_AMQP 23 | 24 | #include "logging/WriterBackend.h" 25 | #include 26 | #include 27 | #include "amqp.h" 28 | #include "message_bus.h" 29 | 30 | using namespace plugin::PS_amqp; 31 | using namespace logging; 32 | 33 | namespace plugin { 34 | namespace PS_amqp { 35 | 36 | class Plugin : public ::plugin::Plugin { 37 | public: 38 | Plugin(); 39 | ~Plugin(); 40 | static WriterBackend* Instantiate(WriterFrontend* frontend); 41 | virtual void InitPostScript(); 42 | virtual void Done(); 43 | protected: 44 | // Overridden from plugin::Plugin. 45 | virtual plugin::Configuration Configure(); 46 | private: 47 | }; 48 | 49 | extern Plugin plugin; 50 | } 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /src/amqp.bif: -------------------------------------------------------------------------------- 1 | # Options for the AMQP writer 2 | 3 | module PS_amqp; 4 | 5 | -------------------------------------------------------------------------------- /src/amqp.cc: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of bro_amqp_plugin. 3 | 4 | Copyright (c) 2015, Packetsled. All rights reserved. 5 | 6 | tcplog is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | tcplog is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with tcplog. If not, see . 18 | 19 | */ 20 | // Aaron Eppert - PacketSled - 2015 21 | #include "config.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "amqp.h" 29 | #include "threading/MsgThread.h" 30 | #include "threading/formatters/JSON.h" 31 | #include "threading/formatters/Ascii.h" 32 | #include "threading/SerialTypes.h" 33 | 34 | using namespace plugin::PS_amqp; 35 | using namespace logging; 36 | using namespace writer; 37 | using namespace std; 38 | 39 | using threading::Value; 40 | using threading::Field; 41 | 42 | amqp::amqp(WriterFrontend* frontend) : 43 | WriterBackend(frontend) { 44 | json = new threading::formatter::JSON(this, 45 | threading::formatter::JSON::TS_EPOCH); 46 | } 47 | 48 | amqp::~amqp() { 49 | if (json) { 50 | delete json; 51 | } 52 | 53 | if (message_bus_pub) { 54 | delete message_bus_pub; 55 | } 56 | } 57 | 58 | std::string amqp::GetTableType(int arg_type, int arg_subtype) { 59 | std::string type; 60 | 61 | switch (arg_type) { 62 | case TYPE_BOOL: 63 | type = "boolean"; 64 | break; 65 | 66 | case TYPE_INT: 67 | case TYPE_COUNT: 68 | case TYPE_COUNTER: 69 | case TYPE_PORT: 70 | type = "integer"; 71 | break; 72 | 73 | case TYPE_SUBNET: 74 | case TYPE_ADDR: 75 | type = "text"; 76 | break; 77 | 78 | case TYPE_TIME: 79 | case TYPE_INTERVAL: 80 | case TYPE_DOUBLE: 81 | type = "double precision"; 82 | break; 83 | 84 | case TYPE_ENUM: 85 | case TYPE_STRING: 86 | case TYPE_FILE: 87 | case TYPE_FUNC: 88 | type = "text"; 89 | break; 90 | 91 | case TYPE_TABLE: 92 | case TYPE_VECTOR: 93 | type = "text"; 94 | break; 95 | 96 | default: 97 | type = Fmt("%d", arg_type); 98 | } 99 | 100 | return type; 101 | } 102 | 103 | // returns true true in case of error 104 | bool amqp::checkError(int code) { 105 | // if (code != SQLITE_OK && code != SQLITE_DONE) { 106 | // Error(Fmt("SQLite call failed: %s", sqlite3_errmsg(db))); 107 | // return true; 108 | // } 109 | 110 | return false; 111 | } 112 | 113 | bool amqp::Init(void) 114 | { 115 | if(message_bus_connstr.empty() || message_bus_exchange.empty() || 116 | message_bus_queue.empty() || probeid.empty() || envid.empty() ) { 117 | return false; 118 | } 119 | 120 | try { 121 | 122 | path = Fmt("\"sensor\": \"probe_%s_%s\",", envid.c_str(), probeid.c_str()); 123 | 124 | /* 125 | if (info_path.length() > 0 ) { 126 | path = Fmt("\"sensor\": \"probe_%s_%s\", \"log\": \"%s\",", 127 | envid.c_str(), probeid.c_str(), info_path.c_str()); 128 | } else { 129 | 130 | } 131 | */ 132 | 133 | message_bus_pub = new plugin::PS_amqp::message_bus_publisher( 134 | message_bus_connstr, message_bus_exchange, message_bus_queue); 135 | if (!message_bus_pub) { 136 | return false; 137 | } 138 | 139 | message_bus_pub->initialize(); 140 | 141 | return true; 142 | } catch (AMQPException e) { 143 | MsgThread::Info(Fmt("PS_amqp - Init - AMQPException: %s", e.getMessage().c_str())); 144 | ReInit(); 145 | } catch (const std::exception &exc) { 146 | MsgThread::Info(Fmt("PS_amqp - Init - std::exception: %s ", exc.what())); 147 | ReInit(); 148 | } catch(...) { 149 | MsgThread::Info("PS_amqp - Init - Exception found"); 150 | ReInit(); 151 | } 152 | 153 | return false; 154 | } 155 | 156 | bool amqp::ReInit(void) 157 | { 158 | bool ret = false; 159 | 160 | if(message_bus_connstr.empty() || message_bus_exchange.empty() || 161 | message_bus_queue.empty() || probeid.empty() || envid.empty() ) { 162 | return false; 163 | } 164 | 165 | try { 166 | if(message_bus_pub) { 167 | MsgThread::Info("PS_amqp - Attempt to reinitialize"); 168 | if (message_bus_pub) { 169 | delete message_bus_pub; 170 | } 171 | sleep(AMQP_RETRY_INTERVAL); 172 | Init(); 173 | } 174 | } catch(...) { 175 | MsgThread::Info("PS_amqp - Exception found"); 176 | } 177 | 178 | return true; 179 | } 180 | 181 | bool amqp::DoInit(const WriterInfo& info, int arg_num_fields, 182 | const Field* const * arg_fields) 183 | { 184 | bool ret = false; 185 | 186 | WriterInfo::config_map::const_iterator it; 187 | num_fields = arg_num_fields; 188 | fields = arg_fields; 189 | 190 | try { 191 | it = info.config.find("connstr"); 192 | if (it == info.config.end()) { 193 | MsgThread::Info(Fmt("connstr configuration option not found")); 194 | return false; 195 | } else { 196 | message_bus_connstr = it->second; 197 | } 198 | 199 | it = info.config.find("exchange"); 200 | if (it == info.config.end()) { 201 | MsgThread::Info(Fmt("exchange configuration option not found")); 202 | return false; 203 | } else { 204 | message_bus_exchange = it->second; 205 | } 206 | 207 | it = info.config.find("queue"); 208 | if (it == info.config.end()) { 209 | MsgThread::Info(Fmt("queue configuration option not found")); 210 | return false; 211 | } else { 212 | message_bus_queue = it->second; 213 | } 214 | 215 | it = info.config.find("probeid"); 216 | if (it == info.config.end()) { 217 | MsgThread::Info(Fmt("probeid configuration option not found")); 218 | return false; 219 | } else { 220 | probeid = it->second; 221 | } 222 | 223 | it = info.config.find("envid"); 224 | if (it == info.config.end()) { 225 | MsgThread::Info(Fmt("envid configuration option not found")); 226 | return false; 227 | } else { 228 | envid = it->second; 229 | } 230 | 231 | info_path = info.path; 232 | 233 | return Init(); 234 | } catch (...) { 235 | MsgThread::Info("PS_amqp - DoInit - Exception found"); 236 | } 237 | 238 | return false; 239 | } 240 | 241 | bool amqp::odesc_to_string_writer(const ODesc &buffer, bool add_log_path) { 242 | bool ret = false; 243 | 244 | std::string out_buf = std::string(reinterpret_cast(buffer.Bytes())); 245 | out_buf = out_buf.insert(1, path); 246 | 247 | if (add_log_path) { 248 | out_buf = out_buf.insert(1, Fmt("\"log\": \"%s\",", info_path.c_str())); 249 | } 250 | 251 | try { 252 | if (!out_buf.empty()) { 253 | message_bus_pub->publish(out_buf); 254 | ret = true; 255 | } 256 | } catch (AMQPException e) { 257 | MsgThread::Info(Fmt("PS_amqp - odesc_to_string_writer(\"%s\") - AMQPException: %s", 258 | out_buf.c_str(), e.getMessage().c_str())); 259 | ReInit(); 260 | } catch (...) { 261 | MsgThread::Info("PS_amqp - odesc_to_string_writer - Exception found"); 262 | } 263 | 264 | return true; 265 | } 266 | 267 | bool amqp::DoWrite(int num_fields, const Field* const * fields, Value** vals) { 268 | try { 269 | bool add_log_path = true; 270 | 271 | if (message_bus_pub) { 272 | ODesc buffer; 273 | 274 | for ( int j = 0; j < num_fields; j++ ) { 275 | const threading::Field* field = fields[j]; 276 | if ( strncasecmp(field->name, "log", 3) == 0 ) { 277 | #if 0 278 | MsgThread::Info("Found existing \"log\" attribute - using instead of default"); 279 | #endif // 0 280 | add_log_path = false; 281 | break; 282 | } 283 | } 284 | 285 | json->Describe(&buffer, num_fields, fields, vals); 286 | odesc_to_string_writer(buffer, add_log_path); 287 | } 288 | } catch (...) { 289 | MsgThread::Info("PS_amqp - DoWrite - Exception found"); 290 | } 291 | return true; 292 | } 293 | 294 | bool amqp::DoRotate(const char* rotated_path, double open, double close, 295 | bool terminating) { 296 | if (!FinishedRotation("/dev/null", Info().path, open, close, terminating)) { 297 | Error(Fmt("error rotating %s", Info().path)); 298 | return false; 299 | } 300 | 301 | return true; 302 | } 303 | -------------------------------------------------------------------------------- /src/amqp.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of bro_amqp_plugin. 3 | 4 | Copyright (c) 2015, Packetsled. All rights reserved. 5 | 6 | tcplog is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | tcplog is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with tcplog. If not, see . 18 | 19 | */ 20 | // Aaron Eppert - PacketSled - 2015 21 | // 22 | // Log writer for AMQP logs. 23 | // 24 | 25 | #ifndef LOGGING_WRITER_AMQP_H 26 | #define LOGGING_WRITER_AMQP_H 27 | 28 | #include "config.h" 29 | 30 | #include 31 | #include "logging/WriterBackend.h" 32 | #include "threading/formatters/JSON.h" 33 | #include "message_bus.h" 34 | #include 35 | 36 | using namespace std; 37 | 38 | #define AMQP_RETRY_INTERVAL 120 39 | 40 | namespace logging { 41 | namespace writer { 42 | class amqp : public WriterBackend { 43 | public: 44 | amqp(WriterFrontend* frontend); 45 | ~amqp(); 46 | 47 | static WriterBackend* Instantiate(WriterFrontend* frontend) { 48 | return new amqp(frontend); 49 | } 50 | 51 | bool Init(void); 52 | bool ReInit(void); 53 | 54 | protected: 55 | virtual bool DoInit(const WriterInfo& info, int arg_num_fields, const threading::Field* const* arg_fields); 56 | virtual bool DoWrite(int num_fields, const threading::Field* const* fields, threading::Value** vals); 57 | virtual bool DoSetBuf(bool enabled) { return true; } 58 | virtual bool DoRotate(const char* rotated_path, double open, double close, bool terminating); 59 | virtual bool DoFlush(double network_time) { return true; } 60 | virtual bool DoFinish(double network_time) { return true; } 61 | virtual bool DoHeartbeat(double network_time, double current_time) { return true; } 62 | 63 | private: 64 | bool checkError(int code); 65 | 66 | int AddParams(threading::Value* val, int pos); 67 | std::string GetTableType(int, int); 68 | 69 | const threading::Field* const *fields; // raw mapping 70 | unsigned int num_fields; 71 | 72 | plugin::PS_amqp::message_bus_publisher *message_bus_pub; 73 | threading::formatter::JSON *json; 74 | 75 | bool odesc_to_string_writer(const ODesc &buffer, bool add_log_path); 76 | 77 | std::string info_path; 78 | std::string path; 79 | std::string message_bus_connstr; 80 | std::string message_bus_exchange; 81 | std::string message_bus_queue; 82 | std::string probeid; 83 | std::string envid; 84 | 85 | }; 86 | } 87 | } 88 | 89 | #endif // LOGGING_WRITER_AMQP_H 90 | -------------------------------------------------------------------------------- /src/message_bus.cc: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of bro_amqp_plugin. 3 | 4 | Copyright (c) 2015, Packetsled. All rights reserved. 5 | 6 | tcplog is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | tcplog is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with tcplog. If not, see . 18 | 19 | */ 20 | // Aaron Eppert - PacketSled - 2015 21 | #include "message_bus.h" 22 | 23 | //using namespace plugin::PS_amqp; 24 | 25 | // 26 | // connStr -> ":@:" 27 | // 28 | plugin::PS_amqp::message_bus_publisher::message_bus_publisher(std::string connStr, std::string _exchange, std::string _queue) : 29 | amqp(connStr), exchange(_exchange), queue(_queue) 30 | { 31 | // std::cout << "message_bus_publisher::message_bus_publisher(" << connStr << "," << _exchange << "," << _queue << ")" << std::endl; 32 | } 33 | 34 | plugin::PS_amqp::message_bus_publisher::~message_bus_publisher() 35 | { 36 | 37 | } 38 | 39 | void plugin::PS_amqp::message_bus_publisher::initialize() 40 | { 41 | if(!exchange.empty()) { 42 | ex = amqp.createExchange(exchange); 43 | 44 | // Force the disabling of the immediate flag. Yes.. it is misspelled 45 | // by the authors. 46 | ex->setParam(~AMQP_IMMIDIATE); 47 | 48 | ex->setHeader("Delivery-mode", 2); 49 | ex->setHeader("Content-type", "application/json"); 50 | ex->setHeader("Content-encoding", "UTF-8"); 51 | } 52 | } 53 | 54 | void plugin::PS_amqp::message_bus_publisher::publish(std::string msg) 55 | { 56 | // std::cout << "PS_amqp - message_bus_publisher::publish - msg = " << msg << std::endl; 57 | 58 | if(!queue.empty()) { 59 | ex->Publish(msg, queue); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/message_bus.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of bro_amqp_plugin. 3 | 4 | Copyright (c) 2015, Packetsled. All rights reserved. 5 | 6 | tcplog is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | tcplog is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with tcplog. If not, see . 18 | 19 | */ 20 | // Aaron Eppert - PacketSled - 2015 21 | #ifndef PS_AMQP_MESSAGE_BUS_HPP 22 | #define PS_AMQP_MESSAGE_BUS_HPP 23 | 24 | #include 25 | #include "threading/SerialTypes.h" 26 | #include "AMQPcpp.h" 27 | 28 | using namespace std; 29 | 30 | namespace plugin { 31 | namespace PS_amqp { 32 | class message_bus_publisher { 33 | public: 34 | message_bus_publisher(std::string connStr, std::string _exchange, std::string _queue); 35 | ~message_bus_publisher(); 36 | void initialize(); 37 | void publish(std::string msg); 38 | private: 39 | AMQP amqp; 40 | AMQPExchange *ex; 41 | std::string exchange; 42 | std::string queue; 43 | }; 44 | } 45 | } 46 | #endif // PS_AMQP_MESSAGE_BUS_HPP 47 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test: 3 | @btest 4 | -------------------------------------------------------------------------------- /tests/Scripts/get-bro-env: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # BTest helper for getting values for Bro-related environment variables. 4 | 5 | base=`dirname $0` 6 | bro=`cat ${base}/../../build/CMakeCache.txt | grep BRO_DIST | cut -d = -f 2` 7 | 8 | if [ "$1" = "brobase" ]; then 9 | echo ${bro} 10 | elif [ "$1" = "bropath" ]; then 11 | ${bro}/build/bro-path-dev 12 | elif [ "$1" = "bro_plugin_path" ]; then 13 | ( cd ${base}/../.. && pwd ) 14 | elif [ "$1" = "bro_seed_file" ]; then 15 | echo ${bro}/testing/btest/random.seed 16 | elif [ "$1" = "path" ]; then 17 | echo ${bro}/build/src:${bro}/aux/btest:${base}/:${bro}/aux/bro-cut:$PATH 18 | else 19 | echo "usage: `basename $0` " >&2 20 | exit 1 21 | fi 22 | -------------------------------------------------------------------------------- /tests/amqp/show-plugin.bro: -------------------------------------------------------------------------------- 1 | # @TEST-EXEC: bro -NN PS::amqp >output 2 | # @TEST-EXEC: btest-diff output 3 | -------------------------------------------------------------------------------- /tests/amqp/test_plugin.bro: -------------------------------------------------------------------------------- 1 | 2 | module amqp_test; 3 | 4 | export { 5 | type Info: record { 6 | uid: string &log; 7 | ts: time &log; 8 | }; 9 | 10 | redef enum Log::ID += { LOG }; 11 | 12 | # Define a hook event. By convention, this is called 13 | # "log_". 14 | global log_amqp_test: event(rec: Info); 15 | } 16 | 17 | event bro_init() { 18 | local filter: Log::Filter = [ 19 | $name="amqp", 20 | $config=table(["connstr"] = "password:username@localhost:5672", 21 | ["exchange"] = "our.direct", 22 | ["queue"] = "queue"), 23 | $writer=Log::WRITER_AMQP 24 | ]; 25 | 26 | Log::create_stream(amqp_test::LOG, [$columns=Info, $ev=log_amqp_test]); 27 | Log::add_filter(amqp_test::LOG, filter); 28 | Log::remove_filter(amqp_test::LOG, "default"); 29 | } 30 | 31 | event new_connection(c: connection) { 32 | local tmp: Info = [ $uid=c$uid, 33 | $ts=c$start_time ]; 34 | 35 | Log::write(amqp_test::LOG, tmp); 36 | } 37 | -------------------------------------------------------------------------------- /tests/btest.cfg: -------------------------------------------------------------------------------- 1 | [btest] 2 | TestDirs = amqp 3 | TmpDir = %(testbase)s/.tmp 4 | BaselineDir = %(testbase)s/Baseline 5 | IgnoreDirs = .svn CVS .tmp 6 | IgnoreFiles = *.tmp *.swp #* *.trace .DS_Store 7 | 8 | [environment] 9 | BROBASE=`%(testbase)s/Scripts/get-bro-env brobase` 10 | BROPATH=`%(testbase)s/Scripts/get-bro-env bropath` 11 | BRO_PLUGIN_PATH=`%(testbase)s/Scripts/get-bro-env bro_plugin_path` 12 | BRO_SEED_FILE=`%(testbase)s/Scripts/get-bro-env bro_seed_file` 13 | PATH=`%(testbase)s/Scripts/get-bro-env path` 14 | TZ=UTC 15 | LC_ALL=C 16 | TRACES=%(testbase)s/Traces 17 | TMPDIR=%(testbase)s/.tmp 18 | BRO_TRACES=`%(testbase)s/Scripts/get-bro-env brobase`/testing/btest/Traces 19 | TEST_DIFF_CANONIFIER=`%(testbase)s/Scripts/get-bro-env brobase`/testing/scripts/diff-canonifier 20 | --------------------------------------------------------------------------------