tag:blogger.com,1999:blog-3753152555672759302024-03-16T06:39:53.659+05:30I Think TechOdyssey of a an aspiring BrahmanaBrahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.comBlogger125125tag:blogger.com,1999:blog-375315255567275930.post-20361404201019568792017-07-17T08:56:00.001+05:302017-07-17T10:56:59.613+05:30$PATH for the pathless<div dir="ltr" style="text-align: left;" trbidi="on">
With the rise in popularity of scripting languages and their adoption in the industry a lot of first time professional programmers (a.k.a fresh graduates) are being exposed to the Linux command line environment and some times Linux as a system itself might be new to them. So they tend to have difficulty in understanding how a program is actually being executed and/or what all is needed to make a program run. This coupled with the magic spewed around by certain tools like <i><b>rvm</b><b> / chruby</b></i> for Ruby and <i><b>nvm</b></i> for Node.js (and their ilk) are just adding to the confusion of how things are executed in the first place. I am not at all saying that such tools are bad. I myself use them and they are very helpful. But if a person is using them without getting the basics right, he/she is going to have a mighty problem wrapping their head around how things are running..!<br />
<br />
In this context, I have been explaining what the <b>$PATH</b> means and what is its purpose a few times of late. So instead of repeating myself every time I thought I would just document what I know about $PATH to help the pathless get on the right PATH (or the <i>PATH OF RIGHTEOUSNESS</i> if you will).<br />
<br />
<u><b>GEEK NOTE</b></u> : This post is aimed at absolute newbies, folks who just got started with something like Ubuntu and are fiddling around with some of the cool new technologies like Node.js / Ruby / <insert day="" fad="" of="" the="">. So this post will not go into the depths nor will it try to be GEEK ACCURATE, i.e. it will not deal with things like POSIX compliance or the behaviour on non-Linux systems, etc. For that matter this will to a large extent be specific to Ubuntu and most likely Bash. We will also not try to distinguish between login and non-login interactive shells. As the screenshots shown below indicate, the assumed environment is running the "Terminal" application in Ubuntu.</insert><br />
<br />
So, lets start with the basics and a few assumptions.<br />
<br />
<u><b>Assumptions :</b></u><br />
<br />
1. We are primarily interested in understanding how programs are run in the Linux command line environment.<br />
2. We will restrict ourselves to the "Terminal" program of the Ubuntu system as the environment. However all / most of the following might be applicable to all such similar programs on different flavours of Linux.<br />
<br />
<u><b>Basics :</b></u><br />
<br />
Whenever you launch the "Terminal" program what you are doing is actually launching a "Shell". Like with any type of software in the Linux world, choices are abundant and there are a lot of shell programs. However the "Terminal" program in Ubuntu (as of this writing) uses the "Bash" shell and that is what we will stick to. So on launching "Terminal" you are effectively launching the bash shell.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiInL57iNYW7mrdVEzyHVGqkPH8oo8xJAw2Vc355rDoIrhttUV7T6M9UCp6ohKkbIRP2le5tW2RyGcB6jVubvVq32aZW43KDvsecbtl6kjY6qCxfbiGTKyBcjZrzNkUZ6x17CMD-liJxSE/s1600/ubuntu-terminal-bash.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="439" data-original-width="735" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiInL57iNYW7mrdVEzyHVGqkPH8oo8xJAw2Vc355rDoIrhttUV7T6M9UCp6ohKkbIRP2le5tW2RyGcB6jVubvVq32aZW43KDvsecbtl6kjY6qCxfbiGTKyBcjZrzNkUZ6x17CMD-liJxSE/s400/ubuntu-terminal-bash.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The "Terminal" application in Ubuntu 16.04</td></tr>
</tbody></table>
<br />
<br />
<u><b>What is a Shell?</b></u><br />
<br />
In the simplest terms, a Shell is a program which helps you run several other programs. It is like this eternal waiter who just waits for you to tell him what program to run and when you give him a program to run, it just runs it, tells you what was the result of running that program and goes back to waiting. Broadly speaking this is all that the shell does : Wait - Run a program - Show results - Wait. Wash-Rinse-Repeat.<br />
<br />
If you have used the Linux command line (a.k.a the shell), you might be thinking that the shell certainly does a lot more than this. You might say "I run so many commands on the shell and it allows me to do a variety of things like search of files, list the directories, check the date etc etc. What about all those functionalities??!". Well, almost all of those actions are nothing but the shell running some program or the other. Almost every "command" that you have run are independent programs provided with the Linux system by default. Whenever you "run a command", you are just telling the shell to search for that program on the system and run it. The standard commands that most Linux users are familiar with are stored in certain predefined standard directories / locations. On Ubuntu those locations are "<span style="font-family: "courier new" , "courier" , monospace;">/bin</span>" or "<span style="font-family: "courier new" , "courier" , monospace;">/usr/bin</span>". While "<span style="font-family: "courier new" , "courier" , monospace;">/bin</span>" has the core system commands, "<span style="font-family: "courier new" , "courier" , monospace;">/usr/bin</span>" has the commands added by other softwares that are installed on the system.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_lca6VJkgdYfax0CgLFjeSkbXP0qs5VmhfjOwOP_eB099hWUObWfDfNCpQxr8xC76dkULdjiwylPo6MdqNpCB7T_scGsq4hKMUxIi6UOxJ0X1qtxgPIEvXPBfpxmHOCFZA43Fnc8fdTY/s1600/ubuntu-ls-bin.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="374" data-original-width="1176" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_lca6VJkgdYfax0CgLFjeSkbXP0qs5VmhfjOwOP_eB099hWUObWfDfNCpQxr8xC76dkULdjiwylPo6MdqNpCB7T_scGsq4hKMUxIi6UOxJ0X1qtxgPIEvXPBfpxmHOCFZA43Fnc8fdTY/s640/ubuntu-ls-bin.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A listing of the /bin directory showing system program executable files. Notice the programs corresponding to the most commonly used commands like "<span style="font-family: "courier new" , "courier" , monospace;">cp</span>", "<span style="font-family: "courier new" , "courier" , monospace;">ls</span>", "<span style="font-family: "courier new" , "courier" , monospace;">mkdir</span>" etc</td></tr>
</tbody></table>
While these are what could be called as "standard system programs", the shell is not limited to these. The shell can run just about any program (technically, any executable file) on the system. All you have to do specify the full path to the location of that file on the command line and the shell will execute it, reporting the result of that execution. So if you have a file in a deep directory structure as shown below :<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXJApREErA1Z8VAs7sSNSyT-HdqT5NlbYb0PxjTJVYsikakz1bA-u_Zn8BgHpIljBqsGxaNbKZKfnXdf3kz6jZgLTfxQXMvndk54jbBiL3Poef-bKpnbbFeaPovW9sxiZD3ObIfVCDej4/s1600/my_program-deep-in-directories.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="284" data-original-width="919" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXJApREErA1Z8VAs7sSNSyT-HdqT5NlbYb0PxjTJVYsikakz1bA-u_Zn8BgHpIljBqsGxaNbKZKfnXdf3kz6jZgLTfxQXMvndk54jbBiL3Poef-bKpnbbFeaPovW9sxiZD3ObIfVCDej4/s640/my_program-deep-in-directories.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The full path to "my_program" will be <span style="font-family: "courier new" , "courier" , monospace;">/home/srirang/work/path_learning/custom_programs/my_program</span></td></tr>
</tbody></table>
When you have such a setup, to run the file "my_program" you just have to type the full path to it and hit enter. Shell will take the file at that location and run it.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">/home/srirang/work/path_learning/custom_programs/my_program </span><span style="font-size: large;">↵</span></blockquote>
There might be two questions now in your head :<br />
<br />
1. For the standard commands I never specified the full path. I just specified the program name and shell ran it without any issues. How did that happen?<br />
2. If I have to specify the full path for each and every time, it seems a mighty tedious way, especially for programs that I run very often. Is there no easier way?<br />
<br />
The answer for both of the these is the "<b>PATH</b>" environment variable.<br />
<br />
You need not specify the full path to the executable program all the time. When you specify only the program name, shell has a mechanism to search for that program on the system and run it. Searching for a program in the entire system every time is massively inefficient. So the shell has a mechanism for us to tell the specific locations where the shell should search for a program whenever we do not specify the full path. The way to specify this is by putting all these locations in an environment variable called the "<b>PATH</b>".<br />
<br />
Whenever a program name is specified with the full path, shell will take the directory locations specified in the "PATH" environment variable one by one and search for the program in each of those locations sequentially. So if you have one or more custom programs that you would be running frequently, then it is best to add the directory locations of those programs to the <b>PATH</b> variable.<br />
<br />
<u><b>Environment variables : Brief introduction :</b></u><br />
<br />
As mentioned earlier PATH is an environment variable. This post will not go into the details of what environment variables are. For the sake of this discussion here are a few points to remember : <br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<ol style="text-align: left;">
<li>Environment variables are like the settings for the shell. The values of the environment variables are used by the shell to decide how it should act.</li>
<li>By convention all environment variables are specified using upper case alphabets, numbers and underscore.</li>
<li>You can have as many variables as you want, although the shell will use only the ones it has specified.</li>
<li>You can set the value of a environment variable like this :<br /><br />VARIABLE_NAME=value<br /><br /><u>Examples:</u><br />MY_VAR=1<br />RUBY_VERSION=2.0.0<br />LANG=en_IN</li>
<li>Very often to make sure that the value of the environment variable is persisted across multiple programs (and not limit it to a single program or command), the "export" keyword is used while setting the value of the variable. Examples : <br /><br /> export MY_VAR=1<br />export RUBY_VERSION=2.0.0<br />export LANG=en_IN</li>
<li>You can read the value of a variable by prepending the $ symbol before the variable name like this :<br /><br />$VARIABLE_NAME</li>
<li>The value of a variable can be used to set the value of another variable by using the same $ symbol. Example :<br /><br />RUBY_DIRECTORY=/usr/lib/$RUBY_VERSION/</li>
<li>If you want to see the value of an environment variable use the "echo" command. See the image below :</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0TN805yJh-b5NxojG9ma6tb1D8qJmuojXlD0B6zgZ1YXdosmrvRc4PTspo6PqN_zPIFKOzk9NvwHtLo_xoRHQGhm4aIZ5dQCVFR5CByehw79ObdlkBVV_TqxQlcqrjX70S33h6-UKND4/s1600/echo-env-var.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="138" data-original-width="363" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0TN805yJh-b5NxojG9ma6tb1D8qJmuojXlD0B6zgZ1YXdosmrvRc4PTspo6PqN_zPIFKOzk9NvwHtLo_xoRHQGhm4aIZ5dQCVFR5CByehw79ObdlkBVV_TqxQlcqrjX70S33h6-UKND4/s400/echo-env-var.png" width="400" /></a></div>
<br />
<u><b>Managing the PATH variable :</b></u><br />
<br />
Here are a few characteristics of the <b>PATH</b> variable : <br />
<ol style="text-align: left;">
<li>The value of the <b>PATH</b> variable is a string.</li>
<li>There can (and will) be multiple directory locations mentioned in the <b>PATH</b> variable.</li>
<li>The individual directory locations are separated by the <b>:</b> (colon) character.</li>
<li>Most common default PATH value is typically this : <br /><br /><span style="font-family: "courier new" , "courier" , monospace;">/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin</span></li>
<li>To see the current value of PATH use <span style="font-family: "courier new" , "courier" , monospace;">echo $PATH</span>. See the image below.</li>
<li>The most common way of adding a new directory location to the PATH is this : <br /><br /><span style="font-family: "courier new" , "courier" , monospace;">export PATH=$PATH:/the/new/directory/location</span></li>
</ol>
Once you add a directory location to the PATH like this any executable program in that directory can be run on the command line directly by specifying just the program name.<br />
<br />
In my system, I have installed Ruby to a particular directory and I want the ruby program to be available on the command line. So this is how my <b>PATH</b> variable looks :<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8F9v_5ybGJQVYoObGPPKBnGuBLQe_cA7TsCn96sC2TNoahOttOg1toqhhvALFRRBHkHHcZ2LQeelGwIWcXtIi-SS3OTdwqHrHo3RWwXp9G6sBrsmoRfo3FYPDzPIpZUyq53KXATVtbkQ/s1600/echo-path.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="284" data-original-width="736" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8F9v_5ybGJQVYoObGPPKBnGuBLQe_cA7TsCn96sC2TNoahOttOg1toqhhvALFRRBHkHHcZ2LQeelGwIWcXtIi-SS3OTdwqHrHo3RWwXp9G6sBrsmoRfo3FYPDzPIpZUyq53KXATVtbkQ/s640/echo-path.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Contents of the PATH variable on my Ubuntu system.</td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<u><b>Few Gotchas :</b></u><br />
<br />
<ol style="text-align: left;">
<li>Environment variables are local to each shell. So if you are running two terminal windows or tabs, the shells running in them will have their own set of environment variables. The value that you set in one shell is not available in the other shells.</li>
<li>The value stored in the environment variables is available until the shell process quits. The values are not persisted beyond the lifetime of the shell. Nothing like saving the environment variables to the hard disk.</li>
</ol>
This would imply that any PATH settings that you would need will have to be done every time you open up a new Terminal window or tab (a.k.a every time you launch a shell). That sounds awfully painful and tedious. Sure it is. But Linux has a solution for you.<br />
<br />
Like many Linux programs, the Bash shell (and almost every other shell too) support a startup configuration file. This file is in your home directory with the name <i><b>.bashrc</b></i> (yes, the name starts with a dot). This file can contain any number of commands that you would run on the command line and all of those will be "executed" every time a Bash shell is launched (a.k.a every time you open a new Terminal window or tab).<br />
<br />
The common practice is to put all the commands setting the values of the necessary variables into this <i><b>.bashrc</b></i> file. That way you are guaranteed that every time you open a new Terminal window or tab, all of these environment variables will be set to the appropriate values. This is why magic tools like "<i><b>rvm</b></i>" or "<i><b>chruby</b></i>" or "<i><b>nvm</b></i>" ask you to add some stuff to your <i><b>.bashrc</b></i> file.<br />
<br />
This should give you an initial understanding of what the <b>PATH</b> variable is for and what someone means when they say "<i>PATH is not setup properly</i>" or "<i>PATH needs to be setup</i>". From this point on, you should be able to google around for additional information and make sense out of it. If something mentioned here is not clear, drop in your questions in the comments and I will try my best to respond with answers.<br />
<br /></div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com3tag:blogger.com,1999:blog-375315255567275930.post-13820354356486880922015-06-27T04:38:00.000+05:302015-06-27T04:38:42.068+05:30PAUS, Mideval history, pre-islamic middle east, religion - A saga of Wikipedia addiction<div dir="ltr" style="text-align: left;" trbidi="on">
I came across the word "PAUS" today in an email and I did not know what it meant. The email did not have much context either. As usual I googled for "define: PAUS" and the smart boy Google showed me the Wikipedia link for some Norwegian patrician family from Oslo named <a href="https://en.wikipedia.org/wiki/Paus" target="_blank">PAUS</a>. I was very sure that the "PAUS" word I had come across had nothing to do with a medieval family from Oslo. Nevertheless being a big Wikipedia addict, I bravely caressed my laptop touchpad, moved the mouse pointer to the Wikipedia link and clicked on it.. ! And the Saga begins.. !<br />
<br />
The Paus family has some semi-interesting history, not very intriguing or aything, but still there is something to read. The one piece of information that got my attention, apart from the awesome estates they own, is one of their coat of arms : They call it "<a href="https://en.wikipedia.org/wiki/Paus#Seals_and_coats_of_arms" target="_blank">Crane in its vigilance</a>". Intrigued by the "vigilance" word I click on that link to see if I will get to read some nice history or myth about some super vigilant crane. I was wondering if it had anything to do with this Crane :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFzY9CrPF0BxynW5ktE2fgWM0NUxs5hY0WO-sCOC_olL4-bI-xNxImmv-QRStRASqSHQ4hLlW5rsZSjQ-9SaKBf39BHW13lVyCzSz3LYmlwHhnc1bjcQgjJWhZGBgo_NVrPIMrMIwCkMA/s1600/crane.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFzY9CrPF0BxynW5ktE2fgWM0NUxs5hY0WO-sCOC_olL4-bI-xNxImmv-QRStRASqSHQ4hLlW5rsZSjQ-9SaKBf39BHW13lVyCzSz3LYmlwHhnc1bjcQgjJWhZGBgo_NVrPIMrMIwCkMA/s320/crane.jpg" width="320" /></a></div>
<br />
The link took me to <a href="https://en.wikipedia.org/wiki/Crane_%28bird%29" target="_blank">this page</a>...!!! It was such a "Duh" movement..! :(<br />
<br />
But Wikipedia being Wikipedia, never ceases to amaze me. After glancing over the page reading a little here and there about the bird I came across this section about <a href="https://en.wikipedia.org/wiki/Crane_%28bird%29#In_mythology_and_symbolism" target="_blank">Cranes in Mythology and Symbolism</a>. Here I found that in pre-islamic Arabia the three chief goddesses were referred to as the "the three exalted cranes". Being a religion history buff I immediately opened the three Wikipedia pages to <a href="https://en.wikipedia.org/wiki/Al-l%C4%81t" target="_blank">the</a> <a href="https://en.wikipedia.org/wiki/Uzza" target="_blank">three</a> <a href="https://en.wikipedia.org/wiki/Manah" target="_blank">goddesses</a>. I did not read all of it but merely glanced over. I found this very interesting modern depiction of the three goddesses.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/2/27/3-Ghar%C4%81niq.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="271" src="https://upload.wikimedia.org/wikipedia/commons/2/27/3-Ghar%C4%81niq.png" width="320" /></a></div>
Source : <a href="https://en.wikipedia.org/wiki/Man%C4%81t" target="_blank">Wikipedia</a><br />
<br />
What immediately caught my attention was that the temples of all three goddesses were raided and idols destroyed when Muhammad and his army seized Mecca at the very beginning of the Islamic period. It was also mentioned that a lot about these idols is written in the "<a href="https://en.wikipedia.org/wiki/Book_of_Idols" target="_blank">Book of Idols</a>". Apparently this book was instrumental in molding the Islamic belief that idol worship is sin. Anyways, religious beliefs apart, the page on this book mentioned about the "founding of Kabba" and I did not know that. As you would have guessed, next I started reading about <a href="https://en.wikipedia.org/wiki/Kaaba" target="_blank">Kabba</a>.<br />
<br />
Contrary to what I though Kabba existed much before Muhammad. There were apparently 360 idols before Muhammad seized Mecca and destroyed them. Amongst several other things, one very interesting incident from history caught my attention. It was the <a href="https://en.wikipedia.org/wiki/Kaaba#After_Muhammad" target="_blank">attack on Kabba and the stealth of the black stone</a> by a sect of people called Qarmatians. After this the ruling caliph had to get the stone back by paying a ransom. One can imagine how much of a tremor this would have created in the Muslim world back then. Now I had to know who these Qarmatians were and why they attacked Kabba. Turns out that <a href="https://en.wikipedia.org/wiki/Qarmatians" target="_blank">Qarmatians</a> are a sect of Shia Muslims itself. Their history is pretty interesting. Apparently the basis of forming this sect was their belief that one of their imam was the Mahdi. Who or what is a Mahdi you ask? Exactly the question that came to my mind and I opened the page on <a href="https://en.wikipedia.org/wiki/Mahdi" target="_blank">Mahdi</a>.<br />
<br />
So Mahdi is this prophesied redeemer of Islam who would come back to earth, sent by god himself, and who would cleanse the world and uphold Islam. Pretty standard fare. Almost every religion has such prophecy I believe. Well so far 4 prominent people have claimed to be the Mahdi (very surely amongst several other not-so-prominent ones). Guess what? Out of the 4, 2 have been from India.. !! 50% share man... wohooo..! We really are a country of god-men, religion no bar.. ! :)<br />
<br />
One of the two men was "<a href="https://en.wikipedia.org/wiki/Mirza_Ghulam_Ahmad" target="_blank">Mirza Ghulam Ahmad</a>" founder of the <a href="https://en.wikipedia.org/wiki/Ahmadiyya" target="_blank">Ahmadiyya</a> movement in India. This one instantly rang a bell in my head. I had heard and read a little about the Ahmadiyya sect. I immediately started reading about this person. His life history was somewhat interesting not very much though. He had some pretty radical thoughts about interpretation of Islam and Jihad. Like any other god-man he had debates with several religious people, wrote a bunch of books. Apart from that the Wikipedia page on him did not offer anything interesting enough to click and go to a new page.<br />
<br />
And at that point this particular Wikipedia journey came to and end.<br />
<br />
However, after all this I still did not know what the "PAUS" in the email meant. Surely my work has nothing to do with a medieval Norwegian family.. ! So I went back to the email to try and get more context. Digging through some of the older emails from the same person I finally found what he was referring to.<br />
<br />
<b>Here comes the grand ending : ;-)</b><br />
<br />
After all this it was revealed to me (probably by divine grace) that, the sender of the email was referring to nothing but this :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPOunYhAYWPPUY2mz3zinDuSPXu4aScx3ZKmuqx_2Y1pALVJvQbAzbA23-J5LAAN-TNw29lELoH2yRZoVCMgXdiQODMJJh9JL8pL5fIRNtLLvsKWjt40yKLF1CAY9ua5rR7sSGd0xk6Yo/s1600/Pav.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPOunYhAYWPPUY2mz3zinDuSPXu4aScx3ZKmuqx_2Y1pALVJvQbAzbA23-J5LAAN-TNw29lELoH2yRZoVCMgXdiQODMJJh9JL8pL5fIRNtLLvsKWjt40yKLF1CAY9ua5rR7sSGd0xk6Yo/s1600/Pav.jpg" /></a></div>
<br />
YES.. !! He was referring to PAVS (P - A - V - S).. Pavs as in Vada Pav, Misal Pav, Samosa Pav, Pav Bhaji, etc etc.. !<br />
<br />
He had misspelled it. He had put in a "U" in place of "V" and that made me wade through Wikipedia for about 45 minutes and then another 30 minutes writing this blog post.. !!<br />
<br />
All hail the PAU.. !<br />
<br />
There you go. That's the root of this entire saga. In honor of this epic saga, I am going to eat Pav... oh sorry PAU BHAJI today. <br />
<br />
Happy PAUing to you too...! :-) </div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com2tag:blogger.com,1999:blog-375315255567275930.post-29421639617175888082015-03-30T19:09:00.000+05:302015-03-30T19:09:29.790+05:30Layman's analysis of an ULIP : Bajaj Allianz Future Gain<div dir="ltr" style="text-align: left;" trbidi="on">
Recently a friend of mine asked me whether he should choose to invest in a Mutual Fund or this ULIP named Bajaj Allianz Future Gain. The ULIP salesman have apparently been pestering him a lot to invest in that scheme while I had strongly suggested him to not go with any ULIP at all. In my books ULIPs have a blanket ban. My friend Prabhakar Kudva and Dhirendra Kumar of <a href="http://valueresearchonline.com/">valueresearchonline.com</a> have given me enough information to realize that combining investment and insurance is not a good idea and ULIPs in India are definitely very bad investment options for almost all.<br />
<br />
valueresearchonline.com had been a regular critic of ULIPs back in 2000s when ULIPs had a free run without any check. In those days ULIPs charged insane charges like 25% to 30% and have literally scammed investors. After a lot of noise was made about this, IRDA finally woke up and put in some nominal rules to regulate this kind of practice. It however left a huge holes in the policy for these insurance companies to exploit. Insurance companies are not so closely watched as the Mutual Fund companies are watched by SEBI and transparency requirements are also lower for insurance companies. As a result ULIPs become very risky options for investors because of the exploitation possibility.<br />
<br />
Anyways that was the history. Despite all this gyaan, my friend however wanted me to take a specific look at this particular ULIP - Bajaj Allianz Future Gain.<br />
<br />
So I tried to do a quantitative analysis of the same to demonstrate how bad an investment option it is.<br />
<br />
NOTE : Professionally I am an engineer and finance is just a hobby for me. So calculations below are as per my understanding and hence should not be taken as serious financial advise.<br />
<br />
Bajan Allianz Future Gain plan facts (Source : <a href="http://www.bajajallianz.com/Corp/content/endowment/future-gain-web.pdf">http://www.bajajallianz.com/Corp/content/endowment/future-gain-web.pdf</a>)<br />
<br />
Minimum premium : 25,000/- Yearly<br />
Minimum sum assured : 2,50,000/- (10 * annual premium)<br />
Minimum Policy term : 10 years<br />
Minimum Premium paying term : 5 years<br />
Lock in period : 5 years<br />
<br />
Premium allocation charge :<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>1st year : 5.5.% of Annual premium = 1,375/-<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>2nd - 5th year : 3.75% of Annual premium = 937.5/- per year. (3,750/- for 4 years)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Average yearly charge = (1375 + 3750) / 5 = 1025<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
Yearly charges so far = 1,025/-<br />
<br />
Policy administration charge :<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>33.33/- per month increasing at 5% p.a. every month<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Assuming this 5% is compunded every month at the end of 5 years this value will be 42.77.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>So for the sake of simplification let us take the average of starting and ending value as the monthly dedudction<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Average monthly dedudction = (33.33 + 42.77) / 2 = 38.05 =~ 38/-<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Yearly policy administration charges = 38 * 12 = 456/-<br />
<br />
Yearly charges so far = 1,481/<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
Mortality charge :<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>For a person aged 30, charge = 1.34 per thousand sum at risk (Deducted at monthly anniversary a.k.a every month)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Sum at risk = Maximum of [death benefit – regular premium fund value - top up premium fund value, zero]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Death benefit = 2,50,500/-<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Regular Premium Fund value will keep changing depending the fund performance.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>At beginning for first year = (First premium - charges) = 25,000 - 1481 = 23,519<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>So sum at risk = 2,50,000 - 23,519 = 226481/-<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Mortality charge = 227 * 1.34 = 304<br />
<br />
Yearly charges so far = 1,785/-<br />
<br />
NOTE : The mortality charges will decrease as you pay more premium and also as the fund gains more value. But to keep things simple taking an average value is acceptable for this calculation and to illustrate the point that ULIPs are not really good options.<br />
<br />
So for a yearly premium of 1,785/- you get a life cover of 2,50,000/- for 5 years (assuming you do not want to pay a premium after the mandatory 5 years)<br />
<br />
Now consider the Anmol Jeevan - II (822) term plan from LIC.<br />
For a yearly premium of 1,617/- you get a life cover of 7,00,000/- for 5 years (Source : <a href="https://www.licindia.in/premium_calculator.htm">https://www.licindia.in/premium_calculator.htm</a>)<br />
<br />
So wouldn't it make sense to separate out investment and insurance? For insurance take a plain term plan and for investment choose a decent ELSS scheme. This way your investment will perform much better and you will also have a much better insurance life cover.</div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com28tag:blogger.com,1999:blog-375315255567275930.post-14205637271862936442015-02-07T07:22:00.001+05:302015-02-09T23:05:38.192+05:30AJAX for beginners - what it is and how it evolved<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr">
Today's websites or web pages are very complex structures involving several components. It can be daunting for a beginner to understand it all at once. To ease the process let's break things down and see how the various pieces fit together.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
At the core of web pages is the HTML. It is the language that browsers understand and it is what web developers use to showcase rich content. Without HTML all our web pages would have been simple text files. Now I assume that you are aware of HTML and how it is used in web pages. Another critical piece that works closely with HTML is CSS, but we can skip that one for now.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Plain HTML web pages are pretty dull. They are not really interactive. What they mainly have apart from text are : </div>
<div dir="ltr">
</div>
<ol style="text-align: left;">
<li>Some formatting information which tells the browser how to show the contents.</li>
<li>Some media content like images or videos.</li>
<li>A bunch of hyperlinks which lead to other similar web pages.</li>
<li>In slightly evolved pages there would be forms which allowed a user to send data back to the servers.</li>
</ol>
<br />
<div dir="ltr">
It is the third one which helped form this "web" of pages which we call the Internet. How do these links work? Pretty simple actually. Each link typically points to a web page on a server. Whenever a user clicked on a link, the browser would fetch that page, remove the existing page and show the newly downloaded one. Some times the link could point back to the same page in which case clicking on it would just "refresh" the existing page. We all know about the refresh/reload button in the browsers don't we?</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
There are a few things to note here.</div>
<div dir="ltr">
</div>
<ol style="text-align: left;">
<li>These basic web pages were dull in the sense that they were not interactive. They did not respond to user actions except for clicks on links, in which case the existing web page goes away and a fresh page is loaded.</li>
<li>When a link was clicked the browser would decide to send a request to the server. The web page itself did not have much control on when the request should be made.</li>
<li>When the browser was making a request in response to a link click, there was pretty much nothing you could do with the web page until the request completed. Every request to the server blocked the entire page and if there were multiple requests that had to be made it had to be sequential, one after the other. A fancy technical word to describe this would be "synchronous".</li>
<li>An obvious observation is that the data that came from server in response to request from a browser was HTML, as in the data and information on how to display that data were sent back from the server all the time.</li>
</ol>
<br />
<div dir="ltr">
While the fourth point appears as not such a big problem, the first three are definitely limitations.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
To work around the first problem browser developers came up with JavaScript. Browser folks told web developers that they can make their web pages interactive and responsive to user actions by writing code to handle those interactions in this new language called JavaScript and including it in the web pages. Web developers could now write different pieces of code to handle different user actions. The browser provided a few functions (aka APIs) in JavaScript which the web developers could use to make changes to the web page. This API is called DOM (Document Object Model). Thus web pages became interactive and responsive.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
The second and third limitations still existed however. The only way to request data from server was through links or in case of evolved pages through forms. Also the web page was one single unit. Whenever something had to change the whole page had to be reloaded. Imagine something like that with your gmail page. How would it be if the page refreshed every time you received a chat message or worse every time one of your contacts logged in or out of chat? That would be disastrous. The fate would be similar of something like a sports website in which the small corner showing the score needs to be updated a lot more frequently than the rest.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
To solve this some people thought of iframes as a solution. Iframe is a HTML tag inside which you can put another HTML page. Now with this arrangement the inner page could be reloaded without affecting the outer page. So the sports website could now put the score part in an iframe and refresh it without affecting the rest of the page. Similarly gmail could break up its page into multiple iframes (It actually does this in reality, but it also does a lot more than this).</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
With iframes the "synchronous" problem was somewhat solved. Multiple requests could now be made in parallel from a single web page. However the method of making the request largely remained the same, using links or forms. It was either not seamless or almost impossible to make requests in any other manner, like say whenever user typed something (like Google search). Now let's see what all capabilities we have on top of the basic web pages.</div>
<div dir="ltr">
</div>
<ol style="text-align: left;">
<li>Web pages can respond to user actions. Some code can be executed on various user actions made on different parts of the page.</li>
<li>This code can modify the web page using DOM.</li>
<li>Browsers are now capable of making multiple requests in parallel without blocking the web page.</li>
</ol>
<br />
<div dir="ltr">
The browser folks now combined these abilities thereby allowing web developers to make requests to servers in response to user actions using JavaScript. These requests could be made in parallel without blocking the page i.e. Asynchronously. Now when the response came back the same JavaScript code could add the HTML received in the response to the existing page using DOM.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
The developers went a step ahead and said "why receive HTML every time? In most cases the formatting or presentation information is already there in the web page. What is needed is only new data or content (For example, in the sports website example, all that is needed is the updated score. Information on how to show that score is already present in the web page). So instead of fetching HTML every time let's just fetch data to make things much faster and efficient". And back then the most popular way of representing data in a structured manner was XML. So developers started receiving data in XML format from the server and using that to update the web page. XML was so popular that browsers added support for automatically parsing XML data received in response to these requests. </div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
This approach of making requests and updating parts of web pages became very popular and was much widely used. Since this was predominantly used to make requests over HTTP (The protocol of the web) to fetch XML data this technology was called "XMLHttpRequest" (Internet explorer called it something different, it probably still does).</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
What all does this XHR offer?</div>
<div dir="ltr">
</div>
<ol style="text-align: left;">
<li>Making requests "Asynchronously"</li>
<li>Making requests from "JavaScript"</li>
<li>Making requests for "XML"</li>
</ol>
<br />
<div dir="ltr">
Put together it forms "AJAX - Asynchronous JavaScript and XML".</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Notes :</div>
<div dir="ltr">
</div>
<ol style="text-align: left;">
<li>Several things have been simplified here as this is aimed at people new to web development and Ajax in particular. This should nevertheless give a good starting point.</li>
<li>References to XML should be read as " something other than HTML". Nowadays XML has been largely replaced by JSON because of several advantages.</li>
<li>XMLHttpRequest does not necessarily mean making asynchronous request. It supports making synchronous requests also. But I don't know if there is a good reason to do it. Making a sync xhr will block the entire page until that request is complete. Really don't do that.</li>
</ol>
</div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-16357044702607364222014-12-12T04:09:00.000+05:302014-12-12T04:09:06.546+05:30As citizens, we are the system<div dir="ltr" style="text-align: left;" trbidi="on">
This post is in response a comment on quora ( <a href="http://www.quora.com/What-are-the-biggest-misconceptions-that-Indians-have-about-India/answer/Prashant-Bhattacharji/comment/2765540">http://www.quora.com/What-are-the-biggest-misconceptions-that-Indians-have-about-India/answer/Prashant-Bhattacharji/comment/2765540</a>) and a couple more comments from the same user in that same thread.<br /><br />===================================================<br /><br />Dear Abhijeet Choudhury,<br /><br />A
lot of what you have said here is true, about the politicians, thugs
and the plight of poor people in India. However I think there are some
misconceptions. First of all here is my inference about who you are
based on your comment and quora profile (Ignore if my inference is wrong
) : <br /><br />1)
You are an IT engineer (mostly at TCS) from a middle class or upper
middle class family who has been in an urban place for most part of your
life, there by lacking touch with the ground reality, especially what
happens in rural and semi-urban places.<br />2) You <span style="font-weight: bold;">probably</span> had been to USA for work and were impressed by the much efficient system and people there<br />3) You probably follow Hollywood and US news/comedy etc and have a very positive view of USA<br /><br />Now the misconceptions<br /><br />1) USA is definitely advanced than India in several aspects. But remember that <br /> -
They got independence centuries before we did. Their situation was also
pretty bad even till the first half of 20th century. The poor people
like the mine labourers, construction workers suffered very badly. (Read
these : <a class="qlink qtext_editor_link_text" data-link-delete="http://en.wikipedia.org/wiki/Truck_system" data-link-text="Truck system" href="http://en.wikipedia.org/wiki/Truck_system" id="qlink_t09uynsttp">Truck system</a> <a class="qlink qtext_editor_link_text" data-link-delete="http://en.wikipedia.org/wiki/Sixteen_Tons" data-link-text="Sixteen Tons" href="http://en.wikipedia.org/wiki/Sixteen_Tons" id="qlink_myh2ba69s7">Sixteen Tons</a> )
It was mainly during and after the second world war that USA super
charged and surged ahead, primarily by accepting people from across the
world and creating an ecosystem where innovation thrived. (That is
something we definitely have to learn)<br /> - their population and population density was and is much lesser than that of India<br /> -
they sort of (not entirely) had a clean slate to start with while we
had a much older history/legacy to deal with. The older it is the more
time it takes to change.<br /><br />None
of these are reasons for us to be complacent with the current state of
affairs. Singapore is a perfect example of how development can be
achieved in short time also. I am merely saying that a comparison of
current India and current USA is not fair. We are definitely
progressing. May not be at rate which is impressive to you, may not be
at the level the west is, nevertheless we are moving forward and there
is ample proof of this. Just look around you and compare the 90s with
the current. Has there been no positive change at all? After 67 years of
independence we are definitely ahead of where USA was after 67 years of
their independence. This is of course because we have leapfrogged in
various fields. And that is precisely why we can catch up with the
developed world. Let us be positive and give ourselves some more time.
Because of our huge mass and very old history, the inertia is very high.
Change will be slow but it will happen. It already has started (and no
this is not a reference to Modi coming to power).<br /><br />2)
You "almost all common people in USA have a lavish life" - Who are
these common people you are referring to? The middle class and upper
middle? Your USA counterparts? Fact check : These people are not "almost
all" by any statistic. It is true that the urban middle class people
are having a decent life in the USA. But so is the urban middle class in
India. We sure have more friction when we deal with certain archaic
govt institutions but on a day-to-day basis the urban middle class has a
fairly smooth life (except may be traffic woes..!). The poor and
jobless, even in USA, have a lot of problems. The number of homeless
people is increasing like anything. The wealth distribution is very
skewed there too. Well qualified people are spending nights in buses
because they can afford an overnight bus journey but cannot afford to
rent a home. (Read : <a class="qlink qtext_editor_link_text" data-link-delete="http://www.telegraph.co.uk/news/worldnews/northamerica/usa/11249291/The-dark-side-of-Silicon-Valley.html" data-link-text="The dark side of Silicon Valley - Telegraph" href="http://www.telegraph.co.uk/news/worldnews/northamerica/usa/11249291/The-dark-side-of-Silicon-Valley.html" id="qlink_ybdovsxuwr">The dark side of Silicon Valley - Telegraph</a>).
I also belong to this same urban middle class category and my life is
pretty smooth. May not be lavish but definitely not struggling. So is
the case with almost all the people in my circles. You cannot compare
the picture of a poor farmer or a construction worker in India with the
picture of an IT guy in USA. The blue collar workers suffer in USA too
(Read : <a class="qlink qtext_editor_link_text" data-link-delete="http://www.theguardian.com/money/2014/nov/28/being-homeless-is-better-than-working-for-amazon" data-link-text="'Being homeless is better than working for Amazon'" href="http://www.theguardian.com/money/2014/nov/28/being-homeless-is-better-than-working-for-amazon" id="qlink_uc5dn37nly">'Being homeless is better than working for Amazon'</a>)<br /><br />3) You talk about loan to poor people. Here are some things you should know : <br /> -
Govt provides "interest free" agriculture loans to farmers. This
facility is being used by many farmers (albeit being misused also).<br /> -
Co-operative societies provide loan to the poor at 3% interest rate
(which is less than the interest your bank gives on your SB account)<br /> -
Micro finance institutions exist through out the country (and several
other neighbouring countries) which are helping workers and
entrepreneurs at the rural, grass-root levels. These are people who sell
fruits and vegetables on hand pulled carts, people who put up small
mobile recharge shops, etc.<br /> - Govt
runs the rural employment guarantee scheme which is analogous to the
"Unemployment compensation" in USA. Again, this is also being misused
but this has indeed prevented a lot of migration of poor people from
rural to urban places there by reducing the "slums" that we see in all
cities.<br /><br />There
are other several steps being taken by the govt to help uplift the
poor. Sure the execution is not the best and efficient. There are a lot
of leaks. But it is not summing up to a zero. There is a positive effect
and we are progressing. It can definitely be a lot better, but that
won't happen with negative attitude. We have to keep a positive outlook
and be ready to get our hands dirty. Otherwise we will just be like
those people sitting in a comfort chair in front of tv watching Sachin
get out and then say "Arre square cut maarna tha yaar..!".<br /><br />4)
In your another comment you talk about traffic violations. You say
people do it because they see politicians and other big people doing it
and also because police extort money from people. I fail to recognize
the correlation. If a politician is breaking traffic rules, what is
stopping you from following the same? I see so many people jump signals
while I always make a point to stop when it is a red. People behind me
honk like crazy, some switch lanes and point fingers at me when they
overtake me and jump the signal. I still don't budge. It is not just me.
I have seen several other people do the same. If you are genuinely
interested in creating a lawful ecosystem, then start following the
rules. You cannot say that I won't do it until every one else starts
doing it. That mentality won't get us anywhere. As Gandhiji said "Be the
change that you wish to see in the world".<br /><br />That
brings me to my final and most important point : In all your posts you
are just pointing fingers at others : other people, the system, the
politicians, the police and so on. You compare all of these in India and
USA. You declare that all of this is better in USA. But you fail to
recognize what contributed to making all of this better in USA. Did it
magically happen? Of course not. The people of the country toiled hard
to reach there. People like you and me. <br /><br />There
was a time in USA when child labourers in coal mines was a common
place. There was a time when farmers in USA paid lawyers with grains and
nuts because they did not have money. There was a time in USA when
racial discrimination was so strong that the African-American folks were
as afraid of just talking as were the shudras in India when
untouchability was at its height. The USA too had a lot of shortcomings.
But they worked to overcome all of that and fullfil their dreams,
albeit in their own ways. There was several altercations and fights.
People had to fight for their rights, their safety, for development.
They still do. (Remember "Occupy Wallstreet", Ferguson shooting?). It
only through such fights that we weed out the bad. Not by complaining.<br /><br />You
might say "What could a regular corporate employee like me who works 9
to 6 for 5 days a week do in this matter?". The simple answer is that
there is not easy way out. If we want to bring about a change we should
be ready to face hardships. To start with pledge to abide by rules
everywhere you interface with government. Getting your driving license?
Do not go through an agent or pay any bribe to the RTO officer.
Purchased a piece of land? Do not under-quote the value to save tax and
pay a bribe to the sub-registrar. Is there a pot hole in the road in
your locality? Go notify that to your ward corporator. If it doesn't
happen in one complaint, do it many times. You sure will be spending
quite a bit of time, at least initially. Please don't think of it as a
waste of time. That would just be a short sighted view. Eventually they
will give in and do the work. There are a lot of things that each and
every one of us can do as citizens to improve the situation. Complaining
is definitely not one of them. And pessimistic attitude definitely
doesn't help one bit.<br /><br />Not
until too long ago the Americans looked up to Europe like you look up
to the USA, picturing Europe to be that much more developed and
sophisticated place. That in no way reduced their national pride.
Everything they did, everything they said was about USA and people of
USA. Majority of the people aiming to be the best cared about being the
best in USA. They did not look for a stamp of approval from some other
country. Their growth and development period was characterized by
indigenous innovation and not by simply importing ideas and technologies
from the already developed world. That is what we should be doing too.
Be proud about our nation while accepting our shortcomings and working
towards overcoming them.<br /><br />All
said and done, please do note that India is not at all a failed
democracy. Compared to a host of oppressive regimes around the world we
have freedom of speech to a vast degree. Except for a few isolated
incidents like the one you mention (two mumbai girls being arrested) we
have a lot of freedom of speech and it is improving. The 66A of IT Act
(under which the girls were arrested) has been challenged in the court
and the court has already opined that the legislation is very vague and
ripe for misuse. The hearing is still on and soon we will see the
legislation being revamped to be meaningful, if not scrapped altogether
(Read : <a class="qlink qtext_editor_link_text" data-link-delete="http://indianexpress.com/article/india/india-others/no-guidelines-prone-to-abuse-sc-criticises-sec-66a-of-it-act/" data-link-text="Sec 66A of IT act lacks guidelines, arrests made over social media posts prone to abuse: SC" href="http://indianexpress.com/article/india/india-others/no-guidelines-prone-to-abuse-sc-criticises-sec-66a-of-it-act/" id="qlink_g3e44bxvfs">Sec 66A of IT act lacks guidelines, arrests made over social media posts prone to abuse: SC</a>).<br /><br />Things
will change. They will improve. They are just waiting for each of one
of us to do our part. Let's not shy away from confronting the problems
and work on solving them instead of just complaining.<br /></div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-41789223354324888252014-05-29T23:16:00.000+05:302014-05-29T23:16:40.917+05:30My response to request for feedback from AAP (Aam Aadmi Party)<div dir="ltr" style="text-align: left;" trbidi="on">
Today I got an email asking me for feedback on AAP (Aam Admi Party). The first question was<br />
<br />
<div class="ss-q-title" style="background-color: #fffbef; color: #28642e; font-family: Molengo, 'Trebuchet MS', Tahoma, Verdana, Arial, sans-serif; font-size: 14px; font-weight: bold; line-height: 18px;">
What would make you volunteer in future? What stopped you from volunteering this time? <label aria-label="(Required field)" for="itemView.getDomIdToLabel()"></label><span class="ss-required-asterisk" style="color: #bc3611;">*</span></div>
<div class="ss-q-help ss-secondary-text" dir="ltr" style="background-color: #fffbef; color: #666666; font-family: Molengo, 'Trebuchet MS', Tahoma, Verdana, Arial, sans-serif; font-size: 14px; line-height: 18px; margin: 0.1em 0px 0.25em;">
Give us as much detail as you'd like</div>
<br />
I took the sub-text literally and a little seriously and wrote a really detailed answer. I thought I might as well put it up here and share with the world (or the one or two who actually read my blog.. :P ). Anyways here it goes :<br />
<br />
Not interested in volunteering for AAP.<br />
<br />
AAP as a party has acted in the most irresponsible, selfish and foolhardy manner ever since it formed the government in Delhi. People of Delhi whole heartedly supported AAP with the hope that they would get some real stable governance for the next 5 years. Instead what they got was utter chaos.<br />
<br />
I expected changes like corruption free governance, no undue fiscal burden on the state, public works development, fulfillment of election promises for once, but all I got to see was a couple of filmy style sacking of corrupt officers, some agitation and finally a resignation just after 49 days. If that was not irresponsible then what is?<br />
<br />
And what do you do after resigning? You forget Delhi altogether and try to become the prime minister of India. If this isn't selfish then what is it?<br />
<br />
Prime minister of India, no less. Are you kidding me? You could not run the state of Delhi for two months and you expect me to hand over the reins of the country to you for the next 5 years?<br />
<br />
Alright lets assume that you genuinely felt that contesting the Lok Sabha elections was a key thing and something that you had do. What did you do? Again like the typical filmy style you go out like an underdog hero and challenge the most popular leader, in a place which is not even your home turf. If this is not foolhardiness then what is it? How much would it have mattered whom you win against. Wouldn't you be able to serve the people better being an MP from somewhere in Delhi (your home turf) instead of creating all this drama of challenging Mr. Modi from Varanasi. Look at how Dr. Jayaprakash Narayan (<a href="http://en.wikipedia.org/wiki/Jayaprakash_Narayan_(Lok_Satta)">http://en.wikipedia.org/wiki/Jayaprakash_Narayan_(Lok_Satta)</a> ) has done it. His party was never in power anywhere, but that never deterred him from becoming one of the best performing MLAs. I believe you wanted to show that you are not afraid of facing anyone in elections and you have the peoples' mandate to contest and win against Mr. Modi. But who cares about that Mr. Kejriwal? Sure you might have put up a good fight, but what does it account to in the end? All that I see is that you were trying to be a bollywood hero in the Indian politics, who wants to the take on the big bad guy (again as declared by yourself). You now lost your chance to voice the opinion of the people you represent in the LokSabha.<br />
<br />
Then comes the ultimate flip-flop you did with the Delhi assembly. Until LokSabha election results were announced you kept hounding the Lt. Governor to dissolve the assembly. You even approached the Supreme Court for this. Then on one fine Tuesday you go and meet the Lt. Governor and make an announcement to the public that you have requested the Lt. Governor to NOT dissolve the assembly but give you another chance and that you will ask people about forming the government again and then decide. And the next day (on Wednesday) you make an yet another U-turn announcing that you have asked the Lt. Governor to dissolve the assembly and you will now ask people about contesting again in the elections.<br />
<br />
How do you think this reflects on you? You accuse every politician out there of corruption, double standards and every other accusation possible and you yourself act in such an irresponsible and opaque manner, saying contradictory things on a daily basis and on top of it claim to be "THE ONLY HONEST POLITICAL PARTY". How can I believe anything you say after you have done so much of circus?<br />
<br />
All this drama eroded complete faith in the capability of AAP to form and run a government in any form, let alone provide better governance than the existing political parties.<br />
<br />
Please note that I have talked only about your own actions and what I feel about those. I have not mentioned any of the other accusations made about AAP or Mr. Kejriwal, like Mr. Kejriwal coming to Varanasi by train saying he has Rs. 500/- in his pocket and going back by flight, or the episode around Mr. Kejriwal's official residence as CM of Delhi, or the incident of Mr. Somnath Bharti and certain people of African origin or the mayraid images and posts circulated on the social network which, of course, you totally accuse as baseless and a defamation propaganda by the IT cell of BJP. I am not even making the comparison between Mr. Modi's Gujarat model and your achievements, because you say that its all an eyewash. So be it. That's why I have mentioned only the actions of AAP and it's leader Mr. Kejriwal.<br />
<br />
Now a few times AAP has come out and said that it is a new political party with inexperienced people and hence they could have made some mistakes. It's good that you acknowledge this. But with this statement you can't ask people to hand over the country's administration to you. If you are new and inexperienced, then start with the basics. Gain that experience that you think is needed. I don't have to tell you that you need to start from the grass-root levels. Making noise in urban places, parading urban youth with the "Aam Aadmi" cap is one thing and working at village panchayat level, addressing rural problems is entirely different.<br />
<br />
You do not have to be a MLA or MP to provide good governance. Those are not the only places where good politicians are needed. Those are not the only places where big time scams and plundering of public funds is done. Gram panchayat, taluk panchayat and Zilla Parishad are equally in need of good politicians and bureaucrats. If one were to accumulate the amount of money siphoned off in the name of NREGA through out the country then I am sure it will beat any of the other big scams that the previous government(s) have been accused of. The amount of pilfering that happens is insane. It easily runs into crores for each panchayat, every year. And I know this first hand.<br />
<br />
Start at those places. Let people across the state and country know you, not just by your agitations, but by real work that you do, by some real meaningful change that you bring about. It's ok if you are unable to bring in a strong legislation like Jan Lokpal. You don't have to throw your hands up in the air in despair saying you were not given enough support. There are other innumerable things that you can and should do and those will have a big positive impact on people even without the Jan Lokpal. If you tell me that there is absolutely no machinery to fight corruption in our system currently then you are absolutely wrong. You do not have to put every single corrupt bureaucrat in jail or suspend them. It's sufficient if you make an example out of one or some of them in a few departments on a regular basis. The rest will automatically shy away from corruption. And you have enough ways to enforce such a thing.<br />
<br />
Also, corruption is not the only problem plaguing our country. There are numerous other things that require attention. Being in a position of power allows you to address these other issues while you carefully maneuver the juggernaut that our system is. It doesn't have to be a head on collision. It's not a "Last man standing" kind of battle. I have personally seen government officials doing this in a very intelligent manner at various levels and I have seen it from very close quarters. It is possible. It is doable. Above all it brings out the desired positive changes and makes the lives of people better. It provides them what they really crave for. It's going to be difficult no doubt, but our constitution and our legal system provide so many options to deal with this juggernaut. This same government infrastructure which the corrupt are mis-utilizing can be turned around as a weapon against them.<br />
<br />
No matter which legislation you bring in, we will not be a corruption free state overnight. It's going to be a long road and you need to be patient about it. We as a country are definitely in a much better position than we were a few decades back. So we can get better. Its just that we have a huge inertia owing to our big mass (aka population). Change is difficult. One is easily tempted about the idea of bringing about a revolution and making overnight changes. Personally, I feel the cost involved for such a revolution is very high and more importantly the desired result is not guaranteed. In comparison the slow and steady here will indeed be the winner.<br />
<br />
You ask me what would make me a AAP volunteer in future. I say look beyond cities. Look at the vast majority of semi-urban and rural places. Go there. Find like minded people in those places. I am sure they are there. Empower them with all that you have. You have top class lawyers with you who can carry out a PIL right up in the supreme court. You have contacts in the press. You can mobilize man power. You can draw the attention of the nation and beyond. You know how to effectively use the RTI. You run NGOs which, despite the allegations of being funded by the CIA through various organizations, can do a lot of good. Do all of that. Become a party of the rural India. Become a household name as the best choice in panchayat politics and then I will probably become an AAP volunteer. Well technically you will not need me at that point and thats a fine contradiction to have. :).<br />
<br />
I say probably because apart from the stuff that I have said above I am not really a fan of AAP party principles, which according to me are very close to communist ideas. So that's altogether a different matter and a commentary on that will have meaning only after the above mentioned things are addressed.<br />
<br />
Oh and one more thing which I almost forgot. Please groom local leaders everywhere. Or rope in existing local leaders whose thought process aligns with yours. Personally a tie-up with Loksatta would have been really good. Nevertheless, do not be a typical "high command controlled" party. Be true to your vision and words and be truly federal even in your party structure and operation.<br />
<br />
P.S : I might have come across as a staunch BJP supporter through out, which at the moment is true. In the recently concluded elections BJP under the leadership of Mr. Narendra Modi has been the best option for the country according to me and I am positive about India's future under the current government. Ideologically though, I think Loksatta is more appealing to me than AAP.</div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com4tag:blogger.com,1999:blog-375315255567275930.post-31700816591564760022013-10-27T05:26:00.000+05:302013-10-27T05:26:00.723+05:30Invalid credentails : OmniAuth + oAuth2 + Rails 4 encrypted cookie store + simultaneous requests<div dir="ltr" style="text-align: left;" trbidi="on">
OmniAuth is a very well know gem in the Ruby/Rails world. Almost every Rails application out there is probably using it to authenticate with one of the various mechanisms it supports. OmniAuth is just awesome.!<br />
<br />
I have been using OmniAuth for about 3 years now in various Rails projects and it has worked very well, although I have had to monkey patch it once or twice to allow me to exploit some of the Facebook features (like authenticated referrals). But all in all, it just works as advertised and you will have an authentication system in pretty much no time at all.<br />
<br />
Yesterday, however, I was having quite a bit of hard time getting OmniAuth to do a simple "Login with Facebook" oAuth2 authorization. It was something that had worked seamlessly on innumerable previous occasions. But yesterday it just kept failing repeatedly, succeeding only once in a while. And it always failed with the same obscure error "Invalid Credentials" during the callback phase. (OmniAuth operates in three phases : Setup, Request and Callback. Apart from OmniAuth wiki on github, this is a good place to read about it : <a href="http://www.slideshare.net/mbleigh/omniauth-from-the-ground-up" target="_blank">http://www.slideshare.net/mbleigh/omniauth-from-the-ground-up</a>). The fact that the error message was not so helpful made this whole process a lot more frustrating. After some hunting on the inter-webs I found that the culprit could be a bad "<span style="font-family: "Courier New",Courier,monospace;">state</span>" parameter.<br />
<br />
Wait, what is this "<span style="font-family: "Courier New",Courier,monospace;">state</span>" parameter?<br />
<br />
<h3 style="text-align: left;">
Background : oAuth-2 CSRF protection</h3>
<br />
oAuth2 specifies the uses of a non-guessable secure random string to be used as a "state" parameter to prevent CSRF attacks on oAuth. More details here : <a href="http://tools.ietf.org/html/rfc6749#section-10.12">http://tools.ietf.org/html/rfc6749#section-10.12</a>. This came out almost a year back and many oAuth providers implement it already, including <a href="https://developers.facebook.com/docs/reference/dialogs/oauth/" target="_blank">Facebook</a>. OmniAuth also implemented it <a href="https://github.com/intridea/omniauth/issues/612" target="_blank">last year</a>. Although not written with the best grammar, <a href="http://homakov.blogspot.in/2012/07/saferweb-most-common-oauth2.html" target="_blank">this article</a> will tell you why this "<span style="font-family: "Courier New",Courier,monospace;">state</span>" parameter is needed and what happens without it.<br />
<br />
To sum it up, oAuth client (our web application) creates a random string, stores it in an accessible place and also sends it to the oAuth provider (Ex : Facebook) as "<span style="font-family: "Courier New",Courier,monospace;">state</span>" during the request phase. Facebook will keep it, authenticate the end user, ask for permissions and when granted sends a callback to our web application by redirecting the user back to our website "with the <span style="font-family: "Courier New",Courier,monospace;">state</span>" as a query parameter. The client (our web application) compares the "<span style="font-family: "Courier New",Courier,monospace;">state</span>" sent by the provider and the one it had stored previously and proceeds only if they match. If they don't then there is no proof that the callback that our web application received is actually from the provider. It could be from some other attacker trying to trick our web application into thinking (s)he is someone else.<br />
<br />
In case of OmniAuth oAuth2, this state parameter is stored as a property in the session with the key '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' during the request phase. The result of the request phase is a redirect to the provider's URL. The new session with the "<span style="font-family: "Courier New",Courier,monospace;">state</span>" stored in it will be set on the client's browser when it receives this redirect (302) response for the request <span style="font-family: "Courier New",Courier,monospace;">/auth/:provider</span> (This is the default OmniAuth route to initiate the request phase). After the provider (Facebook) authenticates the user and user authorizes our application, the provider makes a callback to our application by redirecting the user back to our web application at the callback URL <span style="font-family: "Courier New",Courier,monospace;">/auth/:provider/callback</span> along with the "<span style="font-family: "Courier New",Courier,monospace;">state</span>" as a query parameter. When this callback URL is requested by the browser, the previously stored session cookie containing the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' property is also sent to our web application.<br />
<br />
OmniAuth checks both of these and proceeds only if they match. If they don't match it raises the above mentioned "Invalid Credentials" error. (Yeah, I know, not really a helpful error message..!).<br />
<br />
<h4 style="text-align: left;">
Ok, that is good to hear, but why will there be a mismatch?</h4>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
A mismatch is possible only if the session cookie stored on the user's browser is changed such that the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' property is removed from it or altered after the request phase has set it. This can happen if a second request to our web application was <b>initiated</b> while the request phase of oAuth was running and it <b>completed</b> after the request phase completed but before the callback phase started. Sounds complex? The diagram below illustrates it.</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHhRbJMg9X9AKx1-1tvPwZh0g4TxTAFJ-sPt59rauR_6NUZtXLI-Wp4QjJhmYnCf4OcWyJq4ID0K1RZi92EzSmiWTYIQdfObVOD4qv5yMHxL1RHLeDm8E48BGADzqPAIifx3NFumI9VtE/s1600/omniauth-simultaneous-request-fail.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHhRbJMg9X9AKx1-1tvPwZh0g4TxTAFJ-sPt59rauR_6NUZtXLI-Wp4QjJhmYnCf4OcWyJq4ID0K1RZi92EzSmiWTYIQdfObVOD4qv5yMHxL1RHLeDm8E48BGADzqPAIifx3NFumI9VtE/s320/omniauth-simultaneous-request-fail.png" width="320" /></a></div>
<br />
<div style="text-align: left;">
</div>
<br />
<br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The diagram makes it clear as to when and how the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' gets removed from the session leading to the error. However, apart from the timeline requirements (i.e. when requests start and end), there is another essential criteria for this error to occur : </div>
<blockquote class="tr_bq">
<div style="text-align: left;">
The response of the "other simultaneous request" must set a new session cookie, overriding the existing one. If it does not explicitly specify a session cookie in the response headers, the client's browser will retain the existing cookie and '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' will be preserved in the session.</div>
</blockquote>
<div style="text-align: left;">
Now, from what I have observed, Rails (or one of Rack middlewares) has this nifty feature of <b>not</b> serializing the session and setting the session cookie in the response headers, if the session has not changed in the course of processing a request. So, in our case, if the intermediate simultaneous request does not make any changes to the session, Rails will not explicitly set the session cookie, there by preventing the loss of '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' property in the session.</div>
<div style="text-align: left;">
<br /></div>
<h4 style="text-align: left;">
Ok, then why will the session cookie change and lose the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' property? </h4>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
One obvious thing is that the "other simultaneous request" might change the session - either add or remove or edit any of the properties. There however is another player involved.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
This is where the "Encrypted Cookie Store" of Rails 4 comes into picture. Prior to Rails 4, Rails did not encrypt its session cookie. It merely signed it and verified the signature when it had to de-serialize the session from the request cookie. Read <a href="http://techbrahmana.blogspot.in/2012/03/rails-cookie-handling-serialization-and.html" target="_blank">how Rails 3 handles cookies</a> for a detailed breakdown. Rails 4 goes one step ahead and encrypts the session data with <a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard" target="_blank">AES-256</a> (along with the old signing mechanism. More details on that coming up in a new post). The implementation used is <a href="http://www.ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html" target="_blank">AES-256-CBC from OpenSSL</a>. I am not a Cryptography expert, but the way I understand it, the property of AES is that it results in a different cipher text every time you run the encryption for the same message plain text. Or it could also be because the Rails encryption scheme initializes the encryptor with a random initialization vector every time it encrypts a session (Implementation <a href="https://github.com/rails/rails/blob/051d289030a6cb86590cd1b619eae1879b48458a/activesupport/lib/active_support/message_encryptor.rb#L68" target="_blank">here</a>). Either ways, the session cookie contents are always new for every request even when the actual session object or session contents remain unchanged. As a result Rails will always set the session cookie in the response header for every request and result in the browser updating that cookie in its cookie store.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
In our case, this results in the session being clobbered at the end of the "other simultaneous request" and we end up losing the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' property and oAuth fails.</div>
<div style="text-align: left;">
<br /></div>
<h4 style="text-align: left;">
Umm.. ok, but when and how does this happen in real world, if at all it can?!</h4>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
All these requirements/constraints described above, especially the timing constraints makes one wonder if this can really happen in the real world. Well, for starters it happened to me (hence this blog post..!!). I also tried to think of scenarios other than mine where this would happen. Here are a couple that I could think of :</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b>Scenario - 1) FB Login is in a popup window and the "Simultaneous request" is a XHR - Ex : an analytics or tracking request.</b></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Here is the flow :</div>
<ol style="text-align: left;">
<li>User clicks on a "Login with FB" button on your website.</li>
<li>You popup the FB Login page in a new popup window. Request phase is
initiated. But there is a small window of time before the redirect
response for '<span style="font-family: "Courier New",Courier,monospace;">/auth/facebook</span>' is received and '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' is set.</li>
<li>During that small window of time, in the main window, you send an XHR to
your web app to, may be, track the click on the "Login with FB" button. You might
do this to just track usage or for some A/B testing or to build a funnel, etc. This request sends the session <b>without</b> the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'.</li>
<li>While the XHR is in progress, the redirect from the request phase is complete and the session with '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>' is set. The user now sees FB Login page loading and proceeds to login once it is loaded.</li>
<li>While the user is logging in to FB and approving our app, the XHR has completed and has come back with a session <b>without</b> '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'. This is stored by the browser now.</li>
<li>Once user logs in and approves your app, the callback state starts. But the session sent to your web app is now missing the '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'. </li>
<li>oAuth fails.</li>
</ol>
<b>How big a deal is this scenario?</b><br />
<br />
If you are indeed making a XHR in the background, then this scenario needs to be taken care of. Since the "other simultaneous" request is automatically triggered every time, it is very likely that session will get clobbered.<br />
<br />
<b>How to solve this?</b><br />
<br />
You can either first send the XHR and then in the response handler of that XHR, you can open the FB Login page in the popup. Also have a timeout just to make sure you don't wait for too long (or forever) before you receive a response for that XHR.<br />
<br />
Alternatively, if you can push your tracking events in a queue stored in a cookie, you can do that and then open the FB Login page. Once the FB Login completes, you can pull that event out of the queue and send it. As a backup have a code that runs on every new page load to look for pending events from the queue in the cookie and send those events.<br />
<br />
With HTML5 in place, its probably better to use the localstorage for the queue than the cookie. But again that needs user's permission. Your call.<br />
<br />
<b>Scenario - 2) FB Login is in the same window/tab but User has the website opened in two tabs.</b><br />
<br />
Here is the flow :<br />
<ol style="text-align: left;">
<li>User has your website opened in a browser tab - Tab-1 </li>
<li>User opens a link on your website in a second tab - Tab-2 (Ctrl + Click or 'Open in a new tab' menu item). This request sends the session <b>without</b> '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'.</li>
<li>While that Tab-2 is loading, user clicks on "Login with FB" in Tab-1 initiating the request phase. </li>
<li> If the request loading in Tab-2 is a little time consuming the redirect of the request phase of oAuth in Tab-1 completes before request in Tab-2, setting the session with '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'. After that FB Login page is shown and user proceeds to login and authorize.</li>
<li>While the user is logging in, the request in Tab-2 completes, but with a session that is missing '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'.</li>
<li>After logging in to FB, the callback phase is initiated with a redirect to your web app, but with a session that doesn't have '<span style="font-family: "Courier New",Courier,monospace;">omniauth.state</span>'. </li>
<li>oAuth fails. </li>
</ol>
<b>How big a deal is this scenario?</b><br />
<br />
Not a big deal actually. In your web app, in the oAuth failure handle, you can just redirect the user back to <span style="font-family: "Courier New",Courier,monospace;">/auth/facebook</span>, redoing the whole process again and guess what - this time it will succeed and that too without the user having to do anything because the user is already logged in to FB and has also authorized your app. But just to be on the safer side, you would want to be careful about this loop going infinite (i.e. You start FB auth, it fails and the failure handler restarts the FB auth). Setting a cookie (different from the session cookie) with the attempt count should be good. If the attempt count crosses a certain limit, send the user back to homepage or show up an error page or show a <a href="http://www.lolcats.com/videos.html" target="_blank">lolcats video</a>, c'mon be creative.<br />
<br />
Ok, those are two scenarios that I could think of. I am not sure if there are more.<br />
<br />
<h4 style="text-align: left;">
Can OmniAuth change something to solve this?</h4>
<br />
I
believe so. If OmniAuth uses a different signed and/or encrypted cookie
to store the state value instead of the session cookie none of this
session clobbering would result in loss of the state value. OmniAuth is a
Rack based app and relies on the Session middleware. I am not entirely
sure, but it can probably use the Cookie middleware instead. Just set
its own '<span style="font-family: "Courier New",Courier,monospace;">_oa_state</span>' cookie and use that during callback for verification. <br />
<br />
<h4 style="text-align: left;">
Will you send a pull request making this change? </h4>
<br />
I am not sure. I first will hit the OmniAuth mailing list and find out what the wise folks there have to say about this. If it makes sense and nobody in the awesome Ruby community provides an instant patch, I will try and send a patch myself.<br />
<br />
<b>THE END</b><br />
<b> </b><br />
Ok, so that was the awesome ride through oAuth workings inside the OmniAuth gem. In the course I got to know quite a bit of Rails and also Ruby internals. Looking forward to writing posts about those too. Okay, okay.. fine. I will try and keep those posts short and not make them this long..!!<br />
<br />
Till then, happy oAuthing. :-/ !<br />
<br />
P.S : Security experts, excuse me if I have used "authentication" and "authorization" in the wrong places. I guess I have used it interchangeably as web applications typically do both with oAuth2.<br />
</div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com3tag:blogger.com,1999:blog-375315255567275930.post-53786568647056094382013-10-16T04:10:00.001+05:302013-10-16T04:10:08.828+05:30Creating Wildcard self-signed certificates with openssl with subjectAltName (SAN - Subject Alternate Name)<div dir="ltr" style="text-align: left;" trbidi="on">
For the past few hours I have been trying to create a self-signed certificate for all the sub-domains for my staging setup using wildcard subdomain.<br />
<br />
There are a lot of guides and tutorials on the internet out there which explain the process of creating a self-signed certificate using openssl with a good amount details. Further there are also certain guides to create a self-signed cert for wildcard domain. It's fairly easy. You just specify that your <span style="font-family: "Courier New",Courier,monospace;">Common Name (CN)</span> a.k.a <span style="font-family: "Courier New",Courier,monospace;">FQDN</span> is <span style="font-family: "Courier New",Courier,monospace;">*.yourdomain.com</span> while creating the certificate signing request (CSR).<br />
<br />
This will take care of all of your sub-domains under yourdomain.com (like www.yourdomain.com or mail.yourdomain.com), however your top level bare domain (yourdomain.com) itself is not covered under this certificate. When you use a certificate generated by specifying *.yourdomain.com the browsers will throw up an error when you hit your server with the top level domain name https://yourdomain.com/.<br />
<br />
To address this X.509 certificate standard allows for a type of extension named <span style="font-family: "Courier New",Courier,monospace;">subjectAltName</span> (<a href="http://en.wikipedia.org/wiki/SubjectAltName">http://en.wikipedia.org/wiki/SubjectAltName</a>). Using this you can specify that there are a few other domain names for which this certificate is valid.<br />
<br />
This requires specifying the use of this extension while generating the certificate request AND while signing the certificate. To do this you will have to add a few things to your openssl configuration file (typically <span style="font-family: "Courier New",Courier,monospace;">/etc/ssl/openssl.cnf</span> on a Ubuntu like machine). Alternatively you can copy the config file to another location, add these extension stuff there and then specify the new config file for all your openssl commands. The commands shown below assume the default config file at <span style="font-family: "Courier New",Courier,monospace;">/etc/ssl/openssl.cnf</span> was updated with extension details.<br />
<br />
Here is one blog post which details the updates needed for the openssl config file. <a href="http://grevi.ch/blog/ssl-certificate-request-with-subject-alternative-names-san">http://grevi.ch/blog/ssl-certificate-request-with-subject-alternative-names-san</a>. It also has commands for generating the private key, converting the key to a format which does not ask for password (a.k.a unencrypted key), generating the certificate request (CSR) and finally signing the certificate. The steps mentioned there until the generation of certificate request are correct. It is the last step of signing the certificate that is missing one small piece of information because of which the extension mentioned above (<span style="font-family: "Courier New",Courier,monospace;">subjectAltName</span>) doesn't get added to the final certificate, despite they being present in the certificate request.<br />
<br />
After a lot of searching on the internet, copy pasting the commands exactly, trying my luck at IRC (<span style="font-family: "Courier New",Courier,monospace;">irc.freenode.net#openssl</span>) the answer finally appeared to me in the man pages (duh..! <a href="http://techbrahmana.blogspot.in/2007/05/using-irc-one-place-for-answers-to-all.html" target="_blank">RTFM dude</a>..!!). The man page for x509 (<span style="font-family: "Courier New",Courier,monospace;">man x509</span>) command of openssl has this little entry :<br />
<br />
<blockquote class="tr_bq">
-extfile filename<br />
file containing certificate extensions to use. If not specified then no extensions are added to the certificate.</blockquote>
<br />
So turns out that just specifying the extensions in the openssl config file is not sufficient, but you must also specify the same file as the file containing the extensions to be included in the command line using the above <span style="font-family: "Courier New",Courier,monospace;">-extfile</span> option.<br />
<br />
With that added, you will get a self-signed certificate for your wildcard subdomain which is also valid for your top level bare domain.<br />
<br />
Changes made to <span style="font-family: "Courier New",Courier,monospace;">/etc/ssl/openssl.cnf</span><br />
<br />
Uncomment the req_extensions = v3_req<br />
<pre class="brush: bash">req_extensions = v3_req # The extensions to add to a certificate request</pre>
<br />
<br />
Add subjectAltName to v3_req section<br />
<br />
<pre class="brush: bash">[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
</pre>
<br />
Finally add the alternate names for which you want this certificate to be valid. It would be your toplevel bare domain<br />
<br />
<pre class="brush: bash">[alt_names]
DNS.1 = yourdomain.com
</pre>
<br />
This last section [alt_names] will not be present in the file. You can add it right after the [ v3_req ] section.<br />
<br />
Once config update is done, create your certificate.<br />
Here are the commands that I used to create such a certificate :<br />
<br />
Create a private key :<br />
<pre class="brush: bash">openssl genrsa -des3 -out ssl/staging/yourdomain.com.key 2048</pre>
<br />
This will ask you for a password. Key in a simple one and remember it.<br />
<br />
Convert the private key to an unencrypted format<br />
<br />
<pre class="brush: bash">openssl rsa -in ssl/staging/yourdomain.com.key -out ssl/staging/yourdomain.com.key.rsa</pre>
<br />
This will ask you for a password. Key in the same thing that you used in the previous step.<br />
<br />
Create the certificate signing request<br />
<br />
<pre class="brush: bash">openssl req -new -key ssl/staging/yourdomain.com.key.rsa -out ssl/staging/yourdomain.com.csr</pre>
<br />
This will ask you for a bunch of fields. Enter *.yourdomain.com when it asks for Common Name (or FQDN). The fields after that can be left blank by just hitting return (Enter) key.<br />
<br />
Sign the certificate with extensions<br />
<br />
<pre class="brush: bash">openssl x509 -req -extensions v3_req -days 365 -in ssl/staging/yourdomain.com.csr -signkey ssl/staging/yourdomain.com.key.rsa -out ssl/staging/yourdomain.com.crt -extfile /etc/ssl/openssl.cnf</pre>
<br />
Note that here we specify the openssl config file as the file file containing extensions as that is where we have defined it. Probably we can put the extensions in a separate file too, but I haven't tried that. (Homework?! :P)<br />
<br />
Thats it. Now you have a self-signed wildcard subdomain certificate which is valid for your top level domain too.<br />
<br />
Despite this the first time you hit your SSL enabled website with the above generated certificate your browser will show the standard "Invalid Certificate - Untrusted" page. It is because your certificate is self-signed. You can view the errors in the "Technical Details" section.</div>
Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com15tag:blogger.com,1999:blog-375315255567275930.post-60531341607607729022013-03-05T10:08:00.001+05:302013-03-05T10:09:56.764+05:30Package installation error on Ubuntu because of MTS MBlaze package installed<div dir="ltr" style="text-align: left;" trbidi="on">
A couple of weeks ago I was trying to get the MTS MBlaze data card to work with my Ubuntu machine (A VM actually). I was happy to see that the MTS guys had provided a .deb package to be used with their data card. Installing that .deb package installed something under the name of "crossplatformui" (very misleading btw). There was probably some problem during the installation, some error thrown, but I am unable to recall that now. Despite several attempts I was not able to use the data card and I finally gave up.<br />
<br />
However, that was not the problem. It was what followed afterwards. Ever since that attempt, during every Ubuntu software update process I would encounter an error and would be presented with a huge error log. Every time this was the error :<br />
<br />
<blockquote class="tr_bq">
make -C /lib/modules/3.2.0-38-generic/build M=/usr/local/bin/ztemtApp/zteusbserial/below2.6.27 modules<br />
<br />
make[1]: Entering directory `/usr/src/linux-headers-3.2.0-38-generic'<br />
<br />
CC [M] /usr/local/bin/ztemtApp/zteusbserial/below2.6.27/usb-serial.o<br />
<br />
/usr/local/bin/ztemtApp/zteusbserial/below2.6.27/usb-serial.c:34:28: fatal error: linux/smp_lock.h: No such file or directory<br />
<br />
compilation terminated.<br />
<br />
make[2]: *** [/usr/local/bin/ztemtApp/zteusbserial/below2.6.27/usb-serial.o] Error 1<br />
<br />
make[1]: *** [_module_/usr/local/bin/ztemtApp/zteusbserial/below2.6.27] Error 2<br />
<br />
make[1]: Leaving directory `/usr/src/linux-headers-3.2.0-38-generic'<br />
<br />
make: *** [modules] Error 2<br />
<br />
dpkg: error processing crossplatformui (--configure):<br />
<br />
subprocess installed post-installation script returned error exit status 2</blockquote>
<br />
This happened during literally every update. My guess is that the "crossplatformui" package never got fully installed and was in a "to be installed" zombie state because of the error in compilation and the post-installation script. That way the package manager would try to install this and run its post-install script on every software update/installation and end up reporting a package installation error.<br />
<br />
Looking at the compile commands it was clear from the "zte" string that this was related to the internet data card software. However there was no package with that name and as I said earlier the package name "crossplatformui" is very misleading! After a little bit of looking around I found out that the "crossplatformui" package is indeed the MTS MBlaze software which is causing this problem.<br />
<br />
Immediate first instinct was to remove the package. But alas, their post-uninstall (post-remove) script also was buggy and resulted in an error. Repeated attempts to remove it or even "Completely Remove" it failed and the package just stayed there. Finally I inspected those post-install and post-uninstall scripts. Those are present at :<br />
<br />
<blockquote class="tr_bq">
/var/lib/dpkg/info/crossplatformui.postinst<br />
/var/lib/dpkg/info/crossplatformui.postrm</blockquote>
<br />
The "postrm" script was trying to kill a process, but that was failing. So I commented it out and tried to kill the process myself, but there was no such process. The next failure was because of a "-d" option being passed to the "rm" command. I could not find any documentation for such an option. So I just removed it. Finally at the end of the script I put a "exit 0" because the package manager was complaining that the post-uninstall script exited with a exit value of 1.<br />
<br />
And boy finally it was uninstalled. However these scripts still lingered around. I once again had to go to the Synaptic Package Manager and mark it for "Complete Removal" and purge it away.<br />
<br />
Now it appears that I have gotten rid of this package and all its files. Sadly there were no updates available to check if the error had gone away, but I am thinking (and hoping) it has. Will wait for the next update to find out.<br />
<br />
Here is the update "postrm" script : <a href="https://gist.github.com/brahmana/5087790">https://gist.github.com/brahmana/5087790</a> . If you are seeing the same package installation error, replacing the "postrm" with this script should do the trick. The changes are on line no : 12,14 and 44</div>
Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-16520611411665805852012-12-25T00:28:00.002+05:302012-12-25T00:45:52.539+05:30Presumed Innocent - by Scott Turow - A review<div dir="ltr" style="text-align: left;" trbidi="on">
Last week my friend Ananth Prasad, returned a bunch of my books that were with him for quite some time. Amongst them was a book that I did not remember having read. The age of the paperback was apparent from the brown color that the once white pages of the book now donned. It was a novel named "<a href="https://en.wikipedia.org/wiki/Presumed_Innocent" target="_blank">Presumed Innocent</a>" by the author "<a href="https://en.wikipedia.org/wiki/Scott_Turow" target="_blank">Scott Turow</a>".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpAYWQ8wLMDpGZ4rn_04mno4-6iLzYkxSVs-8QglttZkJY4e44bl8-kC27hrSZAypciP_lOWSF4JvWilzE4HXVyzD8aqHvBq61KZwG-n_ReeoesW7RKuuON_bu9S9AzfGrRKHv3psOBD0/s1600/Scott-Turow-Presumed-Innocent.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpAYWQ8wLMDpGZ4rn_04mno4-6iLzYkxSVs-8QglttZkJY4e44bl8-kC27hrSZAypciP_lOWSF4JvWilzE4HXVyzD8aqHvBq61KZwG-n_ReeoesW7RKuuON_bu9S9AzfGrRKHv3psOBD0/s320/Scott-Turow-Presumed-Innocent.jpg" width="209" /></a></div>
<br />
Neither the title nor the author's name ring any bell when I first saw it and that made me a little skeptical about the book. Nevertheless, I decided to try it out and I am very glad I did it. Although very old, it turns out this book was somewhat of a hit back then and has even been made into a <a href="https://en.wikipedia.org/wiki/Presumed_Innocent_%28film%29" target="_blank">movie starring Harission Ford</a>. Additionally the author is a pretty successful one with his books being translated into 20 languages.. !<br />
<br />
It was very clear from the cover page design and the title that this is about a murder. The author doesn't try to hide this fact and starts the story with the murder of a women. There is no back story, no suspense, nothing. A woman is murdered, that's it. The protagonist is introduced as the guy investigating the murder, on a special request from his boss. The pace of story telling was also OK. It was not super fast-paced like the modern military/CIA spy thrillers. But it was not boring either. I was hooked to the book for the initial few pages when the characters were introduced and the initial scene/plot is laid out. But after that the pace just drops dead and I felt like I am reading the script of one of the Hindi daily soaps that my mother, sisters and aunts watch (In case you did not know the story barely moves ahead in a week's duration in those soaps). IMHO, the initial 150 pages could probably be all dealt with in just about 40 to 50 pages. Personally I am not really a big fan of overly descriptive narrations of mundane things like walking in the woods where the walker notices the rustling of the leaves and imagines something in those sounds or the collection of vague thoughts that the protagonist has when he has hit a low point in his life, etc. If it is descriptive narration it has to be something superbly imaginative and way beyond my own imagination. That's why I find descriptive narrative appealing only when I am reading a fantasy novel. Nobody does it better than JRR Tolkien. :).<br />
<br />
Anyways coming back to "Presumed Innocent", at the end of that boring, slow paced section it is revealed that the protagonist, a character named Rusty Sabich, who was investigating the murder is actually now the accused. And then things start to get interesting. As expected, Rusty goes to the most famous defense lawyer, who undoubtedly was his arch enemy while working as a public prosecutor. Anyways, once the court room drama starts and things start to unravel it gets really gripping. At the very beginning you are given a bunch of data - some well known facts and some speculations and some extrapolated facts at that point in time. With that, and having read a bunch of John Grisham legal thrillers, I decide upon one of the characters as the murderer. As the investigation and trial proceed and more things surface, I can't help but to suspect some other character. This goes on for most part of the rest of the book. But as I proceeded I noticed that I never suspected a character for a second time. It was almost like an elimination process, bringing the reader closer to the actual murderer. After all this running around, it is revealed that my initial suspect is indeed the murderer. So that kind of saves me the "Holy Shit... !!" moment and instead leaves me a "Aah.. Damn it... I was right initially" moment. Although the ending wasn't very spectacular the journey was pretty awesome. So I guess in this case the means justify the end.. :P<br />
<br />
There are two things that I specifically liked about this book :<br />
1) The crisp and clear explanations about the legal procedures and jargon. It was interesting to know. Kind of helped me imagine myself in the story as apart of the legal system. Before reading this I did not know that the Judge played a very important role in a trial in a USA court. I always thought the Jury was the most important and the judge was only there to oversee the trial.<br />
<br />
2) The whole story, plot, dialogues, character presentation, everything appeared very close to reality and not at all very flamboyant. Although this has been made into a full length motion picture, I would prefer to see this as an episode of "<a href="https://en.wikipedia.org/wiki/Law_%26_Order" target="_blank">Law and Order</a>" (that currently airs on FOX-Crime).<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim-3jbva5GQD14Ft1aMtAhvOJhTTYe3ftSKMBbg73MY5rPC1-M43xwmztZ8kYB6ROIwl_-Racm4ESqxcGQdeSv5Sw0vLyNiPcSR17hj7XSjdbKqt-JjmPk-4wTsRllsdcgW_inz5AAx7c/s1600/presumed-innocent-dvd-cover-87.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim-3jbva5GQD14Ft1aMtAhvOJhTTYe3ftSKMBbg73MY5rPC1-M43xwmztZ8kYB6ROIwl_-Racm4ESqxcGQdeSv5Sw0vLyNiPcSR17hj7XSjdbKqt-JjmPk-4wTsRllsdcgW_inz5AAx7c/s320/presumed-innocent-dvd-cover-87.jpg" width="224" /></a></div>
<br />
The story telling is not continuous. The protagonist is not active 24x7. When its weekend and its a holiday in the court, the protagonist spends most of his time at home and his lawyer also takes a break. The story just resumes on Monday, from pretty much where it left off on the previous Friday evening. In fact after the first hearing, nothing much happens before the trial date. This is pretty much how every episode of "Law and Order" is presented. And I like it that way. Makes it appear realistic.<br />
<br />
All in all, it was a good read. In fact very good if I discount the initial slow paced part. Now I am very eager to watch this movie. Apparently the movie was also very well received. Next weekend I guess. :)</div>
Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-15490858546949809202012-06-08T01:04:00.000+05:302012-06-08T01:12:24.932+05:30ಧಾರ್ಮಿಕ ಬೋಧನೆಗಳಿಂದ ಇಹಲೋಕದ ಸಾಮಾನ್ಯ ಜೀವನಕ್ಕೆ ನೆರವು<div dir="ltr" style="text-align: left;" trbidi="on">
ನಮ್ಮ ಸನಾತನ ಧರ್ಮದ ಸಿದ್ಧಾಂತಗಳನ್ನು, ವಿಚಾರಗಳನ್ನು, ರೀತಿ-ನೀತಿಗಳನ್ನು ಸಾರಿ ಹೇಳುವ ಗ್ರಂಥಗಳು ಅನೇಕ. ಈ ಸನಾತನ ಧರ್ಮದ ಅಡಿಪಾಯಿ ಆಗಿರುವ ವೇದ-ಉಪನಿಷತ್ತುಗಳನ್ನು ಹೊರತುಪಡಿಸಿ ಇನ್ನೂ ಅನೇಕಾನೇಕ ಗ್ರಂಥಗಳು, ಮಂತ್ರಗಳು, ಸ್ತುತಿಗಳು, ಸ್ಮೃತಿಗಳೆಲ್ಲಾ ಇರುವುದು ನಮಗೆಲ್ಲರಿಗೂ ತಿಳಿದ ವಿಷಯವೇ. ನನಗೆ ಈ ಮಹಾಗ್ರಂಥಗಳಲ್ಲಿ ಸಾರಲಾಗಿರುವ ವಿಚಾರಗಳನ್ನು ತಿಳಿದುಕೊಳ್ಳುವ ಹಾಗೂ ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವ ಆಸಕ್ತಿ ಇದೆ. ಇತ್ತೀಚಿನ ಕೆಲವು ದಿನಗಳಲ್ಲಿ, ಇಂತಹ ವಿಚಾರಗಳ ಬಗ್ಗೆ ಓದಿ ಚೆನ್ನಾಗಿ ತಿಳಿದುಕೊಂಡಿರುವ ನನ್ನ ಕೆಲವು ಸ್ನೇಹಿತರ ಜೊತೆ ಒಂದಿಷ್ಟು ಚರ್ಚೆ ಮಾಡಿದೆ, ಹಾಗೂ ಕೆಲವೊಂದು ಪುಸ್ತಕಗಳನ್ನು ಓದಿದೆ ಮತ್ತೆ ಒಂದೆರಡು ಪಾಠಗಳಿಗೆ ಹೋಗಿದ್ದೆ. ಸಾಧ್ಯವಾದಲ್ಲಿ ಹಿಂದೂ ಧರ್ಮವನ್ನು ಐತಿಹಾಸಿಕ ಭೂತಕನ್ನಡಿಯಿಂದಾನೂ ನೋಡಲು ಯತ್ನಿಸುತ್ತಿದ್ದೇನೆ. <br />
<br />
ಇದುವರೆಗೆ ನನಗೆ ತಿಳಿದ ಮಟ್ಟಿಗೆ, ನಮ್ಮ ಬೋಧನೆಗಳನ್ನು ಹೀಗೆ ವಿಂಗಡಿಸಬಹುದು :<br />
(ಬಹುಷ ಎಲ್ಲ ಧರ್ಮಗಳ ಬೋಧನೆಗಳನ್ನೂ ಇದೇ ರೀತಿ ವಿಂಗಡಿಸಬಹುದು) <br />
೧. ಪದ್ಧತಿಗಳು - ದಿನನಿತ್ಯ ಮಾಡಬೇಕಾದ ಪೂಜಾದಿ ಕರ್ಮಗಳು, ಏನು ತಿನ್ನಬೇಕು, ಯಾವ್ಯಾವ ಹಬ್ಬಗಳನ್ನು ಹೇಗೆ ಅಚರಿಸಬೇಕು, ಮುಂತಾದವು<br />
೨. ಜೀವನ ನೀತಿಗಳು - ಸದಾ ಸತ್ಯವನ್ನು ನುಡಿಬೇಕು, ಬೇರೆಯವರನ್ನು ಗೌರವದಿಂದ ಕಾಣಬೇಕು, ಕಷ್ಟದಲ್ಲಿದ್ದವರಿಗೆ ಸಹಾಯ ಮಾಡಬೇಕು, ಮುಂತಾದವು<br />
೩. ಆಧ್ಯಾತ್ಮಿಕ ಅಭ್ಯಾಸ - ನಾನು ಅಂದರೆ ಯಾರು, ನಮ್ಮ ಜೀವನದ ಮೂಲ ಉದ್ದೇಶವೇನು, ಈ ವಿಶ್ವದ ಆದಿ-ಅಂತ್ಯಗಳ್ಯಾವು, ಮುಂತಾದವು<br />
<br />
ನಾನು ನೋಡಿದಹಾಗೆ ಪಾಲನೆಯಲ್ಲಿ ಈ ಮೂರು ಭಾಗಗಳು ಹೆಚ್ಚುತ್ತಿರುವ ಕಷ್ಟದ ಕ್ರಮದಲ್ಲಿವೆ. ಅದಕ್ಕಾಗಿಯೇ ಧರ್ಮಾಚರಣೆ ಮಾಡುವವರಲ್ಲಿ ಪದ್ಧತಿಗಳನ್ನು ಪಾಲಿಸುವವರು ಎಲ್ಲಕಿಂತ ಹೆಚ್ಚಿನವರು, ಜೀವನ ನೀತಿಗಳನ್ನ ತಿಳಿದವರು, ಪಾಲಿಸುವವರು ಸ್ವಲ್ಪ ಕಡಿಮೆ. ಆಧ್ಯಾತ್ಮಿಕ ವಿಚಾರಗಳನ್ನು ತಿಳಿದು, ಅದರ ಬಗ್ಗೆ ಅಭ್ಯಾಸ ಮಾಡುವವರು ಇನ್ನೂ ವಿರಳ. ಪ್ರತಿಯೊಂದು ಭಾಗವು ಮುಂದಿನ ಭಾಗಕ್ಕೆ ಹೋಗಲು ಒಂದು ಹೆಜ್ಜೆ ಅಂತಾ ನಾನು ನಂಬಿದ್ದೇನೆ. ಆದರೆ ಬಹಳಷ್ಟು ಜನರು ಇದ್ದನು ತಿಳಿಯದೆ ಬಹತೇಕ ಪದ್ಧತಿಗಳಲ್ಲೇ ನಿಂತುಬಿಟ್ಟಿದ್ದಾರೆ. ಅದರಲ್ಲೂ ಬಹುಸಂಖ್ಯಾತರು ಆ ಪದ್ಧತಿಗಳ ಹಿಂದಿರುವ ಕಾರಣಗಳನ್ನು ತಿಳಿಯೋದಿಲ್ಲಾ. ಉದಾಹರಣೆಗೆ, ಮಂತ್ರಗಳನ್ನು ಅರ್ಥ ತಿಳಿಯದೆ ಬಾಯಿಪಾಠ ಮಾಡಿ ದಿನನಿತ್ಯ ಉಚ್ಛರಿಸುವುದು. ನಾನು ಮಾಡೋದು ಇದೆ. ನಾನು ಬಾಯಿಪಾಠ ಮಾಡಿದ ಎಷ್ಟೋ ಮಂತ್ರಗಳ ಅರ್ಥ ನನಗೆ ತಿಳಿದಿಲ್ಲಾ. ಅರ್ಥವನ್ನು ಕೇಳಿದಾಗ, ಅಥವಾ ಯಾವುದೋ ಒಂದು ಪದ್ಧತಿಯ ಹಿಂದಿರುವ ಕಾರಣ ಕೇಳಿದಾಗ ಸಮಾನ್ಯವಾಗಿ ಸಿಕ್ಕ ಉತ್ತರ ಇವುಗಳಲ್ಲಿ ಯಾವುದಾದರೊಂದು ಇರ್ತಿತ್ತು :<br />
- ಯಾವುದೋ ಒಂದು ಗ್ರಂಥದಲ್ಲಿ ಅದನ್ನ ಮಾಡಬೇಕು ಅಂತ ಹೇಳಲಾಗಿದೆ.<br />
- ಈ ಮಂತ್ರ ಹೇಳೋದರಿಂದ ಪಾಪಗಳೆಲ್ಲಾ ಕೆಳದು ಮೋಕ್ಷ ಸಿಗುತ್ತದೆ.<br />
- ಇದರಿಂದ ಭಗವಂತ ಸಂತುಷ್ಟನಾಗಿ ನಿನಗೆ ಆಶೀರ್ವಾದ ಮಾಡುತ್ತಾನೆ.<br />
ಇತ್ಯಾದಿ<br />
<br />
ಆದರೆ ನನಗೆ ಅನಿಸೋದೇನಂದ್ರೆ ಈ ಬೋಧನೆಗಳು ಬರೀ ಮೋಕ್ಷ ಸಾಧನೆ ಅಲ್ಲದೆ ಇಹಲೋಕದ, ನಮ್ಮ ದಿನನಿತ್ಯದ ಜೀವನದಲ್ಲಿಯೂ ಉಪಯೋಗವಾಗುತ್ತುವೆ ಅಂತಾ. ಕೆಲವೊಂದು ಪುಸ್ತಕಗಳಲ್ಲಿ ಇದೇ ರೀತಿಯ ವಿಚಾರಗಳನ್ನು ಓದಿದ ನಂತರ ಅದು ಖಾತರಿಯೂ ಆಯಿತು. ಅದಕ್ಕೆ ಈಗ ನಾನು ಈ ಪದ್ಧತಿ ಹಾಗೂ ನೀತಿಗಳ ಹಿಂದಿರುವ ಕಾರಣ ಹಾಗು ಅರ್ಥಗಳನ್ನು ತಿಳಿಯೋಣ ಅಂತಾ ಯೋಚಿಸಿದ್ದೇನೆ. ಅದರ ಜೊತೆ ಇವುಗಳಿಂದ ಇದಲೋಕದ ಸಮಾನ್ಯ ಸಾಧನೆಗಳಿಗೆ ಏನು ಉಪಯೋಗ, ಅವುಗಳಿಂದ ನಮ್ಮ ಇಹಲೋಕದ ಜೀವನ ಹೇಗೆ ಉತ್ತಮಗೊಳ್ಳುತ್ತದೆ ಅಂತಾನೂ ತಿಳಿದುಕೊಳ್ಳುವ ಪ್ರಯತ್ನ ಮಾಡುತ್ತೇನೆ<br />
<br />
ಯೋಗಾಸನ, ಆಯುರ್ವೇದಂತಹ ಕೆಲವು ಪದ್ಧತಿಗಳ ಉಪಯೋಗ ತುಂಬಾ ಸರಳವಾಗಿಯೇ ಗೊತ್ತಾಗತ್ತೆ. ಮತ್ತೆ ಕೆಲವು ಪದ್ಧತಿಗಳ ಕಾರಣ ಅಥವಾ ಉಪಯೋಗ ತಿಳಿಯೋದು ಸ್ವಲ್ಪ ಕಷ್ಟ. ಯಾಕಂದರೆ ಅವು ಆಗಿನ ಕಾಲಕ್ಕೆ ಉಪಯುಕ್ತವಾಗಿರಬಹುದು, ಆದರೆ ಈಗ ಅದು ಕೇವಲ ಒಂದು ರೂಢಿಯಾಗಿರಬಹುದು. ಹೀಗಾಗಿ ಅ ಪದ್ಧತಿ ಈಗಿನ ಕಾಲದಲ್ಲಿ ಉಪಯುಕ್ತವಿಲ್ಲದಿರಬಹುದು. ಇನ್ನು ಕೆಲವು ಬರೀ ಒಂದು ಜೀವನದ ಶೈಲಿ ಇರಬಹುದು. ಉದಾಹರಣೆಗೆ ಮಾಂಸಹಾರಿ ಊಟ. ಇದು ಕೆಟ್ಟದ್ದು ಅಂತಾ ಖಡಾಖಂಡಿತವಾಗಿ ಹೇಳೋದಕ್ಕೆ ಆಗೋದಿಲ್ಲಾ. ಹೊರತಾಗಿ "ನಮಗೆ ಅದು ಸೇರೋದಿಲ್ಲಾ, ಅದಕ್ಕಾಗಿ ನಾವು ಅದನ್ನ ತಿನ್ನಿವುದಿಲ್ಲಾ" ಅಂತಾ ಹೇಳಬಹುದು. ಇದು ನಮ್ಮ ಜೀವನ ಶೈಲಿ ಆಗತ್ತೆ. ನನ್ನ ಪ್ರಕಾರ ಇದಕ್ಕೂ ಮೋಕ್ಷ (ಅಂತಹದೊಂದು ಇದೇ ಅಂತಾದ್ರೆ) ಸಿಗೋದಕ್ಕೆ ಏನೂ ಸಂಬಂಧವಿಲ್ಲಾ.<br />
<br />
ಇನ್ನು ನೀತಿಗಳ ಮಹತ್ವ ಹಾಗು ಪ್ರಾಮುಖ್ಯತೆ ನಾವೆಲ್ಲರು ಚಿಕ್ಕವಿರಿದ್ದಾಗಿನಿಂದಲೇ ನಾನಾ ಕಡೆ ಕೇಳುತ್ತಾ, ಓದುತ್ತಾ ಬಂದಿದ್ದೇವೆ. ಸುಮಾರು ನೀತಿಗಳನ್ನು ಧರ್ಮಾತೀತವಾಗಿ ಹೇಳಿಕೊಡಳಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಇದರ ಮಹತ್ವ ತಿಳಿಯಲು ಹೆಚ್ಚೇನು ಕಷ್ಟಪಡಬೇಕಾಗಿಲ್ಲಾ. ಅದರೆ ಇವುಗಳ ಭೌತಿಕ ಉಪಯೋಗಗಳು ಅಷ್ಟು ನೇರವಾಗಿ ತಿಳಿಯೋಗಿಲ್ಲಾ. ಸಾಮಾನ್ಯವಾಗಿ ಧಾರ್ಮಿಕ ಉಪದೇಶಗಳಲ್ಲಿ "ಕರ್ಮ" ಹಾಗೂ "ಪುನರ್ಜನ್ಮದ" ವಿಚಾರಗಳನ್ನು ತಂದು, ಅದರಮೂಲಕ ಇವುಗಳ ಪ್ರಾಮುಖ್ಯತೆ ಮತ್ತು ಉಪಯೋಗವನ್ನು ಹೇಳುತ್ತಾರೆ. ಆದರೆ ಈ ಪುನರ್ಜನ್ಮ ಮತ್ತು ಕರ್ಮದಲ್ಲಿ ಅಷ್ಟೊಂದು ನಂಬಿಕೆ ಇಲ್ಲದಿರುವ ನಾನು ಇವುಗಳಿಂದ ಈ ಜನ್ಮದಲ್ಲೇ ಉಪಯೋಗಗಳಿವೆ ಅಂತ ನಂಬಿದ್ದೇನೆ. ಈ ನೀತಿಗಳನ್ನು ಪಾಲಿಸಿದ್ದರಿಂದ ಒಳ್ಳೆಯದಾಯ್ತು ಅನ್ನುವ ನಿಜ ಸಂಗತಿಗಳ ಬಗ್ಗೆ ತಿಳಿದು ಈ ನನ್ನ ನಂಬಿಕೆಯನ್ನು ಸಧೃಢ ಮಾಡುವ ಯೋಚನೆ ಇದೆ.<br />
<br />
ಕೊನೆಯದಾಗಿ ಈ ಆಧ್ಯಾತ್ಮಿಕ ಅಭ್ಯಾಸ ಇದೆ ಅಲಾ, ಅದು ಸ್ವಲ್ಪ ಕಬ್ಬಿಣದ ಕಡ್ಲೆ ಇದ್ದಹಾಗೆ. ನನಗೆ ಅದರಲ್ಲಿರೋ ಜ್ಞಾನ ಅತ್ಯಲ್ಪ, ಹೌದೋ ಅಲ್ವೋ ಅನ್ನುವಷ್ಟು. ಇದರ ಬಗ್ಗೆ ಏನು ತಿಳಿದರೂ ಅದು ಹೊಸಾದೇ. ಹಾಗಾಗಿ ಏನು ತಿಳಿಯತ್ತೋ ಅದರ ಬಗ್ಗೆ ಬರದ್ರೆ ಆಯ್ತು ಅಂತಾ ಅನ್ಕೊಂಡಿದ್ದೇನೆ.<br />
<br />
ನೋಡೋಣ ಈ ಕೆಲಸಾ ಎಲ್ಲಿವರೆಗೆ ನಡೆಯತ್ತೆ ಅಂತಾ ಮತ್ತೆ ಕೊನೆಗೆ ನನ್ನನ್ನ ಎಲ್ಲಿ ತಂದು ನಿಲ್ಲಿಸುತ್ತೆ ಅಂತಾ.</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-45500898224185152402012-03-18T21:29:00.000+05:302012-03-18T21:29:47.239+05:30Rails cookie handling -- serialization and format<div dir="ltr" style="text-align: left;" trbidi="on">
A typical Rails cookie has this format : <b>cookie-value--signature</b> (the two dashes are literal). The "cookie-value" part is a url encoded, base64 encoded string of the binary dump (via Marshal.dump) of whatever was set in the session. The signature part is a HMAC-SHA1 digest, created using the cookie-value as the data and a secret key. This secret key is typically defined in <span style="font-family: "Courier New",Courier,monospace;">[app-root]/config/initializers/secret_token.rb</span>.<br />
<br />
Let us try and reverse engineer a session cookie for a local app that I am running. I am using Devise for authentication, which in turn uses Warden. I use the Firecookie extension to Firebug to keep track of cookies. It is pretty handy.<br />
<br />
Here is the session cookie set by Rails:<br />
<br />
<pre class="brush: ruby"># Cookie as seen in Firebug
BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZvOhNCU09OOjpPYmplY3RJZAY6CkBkYXRhWxFpVGkvaQGsaQGwaRBpAdFpCGk9aQHtaQBpAGkGSSIiJDJhJDEwJEZseHh3c293Q29LcHhneWMxODR2b08GOwBUSSIPc2Vzc2lvbl9pZAY7AEYiJTUwNDdkOTMwNDNkNGEzOTA4YTkwN2U2MDY5OGRmOTdm--51f90f7176326f61636b89ee9a1fce2a4972d24f
</pre>
<br />
As mentioned at the beginning it has two parts separated by two dashes (--).<br />
<br />
The cookie value in this case is :<br />
<br />
<pre class="brush: ruby"># The cookie-value part
BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZvOhNCU09OOjpPYmplY3RJZAY6CkBkYXRhWxFpVGkvaQGsaQGwaRBpAdFpCGk9aQHtaQBpAGkGSSIiJDJhJDEwJEZseHh3c293Q29LcHhneWMxODR2b08GOwBUSSIPc2Vzc2lvbl9pZAY7AEYiJTUwNDdkOTMwNDNkNGEzOTA4YTkwN2U2MDY5OGRmOTdm
</pre>
<br />
The signature is :
<br />
<pre class="brush: ruby">51f90f7176326f61636b89ee9a1fce2a4972d24f
</pre>
<br />
Whenever Rails gets a cookie it verifies that the cookie is not tampered with, by verifying that the HMAC-SHA1 signature of the cookie-value sent matches the signature sent. We can also do the verification ourselves here. Fire up irb and try the following :
<br />
<pre class="brush: ruby">$ irb
irb(main):003:0> cookie_str = "BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZvOhNCU09OOjpPYmplY3RJZAY6CkBkYXRhWxFpVGkvaQGsaQGwaRBpAdFpCGk9aQHtaQBpAGkGSSIiJDJhJDEwJEZseHh3c293Q29LcHhneWMxODR2b08GOwBUSSIPc2Vzc2lvbl9pZAY7AEYiJTUwNDdkOTMwNDNkNGEzOTA4YTkwN2U2MDY5OGRmOTdm"
=> "BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZvOhNCU09OOjpPYmplY3RJZAY6CkBkYXRhWxFpVGkvaQGsaQGwaRBpAdFpCGk9aQHtaQBpAGkGSSIiJDJhJDEwJEZseHh3c293Q29LcHhneWMxODR2b08GOwBUSSIPc2Vzc2lvbl9pZAY7AEYiJTUwNDdkOTMwNDNkNGEzOTA4YTkwN2U2MDY5OGRmOTdm"
# This cookie_secret comes from [app-root]/config/initializers/secret_token.rb. Obviously you need to keep this secret for your production apps.
irb(main):005:0> cookie_secret = '392cacbaac74af104375eb91324e254ba232424130e69022690aa98c1d0dfade159260588677e2859204298181385a83b923e58c4ef24bb3a40bdad9a41431b4'
=> "392cacbaac74af104375eb91324e254ba232424130e69022690aa98c1d0dfade159260588677e2859204298181385a83b923e58c4ef24bb3a40bdad9a41431b4"
irb(main):006:0> OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, cookie_secret, cookie_str)
=> "51f90f7176326f61636b89ee9a1fce2a4972d24f"
</pre>
<br />
As can be seen the HMAC-SHA1 hexdigest generated with the cookie-value matches the signature part of the cookie. Hence the cookie is not tampered with.<br />
<br />
Now that the cookie authenticity is validated, let us see what information it holds.<br />
<br />
Let us retrace the steps taken by Rails to generate this cookie value to get the value stored in the cookie. The steps taken by Rails are :<br />
<ol style="text-align: left;">
<li>session_dump = Marshal.dump(session)</li>
<li>b64_encoded_session = Base64.encode64(session_dump)</li>
<li>final_cookie_value = url_encode(b64_encoded_session)</li>
</ol>
<br />
The reverse process would be :<br />
<ol style="text-align: left;">
<li>url_decoded_cookie = CGI::unescape(cookie_value)</li>
<li>b64_decoded_session = Base64.decode64(url_decoded_cookie)</li>
<li>session = Marshal.load(b64_decoded_session)</li>
</ol>
<br />
And with a beautiful language like Ruby all these 3 steps can be done in one single line of code. Here it is :<br />
(Btw, I need to require 'mongo' because one of the values contained here is of type BSON::ObjectId which is defined in the mongo gem. Without this Marshal.load will error out)<br />
<br />
<pre class="brush: ruby">irb(main):001:0> require 'mongo'
=> true
irb(main):002:0> require 'cgi'
=> true
irb(main):003:0> cookie_str = "BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZvOhNCU09OOjpPYmplY3RJZAY6CkBkYXRhWxFpVGkvaQGsaQGwaRBpAdFpCGk9aQHtaQBpAGkGSSIiJDJhJDEwJEZseHh3c293Q29LcHhneWMxODR2b08GOwBUSSIPc2Vzc2lvbl9pZAY7AEYiJTUwNDdkOTMwNDNkNGEzOTA4YTkwN2U2MDY5OGRmOTdm"
=> "BAh7B0kiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZvOhNCU09OOjpPYmplY3RJZAY6CkBkYXRhWxFpVGkvaQGsaQGwaRBpAdFpCGk9aQHtaQBpAGkGSSIiJDJhJDEwJEZseHh3c293Q29LcHhneWMxODR2b08GOwBUSSIPc2Vzc2lvbl9pZAY7AEYiJTUwNDdkOTMwNDNkNGEzOTA4YTkwN2U2MDY5OGRmOTdm"
# Reverse engineering the cookie to get the session object
irb(main):004:0> session = Marshal.load(Base64.decode64(CGI.unescape(cookie_str)))
=> {"warden.user.user.key"=>["User", [BSON::ObjectId('4f2aacb00bd10338ed000001')], "$2a$10$FlxxwsowCoKpxgyc184voO"], "session_id"=>"5047d93043d4a3908a907e60698df97f"}
</pre>
<br />
This is the session data that the session cookie was holding. This data is subsequently used by Warden and Devise to fetch the user from the DB and do the authentication.<br />
<br />
And that is how Rails handles cookies (at least how Rails 3.0.11 does. I am not sure if things have changed in later versions)</div>Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com2tag:blogger.com,1999:blog-375315255567275930.post-81692001958170786742012-03-15T00:22:00.000+05:302012-03-15T00:22:11.468+05:30NAS and SAN explained -- with technical differences.<div dir="ltr" style="text-align: left;" trbidi="on">
Acronyms and fancy buzz words (specifically computer science related ones) have always troubled me, at times making me very angry at the person using them and in many cases leaving me in a confused state eventually. So whenever I come across such acronyms/buzz words I try to dissect them and prepare a mental visual map that I will use every time the acronym is used in the future. The acronyms for this write up are <a href="http://en.wikipedia.org/wiki/Network-attached_storage" target="_blank">NAS (Network Attached Storage)</a> and <a href="http://en.wikipedia.org/wiki/Storage_area_network" target="_blank">SAN (Storage Area Network)</a>.<br /><br />These might be very simple and obvious things for many people but I am sure I have lost quite a bit of my hair whenever someone mentioned these acronyms to me. So here is my attempt to decipher them.<br /><br />First the basics. Both of these consist of two building blocks storage and network, or to put in a less naive manner both SAN and NAS allow applications on one machine to access data present on another machine. Okay, so why two names, why two acronyms? To answer that let me just take up these two building blocks separately.<br /><br />In the simplest sense "Storage" means dealing with files stored on the hard disk attached to the system. We do that with the the APIs (or "methods" if you want to avoid the acronym) made available by the filesystem and libraries built using those methods. As an application programmer we almost never worry about how the files are actually stored on the disk. It is the responsibility of the filesystem, the kernel and the disk driver. The application always views the data stored on the disk in terms of files (used in a generic sense to refer to both files and directories) - more so as a stream of bytes. If we dig a little deeper we find that these disks are actually made available to the filesystem by the disk drivers as block devices - i.e. whenever they accept or return data they do it in quantum of blocks. A disk doesn't return you a single byte of data when you read from it. It always returns one or more blocks. From what I understand the size of a block these days is typically 4KB. Amount of data transferred to or from the disk is a multiple of this block size. Allocation of space for files is also made in terms of blocks, which some times leads to a file utilizing the last block partially (and that is why we see the difference in the actual file size and file size of disk entries).<br /><br />That's about storage. To summarize; data is made available as files by filesystem software, but the device actually makes it available as blocks.<br /><br />Network in the simplest sense is communication between two processes - running either on the same machine or on different machines. To simplify it further let's just limit to the case of communication between two processes on two different machines. Typically one of these two processes will be a server processes and the other a client process. The server process would be listening on a specified port to which the client can connect. The client can then send requests over the connection which the server will "serve", by sending back a suitable response. The format of the request and the response are specified before hand and the client and the server agree to conform to that specification. This conformance is what is called the "protocol" which the two processes (or in this case the two machines) are using for their communication. The client typically asks for some data and the server fetches it from some place and sends the requested data as response. The client doesn't know where the server is fetching the data from and the server doesn't know what the client is doing with the data. The protocol is all that matters to them.<br /><br />That's network. No summary here. <br /><br />Okay, so how do storage and network come together now? <br /><br />In the storage example the data on the hard disk (referred to as "our hard disk" henceforth) was being accessed by the applications running on the same machine (referred to as the "host machine" henceforth). Now what if applications running on a different machine (referred to as the "new machine" henceforth) want to access the data on our hard disk? Let us call this requirement as "remote data access".<br /><br />The traditional filesystem software is designed to interact with a disk that was made available to it on the local system by the disk driver and the driver is designed to handle a disk that is attached to this local system. For our "remote data access" either the filesystem software has to get smarter and start talking to the device available on our host machine or the disk driver has to become smarter and make the disk on our host machine available as a local device on the new machine. It is these two options that the two acronyms stand for. One acronym means a smarter filesystem software with the same old driver and another means a smarter driver with the same old filesystem. That's the difference between the two and the reason there are two names and two acronyms.. !<br /><br /><u><b>NAS - Network Attached Storage</b></u> -- This one has a smarter filesystem and the same old driver. In our setup, the filesystem on the "new machine" knows that the disk is on the "host machine" and every time an application requests a file (either for reading or writing) it has to contact the "host machine" over network and retrieve the file. In other words the filesystem on the "new machine" makes a request to the "host machine" - making it a client process. To accept and respond to that request there must be a server process running on the "host machine". This server process fetches the requested file from the disk (using the old driver) and sends it back to the client. The client process, which is the filesystem software, in turn makes that file available to the application that requested it. We can see that the data on the server is made available to the client as a file. <b>This is what defines NAS</b>.<br /><br />So for the filesystem software to get smart, it now needs two components - a client part used by the applications and the server part which handles the disk. There are quite a few such "smart filesystem software" out there. The most common in the UNIX/LINUX world is <a href="http://en.wikipedia.org/wiki/Network_File_System_%28protocol%29" target="_blank">NFS - Network File System</a>. The server part of NFS is named "nfsd". On the client side, the standard "mount" command is smart enough to mount drives with "nfs" filesystem type.<br /><br />Note that here the filesystem software is aware that the disk (and hence the data) is on a remote machine. This is another defining trait of NAS.<br /><br />More details are available here : <a href="http://nfs.sourceforge.net/" target="_blank">http://nfs.sourceforge.net/</a> and here : <a href="https://help.ubuntu.com/8.04/serverguide/C/network-file-system.html" target="_blank">https://help.ubuntu.com/8.04/serverguide/C/network-file-system.html</a><br /><br /><u><b>SAN - Storage Area Network</b></u> -- This one has a smarter disk driver and the same old filesystem. The disk driver on the "new machine" lies to the OS and the filesystem software that there is a disk attached to the system locally. The OS and the filesystem software believe the driver and continue to use the fake disk that the driver provided. Whenever the disk driver is asked to fetch a block (not a file, a block), it in turn sends a request to the "host machine" and retrieves that block of data - thereby becoming the client process in the setup. Accordingly there will be a server process running on the "host machine" which accepts this request, fetches the corresponding block from the actual disk and sends it back to the client. The client, which is the smart disk driver in this case, in turn passes that data to the filesystem software and eventually to the application that requested the file data. It is evident here that the data on the server was made available to the client as "blocks" and not as files. <b>This is what defines SAN</b>.<br /><br />Note that here the filesystem (and every other component apart from disk driver) is not aware that the disk (and the data) is on a remote machine. This is another defining trait of SAN.<br /><br />A very common and popular appearance of SAN these days is in the various cloud offerings. For instance the Amazon cloud offering has a service named EBS - Elastic Block Storage, which makes network storage available as locally attached disk. We can have all the regular filesystems like ext4 or xfs on top of this EBS drive.<br /><br />That's it. The two acronyms have been conquered... !</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com8tag:blogger.com,1999:blog-375315255567275930.post-14663957436166039982012-03-10T11:56:00.000+05:302012-03-10T11:56:11.413+05:30Analysis of the Duqu Trojan worm by Kaspersky Labs<div dir="ltr" style="text-align: left;" trbidi="on">
I happen to come across the discovery and research of the Duqu Trojan worm, which apparently is the successor of the notorious Stuxnet worm. There are a lot of articles to read and I am feeling a little sleepy now and I may not finish all of them and be awake to write a summary of my understanding. So instead of bookmarking all those tabs I am documenting them here with little metadata to identify what each link talks about.<br />
<br />
(Note: Yesterday night I did doze off in the course of writing this post. :P) <br />
<br />
<ol start="0" style="text-align: left;">
<li><b>The FAQ link </b>- <a href="http://www.securelist.com/en/blog/208193178/Duqu_FAQ">http://www.securelist.com/en/blog/208193178/Duqu_FAQ</a><br /><br />A standard FAQ page, good starting point if you are totally new to Duqu or Stuxnet. Also answers some noob questions. Btw, it mentions that one of the Command & Control center servers was hosted in India.. !!<br /><br /></li>
<li><b>The mystery of Duqu - Part one</b> - <a href="http://www.securelist.com/en/blog/208193182/The_Mystery_of_Duqu_Part_One">http://www.securelist.com/en/blog/208193182/The_Mystery_of_Duqu_Part_One</a><br /><br />This one provides the bird's eye view of the worm - it's components, the files involved and how they play together, comparison with Stuxnet (with a missile analogy). It also gives a chronological view of the discovery and detection of this worm. More importantly it talks about the various device drivers - signed and unsigned which were used as a disguise.<br /><br /></li>
<li><b>The Mystery of Duqu: Part Two</b> - <a href="http://www.securelist.com/en/blog/208193197/The_Mystery_of_Duqu_Part_Two">http://www.securelist.com/en/blog/208193197/The_Mystery_of_Duqu_Part_Two</a><br /><br />This one talks about the first detected real world infections that these guys detected using their cloud based Kaspersky Security Network. These were in Sudan and Iran, but no direct link to Iran's nuclear program yet. But one thing comes out - the worm was totally different on each infection. Different driver name and different checksum. In one case different size too. So the mystery actually continues.<br /><br /></li>
<li><b>The Mystery of Duqu: Part Three</b> - <a href="http://www.securelist.com/en/blog/208193206/The_Mystery_of_Duqu_Part_Three">http://www.securelist.com/en/blog/208193206/The_Mystery_of_Duqu_Part_Three</a><br /><br />A short entry which corrects a mistake made in previous post about a network attack. What's more interesting is that, this reveals the starting point of this infection - a.k.a the dropper. Turns out that it was a 0-day exploit in Microsoft Word, related to the file <b>win32k.sys</b> (CVE-2011-3402). So the infected word file was sent to specific people via email. Also each infected file is different, which means the file was crafted individually for each target.<br /><br /></li>
<li><b>The Duqu Saga Continues: Enter Mr. B. Jason and TV’s Dexter</b> - <a href="http://www.securelist.com/en/blog/208193243/The_Duqu_Saga_Continues_Enter_Mr_B_Jason_and_TVs_Dexter">http://www.securelist.com/en/blog/208193243/The_Duqu_Saga_Continues_Enter_Mr_B_Jason_and_TVs_Dexter</a><br /><br />This one gets a little technical and walks us through the modus operandi taking one of the infections mentioned in previous post. It reveals a bunch of things and confirms most of the assumptions made previously - viz : very targeted attack, dynamic modules with little to no trace on target machine, different C&C servers for different targets, etc. It also tells us how the worm authors got creative and created a font named Regular <a href="http://en.wikipedia.org/wiki/Dexter_%28TV_series%29" target="_blank">Dexter</a> and named the creator of font as <a href="http://en.wikipedia.org/wiki/Showtime_%28TV_network%29" target="_blank">Showtime Inc</a>.<br /><br />What is more interesting is the way the comments get even more creative. One comment talks about a new interpretation of a HEX string found in the trojan code - 0xAE790409. Earlier it was thought to be related to the death of Habib Elghanian <a href="http://www.blogger.com/%28http://en.wikipedia.org/wiki/Habib_Elghanian">(http://en.wikipedia.org/wiki/Habib_Elghanian</a>) like in the Stuxnet case. But the new interpretation is that : AE means "Atomic Energy" and (19)79-05-09 is the date on which USA and USSR signed the Salt 2 treaty to limiting nuclear weapons. This is wrong because SALT II was signed on June 18th 1979 - <a href="http://en.wikipedia.org/wiki/Strategic_Arms_Limitation_Talks#SALT_II">http://en.wikipedia.org/wiki/Strategic_Arms_Limitation_Talks#SALT_II</a><br /><br />Another comment interprets the sender email bjasonxxxx@xxx.com as "Bourne Jason", the ultimate spy/operative from the famous Bourne novel/movie series.<br /><br /></li>
<li><b>The Mystery of Duqu: Part Five</b> - <a href="http://www.securelist.com/en/blog/606/The_Mystery_of_Duqu_Part_Five">http://www.securelist.com/en/blog/606/The_Mystery_of_Duqu_Part_Five</a><br /><br />This one dives deep into the structure and layout of the DLL and PNF files of the trojan, the registry entry, the config files, the process it affects, etc.. It gets very technical, and requires knowledge of binary file formats and dll loading mechanism to understand it fully. The loader part is fully disected here, however the payload is still not known. They say it is some C++ code with heavy use of STL and probably a custom framework.<br /><br /></li>
<li><b>The Mystery of Duqu: Part Six (The Command and Control servers)</b> - <a href="http://www.securelist.com/en/blog/625/The_Mystery_of_Duqu_Part_Six_The_Command_and_Control_servers">http://www.securelist.com/en/blog/625/The_Mystery_of_Duqu_Part_Six_The_Command_and_Control_servers</a><br /><br />This one analyzes the command and control servers used by the Duqu trojan. This is the first post where the details of the India C&C server was mentioned. It belonged to a web hosting company named Webwerks - <a href="http://www.web-werks.com/">http://www.web-werks.com/</a> and <a href="http://www.webwerks.in/">http://www.webwerks.in/</a>. The Kaspersky guys say this was the most interesting of all the C&C servers - probably because it was the first one and also the longest serving. Unfortunately they were not able to analyze this as it was cleared off just hours before the hosting company agreed to make an image of this server. Nevertheless they analyzed two servers - one in Vietnam and another in Germany and dug a boat load of information. Final stand is that either OpenSSH 4.3 has a 0-day vulnerability or the server guys had very bad password and hackers cracked it with brute force.<br /><br /></li>
<li><b>The Mystery of the Duqu Framework</b> - <a href="http://www.securelist.com/en/blog/667/The_Mystery_of_the_Duqu_Framework">http://www.securelist.com/en/blog/667/The_Mystery_of_the_Duqu_Framework</a><br /><br />This post details the code structure of payload and tries to decipher the programming language and the framework used. Although many parts appear as standard C++ with heavy use of STL the significant portion of the main payload code appears to not have any link to the standard C runtime and does not appear to be compiled with the Microsoft Visual C++ compiler. The code uses the Win32 native API directly bypassing the runtime. This means the trojan authors used a very obscure programming language and compiler or came up with their own. The comments talk about various possibilities but few actually make sense. One commentor is very sure it is one of the big US software companies and pin points IBM as the prime suspect along with his own myriad set of proofs.<br /><br /></li>
</ol>
The bottom line is that the sponsors of the Duqu worm have deep pockets, are very organized and have very specific targets. Also different parts were probably developed by different teams, with no team knowing the full picture. This very likely means it is state sponsored. My guess is : that information will never come out.</div>Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-68923890477769785822012-02-27T01:46:00.001+05:302012-02-27T02:06:42.307+05:30Windows 7 ನಲ್ಲಿ ಕನ್ನಡ ಟೈಪ್ ಮಾಡೋದು ಹೇಗೆ? - ಒಂದು ಪಾಠ<div dir="ltr" style="text-align: left;" trbidi="on">
ನಾನು ಆನ್-ಲೈನ್ ಮಾತಾಡುವಾಗ (ಚ್ಯಾಟ್ ಮಾಡುವಾಗ) ಆದಷ್ಟು ಕನ್ನಡದಲ್ಲೇ ಮಾತಾಡ್ತೀನಿ, ಅಂದರೆ ಕನ್ನಡದಲ್ಲೇ ಟೈಪ್ ಮಾಡ್ತೀನಿ. ಇದನ್ನ ನೋಡಿದ ಸುಮಾರು ಗೆಳೆಯರು ಹೇಗೆ ಮಾಡ್ತೀಯಾ, ನಾನು ಮಾಡಬಹುದಾ ಅಂತಾ ಕೇಳ್ತಾರೆ. ಅದಕ್ಕೆ ಉತ್ತರವೇ ಈ ಲೇಖನಿ.<br />
<br />
Windows Vista ಇಂದ ಹಿಡಿದು ಕನ್ನಡ ಟೈಪ್ ಮಾಡೋದಕ್ಕೆ ಬೇಕಾಗಿದ್ದೆಲ್ಲಾ Windows ಅಲ್ಲೇ ಇದೆ. ಬೇರೆ ಏನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡೋದು ಬೇಕಾಗಿಲ್ಲಾ. ಕೇವಲ ಕನ್ನಡ ಕೀಬೋರ್ಡನ್ನ ಶುರು ಮಾಡಬೇಕು. ಅದನ್ನ ಹೇಗೆ ಮಾಡಬೇಕು ಅನ್ನೋದಕ್ಕೆ ಒಂದು ಚಿಕ್ಕ ವಿಡಿಯೋ ಮಾಡಿದೆ. ವಿಪರ್ಯಾಸ ಏನಂದ್ರೆ ಆ ವಿಡಿಯೋನಲ್ಲಿ ಧ್ವನಿ ಇಂಗ್ಲಿಷಲ್ಲಿದೆ. :( ಪರವಾಗಿಲ್ಲಾ ಜನರಿಗೆ ಗೊತ್ತಾಗಿ ಕನ್ನಡ ಟೈಪ್ ಮಾಡೋದಕ್ಕೆ ಶುರು ಮಾಡಿದ್ರೆ ಸಾಕು.<br />
<br />
ವಿಡಿಯೋ ಬೇಡಾ ಅಥವಾ ವಿಡಿಯೋ ಸರಿ ಇಲ್ಲಾ ಅನ್ನೋರಿಗೆ ಕೆಳಗೆ ಸ್ಕ್ರೀನ್-ಶಾಟ್ ಗಳೂ (screenshots) ಇವೆ. ಅದನ್ನ ನೋಡಿ, ಅದರ ಜೊತೆ ಇರೋ ವಿವರಣೆಯನ್ನ ನೋಡಿ ಕನ್ನಡ ಕೀಬೋರ್ಡ್ ಶುರು ಮಾಡಬಹುದು. ಈ ವಿವರಣೆಯನ್ನು ವಿಡಿಯೋಗಾಗಿ ಇಂಗ್ಲಿಷಲ್ಲಿ ಬರದಿದ್ದೆ. ಆಲಸಿಯಾಗಿರೋ ನಾನು ಅದನ್ನ ಹಾಗೇ ಕಾಪಿ-ಪೇಸ್ಟ್ ಮಾಡಿದ್ದೇನೆ, ಸ್ವಲ್ಪ ಎಡ್ಜೆಸ್ಟ್ ಮಾಡ್ಕೋಳಿ :)<br />
<br />
ಈ ವಿಡಿಯೋಯನ್ನ ನಾನು ಏನೂ ಶ್ರಮ ಹಾಗೂ ಖರ್ಚಿಲ್ಲದೆ Stupeflix (http://studio.stupeflix.com/) website ಅಲ್ಲಿ ಮಾಡಿದ್ದು. ಅವರಿಗೆ ತುಂಬಾ ಧನ್ಯವಾದಗಳು.<br />
<br />
ಸಿರಿಗನ್ನಡಂ ಗೆಲ್ಗೆ <br />
<br />
<span style="font-size: large;">ವಿಡಿಯೋ</span><br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/1PEe388eo4Y?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
<span style="font-size: large;">ಸ್ಕ್ರೀನ್-ಶಾಟ್ ಗಳು</span><br />
<br />
Open control panel and click on "Change Keyboard and Other input methods".<br />
If you can't see it, make sure to set the view to "Category" in the right top.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1NXiWQZ87dZ_M7VFuu0OQlWD9hRrZUUOj2y2hDpYaF8AmcQYlU-VtFy7xmSmwUAQmoHm8nV5-KEmp1iSyqtPiIvA4Iw-ePecnU5b0gxnWmeNH0A4rbnrr2JcgqV-aTDg-PNjj-6x0uqA/s1600/1-control-panel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1NXiWQZ87dZ_M7VFuu0OQlWD9hRrZUUOj2y2hDpYaF8AmcQYlU-VtFy7xmSmwUAQmoHm8nV5-KEmp1iSyqtPiIvA4Iw-ePecnU5b0gxnWmeNH0A4rbnrr2JcgqV-aTDg-PNjj-6x0uqA/s320/1-control-panel.png" width="320" /></a></div>
<br />
<br />
A new dialog pops up. Click on the "Change keyboards" button in the new dialog box.<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcI3p3bWw7_E8eEspiDqLYnu4QxmT6Jasog3GAKrUYZ7BuNxlJVnhXGF8aMz1rIVsO9RpdfsX9OjeVrCxM6erT6WM171vAe2v9nfSTIpf6I70J1DQtMLSEJc4XdySoIA6-hqJa_-86dkE/s1600/2-keyboard-n-languages-dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcI3p3bWw7_E8eEspiDqLYnu4QxmT6Jasog3GAKrUYZ7BuNxlJVnhXGF8aMz1rIVsO9RpdfsX9OjeVrCxM6erT6WM171vAe2v9nfSTIpf6I70J1DQtMLSEJc4XdySoIA6-hqJa_-86dkE/s320/2-keyboard-n-languages-dialog.png" width="279" /></a></div>
<br />
<br />
Another dialog pops up showing you the keyboards currently in use. Kannada keyboard will not be shown there yet. You will see it after adding it. Click the "Add" button.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_-izpoJ-vcwG45qUuw3MGXm_tj-Z6XVrR1Zp9B2l8iuDXk_7CNnWfl_11NL0OcKlnAvPN90zxhhi74_hni61JPy58LVuHGOdTAfGyJbnJM9aQIVfePFFr7d3i33ZSPVlvxQqCLxrz4w0/s1600/3-text-services-and-input-languages-dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_-izpoJ-vcwG45qUuw3MGXm_tj-Z6XVrR1Zp9B2l8iuDXk_7CNnWfl_11NL0OcKlnAvPN90zxhhi74_hni61JPy58LVuHGOdTAfGyJbnJM9aQIVfePFFr7d3i33ZSPVlvxQqCLxrz4w0/s320/3-text-services-and-input-languages-dialog.png" width="311" /></a></div>
<br />
<br />
A new dialog pops up with a list of all available keyboards. The keyboards are arranged in alphabetical order. You will find Kannada almost at halfway in the list. Scroll down, choose the "Kannada" under, "Kannada, India" entry, by checking the box.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBSObOeOnZwrLzT6NRCZcgDdbQn7A5Q6yE3psEjUX86VJe7bO8fKkgjHod9RG-7tZW4aoQlY9vCwWrq77zt9mf5LFv9CzsI08bViv5kEim5LMPF-lrwoR8kXoTSGtTH7iXqVwpwgTf5P8/s1600/4-add-input-language-dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBSObOeOnZwrLzT6NRCZcgDdbQn7A5Q6yE3psEjUX86VJe7bO8fKkgjHod9RG-7tZW4aoQlY9vCwWrq77zt9mf5LFv9CzsI08bViv5kEim5LMPF-lrwoR8kXoTSGtTH7iXqVwpwgTf5P8/s320/4-add-input-language-dialog.png" width="320" /></a></div>
<br />
<br />
Click "Ok" in this dialog box, and also in every other dialog that opened up in the previous steps.<br />
<br />
<br />
Now you should see a small language bar in the right bottom of your screen. Clicking on it will allow you to change the language.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo9ajEjYm2z-sbSbUv_7d9JYPXumWanTb0S8r2YyItYaNEhvD7NLiWn-Ht4WlcQcFCN418gIxRJVOJOc08WAktpuvYoKojo7UBHQoIh3MVcFkXgq2LoVfvJM_uQKQ1z_bzMDE6Hko8V8s/s1600/5-language-bar-pop-up.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo9ajEjYm2z-sbSbUv_7d9JYPXumWanTb0S8r2YyItYaNEhvD7NLiWn-Ht4WlcQcFCN418gIxRJVOJOc08WAktpuvYoKojo7UBHQoIh3MVcFkXgq2LoVfvJM_uQKQ1z_bzMDE6Hko8V8s/s1600/5-language-bar-pop-up.png" /></a></div>
<br />
<br />
<br />
Alternately you can change the keyboard language by pressing "Alt + Shift" keys together.<br />
<br />
You can start typing kannada whenever you want after changing the language.<br />
<br />
Initially, use the "On Screen Keyboard", to understand how the keys are laid out. <br />
<br />
To launch the "On Screen Keyboard", open the windows menu and type the letters "o s k".<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3d7WDeemtuB4pfpOJU4nrYRxgKNCeJpx9qCr96zH5bF-yLXZV53NfZMqS-ekTOFUtAoWUXkkmu9wu8WD787U9idWU4-bnettINc5zoeMjUHncja6nJOFIpt36qN9fZfFr6cTc5NZjto4/s1600/6-osk-launch-from-start-menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3d7WDeemtuB4pfpOJU4nrYRxgKNCeJpx9qCr96zH5bF-yLXZV53NfZMqS-ekTOFUtAoWUXkkmu9wu8WD787U9idWU4-bnettINc5zoeMjUHncja6nJOFIpt36qN9fZfFr6cTc5NZjto4/s320/6-osk-launch-from-start-menu.png" width="264" /></a></div>
<br />
<br />
The o s k dot e x e will be listed under "Programs". Click it, to launch the "On Screen Keyboard".<br />
<br />
The "On Screen Keyboard" program launches. It starts as an English keyboard, by default.<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAQHmYNmaRYF1u1ChlsVUEuYzjgAh-eo-H5tuoGL5Q8ZR2OxBSbnKx8fnJqDlzmlR7nJvfQ5HM7uDg6HOtXITKTscGQ72thOEbyRts0lejNo06VVPG2rBAdWb9hPCNrr7tThvRkp63hgo/s1600/7-osk-english.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="88" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAQHmYNmaRYF1u1ChlsVUEuYzjgAh-eo-H5tuoGL5Q8ZR2OxBSbnKx8fnJqDlzmlR7nJvfQ5HM7uDg6HOtXITKTscGQ72thOEbyRts0lejNo06VVPG2rBAdWb9hPCNrr7tThvRkp63hgo/s320/7-osk-english.png" width="320" /></a></div>
<br />
<br />
Change the language using the language bar in the right bottom or by pressing "Alt + Shift" keys together.<br />
<br />
Once you change the language, the "On Screen Keyboard" will show the "Kannada" letters.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhr0SGUbReXlnv3O5hFMMJ52a1k8fSNf9lF9-JZ7ZqnTFeMLsPPH0ki-Fcx-SkYK_u3n-dMq3Q1tLhiS1NyjOI-JiDDjCT94veXc4hzAzMGXknRPd0fwwJ27A3WB9LA6y2ELYKcdvQojE/s1600/8-kannada-keyboard-regular.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhr0SGUbReXlnv3O5hFMMJ52a1k8fSNf9lF9-JZ7ZqnTFeMLsPPH0ki-Fcx-SkYK_u3n-dMq3Q1tLhiS1NyjOI-JiDDjCT94veXc4hzAzMGXknRPd0fwwJ27A3WB9LA6y2ELYKcdvQojE/s320/8-kannada-keyboard-regular.png" width="320" /></a></div>
<br />
<br />
Take a closer look at the keyboard layout.<br />
<br />
To the left are the vowels or also known as "swaraa" and to the right are the consonants, also known as "vyanjanaa".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEko1Kxx2wU6Lqgaobfjrq-5aNrZ_aWFgJ3gLpvLsR-bgvUTs20goN3RKe8DRbqxaot4g9_sv8R0iWBKjCe55BK-T9tNlULMmANSiPhh2DmqxOY5nveM9vOQdx0DOPnsZZXbLyklZW-Yw/s1600/9-kannada-keyboard-magnified.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="123" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEko1Kxx2wU6Lqgaobfjrq-5aNrZ_aWFgJ3gLpvLsR-bgvUTs20goN3RKe8DRbqxaot4g9_sv8R0iWBKjCe55BK-T9tNlULMmANSiPhh2DmqxOY5nveM9vOQdx0DOPnsZZXbLyklZW-Yw/s320/9-kannada-keyboard-magnified.png" width="320" /></a></div>
<br />
<br />
Observe the keyboard for a little while to understand the layout.<br />
<br />
Open a notepad and start typing kannada in it with the "On Screen Keyboard". A letter is formed by the combination of a "vyanjanaa" and a "swaraa". Try out the various combinations.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIfZr1pIlIcZnJU4Hj2HGmUB3Adl55PUSpPCYMJXgSjLHMLsZQri1rEb-_JwtqoN8bC85wpDh3SeZ3XnF-lItYAVBcek-e7YGUWGn7cmXYTBPk7VINmzBfjtTW9QXxoE_NgfJBE6tXsQ4/s1600/10-kannada-typing-in-notepad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIfZr1pIlIcZnJU4Hj2HGmUB3Adl55PUSpPCYMJXgSjLHMLsZQri1rEb-_JwtqoN8bC85wpDh3SeZ3XnF-lItYAVBcek-e7YGUWGn7cmXYTBPk7VINmzBfjtTW9QXxoE_NgfJBE6tXsQ4/s1600/10-kannada-typing-in-notepad.png" /></a></div>
<br />
<br />
Once you have little familiarity with the layout, minimize the "On Screen Keyboard" and type using the real keyboard.<br />
<br />
Please be patient and practice regularly to be able to type easily. It will be difficult initially, but it will be a JOY later.<br />
<br />
Good luck!</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-47814439774223869852012-02-02T09:07:00.001+05:302012-02-02T09:07:35.062+05:30Network does not work in Ubuntu after Hibernate and Resume<div dir="ltr" style="text-align: left;" trbidi="on">
I run Ubuntu 10.04 (Lucid Lynx) in VMWare player and Ubuntu has this habit of silently hibernating when it gets a report that battery level is low. Now VMWare player doesn't do a good job in reporting the right battery status and that leads to the virtual machine just hibernating without asking me anything when I will be in the middle of something. When I restart the virtual machine and resume the system there would be no network..!! I would then close all my open applications - editors, DB, rails etc etc.. and reboot the VM. This was pain. <br />
<br />
Today I finally found a solution for this. Turns out that the problem lies with the networking module being used. In my VM I use VMWare player's vmxnet module. I just removed the module and re-added it and that worked. Just two simple commands<br />
<br />
<pre class="brush :bash">sudo modprobe -r vmxnet
sudo modprobe vmxnet
</pre>
<br />
If you are not running Ubuntu as a VM in VMWare player your network module name will be different. <span style="font-family: "Courier New",Courier,monospace;">lsmod</span> might help you find out which you are using.</div>Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-22087273276492425302012-01-21T02:53:00.000+05:302012-01-21T03:20:03.882+05:30Shortcomings of aliased field or attribute names in Mongoid - Part 1<div dir="ltr" style="text-align: left;" trbidi="on">
<blockquote class="tr_bq" style="background-color: #f9f9c5; padding: 10px;">
NOTE: <br />
<ul>
<li>The behavior and shortcomings explained below apply to Mongoid versions 2.4.0 (released on 5th Jan, 2012) and releases previous to that. A <a href="https://github.com/mongoid/mongoid/commit/2994efa12c5ffbabd4fb3d521123e94c248b0aef" target="_blank">recent commit</a> made on 10 Jan, 2012 fixes all these shortcomings.
</li>
<li>For those using the affected versions (all Rails 3.0 developers), <a href="https://gist.github.com/1649542" target="_blank">this monkey patch</a> will address the shortcomings.</li>
</ul>
</blockquote>
<br />
In my previous post I wrote about getting a <a href="http://techbrahmana.blogspot.com/2012/01/getting-list-of-aliased-keyattribute.html">list of aliased field names</a>. From that post it might be evident that dealing with aliased field names is not that straight forward in Mongoid. I am using Mongoid v2.2.4 which the latest version working with Rails 3.0. Mongoid v2.3 and later require ActiveModel 3.1 and hence Rails 3.1.<br />
<br />
Anyways, aliased field names have these shortcomings :<br />
<ol style="text-align: left;">
<li>Accessor methods are defined only with the aliased names and not the actual field names.</li>
<li>Dirty attribute tracking methods are not defined for the aliased names.</li>
<li><span style="font-family: "Courier New",Courier,monospace;">attr_protected</span>, if used, should be used with both short and long forms of field names.</li>
</ol>
Writing about all three in a single post would result in an awfully long post. So I will put details about each of these in their own posts, starting with the first one in this post.<br />
<br />
<h3>
Accessor methods are defined only with the aliased names and not the actual field names.
</h3>
<br />
Consider the following model definition:
<br />
<pre class="brush: ruby">class User
include Mongoid::Document
field :fn, as: :first_name
field :ln, as: :last_name
end
</pre>
I would have expected the additional accessor methods names<span style="font-family: "Courier New",Courier,monospace;"> 'first_name', 'first_name=', 'last_name' and 'last_name=' </span> to be simple wrapper methods which just forward the calls to the original accessor methods :- <span style="font-family: "Courier New",Courier,monospace;">'fn', 'fn=', 'ln' and 'ln='</span>. But Mongoid just doesn't create the shorter form of the accessor methods at all.
<br />
<pre class="brush: ruby">user = User.new
user.respond_to?(:fn) # Returns false
user.respond_to?(:ln) # Returns false
user.respond_to?(:first_name) # Returns true
user.respond_to?(:last_name) # Returns true
</pre>
This doesn't appear like a problem at first sight because an application developer would use the long form of the methods in the application code. Trouble begins in the dirty tracking methods which use the actual attribute name and consequently the shorter form of field names. Take a look at these parts of Mongoid and ActiveModel:
<br />
<ul>
<li>Definition of setter method for any attribute - <a href="https://github.com/mongoid/mongoid/blob/192bb67ba945af28d4f3792540d40e8d140d48c1/lib/mongoid/fields.rb#L315" target="_blank">Github link for v2.2.4</a>
<pre class="brush: ruby">define_method("#{meth}=") do |value|
write_attribute(name, value)
end
</pre>
Notice that the field name (i.e. the short form) is being passed to <span style="font-family: "Courier New",Courier,monospace;">write_attribute</span>, which eventually gets passed to ActiveModel's dirty attribute tracking method <span style="font-family: "Courier New",Courier,monospace;">attribute_will_change!</span></li>
<br />
<li>Definition of the ActiveModel method : <span style="font-family: "Courier New",Courier,monospace;">attribute_will_change! </span>-- <a href="https://github.com/rails/rails/blob/v3.0.11/activemodel/lib/active_model/dirty.rb#L153" target="_blank">Githib link for v3.0.11</a>
<pre class="brush: ruby">def attribute_will_change!(attr)
begin
value = __send__(attr)
value = value.duplicable? ? value.clone : value
rescue TypeError, NoMethodError
end
changed_attributes[attr] = value
end
</pre>
</li>
</ul>
On line no : 3 the method with the same name as that of the attribute's short name is invoked with <span style="font-family: "Courier New",Courier,monospace;">__send__</span>. Since Mongoid doesn't define such methods this mostly results in NoMethodError which is caught and swallowed and nothing happens. This is comparatively harmless. But if at all a method with the same already exists, then that method gets called and a lot of unwanted things can happen. In the case of the User model above, the '<span style="font-family: "Courier New",Courier,monospace;">fn</span>' just results in NoMethodError, where as the '<span style="font-family: "Courier New",Courier,monospace;">ln</span>' field could result in any of the following methods :<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Object.ln</span><br />
<span style="font-family: "Courier New",Courier,monospace;">FileUtils.ln</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Rake::DSL.ln</span><br />
<br />
That could result in pretty nasty errors about these ln methods and you wouldn't even know why these are being called!. Now whether it is a good practice to name your attributes in a way that clash with already defined methods is a totally different thing. But just remember that the cause of a weird error is probably aliasing.
</div>Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-39571003641444197302012-01-18T04:36:00.000+05:302012-01-18T04:44:13.535+05:30Getting the list of aliased key/attribute names from a Mongoid model<div dir="ltr" style="text-align: left;" trbidi="on">
At some point today when I was writing some model specs for one of my Mongoid models, I required the list of all of the attribute/key names. Mongoid provides a handy "<span style="font-family: "Courier New",Courier,monospace;">fields</span>" method for this, which returns an hash of key names and <span style="font-family: "Courier New",Courier,monospace;">Mongoid::Fields::Serializable</span> object pairs. Getting the list of names from that was easy :<span style="font-family: "Courier New",Courier,monospace;"> Model.fields.keys</span>.<br />
<br />
This gives the list of the actual key names. The actual key names, in my case, are very short strings (1 to 3 characters) and I have long aliases for those in my models. What I eventually realized was that I wanted the list of the longer aliased names. Looking around the mongoid code did not give me any direct method. Turns out that the aliased names result in nothing more than a few additional 'wrapper' methods (like the accessors, dirty methods, etc) and there is no table/hash kind of thing maintained anywhere to give the mapping between the actual key name and the aliased ones. So my current guess is that the list of these aliased names is not available directly anywhere.<br />
<br />
So I came up with this hackish way of getting that list of aliased names.<br />
<br />
<pre class="brush: ruby">p = Post.new
actual_field_names = p.fields.keys
all_field_names = p.methods.collect { |m| m.to_s.match(/_changed\?$/).try(:pre_match) }
.select { |e| e }
aliased_field_names = all_field_names - actual_field_names
</pre>
<br />
As mentioned earlier, this is pretty hackish. If you know of a straight forward way, do let me know.<br />
<br />
Note : I eventually found out that I did not actually need this list of aliased names. I did not use this in my project. Nevertheless it works just fine.</div>Brahmana (Srirang)http://www.blogger.com/profile/10677241604486586254noreply@blogger.com1tag:blogger.com,1999:blog-375315255567275930.post-1354705526388290582012-01-01T11:48:00.001+05:302012-01-01T11:48:45.524+05:30MongoDB concurrency - Global write lock and yielding locks<div dir="ltr" style="text-align: left;" trbidi="on">
There has been lot of hue and cry about MongoDB's global write lock. Quite a few people have said (in blog posts, mailing lists etc) that this design ties down MongoDB to a great extent in terms of performance. I too was surprised (actually shocked) when I first read that the whole DB is locked whenever a write happens - i.e a create or update. I can't even read a different document during this time. It did not make any sense to me initially. Previous to this revelation I was very pleased to see MongoDB not having transactions and always thought about that feature as a tool which avoided locking the DB when running expensive transactions. However this global lock sent me wondering whether MongoDB is worth using at all.. !! I was under the assumption that the art of "record level locking" had been mastered by the
database developers. This made MongoDB look like a tool of stone age. <br />
<br />
Well I was wrong. Turns out that "Record level locking" is not that easy (and the reasons for that warrant a different post altogether) and from what I understand MongoDB has no plans of implementing such a thing in the near future. However this doesn't mean the DB will be tied up for long durations (long on some scale) for every write operation. The reason is that MongoDB is designed and implemented in ways different than other databases and there are mechanisms in place to avoid delays to a large extent. Here are a couple of things to keep in mind :<br />
<br />
MongoDB uses memory mapped files to access it's DB files. So a considerable chunk of your data resides in the RAM and hence results in fast access - fast read all the time and very fast write without <a href="http://www.mongodb.org/display/DOCS/Journaling" target="_blank">journaling</a> and pretty fast write with journaling. This means that for several regular operations MongoDB will not hit the disk before sending the response at all - including write operations. So the global lock that is applied exists only for the duration of time needed to update the record in the RAM. This is orders of magnitude faster than writing to the disk. So the DB is locked for a very tiny amount of time. This global lock is after all not as bad as it sounds at first.<br />
<br />
But then the entire database cannot be in RAM. Only a part of it (often referred to as working set) is in RAM. When a record not present in RAM is requested/updated MongoDB hits the disk. Oh no, wait.. so does that mean the DB is locked while Mongo tries read/write that (slow) disk? Definitely not. This is where the "yield" feature comes in. Since 2.0 MongoDB will yield the lock if it is hitting the disk. This means that once Mongo realizes it is going for the disk, it sort of temporarily releases the lock until the data from disk is loaded and available in RAM.<br />
<br />
Although I still prefer record level locking in MongoDB, these two above mentioned features are sufficient to reinstate my respect and love for MongoDB. :)</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-25454508088129673342011-12-12T03:10:00.001+05:302011-12-12T06:47:29.039+05:30Startup Saturday Bangalore - December-2011 - Should you spend your money or someone else's?<div dir="ltr" style="text-align: left;" trbidi="on">
After hearing a lot about <a href="http://headstart.in/">Headstart.in</a> and <a href="http://startupsaturday.headstart.in/" target="_blank">Startup Saturdays</a> and after having read a lot about startup communities and their importance in various blogs (<a href="http://www.paulgraham.com/hubs.html" target="_blank">including Paul Graham's</a>) I attended this month's Bangalore edition of Startup Saturday. I must say that I totally loved it and am really sad that I did not attend it earlier. Well, better late than never.<br />
<br />
This edition's broad focus was on funding and equity distribution. Here is a link to the <a href="http://startupsaturday.headstart.in/event.php?eid=177" target="_blank">event description page</a>. We had <a href="http://www.telibrahma.com/telibrahma/company" target="_blank">Suresh</a> from <a href="http://www.telibrahma.com/" target="_blank">Telibrahma</a> and <a href="http://www.sloka.in/about-us/management-team" target="_blank">Sujai</a> from <a href="http://www.sloka.in/" target="_blank">Sloka Telecom</a> sharing their experience and some of the nitty-gritties associated with securing funding for your startup and managing equity and stakes. Here are a few things that I grasped and managed to remember.<br />
<br />
For those in a hurry, there is a tl;dr section at the bottom. I know your time is precious and I blabber a lot. :) <br />
<ol style="text-align: left;">
<li><b>Start your company with an exit clause in the agreement with your partner<br /><br /></b>Suresh pretty much started the discussion with this point. When you start your company decide first off what the founders are going to do with their share of equity in case they leave the company. You might be thinking that it is such a negative thing to start with, but Suresh made it clear enough that it is essential, irrespective it's positive or negative influence. The rationale is that things look very good at the beginning and everyone is absolutely positive and hopeful, but it is very likely that not all founders will share the same amount of enthusiasm and hope as time passes by. Reasons could be various, but it can just happen. One of the founders might just want to move out at some point. Such an event shouldn't derail your company/organization. This is why it is better (and pretty much essential) to have an exit clause in the initial agreement. The specifics can be anything. You might choose to compensate the person moving out based on the amount of years he/she has put in or the initial investment they came in with or whatever. Just be sure that it is there in black and white in an unambiguous way. You do not want a member of your founding team <a href="http://www.ndtv.com/article/india/karnataka-chief-minister-yeddyurappa-agrees-to-quit-after-bjps-unanimous-order-122718" target="_blank">going out</a> <a href="http://news.in.msn.com/national/article.aspx?ucsort=2&cp-documentid=5326525" target="_blank">shouting</a>, bringing the morale of the team down, now do you?<br /><br /></li>
<li><b>Do not hesitate to talk about money and stake. Finalize it ASAP<br /><br /></b>This is sort of a follow-up point to the previous one. Whenever a startup is formed by a group of people, which is very common, specifically by a group of friends, which is even more common, there can be some stigma about discussions around stake and percentages. There might be one or two members who feel that talking about such things very early is a sign of lack of trust and is not really a good way to start with. As Sujai and Suresh said, this isn't really so. It is always better to finalize these matters at the earliest, no matter how delicate they are. In fact you should do it at the earliest because they are delicate. You do not want to be dealing with them in a crunch situation, which might just worsen the case. So act mature and deal with it, of course in a fair way.<br /><br /></li>
<li><b>Term sheets are very flexible. Use it to achieve a common ground during negotiation<br /><br /></b>It is very common to come up with valuations vastly different from the investor's when you are trying to raise money. In some cases it can be so vast that the middle ground itself is unacceptably far for both the entrepreneur and the investor. For example when raising very early stage funding from an angel investor you might value your company at $1 Million, because you think your idea is kickass and totally innovative and you seem to have a perfect plan. OTOH, the investor values your company at nothing more than $100K, because all you have is an idea and your own expertise/experience. The average of the two numbers is just not acceptable to both of you. But both you and the investor might like each other (the frequency just matches) and you want money and the investor wants to invest. In such a case you can use the term sheet to achieve middle ground. You can tell the investor to give you money at your valuation, and say after a year or two when you go for a bigger round of funding with $5M or $10M valuation, the angel investor will get some perk - like he gets shares at a discount or he gets an outright payout (like interest or dividend on what he invests now) or whatever. But if you fail to reach that goal within the stipulated time, then the angel investor will get some more stake to match "his" initial valuation. <br /><br />This is just an example and terms can be anything that you can negotiate for. The idea is that if there is a good match between the entrepreneur and the investor, then the deal should not fall through just because of differences in valuation. This of course doesn't mean that you should accept money at any crappy valuation that an angel or a VC is throwing at you. See the next point. Also you should not expect investors to put in money at insane valuations just because you got a very innovative product. Be reasonable.<br /><br />If you are new to Term Sheets check out <a href="http://www.feld.com/wp/archives/2011/11/using-veri-to-understand-term-sheets.html" target="_blank">this</a> and <a href="http://www.veri.com/t/understanding-term-sheets/1301" target="_blank">this</a>. <br /><br /></li>
<li><b> It's a good deal only when both parties are happy<br /><br /></b>Often entrepreneurs think that investors are out there to squeeze everything they can from the founders and that one has to be very cautious when dealing with investors. What both Suresh and Sujai said was that a good investor will make sure that the founders will get a good deal, even in cases when all that the founders (typically engineers) know about finance is addition and subtraction. The reason is that, if the VC "tricks" the founders into shelling out a lot of equity for a small sum of money, it is very likely that the founders will lose the motivation to keep going. If all that they own (collectively) is something like 20% or 30% they will soon feel like they are slogging for the investor and there is nothing in there for themselves. This is the worst thing that can happen to a startup. If the founders themselves are not motivated enough, the startup will come to a screeching halt in no time. Alternately, another "good" investor might come along and woo the founders away to form a new company where they really have sizable stake and actually feel like "founders". So both entrepreneurs and investors should go home happy after a deal. If you are not happy with the deal it's better you walk away. Sujai even went on to say that it's better not to deal with investors whom you don't think you can work with without two strips of aspirin, even when the valuation is close to what you want or even more. It's just not worth the headache it will eventually generate. But if your company is dying and you are absolutely in need of cash, then it's a different situation altogether.<br /><br />This piece of wisdom also applies to equity that is given to the co-founders and early employees. Do not be very stingy is handing out equity. Remember that when you get a co-founder or when you hire someone, you and that person are making a deal too. And like every other deal this one should keep both the parties happy. If you do not give sufficient equity to keep them motivated, eventually they will have no reason to stay with you. They will all be working their asses off. You better keep them motivated. Otherwise someone nicer will come along and take them away to their company with a much better offer. Also investors do consider the equity distribution amongst co-founders and the initial team. If they find it highly distorted they will very likely refrain from investing because they are not confident that the team will stick around. This doesn't mean you give out equity like a charity program. It is good (and often necessary) that you as the founder will retain a majority stake. This brings me to the next point.<br /><br /></li>
<li><b>There should be a LEADER -- a MAJORITY STAKE HOLDER<br /><br /></b>As mentioned in the second point, when a group of friends join hands to start a company, the general tendency is to distribute equity equally among themselves. For example 4 friends starting a company might end up owning 25% each. This is very very bad. Both Suresh and Sujai strongly emphasized that there should be a leader (call him/her a CEO or MD or anything) who is also a Majority Stake Holder. It is very common to hit deadlocks, get into conflicts, during product design or in cases when you have <a href="http://www.startuplessonslearned.com/2009/06/pivot-dont-jump-to-new-vision.html" target="_blank">to pivot</a> and it becomes essential that there exists a leader who can resolve these conflicts and take a decision. In the absence of a leader the conflict will persist delaying the process or decision making. Time being an essence in startups, such leader-less scenarios lead to the death of a startup, often with the people involved getting upset with each other. Some might say that they prefer to have a "flat hierarchy" and will take collective decisions. It all sounds good, but doesn't really work always. A leader doesn't mean a dictator. The leader will still invariably consult his team before taking any significant decision. Having a leader also makes interaction with outside parties easier. A customer or an investor doesn't have to deal with 3 to 4 people for the same thing. Doing the same work repeatedly is no fun for anyone (unless you are a body building freak).<br /><br /></li>
<li><b>LEADER should act like one. He/She is the face of the company<br /><br /></b>This is something that my manager (also a very good friend and a mentor) at a previous company explained to me when I said I want to go out and join a friend in his start up venture. <br />Being a leader is not just about holding a title or exercising your superiority during a discussion/conflict. The leader will be the face of the company and is as such thought of as a reflection of the company. When investors put in their money, they invest not just in the idea or the product, but also in the people and very specifically the leader. They expect the leader to steer the company towards success. It is the leader's ability that they trust. Consequently any wrong doing on the leader's part will reflect very poorly on the whole company. Integrity is of utmost importance. For example one might feel a sense of achievement in "tricking" investors with false promises or similar things. But it will create a permanent dent in the image of the company (and also that person). Also, the leader should command respect within the company by virtue of his/her actions and thought process. So choose a wise leader, think a lot before choosing one, especially when you are choosing yourself. (Yeah, the last line is my addition :) )<br /><br /></li>
<li><b> You will miss your first deadline - Learn to live with it<br /><br /></b>Almost every startup start's with a "perfect plan" and with the hope and confidence of "perfect execution" of that plan. You look at the money you have and you feel that you are good to go for a year. Then you look at the idea, discuss about the product, make a plan for the implementation, possibly meet potential customers and promise them a delivery date (mostly a very aggressive target). You then foresee that you are going to get money in 8 months or you will be able to raise good amount of money from investors in not more than 10 months. Isn't that fantastic? You are so safe..! <br /><br />But this rarely, if not never, happens in reality. Sujai spelled it out that each and everyone of us is going to miss our first deadline/target. So one has to learn to live with it, get over it and continue working towards the target. This doesn't mean that we all plan so badly. It's just that the startup environment is so dynamic. There is a lot of flux and uncertainty. It's better to come mentally prepared for shocks and than to come in overly optimistic and get bogged down by these unexpected setbacks.</li>
</ol>
<span style="font-size: large;">tl;dr</span><br />
<span style="font-size: large;"> </span> Here are the main points. If you find something interesting you can go back up and read it in full.<br />
<ol style="text-align: left;">
<li>Start your company with an exit clause in the agreement with your partner</li>
<li>Do not hesitate to talk about money and stake. Finalize it ASAP</li>
<li>Term sheets are very flexible. Use it to achieve a common ground during negotiation</li>
<li>It's a good deal only when both parties are happy</li>
<li>There should be a LEADER -- a MAJORITY STAKE HOLDER</li>
<li>LEADER should act like one. He/She is the face of the company</li>
<li>You will miss your first deadline - Learn to live with it</li>
</ol>
This discussion was followed by a product demo by Saptarshi from <a href="http://quikast.com/" target="_blank">Quikast</a>. They are building some cool stuff. I wish them all the best. </div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-76606962098269745192011-11-27T00:25:00.001+05:302011-11-27T03:43:44.020+05:30A testimonial to one of the best mentors I have had<div dir="ltr" style="text-align: left;" trbidi="on">
I have previously written about my internship at IBM in <a href="http://techbrahmana.blogspot.com/2007/06/ibm-internship-prolouge.html" target="_blank">this post</a> and <a href="http://techbrahmana.blogspot.com/2007/07/ibm-internship-part-i-interview.html" target="_blank">this post</a>. The first post makes it pretty clear that the internship was a very productive (very likely most productive) part of my engineering student life. The second post briefly talks about Gautham Pai as being my guru. Both are very much true and I am thankful to Gautham for having provided me the opportunity to be on the Eclifox team. Although I have expressed my gratitude to Gautham a few times, I never really wrote it down anywhere, neither in my blog nor on any social n/w site. A few months ago Gautham started his own company <a href="http://www.jnaapti.com/" target="_blank">Jnaapti</a>, which is a technical skill development company. Basically he is doing what he is very good at, i.e. bringing the best out of anyone willing to learn and succeed. As part of the company operations he conducts training sessions for various corporate clients and also mentors engineering students helping them understand their subjects better using some useful project as a means of teaching. He is experimenting with various educational methodologies and different ways to teach/mentor students remotely. I am very confident that his efforts are going to change the landscape of computer science engineering education vastly. Having been mentored and guided by Gautham at various points, I thought now would be a good time to pen down a testimonial and finally put that gratitude in words. So here it goes :<br />
<br />
<br />
<blockquote class="tr_bq">
Every software engineer who has been in the industry, even for a small amount of
time, surely knows the gap between academic teaching and the industry
requirements and the initial uphill task of coping up when a fresh
engineering graduate joins any company. It would not have been different
for me, if not for Gautham's guidance as my senior at college and my
mentor at IBM during my internship. With Gautham's mentoring, the
internship was probably one of the most productive spans in my 4 years
of engineering studies and also the one packed with maximum learning.
Additionally it opened up a number of opportunities for me which I
previously did not even know existed - like my participation in <a href="http://techbrahmana.blogspot.com/2007/06/my-gsoc-2007-story.html" target="_blank">Google Summer code</a> and later <a href="http://techbrahmana.blogspot.com/2007/10/first-check-in-of-my-code-into-mozilla_25.html" target="_blank">being with the Mozilla</a> <a href="https://wiki.mozilla.org/User:Brahmana" target="_blank">community for quite some time</a> and many others.<br />
<br />
Traits like general intelligence, theoretical understanding of the
subjects and the ability to solve problems are undoubtedly necessary,
but not sufficient. An engineer should be able to think not just about
the next line of the code that he is going to write but also think about
product that he is building or helping build. He should also know that
any technology is just a tool to get the work done and not something
that limits you. That way you just pick any new tool that you come
across and find useful or necessary for the job. This also means you
keep up with the latest happenings in the tech world via blogs,
articles, mailing lists etc. Above all the zeal to do more, to come up
with new ideas, to start executing those ideas and the persistence to
see them through, in the course carefully managing a team as a leader,
are what will make an engineer truly successful.<br />
<br />
I, of course, did not realize or understand all this during my
internship. These were not handed out to me in bulleted list of To-Dos.
Rather it was all nicely baked into the project that I (with a few
friends) carried out and I was set on the right path without any
additional effort. More than that, all of this was demonstrated to us in
practice by Gautham himself and some of it just rubbed off on me, making
me a much better problem solver, much better product developer, much
better ENGINEER, than I would have been otherwise. Now when I look back
at my internship days and my days as an engineer after that, I clearly
see the impact and how much it has helped. That's Gautham and his way of
mentoring. Thank you Gautham for letting me be part of the Eclifox team
and for your guidance till date and the future too. :). (For the
readers : Eclifox was what we built during our internship - <a href="http://buzypi.in/2007/10/11/eclifox-bringing-eclipse-to-the-browser/" target="_blank">http://buzypi.in/2007/10/11/<wbr></wbr>eclifox-bringing-eclipse-to-<wbr></wbr>the-browser/</a> and I am very proud of it.)</blockquote>
In case you are wondering where did all of this finally land me, here is my <a href="http://www.linkedin.com/in/srirang" target="_blank">linkedIn profile</a>. :)<br />
Keep up the great work Gautham. Wish you all the success and happiness.</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-63019201368398911402011-11-25T09:19:00.001+05:302011-11-25T09:57:39.448+05:30Transactions - both single node and distributed - are hardwired in Windows - since Win 95<div dir="ltr" style="text-align: left;" trbidi="on">
Transactions or "Atomic Transactions" to be precise, are very well known to anyone who has worked with databases. With the recent advent of NoSQL databases and the CAP theorem being used/abused by anyone and everyone, words like "consistency" and "transactional model" have become run-of-the-mill jargon. But what is actually interesting is that the concept of transactions or transactional model goes beyond our typical RDBMS. Things get even more challenging when we try to achieve transactions in a distributed system. Because transactions inherently lock the resource(s)/data they are operating on until the transaction completes, those resources can become inaccessible altogether very easily in a distributed setup if one of the node fails or if there is some problem with the network or any such thing, there by increasing the complexity of implementing distributed transactions by many folds compared to transactions on a single node.<br />
<br />
Today I was trying to figure out if there is a way to "simulate" (albeit it will be very crude) some sort of transactions in my application which uses MongoDB (which doesn't support transactions by design - to avoid the locking mentioned above, although ironically there is a global write lock..!!). Searching on the internet lead me to <a href="http://ayende.com/blog/23553/yoursquo-ll-pry-transactions-from-my-dead-cold-broken-hands" target="_blank">this blog of a Raven DB developer</a>. The author there mentions that RavenDB supports both sharding and transactions, which means it has implemented distributed transaction support. At first read I was pretty impressed (this was the first time I had heard about RavenDB). Before I could ask the author about the implementation details I saw a comment in which the author had mentioned that they use DTC (which again was a new thing). Turns out DTC, Distributed Transaction Controller, is a service that is baked right in the Windows OS itself, that too dating back to the Windows 95 days (wow.. now I am impressed with Windows..!). Here is <a href="http://msdn.microsoft.com/en-us/library/ms679938%28v=VS.85%29.aspx" target="_blank">the MSDN article</a> describing the service.<br />
<br />
The MSDN article clearly explains the basics of distributed transactions and how it is modeled. What is worth noting is that, by abstracting out the code for carrying out distributed transactions as a service, multiple resource managers (like different databases, queue servers, file servers/managers, etc..) can all interact together in a single transaction. For example, lets say that you have web application where in a client request results in a job being picked up from a queue for processing and simultaneously you update the status of the job in a DB and also create a new file associated with the start of the job. Very evidently all the three resource managers and the web application itself can be (very likely will be) on different nodes. With something like DTC you can easily create a new transaction, send across a commit message and you will get a success notification only if all three actions were successful or else none of the actions go through. Of course, this is possible only if all the three resource managers involved here adhere to the Microsoft's DTC specification and provide the necessary interface to work with it.<br />
<br />
The previous example might make DTC appear like this Jason Bourne kind of super dude who can take care of all the heavy lifting and also do it very efficiently. But remember even Bourne gets shot at and also loses his girl. So DTC is not fully immune to problems either. Here is one <a href="http://blog.jonathanoliver.com/2011/04/my-beef-with-msdtc-and-two-phase-commits/" target="_blank">blog post titled "My beef with MSDTC and two phase commits"</a>. It is definitely worth reading. Note that my impression about DTC is purely based on reading the documentation. I have not written a single line of code using DTC.</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com1tag:blogger.com,1999:blog-375315255567275930.post-31192887978455562952011-11-16T00:45:00.001+05:302011-11-16T02:01:26.245+05:30Microsoft's Virtual Wifi adapter ( or virtual wifi card) -- cool technology<div dir="ltr" style="text-align: left;" trbidi="on">
I wasn't aware of the very interesting research on Virtual Wifi Adapters that Microsoft guys have been carrying out. Apparently they have been doing it for quite some time now. What this research group is trying to do is basically allow us to have an unlimited number of "virtual" wireless cards on our computers, each connecting to a different wireless connection, and all of it using just a single physical card. That is some awesome stuff.. !<br />
<br />
A couple of days ago I opened up the Dell Support Center tool on my laptop and it popped up a message saying a device on my system is in the disabled state. I was pretty startled to see that, as pretty much every device on my laptop is used by me daily. On clicking the message it told me that the disabled device is "Microsoft Viritual Wifi Miniport". That did not make any sense to me. I had absolutely no clue about this device.<br />
<br />
Searching the internet led me to <a href="http://msdn.microsoft.com/en-us/library/dd815243%28VS.85%29.aspx">this Microsoft page</a> (along with several others, of course) which gave me a fair idea of what this device might be, but nothing concrete. It was this <a href="http://www.istartedsomething.com/20090516/windows-7-native-virtual-wifi-technology-microsoft-research/">fine article on istartedsomething.com</a> that clearly explained what this is all about. In the same article the author tells us that Microsoft has been carrying out research in this regard for a few years now. But nothing was given to end users until Windows 7 baked in this wifi card virtualization natively. And not just that, all WiFi card providers are expected to add support for this virtualization in their drivers if they want their drivers to be properly signed digitally and recognized by Windows during installation. I say that is "Wicked cool".. :)<br />
<br />
About the technology itself, it can be described as a way to make "software copies" of your Wireless card and use those copies to "connect to multiple networks simultaneously". Although research prototypes can apparently create any number of virtual devices over the single actual hardware device, Windows 7 limits it to just one copy/virtual device.<br />
<br />
This whole research is doubly fascinating.<br />
<br />
First because the applications of this research work are very interesting. One such application is explained in the article mentioned above. It talks about being able to connect to an existing wireless access point with your laptop and at the same time making your laptop a wireless access point in itself. It means, if someone is far from the actual access point and your laptop happens to be closer, he/she can connect to your laptop instead and your laptop will forward their connections to the actual wireless access point. Of course, this can only happen when the two laptops involved are in the same security/trust group. I wouldn't go on and connect via some random stranger's laptop. It is like letting that person look at all the data coming in and going out of your computer over the internet (or network in general). Despite such caveats, this is very much a practical use case. May be you wouldn't use it to be a hop in the network (or more like a virtual signal booster), but you may use it to make P2P/direct connections with another laptop close by for sharing files instead of doing over the wireless LAN. Or, if access to wireless network is possible only after you authenticate via certificate (like in a corporate setup) and the certificates can be put only one of your laptops (the official company laptop), the connection sharing will indeed come in handy.<br />
<br />
Secondly, and more importantly, the complexities associated with this are lot and that makes it all the more exciting. If we delve a little deeper into what this virtual adapter is and how it works, we will see that it is actually a piece of software sitting between the actual device driver and the rest of the network stack (i.e. all above the MAC layer in the OSI model). This little piece of software is supposed to appear as one or more "devices" to the OS and hence it invariably has to have its own device driver. That is the "Virtual WiFi Filter" driver or VWifi driver. This VWifi driver tells the OS that there are multiple wireless cards and the OS then allows the user to connect to different available wireless connections via these virtual cards. But note that all this time, there is only one physical card and hence at any given point in time that one physical card can be connected to (or can communicate with) only one wireless network. It is the job of the virtual adapter software to cycle over all the virtual wireless cards and service the network requests made through them using the one physical card, in a time shared manner all the while keeping it transparent to the user. Although it sounds very similar to the kernel's process scheduling which makes use of the single processor in a time shared manner, this is actually somewhat different because of the way wireless networks work.<br />
<br />
Note that different wireless networks behave differently. They might be operating at different frequencies, they might be having different authentication/encryption schemes, the bandwidth might be different and probably many other factors that I can't think of right now. So every time the actual wireless card switches to a different connection, there can be a shift in all or some of the above mentioned attributes. The card might have to step up or down its operating frequency, change to a different encryption scheme and all of this on the fly. Now that is a lot of work to do and in fact all of this switching can just drag the network performance to the ground. This makes the design and implementation of the virtualization software pretty challenging. This and many other challenges/caveats are discussed in this <a href="http://research.microsoft.com/en-us/um/redmond/projects/virtualwifi/faq.htm">Microsoft Research's FAQ page.</a><br />
<br />
I have been very excited about this research work ever since I read it and have been meaning to try out writing some network code using the virtual adapter. Sadly I have zero experience in network programming in Windows and currently don't have enough time to read up all of that. I hope such a thing will come up in Linux some time soon, if it isn't already there. </div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0tag:blogger.com,1999:blog-375315255567275930.post-61743608779713502582011-10-30T02:07:00.002+05:302011-10-30T02:08:29.124+05:30Computer hardware test/analysis tools<div dir="ltr" style="text-align: left;" trbidi="on">
Today I happen to look into the causes for over-heating of my Dell Studio 14 (1458) laptop (i7, 720QM, 4GB RAM, Win 7 with ATI Mobility Radeon HD 5450 - 1GB) and came across these various tools which people use to test/analyze their hardware.<br />
<br />
ThrottleStop<br />CPUmark<br />CPU RightMark<br />Furmark<br />ORTHOS<br />HWMonitor<br />RMClock - Undervolt processor. <br />GPU-Z<br />
<br />
I am yet to use any of these, but I do hope to run them soon and post some results here, JFK. :)</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com1tag:blogger.com,1999:blog-375315255567275930.post-48965471388083769372011-10-15T22:30:00.000+05:302011-10-17T00:19:46.029+05:30Machine Learning online course - Class 1<div dir="ltr" style="text-align: left;" trbidi="on">
As I mentioned in my <a href="http://techbrahmana.blogspot.com/2011/10/starting-with-stanford-online-machine.html">previous blog post</a> I am going to use this blog as my course notebook. All posts related to this course will have a "ml-class" tag, just in case. <br />
<br />
The first class was all introduction stuff, as expected. What I really liked about this class was the real world examples used. They were very useful in understanding what to expect from this course. Anyways, here are my notes for the class :<br />
<br />
Initially there were formal definitions of Machine Learning, one of them with rhyming phrases. I think we can skip those parts.<br />
<br />
There are two types of learning algorithms - Supervised and Unsupervised<br /><br />1) Supervised - A bunch of right answers are already provided to the machine. The machine has to try and get more of those right answers for the next set of questions.<br />The data provided already has some sense of direction or some sort of inference. It is like a set of input and output values and we have to predict the output value for a new input value given based on the existing data. Here the resultant dimension is known and defined. We have to find a suitable function which when applied on the given set of input values will best match the corresponding output values. This same function will then be used to predict output values of new inputs.<br /> - Eg : <br /> 1) Predicting the price of the house of a particular size given the price of various houses of varying sizes.<br /> 2) Predicting whether a tumor is malignant or not based on the size given the answer for tumors of various sizes<br /> <br /> Different Types<br /> 1) Regression - Machine tries to predict a continuous valued attribute, i.e. the value of the attribute whose value we are trying to predict belongs to a continuous range. (The house price example)<br /> 2) Classification - Machine tries to predict a discrete valued output, i.e the range of values is a finite small set of discreet values. (The tumor example)<br /> <br />2) Unsupervised learning - The data set given doesn't provide anything conclusive. It is just a data set and we are expected to make sense out of it and come up with the inference. There is no expected or target domain defined. It has to be inferred by examining the data. Very likely several target domains will be defined over the course of analyzing the data.<br /> - Types :<br /> 1) Clustering of data - <br /> -Eg : Google news example. Several articles about the same topic are grouped/clustered together. The input data set for this is just a bunch of articles (which is just one dimension/attribute). The other dimension (which is the common topic) itself is not well defined, i.e. the topics are not known before hand. We keep defining them as we go. So we have to infer that some of the articles belong to the same/similar topic and can be grouped together.<br />
<br />
That's it. Done with the first class. YAY.. !. I am yet to attempt the review exercises. I have decided to go for review exercises of this and the next class together.<br />
<br />
ಹರಿಃ ಓಂ.</div>Srirang (Brahmana)http://www.blogger.com/profile/17062039475270027427noreply@blogger.com0