Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Tuesday, January 1, 2013

Deprecated functions in ffmpeg library

Well, I have some code that uses some old FFMPEG library, and now, as I updated my laptop to Fedora 18, it turns out that those functions are gone for good. I found some resources about how to port old code (here, here and here), but since it wasn't what I needed I decided to write my own version. So, here we go.

url_open()

This function has been changed to avio_open. There is also url_close which is renamed to avio_close. This information I found here.

av_new_stream()

This function is still supported as of FFMPEG 1.0.1 but it is marked as deprecated. It will be replaced with avformat_new_stream(). Suppose that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 old code was:
AVStream *st = av_new_stream(oc, i);
cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 modified code should be:
AVStream *st = avformat_new_stream(oc, NULL);
st->id = i
Be careful to check first that st isn't NULL!

dump_format()

This function was renamed to av_dump_format().

av_write_header()

Replaced with avformat_write_header() that accepts two arguments instead of one. Pass NULL as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second argument to get identical behavior to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 old function.

av_codec_open()

This one is replaced with av_codec_open2(). The replacement function accepts three arguments instead of two, but put NULL as a third argument to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same behavior as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 old function.

avcodec_encode_audio()

Replaced with avcodec_encode_audio2().

av_set_parameters()

I couldn't fine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 replacement for this one. First, I've found that this function doesn't have replacement. But it was when it was still available in FFMPEG, even though deprecated. Then, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y removed it, and thus it has to have replacement. In certain places I found that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y only disabled it, on ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs that its parameters have to be passed  to avformat_write_header. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end, I gave up because I didn't need working version of that part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code for now. Since in my case avformat_alloc_context() is called and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n av_set_parameters(), last what I looked at was to call avformat_alloc_output_context2() instead of avformat_alloc_context(). But cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 change is not trivial so I skipped it.

SampleFormat

This enum has been renamed AVSampleFormat.

URL_WRONLY 

This constant has been replaced with AVIO_FLAG_WRITE.

SAMPLE_FMT_U8, SAMPLE_FMT_S16, SAMPLE_FMT_S32, etc.

Those are prefixed now with AV_, so use AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16, etc.


Thursday, December 27, 2012

UDP Lite...

Many people know for TCP and UDP, at least those that work in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 field of networking or are learning computer networks in some course. But, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 truth is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs too, e.g. SCTP, DCCP, UDP Lite. And all of those are actually implemented in Linux kernel. What I'm going to do is describe each one of those in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following few posts and give examples of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir use. In this post, I'm going to talk about UDP Lite. I'll assume that you know UDP and also that you know how to use socket API to write UDP application.

UDP Lite is specified in RFC3828: The Lightweight User Datagram Protocol (UDP-Lite) . The basic motivation for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 introduction of a new variant of UDP is that certain applications (primarily multimedia ones) want to receive packets even if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are damaged. The reason is that codecs used can recover and mask errors. UDP itself has a checksum field that covers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whole packet and if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is an error in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 packet, it is silently dropped. It should be noted that this checksum is quite weak actually and doesn't catch a lot of errors, but nevercá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less it is problematic for such applications. So, UDP lite changes standard UDP behavior in that it allows only part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 packet to be covered with a checksum. And, because it is now different protocol, new protocol ID is assigned to it, i.e. 136.

So, how to use UDP Lite in you applications? Actually, very easy. First, when creating socket you have to specify that you want UDP Lite, and not (default) UDP:
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE);
Next, you need to define what part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 packet will be protected by a checksum. This is achieved with socket options, i.e. setsockopt(2) system call. Here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function that will set how many octets of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 packet has to be protected:
void setoption(int sockfd, int option, int value)
{
    if (setsockopt(sockfd, IPPROTO_UDPLITE, option,
            (void *)&value, sizeof(value)) == -1) {
        perror("setsockopt");
        exit(1);
    }
}
It receives socket handle (sockfd) created with socket function, option that should be set (option) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 option's value (value). There are two options, UDPLITE_SEND_CSCOV and UDPLITE_RECV_CSCOV. Option UDPLITE_SEND_CSCOV sets cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of protected octets for outgoing packets, and UDPLITE_RECV_CSCOV sets at least how many octets have to be protected in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 inbound packets in order to be passed to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application.

