Tuesday, 6 November 2012

How to connect to a remote SSH server using public/private key cryptography?

Generally we use username and password to connect to a remote SSH server. Connecting using password is a cumbersome and less secure approach. Here are some of the drawbacks of connecting using password.

1) If you use more than one account then you need to remember password for all the accounts.
2) Changing password is an annoying task and you need to communicate password change to everyone who is using shared account.
3) Passwords are not as secure way of authentication as using keys. Each time you use password, it is passed over the network for authentication.

Now, let's see what is a key?. When we use keys to authenticate over the network, we actually use public/private key cryptography for authentication.

How does a public/private key cryptography work?

In this method, we generate two keys, a public key and a private key. Public key is known to everyone, we can also transfer it over the network. Private key is known only to us, we do not transmit it over the network, nor do we tell it to anyone. Private key is present only on your local machine and that also in a way, that only the authorized account/user can access it.

Now, when both the keys are generated, we install public key on remote machine and keep private key with us.

Following steps are followed when we try to authenticate to the server using keys.

1) Local machine requests the server for connection.
2) Server sends some data known as challenge, encrypted by public key, to the local machine.
3) Local machine/account uses its private key to decrypt the data and sends it back to the server.
4) If the server finds that both the data(sent and received) match then it allows the connection, otherwise it refuses the connection.

Let's see, how we can actually set key based authentication

1) Generate keys
Run the following program on shell

ssh-keygen
This will generate both, public as well as private key. When this program is run, it asks for the file name in which you want to save the keys and a passphrase for private key. I will discuss passphrase after sometime. For the time being, if you want, you can enter it, or leave it and press enter. Supposing, you gave file name for the keys to be my_secret_key then two files will be generated.
my_secret_key will have the private key.
my_secret_key.pub will have the public key.

2) After the keys are generated, you will have to install public key on the remote server. For this, secure copy public key from your local machine to remote machine.

scp /home/XYZ/my_secret_key.pub remote_user@host.com:/home/remote_user/

Now the public key is copied to the home directory of remote_user.

3) After this, log in to the remote host using ssh with the account for which you want to install the public key, in this case it is remote_user. This is the last time you will be logging using your password.

Make .ssh directory inside your home directory, only if it is not present. Assuming that you are in home directory.

mkdir ./.ssh (if not present)

Note: This directory is hidden, so use ls -a to check for its presence.

If .ssh directory is present then check for the file authorized_keys. If present, then append the content of my_secret_key.pub into it as

cat my_secret_key.pub >> /home/remote_user/.ssh/authorized_keys

or else, make the file.

Anyways, append will make the file if not present, so you need not make it explicitly. You only have to take care that you might not delete someone else's public key present for the same account.
Your public key is installed on the remote machine.

Come back to your local machine. Remember you entered a passphrase(if entered) while generating keys. This passphrase will be used to encrypt your private key. The private key will be stored in an encrypted form, if passphrase is used, on the local machine. So, even in the case your encrypted private key becomes vulnerable, nobody will be able to decrypt it and use it to decrypt challenge(which the server sends), unless they know the passphrase. Now you get the importance of passphrase.

Everything set, you can try connecting to remote SSH server using keys.

ssh -i my_secret_key remote_user@host.com

It will ask for your passphrase(if set).

After you enter the passphrase, you are connected to the server.

The best part of connecting by this approach is that your password is not passed over the network, not even your passphrase.

If you don't want to enter your passphrase again and again, you can set up your passphrase in an agent. An agent is a program which remembers the passphrase for you, and whenever you try to use SSH client to connect to the host, it enters the passphrase on your behalf.

For more info visit

Monday, 29 October 2012

How to use FTP in a shell script?

FTP is a standard protocol for file transfer. With FTP, files can be transferred to and from a remote host. Remote host has a FTP server installed on it which listens to FTP clients. FTP client is the program which communicates with FTP server.
Suppose that a user has an account on FTP server with username name and password pass.
Now, let's write a script to transfer a file from a remote host to local machine.

