├── README.md ├── bro_policy └── README ├── docs └── images │ ├── .svn │ ├── all-wcprops │ ├── entries │ ├── prop-base │ │ └── AuditRawDataFlow.png.svn-base │ └── text-base │ │ └── AuditRawDataFlow.png.svn-base │ ├── AuditRawDataFlow.png │ └── DataStructOrganization.png ├── log_normalizer ├── LICENSE.inotail ├── LICENSE.stringencoders ├── Makefile ├── README ├── README-original ├── auditparse.1 ├── auditparse.c ├── auditparse.h ├── changelog-original ├── inotify-syscalls.h ├── inotify.h ├── modp_burl.c ├── modp_burl.h ├── modp_burl_data.h └── modp_stdint.h ├── log_normalizer_DEPRECATED ├── EXECVE_OBJ.py ├── GENERIC_OBJ.py ├── PLACE_OBJ.py ├── SOCK_OBJ.py ├── SYSCALL_OBJ.py ├── USER_OBJ.py ├── normalize_auditd.py ├── tail.py └── util.py └── system_config ├── audit.rules └── auditd.conf /README.md: -------------------------------------------------------------------------------- 1 | Directory structure looks like: 2 | bro_policy 3 | Former location of bro policy for digesting logs. Moved to it's own repo for now. 4 | 5 | docs 6 | Just some pics to keep track of the data flow. 7 | 8 | log_normalizer 9 | c-Based log normalizer script - see README for details. More docs coming... 10 | 11 | log_normalizer_deprecated 12 | Python script to take the output from the auditd logs and make them somewhat more machine parsable. Please note that this program leaks memory badly based on some interactions between python < 3.3 and libc. Since the audit-libs-python.x86_64 package seems to have issues with python 3.x I have given up hope for this. 13 | 14 | system_config 15 | Sample config files for the /etc/audit directory which will control the behavior of auditd (auditd.conf) and what will get recorded by the system reporting (audit.rules). 16 | 17 | 18 | -------------------------------------------------------------------------------- /bro_policy/README: -------------------------------------------------------------------------------- 1 | For usability I have decoupled the core data creation functionality 2 | located in the auditdBroFramework repo (this one), and put it in: 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/images/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 34 4 | /svn/!svn/ver/18/trunk/docs/images 5 | END 6 | AuditRawDataFlow.png 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 55 10 | /svn/!svn/ver/18/trunk/docs/images/AuditRawDataFlow.png 11 | END 12 | -------------------------------------------------------------------------------- /docs/images/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 18 5 | https://auditd-ids-framework.googlecode.com/svn/trunk/docs/images 6 | https://auditd-ids-framework.googlecode.com/svn 7 | 8 | 9 | 10 | 2013-04-29T18:59:12.297821Z 11 | 18 12 | scampbell@lbl.gov 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | c0157cc6-dc50-384f-05ab-bff4ea8d2473 28 | 29 | AuditRawDataFlow.png 30 | file 31 | 32 | 33 | 34 | 35 | 2013-04-29T18:58:39.000000Z 36 | b4ed97a88cea3d021d20746a3d2654dd 37 | 2013-04-29T18:59:12.297821Z 38 | 18 39 | scampbell@lbl.gov 40 | has-props 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 39101 62 | 63 | -------------------------------------------------------------------------------- /docs/images/.svn/prop-base/AuditRawDataFlow.png.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mime-type 3 | V 24 4 | application/octet-stream 5 | END 6 | -------------------------------------------------------------------------------- /docs/images/.svn/text-base/AuditRawDataFlow.png.svn-base: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/set-element/auditdBroFramework/2e43b42d1af1009e8891bb97991026eb24025af7/docs/images/.svn/text-base/AuditRawDataFlow.png.svn-base -------------------------------------------------------------------------------- /docs/images/AuditRawDataFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/set-element/auditdBroFramework/2e43b42d1af1009e8891bb97991026eb24025af7/docs/images/AuditRawDataFlow.png -------------------------------------------------------------------------------- /docs/images/DataStructOrganization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/set-element/auditdBroFramework/2e43b42d1af1009e8891bb97991026eb24025af7/docs/images/DataStructOrganization.png -------------------------------------------------------------------------------- /log_normalizer/LICENSE.inotail: -------------------------------------------------------------------------------- 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 | 294 | Copyright (C) 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 | , 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 | -------------------------------------------------------------------------------- /log_normalizer/LICENSE.stringencoders: -------------------------------------------------------------------------------- 1 | * ------------------------------------------------------------------------------ 2 | * Additional URL encoding code taken from stringcoders-v3.10.3 source. Thanks! 3 | * ------------------------------------------------------------------------------ 4 | * http://code.google.com/p/stringencoders/ 5 | * 6 | * Copyright © 2006,2007 Nick Galbreath -- nickg [at] modp [dot] com 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are 11 | * met: 12 | * 13 | * Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 16 | * Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 20 | * Neither the name of the modp.com nor the names of its 21 | * contributors may be used to endorse or promote products derived from 22 | * this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | * 36 | * This is the standard "new" BSD license: 37 | * http://www.opensource.org/licenses/bsd-license.php 38 | -------------------------------------------------------------------------------- /log_normalizer/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for auditparse 2 | # 3 | # Copyright (C) 2006-2007 Tobias Klauser 4 | # 5 | # Licensed under the terms of the GNU General Public License; version 2 or later. 6 | 7 | VERSION = 0.5 8 | 9 | # Paths 10 | prefix = /usr/local 11 | BINDIR = $(prefix)/bin 12 | MANDIR = $(prefix)/share/man/man1 13 | 14 | CC := gcc -laudit -lauparse 15 | CFLAGS := $(CFLAGS) -pipe -D_USE_SOURCE -DVERSION="\"$(VERSION)\"" -W -Wall \ 16 | -Wstrict-prototypes -Wsign-compare -Wshadow -Wchar-subscripts \ 17 | -Wmissing-declarations -Wpointer-arith -Wcast-align -Wmissing-prototypes -laudit -lauparse 18 | 19 | # Compile with 'make DEBUG=true' to enable debugging 20 | DEBUG = false 21 | ifeq ($(strip $(DEBUG)),true) 22 | CFLAGS += -g -DDEBUG 23 | endif 24 | 25 | all: auditparse 26 | auditparse: auditparse.o modp_burl.o 27 | modp_burl: modp_burl.o 28 | 29 | %.o: %.c %.h 30 | $(CC) $(CFLAGS) -c $< -o $@ 31 | 32 | install: auditparse 33 | install -m 775 -D auditparse $(BINDIR)/auditparse 34 | install -m 644 -D auditparse.1 $(MANDIR)/auditparse 35 | gzip -9 $(MANDIR)/auditparse.1 36 | 37 | uninstall: 38 | rm $(BINDIR)/auditparse $(MANDIR)/auditparse.1* 39 | 40 | cscope: 41 | cscope -b 42 | 43 | clean: 44 | rm -f auditparse *.o cscope.* 45 | -------------------------------------------------------------------------------- /log_normalizer/README: -------------------------------------------------------------------------------- 1 | This program is a modified version of the inotail-0.5 program. The authors of that 2 | well behaved tool have nothing to do with this mess... 3 | 4 | The program will read/tail a raw auditd.log file and convert the contents to output which 5 | can be digested by the bro auditd framework project. All errors and problems are 6 | my own. 7 | 8 | Code has been taken from the auditd project - in particular the auparse program/library. 9 | Details can be found here: 10 | https://people.redhat.com/sgrubb/audit/ 11 | 12 | As well the URI encoding libraries have been taken from: 13 | http://code.google.com/p/stringencoders/ 14 | 15 | From that: 16 | 17 | * ------------------------------------------------------------------------------ 18 | * Additional URL encoding code taken from stringcoders-v3.10.3 source. Thanks! 19 | * ------------------------------------------------------------------------------ 20 | * http://code.google.com/p/stringencoders/ 21 | * 22 | * Copyright © 2006,2007 Nick Galbreath -- nickg [at] modp [dot] com 23 | * All rights reserved. 24 | * 25 | * Redistribution and use in source and binary forms, with or without 26 | * modification, are permitted provided that the following conditions are 27 | * met: 28 | * 29 | * Redistributions of source code must retain the above copyright 30 | * notice, this list of conditions and the following disclaimer. 31 | * 32 | * Redistributions in binary form must reproduce the above copyright 33 | * notice, this list of conditions and the following disclaimer in the 34 | * documentation and/or other materials provided with the distribution. 35 | * 36 | * Neither the name of the modp.com nor the names of its 37 | * contributors may be used to endorse or promote products derived from 38 | * this software without specific prior written permission. 39 | * 40 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 | * 52 | * This is the standard "new" BSD license: 53 | * http://www.opensource.org/licenses/bsd-license.php 54 | 55 | I am profoundly grateful to the developers of these tools and libraries 56 | as they did not ask for this to be done to their very nice codes ... 57 | -------------------------------------------------------------------------------- /log_normalizer/README-original: -------------------------------------------------------------------------------- 1 | inotail - inotify enhanced tail 2 | o===============================o 3 | 4 | inotail is a replacement for the 'tail' program found in the base installation 5 | of every Linux/UNIX system. It makes use of the inotify infrastructure in recent 6 | versions of the Linux kernel to speed up tailing files in the follow mode (the 7 | '-f' option). Standard tail polls the file every second by default while inotail 8 | listens to special events sent by the kernel through the inotify API to 9 | determine whether a file needs to be reread. 10 | 11 | Currently inotail is not fully compatible to neither POSIX or GNU tail but might 12 | be in the future. 13 | 14 | Requirements 15 | ------------ 16 | - Linux kernel 2.6.13 or higher with CONFIG_INOTIFY enabled 17 | - Standard C Library (tested with GNU libc but might work with others too) 18 | - GCC (other compilers might work but are not tested) 19 | 20 | Building and installing inotail 21 | ------------------------------- 22 | To build inotail type: 23 | 24 | $ make 25 | 26 | By default, inotail is installed to /usr/local/bin/, the manpage is installed to 27 | /usr/local/share/man/man1/. To install the inotail files to these locations type: 28 | 29 | $ make install 30 | 31 | To change these locations just set the prefix variable. E.g. to install the 32 | inotail binary to /usr/ and the manpage to /usr/share/man/ respectively type: 33 | 34 | $ make prefix=/usr install 35 | 36 | License 37 | ------- 38 | inotail is licensed under the terms of the GNU General Public License version 2 39 | or later. You can find the full text in the file LICENSE in the source tree of 40 | inotail. 41 | 42 | The files inotify.h and inotify-syscalls.h were taken from the source tree of 43 | the Linux kernel and slightly altered. Both are licensed under the terms of the 44 | GNU General Public License version 2. 45 | 46 | -- Tobias Klauser 47 | -------------------------------------------------------------------------------- /log_normalizer/auditparse.1: -------------------------------------------------------------------------------- 1 | '\" t 2 | .\" ** The above line should force tbl to be a preprocessor ** 3 | .\" Man page for inotail 4 | .\" 5 | .\" Copyright (c) 2006 Tobias Klauser 6 | .\" 7 | .\" You may distribute under the terms of the GNU General Public 8 | .\" License as specified in the file COPYING that comes with 9 | .\" inotail. 10 | 11 | .pc 12 | .TH INOTAIL 1 "2006-08-13" "" "Inotify enhanced tail" 13 | .SH NAME 14 | inotail \- A fast and lightweight version of tail using inotify 15 | .SH SYNOPSIS 16 | .B inotail 17 | [OPTION]... [FILE]... 18 | .SH DESCRIPTION 19 | .B inotail 20 | is a replacement for the 'tail' program found in the base installation of every 21 | Linux/UNIX system. It makes use of the inotify infrastructure in recent versions 22 | of the Linux kernel to speed up tailing files in the follow mode (the '\-f' 23 | option). Standard tail polls the file every second by default while inotail 24 | listens to special events sent by the kernel through the inotify API to 25 | determine whether a file needs to be reread. \fINote:\fR inotail will not work 26 | on systems running a kernel without inotify. To enable inotify, please set 27 | CONFIG_INOTIFY=y in your Linux kernel configuration and recompile it. 28 | .PP 29 | Currently inotail is not fully compatible to neither POSIX or GNU tail but might 30 | be in the future. 31 | .SH OPTIONS 32 | .TP 33 | .B \-c \fIN\fR, \fB\-\-bytes\fR=\fIN\fR 34 | output the last N bytes. If the first character of N is a '+', begin printing 35 | with the Nth character from the start of each file. 36 | .TP 37 | .B \-f, \fB\-\-follow 38 | keep the file(s) open and print appended data as the file grows 39 | .TP 40 | .B \-n \fIN\fR, \fB\-\-lines\fR=\fIN\fR 41 | output the last N lines (default: 10) If the first character of N is a '+', 42 | begin printing with the Nth line from the start of each file. 43 | .TP 44 | .B \-v, \fB\-\-verbose 45 | print headers with file names 46 | .TP 47 | .B \-h, \fB\-\-help 48 | show help and exit 49 | .TP 50 | .B \-V, \fB\-\-version 51 | show inotail version and exit 52 | .SH AUTHOR 53 | .PP 54 | Written by Tobias Klauser 55 | 56 | .SH SEE ALSO 57 | .PP 58 | .BR tail(1), 59 | .BR inotify(7) 60 | -------------------------------------------------------------------------------- /log_normalizer/auditparse.c: -------------------------------------------------------------------------------- 1 | /* Author: Scott Campbell 2 | * 2018/01/25 3 | * 4 | * Light weight program to read native linux auditd logs, 5 | * translate them into a more portable format and write 6 | * logs to a local TCP socket. 7 | * Socket writing taken from the nersc.c program in the isshd project. 8 | * 9 | * Core 'tail' like functionality derived from the following: 10 | * 11 | * inotail.c 12 | * A fast implementation of tail which uses the inotify API present in 13 | * recent versions of the Linux kernel. 14 | * 15 | * Copyright (C) 2005-2007, Tobias Klauser 16 | * 17 | * The idea was taken from turbotail. 18 | * 19 | * This program is free software; you can redistribute it and/or modify it under 20 | * the terms of the GNU General Public License as published by the Free Software 21 | * Foundation; either version 2, or (at your option) any later version. 22 | * 23 | * This program is distributed in the hope that it will be useful, but WITHOUT 24 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 25 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 26 | * details. 27 | * 28 | * You should have received a copy of the GNU General Public License along with 29 | * this program; if not, write to the Free Software Foundation, Inc., 51 30 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 31 | */ 32 | 33 | #define _GNU_SOURCE 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include "inotify.h" 48 | #include "inotify-syscalls.h" 49 | 50 | /* Start of new code ... */ 51 | #include "auditparse.h" 52 | 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include "modp_burl.h" 58 | 59 | #define PROGRAM_NAME "inotail" 60 | #define DEFAULT_BUFFER_SIZE 4096 61 | #define STUN_ERROR_MOD 10 62 | #define STUNNEL_PORT 799 63 | #define STUNNEL_HOST "localhost" 64 | 65 | /* inotify event buffer length for one file */ 66 | #define INOTIFY_BUFLEN (4 * sizeof(struct inotify_event)) 67 | 68 | struct file_struct *files = NULL; 69 | 70 | /* inotify fd */ 71 | int ifd = 0; 72 | 73 | /* Some additional things for auparse functionality */ 74 | 75 | /* Both the 'ses' and 'pid' values will be used for the base lookups in auditd_core. 76 | * 77 | * Because of this, records after the first in an event will be benefited by passing 78 | * this information along. If this is not done, a great deal of state goo and churn 79 | * is introduced later in the bro code. 80 | * 81 | * The ses identifier is the primary with the pid as a backup since sid sometimes has 82 | * a value of 'unset'. 83 | */ 84 | int holder_size = 256; 85 | char ses_holder[256]; 86 | char pid_holder[256]; 87 | 88 | int sis_socket = -1; /* socket test varible */ 89 | int sis_connect = -1; /* connect test variable */ 90 | int stun_conn_error = 0; /* track the number of connection errors to the transport */ 91 | int stun_write_error = 0; /* track the number of write errors to the transport */ 92 | 93 | char msgbuf[4*DEFAULT_BUFFER_SIZE]; 94 | 95 | auparse_state_t *au; 96 | char *aud_buf; 97 | 98 | /* Print header with filename before tailing the file? */ 99 | static char verbose = 0; 100 | 101 | /* Tailing relative to begin or end of file */ 102 | static char from_begin = 0; 103 | 104 | /* Number of ignored files */ 105 | static int n_ignored = 0; 106 | 107 | /* Command line options */ 108 | static const struct option long_opts[] = { 109 | { "bytes", required_argument, NULL, 'c' }, 110 | { "follow", optional_argument, NULL, 'f' }, 111 | { "lines", required_argument, NULL, 'n' }, 112 | { "verbose", no_argument, NULL, 'v' }, 113 | { "help", no_argument, NULL, 'h' }, 114 | { "version", no_argument, NULL, 'V' }, 115 | { NULL, 0, NULL, 0 } 116 | }; 117 | 118 | static void *emalloc(size_t size) 119 | { 120 | void *ret = malloc(size); 121 | 122 | if (unlikely(!ret)) { 123 | fprintf(stderr, "Error: Failed to allocate %d bytes of memory (%s)\n", (int)size, strerror(errno)); 124 | exit(EXIT_FAILURE); 125 | } 126 | 127 | return ret; 128 | } 129 | 130 | static char* encode_string(const char* src, const int len) 131 | { 132 | char *url_enc_string; 133 | 134 | /* take a string and return a pointer to the URI encoded version */ 135 | int new_len = modp_burl_encode_len(len); 136 | 137 | url_enc_string = emalloc(new_len); 138 | 139 | if ( url_enc_string == NULL ) 140 | return (char*)src; 141 | else 142 | 143 | /* We do not test the return here since it is done via the call itself. */ 144 | modp_burl_encode(url_enc_string, src, len); 145 | return url_enc_string; 146 | } 147 | 148 | /* communication routines below */ 149 | static int sis_opentcp(char *hostname, int portnum) 150 | { 151 | struct sockaddr_in sa; 152 | struct hostent *hp = NULL; 153 | int s, valopt; 154 | fd_set myset; 155 | struct timeval tv; 156 | socklen_t lon; 157 | 158 | s = -1; 159 | sis_connect = -1; 160 | 161 | hp = gethostbyname(hostname); 162 | 163 | if (hp == NULL) { 164 | hp = gethostbyaddr(hostname, strlen(hostname), AF_INET); 165 | if (hp == NULL) { 166 | syslog(LOG_INFO, "error resolving stunnel server address, exiting open"); 167 | return(-1); 168 | } 169 | } 170 | 171 | sa.sin_family = AF_INET; 172 | sa.sin_port = htons(portnum); 173 | (void) memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); 174 | 175 | if ((s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 176 | 177 | syslog(LOG_INFO, "error opening connection to stunnel listener, exiting open"); 178 | return (-1); 179 | } 180 | 181 | /* now make the socket non-blocking */ 182 | if ( fcntl(s,F_SETFL,FNDELAY) == -1) { 183 | syslog(LOG_INFO, "Failure setting socket to no-blocking"); 184 | } 185 | 186 | sis_connect = connect(s, (struct sockaddr *) & sa, sizeof(sa)); 187 | 188 | if ( sis_connect < 0 ) { 189 | 190 | /* 191 | * We might be waiting for the connection to complete - 192 | * quick check for that condition. 193 | */ 194 | 195 | if (errno == EINPROGRESS) { 196 | 197 | /* sit for 2 seconds */ 198 | tv.tv_sec = 2; 199 | tv.tv_usec = 0; 200 | FD_ZERO(&myset); 201 | FD_SET(s, &myset); 202 | 203 | if (select(s+1, NULL, &myset, NULL, &tv) > 0) { 204 | lon = sizeof(int); 205 | getsockopt(s, SOL_SOCKET, SO_ERROR, (void *)(&valopt), &lon); 206 | 207 | if (valopt) { 208 | if ( ( stun_conn_error % STUN_ERROR_MOD ) == 0 ) { 209 | syslog(LOG_INFO, "connection to stunnel rejected/timeout, exiting open, error = %d, %s" , 210 | valopt, strerror(valopt)); 211 | 212 | sleep(5); 213 | stun_conn_error++; 214 | close(s); 215 | sis_connect = -1; 216 | return(-1); 217 | } 218 | } 219 | else { 220 | /* sitting around has worked, mark connect as successful */ 221 | sis_connect = 1; 222 | } 223 | } 224 | } 225 | else { 226 | /* some simple sanity filtering for connect errors */ 227 | if ( ( stun_conn_error % STUN_ERROR_MOD ) == 0 ) { 228 | syslog(LOG_INFO, "connection to stunnel rejected, exiting open"); 229 | 230 | sleep(5); 231 | stun_conn_error++; 232 | close(s); 233 | return(-1); 234 | } 235 | } 236 | } 237 | 238 | return(s); 239 | } 240 | 241 | 242 | /* this may seem a bit overmuch, but there are some issues with the auparse_interpret_field function 243 | not providing anything but a NULL back which makes all the smoke leak out... 244 | */ 245 | const char* auparse_interpret_field_wrap(auparse_state_t *_au) 246 | { 247 | const char* ret_val; 248 | const char* nval = "NULL"; 249 | 250 | ret_val = (char*)auparse_interpret_field(_au); 251 | 252 | if ( ret_val == NULL ) { 253 | return nval; 254 | } 255 | else 256 | return ret_val; 257 | } 258 | 259 | const char* auparse_get_field_str_wrap(auparse_state_t *_au) 260 | { 261 | const char* ret_val; 262 | const char* nval = "NULL"; 263 | 264 | ret_val = (char*)auparse_get_field_str(_au); 265 | if ( ret_val == NULL ) { 266 | return nval; 267 | } 268 | else 269 | return ret_val; 270 | } 271 | 272 | const char* auparse_get_field_name_wrap(auparse_state_t *_au) 273 | { 274 | const char* ret_val; 275 | const char* nval = "NULL"; 276 | 277 | ret_val = (char*)auparse_get_field_name(_au); 278 | 279 | if ( ret_val == NULL ) { 280 | return nval; 281 | } 282 | else 283 | return ret_val; 284 | } 285 | /* auparse_get_num_fields: returns error as n=0 */ 286 | /* end auparse wrapper set */ 287 | 288 | static int s_write(char *buffer) 289 | { 290 | int err = 0; 291 | size_t sent = 0; 292 | 293 | if ( sis_connect != -1 && sis_socket != -1) 294 | sent = send(sis_socket, buffer, strlen(buffer), 0); 295 | 296 | /* this may be a little heavy handed ... */ 297 | if (sent != strlen(buffer) || sis_socket == -1 || sis_connect == -1) { 298 | 299 | /* 300 | * Close the fd since writes are failing, but only 301 | * if there is an error on it already since that would 302 | * close a socket that was never opened ... 303 | */ 304 | 305 | if ( stun_write_error > 0 ) { 306 | 307 | close(sis_socket); 308 | sis_socket = -1; 309 | sis_connect = -1; 310 | 311 | /* 312 | * Some simple sanity filtering for connect errors 313 | * this will flag every 10th error starting after #1 314 | */ 315 | 316 | if ( ( stun_write_error % STUN_ERROR_MOD ) == 1 ) { 317 | syslog(LOG_INFO, "write to stunnel failed, reopening connection"); 318 | } 319 | 320 | sleep(5); 321 | 322 | } 323 | 324 | stun_write_error++; 325 | sis_socket = sis_opentcp(STUNNEL_HOST, STUNNEL_PORT); 326 | 327 | if ( sis_socket == -1 || sis_connect == -1 ) { 328 | err = -1; 329 | } 330 | else { 331 | sent = send(sis_socket, buffer, strlen(buffer), 0); 332 | err = 1; 333 | } 334 | 335 | } 336 | 337 | return(err); 338 | } 339 | 340 | 341 | /* object processing routines below */ 342 | 343 | static void process_place_obj(auparse_state_t *_au, int *event_cnt, int num_records, int record_cnt) 344 | { 345 | char* type = "NULL"; 346 | char* t_type = NULL; 347 | char* node = "localhost"; 348 | char* t_node = NULL; 349 | char* cwd = "NULL"; 350 | char* t_cwd = NULL; 351 | char* path_name = "NULL"; 352 | char* t_path_name = NULL; 353 | char* inode = "NULL"; 354 | char* mode = "NULL"; 355 | char* t_mode = NULL; 356 | char* ouid = "NULL"; 357 | char* ogid = "NULL"; 358 | 359 | int num_fields = auparse_get_num_fields(_au) - 1; 360 | int n; 361 | 362 | /* test error condition */ 363 | if ( num_fields == -1 ) 364 | return; 365 | 366 | const au_event_t *e = auparse_get_timestamp(_au); 367 | 368 | if (e == NULL) 369 | return; 370 | 371 | if ( auparse_first_field(_au) == 0 ) 372 | return; 373 | 374 | for ( n = 0 ; n <= num_fields; n++ ) { 375 | 376 | char* field_name = (char*)auparse_get_field_name_wrap(_au); 377 | 378 | if ( strcmp(field_name, F_TYPE) == 0 ) { 379 | type = (char*)auparse_interpret_field_wrap(_au); 380 | t_type = encode_string( type, strlen(type)); 381 | } 382 | 383 | if ( strcmp(field_name, F_NODE) == 0 ) { 384 | node = (char*)auparse_interpret_field_wrap(_au); 385 | t_node = encode_string( node, strlen(node)); 386 | } 387 | 388 | if ( strcmp(field_name, F_CWD) == 0 ) { 389 | cwd = (char*)auparse_interpret_field_wrap(_au); 390 | t_cwd = encode_string( cwd, strlen(cwd)); 391 | } 392 | 393 | if ( strcmp(field_name, F_NAME) == 0 ) { 394 | path_name = (char*)auparse_interpret_field_wrap(_au); 395 | t_path_name = encode_string( path_name, strlen(path_name)); 396 | } 397 | 398 | if ( strcmp(field_name, F_INODE) == 0 ) 399 | inode = (char*)auparse_interpret_field_wrap(_au); 400 | 401 | if ( strcmp(field_name, F_MODE) == 0 ) { 402 | mode = (char*)auparse_interpret_field_wrap(_au); 403 | t_mode = encode_string( mode, strlen(mode)); 404 | } 405 | 406 | if ( strcmp(field_name, F_OUID) == 0 ) 407 | ouid = (char*)auparse_interpret_field_wrap(_au); 408 | 409 | if ( strcmp(field_name, F_OGID) == 0 ) 410 | ogid = (char*)auparse_interpret_field_wrap(_au); 411 | 412 | auparse_next_field(_au); 413 | } 414 | 415 | bzero(msgbuf, sizeof(msgbuf)); 416 | snprintf(msgbuf,sizeof(msgbuf) - 1, "NERSCAUD %i:%i:%i PLACE_OBJ %s %u.%u %s %s %s %s %s %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses_holder, pid_holder, t_cwd, t_path_name, inode, t_mode, ouid, ogid); 417 | s_write(msgbuf); 418 | 419 | free(t_type); 420 | free(t_node); 421 | free(t_cwd); 422 | free(t_path_name); 423 | free(t_mode); 424 | 425 | return; 426 | } 427 | 428 | static void process_user_obj(auparse_state_t *_au, int *event_cnt, int num_records, int record_cnt) 429 | { 430 | char* type = "NULL"; 431 | char* t_type = NULL; 432 | char* node = "localhost"; 433 | char* t_node = NULL; 434 | 435 | char* ses = "NULL"; 436 | char* egid = "NULL"; 437 | char* auid = "NULL"; 438 | char* euid = "NULL"; 439 | char* fsgid = "NULL"; 440 | char* fsuid = "NULL"; 441 | char* gid = "NULL"; 442 | char* suid = "NULL"; 443 | char* sgid = "NULL"; 444 | char* uid = "NULL"; 445 | char* pid = "NULL"; 446 | 447 | char* success = "NULL"; 448 | char* xit = "NULL"; 449 | char* t_xit = NULL; 450 | char* term = "NULL"; 451 | char* exe = "NULL"; 452 | char* t_exe = NULL; 453 | 454 | int num_fields = auparse_get_num_fields(_au) - 1; 455 | int n; 456 | 457 | /* test error condition */ 458 | if ( num_fields == -1 ) 459 | return; 460 | 461 | const au_event_t *e = auparse_get_timestamp(_au); 462 | 463 | if (e == NULL) 464 | return; 465 | 466 | if ( auparse_first_field(_au) == 0 ) 467 | return; 468 | 469 | for ( n = 0 ; n <= num_fields; n++ ) { 470 | 471 | char* field_name = (char*)auparse_get_field_name_wrap(_au); 472 | 473 | if ( strcmp(field_name,F_TYPE) == 0 ) { 474 | type = (char*)auparse_interpret_field_wrap(_au); 475 | t_type = encode_string( type, strlen(type)); 476 | } 477 | 478 | if ( strcmp(field_name, F_NODE) == 0 ) { 479 | node = (char*)auparse_interpret_field_wrap(_au); 480 | t_node = encode_string( node, strlen(node)); 481 | } 482 | 483 | if ( strcmp(field_name, F_SES) == 0 ) 484 | ses = (char*)auparse_get_field_str_wrap(_au); 485 | 486 | if ( strcmp(field_name, F_EGID) == 0 ) 487 | egid = (char*)auparse_interpret_field_wrap(_au); 488 | 489 | if ( strcmp(field_name, F_AUID) == 0 ) 490 | auid = (char*)auparse_get_field_str_wrap(_au); 491 | 492 | if ( strcmp(field_name, F_EUID) == 0 ) 493 | euid = (char*)auparse_interpret_field_wrap(_au); 494 | 495 | if ( strcmp(field_name, F_FSGID) == 0 ) 496 | fsgid = (char*)auparse_interpret_field_wrap(_au); 497 | 498 | if ( strcmp(field_name, F_FSUID) == 0 ) 499 | fsuid = (char*)auparse_interpret_field_wrap(_au); 500 | 501 | if ( strcmp(field_name, F_GID) == 0 ) 502 | gid = (char*)auparse_interpret_field_wrap(_au); 503 | 504 | if ( strcmp(field_name, F_SUID) == 0 ) 505 | suid = (char*)auparse_interpret_field_wrap(_au); 506 | 507 | if ( strcmp(field_name, F_SGID) == 0 ) 508 | sgid = (char*)auparse_interpret_field_wrap(_au); 509 | 510 | if ( strcmp(field_name, F_UID) == 0 ) 511 | uid = (char*)auparse_interpret_field_wrap(_au); 512 | 513 | if ( strcmp(field_name, F_PID) == 0 ) 514 | pid = (char*)auparse_get_field_str_wrap(_au); 515 | 516 | if ( strcmp(field_name, F_SUCCESS) == 0 ) 517 | success = (char*)auparse_interpret_field_wrap(_au); 518 | 519 | if ( strcmp(field_name, F_EXIT) == 0 ) { 520 | xit = (char*)auparse_interpret_field_wrap(_au); 521 | t_xit = encode_string( xit, strlen(xit)); 522 | } 523 | 524 | if ( strcmp(field_name, F_TERM) == 0 ) 525 | term = (char*)auparse_interpret_field_wrap(_au); 526 | 527 | if ( strcmp(field_name, F_EXE) == 0 ) { 528 | exe = (char*)auparse_interpret_field_wrap(_au); 529 | t_exe = encode_string( exe, strlen(exe)); 530 | } 531 | 532 | auparse_next_field(_au); 533 | } 534 | 535 | strncpy(ses_holder,ses,holder_size); 536 | strncpy(pid_holder,pid,holder_size); 537 | 538 | bzero(msgbuf, sizeof(msgbuf)); 539 | snprintf(msgbuf, sizeof(msgbuf) - 1, "NERSCAUD %i:%i:%i USER_OBJ %s %u.%u %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses, auid, egid, euid, fsgid, fsuid, gid, suid, sgid, uid, pid, success, t_xit, term, t_exe); 540 | s_write(msgbuf); 541 | 542 | free(t_node); 543 | free(t_type); 544 | free(t_xit); 545 | free(t_exe); 546 | 547 | return; 548 | } 549 | 550 | static void process_syscall_obj(auparse_state_t *_au, int *event_cnt, int num_records, int record_cnt) 551 | { 552 | 553 | char* type = "NULL"; 554 | char* t_type = NULL; 555 | char* node = "localhost"; 556 | char* t_node = NULL; 557 | char* ses = "NULL"; 558 | char* auid = "NULL"; 559 | 560 | char* egid = "NULL"; 561 | char* euid = "NULL"; 562 | char* fsgid = "NULL"; 563 | char* fsuid = "NULL"; 564 | char* gid = "NULL"; 565 | char* suid = "NULL"; 566 | char* sgid = "NULL"; 567 | char* uid = "NULL"; 568 | 569 | char* comm = "NULL"; 570 | char* t_comm = NULL; 571 | char* exe = "NULL"; 572 | char* t_exe = NULL; 573 | char* a0 = "NULL"; 574 | char* t_a0 = NULL; 575 | char* a1 = "NULL"; 576 | char* t_a1 = NULL; 577 | char* a2 = "NULL"; 578 | char* t_a2 = NULL; 579 | char* a3 = "NULL"; 580 | char* t_a3 = NULL; 581 | char* pid = "NULL"; 582 | char* ppid = "NULL"; 583 | char* success = "NULL"; 584 | char* xit = "NULL"; 585 | char* t_xit = NULL; 586 | char* tty = "NULL"; 587 | char* key = "NULL"; 588 | char* sysc_name = "NULL"; 589 | 590 | int num_fields = auparse_get_num_fields(_au) - 1; 591 | int n; 592 | 593 | /* test error condition */ 594 | if ( num_fields == -1 ) 595 | return; 596 | 597 | const au_event_t *e = auparse_get_timestamp(_au); 598 | 599 | if (e == NULL) 600 | return; 601 | 602 | if ( auparse_first_field(_au) == 0 ) 603 | return; 604 | 605 | for ( n = 0 ; n <= num_fields; n++ ) { 606 | 607 | char* field_name = (char*)auparse_get_field_name_wrap(_au); 608 | 609 | if ( strcmp(field_name,F_TYPE) == 0 ) { 610 | type = (char*)auparse_interpret_field_wrap(_au); 611 | t_type = encode_string( type, strlen(type)); 612 | } 613 | 614 | if ( strcmp(field_name, F_NODE) == 0 ) { 615 | node = (char*)auparse_interpret_field_wrap(_au); 616 | t_node = encode_string( node, strlen(node)); 617 | } 618 | 619 | if ( strcmp(field_name, F_SES) == 0 ) 620 | ses = (char*)auparse_get_field_str_wrap(_au); 621 | 622 | if ( strcmp(field_name, F_EGID) == 0 ) 623 | egid = (char*)auparse_interpret_field_wrap(_au); 624 | 625 | if ( strcmp(field_name, F_AUID) == 0 ) 626 | auid = (char*)auparse_get_field_str_wrap(_au); 627 | 628 | if ( strcmp(field_name, F_EUID) == 0 ) 629 | euid = (char*)auparse_interpret_field_wrap(_au); 630 | 631 | if ( strcmp(field_name, F_FSGID) == 0 ) 632 | fsgid = (char*)auparse_interpret_field_wrap(_au); 633 | 634 | if ( strcmp(field_name, F_FSUID) == 0 ) 635 | fsuid = (char*)auparse_interpret_field_wrap(_au); 636 | 637 | if ( strcmp(field_name, F_GID) == 0 ) 638 | gid = (char*)auparse_interpret_field_wrap(_au); 639 | 640 | if ( strcmp(field_name, F_SUID) == 0 ) 641 | suid = (char*)auparse_interpret_field_wrap(_au); 642 | 643 | if ( strcmp(field_name, F_SGID) == 0 ) 644 | sgid = (char*)auparse_interpret_field_wrap(_au); 645 | 646 | if ( strcmp(field_name, F_UID) == 0 ) 647 | uid = (char*)auparse_interpret_field_wrap(_au); 648 | 649 | if ( strcmp(field_name, F_COMM) == 0 ) { 650 | comm = (char*)auparse_interpret_field_wrap(_au); 651 | t_comm = encode_string( comm, strlen(comm)); 652 | } 653 | 654 | if ( strcmp(field_name, F_A0) == 0 ) { 655 | a0 = (char*)auparse_get_field_str_wrap(_au); 656 | t_a0 = encode_string( a0, strlen(a0)); 657 | } 658 | 659 | if ( strcmp(field_name, F_A1) == 0 ) { 660 | a1 = (char*)auparse_get_field_str_wrap(_au); 661 | t_a1 = encode_string( a1, strlen(a1)); 662 | } 663 | 664 | if ( strcmp(field_name, F_A2) == 0 ) { 665 | a2 = (char*)auparse_get_field_str_wrap(_au); 666 | t_a2 = encode_string( a2, strlen(a2)); 667 | } 668 | 669 | if ( strcmp(field_name, F_A3) == 0 ) { 670 | a3 = (char*)auparse_get_field_str_wrap(_au); 671 | t_a3 = encode_string( a3, strlen(a3)); 672 | } 673 | 674 | if ( strcmp(field_name, F_PID) == 0 ) 675 | pid = (char*)auparse_get_field_str_wrap(_au); 676 | 677 | if ( strcmp(field_name, F_PPID) == 0 ) 678 | ppid = (char*)auparse_get_field_str_wrap(_au); 679 | 680 | if ( strcmp(field_name, F_SUCCESS) == 0 ) 681 | success = (char*)auparse_interpret_field_wrap(_au); 682 | 683 | if ( strcmp(field_name, F_EXIT) == 0 ) { 684 | xit = (char*)auparse_interpret_field_wrap(_au); 685 | t_xit = encode_string( xit, strlen(xit)); 686 | } 687 | 688 | if ( strcmp(field_name, F_TTY) == 0 ) 689 | tty = (char*)auparse_interpret_field_wrap(_au); 690 | 691 | if ( strcmp(field_name, F_EXE) == 0 ) { 692 | exe = (char*)auparse_interpret_field_wrap(_au); 693 | t_exe = encode_string( exe, strlen(exe)); 694 | } 695 | 696 | if ( strcmp(field_name, F_KEY) == 0 ) 697 | key = (char*)auparse_interpret_field_wrap(_au); 698 | 699 | if ( strcmp(field_name, F_SYSCALL) == 0 ) 700 | sysc_name = (char*)auparse_interpret_field_wrap(_au); 701 | 702 | auparse_next_field(_au); 703 | 704 | } 705 | 706 | bzero(msgbuf, sizeof(msgbuf)); 707 | snprintf(msgbuf, sizeof(msgbuf) - 1, "NERSCAUD %i:%i:%i SYSCALL_OBJ %s %u.%u %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses, auid, sysc_name, key, t_comm, t_exe, t_a0, t_a1, t_a2, t_a3, uid, gid, euid, egid, fsuid, fsgid, suid, sgid, pid, ppid, tty, success, t_xit); 708 | s_write(msgbuf); 709 | 710 | strncpy(ses_holder,ses,holder_size); 711 | strncpy(pid_holder,pid,holder_size); 712 | 713 | free(t_node); 714 | free(t_type); 715 | free(t_comm); 716 | free(t_a0); 717 | free(t_a1); 718 | free(t_a2); 719 | free(t_a3); 720 | free(t_xit); 721 | free(t_exe); 722 | 723 | return; 724 | } 725 | 726 | static void process_sock_obj(auparse_state_t *_au, int *event_cnt, int num_records, int record_cnt) 727 | { 728 | char* type = "NULL"; 729 | char* t_type = NULL; 730 | char* node = "localhost"; 731 | char* t_node = NULL; 732 | char* saddr = "NULL"; 733 | char* t_saddr = NULL; 734 | 735 | int num_fields = auparse_get_num_fields(_au) - 1; 736 | int n; 737 | 738 | /* test error condition */ 739 | if ( num_fields == -1 ) 740 | return; 741 | 742 | const au_event_t *e = auparse_get_timestamp(_au); 743 | 744 | if (e == NULL) 745 | return; 746 | 747 | if ( auparse_first_field(_au) == 0 ) 748 | return; 749 | 750 | for ( n = 0 ; n <= num_fields; n++ ) { 751 | 752 | char* field_name = (char*)auparse_get_field_name_wrap(_au); 753 | 754 | if ( strcmp(field_name,F_TYPE) == 0 ) { 755 | type = (char*)auparse_interpret_field_wrap(_au); 756 | t_type = encode_string( type, strlen(type)); 757 | } 758 | 759 | if ( strcmp(field_name, F_NODE) == 0 ) { 760 | node = (char*)auparse_interpret_field_wrap(_au); 761 | t_node = encode_string( node, strlen(node)); 762 | } 763 | 764 | if ( strcmp(field_name, F_SADDR) == 0 ) { 765 | saddr = (char*)auparse_interpret_field_wrap(_au); 766 | t_saddr = encode_string( saddr, strlen(saddr)); 767 | } 768 | 769 | auparse_next_field(_au); 770 | } 771 | 772 | bzero(msgbuf, sizeof(msgbuf)); 773 | snprintf(msgbuf, sizeof(msgbuf) -1, "NERSCAUD %i:%i:%i SADDR_OBJ %s %u.%u %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses_holder, pid_holder, t_saddr); 774 | s_write(msgbuf); 775 | 776 | free(t_type); 777 | free(t_node); 778 | free(t_saddr); 779 | 780 | return; 781 | } 782 | 783 | 784 | 785 | static void process_execv_obj(auparse_state_t *_au, int *event_cnt, int num_records, int record_cnt) 786 | { 787 | char* type = "NULL"; 788 | char* t_type = NULL; 789 | char* node = "localhost"; 790 | char* t_node = NULL; 791 | char* argc = "NULL"; 792 | char* a0 = "NULL"; 793 | char* t_a0 = NULL; 794 | char* a1 = "NULL"; 795 | char* t_a1 = NULL; 796 | char* a2 = "NULL"; 797 | char* t_a2 = NULL; 798 | char* a3 = "NULL"; 799 | char* t_a3 = NULL; 800 | 801 | int num_fields = auparse_get_num_fields(_au) - 1; 802 | int n; 803 | 804 | /* test error condition */ 805 | if ( num_fields == -1 ) 806 | return; 807 | 808 | const au_event_t *e = auparse_get_timestamp(_au); 809 | 810 | if (e == NULL) 811 | return; 812 | 813 | if ( auparse_first_field(_au) == 0 ) 814 | return; 815 | 816 | for ( n = 0 ; n <= num_fields; n++ ) { 817 | 818 | char* field_name = (char*)auparse_get_field_name_wrap(_au); 819 | 820 | if ( strcmp(field_name,F_TYPE) == 0 ) { 821 | type = (char*)auparse_interpret_field_wrap(_au); 822 | t_type = encode_string(type, strlen(type)); 823 | } 824 | 825 | if ( strcmp(field_name, F_NODE) == 0 ) { 826 | node = (char*)auparse_interpret_field_wrap(_au); 827 | t_node = encode_string(node, strlen(node)); 828 | } 829 | 830 | if ( strcmp(field_name, F_ARGC) == 0 ) 831 | argc = (char*)auparse_interpret_field_wrap(_au); 832 | 833 | 834 | /* Few notes on the arguments - A_A0 is always the 835 | * name of the executable since it is the first 836 | * argument sent to the exec call. 837 | * Since this is redundant, we will only provide 838 | * a1-a3 as the role of this call is to supply 839 | * exec arguments rather than the whole line. 840 | */ 841 | 842 | if ( strcmp(field_name, F_A0) == 0 ) { 843 | a0 = (char*)auparse_get_field_str_wrap(_au); 844 | t_a0 = encode_string( a0, strlen(a0)); 845 | } 846 | 847 | if ( strcmp(field_name, F_A1) == 0 ) { 848 | a1 = (char*)auparse_get_field_str_wrap(_au); 849 | t_a1 = encode_string( a1, strlen(a1)); 850 | } 851 | 852 | if ( strcmp(field_name, F_A2) == 0 ) { 853 | a2 = (char*)auparse_get_field_str_wrap(_au); 854 | t_a2 = encode_string( a2, strlen(a2)); 855 | } 856 | 857 | if ( strcmp(field_name, F_A3) == 0 ) { 858 | a3 = (char*)auparse_get_field_str_wrap(_au); 859 | t_a3 = encode_string( a3, strlen(a3)); 860 | } 861 | 862 | auparse_next_field(_au); 863 | } 864 | 865 | bzero(msgbuf, sizeof(msgbuf)); 866 | //printf("NERSCAUD %i:%i:%i EXEC_OBJ %s %u.%u %s %s %s %s %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses_holder, pid_holder, argc, t_a0, t_a1, t_a2, t_a3); 867 | snprintf(msgbuf, sizeof(msgbuf) - 1, "NERSCAUD %i:%i:%i EXEC_OBJ %s %u.%u %s %s %s %s %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses_holder, pid_holder, argc, t_a0, t_a1, t_a2, t_a3); 868 | s_write(msgbuf); 869 | 870 | free(t_type); 871 | free(t_node); 872 | free(t_a0); 873 | free(t_a1); 874 | free(t_a2); 875 | free(t_a3); 876 | 877 | return; 878 | } 879 | 880 | static void process_generic_obj(auparse_state_t *_au, int *event_cnt, int num_records, int record_cnt) 881 | { 882 | 883 | char* type = "NULL"; 884 | char* t_type = NULL; 885 | char* node = "localhost"; 886 | char* t_node = NULL; 887 | char* ses = "NULL"; 888 | char* auid = "NULL"; 889 | 890 | char* egid = "NULL"; 891 | char* euid = "NULL"; 892 | char* fsgid = "NULL"; 893 | char* fsuid = "NULL"; 894 | char* gid = "NULL"; 895 | char* suid = "NULL"; 896 | char* sgid = "NULL"; 897 | char* uid = "NULL"; 898 | 899 | char* comm = "NULL"; 900 | char* t_comm = NULL; 901 | char* exe = "NULL"; 902 | char* t_exe = NULL; 903 | char* a0 = "NULL"; 904 | char* t_a0 = NULL; 905 | char* a1 = "NULL"; 906 | char* t_a1 = NULL; 907 | char* a2 = "NULL"; 908 | char* t_a2 = NULL; 909 | char* a3 = "NULL"; 910 | char* t_a3 = NULL; 911 | char* pid = "NULL"; 912 | char* ppid = "NULL"; 913 | char* success = "NULL"; 914 | char* xit = "NULL"; 915 | char* t_xit = NULL; 916 | char* tty = "NULL"; 917 | char* key = "NULL"; 918 | 919 | int num_fields = auparse_get_num_fields(_au) - 1; 920 | int n; 921 | 922 | /* test error condition */ 923 | if ( num_fields == -1 ) 924 | return; 925 | 926 | const au_event_t *e = auparse_get_timestamp(_au); 927 | 928 | if (e == NULL) 929 | return; 930 | 931 | if ( auparse_first_field(_au) == 0 ) 932 | return; 933 | 934 | for ( n = 0 ; n <= num_fields; n++ ) { 935 | 936 | char* field_name = (char*)auparse_get_field_name_wrap(_au); 937 | 938 | if ( strcmp(field_name,F_TYPE) == 0 ) { 939 | type = (char*)auparse_interpret_field_wrap(_au); 940 | t_type = encode_string(type, strlen(type)); 941 | } 942 | 943 | if ( strcmp(field_name, F_NODE) == 0 ) { 944 | node = (char*)auparse_interpret_field_wrap(_au); 945 | t_node = encode_string(node, strlen(node)); 946 | } 947 | 948 | if ( strcmp(field_name, F_SES) == 0 ) 949 | ses = (char*)auparse_get_field_str_wrap(_au); 950 | 951 | if ( strcmp(field_name, F_EGID) == 0 ) 952 | egid = (char*)auparse_interpret_field_wrap(_au); 953 | 954 | if ( strcmp(field_name, F_AUID) == 0 ) 955 | auid = (char*)auparse_get_field_str_wrap(_au); 956 | 957 | if ( strcmp(field_name, F_EUID) == 0 ) 958 | euid = (char*)auparse_interpret_field_wrap(_au); 959 | 960 | if ( strcmp(field_name, F_FSGID) == 0 ) 961 | fsgid = (char*)auparse_interpret_field_wrap(_au); 962 | 963 | if ( strcmp(field_name, F_FSUID) == 0 ) 964 | fsuid = (char*)auparse_interpret_field_wrap(_au); 965 | 966 | if ( strcmp(field_name, F_GID) == 0 ) 967 | gid = (char*)auparse_interpret_field_wrap(_au); 968 | 969 | if ( strcmp(field_name, F_SUID) == 0 ) 970 | suid = (char*)auparse_interpret_field_wrap(_au); 971 | 972 | if ( strcmp(field_name, F_SGID) == 0 ) 973 | sgid = (char*)auparse_interpret_field_wrap(_au); 974 | 975 | if ( strcmp(field_name, F_UID) == 0 ) 976 | uid = (char*)auparse_interpret_field_wrap(_au); 977 | 978 | if ( strcmp(field_name, F_COMM) == 0 ) { 979 | comm = (char*)auparse_interpret_field_wrap(_au); 980 | t_comm = encode_string( comm, strlen(comm)); 981 | } 982 | 983 | if ( strcmp(field_name, F_A0) == 0 ) { 984 | a0 = (char*)auparse_get_field_str_wrap(_au); 985 | t_a0 = encode_string( a0, strlen(a0)); 986 | } 987 | 988 | if ( strcmp(field_name, F_A1) == 0 ) { 989 | a1 = (char*)auparse_get_field_str_wrap(_au); 990 | t_a1 = encode_string( a1, strlen(a1)); 991 | } 992 | 993 | if ( strcmp(field_name, F_A2) == 0 ) { 994 | a2 = (char*)auparse_get_field_str_wrap(_au); 995 | t_a2 = encode_string( a2, strlen(a2)); 996 | } 997 | 998 | if ( strcmp(field_name, F_A3) == 0 ) { 999 | a3 = (char*)auparse_get_field_str_wrap(_au); 1000 | t_a3 = encode_string( a3, strlen(a3)); 1001 | } 1002 | 1003 | if ( strcmp(field_name, F_PID) == 0 ) 1004 | pid = (char*)auparse_get_field_str_wrap(_au); 1005 | 1006 | if ( strcmp(field_name, F_PPID) == 0 ) 1007 | ppid = (char*)auparse_get_field_str_wrap(_au); 1008 | 1009 | if ( strcmp(field_name, F_SUCCESS) == 0 ) 1010 | success = (char*)auparse_interpret_field_wrap(_au); 1011 | 1012 | if ( strcmp(field_name, F_EXIT) == 0 ) { 1013 | xit = (char*)auparse_interpret_field_wrap(_au); 1014 | t_xit = encode_string( xit, strlen(xit)); 1015 | } 1016 | 1017 | if ( strcmp(field_name, F_TTY) == 0 ) 1018 | tty = (char*)auparse_interpret_field_wrap(_au); 1019 | 1020 | if ( strcmp(field_name, F_EXE) == 0 ) { 1021 | exe = (char*)auparse_interpret_field_wrap(_au); 1022 | t_exe = encode_string( exe, strlen(exe)); 1023 | } 1024 | 1025 | if ( strcmp(field_name, F_KEY) == 0 ) 1026 | key = (char*)auparse_interpret_field_wrap(_au); 1027 | 1028 | auparse_next_field(_au); 1029 | 1030 | } 1031 | 1032 | bzero(msgbuf, sizeof(msgbuf)); 1033 | snprintf(msgbuf, sizeof(msgbuf) - 1, "NERSCAUD %i:%i:%i GENERIC_OBJ %s %u.%u %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", *event_cnt, num_records, record_cnt, t_type, (unsigned)e->sec, e->milli, t_node, ses, auid, key, t_comm, t_exe, t_a0, t_a1, t_a2, t_a3, uid, gid, euid, egid, fsuid, fsgid, suid, sgid, pid, ppid, tty, success, t_xit); 1034 | s_write(msgbuf); 1035 | 1036 | strncpy(ses_holder,ses,holder_size); 1037 | strncpy(pid_holder,pid,holder_size); 1038 | 1039 | free(t_node); 1040 | free(t_type); 1041 | free(t_comm); 1042 | free(t_a0); 1043 | free(t_a1); 1044 | free(t_a2); 1045 | free(t_a3); 1046 | free(t_xit); 1047 | free(t_exe); 1048 | 1049 | return; 1050 | } 1051 | 1052 | 1053 | /* 1054 | * This takes the generic audit identifier and provide back a 1055 | * mapping to the equivelant type that will be expected on analysis. 1056 | */ 1057 | 1058 | static int return_audtype(int rawtype) 1059 | { 1060 | // default value 1061 | int ret_val = GENERIC_OBJ; 1062 | 1063 | if ( rawtype == 1307 || rawtype == 1302 ) // CWD|PATH 1064 | ret_val = PLACE_OBJ; 1065 | 1066 | if ( rawtype == 1300 ) // SYSCALL 1067 | ret_val = SYSCALL_OBJ; 1068 | 1069 | // AUDIT_USER_AUTH, AUDIT_USER_ACCT, AUDIT_USER_MGMT, AUDIT_CRED_ACQ, AUDIT_USER_START 1070 | // AUDIT_USER_END, AUDIT_USER_CHAUTHTOK, AUDIT_USER_ERR, AUDIT_USER_LOGIN, AUDIT_USER_LOGOUT 1071 | // AUDIT_USER_SELINUX_ERR, AUDIT_USER_CMD 1072 | // 1073 | int i; 1074 | for (i = 0; i < user_types_count; i++) { 1075 | if ( rawtype == user_types[i] ) 1076 | { 1077 | ret_val = USER_OBJ; 1078 | break; 1079 | } 1080 | } 1081 | 1082 | if ( rawtype == 1306 ) // SOCKADDR 1083 | ret_val = SOCK_OBJ; 1084 | 1085 | if ( rawtype == 1309 ) // EXECVE 1086 | ret_val = EXECVE_OBJ; 1087 | 1088 | return ret_val; 1089 | } 1090 | 1091 | static void auparse_callback(auparse_state_t *_au, auparse_cb_event_t cb_event_type, void *user_data) 1092 | { 1093 | int *event_cnt = (int *)user_data; 1094 | int num_records = auparse_get_num_records(_au); 1095 | int record_cnt; 1096 | 1097 | if (cb_event_type == AUPARSE_CB_EVENT_READY) { 1098 | 1099 | if (auparse_first_record(_au) <= 0) { 1100 | return; 1101 | } 1102 | 1103 | record_cnt = 1; 1104 | do { 1105 | 1106 | int audtype = return_audtype(auparse_get_type(_au)); 1107 | 1108 | switch(audtype) { 1109 | 1110 | case PLACE_OBJ: 1111 | // au, event number:total rec in event:this num in event 1112 | process_place_obj(_au, event_cnt, num_records, record_cnt); 1113 | break; 1114 | 1115 | case USER_OBJ: 1116 | process_user_obj(_au, event_cnt, num_records, record_cnt); 1117 | break; 1118 | 1119 | case SYSCALL_OBJ: 1120 | process_syscall_obj(_au, event_cnt, num_records, record_cnt); 1121 | break; 1122 | 1123 | case SOCK_OBJ: 1124 | process_sock_obj(_au, event_cnt, num_records, record_cnt); 1125 | break; 1126 | 1127 | case EXECVE_OBJ: 1128 | /* execve arguments */ 1129 | process_execv_obj(_au, event_cnt, num_records, record_cnt); 1130 | break; 1131 | 1132 | case GENERIC_OBJ: 1133 | process_generic_obj(_au, event_cnt, num_records, record_cnt); 1134 | break; 1135 | } 1136 | 1137 | const au_event_t *e = auparse_get_timestamp(_au); 1138 | 1139 | if (e == NULL) { 1140 | return; 1141 | } 1142 | 1143 | record_cnt++; 1144 | 1145 | } while(auparse_next_record(_au) > 0); // end of do 1146 | 1147 | (*event_cnt)++; 1148 | 1149 | } // end cb_event_type == AUPARSE_CB_EVENT_READY 1150 | } 1151 | 1152 | 1153 | static void usage(const int status) 1154 | { 1155 | fprintf(stdout, "Usage: %s [OPTION]... [FILE]...\n\n" 1156 | " -c N, --bytes=N output the last N bytes\n" 1157 | " -f, --follow output as the file grows\n" 1158 | " -n N, --lines=N output the last N lines (default: %d)\n" 1159 | " -v, --verbose print headers with file names\n" 1160 | " -h, --help show this help and exit\n" 1161 | " -V, --version show version and exit\n\n" 1162 | "If the first character of N (the number of bytes or lines) is a `+',\n" 1163 | "begin printing with the Nth item from the start of each file, otherwise,\n" 1164 | "print the last N items in the file.\n", PROGRAM_NAME, DEFAULT_N_LINES); 1165 | 1166 | exit(status); 1167 | } 1168 | 1169 | static inline void setup_file(struct file_struct *f) 1170 | { 1171 | f->fd = f->i_watch = -1; 1172 | f->size = 0; 1173 | f->blksize = DEFAULT_BUFFER_SIZE; 1174 | f->ignore = 0; 1175 | } 1176 | 1177 | static void ignore_file(struct file_struct *f) 1178 | { 1179 | if (f->fd != -1) { 1180 | close(f->fd); 1181 | f->fd = -1; 1182 | } 1183 | f->ignore = 1; 1184 | n_ignored++; 1185 | } 1186 | 1187 | static inline char *pretty_name(char *filename) 1188 | { 1189 | return (strcmp(filename, "-") == 0) ? "standard input" : filename; 1190 | } 1191 | 1192 | static void write_header(char *filename) 1193 | { 1194 | static unsigned short first_file = 1; 1195 | static char *last = NULL; 1196 | 1197 | if (last != filename) { 1198 | fprintf(stdout, "%s==> %s <==\n", (first_file ? "" : "\n"), pretty_name(filename)); 1199 | fflush(stdout); /* Make sure the header is printed before the content */ 1200 | } 1201 | 1202 | first_file = 0; 1203 | last = filename; 1204 | } 1205 | 1206 | static off_t lines_to_offset_from_end(struct file_struct *f, unsigned long n_lines) 1207 | { 1208 | off_t offset = f->size; 1209 | char *buf = emalloc(f->blksize); 1210 | 1211 | n_lines++; /* We also count the last \n */ 1212 | 1213 | while (offset > 0 && n_lines > 0) { 1214 | int i; 1215 | ssize_t rc, block_size = f->blksize; /* Size of the current block we're reading */ 1216 | 1217 | if (offset < block_size) 1218 | block_size = offset; 1219 | 1220 | /* Start of current block */ 1221 | offset -= block_size; 1222 | 1223 | if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) { 1224 | fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); 1225 | free(buf); 1226 | return -1; 1227 | } 1228 | 1229 | rc = read(f->fd, buf, block_size); 1230 | if (unlikely(rc < 0)) { 1231 | fprintf(stderr, "Error: Could not read from file '%s' (%s)\n", f->name, strerror(errno)); 1232 | free(buf); 1233 | return -1; 1234 | } 1235 | 1236 | for (i = block_size - 1; i > 0; i--) { 1237 | if (buf[i] == '\n') { 1238 | if (--n_lines == 0) { 1239 | free(buf); 1240 | return offset += i + 1; /* We don't want the first \n */ 1241 | } 1242 | } 1243 | } 1244 | } 1245 | 1246 | free(buf); 1247 | return offset; 1248 | } 1249 | 1250 | static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned long n_lines) 1251 | { 1252 | char *buf; 1253 | off_t offset = 0; 1254 | 1255 | /* tail everything for 'inotail -n +0' */ 1256 | if (n_lines == 0) 1257 | return 0; 1258 | 1259 | n_lines--; 1260 | buf = emalloc(f->blksize); 1261 | 1262 | while (offset <= f->size && n_lines > 0) { 1263 | int i; 1264 | ssize_t rc, block_size = f->blksize; 1265 | 1266 | if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) { 1267 | fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); 1268 | free(buf); 1269 | return -1; 1270 | } 1271 | 1272 | rc = read(f->fd, buf, block_size); 1273 | if (unlikely(rc < 0)) { 1274 | fprintf(stderr, "Error: Could not read from file '%s' (%s)\n", f->name, strerror(errno)); 1275 | free(buf); 1276 | return -1; 1277 | } else if (rc < block_size) 1278 | block_size = rc; 1279 | 1280 | for (i = 0; i < block_size; i++) { 1281 | if (buf[i] == '\n') { 1282 | if (--n_lines == 0) { 1283 | free(buf); 1284 | return offset + i + 1; 1285 | } 1286 | } 1287 | } 1288 | 1289 | offset += block_size; 1290 | } 1291 | 1292 | free(buf); 1293 | return offset; 1294 | } 1295 | 1296 | static off_t lines_to_offset(struct file_struct *f, unsigned long n_lines) 1297 | { 1298 | if (from_begin) 1299 | return lines_to_offset_from_begin(f, n_lines); 1300 | else 1301 | return lines_to_offset_from_end(f, n_lines); 1302 | } 1303 | 1304 | static off_t bytes_to_offset(struct file_struct *f, unsigned long n_bytes) 1305 | { 1306 | off_t offset = 0; 1307 | 1308 | /* tail everything for 'inotail -c +0' */ 1309 | if (from_begin) { 1310 | if (n_bytes > 0) 1311 | offset = (off_t) n_bytes - 1; 1312 | } else if ((off_t) n_bytes < f->size) 1313 | offset = f->size - (off_t) n_bytes; 1314 | 1315 | return offset; 1316 | } 1317 | 1318 | static ssize_t tail_pipe(struct file_struct *f) 1319 | { 1320 | ssize_t rc; 1321 | char *buf = emalloc(f->blksize); 1322 | 1323 | if (verbose) 1324 | write_header(f->name); 1325 | 1326 | /* We will just tail everything here */ 1327 | while ((rc = read(f->fd, buf, f->blksize)) > 0) { 1328 | auparse_feed(au, buf, rc); 1329 | } 1330 | 1331 | free(buf); 1332 | return rc; 1333 | } 1334 | 1335 | static int tail_file(struct file_struct *f, unsigned long n_units, char mode, char forever) 1336 | { 1337 | ssize_t bytes_read = 0; 1338 | off_t offset = 0; 1339 | char *buf; 1340 | struct stat finfo; 1341 | 1342 | if (strcmp(f->name, "-") == 0) 1343 | f->fd = STDIN_FILENO; 1344 | else { 1345 | f->fd = open(f->name, O_RDONLY); 1346 | if (unlikely(f->fd < 0)) { 1347 | fprintf(stderr, "Error: Could not open file '%s' (%s)\n", f->name, strerror(errno)); 1348 | ignore_file(f); 1349 | return -1; 1350 | } 1351 | } 1352 | 1353 | if (fstat(f->fd, &finfo) < 0) { 1354 | fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno)); 1355 | ignore_file(f); 1356 | return -1; 1357 | } 1358 | 1359 | if (!IS_TAILABLE(finfo.st_mode)) { 1360 | fprintf(stderr, "Error: '%s' of unsupported file type (%s)\n", f->name, strerror(errno)); 1361 | ignore_file(f); 1362 | return -1; 1363 | } 1364 | 1365 | /* Cannot seek on these */ 1366 | if (IS_PIPELIKE(finfo.st_mode) || f->fd == STDIN_FILENO) 1367 | return tail_pipe(f); 1368 | 1369 | f->size = finfo.st_size; 1370 | f->blksize = finfo.st_blksize; /* TODO: Can this value be 0? */ 1371 | 1372 | if (mode == M_LINES) 1373 | offset = lines_to_offset(f, n_units); 1374 | else 1375 | offset = bytes_to_offset(f, n_units); 1376 | 1377 | /* We only get negative offsets on errors */ 1378 | if (unlikely(offset < 0)) { 1379 | ignore_file(f); 1380 | return -1; 1381 | } 1382 | 1383 | if (verbose) 1384 | write_header(f->name); 1385 | 1386 | if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) { 1387 | fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); 1388 | return -1; 1389 | } 1390 | 1391 | buf = emalloc(f->blksize); 1392 | 1393 | while ((bytes_read = read(f->fd, buf, f->blksize)) > 0) { 1394 | auparse_feed(au,buf, bytes_read); 1395 | } 1396 | 1397 | if (!forever) { 1398 | if (close(f->fd) < 0) { 1399 | fprintf(stderr, "Error: Could not close file '%s' (%s)\n", f->name, strerror(errno)); 1400 | free(buf); 1401 | return -1; 1402 | } 1403 | } /* Let the fd open otherwise, we'll need it */ 1404 | 1405 | free(buf); 1406 | return 0; 1407 | } 1408 | 1409 | static int handle_inotify_event(struct inotify_event *inev, struct file_struct *f) 1410 | { 1411 | int ret = 0; 1412 | 1413 | if (inev->mask & IN_MODIFY) { 1414 | char *fbuf; 1415 | ssize_t rc; 1416 | struct stat finfo; 1417 | 1418 | if (verbose) 1419 | write_header(f->name); 1420 | 1421 | /* Seek to old file size */ 1422 | if (lseek(f->fd, f->size, SEEK_SET) == (off_t) -1) { 1423 | fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); 1424 | ret = -1; 1425 | goto ignore; 1426 | } 1427 | 1428 | fbuf = emalloc(f->blksize); 1429 | 1430 | while ((rc = read(f->fd, fbuf, f->blksize)) != 0) { 1431 | auparse_feed(au,fbuf, rc); 1432 | } 1433 | 1434 | if (fstat(f->fd, &finfo) < 0) { 1435 | fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno)); 1436 | ret = -1; 1437 | free(fbuf); 1438 | goto ignore; 1439 | } 1440 | 1441 | f->size = finfo.st_size; 1442 | 1443 | free(fbuf); 1444 | return ret; 1445 | } else if (inev->mask & IN_DELETE_SELF) { 1446 | fprintf(stderr, "File '%s' deleted.\n", f->name); 1447 | } else if (inev->mask & IN_MOVE_SELF) { 1448 | fprintf(stderr, "File '%s' moved.\n", f->name); 1449 | 1450 | // SCOTT 1451 | close(f->fd); 1452 | 1453 | /* without this, the program will leak the inotify descriptor 1454 | * which would be bad for all sorts of reasons ... 1455 | */ 1456 | if ( ifd != 0 ) 1457 | close(ifd); 1458 | 1459 | free(files); 1460 | struct file_struct *new_files = NULL; 1461 | new_files = emalloc( sizeof(struct file_struct) ); 1462 | new_files[0].name = "/var/log/audit/audit.log"; 1463 | setup_file(&new_files[0]); 1464 | 1465 | // Take a sec here to let the new file get 1466 | // set up by the OS - there are problems with this 1467 | // asking just a bit too soon. 1468 | sleep(1); 1469 | tail_file(new_files, DEFAULT_N_LINES, M_LINES, 1); 1470 | watch_files(new_files, 1); 1471 | return 0; 1472 | 1473 | } else if (inev->mask & IN_UNMOUNT) { 1474 | fprintf(stderr, "Device containing file '%s' unmounted.\n", f->name); 1475 | } 1476 | 1477 | ignore: 1478 | ignore_file(f); 1479 | return ret; 1480 | } 1481 | 1482 | static int watch_files(struct file_struct *_files, int n_files) 1483 | { 1484 | int i; 1485 | char buf[n_files * INOTIFY_BUFLEN]; 1486 | 1487 | ifd = inotify_init(); 1488 | if (errno == ENOSYS) { 1489 | fprintf(stderr, "Error: inotify is not supported by the kernel you're currently running.\n"); 1490 | exit(EXIT_FAILURE); 1491 | } else if (unlikely(ifd < 0)) { 1492 | fprintf(stderr, "Error: Could not initialize inotify (%s)\n", strerror(errno)); 1493 | exit(EXIT_FAILURE); 1494 | } 1495 | 1496 | for (i = 0; i < n_files; i++) { 1497 | if (!_files[i].ignore) { 1498 | _files[i].i_watch = inotify_add_watch(ifd, _files[i].name, 1499 | IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT); 1500 | 1501 | if (_files[i].i_watch < 0) { 1502 | fprintf(stderr, "Error: Could not create inotify watch on file '%s' (%s)\n", 1503 | _files[i].name, strerror(errno)); 1504 | ignore_file(&_files[i]); 1505 | } 1506 | } 1507 | } 1508 | 1509 | while (n_ignored < n_files) { 1510 | ssize_t len; 1511 | int ev_idx = 0; 1512 | 1513 | len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); 1514 | if (unlikely(len < 0)) { 1515 | /* Some signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ 1516 | if (errno == EINTR || errno == EAGAIN) 1517 | continue; 1518 | else { 1519 | fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); 1520 | exit(EXIT_FAILURE); 1521 | } 1522 | } 1523 | 1524 | while (ev_idx < len) { 1525 | struct inotify_event *inev; 1526 | struct file_struct *f = NULL; 1527 | 1528 | inev = (struct inotify_event *) &buf[ev_idx]; 1529 | 1530 | /* Which file has produced the event? */ 1531 | for (i = 0; i < n_files; i++) { 1532 | if (!_files[i].ignore 1533 | && _files[i].fd >= 0 1534 | && _files[i].i_watch == inev->wd) { 1535 | f = &_files[i]; 1536 | break; 1537 | } 1538 | } 1539 | 1540 | if (unlikely(!f)) 1541 | break; 1542 | 1543 | if (handle_inotify_event(inev, f) < 0) 1544 | break; 1545 | 1546 | ev_idx += sizeof(struct inotify_event) + inev->len; 1547 | } 1548 | } 1549 | 1550 | close(ifd); 1551 | return -1; 1552 | } 1553 | 1554 | int main(int argc, char **argv) 1555 | { 1556 | int i, c, ret = 0; 1557 | int n_files; 1558 | unsigned long n_units = DEFAULT_N_LINES; 1559 | char forever = 0, mode = M_LINES; 1560 | char **filenames; 1561 | 1562 | int event_cnt = 1; 1563 | 1564 | /* Set up logging */ 1565 | openlog("AUDITD_BRO", 0, LOG_USER); 1566 | 1567 | au = auparse_init(AUSOURCE_FEED, 0); 1568 | auparse_add_callback(au, auparse_callback, &event_cnt, NULL); 1569 | 1570 | if (au == NULL) { 1571 | printf("Error - %s\n", strerror(errno)); 1572 | return 1; 1573 | } 1574 | 1575 | while ((c = getopt_long(argc, argv, "c:n:fvVh", long_opts, NULL)) != -1) { 1576 | switch (c) { 1577 | case 'c': 1578 | mode = M_BYTES; 1579 | /* fall through */ 1580 | case 'n': 1581 | if (*optarg == '+') { 1582 | from_begin = 1; 1583 | optarg++; 1584 | } else if (*optarg == '-') 1585 | optarg++; 1586 | 1587 | if (!is_digit(*optarg)) { 1588 | fprintf(stderr, "Error: Invalid number of units: %s\n", optarg); 1589 | exit(EXIT_FAILURE); 1590 | } 1591 | n_units = strtoul(optarg, NULL, 0); 1592 | break; 1593 | case 'f': 1594 | forever = 1; 1595 | break; 1596 | case 'v': 1597 | verbose = 1; 1598 | break; 1599 | case 'V': 1600 | fprintf(stdout, "%s %s\n", PROGRAM_NAME, VERSION); 1601 | exit(EXIT_SUCCESS); 1602 | case 'h': 1603 | usage(EXIT_SUCCESS); 1604 | default: 1605 | usage(EXIT_FAILURE); 1606 | } 1607 | } 1608 | 1609 | /* Do we have some files to read from? */ 1610 | if (optind < argc) { 1611 | n_files = argc - optind; 1612 | filenames = argv + optind; 1613 | } else { 1614 | /* It must be stdin then */ 1615 | static char *dummy_stdin = "-"; 1616 | n_files = 1; 1617 | filenames = &dummy_stdin; 1618 | 1619 | /* POSIX says that -f is ignored if no file operand is 1620 | specified and standard input is a pipe. */ 1621 | if (forever) { 1622 | struct stat finfo; 1623 | int rc = fstat(STDIN_FILENO, &finfo); 1624 | 1625 | if (unlikely(rc == -1)) { 1626 | fprintf(stderr, "Error: Could not stat stdin (%s)\n", strerror(errno)); 1627 | exit(EXIT_FAILURE); 1628 | } 1629 | 1630 | if (rc == 0 && IS_PIPELIKE(finfo.st_mode)) 1631 | forever = 0; 1632 | } 1633 | } // end stdin 1634 | 1635 | files = emalloc(n_files * sizeof(struct file_struct)); 1636 | 1637 | for (i = 0; i < n_files; i++) { 1638 | files[i].name = filenames[i]; 1639 | setup_file(&files[i]); 1640 | ret = tail_file(&files[i], n_units, mode, forever); 1641 | if (ret < 0) 1642 | ignore_file(&files[i]); 1643 | } 1644 | 1645 | if (forever) 1646 | ret = watch_files(files, n_files); 1647 | 1648 | free(files); 1649 | 1650 | auparse_flush_feed(au); 1651 | auparse_destroy(au); 1652 | closelog(); 1653 | 1654 | return ret; 1655 | } 1656 | 1657 | -------------------------------------------------------------------------------- /log_normalizer/auditparse.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2007, Tobias Klauser 3 | * 4 | * Licensed under the terms of the GNU General Public License; version 2 or later. 5 | */ 6 | 7 | #ifndef _INOTAIL_H 8 | #define _INOTAIL_H 9 | 10 | #include 11 | #include 12 | 13 | /* Number of items to tail. */ 14 | #define DEFAULT_N_LINES 10 15 | 16 | /* tail modes */ 17 | enum { M_LINES, M_BYTES }; 18 | 19 | /* Every tailed file is represented as a file_struct */ 20 | struct file_struct { 21 | char *name; /* Name of file (or '-' for stdin) */ 22 | int fd; /* File descriptor (or -1 if file is not open */ 23 | off_t size; /* File size */ 24 | blksize_t blksize; /* Blocksize for filesystem I/O */ 25 | unsigned ignore; /* Whether to ignore the file in further processing */ 26 | int i_watch; /* Inotify watch associated with file_struct */ 27 | }; 28 | 29 | #define PLACE_OBJ 1 30 | #define USER_OBJ 2 31 | #define SYSCALL_OBJ 3 32 | #define SOCK_OBJ 4 33 | #define EXECVE_OBJ 5 34 | #define GENERIC_OBJ 6 35 | 36 | int user_types[] = {1100, 1101, 1102, 1103, 1105, 1106, 1108, 1109, 1112, 1113, 1122, 1123}; 37 | int user_types_count = 12; 38 | 39 | #define F_A0 "a0" 40 | #define F_A1 "a1" 41 | #define F_A2 "a2" 42 | #define F_A3 "a3" 43 | #define F_ARG "arg" 44 | #define F_ARGC "argc" 45 | #define F_AUID "auid" 46 | #define F_COMM "comm" 47 | #define F_CWD "cwd" 48 | #define F_EGID "egid" 49 | #define F_EUID "euid" 50 | #define F_EXE "exe" 51 | #define F_EXIT "exit" 52 | #define F_FLAVOR "flavor" 53 | #define F_FSGID "fsgid" 54 | #define F_FSUID "fsuid" 55 | #define F_GID "gid" 56 | #define F_INODE "inode" 57 | #define F_HEY "key" 58 | #define F_MODE "mode" 59 | #define F_MSG "msg" 60 | #define F_NAME "name" 61 | #define F_NODE "node" 62 | #define F_AGID "ogid" 63 | #define F_PID "pid" 64 | #define F_PPID "ppid" 65 | #define F_SADDR "saddr" 66 | #define F_SES "ses" 67 | #define F_SGID "sgid" 68 | #define F_SUCCESS "success" 69 | #define F_SUID "suid" 70 | #define F_SYSCALL "syscall" 71 | #define F_TERMINAL "terminal" 72 | #define F_TIME "time" 73 | #define F_TTY "tty" 74 | #define F_TYPE "type" 75 | #define F_UID "uid" 76 | #define F_FLAVOR "flavor" 77 | #define F_OUID "ouid" 78 | #define F_OGID "ogid" 79 | #define F_TERM "terminal" 80 | #define F_KEY "key" 81 | 82 | #define IS_PIPELIKE(mode) \ 83 | (S_ISFIFO(mode) || S_ISSOCK(mode)) 84 | 85 | /* inotail works on these file types */ 86 | #define IS_TAILABLE(mode) \ 87 | (S_ISREG(mode) || IS_PIPELIKE(mode) || S_ISCHR(mode)) 88 | 89 | #define is_digit(c) ((c) >= '0' && (c) <= '9') 90 | 91 | #ifdef DEBUG 92 | # define dprintf(fmt, args...) fprintf(stderr, fmt, ##args) 93 | #else 94 | # define dprintf(fmt, args...) 95 | #endif /* DEBUG */ 96 | 97 | #ifdef __GNUC__ 98 | # define unlikely(x) __builtin_expect(!!(x), 0) 99 | #else 100 | # define unlikely(x) (x) 101 | #endif /* __GNUC__ */ 102 | 103 | #endif /* _INOTAIL_H */ 104 | 105 | static int tail_file(struct file_struct *f, unsigned long n_units, char mode, char forever); 106 | static int handle_inotify_event(struct inotify_event *inev, struct file_struct *f); 107 | static int watch_files(struct file_struct *files, int n_files); 108 | const char* auparse_interpret_field_wrap(auparse_state_t *_au); 109 | const char* auparse_get_field_str_wrap(auparse_state_t *_au); 110 | const char* auparse_get_field_name_wrap(auparse_state_t *_au); 111 | -------------------------------------------------------------------------------- /log_normalizer/changelog-original: -------------------------------------------------------------------------------- 1 | inotail 0.5 2 | 3 | * Output verbose file headers correctly when used in a pipe 4 | * Small code cleanups 5 | 6 | -- Tobias Klauser 2007-09-07 13:30 7 | 8 | inotail 0.4 9 | 10 | * Use dynamic buffers of optimal size (st_blksize in struct stat) for 11 | filesystem I/O (patch by Folkert van Heusden) 12 | * Added handling of EINTR/EAGAIN while watching files for changes (patch by 13 | Anthony Martinez) 14 | * Better error checking and handling (patch by Folkert van Heusden) 15 | * Various cleanups 16 | 17 | -- Tobias Klauser 2007-06-20 15:00 18 | 19 | inotail 0.3 20 | 21 | * Follow files even if they were moved 22 | * Fix a problem when tailing more than 4096 bytes/chars at once 23 | * Only print the filename once when the -v option is specified 24 | * Various small fixes and cleanups 25 | 26 | -- Tobias Klauser 2007-04-17 13:44 27 | 28 | inotail 0.2 29 | 30 | * Support for the -n/-c + options (tail relative to start of file) 31 | * Copyright and license cleanup 32 | * Various fixes 33 | 34 | -- Tobias Klauser 2006-11-30 17:56 35 | -------------------------------------------------------------------------------- /log_normalizer/inotify-syscalls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Inotify syscall numbers 3 | * Taken from the Linux kernel source tree 4 | * 5 | * Licensed under the terms of the GNU General Public License Version 2. 6 | * 7 | * Copyright (c) 2006-2007 Tobias Klauser 8 | */ 9 | 10 | #ifndef _LINUX_INOTIFY_SYSCALLS_H 11 | #define _LINUX_INOTIFY_SYSCALLS_H 12 | 13 | #include 14 | /* glibc already defines them for some architectures */ 15 | #ifndef __NR_inotify_init 16 | #if defined(__i386__) 17 | # define __NR_inotify_init 291 18 | # define __NR_inotify_add_watch 292 19 | # define __NR_inotify_rm_watch 293 20 | #elif defined(__x86_64__) 21 | # define __NR_inotify_init 253 22 | # define __NR_inotify_add_watch 254 23 | # define __NR_inotify_rm_watch 255 24 | #elif defined(__powerpc__) || defined(__powerpc64__) 25 | # define __NR_inotify_init 275 26 | # define __NR_inotify_add_watch 276 27 | # define __NR_inotify_rm_watch 277 28 | #elif defined (__ia64__) 29 | # define __NR_inotify_init 1277 30 | # define __NR_inotify_add_watch 1278 31 | # define __NR_inotify_rm_watch 1279 32 | #elif defined (__s390__) 33 | # define __NR_inotify_init 284 34 | # define __NR_inotify_add_watch 285 35 | # define __NR_inotify_rm_watch 286 36 | #elif defined (__alpha__) 37 | # define __NR_inotify_init 444 38 | # define __NR_inotify_add_watch 445 39 | # define __NR_inotify_rm_watch 446 40 | #elif defined (__sparc__) || defined (__sparc64__) 41 | # define __NR_inotify_init 151 42 | # define __NR_inotify_add_watch 152 43 | # define __NR_inotify_rm_watch 156 44 | #elif defined (__arm__) 45 | # define __NR_inotify_init (__NR_SYSCALL_BASE + 316) 46 | # define __NR_inotify_add_watch (__NR_SYSCALL_BASE + 317) 47 | # define __NR_inotify_rm_watch (__NR_SYSCALL_BASE + 318) 48 | #elif defined (__sh__) 49 | # define __NR_inotify_init 290 50 | # define __NR_inotify_add_watch 291 51 | # define __NR_inotify_rm_watch 292 52 | #elif defined (__m32r__) 53 | # define __NR_inotify_init 290 54 | # define __NR_inotify_add_watch 291 55 | # define __NR_inotify_rm_watch 292 56 | #elif defined (__hppa__) 57 | # define __NR_inotify_init 269 58 | # define __NR_inotify_add_watch 270 59 | # define __NR_inotify_rm_watch 271 60 | #elif defined (__mips__) 61 | # include 62 | # if _MIPS_SIM == _MIPS_SIM_ABI32 63 | # define __NR_Linux 4000 64 | # define __NR_inotify_init (__NR_Linux + 284) 65 | # define __NR_inotify_add_watch (__NR_Linux + 285) 66 | # define __NR_inotify_rm_watch (__NR_Linux + 286) 67 | # elif _MIPS_SIM == _MIPS_SIM_ABI64 68 | # define __NR_Linux 5000 69 | # define __NR_inotify_init (__NR_Linux + 243) 70 | # define __NR_inotify_add_watch (__NR_Linux + 244) 71 | # define __NR_inotify_rm_watch (__NR_Linux + 245) 72 | # elif _MIPS_SIM == _MIPS_SIM_NABI32 73 | # define __NR_Linux 6000 74 | # define __NR_inotify_init (__NR_Linux + 247) 75 | # define __NR_inotify_add_watch (__NR_Linux + 248) 76 | # define __NR_inotify_rm_watch (__NR_Linux + 249) 77 | # endif 78 | #elif defined (__m68k__) 79 | # define __NR_inotify_init 284 80 | # define __NR_inotify_add_watch 285 81 | # define __NR_inotify_rm_watch 286 82 | #else 83 | # error "inotify not supported on this architecture!" 84 | #endif 85 | #endif /* __NR_inotify_init */ 86 | 87 | static inline int inotify_init(void) 88 | { 89 | return syscall(__NR_inotify_init); 90 | } 91 | 92 | static inline int inotify_add_watch(int fd, const char *name, __u32 mask) 93 | { 94 | return syscall(__NR_inotify_add_watch, fd, name, mask); 95 | } 96 | 97 | static inline int inotify_rm_watch(int fd, __u32 wd) 98 | { 99 | return syscall(__NR_inotify_rm_watch, fd, wd); 100 | } 101 | 102 | #endif /* _LINUX_INOTIFY_SYSCALLS_H */ 103 | -------------------------------------------------------------------------------- /log_normalizer/inotify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Inode based directory notification for Linux 3 | * Taken from the Linux kernel source tree 4 | * 5 | * Licensed under the terms of the GNU General Public License Version 2. 6 | * 7 | * Copyright (C) 2005 John McCutchan 8 | */ 9 | 10 | #ifndef _LINUX_INOTIFY_H 11 | #define _LINUX_INOTIFY_H 12 | 13 | #include 14 | 15 | /* 16 | * struct inotify_event - structure read from the inotify device for each event 17 | * 18 | * When you are watching a directory, you will receive the filename for events 19 | * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd. 20 | */ 21 | struct inotify_event { 22 | __s32 wd; /* watch descriptor */ 23 | __u32 mask; /* watch mask */ 24 | __u32 cookie; /* cookie to synchronize two events */ 25 | __u32 len; /* length (including nulls) of name */ 26 | char name[0]; /* stub for possible name */ 27 | }; 28 | 29 | /* the following are legal, implemented events that user-space can watch for */ 30 | #define IN_ACCESS 0x00000001 /* File was accessed */ 31 | #define IN_MODIFY 0x00000002 /* File was modified */ 32 | #define IN_ATTRIB 0x00000004 /* Metadata changed */ 33 | #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ 34 | #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ 35 | #define IN_OPEN 0x00000020 /* File was opened */ 36 | #define IN_MOVED_FROM 0x00000040 /* File was moved from X */ 37 | #define IN_MOVED_TO 0x00000080 /* File was moved to Y */ 38 | #define IN_CREATE 0x00000100 /* Subfile was created */ 39 | #define IN_DELETE 0x00000200 /* Subfile was deleted */ 40 | #define IN_DELETE_SELF 0x00000400 /* Self was deleted */ 41 | #define IN_MOVE_SELF 0x00000800 /* Self was moved */ 42 | 43 | /* the following are legal events. they are sent as needed to any watch */ 44 | #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ 45 | #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 46 | #define IN_IGNORED 0x00008000 /* File was ignored */ 47 | 48 | /* helper events */ 49 | #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */ 50 | #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ 51 | 52 | /* special flags */ 53 | #define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */ 54 | #define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */ 55 | #define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ 56 | #define IN_ISDIR 0x40000000 /* event occurred against dir */ 57 | #define IN_ONESHOT 0x80000000 /* only send event once */ 58 | 59 | /* 60 | * All of the events - we build the list by hand so that we can add flags in 61 | * the future and not break backward compatibility. Apps will get only the 62 | * events that they originally wanted. Be sure to add new events here! 63 | */ 64 | #define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \ 65 | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \ 66 | IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \ 67 | IN_MOVE_SELF) 68 | 69 | #endif /* _LINUX_INOTIFY_H */ 70 | -------------------------------------------------------------------------------- /log_normalizer/modp_burl.c: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ 2 | /* vi: set expandtab shiftwidth=4 tabstop=4: */ 3 | 4 | /** 5 | * \file 6 | *
  7 |  * BFASTURL.c High performance URL encoder/decoder
  8 |  * http://code.google.com/p/stringencoders/
  9 |  *
 10 |  * Copyright © 2006,2007  Nick Galbreath -- nickg [at] modp [dot] com
 11 |  * All rights reserved.
 12 |  *
 13 |  * Redistribution and use in source and binary forms, with or without
 14 |  * modification, are permitted provided that the following conditions are
 15 |  * met:
 16 |  *
 17 |  *   Redistributions of source code must retain the above copyright
 18 |  *   notice, this list of conditions and the following disclaimer.
 19 |  *
 20 |  *   Redistributions in binary form must reproduce the above copyright
 21 |  *   notice, this list of conditions and the following disclaimer in the
 22 |  *   documentation and/or other materials provided with the distribution.
 23 |  *
 24 |  *   Neither the name of the modp.com nor the names of its
 25 |  *   contributors may be used to endorse or promote products derived from
 26 |  *   this software without specific prior written permission.
 27 |  *
 28 |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 29 |  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 30 |  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 31 |  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 32 |  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 33 |  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 34 |  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 35 |  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 36 |  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 37 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 38 |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 39 |  *
 40 |  * This is the standard "new" BSD license:
 41 |  * http://www.opensource.org/licenses/bsd-license.php
 42 |  * 
43 | */ 44 | 45 | #include "modp_burl.h" 46 | #include "modp_stdint.h" 47 | #include "modp_burl_data.h" 48 | 49 | int modp_burl_encode(char* dest, const char* src, int len) 50 | { 51 | 52 | const char* deststart = dest; 53 | const uint8_t* s = (const uint8_t*)src; 54 | const uint8_t* srcend = s + len; 55 | char c; 56 | uint8_t x; 57 | 58 | while (s < srcend) { 59 | x = *s++; 60 | c = (char)gsUrlEncodeMap[x]; 61 | if (c) { 62 | *dest++ = c; 63 | } else { 64 | *dest++ = '%'; 65 | *dest++ = (char)gsHexEncodeMap1[x]; 66 | *dest++ = (char)gsHexEncodeMap2[x]; 67 | /* 68 | is the equiv of this 69 | static const char sHexChars[] = "0123456789ABCDEF"; 70 | *dest++ = (char)sHexChars[x >> 4]; 71 | *dest++ = (char)sHexChars[x & 0x0F]; 72 | */ 73 | } 74 | } 75 | *dest = '\0'; 76 | return (int)(dest - deststart); // compute "strlen" of dest. 77 | } 78 | 79 | /** 80 | * The implementation is identical except it uses a 81 | * different array 82 | */ 83 | int modp_burl_min_encode(char* dest, const char* src, int len) 84 | { 85 | 86 | const char* deststart = dest; 87 | const uint8_t* s = (const uint8_t*)src; 88 | const uint8_t* srcend = s + len; 89 | char c; 90 | uint8_t x; 91 | 92 | while (s < srcend) { 93 | x = *s++; 94 | c = (char)(gsUrlEncodeMinMap[x]); /** CHANGE HERE **/ 95 | if (c) { 96 | *dest++ = c; 97 | } else { 98 | *dest++ = '%'; 99 | *dest++ = (char) gsHexEncodeMap1[x]; 100 | *dest++ = (char)(gsHexEncodeMap2[x]); 101 | /* 102 | is the equiv of this 103 | static const char sHexChars[] = "0123456789ABCDEF"; 104 | *dest++ = sHexChars[x >> 4]; 105 | *dest++ = sHexChars[x & 0x0F]; 106 | */ 107 | } 108 | } 109 | *dest = '\0'; 110 | return (int)(dest - deststart); // compute "strlen" of dest. 111 | } 112 | 113 | /** 114 | * Give exact size of encoded output string 115 | * without doing the encoding 116 | */ 117 | int modp_burl_encode_strlen(const char* src, const int len) 118 | { 119 | int count = 0; 120 | const char* srcend = src + len; 121 | while (src < srcend) { 122 | if (gsUrlEncodeMap[ (uint8_t) *src++]) { 123 | count++; 124 | } else { 125 | count += 3; 126 | } 127 | } 128 | return count; 129 | } 130 | 131 | /** 132 | * Give exact size of encoded output string 133 | * without doing the encoding 134 | */ 135 | int modp_burl_min_encode_strlen(const char* src, const int len) 136 | { 137 | int count = 0; 138 | const char* srcend = src + len; 139 | while (src < srcend) { 140 | if (gsUrlEncodeMinMap[ (uint8_t) *src++]) { 141 | count++; 142 | } else { 143 | count += 3; 144 | } 145 | } 146 | return count; 147 | } 148 | 149 | int modp_burl_decode(char* dest, const char* s, int len) 150 | { 151 | uint32_t d = 0; // used for decoding %XX 152 | const uint8_t* src = (const uint8_t*) s; 153 | const char* deststart = dest; 154 | const uint8_t* srcend = (const uint8_t*)(src + len); 155 | const uint8_t* srcendloop = (const uint8_t*)(srcend - 2); 156 | 157 | while (src < srcendloop) { 158 | switch (*src) { 159 | case '+': 160 | *dest++ = ' '; 161 | src++; 162 | break; 163 | case '%': 164 | d = (gsHexDecodeMap[(uint32_t)(*(src + 1))] << 4) | 165 | gsHexDecodeMap[(uint32_t)(*(src + 2))]; 166 | if (d < 256) { // if one of the hex chars is bad, d >= 256 167 | *dest = (char) d; 168 | dest++; 169 | src += 3; 170 | } else { 171 | *dest++ = '%'; 172 | src++; 173 | } 174 | break; 175 | default: 176 | *dest++ = (char) *src++; 177 | } 178 | } 179 | 180 | // handle last two chars 181 | // dont decode "%XX" 182 | while (src < srcend) { 183 | switch (*src) { 184 | case '+': 185 | *dest++ = ' '; 186 | src++; 187 | break; 188 | default: 189 | *dest++ = (char)( *src++); 190 | } 191 | } 192 | 193 | *dest = '\0'; 194 | return (int)(dest - deststart); // compute "strlen" of dest. 195 | } 196 | 197 | -------------------------------------------------------------------------------- /log_normalizer/modp_burl.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ 2 | /* vi: set expandtab shiftwidth=4 tabstop=4: */ 3 | 4 | /** 5 | * \file 6 | *
  7 |  * High Performance URL Encoder/Decoder
  8 |  *
  9 |  * Copyright © 2006, 2007  Nick Galbreath -- nickg [at] modp [dot] com
 10 |  * All rights reserved.
 11 |  *
 12 |  * http://code.google.com/p/stringencoders/
 13 |  *
 14 |  * Released under bsd license.  See bfast64.c for details.
 15 |  * 
16 | */ 17 | 18 | #ifndef COM_MODP_STRINGENCODERS_BURL 19 | #define COM_MODP_STRINGENCODERS_BURL 20 | 21 | #ifdef __cplusplus 22 | #define BEGIN_C extern "C" { 23 | #define END_C } 24 | #else 25 | #define BEGIN_C 26 | #define END_C 27 | #endif 28 | 29 | BEGIN_C 30 | 31 | /** 32 | * Url encode a string. This uses a very strict definition of url 33 | * encoding. The only characters NOT encoded are A-Z, a-z, 0-9, "-", 34 | * "_", ".", along with the space char getting mapped to "+". 35 | * Everything else is escaped using "%HEXHEX" format. This is 36 | * identical to the implementation of php's urlencode and nearly 37 | * identical to Java's UrlEncoder class (they do not escape '*' for 38 | * some reason). 39 | * 40 | * \param[out] dest output string. Must 41 | * \param[in] str The input string 42 | * \param[in] len The length of the input string, excluding any 43 | * final null byte. 44 | */ 45 | int modp_burl_encode(char* dest, const char* str, int len); 46 | 47 | /** 48 | * Url encode a string. This uses a minimal definition of url 49 | * encoding. This works similar to the previous function except '~', 50 | * '!', '$', '\'', '(', ')', '*', ',', ';', ':', '@', '/', '?' are NOT 51 | * escaped. This will allow decoding by standard url-decoders and 52 | * make the encoded urls more readable. 53 | * 54 | * \param[out] dest output string. Must 55 | * \param[in] str The input string 56 | * \param[in] len The length of the input string, excluding any 57 | * final null byte. 58 | */ 59 | int modp_burl_min_encode(char* dest, const char* str, int len); 60 | 61 | /** \brief get size of output string w/o doing actual encoding 62 | * 63 | * \param[in] src input string, not null 64 | * \param[in] len length of input string 65 | * \return length of output string NOT including any final null byte 66 | */ 67 | int modp_burl_min_encode_strlen(const char* src, const int len); 68 | 69 | /** 70 | * Provides the maximum size for output string given 71 | * and input size of A bytes. 72 | */ 73 | #define modp_burl_encode_len(A) (3*A + 1) 74 | 75 | /** 76 | * Given the exact size of output string. 77 | * 78 | * Can be used to allocate the right amount of memory for 79 | * modp_burl_encode. Be sure to add 1 byte for final null. 80 | * 81 | * This is somewhat expensive since it examines every character 82 | * in the input string 83 | * 84 | * \param[in] str The input string 85 | * \param[in] len THe length of the input string, excluding any 86 | * final null byte (i.e. strlen(str)) 87 | * \return the size of the output string, excluding the final 88 | * null byte. 89 | */ 90 | int modp_burl_encode_strlen(const char* str, const int len); 91 | 92 | /** 93 | * URL Decode a string 94 | * 95 | * \param[out] dest The output string. Must be at least (len + 1) 96 | * bytes allocated. This may be the same as the input buffer. 97 | * \param[in] str The input string that is URL encoded. 98 | * \param[in] len The length of the input string (excluding final 99 | * null byte) 100 | * \return the strlen of the output string. 101 | */ 102 | int modp_burl_decode(char* dest, const char* str, int len); 103 | 104 | /** 105 | * Returns memory required to decoded a url-encoded 106 | * string of length A. 107 | * 108 | */ 109 | #define modp_burl_decode_len(A) (A + 1) 110 | 111 | END_C 112 | 113 | #ifdef __cplusplus 114 | #include 115 | #include 116 | 117 | namespace modp { 118 | 119 | inline std::string url_encode(const char* s, size_t len) 120 | { 121 | std::string x(modp_burl_encode_len(len), '\0'); 122 | int d = modp_burl_encode(const_cast(x.data()), s, len); 123 | x.erase(d, std::string::npos); 124 | return x; 125 | } 126 | 127 | inline std::string url_encode(const char* s) 128 | { 129 | return url_encode(s, strlen(s)); 130 | } 131 | 132 | inline std::string url_encode(const std::string& s) 133 | { 134 | return url_encode(s.data(), s.size()); 135 | } 136 | 137 | /** 138 | * Standard (maximal) url encoding. 139 | * 140 | * \param[in,out] s the string to be encoded 141 | * \return a reference to the input string 142 | */ 143 | inline std::string& url_encode(std::string& s) 144 | { 145 | std::string x(url_encode(s.data(), s.size())); 146 | s.swap(x); 147 | return s; 148 | } 149 | 150 | /** 151 | * Minimal Url Encoding 152 | * 153 | * \param[in,out] s the string to be encoded 154 | * \return a reference to the input string 155 | */ 156 | inline std::string& url_min_encode(std::string& s) 157 | { 158 | std::string x(modp_burl_encode_len(s.size()), '\0'); 159 | int d = modp_burl_min_encode(const_cast(x.data()), s.data(), s.size()); 160 | x.erase(d, std::string::npos); 161 | s.swap(x); 162 | return s; 163 | } 164 | 165 | inline std::string url_min_encode(const std::string& s) 166 | { 167 | std::string x(modp_burl_encode_len(s.size()), '\0'); 168 | int d = modp_burl_min_encode(const_cast(x.data()), s.data(), s.size()); 169 | x.erase(d, std::string::npos); 170 | return x; 171 | } 172 | 173 | /** 174 | * Url decode a string. 175 | * This function does not allocate memory. 176 | * 177 | * \param[in,out] s the string to be decoded 178 | * \return a reference to the input string. 179 | * There is no error case, bad characters are passed through 180 | */ 181 | inline std::string& url_decode(std::string& s) 182 | { 183 | int d = modp_burl_decode(const_cast(s.data()), s.data(), s.size()); 184 | s.erase(d, std::string::npos); 185 | return s; 186 | } 187 | 188 | inline std::string url_decode(const char* str) 189 | { 190 | std::string s(str); 191 | url_decode(s); 192 | return s; 193 | } 194 | 195 | inline std::string url_decode(const char* str, size_t len) 196 | { 197 | std::string s(str, len); 198 | url_decode(s); 199 | return s; 200 | } 201 | 202 | inline std::string url_decode(const std::string& s) 203 | { 204 | std::string x(s); 205 | url_decode(x); 206 | return x; 207 | } 208 | } 209 | #endif 210 | 211 | #endif 212 | -------------------------------------------------------------------------------- /log_normalizer/modp_burl_data.h: -------------------------------------------------------------------------------- 1 | static const unsigned char gsUrlEncodeMap[256] = { 2 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 3 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 4 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 5 | '\0', '\0', '+', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 6 | '\0', '\0', '\0', '\0', '\0', '-', '.', '\0', '0', '1', 7 | '2', '3', '4', '5', '6', '7', '8', '9', '\0', '\0', 8 | '\0', '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D', 'E', 9 | 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 10 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 11 | 'Z', '\0', '\0', '\0', '\0', '_', '\0', 'a', 'b', 'c', 12 | 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 13 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 14 | 'x', 'y', 'z', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 15 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 16 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 17 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 18 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 19 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 20 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 21 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 22 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 23 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 24 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 25 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 26 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 27 | '\0', '\0', '\0', '\0', '\0', '\0' 28 | }; 29 | 30 | static const unsigned char gsUrlEncodeMinMap[256] = { 31 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 32 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 33 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 34 | '\0', '\0', '+', '!', '\0', '\0', '$', '\0', '\0', '\0', 35 | '(', ')', '*', '\0', ',', '-', '.', '/', '0', '1', 36 | '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', 37 | '\0', '\0', '\0', '?', '@', 'A', 'B', 'C', 'D', 'E', 38 | 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 39 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 40 | 'Z', '\0', '\0', '\0', '\0', '_', '\0', 'a', 'b', 'c', 41 | 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 42 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 43 | 'x', 'y', 'z', '\0', '\0', '\0', '~', '\0', '\0', '\0', 44 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 45 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 46 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 47 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 48 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 49 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 50 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 51 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 52 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 53 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 54 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 55 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 56 | '\0', '\0', '\0', '\0', '\0', '\0' 57 | }; 58 | 59 | static const uint32_t gsHexDecodeMap[256] = { 60 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 61 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 62 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 63 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 64 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256, 65 | 256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256, 66 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 67 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 68 | 256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256, 69 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 70 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 71 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 72 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 73 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 74 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 75 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 76 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 77 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 78 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 79 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 80 | 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 81 | 256, 256, 256, 256 82 | }; 83 | 84 | static const unsigned char gsHexEncodeMap1[256] = { 85 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 86 | '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', 87 | '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', 88 | '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', 89 | '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', 90 | '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', 91 | '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', 92 | '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', 93 | '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', 94 | '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', 95 | '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', 96 | '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', 97 | '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', 98 | '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', 99 | '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', 100 | '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', 101 | 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 102 | 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 103 | 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 104 | 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 105 | 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'D', 'D', 106 | 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 107 | 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', 'E', 'E', 108 | 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 109 | 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 110 | 'F', 'F', 'F', 'F', 'F', 'F' 111 | }; 112 | 113 | static const unsigned char gsHexEncodeMap2[256] = { 114 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 115 | 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', 116 | '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 117 | 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', 118 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', 119 | '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 120 | 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', 121 | '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 122 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 123 | 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', 124 | '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 125 | 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', 126 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', 127 | '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 128 | 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', 129 | '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 130 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 131 | 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', 132 | '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 133 | 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', 134 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', 135 | '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 136 | 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', 137 | '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 138 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 139 | 'A', 'B', 'C', 'D', 'E', 'F' 140 | }; 141 | 142 | -------------------------------------------------------------------------------- /log_normalizer/modp_stdint.h: -------------------------------------------------------------------------------- 1 | /* vi: set ft=c expandtab shiftwidth=4 tabstop=4: */ 2 | #ifndef MODP_STDINT_H_ 3 | #define MODP_STDINT_H_ 4 | 5 | #ifndef _WIN32 6 | # include 7 | #else 8 | /* win64 is llp64 so these are the same for 32/64bit 9 | so no check for _WIN64 is required. 10 | */ 11 | typedef unsigned char uint8_t; 12 | typedef signed char int8_t; 13 | typedef unsigned short uint16_t; 14 | typedef signed short int16_t; 15 | typedef unsigned int uint32_t; 16 | typedef signed int int32_t; 17 | typedef unsigned __int64 uint64_t; 18 | typedef signed __int64 int64_t; 19 | #endif 20 | 21 | #endif /* MODP_STDINT_H_ */ 22 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/EXECVE_OBJ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../../bindings/python/build/lib.linux-i686-2.4' 7 | import re 8 | import auparse 9 | import audit 10 | import util 11 | import urllib 12 | 13 | # filter for object 14 | data_filter = ['flavor', 'type', 'time', 'argc' ] 15 | EXECVE_ARG_RE = re.compile('a[0-9]{1,3}') 16 | 17 | class init: 18 | # common fields 19 | flavor = 'EXECVE_OBJ' 20 | time = 1346257201.413 21 | type = 'NULL' 22 | node = 'localhost' 23 | # 24 | argc = -1 25 | # aggrigate string holding the entire exec argument set 26 | arg = 'NULL' 27 | 28 | def load(s,au): 29 | 30 | event = au.get_timestamp() 31 | arg_count = 0 32 | 33 | if event is None: 34 | print "Error getting timestamp - aborting" 35 | return 0 36 | 37 | s.time = "%d.%d" % (event.sec,event.milli) 38 | 39 | au.first_field() 40 | while True: 41 | key = au.get_field_name() 42 | value = au.interpret_field() 43 | value_raw = au.get_field_str() 44 | 45 | if key == 'node': 46 | s.node = urllib.quote(value) 47 | if key == 'type': 48 | s.type = urllib.quote(value) 49 | elif key == 'argc': 50 | s.argc = value 51 | 52 | # add togther the collection of arguments into a 53 | # single string, then encode it 54 | if EXECVE_ARG_RE.match(key) : 55 | if arg_count == 0: 56 | s.arg = '' 57 | 58 | s.arg = "%s %s" % (s.arg,value) 59 | arg_count = arg_count + 1 60 | 61 | if arg_count == int(s.argc): 62 | s.arg = urllib.quote(s.arg) 63 | 64 | if not au.next_field(): 65 | break 66 | # some times if argc == -1 there is a bunch of kindof 67 | # interesting, but not useful text. snip it 68 | if s.argc == -1: 69 | s.arg = '' 70 | 71 | return s 72 | 73 | def print_o(s): 74 | print "%s %s %s %s %s %s %s %s %s %s" % (s.flavor, s.type, s.time, s.node, s.cwd, s.path_name, s.inode, s.mode, s.ouid, s.ogid) 75 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/GENERIC_OBJ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../../bindings/python/build/lib.linux-i686-2.4' 7 | import re 8 | import auparse 9 | import audit 10 | import util 11 | import urllib 12 | 13 | # filter for object 14 | data_filter = [ 'node', 'msg', 'auid', 'egid', 'euid', 'fsgid', 'fsuid', 'gid', 'suid', 'sgid', 'uid', 'comm', 'exe', 'pid', 'ppid', 'cwd', 'key', 'tty', 'terminal', 'saddr', 'type', 'ses', 'auid', 'exit', 'success', 'a0', 'a1', 'a2' ] 15 | 16 | 17 | class init: 18 | # common fields 19 | flavor = 'GENERIC_OBJ' 20 | time = 1346257201.413 21 | node = 'localhost' 22 | # All events that are logged from one application's system call have the same event ID 23 | #syscall_id = 0 24 | # ses: The login session ID - maps user login to a process 25 | ses = -1 26 | # auid: audit user identity - remains the same through user priv translations like su 27 | auid = -1 28 | type = 'NULL' 29 | # 30 | # who 31 | egid = -1 32 | euid = -1 33 | fsgid = -1 34 | fsuid = -1 35 | gid = -1 36 | suid = -1 37 | sgid = -1 38 | uid = -1 39 | ## process info 40 | # comm: The application name under which it appears in the task list. 41 | comm = 'NULL' 42 | # exe: The resolved pathname to the binary program. 43 | exe = 'NULL' 44 | a0 = 'NULL' 45 | a1 = 'NULL' 46 | a2 = 'NULL' 47 | pid = -1 48 | ppid = -1 49 | # success: Whether the system call succeeded or failed. 50 | success = 'NULL' 51 | # exit: The exit value returned by the system call. 52 | exit = 0 53 | key = 'NULL' 54 | tty = 'NULL' 55 | terminal = 'NULL' 56 | #saddr = "NULL" 57 | 58 | def load(s,au): 59 | 60 | event = au.get_timestamp() 61 | if event is None: 62 | print "Error getting timestamp - aborting" 63 | return 0 64 | 65 | s.time = "%d.%d" % (event.sec,event.milli) 66 | 67 | au.first_field() 68 | while True: 69 | key = au.get_field_name() 70 | value = au.interpret_field() 71 | value_raw = au.get_field_str() 72 | 73 | if key in data_filter: 74 | 75 | if key == 'node': 76 | s.node = urllib.quote(value) 77 | if key == 'type': 78 | s.type = urllib.quote(value) 79 | elif key == 'node': 80 | s.node = urllib.quote(value) 81 | elif key == 'msg': 82 | s.msg = urllib.quote(value) 83 | elif key == 'auid': 84 | s.auid = value_raw 85 | elif key == 'egid': 86 | s.egid = value 87 | elif key == 'euid': 88 | s.euid = value 89 | elif key == 'fsgid': 90 | s.fsgid = value 91 | elif key == 'fsuid': 92 | s.fsuid = value 93 | elif key == 'gid': 94 | s.gid = value 95 | elif key == 'suid': 96 | s.suid = value 97 | elif key == 'sgid': 98 | s.sgid = value 99 | elif key == 'uid': 100 | s.uid = value 101 | elif key == 'comm': 102 | s.comm = urllib.quote(value) 103 | elif key == 'exe': 104 | s.exe = urllib.quote(value) 105 | elif key == 'pid': 106 | s.pid = value_raw 107 | elif key == 'ppid': 108 | s.ppid = value_raw 109 | elif key == 'key': 110 | s.key = value 111 | elif key == 'tty': 112 | if value == '(none)': 113 | s.tty = 'NO_TTY' 114 | else: 115 | s.tty = value 116 | elif key == 'terminal': 117 | if value == '(none)': 118 | s.terminal = 'NO_TERMINAL' 119 | else: 120 | s.terminal = value 121 | elif key == 'saddr': 122 | s.saddr = value 123 | elif key == 'type': 124 | s.type = value 125 | elif key == 'ses': 126 | s.ses = value_raw 127 | elif key == 'auid': 128 | s.auid = value_raw 129 | elif key == 'exit': 130 | s.exit = urllib.quote(value) 131 | elif key == 'success': 132 | s.success = value 133 | elif key == 'a0': 134 | s.a0 = urllib.quote(value_raw) 135 | elif key == 'a1': 136 | s.a1 = urllib.quote(value_raw) 137 | elif key == 'a2': 138 | s.a2 = urllib.quote(value_raw) 139 | 140 | if not au.next_field(): 141 | break 142 | 143 | return s 144 | 145 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/PLACE_OBJ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../../bindings/python/build/lib.linux-i686-2.4' 7 | import re 8 | import auparse 9 | import audit 10 | import util 11 | import urllib 12 | 13 | # filter for object 14 | data_filter = ['flavor', 'type', 'time', 'node', 'cwd', 'name', 'inode', 'mode', 'ouid', 'ogid'] 15 | 16 | class init: 17 | # common fields 18 | flavor = 'PLACE_OBJ' 19 | time = 1346257201.413 20 | type = 'NULL' 21 | node = 'localhost' 22 | # 23 | cwd = 'NULL' 24 | path_name = 'NULL' 25 | inode = -1 26 | mode = -1 27 | ouid = -1 28 | ogid = -1 29 | 30 | def load(s,au): 31 | 32 | event = au.get_timestamp() 33 | if event is None: 34 | print "Error getting timestamp - aborting" 35 | return 0 36 | 37 | s.time = "%d.%d" % (event.sec,event.milli) 38 | 39 | au.first_field() 40 | while True: 41 | key = au.get_field_name() 42 | value = au.interpret_field() 43 | value_raw = au.get_field_str() 44 | 45 | if key in data_filter: 46 | 47 | if key == 'node': 48 | s.node = urllib.quote(value) 49 | if key == 'type': 50 | s.type = urllib.quote(value) 51 | elif key == 'cwd': 52 | s.cwd = urllib.quote(value) 53 | elif key == 'name': 54 | s.path_name = urllib.quote(value) 55 | elif key == 'inode': 56 | s.inode = value 57 | elif key == 'mode': 58 | s.mode = value_raw 59 | elif key == 'ouid': 60 | s.ouid = value 61 | elif key == 'ogid': 62 | s.ogid = value 63 | 64 | if not au.next_field(): 65 | break 66 | 67 | return s 68 | 69 | def print_o(s): 70 | print "%s %s %s %s %s %s %s %s %s %s" % (s.flavor, s.type, s.time, s.node, s.cwd, s.path_name, s.inode, s.mode, s.ouid, s.ogid) 71 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/SOCK_OBJ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../../bindings/python/build/lib.linux-i686-2.4' 7 | import re 8 | import auparse 9 | import audit 10 | import util 11 | import urllib 12 | 13 | # filter for object 14 | data_filter = ['flavor', 'type', 'time', 'node', 'saddr'] 15 | 16 | class init: 17 | # common fields 18 | flavor = 'SADDR_OBJ' 19 | time = 1346257201.413 20 | type = 'NULL' 21 | node = 'localhost' 22 | # 23 | saddr = 'NULL' 24 | 25 | def load(s,au): 26 | 27 | event = au.get_timestamp() 28 | if event is None: 29 | print "Error getting timestamp - aborting" 30 | return 0 31 | 32 | s.time = "%d.%d" % (event.sec,event.milli) 33 | 34 | au.first_field() 35 | while True: 36 | key = au.get_field_name() 37 | value = au.interpret_field() 38 | value_raw = au.get_field_str() 39 | 40 | if key in data_filter: 41 | 42 | if key == 'node': 43 | s.node = urllib.quote(value) 44 | if key == 'type': 45 | s.type = urllib.quote(value) 46 | elif key == 'saddr': 47 | s.saddr = urllib.quote(value) 48 | 49 | if not au.next_field(): 50 | break 51 | 52 | return s 53 | 54 | def print_o(s): 55 | print "%s %s %s %s %s %s %s %s %s %s" % (s.flavor, s.type, s.time, s.node, s.cwd, s.path_name, s.inode, s.mode, s.ouid, s.ogid) 56 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/SYSCALL_OBJ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../../bindings/python/build/lib.linux-i686-2.4' 7 | import re 8 | import auparse 9 | import audit 10 | import util 11 | import urllib 12 | 13 | # filter for object 14 | data_filter = [ 'node', 'msg', 'auid', 'egid', 'euid', 'fsgid', 'fsuid', 'gid', 'suid', 'sgid', 'uid', 'comm', 'exe', 'pid', 'ppid', 'cwd', 'key', 'tty', 'syscall', 'saddr', 'type', 'ses', 'auid', 'exit', 'success', 'a0', 'a1', 'a2' ] 15 | 16 | 17 | class init: 18 | # common fields 19 | flavor = 'SYSCALL_OBJ' 20 | time = 1346257201.413 21 | node = 'localhost' 22 | # All events that are logged from one application's system call have the same event ID 23 | #syscall_id = 0 24 | # ses: The login session ID - maps user login to a process 25 | ses = -1 26 | # auid: audit user identity - remains the same through user priv translations like su 27 | auid = -1 28 | type = 'NULL' 29 | # 30 | # who 31 | egid = -1 32 | euid = -1 33 | fsgid = -1 34 | fsuid = -1 35 | gid = -1 36 | suid = -1 37 | sgid = -1 38 | uid = -1 39 | ## process info 40 | # comm: The application name under which it appears in the task list. 41 | comm = 'NULL' 42 | # exe: The resolved pathname to the binary program. 43 | exe = 'NULL' 44 | a0 = 'NULL' 45 | a1 = 'NULL' 46 | a2 = 'NULL' 47 | pid = -1 48 | ppid = -1 49 | # success: Whether the system call succeeded or failed. 50 | success = 'NULL' 51 | # exit: The exit value returned by the system call. 52 | exit = 0 53 | key = 'NULL' 54 | tty = 'NULL' 55 | syscall = 'NULL' 56 | #saddr = "NULL" 57 | 58 | def load(s,au): 59 | 60 | event = au.get_timestamp() 61 | if event is None: 62 | print "Error getting timestamp - aborting" 63 | return 0 64 | 65 | s.time = "%d.%d" % (event.sec,event.milli) 66 | 67 | au.first_field() 68 | while True: 69 | key = au.get_field_name() 70 | value = au.interpret_field() 71 | value_raw = au.get_field_str() 72 | 73 | if key in data_filter: 74 | 75 | if key == 'node': 76 | s.node = urllib.quote(value) 77 | if key == 'type': 78 | s.type = urllib.quote(value) 79 | elif key == 'node': 80 | s.node = urllib.quote(value) 81 | elif key == 'msg': 82 | s.msg = urllib.quote(value) 83 | elif key == 'auid': 84 | s.auid = value_raw 85 | elif key == 'egid': 86 | s.egid = value 87 | elif key == 'euid': 88 | s.euid = value 89 | elif key == 'fsgid': 90 | s.fsgid = value 91 | elif key == 'fsuid': 92 | s.fsuid = value 93 | elif key == 'gid': 94 | s.gid = value 95 | elif key == 'suid': 96 | s.suid = value 97 | elif key == 'sgid': 98 | s.sgid = value 99 | elif key == 'uid': 100 | s.uid = value 101 | elif key == 'comm': 102 | s.comm = urllib.quote(value) 103 | elif key == 'exe': 104 | s.exe = urllib.quote(value) 105 | elif key == 'pid': 106 | s.pid = value 107 | elif key == 'ppid': 108 | s.ppid = value 109 | elif key == 'key': 110 | s.key = value 111 | elif key == 'tty': 112 | if value == '(none)': 113 | s.tty = 'NO_TTY' 114 | else: 115 | s.tty = value 116 | elif key == 'syscall': 117 | s.syscall = value 118 | elif key == 'saddr': 119 | s.saddr = value 120 | elif key == 'type': 121 | s.type = value 122 | elif key == 'ses': 123 | s.ses = value_raw 124 | elif key == 'auid': 125 | s.auid = value 126 | elif key == 'exit': 127 | s.exit = urllib.quote(value) 128 | elif key == 'success': 129 | s.success = value 130 | elif key == 'a0': 131 | s.a0 = urllib.quote(value_raw) 132 | elif key == 'a1': 133 | s.a1 = urllib.quote(value_raw) 134 | elif key == 'a2': 135 | s.a2 = urllib.quote(value_raw) 136 | 137 | if not au.next_field(): 138 | break 139 | 140 | return s 141 | 142 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/USER_OBJ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../../bindings/python/build/lib.linux-i686-2.4' 7 | import re 8 | import auparse 9 | import audit 10 | import util 11 | import urllib 12 | 13 | # filter for object 14 | data_filter = [ 'pid', 'time', 'node', 'ses', 'auid', 'type', 'egid', 'euid', 'fsgid', 'fsuid', 'gid', 'suid', 'sgid', 'uid', 'success', 'exit', 'terminal', 'exe'] 15 | 16 | class init: 17 | # common fields 18 | flavor = 'USER_OBJ' 19 | time = 1346257201.413 20 | node = 'localhost' 21 | # ses: The login session ID - maps user login to a process 22 | ses = -1 23 | # auid: audit user identity - remains the same through 24 | # user priv translations like su 25 | auid = -1 26 | # type: name of event type 27 | type = 'NULL' 28 | # 29 | # who 30 | egid = -1 31 | euid = -1 32 | fsgid = -1 33 | fsuid = -1 34 | gid = -1 35 | suid = -1 36 | sgid = -1 37 | uid = -1 38 | pid = -1 39 | # success: Whether the system call succeeded or failed. 40 | success = 'NULL' 41 | # exit: The exit value returned by the system call. 42 | exit = 0 43 | # 44 | term = 'NULL' 45 | exe = 'NULL' 46 | 47 | # take the record and normalize it against the local object type 48 | def load(s,au): 49 | 50 | event = au.get_timestamp() 51 | if event is None: 52 | print "Error getting timestamp - aborting" 53 | return 0 54 | 55 | s.time = "%d.%d" % (event.sec,event.milli) 56 | 57 | au.first_field() 58 | while True: 59 | key = au.get_field_name() 60 | value = au.interpret_field() 61 | value_raw = au.get_field_str() 62 | 63 | if key in data_filter: 64 | #print "key=" , key, " value=", value 65 | if key == 'node': 66 | s.node = urllib.quote(value) 67 | elif key == 'ses': 68 | s.ses = value_raw 69 | elif key == 'auid': 70 | s.auid = value_raw 71 | elif key == 'type': 72 | s.type = value 73 | elif key == 'egid': 74 | s.egid = value 75 | elif key == 'euid': 76 | s.euid = value 77 | elif key == 'fsgid': 78 | s.fsgid = value 79 | elif key == 'fsuid': 80 | s.fsuid = value 81 | elif key == 'gid': 82 | s.gid = value 83 | elif key == 'suid': 84 | s.suid = value 85 | elif key == 'sgid': 86 | s.sgid = value 87 | elif key == 'uid': 88 | s.uid = value 89 | elif key == 'pid': 90 | s.pid = value_raw 91 | elif key == 'success': 92 | s.success = value 93 | elif key == 'exit': 94 | s.exit = value 95 | elif key == 'terminal': 96 | if value == '(none)': 97 | s.term = 'NO_TERM' 98 | else: 99 | s.term = value 100 | elif key == 'exe': 101 | s.exe = urllib.quote(value) 102 | 103 | if not au.next_field(): 104 | break 105 | 106 | return s 107 | 108 | def print_o(s): 109 | # print the object in a well defined way 110 | print "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s" % (s.flavor, s.type, s.time, s.node, s.ses, s.auid, s.egid, s.euid, s.fsgid, s.fsuid, s.gid, s.suid, s.sgid, s.uid, s.pid, s.success, s.exit, s.term, s.exe) 111 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/normalize_auditd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | srcdir = os.getenv('srcdir') 5 | 6 | # These define the two main points of configuration. 7 | # DATA_FILE: The constantly appending raw auditd log file 8 | # LOAD_PATH: Location of the audit-... install library files containing 9 | # the python2.6/site-packages 10 | # 11 | DATA_FILE = "/var/log/audit/audit.log" 12 | #DATA_FILE = "./D" 13 | LOAD_PATH = '/home/scottc/development/audit_watch/AUDIT2.2.2/lib64/python2.6/site-packages' 14 | 15 | import sys 16 | import time 17 | import re 18 | 19 | sys.path.insert(0, LOAD_PATH) 20 | import auparse 21 | import audit 22 | 23 | # local python libs 24 | from tail import FileTail 25 | import USER_OBJ 26 | import PLACE_OBJ 27 | import SYSCALL_OBJ 28 | import GENERIC_OBJ 29 | import SOCK_OBJ 30 | import EXECVE_OBJ 31 | 32 | # Bunch of regular expressions to process the data raw data 33 | # 34 | WHERE_RE= re.compile('CWD|PATH') 35 | SYSCALL_RE = re.compile('SYSCALL') 36 | WHO_RE = re.compile('USER_') 37 | INTERNAL_RE = re.compile('DAEMON|SERVICE') 38 | SOCKET_RE = re.compile('SOCKADDR') 39 | EXECVE_RE = re.compile('EXECVE') 40 | 41 | place_object = PLACE_OBJ.init() 42 | user_object = USER_OBJ.init() 43 | syscall_object = SYSCALL_OBJ.init() 44 | socket_object = SOCK_OBJ.init() 45 | execve_object = EXECVE_OBJ.init() 46 | generic_object = GENERIC_OBJ.init() 47 | 48 | event_count = 0 49 | # 50 | def none_to_null(s): 51 | 'used so output matches C version' 52 | if s is None: 53 | return '(null)' 54 | else: 55 | return s 56 | 57 | def feed_callback(au, cb_event_type, event_cnt): 58 | 59 | global event_count 60 | 61 | global place_object 62 | global user_object 63 | global syscall_object 64 | global socket_object 65 | global execve_object 66 | global generic_object 67 | 68 | while True: 69 | 70 | event_count += 1 71 | record_count = 1 72 | 73 | # Both the ses and pid values will be used for the base lookups in auditd_core. 74 | # Because of this, records after the first in an event will be benefited by passing 75 | # this information along. If this is not done, a great deal of state goo and churn 76 | # is introduced later in the bro code. 77 | # The ses identifier is the primary with the pid as a backup since sid sometimes has 78 | # a value of 'unset'. 79 | # 80 | ses_holder = 0 81 | pid_holder = 0 82 | event_rec_count = au.get_num_records() 83 | 84 | while True: 85 | 86 | if WHERE_RE.match(audit.audit_msg_type_to_name(au.get_type()) ) : 87 | place_object = place_object.load(au) 88 | print "%s:%s:%s %s %s %s %s %s %s %s %s %s %s %s %s" % (event_count, event_rec_count, record_count, place_object.flavor, place_object.type, place_object.time, place_object.node, ses_holder, pid_holder, place_object.cwd, place_object.path_name, place_object.inode, place_object.mode, place_object.ouid, place_object.ogid) 89 | 90 | ### ------------------------------ ### 91 | elif WHO_RE.match(audit.audit_msg_type_to_name(au.get_type()) ) : 92 | user_object = user_object.load(au) 93 | if record_count == 1: 94 | ses_holder = user_object.ses 95 | pid_holder = user_object.pid 96 | else: 97 | user_object.ses = ses_holder 98 | user_object.pid = pid_holder 99 | 100 | print "%s:%s:%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s" % (event_count, event_rec_count, record_count, user_object.flavor, user_object.type, user_object.time, user_object.node, user_object.ses, user_object.auid, user_object.egid, user_object.euid, user_object.fsgid, user_object.fsuid, user_object.gid, user_object.suid, user_object.sgid, user_object.uid, user_object.pid, user_object.success, user_object.exit, user_object.term, user_object.exe) 101 | 102 | ### ------------------------------ ### 103 | elif SYSCALL_RE.match(audit.audit_msg_type_to_name(au.get_type()) ) : 104 | syscall_object = syscall_object.load(au) 105 | if record_count == 1: 106 | ses_holder = syscall_object.ses 107 | pid_holder = syscall_object.pid 108 | 109 | print '%s:%s:%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s' % (event_count, event_rec_count, record_count, syscall_object.flavor, syscall_object.type, syscall_object.time, syscall_object.node, syscall_object.ses, syscall_object.auid, syscall_object.syscall, syscall_object.key, syscall_object.comm, syscall_object.exe, syscall_object.a0, syscall_object.a1, syscall_object.a2, syscall_object.uid, syscall_object.gid, syscall_object.euid, syscall_object.egid, syscall_object.fsuid, syscall_object.fsgid, syscall_object.suid, syscall_object.sgid, syscall_object.pid, syscall_object.ppid, syscall_object.tty, syscall_object.success, syscall_object.exit) 110 | 111 | ### ------------------------------ ### 112 | elif SOCKET_RE.match(audit.audit_msg_type_to_name(au.get_type()) ) : 113 | socket_object = socket_object.load(au) 114 | print '%s:%s:%s %s %s %s %s %s %s %s' % (event_count, event_rec_count, record_count, socket_object.flavor, socket_object.type, socket_object.time, socket_object.node, ses_holder, pid_holder, socket_object.saddr) 115 | 116 | ### ------------------------------ ### 117 | elif EXECVE_RE.match(audit.audit_msg_type_to_name(au.get_type()) ) : 118 | execve_object = execve_object.load(au) 119 | print '%s:%s:%s %s %s %s %s %s %s %s %s' % (event_count, event_rec_count, record_count, execve_object.flavor, execve_object.type, execve_object.time, execve_object.node, ses_holder, pid_holder, execve_object.argc, execve_object.arg) 120 | 121 | ### ------------------------------ ### 122 | else: 123 | generic_object = generic_object.load(au) 124 | if record_count == 1: 125 | ses_holder = generic_object.ses 126 | pid_holder = generic_object.pid 127 | else: 128 | generic_object.ses = ses_holder 129 | generic_object.pid = pid_holder 130 | 131 | print '%s:%s:%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s' % (event_count, event_rec_count, record_count, generic_object.flavor, generic_object.type, generic_object.time, generic_object.node, generic_object.ses, generic_object.auid, generic_object.key, generic_object.comm, generic_object.exe, generic_object.a0, generic_object.a1, generic_object.a2, generic_object.uid, generic_object.gid, generic_object.euid, generic_object.egid, generic_object.fsuid, generic_object.fsgid, generic_object.suid, generic_object.sgid, pid_holder, generic_object.ppid, ses_holder, generic_object.tty, generic_object.terminal, generic_object.success, generic_object.exit) 132 | 133 | record_count += 1 134 | 135 | if not au.next_record(): break 136 | if not au.parse_next_event(): break 137 | 138 | ###################################################### 139 | # this is the main "loop" 140 | ###################################################### 141 | au = auparse.AuParser(auparse.AUSOURCE_FEED); 142 | event_cnt = 1 143 | au.add_callback(feed_callback, [event_cnt]) 144 | chunk_len = 3 145 | 146 | t=FileTail(DATA_FILE) 147 | for s in t: 148 | au.feed(s) 149 | 150 | au.flush_feed() 151 | 152 | sys.exit(0) 153 | 154 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/tail.py: -------------------------------------------------------------------------------- 1 | """ $Id: filetail.py 1512 2011-05-20 16:14:29Z morrissj $ 2 | This has been slightly modified from the original. Any problems with this should 3 | be promptly assigned to me. 4 | 5 | Python3 module for tailing a file such as a system log that grows continuously. 6 | Transparently handles files that get rotated or trucated. 7 | Inspired by the Perl File::Tail module. 8 | 9 | A simple algorithm is used to dynamically sleep when no new data is available in 10 | the file. The longer the amount of time goes by w/o new data the longer the 11 | sleep interval will be (up to "max_interval") and starts at "interval". 12 | 13 | Example: 14 | from filetail import FileTail 15 | tail = FileTail("/var/log/syslog") 16 | for line in tail: 17 | # do something 18 | pass 19 | 20 | """ 21 | 22 | import os 23 | import sys 24 | from stat import * 25 | from math import floor 26 | from time import sleep, time 27 | 28 | class FileTail(object): 29 | """ 30 | Tail a file, even if its rotated/truncated. 31 | Inspiration came from the perl module File::Tail. 32 | """ 33 | 34 | def __init__(self, 35 | file, # filename to monitor 36 | start_pos="end", # where to initially start reading from, "head" or "end" 37 | #max_buffer_size=16384, # Max buffer size hint (Not exact; @see file.readlines) 38 | interval=0.1, # sleep time to wait if no data is present (dynamically changes) 39 | #min_interval=0.01, # min sleep time 40 | max_interval=1, # max sleep time 41 | max_wait=20, # max time to wait with no data before reopening file 42 | reopen_check="inode", # how to check if file is different (inode or time) - inode does not work on win32 43 | encoding="utf-8" # file encoding 44 | ): 45 | 46 | self.start_pos = start_pos 47 | self.reopen_check = reopen_check 48 | self.max_wait = max_wait 49 | #self.max_buffer_size = max_buffer_size 50 | #self.min_interval = min_interval 51 | self.max_interval = max_interval 52 | self.interval = interval 53 | if self.interval > self.max_interval: 54 | self.interval = self.max_interval 55 | self.encoding = encoding 56 | 57 | # will throw exception if it fails... caller should intercept 58 | self.open(file, start_pos=start_pos) 59 | 60 | # initialize some internal vars 61 | self._buffer = [] 62 | self.last_time = time() 63 | self.last_count = 0 64 | 65 | def open(self, file, start_pos="head"): 66 | """Open the file to tail and initialize our state.""" 67 | fh = open(file, "r") 68 | #fh = open(file, "r", encoding=self.encoding) 69 | 70 | # seek to the initial position in the file we want to start reading 71 | if start_pos == "end" or start_pos == "tail": 72 | fh.seek(0, os.SEEK_END) # End of file 73 | elif start_pos == "start" or start_pos == "head": 74 | #fh.seek(0, os.SEEK_SET) # Beginning of file 75 | pass 76 | elif start_pos is not None: 77 | if start_pos >= 0: # Absolute position 78 | fh.seek(start_pos, os.SEEK_SET) 79 | else: # Absolute position (from end) 80 | fh.seek(abs(start_pos), os.SEEK_END) 81 | 82 | # if we passed the end of the file rewind to the actual end. 83 | # This avoids a potential race condition if the file was being rotated 84 | # in the process of opening the file. Not sure if this can actually 85 | # happen, but better safe than sorry. 86 | pos = fh.tell() 87 | if pos > os.stat(file)[ST_SIZE]: 88 | pos = fh.tell() 89 | 90 | self.fh = fh 91 | self.pos = pos 92 | self.stat = os.fstat(fh.fileno()) 93 | self.file = file 94 | 95 | def reopen(self): 96 | """ 97 | Attempt to reopen the current file. If it doesn't appear to have 98 | changed (been rotated) then the current file handle is not changed. 99 | """ 100 | 101 | #print("Reopening", self.file, "...", end="") 102 | 103 | # if we don't have an opened file already then try to open it now 104 | if not self.fh or self.fh.closed: 105 | try: 106 | self.open(self.file, start_pos="head"); 107 | except IOError: 108 | return False 109 | return True 110 | 111 | # save current values 112 | fh = self.fh 113 | pos = self.pos 114 | cur = self.stat 115 | 116 | # reopen same file 117 | try: 118 | self.open(self.file, "head") 119 | except IOError as e: 120 | print("FILE %s DOES NOT EXIST" % self.file) 121 | return False 122 | 123 | new = self.stat 124 | #print(new.st_ino, ' == ', cur.st_ino) 125 | if ( 126 | (self.reopen_check == 'inode' and new.st_ino == cur.st_ino) 127 | or 128 | (self.reopen_check == 'time' and new.st_mtime <= floor(self.last_time) and new.st_size == pos) 129 | ): 130 | #print("FILE NOT CHANGED") 131 | # file appears to be the same or older than our last read 132 | #self.last_time = new.st_mtime 133 | self.fh = fh 134 | self.pos = pos 135 | self.stat = cur 136 | return False 137 | 138 | return True 139 | 140 | 141 | def __iter__(self): 142 | """ 143 | Return iterator to support: 144 | for line in filetail: 145 | print line 146 | """ 147 | self.wait_count = 0 148 | return self 149 | 150 | 151 | def __next__(self): 152 | """Interator "next" call.""" 153 | return self.next() 154 | 155 | 156 | def next(self): 157 | line = None 158 | self.wait_count = 0 159 | 160 | # low CPU (probably same as the block below this, but ALLOWS tell()! 161 | while not line: 162 | line = self.fh.readline() 163 | if line != "": 164 | # track the time we received new data and how much 165 | self.last_time = time() 166 | self.last_count = 1 167 | else: 168 | self.wait() 169 | 170 | ## uses the least amount of CPU, but does not allow me to tell() 171 | ## is that a bug in readlines()? 172 | #while len(self._buffer) == 0: 173 | # self._buffer = self.fh.readlines(self.max_buffer_size) 174 | # if len(self._buffer) > 0: 175 | # # track the time we received new data and how much 176 | # self.last_time = time() 177 | # self.last_count = len(self._buffer) 178 | # self.wait_count = 0 179 | # else: 180 | # self.wait() 181 | #line = self._buffer.pop(0) 182 | 183 | # dealing with the file as binary isn't working as well as i hoped 184 | #while len(self.lines) == 0: 185 | # buffer = self.fh.read(self.max_buffer_size).decode(self.encoding) 186 | # if buffer is not None: 187 | # self._buffer += buffer 188 | # size = self.enqueue(self._buffer) 189 | # if size: 190 | # self._buffer = self._buffer[size:] 191 | # else: 192 | # self.wait() 193 | #line = self.lines.pop(0) 194 | 195 | # uses too much CPU!! (but not 100%) 196 | #line = self.fh.readline() 197 | #while line == "": 198 | # self.wait() 199 | # line = self.fh.readline() 200 | # if line != "": 201 | # # track the time we received new data and how much 202 | # self.pos = self.fh.tell() 203 | # self.last_time = time() 204 | # self.last_count = 1 #len(self._buffer) 205 | # self.wait_count = 0 206 | 207 | return line 208 | 209 | #def enqueue(self, buffer): 210 | # """ 211 | # Extract any lines from buffer and add to our self.lines list. Ignores 212 | # the last line if it does not have a line termination ("\n") 213 | # @return total characters extracted from buffer. 214 | # """ 215 | # lines = buffer.splitlines(True) 216 | # total = 0; 217 | # for l in lines: 218 | # if l.endswith("\n"): 219 | # self.lines.append(l) 220 | # total += len(l) 221 | # return total 222 | 223 | # wait for X seconds. The sleep interval is dynamically predicted based on 224 | # how much was previously read. The predicted interval will never be more 225 | # than max_interval. If enough time passes w/o any new data the file will 226 | # be reopened and checked. 227 | def wait(self): 228 | if self.wait_count == 0: 229 | self.pos = self.fh.tell() 230 | self.stat = os.fstat(self.fh.fileno()) 231 | 232 | self.wait_count += 1 233 | elapsed = time() - self.last_time 234 | 235 | # if we've waited long enough try to reopen the file, if that returns 236 | # true then we're done here and we do not sleep. 237 | if elapsed >= self.max_wait: 238 | self.last_time = time() 239 | if self.reopen(): 240 | return 241 | 242 | 243 | # determine delay value. Delay is longer based on total time passed 244 | # note: currently last_count is always 1. 245 | if self.last_count: 246 | #delay = (time() - self.last_time) / self.last_count 247 | delay = elapsed 248 | else: 249 | delay = self.interval 250 | 251 | # don't delay too long 252 | if delay > self.max_interval: 253 | delay = self.max_interval 254 | #elif delay < self.min_interval: 255 | # delay = self.min_interval 256 | 257 | #print("delay={:0.06f} elapsed={:0.06f}".format(delay, elapsed)) 258 | sleep(delay) 259 | 260 | # end of FileTail class 261 | 262 | 263 | def main(): 264 | print("No tests implemented.") 265 | 266 | 267 | if __name__ == "__main__": 268 | sys.exit(main()) 269 | -------------------------------------------------------------------------------- /log_normalizer_DEPRECATED/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import urllib 4 | import syslog 5 | import time 6 | import socket 7 | import re 8 | import pwd 9 | import grp 10 | import shlex 11 | import binascii 12 | 13 | def process_string(value): 14 | # this will return the translated value unless (1) a binary value 15 | # is returned as part of the translation, or (2) a ValueError is 16 | # thrown which typically indicates that a "normal" string has been 17 | # handed to the function 18 | 19 | retstring = '' 20 | 21 | # too short - just return value 22 | if len(value) <= 2: 23 | return value 24 | 25 | for i in range(len(value)/2): 26 | realIdx = i*2 27 | 28 | # ValueError happens w/ 'normal' text - if it 29 | # is run into, just return value 30 | try: 31 | n = int(value[realIdx:realIdx+2],16) 32 | except ValueError: 33 | return value 34 | 35 | if ( n > 31 and n < 127 ): 36 | retstring = retstring + chr(n) 37 | else: 38 | # the character is non-printing so just return value 39 | return value 40 | 41 | return retstring 42 | 43 | def process_exe(value): 44 | ret = 'ERROR' 45 | 46 | if len(value) % 2 != 0: 47 | value = value + '0' 48 | 49 | try: 50 | ret = binascii.unhexlify(value) 51 | #print ret 52 | except TypeError: 53 | ret = value 54 | 55 | return ret 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /system_config/audit.rules: -------------------------------------------------------------------------------- 1 | # #### -- ## Auditd Rules ## -- ##### 2 | 3 | ##| -------------------------------------------------------------------------------- 4 | ##| NETWORK: network related system calls to gather socket data from 5 | ##| inbound and outbound traffic. 6 | ##| start mod5 7 | ##| bind: EACCES The address is protected, and the user is not the superuser. 8 | ##| EACCES Search permission is denied on a component of the path prefix. (AF_UNIX) 9 | ##| EFAULT addr points outside the user’s accessible address space. 10 | ##| connect: EACCES, EPERM The user tried to connect to a broadcast address without having the 11 | ##| socket broadcast flag enabled or the connection request failed because of a local firewall rule. 12 | ##| accept: EPERM Firewall rules forbid connection. 13 | ##| 14 | ##| -------------------------------------------------------------------------------- 15 | 16 | -a always,exit -F arch=b64 -S bind -S connect -S accept -S accept4 -S listen -S socketpair -S socket -F exit=-EACCES -k SYS_NET_ERR 17 | -a always,exit -F arch=b64 -S bind -S connect -S accept -S accept4 -S listen -S socketpair -S socket -F exit=-EPERM -k SYS_NET_ERR 18 | -a always,exit -F arch=b64 -S bind -S connect -S accept -S accept4 -S listen -S socketpair -S socket -k SYS_NET 19 | 20 | ##| -------------------------------------------------------------------------------- 21 | ##| MISC OS: 22 | ##| 23 | ##| init_module - Initialize a loadable module entry 24 | ##| -EPERM The user must have administrator module modification capabilities. 25 | ##| delete_module - Delete a loadable module 26 | ##| -EPERM The user must have administrator module modification capabilities. 27 | ##| pivot_root - change the root file system 28 | ##| -EPERM The calling process does not have the CAP_SYS_ADMIN capability. 29 | ##| mount: -EACCES A component of a path was not searchable; 30 | ##| mknod: -EPERM mode requested creation of something other than a regular file, FIFO (named pipe), or Unix domain socket 31 | ##| 32 | ##| -------------------------------------------------------------------------------- 33 | -a always,exit -F arch=b64 -S init_module -S delete_module -S mount -S pivot_root -S chroot -S mknod -F exit=-EPERM -k SYS_OS_ERR 34 | #-a always,exit -F arch=b64 -S init_module -S delete_module -S mount -S pivot_root -S chroot -S mknod -F exit=-EACCESS -k SYS_OS_ERR 35 | -a always,exit -F arch=b64 -S init_module -S delete_module -S mount -S pivot_root -S chroot -S mknod -k SYS_OS 36 | 37 | ##| -------------------------------------------------------------------------------- 38 | ##| FILES: - Changes in ownership and permissions. 39 | ##| 40 | ##| mknodat - create a special or ordinary file relative to a directory file descriptor 41 | ##| linkat - create a file link relative to directory file descriptors 42 | ##| 43 | ##| -------------------------------------------------------------------------------- 44 | -a always,exit -F arch=b64 -S creat -S mkdir -S mknod -S link -S symlink -S mknodat -S linkat -S symlinkat -F exit=-EACCES -k SYS_FILE_CREATE_ERR 45 | -a always,exit -F arch=b64 -S mkdir -S mkdirat -S link -S symlink -F exit=-EPERM -k SYS_FILE_CREATE_ERR 46 | 47 | ##| unsuccessful modifications 48 | -a always,exit -F arch=b64 -S rename -S renameat -S truncate -F exit=-EACCES -k SYS_FILE_MOD_ERR 49 | -a always,exit -F arch=b64 -S rename -S renameat -S truncate -F exit=-EPERM -k SYS_FILE_MOD_ERR 50 | 51 | ##| all chmods/chown, successful or otherwise 52 | -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F exit=-EACCES -k SYS_FILE_PERM_ERR 53 | -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F exit=-EPERM -k SYS_FILE_PERM_ERR 54 | -a always,exit -F arch=b64 -S chown -S fchown -S fchownat -F exit=-EACCES -k SYS_FILE_PERM_ERR 55 | -a always,exit -F arch=b64 -S chown -S fchown -S fchownat -F exit=-EPERM -k SYS_FILE_PERM_ERR 56 | 57 | -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -k SYS_FILE_PERM 58 | -a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -k SYS_FILE_PERM 59 | 60 | ##| very special hello for the extended attribute set 61 | -a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -k SYS_FILE_XPERM 62 | 63 | ##| unsuccessful deletion 64 | -a always,exit -F arch=b64 -S rmdir -S unlink -S unlinkat -F exit=-EACCES -k SYS_FILE_DELETE_ERR 65 | -a always,exit -F arch=b64 -S rmdir -S unlink -S unlinkat -F exit=-EPERM -k SYS_FILE_DELETE_ERR 66 | 67 | ##| unsuccessful open 68 | -a always,exit -F arch=b64 -S open -S openat -F exit=-EACCES -k SYS_FILE_OPEN_ERR 69 | -a always,exit -F arch=b64 -S open -S openat -F exit=-EPERM -k SYS_FILE_OPEN_ERR 70 | 71 | ##| -------------------------------------------------------------------------------- 72 | ##| EXECUTE: anything that gets executed should get logged 73 | ##| -------------------------------------------------------------------------------- 74 | -a always,exit -F arch=b64 -S execve -k SYS_EXEC 75 | ##| suid invocation 76 | -a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -F exit=EPERM -k SYS_SUID_ERR 77 | -a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k SYS_SUID 78 | 79 | ##| -------------------------------------------------------------------------------- 80 | ##| TIME: 81 | ##| -------------------------------------------------------------------------------- 82 | -a always,exit -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -F exit=-EPERM -k SYS_TIME_ERR 83 | -a always,exit -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k SYS_TIME 84 | 85 | ##| -------------------------------------------------------------------------------- 86 | ##| FILE SYSTEM MODS: 87 | ##| -------------------------------------------------------------------------------- 88 | ##| pam configuration 89 | -w /etc/pam.d/ -p wa -k CFG_PAM 90 | -w /etc/security/access.conf -p wa -k CFG_PAM 91 | -w /etc/security/limits.conf -p wa -k CFG_PAM 92 | -w /etc/security/pam_env.conf -p wa -k CFG_PAM 93 | -w /etc/security/namespace.conf -p wa -k CFG_PAM 94 | -w /etc/security/namespace.d/ -p wa -k CFG_PAM 95 | -w /etc/security/namespace.init -p wa -k CFG_PAM 96 | -w /etc/security/sepermit.conf -p wa -k CFG_PAM 97 | -w /etc/security/time.conf -p wa -k CFG_PAM 98 | 99 | ##| system type directory (s) 100 | -w /etc -p w -k SYS_FILE 101 | -w /usr/bin -p w -k SYS_FILE 102 | -w /usr/sbin -p w -k SYS_FILE 103 | -w /lib -p w -k SYS_FILE 104 | -w /opt -p w -k SYS_FILE 105 | 106 | ##| track auditd mods 107 | ##| Set a watch on an audit configuration file. 108 | ##| Log all write and attribute change attempts to this file. 109 | -w /etc/audit/auditd.conf -p wa -k SYS_AUDITD 110 | -w /etc/audit/audit.rules -p wa -k SYS_AUDITD 111 | -w /etc/libaudit.conf -p wa -k SYS_AUDITD 112 | -w /etc/sysconfig/auditd -p wa -k SYS_AUDITD 113 | 114 | # #### -- ## End Auditd Rules ## -- ##### 115 | 116 | -------------------------------------------------------------------------------- /system_config/auditd.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This file controls the configuration of the audit daemon 3 | # 4 | 5 | log_file = /var/log/audit/audit.log 6 | log_format = RAW 7 | # specifies the group that is applied to the log file’s permissions 8 | log_group = root 9 | 10 | # This is a non-negative number that tells the audit daemon how much 11 | # of a priority boost it should take. The default is 4. 12 | # No change is 0. 13 | priority_boost = 3 14 | 15 | # values are none, incremental, data, and sync. 16 | # none: no special effort is made to flush the audit records to disk 17 | # incremental: Then the freq parameter is used to determine how 18 | # often an explicit flush to disk is issued 19 | # data: keep the data portion of the disk file sync’d at all times 20 | # sync: both the data and meta-data fully sync’d with every write to disk 21 | # 22 | flush = INCREMENTAL 23 | 24 | # how many records to write before issuing an explicit flush to disk 25 | # command. Default = 20 26 | #freq = 200 27 | freq = 500 28 | 29 | # This option controls whether you want blocking/lossless or 30 | # non-blocking/lossy communication between the audit daemon and 31 | # the dispatcher. There is a 128k buffer between the audit daemon 32 | # and dispatcher. This is good enogh for most uses. If lossy 33 | # is chosen, incoming events going to the dispatcher are discarded 34 | # when this queue is full. (Events are still written to disk if 35 | # log_format is not nolog.) Otherwise the auditd daemon will 36 | # wait for the queue to have an empty spot before logging to disk. 37 | # The risk is that while the daemon is waiting for network IO, an 38 | # event is not being recorded to disk. Valid values are: 39 | # lossy and lossless. Lossy is the default value. 40 | disp_qos = lossy 41 | 42 | # The dispatcher is a program that is started by the audit 43 | # daemon when it starts up. 44 | dispatcher = /sbin/audispd 45 | 46 | # This option controls how computer node names are inserted into 47 | # the audit event stream. It has the following choices: none, hostname, 48 | # fqd, numeric, and user. 49 | name_format = hostname 50 | 51 | # This keyword specifies the maximum file size in megabytes 52 | max_log_file = 100 53 | max_log_file_action = ROTATE 54 | # max # log files 55 | num_logs = 10 56 | 57 | # This is a numeric value in megabytes that tells the audit daemon 58 | # when to perform a configurable action because the system is 59 | # starting to run low on disk space. 60 | space_left = 75 61 | # This parameter tells the system what action to take when the 62 | # system has detected that it is starting to get low on disk space. 63 | space_left_action = SYSLOG 64 | action_mail_acct = root 65 | 66 | # This is a numeric value in megabytes that tells the audit 67 | # daemon when to perform a configurable action because the system is 68 | # running low on disk space. 69 | admin_space_left = 50 70 | # This parameter tells the system what action to take when the system 71 | # has detected that it is low on disk space. Valid values are 72 | # ignore, syslog, email, exec, suspend, single, and halt. 73 | # Suspend will cause the audit daemon to stop writing records to the disk. 74 | admin_space_left_action = SUSPEND 75 | disk_full_action = SUSPEND 76 | disk_error_action = SUSPEND 77 | 78 | # This is a numeric value in the range 1..65535 which, if specified, 79 | # causes auditd to listen on the corresponding TCP port for audit records 80 | # from remote systems. 81 | #tcp_listen_port = 82 | # This is a numeric value which indicates how many pending (requested 83 | # but unaccepted) connections are allowed. The default is 5. 84 | tcp_listen_queue = 5 85 | # This is a numeric value which indicates how many concurrent 86 | # connections from one IP address is allowed. 87 | # The default is 1 and the maximum is 16. 88 | tcp_max_per_addr = 1 89 | # This parameter may be a single numeric value or two values separated 90 | # by a dash (no spaces allowed). It indicates which client ports 91 | # are allowed for incoming connections. 92 | #tcp_client_ports = 1024-65535 93 | # This parameter indicates the number of seconds that a client 94 | # may be idle (i.e. no data from them at all) before auditd complains. 95 | tcp_client_max_idle = 0 96 | 97 | # If set to "yes", Kerberos 5 will be used for authentication 98 | # and encryption. The default is "no". 99 | enable_krb5 = no 100 | # This is the principal for this server. The default is "auditd". 101 | krb5_principal = auditd 102 | # Location of the key for this client’s principal. Note that the key 103 | # file must be owned by root and mode 0400. 104 | # The default is /etc/audit/audit.key 105 | #krb5_key_file = /etc/audit/audit.key 106 | --------------------------------------------------------------------------------