You can also obtain values using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following function:
int getoption(int sockfd, int option)
{
  int cov;
  socklen_t len = sizeof(int);
  if (getsockopt(sockfd, IPPROTO_UDPLITE, option,
  (void *)&cov, &len) == -1) {
  perror("getsockopt");
exit(1);
}
return cov;
}
This function accepts socket (sockfd) and option it should retrieve (i.e. UDPLITE_SEND_CSCOV or UDPLITE_RECV_CSCOV) and returns cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 option's value. Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two constants, UDPLITE_SEND_CSCOV or UDPLITE_RECV_CSCOV, should be explicitly defined in your source because it is possible that glibc doesn't (yet) define cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.

I wrote fully functional client and server applications you can download and test. To compile cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m you don't need any special options. So that should be easy. Only change you'll probably need is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IP address that clients sends packets to. This is a constant SERVER_IPADDR which contains server's IP address hex encoded. For example, IP address 127.0.0.1 is 0x7f000001.

Finally, I have to say that UDP Lite will probably have problems traversing NATs. For example, I tried  it on my ADSL connection and it didn't pass through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NAT. What I did is that I just started client with IP address of one of my servers on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Internet, and on that server I sniffed packets. Nothing came to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server. This will probably be a big problem for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 adoption of UDP Lite, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time will tell...

You can read more about this subject on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wikipedia page and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux manual page udplite(7).

Tuesday, December 25, 2012

Controlling which congestion control algorithm is used in Linux

Linux kernel has a quite advanced networking stack, and that's also true for congestion control. It is a very advanced implementation who's primary characteristics are modular structure and flexibility. All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 specific congestion control algorithms are separated into loadable modules. The following congestion control mechanisms are available in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mainline kernel tree:
Default, system wide, congestion control algorithm is Cubic. You can check that by inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file /proc/sys/net/ipv4/tcp_congestion_control:
$ cat /proc/sys/net/ipv4/tcp_congestion_control 
cubic
So, to change system-wide default you only have to write a name of congestion control algorithm to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same file. For example, to change it to reno you would do it this way:
# echo reno > /proc/sys/net/ipv4/tcp_congestion_control
# cat /proc/sys/net/ipv4/tcp_congestion_control
reno
Note that, to change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value, you have to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root user. As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root you can specify any available congestion algorithm you wish. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 algorithm you specified isn't loaded into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel, via standard kernel module mechanism, it will be automatically loaded. To see what congestion control algorithms are currently loaded take a look into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file /proc/sys/net/ipv4/tcp_available_congestion_control:
$ cat /proc/sys/net/ipv4/tcp_available_congestion_control
vegas lp reno cubic
It is also possible to change congestion control algorithm on a per-socket basis using setsockopt(2) system call. Here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 essential part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code to do that:
...
int s, ns, optlen;
char optval[TCP_CA_NAME_MAX];
...
s = socket(AF_INET, SOCK_STREAM, 0);
...
ns = accept(s, ...);
...
strcpy(optval, "reno");
optlen = strlen(optval);
if (setsockopt(ns, IPPROTO_TCP, TCP_CONGESTION, optval, optlen) < 0) {
    perror("setsockopt");
    return 1;
}
In this fragment we are setting congestion control algorithm to reno. Note that that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 constant TCP_CA_NAME_MAX (value 16) isn't defined in system include files so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y have to be explicitly defined in your sources.

When you are using this way of defining congestion control algorithm, you should be aware of few things:
  1. You can change congestion control algorithm as an ordinary user.
  2. If you are not root user, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n you are only allowed to use congestion control algorithms specified in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file /proc/sys/net/ipv4/tcp_allowed_congestion_control. For all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r you'll receive error message.
  3. No congestion control algorithm is bound to socket until it is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connected state.