#! /bin/sh 
ftp -in host/ip<<END 
user name pass 
cd /var/myremotedir 
lcd /var/mylocaldir 
get file 
close 
bye 
END 
echo 'transfer completed' 

 In the above script, we are transferring file from remote directory /var/myremotedir to local directory /var/mylocaldir. cd is used to change directory at remote server. lcd is used to change directory at local machine. get is used to transfer file from remote directory to local directory. Similarly, we can use put to transfer file from local directory to remote directory. Note: Here cd, lcd, get are ftp commands and not unix commands. FTP server should be installed and listening on remote machine for FTP client to communicate. The username and password used by FTP client should be registered with FTP server.

For more info visit

Sunday, 21 October 2012

Use NSUserDefaults to store default values or user settings for an application...

NSUserDefaults is the class which is used to store default values for an application. It stores the values inside the application's sandbox. The values which can be stored are either scalar or which can be serialized into a property list.
NSUserDefaults is a singleton, means it can have only one instance for an application. You don't have to worry about the storage location, updating data or deallocating the object once its use is over. This all is being handled by NSUserDefaults. Infact, NSUserDefaults also caches the information in the memory so that disk read/write is reduced.
NSUserDefaults periodically keeps on synchronizing the values stored in memory with the values stored in disk. It also provides the synchronize method, which can be used to synchronize the values explicitly. It stores objects using key-value pair.
Now, let's see how to use this class for storing defaults.
Get the singleton object  
NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults];
  Store/read values
There are some setters and getters methods to store and retrieve values.
[userdefaults setDouble:2.41 forKey:@"doublevalue"]; 
[userdefaults doubleForKey:@"doublevalue"]; 
  Similar type of methods are there for float and integer as well.
 To set an object for a key we can use
NSArray userarray = [[NSArray alloc] init..........];
 [userdefaults setObject:userarray forKey:@"arr"]; 
[userdefaults objectForKey:@"arr"];
  In the above code, we have set an array object.
NSUserDefaults also provides the facility for storing default values in userdefaults. We can store default values for usedefaults until user sets the values. This can be done by using registerDefaults method of NSUserDefaults. This method takes an NSDictionary objects as its parameter.
NSMutableDictionary *defval = [NSMutableDictionary dictionary]; 
[defs setObject:@”Beginner” forKey:@”Level”];
 [[NSUserDefaults standardUserDefaults] registerDefaults:defval];

For more info visit

Sunday, 7 October 2012

How to use NSOperation and NSOperationQueue for multithreading?

Multithreading is an important aspect of iOS applications. We cannot always load our main thread with all the tasks. If an application is designed to perform all the tasks serially then there is no need of multithreading, but most of the applications have some tasks which can be completed without depending on other tasks, or if main thread has to be left available for user interaction. In these cases, it's a compulsion to go for multithreading.
You can always go with NSThread to multithread your application, but doing so is only recommended when your requirements are such that there is no other option, except to use NSThread. Sometimes using NSThread may not be as efficient as using NSOperation, as NSOperation takes into account the current system load and cores available to decide the extent to which application can be multithreaded.
If you use NSOperation, you don't have to take care of spawning a new thread or terminating it after your work is complete. You also don't have to worry about the number of threads to use to make application work more efficiently. It's not like, using more threads makes your application more efficient. Remember, a thread always has a cost associated with it, as it shares stack space with the main process.
In simple terms, any instance of subclass of NSOperation class will denote the operation which we have to perform in mutithreaded manner with respect to other operations denoted by other instances of subclass of NSOperation or the operation performed by main thread itself.
Why have I used term, subclass of NSOperation class?
NSOperation is an abstract class, so you cannot instantiate it directly. You will have to subclass it if you have to use it. But don't worry, Foundation framework provides NSInvocationOperation subclass which can be used directly for instantiating operations.
NSInvocationOperation provides almost everything to perform multithreading, but in case if you feel that it is unable to cater your needs, you can always subclass NSOperation.
NSOperationQueue class can be instantiated directly to create a queue where we can add our operations. Once you add operations to NSOperationQueue, it will take care of when and how to execute your operations, and how many threads to use for execution. NSOperationQueue starts executing operations almost as soon as they are added to the queue, provided they do not have dependency on some other operations in the same or some other queue, or your queue is not overloaded.
Now, let's see how to use NSOperation and NSOperationQueue.
Note: I won't be dealing with creating custom subclass of NSOperation in this post.
Create an operation
@implementation testViewController
 - (void)viewDidLoad { 
aQueue = [[NSOperationQueue alloc] init]; 
[super viewDidLoad]; 
}
 -(void)fun1:(NSObject *)obj { 
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(fun2:) object:obj];
[theOp addObserver:self forKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL]; [aQueue addOperation:theOp]; 
[theOp release]; 
}  
-(void)fun2:(NSObject *) obj { 
// Start your parallel task 
}
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
if ([keyPath isEqual:@"isFinished"]) { 
// Do something, operation has finished. 

@end

fun2 is the entry point for the new task/thread. NSOperation is KVO (Key Value Observing) compliant class, so you can register your objects for receiving notifications. In the above code, I have registered the current object for receiving notification when an operation finishes.
Note: Don't try to change your operation object once it has been submitted to the queue, because after submitting you never know when queue starts executing it.
For more info visit

Tuesday, 2 October 2012

CRON not sending mails!!!

A while back I faced an issue in which a script set up on cron was not sending mails, and the strange thing was that, when I was running the script from the shell, it was sending mails.
So, it was confirmed that there is no issue with the code or mail command in the script. What was the issue then?
After searching on google, I found out that cron doesn't have all the permissions and privileges which the user has. In my case, though the script in cron was set up by the user who has the privilege to run the mail command, but it wasn't running with the privileges of the user.
Some values were missing from the PATH environment variables due to which the shell was unable to recognize the command name.
How to deal with this problem?
There are many ways to deal with problems like this
1) Execute the profile of the user which has PATH variable set as required.
2) Write command name with full path.
3) Set up PATH environment variable in the script to include the Path of the command.

