C loops: for() and the comma operator

November 2, 2012 2 comments

Everybody knows that in C a for loop has the syntax:

for (variable initialization; exit condition; variable update) {
++++// the body comes here
}

a typical example being:

int i;
for (i = 0; i < 5; i++) {
++++printf("%i ", i);
}

However, all three expressions in the for statement are optional. Even the body is optional. Due to this flexibility when one starts to read C code written by other people it is easy to find for loops with very different looks. In general, those variations are easy to understand. For instance, the above loop can also be written as follows:

int i = 0;
for(; i < 5; i++) {
++++printf("%i ", i);
}

so the variable initialization has been done before the loop is called. If the exit condition is absent then it always evaluates to True. And if the update variable expression is omitted then it is done in the loop body. If all three expressions have been removed from the for statement then we have a potentially infinite loop and we should insert a break statement somewhere in the body.

Things get interesting when the for statement is combined with the infrequently used comma operator.

The comma operator is a sequence point (as they are && and ||) so the order of evaluation of the operands is fixed. It is a binary operator that evaluates its first operand, performs all side effects and discards the result, and then evaluates the second operand and returns its value and type so:

x = (y, z);

will do y and, after performing all side effects, will discard it, then do z and finally will set x to z.

Because the comma operator discards its first operand, it is useful where the first operand has desirable side effects, such as in the initializer or the counting expression of a for loop.

We can use that operator to combine the variable update and the exit condition expressions of the for statement in a single expression:

int i=-1;
for (;i=i+1,i<5;) {
++++printf("%i ", i);
}

As a result, at each iteration the counter is incremented and discarded, then exit condition is evaluated and its result returned so the value of the comma expression is the value of the exit condition.

The equivalent while loop is:

int i=-1;
i = i + 1;
while(i < 5) {
++++printf("%i ", i);
++++i = i + 1;
}

In the following example the exit condition works as in the previous one. In addition, two variables are set in the variable initialization expression. And the update variable expression is used to append statements to the body of the loop:

int i, j;
for (i=-1,j=0;i=i+1,i<5;j=i+1,printf("%i\n", j)){
++++printf("%i\t", i);
}

It is equivalent to the following while loop:

int i = -1;
int j = 0;
i = i + 1;
while(i<5) {
++++printf("%i\t", i);
++++j = i + 1;
++++printf("%i\n", j);
++++i = i + 1;
}

Notice that the examples above are intentionally simple. They just pretend to show you how the combination for statement + comma operator works. In general, comma operator is used to produce side effects in the following situations:

  • calling a function
  • entering or repeating an iteration loop
  • testing a condition

You can see also:

Advertisements

Setup an Android development environment on Ubuntu

May 19, 2012 1 comment

Recently I’ve been involved in a project for developing an Android smartphone application. This is a new working field for me as I had never developed applications for mobile devices before. So it requires an important extra effort on my side (tons of things to learn). As I always do when I find myself turned into a newbie I’ve started to read documentation… and I’ve setup my development environment. For doing the setup I’ve followed the instructions found here. In theory it is an easy process. In practice it can be a little bit complicated so I decided to write this post. The setup described in this post has been tested on my Kubuntu Oneiric laptop.

First of all I’ve installed the openJDK implementation of the Java6 SDK:

$ sudo apt-get install openjdk

Other Java implementations have been discarded due to different reasons:

  • Java7 is not supported by Android
  • Java Oracle packages are not available on Ubuntu Oneiric official/partner repositories
  • the GNU Java compiler is not compatible with the Eclipse IDE so it is not an option if you plan to develop with Eclipse

The recommended IDE for developing Android applications is Eclipse because there is a plugin for integrating the Android SDK with it. The Ubuntu Eclipse package uses openJDK by default but it depends on the GNU Java compiler which, as I said, is not compatible with the Android SDK so I don’t now if it is a good idea to install Eclipse from the Ubuntu repos. Just in case I’ve downloaded Eclipse Classic (the version recommended by Android) from its website and installed it on the /opt/ folder. Installing Eclipse is trivial, just untar it and add the eclipse folder to your PATH.