You can also obtain current control congestion algorithm using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following snippet of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code:
optlen = TCP_CA_NAME_MAX;
if (getsockopt(ns, IPPROTO_TCP, TCP_CONGESTION, optval, &optlen) < 0) {
    perror("getsockopt");
    return 1;
}
Here you can download a code you can compile and run. To compile it just run gcc on it without any special options. This code will start server (it will listen on port 10000). Connect to it using telnet (telnet localhost 10000) in anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r terminal and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 moment you do that you'll see that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 example code printed default congestion control algorithm and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n it changed it to reno. It will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n close connection.

Instead of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conclusion I'll warn you that this congestion control algorithm manipulation isn't portable to ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r systems and if you use this in your code you are bound to Linux kernel.

Sunday, August 12, 2012

Implementing OSSEC log reader for Linux audit logs...

After writing log readers for mod_security and regex, I was asked in a private mail if I could implement log reader for Linux audit logs, so I decided to try. Basically, first I was thinking about implementing something more general but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n I decided to keep it simple and not to overdesign it. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conclusion section I'll return to this more complex type of log reader.

Format of linux audit logs

Log records in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux audit files can consist of one or more log lines. For example, here is a record that consists of three lines:
type=NETFILTER_CFG msg=audit(1344674083.473:7422): table=filter family=2 entries=0
type=NETFILTER_CFG msg=audit(1344674083.473:7422): table=filter family=10 entries=0
type=SYSCALL msg=audit(1344674083.473:7422): arch=c000003e syscall=56 success=yes exit=5246 a0=60000011 a1=0 a2=0 a3=0 items=0 ppid=5239 pid=5245 auid=5056 uid=5056 gid=1000 euid=0 suid=0 fsuid=0 egid=1000 sgid=1000 fsgid=1000 tty=pts7 ses=5 comm="chrome-sandbox" exe="/opt/google/chrome/chrome-sandbox" subj=unconfined_u:unconfined_r:chrome_sandbox_t:s0-s0:c0.c1023 key=(null)
and here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one that consist of two lines:
type=AVC msg=audit(1344110282.960:999): avc: denied { write } for pid=4690 comm="plugin-containe" name=".pulse-cookie" dev="dm-3" ino=2883770 scontext=unconfined_u:unconfined_r:mozilla_plugin_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file
type=SYSCALL msg=audit(1344110282.960:999): arch=c000003e syscall=2 success=no exit=-13 a0=7fc060e29240 a1=80142 a2=180 a3=394f64947c items=0 ppid=4463 pid=4690 auid=5056 uid=5056 gid=1000 euid=5056 suid=5056 fsuid=5056 egid=1000 sgid=1000 fsgid=1000 tty=(none) ses=5 comm="plugin-containe" exe="/usr/lib64/xulrunner-2/plugin-container" subj=unconfined_u:unconfined_r:mozilla_plugin_t:s0-s0:c0.c1023 key=(null)
In all those cases, log records share cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same ID (I'll call it a log record ID from now on) which is a number after a timestamp (I placed it in bold in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous two examples).

Design

At least in principle, it is easy to parse those logs. We just extract that field (first number after colon). What makes it complicated is that it isn't garantueed (at least I'm not aware) that log records will not be mixed (i.e. first lines 1 of two records, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir second lines). Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code for reading log files can be called when partial log lines, or records, are written! Finally, we don't know how many lines in each record cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re will be!

So, after we get a new log record ID, we have to wait a bit to see if we are going to receive anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one. After that time passes, without receiving anything, we pass what we have up to now. Again, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a choice here! We can reset timeout if we receive something new, or we can count from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first line. Basically, we can have timeout or window.