For more info visit

Sunday, 16 September 2012

How to mount a Pen Drive manually in Linux?

Most of you must be thinking that why do we need to mount a pen drive or any other external Hard Drive manually. Why cant' we just plug in the drive and let Linux do things for us, i.e. formatting (creating a file system on drive) and then mounting it inside the root file system.
The answer is, we can always let Linux automatically mount the drive for us. Infact, in my version of Linux, as soon as I plug in the drive, it is mounted at /media/Pendrive, supposing that my pendrive name is Pendrive.
But sometimes, we do not want automatic mounting. Infact, we want to mount our external hard drive or pendrive at a specified location for things to work. This is the scenario where we need manual mounting of a drive.
Let's see how to mount a drive manually.
If your drive is mounted automatically on plugging in then dismount the drive from the location on which it is mounted by using the command.
umount /media/Pendrive # supposing pendrive is mounted on /media/Pendrive
umount /dev/sdb1 # supposing the name Linux gave to my device is sdb1
You can also give the device name for dismounting if you know, or you can check it by using the command dmesg
Look for an SCSI device with storage capacity as that of your drive ( name would be like sda1,sda2...., sdb1,sdb2...)
Make the directory where you want to mount the drive. Let's say I want to mount the drive at /Folder
Mount the drive using the following command
mount -t ext2 /dev/sdb1 /Folder
Now the drive is mounted at /Folder. Here, ext2 denotes the file system for the drive.
Again, if you want that that your drive should be automatically mounted at the specified location when the system boots up and should be dismounted when the system shuts down, add the following line in /etc/fstab.
/dev/sdb1 /Folder ext2 defaults 0 0
The file systems in /etc/fstab are automatically mounted during system start up and dismounted during system shutdown.
You can always mount all the file systems in fstab using mount -a

For more info visit

Sunday, 9 September 2012

{ } and ( ), two different ways of grouping commands in shell script.

There are two different ways of grouping commands in unix shell script.
i) ( ) : When we group commands inside ( ), the commands are executed in the subshell, instead of current shell.
ii) { } : When we group commands inside { }, the commands are executed in the current shell.
Let's understand it with the help of an example. In this example, we will try to change the working directory of a shell and verify whether it has been changed or not.
Open shell and type the following command. Assuming that shell's pwd before executing the below command is /
$ { cd /etc/mail ; pwd ; }
The output will be
/etc/mail
This cd command was run on the current shell. If you want to verify, execute pwd again and you will see the same output
$ pwd
/etc/mail
Now, we will execute the same set of commands using ( ). Again assuming that pwd is /etc/mail
$ ( cd .. ; pwd )
The output will be
/etc
This cd command was run on the subshell. If you want to verify, execute pwd and you will see the output
$ pwd
/etc/mail
We can see that pwd of the current shell has not changed.
Note: Always use ; before } if { and } appears on the same line. This is not needed in case of ( ).
For more info visit