Next I’ve installed the Android SDK Starter Package under /opt/. Again, the installation is trivial, just untar the package and add the android-sdk-yourplatform/tools and android-sdk-yourplatform/platform-tools folders to your PATH.

Once the Starter Package is installed one should execute the command

$ android &

which launches the Android SDK Manager, a tool included in the Starter Package. It is a graphical program, with a simple UI, that allows you to setup your SDK by downloading the essential packages for your development environment. In my case I’ve installed the following packages:

  • SDK Tools (latest version is required)
  • SDK Platform-tools (latest version is required)
  • SDK Platform (latest one is recommended)
  • Documentation for Android SDK

Additional packages that I’ve installed include the Google API, SDK Samples and the sources for Android SDK.

If you plan to publish your application, you will want to download additional SDK platforms corresponding to the Android platform versions on which you want the application to run.

Downloading those packages is sometimes a very slow process. If this problem hits you just cancel the installation and try again later (it is a simple workaround but it worked for me).

The last step is to install the Android Development Tool plugin for Eclipse. It must be done using the Update Manager feature of Eclipse as described here. The plugin configuration is very easy, just follow the wizard steps. At the end you will have an Android toolbar on your Eclipse main window. This new toolbar will contain buttons for launching the Android SDK Manager, managing Android Virtual Devices, etc.

Using this plugin is not mandatory but it seems to be highly recommended. If you don’t want to use it then you aren’t forced to use the Eclipse IDE.

That’s all. Now I’ve to see how it works and decide if I like it or I prefer to look for alternative environments. If you’re writing Android apps with a different development environment (for instance, not using Eclipse or not using an IDE at all) please, leave a comment.

Irssi and tmux (or screen)

March 24, 2012 10 comments

In my last post I described a basic setup for bitlbee and irssi. Now I’ll describe my current irssi configuration. The setup described here has been tested on my Kubuntu Oneiric laptop.

Irssi is highly configurable via Perl scripts. You can write your own scripts, use those included in your GNU/Linux distro or download them from the scripts section of the irssi website or from other places. I’ve used the last two methods.

Currently I’m using three scripts: adv_windowlist.pl (downloaded from here), nicklist.pl and hilightwin.pl (both of them from the irssi-scripts Kubuntu package).

The advanced window list script allows you to customise the channels status bar and the active windows list.

The nicklist script places all nicknames in a channel in a bar at the side of the window like many other IRC-channels. You can use it in two modes: fifo or screen.

With the hilightwin.pl script every time you get hilighted (someone types your nickname or any other higlighted word or sends you a private message) a copy of that message will be sent to a separate window.

In order to run the scripts automatically at irssi startup I’ve created the recommended ~/.irssi/scripts/autorun subtree. I’ve put adv_windowlist.pl under the scripts directory and created symbolic links to all the three scripts mentioned above under the autorun directory.

And now for the scripts configuration. Start irssi and from the status window run the following commands to setup the hilightwin.pl script so that it displays a window on the top of the terminal at all time. That way it will be difficult for you to miss important messages:

/run autorun/hilightwin.pl
/window new split
/window name hilight
/window size 6
/layout save

Next configure the adv_windowlist.pl script. The settings and explanations for them are atop the script, in the OPTIONS section. From the status window run the command:

/set awl_display_key $Q%K|%n$H$C$S
/set awl_block -15