Finally, no matter how we implement wait time, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is additional quirck in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way reading log files works. Namely, we can not set timeout mechanism that will call us after some time. We are called by logcollector.c module in regular intervals defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration file (defaulting to 2 s). So, we are going to implement timeout, not in time units, but in a number of those calls. So, if you say window is 1, this means that when we find new log record ID, we'll wait that we are called once more, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n we'll join and send a record. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interval is defined to be 2s, that means waiting time of 2s. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 window is 2, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n we'll send record after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second call, or after 4s. Timeout, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, will function a bit differently. If we say that timeout is 1, that means that at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 moment we find a new log record ID we start timer (initialized to 1). At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next call we first decrement all timers, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n if we get that same log record ID again, we'll reinitialize timer. Finally, we  send all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 records that have expired timers.

Note that we are here introducing runtime per-log reader data (timers, saved logs), which is different than configuration per-log reader data (that comes exclusively from configuration files)! This will be reflected later in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation.

Finally, since this is a Linux specific feature, it is completly disabled if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source is compiled on (or for) windows!

Configuration

So, this is how to configure this log reader in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OSSEC's configuration files. To say that some log file is audit type, you'll use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following element:
linux_auditd
Both timeout and window are specified in time units (T and W must be numbers) defined by logcollector.loop_timeout variable (defined in internal_options.conf). You have to specify one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. It is error to define both, or none!

Implementation notes

For keeping logs until timeout or window expires, I'm using doubly linked list. It is inefficient, but for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time being it will do. More specifically, I'm using OSSEC's list implemenation in shared/list_op.c.
For testing purposes, I also added code that is enabled by defining BUILD_TEST_BINARY. In that case read_linux_audit is compiled which accepts log file that should be read. To emulate how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log grows, binary first opens a new temporary file, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n reads a random number of lines from original file, writes it to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 temporary file, and calls read_linux_audit function, after which, it pauses. This is repeated until all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original log file is exhausted.
To build test binary, first build evertyhing. Then, go to logcollector directory and run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re 'make test'. You'll cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n have binary read_linux_audit.
The testing was as follows:
  1. Run read_linux_audit on a sample audit.log and redirect output to some temporary file. Count a number of lines in a temporary file, it has to be smaller cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original file.
  2. Using simple shell pipe "cut -f2 -d: audit.log | cut -f1 -d\) | sort | uniq | wc -l" I got how many uniqe lines. There was a difference between this and previous step.
  3. Search for a difference (using diff for example) and analyze why it happened. :D

Conclusion

As I said in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 introduction section, I was thinking about implementing a more general reader. Namely, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 idea was that you give cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reader regular expression, and this regular expression is executed against every line. All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lines that have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same return value are treated as a part of a single record and thus are concatenated. Probably when this reader is finished, I suppose writing that more complex one wouldn't be a problem.

I also fixed few small bugs in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code I sent previously, and, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new patch can be found here.

Friday, August 10, 2012

Adding new log types to OSSEC...

I'm using OSSEC for log monitoring, and while it is a great tool cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are some drawbacks. One is that (not so) occasionally Java stack traces are dumped into syslog and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are not properly handled/parsed by OSSEC. The ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r drawback is that I want OSSEC to monitor mod_security logs, which are multi line logs with variable number of lines belonging to each HTTP request/response processed by mod_security. So, I wanted to modify OSSEC in order to allow it to handle those cases, too. To be able to modify OSSEC I started with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 analysis of its source (version 2.6) and based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 analysis, I wrote this text. The goal of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 analysis was to get acquainted on how OSSEC handles log files, document this knowledge, and to propose solution that would handle Java stack traces and mod_security logs.

Configuring log files monitoring

First, ehere are some global parameters that control global log monitoring behavior of each OSSEC agent, or server. More specifically, logcollector.loop_timeout in internaloptions.conf defines how much time (in seconds) OSSEC will wait before checking if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are additions to all log files that it monitors. Default value is 2s, with minimal allowed value of 1 second and maximum 120s.
This is actually cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most important parameter. There are two additional ones, logcollector.open_attempts with allowed values between 2 and 998, and logcollector.debug with allowed values 0, 1 and 2.

Supported log types in OSSEC

