Thursday, January 31, 2013

How to create and update hashed linux passwords


The problem 

I'm provisioning laboratory of about 10 computers, the problems are: 
  • We will scrape old and add new computers fairly regulary 
  • There are more than one admin of this system 
For now I kept admin's passwords in plaintet, well all except mine, that wasn't stored since I set up all computers, and set my password by hand. And storing admin passwords in plaintext (even on secure servers) is bad. 

Generating crypt hashes

Linux stores password as hashed values, but these hashes are not 'off the shelf`, basically most modern distributions use SHA-512 hashes, with own magic changes. So only way to get your password hashed is to call crypt function. 

Good thing is that python provides own wrappers for this so I didn't have to write glue code to C. 

import crypt;
result = crypt.crypt('password', 'salt'); 

Inserting crypt hashes into shadow database

This is a bit trickier, python has binding for both /etc/passwd and /etc/shadow databases, but unfortunately these are read only. 

Howewer there is thechpasswd command, that allows one to specify encrypted passwords for users. It expects standard input that contains lines with format {username}:{password}, one pair per line. 

If you call it with -e switch it will treat passed values as valid hashes and insert into /etc/shadow without changes. 

For example: 

echo "test:$6$23IagSE3$z.EZe5H1pfHCHMWw8UYqTpEGyS7apgoOBL5sG27/adt5CBC44LrLygywwRtvReY7lMlGj82SgQgjcP6OjE7Cf1" > chpasswd -e 






Wednesday, October 24, 2012


Jeff Atwood wrote an excellent post on multitasking, or more specifically: on that that you basically can't do multitasking and stay a effective. One of the points of this post is that multitasking is hard.

Since I am either sole programmer or a manager in 6 software projects (as you can guess these project aren't exactly very big), I guess I could share methods I devised to still get stuff done.

Don't multitask

Main problem with having many other software projects is cost of context switching. You either try to fit details of cople of projects in your brain --- which won't work, since it is way too much information, or you have to relearn details of a project, when starting doing your work on it.

Only way to do many projects and stay productive is not to multi-task and avoid context switching.

Minimal amount of time that you devote to a single project should be at least a day - ideally more like a working week. And if you are working on one project don't do anything else, no matter how urgent it is - it is not urgent enough.

My working day usually consists of about 6 working hours (or 12 pomodoros), if I assume that switching to a project takes 1 - 2 hours, then I loose about 20% of my time due to context switch.

Standardize

Minimize amount of re-learning when switching to a new project. Use standards throughout your environment. Since all Django project look basically the same switching from one to another is way easier than, say one custom servlet app to another.

In Java use standards like:

  • Maven (ant is not a standard, if you want to stick around ant - standardize it so all your projects are managed using the same commands, by managing I mean not only *building* but also: running development version, deploying, migrating and so on. 
  • Frameworks - and if possible stick to one framework. 

Switching from Java project to Python project is also more costly than switching between projects in the same language, well hell switching between projects using different VCS is harder.

Do it by the book

If you do only one project at a time you might get away with doing stuff the easy way, taking shortcuts and doing hasty hacks. On the other hand --- if you share your time between projects --- you will forget about those hacks, about your shortcuts and so on, and they'll bite you. So you need to od stuff the proper way.

Do tests

When you return to your project, you'll have fair chance that you'll forget how it works. So you will break stuff. Better to find his during testing.

Moreover --- since you'll work on many projects at once, you'll have less time to do proper hand testing, so your automatic test better be comprehensive.

Document your code

You'll forget how it works, better to have it's internals documentes.

Try to create working units of code

While working on a single project try to commit a working unit of code to the repository before switching to another one. This way when you'll get back you won't have to relearn internals of half done feature to finish it.

Doing tests also helps you to get your unit of code in working order :)