where $Q is the meta-keymap key (ALT on my system), %K changes the color of the pipe character, %n changes the color of the window name, $H means start hilighting, $S means stop hilightning and $C is the name of the window. The second line defines the width of the status bar region dedicated to every window. Unfortunaltely the hilight part fails for me (maybe I’m misunderstanding something, suggestions are welcome 🙂

Next configure the nicklist.pl script. Here I’ll assume you’re running irssi in a tmux session. From the status window execute (comments have been added for clarity, obviously you don’t have to write them):

# split the terminal window in two panes
CTRL+b %
# resize the right pane to its minimum with
CTRL+b right_arrow_pressed until the desired width is get
# back to the pane where irsii is running
CTRL+b o
# Configure the nicklist script in FIFO mode
/nicklist fifo
# back to the right pane and get its size (rows, columns)
$ stty size
42 20
$ cat ~/.irssi/nicklistfifo
# back to the pane where irsii is running
/set nicklist_height 42
/set nicklist_width 20
/nicklist fifo

If you use screen instead of tmux the setup is easier, but it doesn’t work so smoothly:

/nicklist screen

Eventually save your configuration:

/save

Here you can see the whole thing in action:

PS: As an added bonus of running irssi inside a tmux session the nicklist script works even if you are not running a X session. It is fun to see it working in a Linux console 🙂

BitlBee and Irssi

February 26, 2012 3 comments

If you are a real geek and want to do your chatting (IRC or IM) on text mode instead of using a GUI then this entry is for you.

After searching the Internet and trying some nice applications for chatting using the command line (e.g. CenterIM) my choice is the pair BitlBee/Irssi. The setup described in this entry has been tested on my Kubuntu Oneiric laptop.

BitlBee is an IRC gateway program for MSN, ICQ, AIM, Jabber and Google Talk. It behaves as a IRC server, creates a IRC channel with all your contacts and allows you to talk to them as if they were normal IRC users. So it must be combined with a IRC client such as Irss  (other cool combination you can try is done with web browser IRC clients such as cgi-irc).

BitlBee can be used in two different ways, via its public servers or installing it on your computer. Using a public server does involve a security risk, where as running your own BitlBee server does not. So my advice is to install your own server locally and run it via xinetd as it seems the safer option.

I’ve installed the following packages:

  • xinetd
  • bitlbee
  • irssi
  • irssi-scripts

It is recommended to run bitlbee via xinetd but the bitlbee package doesn’t provide/create the right file under /etc/xinetd.d/ so we have to add it by hand. The filename is bitlbee and its contents are:

service ircd
{
socket_type = stream
protocol = tcp
wait = no
user = bitlbee
server = /usr/sbin/bitlbee
port = 6667
disable = no
bind = localhost # prevent non-local access by binding to the loopback device
}

At this point one should stop the bitlbee daemon if it is running and restart the xinetd:

# /etc/init.d/bitlbee stop
# /etc/init.d/xinetd restart

The next step is to configure the BitlBee server. You have to launch irss and connect it to the BitlBee server:

$ irssi
/connect localhost

This is done in the status window (which prompt is [(status)]). If everything goes fine the control channel window (which prompt is [&bitlbee]) will be created. Change to the control channel window with the command:

/window 2

or with ALT+2 (you can cycle between windows using ALT+left/right arrow). Then you register yourself in the server using a password:

register your_password

(note that this is not an IRC command but a BitlBee one so it is not prefixed with a slash). After registering all your IM settings (passwords, contacts, etc.) will be saved on the BitlBee server. Finally you add your IM accounts. For instance, if you want to add a Google Talk account enter the following command:

account add jabber example@gmail.com

Then you will be asked to use the /OPER command to enter the account password. Do it:

/OPER

At the prompt, enter your account password (it won’t be visible). That’s all, the account has been added.

Once you’ve created all your accounts you’ll need to activate them. The following command does it:

account on

Lastly, save the settings on your account and quit the program:

save
/quit

Now that the basic BitlBee setup is done let’s see how a typical session is run. On your favorite terminal launch the Irssi client:

$ irssi

A new Irssi session will be started and you will see the status window (with prompt [(status)]). Type the command:

/connect localhost

A message saying that the connection has been established should be displayed. Change to the bitlbee control channel pressing ALT+2 or typing the command:

/window 2

The prompt on this window is [&bitlbee]. Now identify yourself with the password used for registering in the BitlBee server:

identify your_password

Now you are recognized and logged on to all your IM accounts automatically. In the bitlbee control channel there are 2 users now, @your_nick and @root. You can see the list of IM accounts you’re connected to:

account list

Or you can see the list of all your contacts (buddies):

blist

You can chat with your buddies on the bitlbee control channel:

buddy_nick: Hi, how are you?

If you prefer to create a dedicated window for private chatting you can use the /msg or /query IRC commands:

/msg buddy_nick Hi, how are you?

Move to the just created window (which will have a [buddy_nick] prompt) and chat normally.
You can close this window with the /q command or with the /wc command (which is useful too for parting channels on disconnected networks).

Irssi can handle multiple IRC connections simultaneously, thus it is possible to be active in channels on different networks at the same time. So being connected to your Google Talk account you can move to the status window, connect to, let’s say, the Freenode network, switch to that network and join to the #ubuntu channel:

/connect irc.freenode.net
CTRL+X
/join #ubuntu

You can use Ctrl-X to switch between network connections and see which the active network is by looking at the status bar.

As expected, you can leave a given channel on a connected network using /part, disconnect from a network using /disconnect and quit your IRC session using /quit.

This has been just a brief introduction to BitlBee/Irssi but there are lots of things you can do yet: customise your Irssi instalation, enhance it via themes and scripts, run it in a screen session (this is really cool :-)…

Integrating keychain with KDE

November 29, 2010 2 comments

In the last post I introduced keychain and compare it with pam_ssh. I described some nice features of keychain, in particular how it can use long term running SSH/GPG agents. However the explained setup is not well integrated with KDE because of the environment problem described in that post. Although KMail can be configurated to sign sent messages with GPG keys, this feature doesn’t work with keychain out of the box. Let’s suppose that we want to sign our messages with the key 5E653DA8 -without entering the passphrase- and we want to use keychain for managing our GPG keys. In order to get our goal we configure properly the gpg.conf (ensuring that GPG will use the gpg-agent) file and add to our .bashrc file a block like

eval `keychain --nogui --noinherit --stop others id 5E653DA8`
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh-gpg" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh-gpg"
fi

We restart the X session just to be sure that keychain will add the key to the gpg-agent. Now we start KMail from the KMenu and try to send a signed message using the GPG support. The result is a dialog displaying the message “Signing failed: Bad passphrase”. The reason, as you can guess, is that the environment variables that keychain uses to expose the GPG agent are not known by KMail (in fact they are not available to KDE). This can be fixed in several ways. We can launch KMail via command line from a shell running keychain. But we prefer to launch it from the KMenu so we discard this workaround. Other possibility is to use the KmenuEdit tool and change the launch command from KMail to something like:

GPG_AGENT_INFO=/tmp/gpg-xJRtSl/S.gpg-agent:2249:1; kmail

(of course we get the GPG_AGENT_INFO value from ~./keychain/${HOSTNAME}-sh-gpg). But this doesn’t work if we use KMail as a component of Kontact. We can try to do the KMenuEdit trick with Kontact but then KMail will show us again the error message if we try to sign a message (it seems that Kontact doesn’t pass the environment to the KMail plugin).

The proper way to deal with this problem is to use the ~/.kde/env folder, of course. After all is a environment problem. So we put the following script in this folder:

#!/bin/sh
eval `keychain --nogui --noinherit --stop others`
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh-gpg" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh-gpg"
fi

This way the environment variables setup by keychain will be available to the KDE. Now we can start KMail in every possible way and we will be able to send signed messages without entering the passphrase (we may need to adjust the ttl of the passphrase to a value suitable for our needs. This change can be done in the gpg-agent.conf file).

Categories: GNU/Linux, Security Tags: , ,

Single sign-on: keychain vs pam_ssh

November 10, 2010 3 comments

As an unexpected consequence of the previous post about single sign-on in kdm via pam_ssh I met keychain. It is a nice tool for dealing with both SSH keys and GPG keys. Its main goal is to share a unique ssh-agent between logins. In this post I’ll describe briefly some nice features of keychain and will explain how it can be used for getting single sign-on. As usual, everything shown here has been done on a (testing) Debian box with KDE SC4.

Before starting I assume that your /etc/pam.d/kdm is not using pam_ssh, that OpenSSH is properly installed in your system and you have created a RSA key. In your ~/.bashrc file you have added the line

eval `keychain --nogui id_rsa`

If you restart your X session -so that current ssh-agent and gpg-agent will be killed and new agents will be created during the X session startup sequence- and open a konsole you’ll see something like:

Starting a shell with keychain

The already running agents are, by default, inherited by keychain. Then it uses ssh-add to add the SSH keys specified in the command line to the ssh-agent, and set up the shell environment so that ssh can find the running agent. Because this is the first time we login in this system, the ssh-agent doesn’t know the required SSH keys and we’ll be prompted for a passphrase. If the supplied passphrase is correct then the SSH key will be added to the ssh-agent. If we want to add more identities we can do it via ssh-add command.

Your ~./keychain directory is now populated with the files initialised during the keychain startup (see the above screenshot).

Let’s suppose you start a new konsole (or whatever terminal emulator you like). It doesn’t matter if it is a subshell of the current konsole or not. The .bashrc file will be sourced and keychain executed allowing you to reuse the running ssh-agent so the SSH key added in the first opened shell is available to this new shell too:

Opening a new shell in the X session.

Things get interesting when you want to use ssh in situations in which the environement needed by the ssh-agent (SSH_AUTH_SOCK and SSH_AGENT_PID variables) is not known by the shell. Normally you would need to start new agents. But keychain solves this problem in a clever way: the required environment is described in the files under .keychain and those files can be sourced, exposing the environment to the shell. Let’s see some examples.

You will face the environment problem if you want to run ssh commands in a non interactive shell, for instance in cron jobs. A simple working example of a cron job (assuming that your job is a bash-like script and the the job will be run by the user running the agent) follows:

#!/bin/sh
source /home/vmas/.keychain/rachael-sh
ssh vmas@a_remote_server "ls -l" >> ~/output.txt

As an alternative you can do:

#!/bin/sh
eval `keychain --noask --eval id_rsa` || exit 1
ssh vmas@a_remote_server "ls -l" >> ~/output.txt

Other example. If you connect remotely (for instance via ssh) to your X session you will see something like:

As you can see, the problem is fixed by sourcing the appropriate file.

As a last example, you can login in a virtual console (for instance tty3 via Alt+Ctrl+F3). You will be presented with the usual keychain stuff. However, no identities will be added to the ssh-agent due, one more time, to the environment problem. So the ssh-agent -l command will display the message:

Could not open a connection to your authentication agent.

This problem is fixed again by sourcing the .keychain/${HOSTNAME}-sh.

You can make things easier adding the next lines to your .bashrc, after the line calling keychain. They remove the need of explicitly sourcing files in interactive sessions:

if [ -f "${HOME}/.keychain/${HOSTNAME}-sh" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh"
fi

Last but not least, keychain can provide you with long term running agents (one of my favorites features). Until now we’ve launched keychain in a way that inherits the agents provided by the X session. It means that if we restart that session the agents will be killed and created again so keychain will use a new pair of agents every time an X session starts. We can force keychain to keep running the agents used the first time it was invoked. In order to do that we change our .bashrc replacing the old keychain invocation with this one:

eval `keychain --nogui --noinherit --stop others id_rsa`

meaning that keychain will not inherit the agents started by the X session (in fact they will be killed). Instead keychain will use its own agents.

In summary, we can say that using keychain we’ll have a unique, long term running, ssh-agent shared between user logins instead of a ssh-agent per login and we’ll be able to use SSH keys in non-interactive sessions too. All the examples above use SSH keys but keychain also supports GPG keys.

Even more, we can use keychain to get single sign-on and a unique ssh-agent shared between logins all at once. Simply add the following lines to your .bashrc:


eval `keychain --nogui --noinherit --stop others id_rsa`
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh"
fi

This is an interesting combination. Now the very first time that you login in a X session, you will have to authenticate twice: first with your regular password in order to start the session, and then with your passphrase (required by keychain). But from now on every time you restart your X session you will enjoy a nice single sign-on using just your regular password (something I’ve not been able to do with pam_ssh) plus the flexible management of SSH/GPG keys provided by keychain.

Categories: GNU/Linux, Security Tags: , , ,

Single sign-on with kdm for Debian via pam_ssh (III)

November 1, 2010 3 comments

In my previous post I thought I got pam_ssh and gpg-agent working together in a seamless way. As Sheldon Cooper would say, “In the world of emoticons, I was colon capital D”. But although all configurations included there worked for me like a charm, they didn’t work for Ivan. Indeed things worked for me better than I expected: when looking for the reasons of Ivan’s problems I realized that I could remove any reference to pam_ssh from my /etc/pam.d/kdm file, start a new X session using my regular password for login and still have my SSH keys added to the agent! Obviously it was all a mirage. I wasn’t aware that a ~/.gnupg/sshcontrol file containing references to all my SSH keys was living in my system. It seems that due to this file the SSH keys were automatically added to the agent every time I started a X session, because ssh-add -L always returned a list of keys, even when I removed every pam_ssh reference from /etc/pam.d/kdm.

When I removed the sshcontrol file the inconditional addition of SSH keys went away. So let me start again from the beginning. At the moment we forget about the gpg-agent. The following configurations work for me using the ssh-agent:

auth required pam_ssh.so
#@include common-auth

@include common-session
session optional pam_ssh.so

This config forces me to authenticate with my passphrase. The SSH keys are then added to the ssh-agent and I can use them during my X session without entering the passphrase. So far so good.

@include common-auth
auth optional pam_ssh.so use_first_pass

@include common-session
session optional pam_ssh.so

With this config I can login using my password. But my SSH keys are not added to the ssh-agent. However the README.Debian, in the paragraph talking about this configuration says:

“By thus adding ssh-auth after common-auth, ssh-auth can use the user’s
password to decrypt the user’s traditional SSH keys (identity, id_rsa,
or id_dsa)…”

So, if I understand it properly, pam_ssh should be able to add my SSH keys to the agent when I authenticate using my password. But it doesn’t (unless that the password equals to the passphrase, which doesn’t make sense for me) and I feel a little bit disappointed. The same happens with the next configuration:

auth sufficient pam_ssh.so try_first_pass
@include common-auth

@include common-session
session optional pam_ssh.so

With this config I can login using my passphrase or my password. If I use my passphrase then my SSH keys are added to the ssh-agent  but again if I use my password they are not.

And now let’s consider the replacement of ssh-agent with gpg-agent. I’ve setup my system as follows in order to use only the gpg-agent (detailed information can be found, for instance, here) :

– in /etc/X11/Xsession.options I’ve commented out the line use-ssh-agent
– in /etc/X11/Xsession.d/90gpg-agent I’ve added the --enable-ssh-support option to the
STARTUP line
– I’ve disabled ssh at the gnome-keyring:
$ gconftool-2 --set -t bool /apps/gnome-keyring/daemon-components/ssh false

However, all the above /etc/pam.d/kdm configurations fail with this setup. The “session optional pam_ssh.so” line always start a ssh-agent and SSH keys are never added to it. If I remove that line the ssh-agent is not run but SSH keys are not loaded into the gpg-agent so pam_ssh doesn’t appear to be compatible with gpg-agent. If any of you know how to make them work together, please, let me know. In the meantime I’ll have a look to alternatives to pam_ssh: keychain, libpam-gnome-keyring… As usual, suggestions are welcome 🙂

Categories: GNU/Linux, Security Tags: , ,