If I correctly understand it, OSSEC treats log files as consisting of records. Each record being independent from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous, or any later ones. Rules, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, act on records. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 majority of cases cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 record is identical to a single line of a log file. This is, I suppose, legacy from syslog in which each line was (and still is) separate log entry. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mean time OSSEC was extended so that it supports more different log files:
  • multiline log (read_multiline). The problem with this log format is that it expects that each record consists of a fixed number of lines.
  • snort full log (read_snortfull). This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 closest one to what I need with respect to mod_security, i.e. this one reads several lines, combines cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, and sends cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to log analyzer.
  • some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs I won't analyze now.
The length of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 record is restricted to 6144 characters (constant OS_MAXSTR defined in headers/defs.h). Everything above that length will be cut off and discarded, with an error message logged.

Configuring log files

So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are different log types and to tell ossec for some file which type it is, you use element associated with each monitored file. Each monitored file is defined in element directly beneath element in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ossec configuration file, for example:

   ...
  
      syslog
      path_to_log_file
  

   ...
The configuration file, along with all of its elements, is read by configuration loader placed in src/config subdirectory. The localfile element is processed in function Read_Localfile (file localfile-config.c). For each one logreader structure (defined in localfile-config.h) is allocated and initialized. This structure has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following content:
typedef struct _logreader
{
    unsigned int size;
    int ign;

    #ifdef WIN32
    HANDLE h;
    int fd;
    #else
    ino_t fd;
    #endif
    /* ffile - format file is only used when
     * cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file has format string to retrieve
     * cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 date,
     */
    char *ffile;
    char *file;
    char *logformat;
    char *djb_program_name;
    char *command;
        char *alias;
    void (*read)(int i, int *rc, int drop_it);
    FILE *fp;
}logreader;
Analyzing localfile-config.c file I came to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following conclusions:
  • Underneath element cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following elements are accepted/valid: <>, , , , and .
  • defines cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file, with full path, that is being monitored.
  • tells OSSEC in which format are records stored. The following are hardcoded values in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Read_Local.c file: syslog, generic, snort-full, snort-fast, apache, iis, squid, nmapq, mysql_log, mssql_log, postgresql_log, djb_multilog, syslog-pipe, command, full_command, multi-line, and eventlog. What's interesting is that some of those (marked in bold) don't appear later in log collector!
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 syntax of accepted multi-line log_format is:
    multiline[ ]*:[ ]*[0-9]*[ ]* 
    note that it is not an error, i.e. you can avoid writing any number, but that number defines how many lines should be concatenated before being sent to analyzer module, so it is important you don't skip it. The number part is made available in logformat field of logreader structure. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, when check is made to determine which type of logformat is some logff structure, to detemine it is a multiline cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first character is checked if it is a digit. If it is, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n it is a multiline format. This is actually a hack because in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original design it wasn't planned to have parameters to certain log types!
  • is used to run some external process, collect its output, and send it to central log. Each line outputed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command will be treated as a separate log record. Empty lines are removed, i.e. ignored. Note that command is passed to shell using popen library call. So, you can place shell commands cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re too.
  • in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a reference to a full_command log type format, but it is not supported in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration file. The difference is that this form reads command's output as a single log record.
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of element is stored into logreader.ign field. But cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 use of this field is strange because it is overwritten with number of failed attempts to open log file. I would assume that this parameter would, somehow, allow rate limiting.
  • When defining cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of element certain variables can be used. In case of Windows operating systems, that means % variables (e.g. %SYSTEM% and similar). In case of Unix/Linux glob patterns are allowed (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se are not allowed on Windows). Also, strftime time format specifiers can be used and in that case strftime function will be called with time format specifier and current local time to produce final log's file name.
  • defines an alias for a log file. It is used in read_command.c and read_fullcommand.c files, only. Probably to be substituted instead of command in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output sent to log collector (for readability purposes, instead of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whole complex command line you see just its short version).
  • The function pointer should point to a function returning nothing (void). But, all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read functions return void * pointer and this return value is forced during assignment of a function to this field. Finally, this return value is never used.
  • The return code (*rc parameter) of read functions is also used in a strange way and only once it is different than 0.
