source: trunk/docs/HOWTO-write-modules.html@ 137

Last change on this file since 137 was 1, checked in by katerina, 19 years ago

Initial import

File size: 23.2 KB
Line 
1<html>
2<head>
3<title>HOWTO Write Samhain Modules</title>
4<style type="text/css">
5<!--
6
7html { background: #eee; color: #000; }
8
9body { background: #eee; color: #000; margin: 0; padding: 0;}
10
11div.body {
12 background: #fff; color: #000;
13 margin: 0 1em 0 1em; padding: 1em;
14 font-family: serif;
15 font-size: 1em; line-height: 1.2em;
16 border-width: 0 1px 0 1px;
17 border-style: solid;
18 border-color: #aaa;
19}
20
21div.block {
22 background: #b6c5f2; color: #000;
23 margin: 1em; padding: 0 1em 0 1em;
24 border-width: 1px;
25 border-style: solid;
26 border-color: #2d4488;
27}
28
29div.warnblock {
30 background: #b6c5f2; color: #000;
31 margin: 1em; padding: 0 1em 0 1em;
32 border-width: 1px;
33 border-style: solid;
34 border-color: #FF9900;
35}
36
37table {
38 background: #F8F8F8; color: #000;
39 margin: 1em;
40 border-width: 0 0 0 1px;
41 border-style: solid;
42 border-color: #C0C0C0;
43}
44
45td {
46 border-width: 0 1px 1px 0;
47 border-style: solid;
48 border-color: #C0C0C0;
49}
50
51th {
52 background: #F8F8FF;
53 border-width: 1px 1px 2px 0;
54 border-style: solid;
55 border-color: #C0C0C0;
56}
57
58
59/* body text, headings, and rules */
60
61p { margin: 0; text-indent: 0em; margin: 0 0 0.5em 0 }
62
63h1, h2, h3, h4, h5, h6 {
64 color: #206020; background: transparent;
65 font-family: Optima, Arial, Helvetica, sans-serif;
66 font-weight: normal;
67}
68
69h1 { font-size: 1.69em; margin: 1.4em 0 0.4em 0; }
70h2 { font-size: 1.44em; margin: 1.4em 0 0.4em 0; }
71h3 { font-size: 1.21em; margin: 1.4em 0 0.4em 0; }
72h4 { font-size: 1.00em; margin: 1.4em 0 0.4em 0; }
73h5 { font-size: 0.81em; margin: 1.4em 0 0.4em 0; }
74h6 { font-size: 0.64em; margin: 1.4em 0 0.4em 0; }
75
76hr {
77 color: transparent; background: transparent;
78 height: 0px; margin: 0.6em 0;
79 border-width: 1px ;
80 border-style: solid;
81 border-color: #999;
82}
83
84/* bulleted lists and definition lists */
85
86ul { margin: 0 1em 0.6em 2em; padding: 0; }
87li { margin: 0.4em 0 0 0; }
88
89dl { margin: 0.6em 1em 0.6em 2em; }
90dt { color: #285577; }
91
92tt { color: #602020; }
93
94/* links */
95
96a.link {
97 color: #33c; background: transparent;
98 text-decoration: none;
99}
100
101a:hover {
102 color: #000; background: transparent;
103}
104
105body > a {
106 font-family: Optima, Arial, Helvetica, sans-serif;
107 font-size: 0.81em;
108}
109
110h1, h2, h3, h4, h5, h6 {
111 color: #2d5588; background: transparent;
112 font-family: Optima, Arial, Helvetica, sans-serif;
113 font-weight: normal;
114}
115
116 -->
117</style></head>
118
119<body>
120<div class="body">
121<p style="text-align: center; background: #ccc; border: 1px solid #2d5588;"><a
122 style="text-decoration: none;"
123 href="http://www.la-samhna.de/samhain/">samhain file integrity
124 scanner</a>&nbsp;|&nbsp;<a style="text-decoration: none;"
125 href="http://www.la-samhna.de/samhain/s_documentation.html">online
126 documentation</a></p>
127<br><center>
128<h1>Writing modules for samhain</h1>
129</center>
130<br>
131<hr>
132<p>
133This document should help anyone who is sitting down to write a module
134for the samhain host intrusion detection system. We give an overview
135of samhain's structure from the point of view of the module author,
136and describe some of the samhain utility and interface functions
137available. Lastly, we explain how to integrate your module into the
138samhain autoconf build tools.
139</p>
140<h2>Introduction</h2>
141<p>
142Samhain is a rather useful file integrity and host intrusion detection
143system. It is written entirely in C, and much care has been given to
144making it robust and secure. Additionally, it has been written with
145extensibility in mind, and so interfaces for adding user-contributed
146modules have been provided. A module author can easily extend the
147configuration file syntax and have his checking code run on a regular
148basis as one of samhain's internal checks.
149</p>
150
151<h2>Prerequisites</h2>
152<p>
153You'll need to know how to read and write C. You'll need the latest
154source for samhain. You'll need to have read all of samhain's other
155documentation. Finally, if you want to make your module build as part
156of the samhain tree (you do), you'll need GNU's autoconf package.
157</p>
158<h2>An overview of samhain's execution</h2>
159<p>
160Here's what happens when samhain starts:
161<ul>
162 <li>
163 Check if samhain has been called with one of the "init.d" type
164 commands - start, stop, reload, status. If so, these are handled
165 as you might expect. Nice feature.
166 </li>
167 <li>
168 Initialise all global structures and parse command-line options.
169 </li>
170 <li>
171 Read the configuration file. This is handled in sh_readconf_read().
172 This includes attempting to download the file if samhain has been
173 compiled to do so.
174 </li>
175 <li>
176 Drop privileges if server.
177 </li>
178 <li>
179 Test the checksum on the database if client or standalone.
180 </li>
181 <li>
182 Now test if samhain has been compiled as a client or a server.
183 <ul>
184 <li>
185 If server, enter server main loop sh_receive() in
186 sh_forward.c. This is simple enough; apart from checks for
187 signals received, the server just accepts incoming
188 connections, verifies that they are from an authorised
189 client, and logs the message received.
190 </li>
191 <li>
192 If client or standalone, we run the rest of main() in
193 samhain.c, which follows:
194 </li>
195 </ul>
196 </li>
197 <li>
198 Initialise modules - that is, call the mod_init() function on each
199 module. Note that if the module intialisation routine returns a
200 nonzero value, you should also have it free anything that's been
201 allocated by the configuration file reading functions, since this
202 method is always called after an sh_readconf_read(), i.e. when the
203 configuration file is re-read after a SIGHUP.
204 </li>
205 <li>
206 Test the setup that's been read from the configuration - for example,
207 check if any files or directories have been defined twice.
208 </li>
209 <li>
210 Enter the main loop (which runs just once if samhain is not
211 configured as a daemon). Test if any signals have been received,
212 and handle them appropriately:
213 <ul>
214 <li>
215 On reconfiguration (SIGHUP), clear internal file lists etc.
216 and call the mod_reconf() function on each module. This should
217 clean up anything internal to the module before the
218 configuration file is re-read. Then read the configuration
219 file again and set things up as before, including a new call
220 to mod_init().
221 </li>
222 <li>
223 On SIGIOT (SIGABRT), shut down the log-file for a moment
224 to allow for rotation.
225 </li>
226 <li>
227 On SIGQUIT, terminate. Note that any call to exit() will
228 invoke the exit_handler() defined in samhain.c; the first
229 thing this does is to call mod_cleanup() on all modules.
230 Then it cleans up everything else in samhain and exits.
231 </li>
232 <li>
233 On SIGUSR1 turn toggle debugging on/off.
234 </li>
235 <li>
236 On SIGUSR2 suspend the daemon an notify the server to
237 allow a second instance of samhain downloading its
238 configuration file without triggering an alert (restart
239 without exit) on the server.
240 </li>
241 </ul>
242 </li>
243 <li>
244 If it's time to check files, check directories and then files, and
245 then flush the mail queue.
246 </li>
247 <li>
248 Execute modules. For each module, if mod_timer(tcurrent) returns a
249 nonzero value, then execute mod_check().
250 </li>
251 <li>
252 Do various maintenance operations such as logging a timestamp/sending
253 some mail if it's time, seeding/re-seeding the PRNG, etc.
254 </li>
255</ul>
256You'll note that in the text above I refer to a couple of module
257functions - mod_init(), mod_check(), etc. These are function pointers
258that act as hooks for attaching modules to samhain. Next we'll
259describe how they are used.
260</p>
261
262<h2>Samhain's module interface</h2>
263<p>
264Here we'll describe the interface samhain provides to module authors.
265</p>
266
267<h3>The module list</h3>
268<p>
269In sh_modules.h, the following structure is defined:
270</p>
271<pre>
272
273typedef struct mod_type
274{
275 /* The name of the module */
276 char * name;
277
278 /* Set by samhain to 1 on successful initialization, else 0 */
279 int initval;
280
281 /* The initialization function. Return 0 on success. */
282 int (* mod_init) (void);
283
284 /* The timer function. Return 0 if NOT time to check. */
285 int (* mod_timer) (unsigned long tcurrent);
286
287 /* The check function. Return 0 on success. */
288 int (* mod_check) (void);
289
290 /* The cleanup function. Return 0 on success. */
291 int (* mod_cleanup) (void);
292
293 /* The preparation for reconfiguration. Return 0 on success. */
294 int (* mod_reconf) (void);
295
296 /* Section header in config file */
297 char * conf_section;
298
299 /* A table of key/handler_function for config file entries */
300 sh_rconf * conf_table;
301
302} sh_mtype;
303</pre>
304
305<p>
306This is the structure used to hook modules into samhain. There is a
307list of these structures (modList), defined in sh_modules.c,
308containing pointers to the functions to be used for each module
309compiled into samhain. For example,
310</p>
311
312<pre>
313
314sh_mtype modList[] = {
315#ifdef SH_USE_UTMP
316 {
317 N_("UTMP"),
318 0,
319 sh_utmp_init,
320 sh_utmp_timer,
321 sh_utmp_check,
322 sh_utmp_end,
323 sh_utmp_null,
324
325 N_("[Utmp]"),
326 sh_utmp_table,
327 },
328#endif
329</pre>
330<p>
331is the beginning of that table. The author of the sh_utmp module has
332initialised the structure with the name of the module (note that N_()
333is just a macro used to delimit strings here), a 0 to signify that the
334module has not yet been initialised, and then pointers to _init(),
335_timer(), _check(), _cleanup() and _reconf() functions for the
336module. Finally, the last two structure elements are for configuration
337file parsing: the first is the section heading in the configuration
338file for this module, and the second is a table of type
339</p>
340
341<pre>
342
343typedef struct rconf
344{
345 char * the_opt;
346 int (*func)(char * opt);
347} sh_rconf;
348</pre>
349
350<p>
351(also defined in sh_modules.h). This structure is for storing options
352for this module to be found in the configuration file, as well as the
353functions that will be used to parse them when found. In the sh_utmp
354example above, we can see that this table has been set to
355sh_utmp_table - this is a reference to a list of the Utmp module's
356configuration options declared in sh_utmp.h. It should be clear now
357that one of the changes you will need to make to samhain's source
358files is to include your header file in sh_modules.c and add a modList
359entry like the above.
360</p>
361
362<p>
363For a description of when during samhain's execution these various
364module hooks are called, see the overview above. It would likely be
365helpful to you now to read through the source for one of the modules
366provided with samhain and see the above actually implemented. You
367should also be able to use one of these modules as a template for your
368own.
369</p>
370
371<h3>The message catalogue</h3>
372
373<p>
374Most module authors will want to log messages in their own specified
375format; samhain stores all of its message formats in a "messages
376catalogue" found in sh_cat.h and sh_cat.c. For example, for the
377sh_suidchk module we find the following entries in sh_cat.h, as part
378of an enum:
379</p>
380
381<pre>
382
383#ifdef SH_USE_SUIDCHK
384 MSG_SUID_POLICY,
385 MSG_SUID_FOUND,
386 MSG_SUID_STAT,
387 MSG_SUID_SUMMARY,
388#endif
389</pre>
390
391<p>
392Correspondingly in sh_cat.c we find
393</p>
394
395<pre>
396
397#ifdef SH_USE_SUIDCHK
398 { MSG_SUID_POLICY, SH_ERR_SEVERE, RUN, N_("msg=\"POLICY SUIDCHK %s\" path=\"%s\"") },
399 { MSG_SUID_FOUND, SH_ERR_INFO, RUN, N_("msg=\"Found suid/sgid file\" path=\"%s\"") },
400 { MSG_SUID_STAT, SH_ERR_ERR, ERR, N_("msg=\"stat: %s\" path=\"%s\"") },
401 { MSG_SUID_SUMMARY,SH_ERR_INFO, RUN, N_("msg=\"Checked for SUID programs: %ld files, %ld seconds\"") },
402#endif
403</pre>
404<p>
405as part of the table msg_cat[] of type cat_entry:
406</p>
407<pre>
408
409typedef struct foo_cat_entry {
410 unsigned long id;
411 unsigned long priority;
412 unsigned long class;
413 char * format;
414} cat_entry;
415</pre>
416<p>
417The first member of this structure is the message type's ID, as
418defined in the enum in sh_cat.h. The second is the default priority of
419such messages, defined as in the samhain documentation. The third is
420the class of the message, again defined as in the samhain
421documentation. Finally we have the message format itself, which is a
422printf() style format string.
423</p>
424<p>
425This catalogue is used by the logging functions in samhain; you will
426need to add your own message types and formats to sh_cat.h and
427sh_cat.c. Note that because samhain can be compiled for XML style
428logging, you will actually need to make two entries in sh_cat.c for
429each message; see the file itself for details.
430</p>
431<p>
432Note that there is a generic message format with the ID 'MSG_E_SUBGEN'
433and the default priority 'SH_ERR_ERR'. If you are using this message
434format, then you can log (a) a string, and (b) the name of the subroutine.
435</p>
436<p>
437This completes our description of samhain's module interface.
438</p>
439
440<h2>Samhain's utility functions</h2>
441<p>
442Here we'll describe the main utility functions available to samhain module
443authors.
444</p>
445
446<h3>String wrapping macros</h3>
447
448<p>
449Constant strings should be wrapped in the _(string) macro. Initialisation
450strings that cannot be replaced with a function should be wrapped
451in a N_(string) macro, and the variable thus initialized should be
452wrapped in a _(var) macro whereever used. This is important for the
453'stealth' functionality of samhain.
454</p>
455
456<h3>Logging messages</h3>
457
458<pre>
459#include "sh_error.h"
460
461void sh_error_handle(int severity, char * file, long line, long status,
462 unsigned long msg_id, ...)
463</pre>
464<p>
465This is samhain's logging/reporting function, so the name is a little
466misleading - errors are not the only thing we should handle with
467this. The first four arguments are simple enough: severity is the
468logging severity, defined in the enum ShErrLevel from sh_error.h; file
469and line are the current file and line - usually you'll be using FIL__
470and __LINE__ for these; status is not very important - for module
471authors it'll do to always pass 0 to this. The final named argument is
472msg_id, which should be one of the message IDs defined in sh_cat.h;
473these correspond to message format strings in printf() format, which
474will be interpolated with the following arguments to form the log
475message.
476</p>
477<p>
478The '__LINE__' macro is provided by the C preprocessor. The FIL__ macro
479should be #defined to '_("sourcefile_name")' (see 'String wrapping macros'
480above).
481<p>
482Example of use:
483</p>
484<pre>
485#undef
486#define FIL__ _("sh_mounts.c")
487
488sh_error_handle(ShMountsSevMnt, FIL__, __LINE__, 0, MSG_MNT_MNTMISS,
489 cfgmnt->path);
490</pre>
491<p>
492See cat.c for the definition of MSG_MNT_MNTMISS:
493</p>
494<pre>
495
496{ MSG_MNT_MNTMISS, SH_ERR_WARN, RUN, N_("msg=\"Mount missing\" path=\"%s\"")},
497</pre>
498<p>
499So we print this out at severity ShMountsSevMnt, which in this case is
500a configured value read from the samhain configuration file (see
501sh_mounts.c). If we wanted to print it at the default severity
502(SH_ERR_WARN), we could pass -1 as the severity.
503</p>
504
505<h3>Checking files for modification</h3>
506
507<pre>
508#include "sh_files.h"
509
510int sh_files_pushdir_?? (char * dirName);
511int sh_files_pushfile_?? (char * fileName);
512</pre>
513<p>
514These functions push directories and files onto the stack of those to check
515for the specified policy (see the samhain documentation for further
516information):
517<table>
518 <tr><td> sh_files_pushdir_user0 </td><td>pushes the directory at USER0 </td></tr>
519 <tr><td align=right> ... _user1</td><td align=right>USER1</td></tr>
520 <tr><td align=right> ... _attr</td><td align=right>ATTR</td></tr>
521 <tr><td align=right> ... _ro</td><td align=right>READONLY</td></tr>
522 <tr><td align=right> ... _log</td><td align=right>LOGFILE</td></tr>
523 <tr><td align=right> ... _glog</td><td align=right>GROWING LOGFILE</td></tr>
524 <tr><td align=right> ... _noig</td><td align=right>IGNORE NONE</td></tr>
525 <tr><td align=right> ... _allig</td><td align=right>IGNORE ALL</td></tr>
526</table>
527So if you're writing a module that adds particular files to check, like the
528sh_userfiles module for example, these are the functions to use.
529</p>
530
531<h3>Managing memory</h3>
532
533<pre>
534#include "sh_mem.h"
535
536#define SH_FREE(a) ...
537#define SH_ALLOC(a) ...
538</pre>
539<p>
540These are the macros to use when you're allocating/freeing memory in
541samhain. They do all the error checking/reporting you need, so when
542you get memory from SH_ALLOC you can just get to using it right away.
543</p>
544
545<h3>Parsing strings</h3>
546
547<pre>
548#include "sh_utils.h"
549
550char * sh_util_strdup (const char * str);
551char * sh_util_strsep (char **str, const char *delim);
552char * sh_util_strconcat (const char * arg1, ...);
553
554int sh_util_flagval(char * c, int * fval);
555int sh_util_isnum (char *str);
556
557#include "slib.h"
558
559int sl_strlcpy (char * dst, const char * src, size_t siz);
560int sl_strlcat (char * dst, const char * src, size_t siz);
561int sl_snprintf(char *str, size_t n, const char *format, ... );
562</pre>
563<p>
564These functions are the samhain internal functions for string
565handling. The first three act like their C library counterparts,
566except using samhain's memory management functions and error
567checking. sh_util_flagval converts the passed string into a truth
568value - the value is stored in <b>fval</b> as 1 or 0 - and returns 0
569on success, -1 on failure. sh_util_isnum just checks if the passed
570string is all numeric.
571</p>
572<p>
573The functions sl_strlcpy and sl_strlcat work similar to the C library
574strncpy/strncat functions, except that the destination string is always
575null terminated, and the third argument must be the full length of the
576destination buffer, <i>not</i> the remaining space. On success, the
577return value is 0.
578</p>
579<p>
580The function sl_snprintf provides either the system snprintf, or a replacement,
581if the system has no or a buggy snprintf.
582</p>
583
584<h3>Tracing execution</h3>
585
586<pre>
587#include "slib.h"
588
589#define SL_ENTER(s) ...
590#define SL_RETURN(retval, s) ...
591</pre>
592<p>
593These macros are for tracing execution through samhain functions. You
594should use SL_ENTER with the name of the function for each function
595entered, and SL_RETURN with the return value and the name of the
596function for each exit if you want to maintain compatibility with the
597rest of samhain.
598</p>
599
600<h3>Executing external programs (popen)</h3>
601
602<pre>
603#include "sh_extern.h"
604
605
606sh_tas_t task;
607/* Prepare task */
608sh_ext_tas_init(&task);
609sh_ext_tas_command(&task, char * command);
610sh_ext_tas_add_argv(&task, char * val);
611sh_ext_tas_add_envv (&task, char * environment_variable, char * value);
612
613int sh_ext_popen(&task);
614int sh_ext_pclose(&task);
615</pre>
616<p>
617To prepare a task to run, use 'sh_ext_tas_init' to initialise the task
618structure. With 'sh_ext_tas_command' the command (absolute path) is set,
619with 'sh_ext_tas_add_argv' command line options are added. Environment
620variables can be set with 'sh_ext_tas_add_envv'.
621</p>
622<p>
623To open for read, set &quot;task.rw = 'r';&quot;, to open for write
624use &quot;task.rw = 'w';&quot;.
625</p>
626<p>
627To run the task with privileges dropped to another UID, set
628&quot;task.privileged = 0;&quot; and task.run_user_uid, task.run_user_gid
629to the desired UID/GID.
630</p>
631<p>
632To verify the checksum of the called executable, set
633task.checksum[KEY_LEN+1] to the TIGER192 checksum of the executable.
634</p>
635<p>
636After successful execution of sh_ext_popen (return status 0),
637task.pipe is the stream opened for read or write, and task.pipeFD
638its associated file descriptor.
639</p>
640
641<h3>Inserting arbitrary data into the baseline database</h3>
642<pre>
643
644#include "sh_hash.c"
645
646void sh_hash_push2db (char * key, unsigned long val1,
647 unsigned long val2, unsigned long val3,
648 unsigned char * str, int size);
649
650char * sh_hash_db2pop (char * key, unsigned long * val1,
651 unsigned long * val2, unsigned long * val3,
652 int * size);
653</pre>
654<p>
655The baseline database has a fixed record format. To enter data, these need
656to be prepared in the required format. To retrieve the data, the
657'filepath' is used as key (if your data is not a file, you would provide
658a dummy pathname as key). For convenience, the two functions noted below
659are provided.
660</p>
661<p>
662When checking files, samhain will walk the database to find files that
663are in the database, but have been deleted from the disk. If you enter
664non-file data, you need to mark it as such by using a key that
665starts with a 'K'.
666</p>
667<pre>
668
669#include "sh_hash.c"
670
671void sh_hash_push2db (char * key, unsigned long val1,
672 unsigned long val2, unsigned long val3,
673 unsigned char * str, int size);
674
675char * sh_hash_db2pop (char * key, unsigned long * val1,
676 unsigned long * val2, unsigned long * val3,
677 int * size);
678</pre>
679<p>
680To insert data, use 'sh_hash_push2db'. You can insert up to three long
681integers (val1, val2, val3) and/or a binary string of length size
682(max. (PATH_MAX-1)/2). As noted
683above, you need to supply a key (stored as the 'filepath', which should
684start with the character 'K'). To retrieve data, you can use
685'sh_hash_db2pop'. The return value is either NULL (if no string was
686stored under this key), or the stored string (length returned in 'size').
687</p>
688<p>
689A string to store may consist of any characters, including NULLs, and
690need not be NULL terminated. The returned string is
691always NULL terminated (the terminating NULL is not included in 'size'),
692and should be freed with SH_FREE() if not required anymore.
693</p>
694<p>
695If the key is not found in the database, <b>size</b> is set to -1.
696</p>
697
698<h2>Incorporating modules into the samhain build</h2>
699<p>
700This is a somewhat secondary but important part of writing a module
701for samhain:
702how to incorporate it into the samhain configuration and build process.
703This just involves hacking the autoconf and makefile setup to include your
704module. We'll present this file-by-file.
705</p>
706<h3>Makefile.in</h3>
707<p>
708You need to add a few bits to this file. First, add your header,
709source and object filenames to the HEADERS, SOURCES and OBJECTS
710variables. Then add your header to the dependencies for sh_modules.o
711and ./sh_modules.o. Finally add dependency lines for your module
712object file sh_whatever.o and ./sh_whatever.o, modelling them on the
713other module object dependency lines.
714</p>
715<h3>acconfig.h</h3>
716<p>
717The config.h.in will be generated from this file by 'autoheader'.
718You just need to add a line like
719<pre>
720#undef SH_USE_MOUNTS
721</pre>
722that will be defined by the ./configure code if the user specifies
723the module as enabled.
724</p>
725<h3>aclocal.m4</h3>
726<p>
727This file is used by 'autoconf' to help generate ./configure. You need to add
728your module's ./configure option to the SH_ENABLE_OPTS variable; for example,
729to add the option --enable-mounts-check, we added the string 'mounts-check' to
730this variable.
731</p>
732<h3>configure.ac</h3>
733This is the other file used by 'autoconf' to generate ./configure. You need to
734add an AC_ARG_ENABLE call to this file, along the lines of those for other
735modules. For example, we added
736<pre>
737AC_ARG_ENABLE(mounts-check,
738 [ --enable-mounts-check check mount options on filesystems [[no]
739]],
740 [
741 if test "x${enable_mounts_check}" = xyes; then
742 AC_DEFINE(SH_USE_MOUNTS)
743 fi
744 ]
745)
746</pre>
747for the sh_mounts module. This causes the #undef from acconfig.h above
748to be defined when ./configure is run with the --enable-mounts-check argument.
749</p>
750This is all that you need. Once you've done the above, you'll need to
751run 'autoheader' and 'autoconfig' to generate config.h.in and the
752./configure script. Then your module will build as part of the samhain
753source.
754</p>
755
756<h2>Conclusion</h2>
757<p>
758Armed with the above information, any proficient C programmer should
759be able to adapt and extend samhain to do whatever it is they need. We
760hope that this document has been reasonably clear, easy to follow and
761useful; please feel free to update it for clarity, accuracy and
762completeness and resubmit it to the samhain project.
763</p>
764<p>
765This document was written by the eircom.net Computer Incident Response Team.
766Updated with CSS by Rainer Wichmann.
767</p>
768</div>
769</body>
770</html>
Note: See TracBrowser for help on using the repository browser.