Fedora Activity (half) Day
The FAD (Fedora Activity Day) was announced over a month ago with an intention to get some real work done during an event. I really only had a chance to participate in 1/4th of the FAD (1/2 day on Saturday), since I had to fly to Bangalore on Saturday evening to spend the weekend (or whatever was left of it) with family. But that was enough to get whatever I wanted out of the event.
Being pretty much a newcomer into the Fedora community, there wasn't much that I could think of to directly contribute but I wanted to do something. I really only maintain 1 package, which also does not have much traffic, so I wasn't exactly brimming with ideas. Rahul helped me there by asking me to do an Autotools workshop. I was also looking forward to meeting some of the guys I had met at FOSS.in last year; Susmit, Hiemanshu and Sayamindu. I could not meet Hiemanshu (did he come at all?), but it was good to meet Susmit and Sayamindu after quite a long time.
We started the day with my autotools workshop; I hope at least someone found it useful. I demonstrated the process of autotoolizing a simple C program using the same example I used during my Fedora classroom session earlier this month: linkc. The main reason I keep choosing this program is that I am too lazy to find or write anything on my own. The other reason is that the program helps to cover quite a few things at one go -- it is small, it has an external dependency, a subdirectory and some distributable files. So all those things win over the fact that the app just doesn't work as advertised. Oh well...
Once the only "session" of the day was over, everyone announced their aims for the two days while Sankarshan distributed some swag (t-shirts, stickers and buttons). After that it was pretty much everyone working on their own stuff. Me too.
Only a couple of days before FAD, Ray van Dolson added me as a co-maintainer for libyahoo2 in Fedora so that we could share the workload of doing releases/bug fixes. After discussion with him, I decided to do a libyahoo2 release into rawhide during the event. So I finally had something that I could do, which was much closer to Fedora.
I knew that the release would break freehoo, a console messenger for yahoo since libyahoo2 1.0.0 broke all backward compatibility, so I set about fixing that. The result was a bug report with a patch to fix freehoo to build with the latest libyahoo2. Finally, I also changed ayttm to dynamically link against libyahoo2 instead of cloning the code base all the time. There was absolutely no incentive in maintaining two code bases for it, so it finally had to go.
By the time the ayttm change was done, it was time to leave. But before that, Kushal asked me to take a look at libraw to see if I could pitch in with something there. So I will be looking at autotoolizing it and packaging it for Fedora. I was supposed to do it today, but all of my day was spent in playing catch-up with work at my day job. Maybe I'll have more time tomorrow for it.
Finding connections to a specific port with SystemTap
Earlier in the week I was asked by someone if I know a way to monitor applications trying to connect to the telnet port. The obvious answer was netstat/lsof, but the problem was that this application would be up for merely seconds and he did not know when/where it started up. All he had was his telnetd log telling him about the connections. So I decided to go the SystemTap way and came up with this:
/* snoop.stp */ function sockaddr_to_port:long(sck:long) %{ short ret = 0; struct sockaddr *sock = (struct sockaddr *) (long) THIS->sck; memcpy(&ret, sock->sa_data+1, 1); memcpy(((char *)&ret)+1, sock->sa_data, 1); THIS->__retvalue = ret; %} global testport = 0 probe begin(0) { if (testport == 0) { printf("Usage staprun snoop.ko testport=<portnum>\n"); exit(); } } probe syscall.connect { port = sockaddr_to_port($uservaddr) if (port == testport) { printf ("%d: %s trying to connect to port %d\n", gettimeofday_s(), execname(), testport); printf ("\tPID: %d\n", pid()); printf ("\tUID: %d\n", uid()); printf ("\tEUID: %d\n", euid()); printf ("\tParent: %s\n", pexecname()); printf ("\tPPID: %d\n", ppid()); } }
So this really is a very simple tap on the connect syscall to be able to intercept all connect requests on the system. The sockaddr_to_port
is a little more interesting. It takes the first two bytes of sockaddr->sa_data and swaps them to get them to the correct byte order to return as the port number. The reason for the swap is that network byte ordering is essentially big endian (The most significant byte first) while x86 computers are little endian. So the port number 23, at byte level would be seen on your computer as:
0x00170000
while in network byte order it is seen as:
0x00000017
Once we have the port number, the rest is easy pickings with SystemTap giving us easy functions to collect the executable name, pid, parent process name, etc. As for the date, one may easily convert it to human readable form using:
date -d @<my date in seconds>
Now that we have all the pieces in place, we can build the above script into a kernel module using:
stap -vvvg -r `uname -r` snoop.stp -m snoop
The output of this is the kernel module named snoop.ko. The -g signifies the "Guru mode". We need it since our function sockaddr_to_port
is embedded C and we need to tell stap that we really know what we're doing. I like putting in a lot of v's in the first place so that I get build errors right away. This is essentially building a kernel module. The -r and -m are for kernel version number and module name respectively. Once built, you can deploy the module using:
staprun snoop.ko testport=23
This loads the module into the kernel and waits to print messages (whenever the program decides to connect to telnet) to standard output. If you look into the output of lsmod, you will find that snoop is a loaded module.
Packages you will need to implement all of this:
- systemtap
- systemtap-runtime
- kernel-debuginfo
- kernel-devel
- kernel-debuginfo-common
If you're using the PAE kernel then you need the kernel-PAE-debuginfo and kernel-PAE-devel instead of kernel-debuginfo and kernel-devel. If you're only looking to deploy a binary systemtap module, you will only need systemtap-runtime. Yes, I can run a module built on one system, on another system provided they have the same kernel version and architecture. But be careful of what you run, always inspect the source to make sure you're not running anything malicious.
Checking Reliance Netconnect prepaid account usage
So I've been using the Reliance Netconnect usb dongle since I shifted to Magarpatta City. Since work is so close to home now, I really only need internet access at home to check emails when I wake up (yes, I am an addict). Being a prepaid account, I wanted to know how I could monitor my usage. I asked the vendor and he told me to go to the Usage menu. I told him I use Linux. He insisted that I ought to be going to the usage menu.
I gave up asking him.
And it was a good thing I did, because the information was quite easily available online. All you had to do was go to this URL and enter your MDN, i.e. the number of your netconnect dongle. But that was very cumbersome, so I hacked up this little script so that usage monitoring is now just a command away:
#!/bin/sh cleanup_temp () { rm -f $tempfile exit 2 } if [ $# -lt 1 ]; then echo "Usage: $0 <reliance netconnect number>" exit 1 fi trap cleanup_temp SIGINT trap cleanup_temp SIGTERM trap cleanup_temp SIGHUP tempfile=`mktemp` nc reliancenetconnect.co.in 80 > $tempfile <<ECHO POST /RNetconnect/RNC/Netconnect_Authentication.jsp HTTP/1.1 Host:reliancenetconnect.co.in Content-type: application/x-www-form-urlencoded Content-Length: 14 MDN=$1 ECHO grep "and your Netconnect" $tempfile | links -dump rm -f $tempfile
And if you want to make things even simpler, modify the above to read the number from an environment variable and export that variable in your .bashrc.
libyahoo2 is now 1.0.0
There have been a number of code changes in libyahoo2 since some time now, with Gennady Feldman and later me pitching in. So it was finally time to do a release. My primary motivation for this was to remove libyahoo2 code base from ayttm and have it link dynamically to libyahoo2. I hope Ray van Dolson packages libyahoo2 for Fedora soon, so that I can pester Minto to package ayttm with that patch too.
The YMSG16 support changes in 1.0.0 will break things for many people using libyahoo2, but that was necessary. I wanted to avoid tying libyahoo2 to a specific crypto library for SSL use and also reduce the overhead of maintaining that code base. The result of this change is that it removed all of the networking code from libyahoo2 as well, which reduced maintenance overhead even more.
Another big change was the removal of the ability to bypass the callback struct and link functions directly. It would make things difficult when you're trying to find out in your configure script if the library is installed. One would have to write a test program in the autoconf, which would have to have all the callbacks implemented, to be able to compile successfully. That is painful. Also, The approach is much more extensible compared to earlier the approach.
There are a number of things that we still need to get done in libyahoo2:
- Chat room support
- Webcam support— I am not sure if it is broken since I don't have a webcam to test, but I want to make sure anyway
- Are mail notifications working?
- Voice support
I will be submitting a Fedora Summer Coding idea for libyahoo2 soon to add chat room support as a mentor. The major skills required for this would be C and the ability to read and understand wireshark dumps.
Viewing signal numbers in gdb
Recently someone asked me if there was a way, with gdb, to find out for which signal a particular signal handler was called. The catch was that there were no debugging symbols, but the binary was not stripped either. That way I could set breakpoints and do some general debugging on the flow of the program but not view variable values directly. So the backtrace does not show the signal number that was passed into the signal handler and I would have to do some magic to get at that value. So here's a little demo to explain what I did:
So I had a program that looked like this:
#include <signal.h> #include <stdio.h> void foo(void) { printf ("that's all folks!\n"); } void handler(int sig) { foo(); } int main() { signal(SIGIO, handler); while(1); }
I built the program, started it under gdb and set a break point at foo(). I then ran it and from another terminal, did a killall -IO a.out. here's what I got:
(gdb) bt #0 0x00000000004004dc in foo () #1 0x00000000004004f8 in handler () #2 <signal handler called> #3 0x000000000040050d in main ()
Notice that the argument value for the handler() function is not shown, which is our problem. This is because there is no way that gdb would know anything about the arguments without any debug symbols, i.e. the number of arguments, the size of each argument, etc. But we do. A signal handler has only one argument and it is an integer. It is the signal number.
To go any further, we need to check out the stack frame of handler(). As you can see in the stacktrace above, it is frame 1, so here's what we get:
(gdb) info frame 1 Stack frame at 0x7fff84277c30: rip = 0x4004f8 in handler; saved rip 0x301e2301b0 called by frame at 0x7fff84277c38, caller of frame at 0x7fff84277c10 Arglist at 0x7fff84277c20, args: Locals at 0x7fff84277c20, Previous frame's sp is 0x7fff84277c30 Saved registers: rbp at 0x7fff84277c20, rip at 0x7fff84277c28
So we know now that the arglist starts at 0x7fff84277c20, so the signal number argument should be in this region. Since it is a 32 bit value, we do some basic math and go down the stack by 4 bytes to see what word is stored at 0x7fff84277c1c:
(gdb) x/1 0x7fff84277c1c 0x7fff84277c1c: 0x0000001d
Do some more college math and convert 0x0000001d to decimal and we get 29. Lookup signum.h (search for it in /usr/include) and you'll see that it is SIGIO, the signal I sent in my kill. W00t!!
One may use this method to also get local variables of that function. It is just that we will have to do some guessing to find out the sequence of the locals in the stack if one does not have access to the source code. It should not be that hard though. This may also be one of the bases for those try to use buffer overflows to overwrite some value in the stack and hence modify the flow of a program. I'm yet to figure out how one could overwrite stuff far enough to drop from the program right into a shell. Learning computer science bit by bit now after wasting 6+ years of formal schooling in it :)
gource in Fedora
My first package submission was finally completed a few days ago with everything from ticket overload, personal issues to my US trip making sure that I had little time to get things done on time. I had started this in the first week of December and it took all of 2 months and some days to get my stuff together and put out an rpm package for gource. It is finally done now and you can install gource on your Fedora 12 box (or later if you're nutty like me) with just a
~# yum install gource
I've built gource only for F-12 and later since F-11 does not have the required version of ftgl. That is OK I guess since F-11 is way too old anyway ;)
Messaging and me
I've been in the US for a week now. I've reached Raleigh, the final destination in my short trip in the US. I'll be here for another week before I go back /home. I was in Westford last week and in Boston over the weekend.
I was in Westford to get trained to support Red Hat MRG Messaging. The upstream for this is the Apache QPid Project. This seems to be a very promising product, especially with its speed of messaging. The training was fun and I got to meet some really cool people here, including fellow GSS geeks Ryan Mitchell and Andrew Blum. I got a chance to interact with the qpid hackers too, which was really cool. I attempted to dig a bit into the code to understand some random stuff, but haven't made much headway since.
I left for Boston on Friday and spent the weekend there. I only had enough time to visit the Museum of Science and the Aquarium. We managed time pretty badly though; we could have squeezed in some more. I met up with Philip for lunch today at an interesting place called the Toro in South End, Boston. You gotta go there to try the bone marrow tapas. It was awesome.
Waiting now to get to the mother ship, the GSS headquarters tomorrow; a chance to meet people who I work with across the oceans and across time zones.
Net4 and the agony of Received-SPF
Warning: This is a bit of a rant, so read on only if you’re in a bad mood and want someone to cuss at (either me or the entity I’m cussing at ;) )
I had recently bought email hosting services for my Mom from Net4 following decent service on the domain and web hosting front. It was a stupid decision. Net4 support for email pretty much sucks. Maybe I have only been lucky with the web hosting support too as I did not have to deal with morons for the most part. For the last two days I haven’t been so lucky.
I noticed the problem soon after the email hosting got activated — emails that I would send to any gmail accounts would go into the spam folder. I ignored it in the beginning mainly because I wasn't interested enough to look hard for what is wrong. But recently mom started complaining about it since her customers were not getting her emails. So we opened a ticket with Net4. For good measure, I also called so that I get immediate feedback. I was told to attach a sample email that went into spam. I did that. The support person then closed the ticket the next day asking for a sample email. Interesting.
So I open a support ticket once again and this time I try to do some research on why gmail may be doing this. I noticed the following header:
Received-SPF: neutral (google.com: xx.yy.zz.aa is neither permitted nor denied by best guess record for domain of mom@example.com) client-ip=xx.yy.zz.aa;
So I look up google and come across this article on SPF records. Apparently, net4 ought to be adding an SPF entry for my domain associating it with their mail servers. This entry will lead to the Received-SPF header being "pass" instead of "neutral". This is something that gmail takes into consideration while filtering for spam. While I realize that there may be other matters (email content, subject, etc.), all those factors do not come into the picture with my sample email. This seems to be the only missing link since my domain, mail server, etc. are not blacklisted either. I mention it in the support ticket and again attach the sample email. The ticket gets closed again with a request for a sample email. WTF?
I call up and ask the support tech. I try explaining about SPF and how that might be affecting things and he goes all ballistic (not figuratively, he's positively shouting) on me saying that this is on Linux and it does not work the way I am saying. With my ego hurt, I shouted back saying that I work for a Linux company :P
We end the call with the tech telling me that I am only throwing keywords around without knowing anything about it. He asks me how I would fix this and I admit that I don't know right away but I can do his job and look it up. He then bullshits me about how it is "the pop3 end which marks the spam with either SPAM tag in subject or moving to a spam folder" and so on. According to him SPF is something different and there is nothing wrong with it. He ended it saying that I was being an ass and that he will escalate the issue.
No, there is no hope. The last two issues were escalated too. Apparently everyone at Net4 is just a bunch of incompetent fools. Either that or those who aren't are eyeing management positions since that is the "way up the ladder". Or they're on their way out.
I think I need to be on my way out of this service. I may not get a refund this time but I can surely make sure that I don't renew my services with them and definitely not recommend their services to people I care about.
The question of cdb and pjpdns
I finally got myself to start working on the pjpdns stuff and the cdb vs tinycdb question resolved itself pretty soon as far as pjpdns is concerned. Some functions and their arguments (cdb_findnext, cdb_findstart, etc.) have changed in tinycdb due to which pjpdns would not link against it as is. I would have to patch it to get it working.
Of course, being a lazy bum, I took the easy route and linked against my fork of cdb, which worked. Here is my fork of pjpdns with the changes. There are still some things that can be trimmed out in pjpdns as a result of this. There's also the entire "unlicensed code" thing I need to sort out since a lot of code in the original cdb does not have any license.
There are also a bunch of other changes I made to pjpdns, which included removing some auto-generated cruft from the repository and adding a bit of autotools candy so that any future autotools related changes don't result in git-log spam.
cdb f0rked!
PJP had given a presentation some weeks ago on what would probably end up being pjpdns. One of the problems pointed on on his review request for inclusion of djbdns into Fedora was that it included code for cdb, which exists as a separate package and hence should be dynamically linked to instead. Someone even pointed out that (s)he had autotoolized cdb but did not respond to any further requests for more information.
I figured it was something I could do, so I went ahead and ported cdb to gnu-autotools. Here is my cdb fork. There is still some code which is unused, but I haven't really bothered to update in much since the time I found tinycdb, which seems to be maintained too. So my next project is to try and get djbdns to either use tinycdb or if that fails, my cdb fork.
I wonder how I can license the cdb fork though (if I decide to distribute it at some point). A lot of code is unlicensed, which is why (according to wikipedia) the tinycdb fork was written in the first place.
Oh, and let it be recorded officially and publicly that if pjpdns goes live, it was me who misread djbdns during the beginning of the presentation as pjpdns. Yes, that is my desperate attempt at being relevant to something completely unrelated :D
Comments are closed.