Reading and processing log files

Actual monitoring of log files is done by logcollector module (contained in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 src/logcollector subdirectory). If you look at process list you'll see it under cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name ossec-logcollector.
C's main() function of Logcollector module obtains array of logreader structures from config module and calls main function LogCollectorStart(). LogCollectorStart() references logreader structures through logff array pointer.
logreader structures are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n initialized.
Functions to read different type of files are placed in separate files prefixed with string read_. Each file has one globally visible entry function that has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following prototype:
void *read_something(int pos, int *rc, int drop_it);
The function return value isn't used, and most (but not all!) functions just return NULL. pos is index into structure that defines which particular file should be checked by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function. Basically, it indexes array logff. So, logff[pos] is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log file that has to be processed. rc is output parameter that contains return code. Finally, drop_it is a flag that tells reader function to drop record (drop_it != 0) or to process it as usual (drop_it == 0).
So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conclusion is that I should/would create cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following log readers:
  • regex reader that uses regex to define start of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 block, so everything between one line that matches given regex is treated as a log record until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first line that matches cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 regex again. The variation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365me is to have separate regex for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 block.
  • modsec_audit reader. A separate log reader that would combine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 multiline output of modsec into a single line/record understood by ossec. In particular, I'll read only audit log of mod_security, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is also debug log which I'll ignore for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time being.
Plan

So, as I said, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 goal was to solve Java and mod_security log problems. While studying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source I decided to implement two log readers. I'll leave Java for now, since I think it is better solved with modifying syslog (concatenating next line if it doesn't start at column 1). So, one reader that will process mod_security's audit log files and anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one that will use regex to search for start and end of each record. To do so, obviously those two have to be implemented, but also appropriate configurations has to be defined.
Since I definitely decided to go with attributes instead of hacks (as multiline is) I also decided to convert multiline to use attribute to define number of lines that has to be concatenated.
So, new multiline definition in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration file will be:
multiline
And cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attribute lines is mandatory, it defines how many lines in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log file makes one log record! On cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, mod_security for now will use very simple configuration style:
modsec_audit
Finally, regex based log type will use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following type:
regex
And if end_regex isn't specified, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of start_regex will be assumed to be also end_regex. start_regex attribute is mandatory.

Well, basically, that's for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plan.

Implementation

I first implemented code that reads and parses configuration. In order to do that I had to change files src/config/localfile-config.[ch] and src/error_messages/error_messages.h files. Note that I introduced a new field void *data into logreader structure who's purpose is to keep private data of each log reader. In that way I'm not cluttering structure with lots of attributes used only sporadically. Alternatively, I could use union and place everything cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re, but for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time being this will do.

Then I modified src/logcollector/read_multiline.c to take its parameter from a new place in logreader structure, i.e. from private *data pointer. The small problem with how I did it is that it is dependent on 32/64-bit architecture as I'm directly manipulating with pointers, which is actually one big no-no. :) But, for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 prototype it will do.

Next, I copied read_multiline.c into read_modsec_audit.c and modified it to work with mod_security audit logs. Note that mod_security, for each request and response (that are treated as a single record) creates a series of lines and blocks. Block are separated by blank lines, but everything is kept between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following lines:
-- 62a78a12-A--

...

-- 62a78a12-Z--
Blank lines before and after those that mark beginning and an end are ignored. Random looking number (62a78a12) is an identifier that binds multiple blocks togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r in log files. In my implementation I assume cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no interleaving of those!

Finally, I implemented read_regex.c. This one is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read_modsec_audit.c but instead of fixed delimiters for start and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end or a record, delimiters are provided via configuration file in a form of regular expressions. Note that it would be possible to make read_modsec_audit a special case of read_regex via appropriate use of regular expressions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration file.

When modules were finished I just had to integrate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m into logcollector.[ch] (and modify how multiline is detected). And cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation was finished.

All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 changes are provided in new_log_types-v00.patch.

Some conclusions and ideas for a future work

There are few shortcomings of this implementation. First, it is implemented on Linux and only slightly tested even on that platform. So, it is very likely buggy and non-portable across different platforms. Next, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is certainly a non-portable part with respect to 32-bit vs. 64-bit pointers. I marked that part in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code. Finally, security review has to be done, after all, this is security sensitive application!

It seems to me that multiline module doesn't seem to work right, i.e. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are some corner cases when it misbehaves. Namely, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a check that a single line doesn't exceed maximum line size, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no check if more than one line exceeds that threshold. And, probably, if it exceeds, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reading will get out of sync, i.e. wrong lines will be grouped togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r.

For regexp module written as a part of this treatise probably additional attributes should be included, like flags so that you can say, e.g., if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 match should be case sensitive or not. Or, that you can remember matches from start_regex (using () operator) and reuse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m in end_regex regular expression.
For cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end, I don't want to criticize too much, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 build system of OSSEC isn't what you would call: flexible. This isn't a problem for production environment, but for development it is since, to test a single change, you have to rebuild all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source. Also, OSSEC assumes you run it from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 installation directory, which is owned by a root. Again, this is a problem for a development, more specifically testing. I think cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a lot of room for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 improvement.

Thursday, January 19, 2012

Problem with avformat_open_input()

I lost too much time because of a misleading error message reported by avformat_open_input function! I used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following code that exhibit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 error:
AVFormatContext *pFormatCtx = NULL;
...
ret = avformat_open_input(&pFormatCtx, argv[1], NULL, NULL);
if (ret < 0)
   print_error_and_exit(ret, "avformat_open_input()");
print_error_and_exit() is a helper function that uses av_strerror() to give textual representation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 error code stored in ret. Running this code produced cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following output:
$ ./a.out infile.wav outfile.wav
avformat_open_input(): No such file or directory
But cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 infile.wav was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re! Using strace I found that open system call wasn't called and so it was certainly an internal error. This was frustrating! The reason I started to write this code was to find out why I'm getting anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r error in VoIP tool simulator, but I was stuck on something even more basic: Not being able to open a wav file. Googling around I finally found cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following link which explained me a real cause of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 error, i.e. I forgot to call av_register_all() initialization function.

This again shows how important good error reporting is, in both libraries and application programs!

I had also anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r problem with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous code. It was segfaulting within avformat_open_input(). At first, I thought that I found a bug within a library but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n I realized I forgot to initialize pFormatCtx to NULL. Namely, allocating a dynamic variable on stack didn't zero it so it was non-NULL and avformat_open_input() misbehaved. Mea culpa! :)

Thursday, October 13, 2011

Dennis Ritchie died...

Well, anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r great figure of computing has prematurely left us, according to reports on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Internet. This one isn't so well known like Steve Jobs, but his work certainly matches cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one done by Jobs, and in my humble opinion, even exceeds it. His "problem", sort to speak, is that he did everything in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core area of computer science, not in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 consumer part, and he did majority of his work during cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 years when most people even didn't know that computers exists.

The guy is Dennis Ritchie, and he invented C programming language and also took important part in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 development of Unix operating system. His influence was and is great. For example, Android smart phones today all run on top of Linux, which itself started as a Unix derivative. MS DOS was a very poor copy of Unix, and it was evident that it tried to copy Unix. Windows NT in part was also influenced by Unix. Not to mention MacOS X which, in its core, is Unix! And today's biggest businesses run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir core services on Unix machines, not Windows.

The C programming language was, and still is, extremely influential. First, majority of today's operating systems are written in C, and all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r languages have ability to link with libraries written in C. There are numerous applications and libraries written in C. C is, in essence, lowest common denominator. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, we have today many languages which directly or indirectly borrow features from C. For a start C++ started as an extension to C. Which itself influenced many ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r object-oriented programming languages. C's influence can be traced also in all ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r non-OO languages.

All in all, I'm very sad that he passed away. RIP Dennis Ritchie.

About Me

scientist, consultant, security specialist, networking guy, system administrator, philosopher ;)

Blog Archive