Archive for the ‘Personal’ Category

Solving excel troubles by thinking out of the box

Saturday, July 2nd, 2011

A friend of mine just pinged me, wanting to know if I knew a way to programmatically add a range of number sequences to an excel worksheet.

I know nothing about excel scripting (or VBA-stuff or that type of things). But that didn’t stop me from getting an idea.

So I questioned him relentlessly until I was sure I knew what the expected output should be.

What he wanted was 16560 rows  in a worksheet. Rows 1 through 60 should contain the number 1. Rows 61 to 120 should contain the number 2, etc…

The final 60 rows should contain the number 276.

Why would he want this? I don’t know, some school work I presume. I didn’t particularly care, I assume his teacher wanted that format and was to lazy to provide a template…

I did however care that I found the problem interesting. How could I help, without any knowledge in VBA-scripting, and no desire to learn it within the next two hours?

The solution was rather neat:

$ touch file.csv
$ for i in `seq 1 276`;
    for a in `seq 1 60`;
        echo "$i" >> file.csv
$ unix2dos file.csv

After having created the file, ensured it would work on his windows system, and transferred it to him (and he verified that it worked to import it and copy the results over to where he needed to work with it) I timed the execution of the loop.

2.33 seconds, against several hours if doing it manually, or $DEITY knows how long if it involved learning how to create a VBA script to do it for you…

He was pleased, I had fun, all in all 25 well spent minutes. Win-win.

And it was definitely easier, for me, to create a csv-file for him to import, than to learn me sum VBA.



Sunday, June 19th, 2011


I have begun to use {c,d}f<character> to change or delete from the cursor up until (including) <character>.

It has made me a little bit faster in some few edge cases of text-editing, but today (Monday) I found myself in need of doing a couple of manipulations on text up until (NOT including) <character>. helped me find {c,d}t<character>.

Very nice :)

MediaWiki sortable tables

In preparation for FSCONS one of my duties as team leader for the Hardware team is to keep track of all the hardware available to FSCONS (i.e. hardware owned by FFKP) and Jonas felt it would be a good idea to have that list available on a wiki.

When I was done adding the laptops and cameras it kindof bugged me that I’d added the laptops in the “wrong” order (i.e. the serial number column wasn’t ordered).

Luckily this was an easy fix, as one can add class="wikitable sortable" to the table header in the wiki-syntax and it will automagically add the necessary javascript and buttons to make each column sortable.


The “Bump” Challenge aimed at creating a simple(r) way of exchanging public keys and establishing trust, possibly (probably?) using smartphones which are able to sync with the FreedomBox, seems like a rather nice idea.

Personal Wikis

A wiki can be a great tool, and for a while I was maintaining a personal mediawiki installation, just adding stuff I needed from time to time, but never often enough that I could learn it.

Then I stumbled over Zim, which became collateral damage as I got into my “replace as much as possible with a command-line alternative”-phase (this phase hasn’t abated yet ;)) which left me migrating to VimWiki.

I am not likely to replace VimWiki, it works well for me, but sometimes it might not be the right tool for the job. Which is why I am always on the lookout for new stuff.

I already knew about ikiWiki, but at the time I discovered it I didn’t have the time to look further into it. I guess I should change that.

And today I found TiddlyWiki, a wiki self-contained within an html file. Which people have extended for other uses.

SQLite Triggers

SQLite has support for triggers, how cool is that?! And these triggers can be triggered by other triggers! :D


Vim Casts is a Vim screencast resource for learning / improving your knowledge in Vim (thank you for the tip hook).

Tahoe-LAFS (Least Authority File System) is a decentralized fault-tolerant peer-to-peer file system. I can’t really speak about its security, but it looks pretty good, at least on paper.

ZRTP seems to be a pretty cool VoIP encryption protocol, and there seems to be an implementation for Android devices as well.

“Towards a Lifelong Content Management System” is a rather nice, well thought-through blog post on how we might want to change the way we think about content management systems (thanks @mlinksva).



Sunday, June 12th, 2011


This is a technology demonstrator of the FSCONS myConf concept that doesn’t rely on any server-side programming.

It also became my first project under git versioning.

myConf is a concept we’ve (FSCONS) been thinking about implementing since, IIRC, 2009.

Basically it should allow a participant to tailor a personalized conference schedule, instead of having to mark it up in a dead-tree version.

Or so is at least my understanding of the myConf concept.

In short it is a Javascript (jQuery) / JSON-powered site, from which I have now learnt two things:

  • It is as important (if not more so actually) to have a good JSON structure as it is to have a good database design, otherwise it WILL come back and bite you, hard
  • It is actually quite fascinating what one can do with Javascript (at least when a library is used so that you don’t need to even think about platform irregularities)

Expect a public release shortly.

vim foldsearch plugin

I was editing my sudoers file (I still haven’t gotten myself off sudo) and started wondering if there perchance wasn’t a way in vim to hide lines according to some pattern.

The default archlinux sudoers file is full of comments, to the point that it is almost hard to see the uncommented lines.

:g/pattern and :v/pattern only takes you so far, i.e. it shows you the lines, but immediately disappears when trying to edit or move or anything except just looking at it.

Luckily for me other people had already asked the same question, and yet other people had answered it.

Which lead me to the vim foldsearch plugin. Best of all, it is easy to use.

Search for something, i.e.:

/my pattern here

and then use <Leader>fs (I have mapped <Leader> to \ in my config, so for me that would be \fs) and voilà, all the lines not matching the search are folded away.


I am sure I have already written about renameutils, or more likely about qmv, but it is worth repeating. qmv rocks!

wmii is my window-manager, although I am probably running version 3.6 or something (i.e. not 3.9) so this might not be usable for people other than wmii 3.6 users.

Anyway, last Friday I got the idea to write a little script to switch wallpapers for me. Today I sat down and hacked it together:

tmpList="$(ls -l ${HOME}/wallpapers/*.jpg | awk '{ print $NF }')"
randomWallpaper="${tmpList[$(($RANDOM % ${#tmpList[@]}))]}"
ln -fs "$randomWallpaper" "${HOME}/wallpaper.jpg"
exit 0


shunit2 Unit-testing for (Bash) shell scripts, this is so cool :D
Akka for a simple way of writing concurrent applications in Java
Protolol jokes for nerds


Sunday, June 5th, 2011

SSH tunnelling

This Friday I finally got a valid reason to dig into how one sets up an SSH tunnel between two machines. The reason was that I was sitting at the new FFKP office lulzing about with razor, and found myself needing to test some PHP I had been working on.

So I was not at home, I am not stuffing Apache and PHP and MySQL onto my netbook just to do web dev stuff, so I needed contact with my “server” back home.

The slight problem being that since it is for development use only, I don’t expose its Apache to the Internet, only to the local network. SSH is another matter altogether.

So I thought that it shouldn’t be impossible to set up what I wanted, i.e. from my netbook, type in localhost:8080 (or whatever port number floats your boat) and be routed through the tunnel to the server.

It turns out there was this really neat write up on how to do it, already available, and even better, it was really simple:

ssh -f <user>@<remote-host> -L <local-port>:<remote-host>:<remote-port> -N

-f makes it a background process, -L tells SSH we want a tunnel, -N tells SSH that we aren’t trying to execute a command.

This is something I might even begin to remember :)


wmfs, or window manager from scratch, seems like an awfully nice little tiling window manager.

Unfortunately I haven’t gotten the time this weekend to play with it, but perhaps a little later today?

I was warned on diaspora that there is a pretty huge-ish performance-related bug in the code right now, and since I haven’t tested it yet I can’t make any recommendations, but from the very superficial (and that will hopefully soon change) observation of the documentation, it seems like it could be a wmii-replacer.


As I am attempting to learn git, I soon came to the conclusion that the best way to learn it would be to use it.

After all, the basics are not extremely different from mercurial, and while most of my projects remain single-person-projects, the basics are more than enough for me.

So I hereby solemnly swear that the next little project I start, whatever it may be, will be versioned using git instead of mercurial.

My foray into the git world also meant that I started looking at the two largest git hosting solutions (both of them free as in beer, and one free as in freedom, github and gitorious.

In doing so, I ran through the list of hosted projects, and there is so much cool stuff out there to test, and try, and learn, and play with… so many things, so little time.

  • z – jump around, which studies your usage of the various directories on your machine, learns, and then makes it easy to jump to “popular” directories easily
  • yajl, Yet Another JSON Library, and I likes me sum JSON
  • Underscore.js, a javascript “utility-belt” library
  • wormhole a jQuery plugin, which for most parts would probably be more fun than useful, but it seems to have been initially written to scratch an itch
  • Backbone.js, which I had already read about here and been wanting to play with it ever since
  • Microjs, a site for finding the javascript framework you need, in order to do what you want
  • Raphaël, a javascript library for working with SVG
  • TMS, a Temporary Mail Server, written in Python, this just must be useful for testing and debugging mail-stuff
  • tablib, another Python module, this one for parsing and converting tabular datasets between various formats, (i.e. csv, html, json, ods, xls(x), yaml)
  • twotwodo, a personal 2do list in the browser, using jQuery (javscript) for logic, and cookies for storage (so it is local to the machine, with no shared storage back-end, which can be good sometimes
  • protovis, nice javascript visualization toolkit

Two other links I find worth mentioning are:

FamFamFam has a rather nice-looking icon set (Silk), licensed using CC By 2.5 or 3.0, which I might finally get to use in a project of mine (haven’t really gotten a chance since it was a long time since I did any serious web programming.)

Finally, a blog which has helped me greatly in understanding various things is BetterExplained which has now released something new which they call, and I will follow this with great interest.

Revelation of the week

The one real “aha” moment this week was Friday afternoon, when Grégoire showed me that it was possible to add people from other diaspora seeds by searching for their <username>@<other-seed>.
That was good news since I was rather bummed out about razor and greg had set up shop at leaving me with relatively few contacts on “my” seed.

Other than that, to be honest, this week has been pretty boring. I did get a whole lot done in timetrack yesterday, and found a deeper love for grep‘s -A flag, and I have been doing some serious thinking about writing my own “makefile blogging”-thingy.

Friday night right before falling asleep I got the idea to write a little script which would pick a wallpaper at random and set that as the active wallpaper at startup. Since I use wmii, and wmii uses xloadimage, given a path, I could simply put all my wallpapers in a directory and have the script symlink one at random on start up.

rkhunter and pacman on arch

Tuesday, May 31st, 2011

I read a notice, or a post, somewhere the other week, and it planted a seed in my head, so today I installed chkrootkit and rkhunter.

chkrootkit revealed nothing of interest, while rkhunter did find potential problems.

At first I found it rather unsettling. rkhunter pointed at specific files which it obviously didn’t think should be there.

On my desktop that was /usr/lib/libtty.a which could be a part of a rootkit named “fuck `it“. Cleverly putting that grave accent in the name of the rootkit, the original authors have effectively made it impossible to search for (at least using Google).

Resisting the urge to panic and do something rash (like formatting the system) I instead booted up my netbook as well, installing rkhunter and executing it there as well.

The two installs are almost identical, and if anything, the netbook, at times operating outside my own network, should run a higher risk of getting infected with stuff (or so my reasoning goes anyway).

The report on my netbook came back with other things, mostly sshd configuration stuff, but sshd is never running on the netbook (I edited the config options anyway as they were reasonable and would protect the system if the ssh daemon was ever started on the netbook), an entry in /etc/rc.local (which I know I put there), and a hidden compressed man-page which rkhunter had reported on the desktop as well.

Back to libtty.a. the good news was that I could list it, it wasn’t hiding, well the file was one amonst a plethora of files in /usr/lib/ but having pinpointed it, it didn’t try to hide from me.

So my next thought was: “It must have come from somewhere.”

There are few things I have installed from source, so the most obvious place to look was towards packages installed from AUR.

Which means that I could ask pacman which package this file belonged to.

pacman -Qo /usr/lib/libtty.a revealed that the package it came from was termrec, a packaged I had installed because I at one time or another had an idea.

termrec is used to record and replay a terminal session, but I never got around to trying it out.

It is entirely possible that the behaviour of termrec is close enough to that of a malware to be identified as such, but once I realized the connection I was a lot calmer.

Then again, I haven’t used termrec, and have no reason to keep it around, so I uninstalled it, and with it, /usr/lib/libtty.a disappeared as well, so I don’t believe there ever was a threat.

As for the hidden, compressed man-page, it turned out to belong to krb5, so I am pretty sure that is harmless as well.

All in all, it was a pretty nice experience, especially the fact that I was mindful enough to keep cool :)



Sunday, May 29th, 2011


I have come up with a way to achieve the changes I want, but without introducing sqlite3 as a dependency, and a big part of the solution is to use bash arrays.

Furthermore, I have been thinking about how to, if possible, get timetrack to automagically start a new session when a file in the project is opened.

This won’t help anyone to start the timetracker when thinking about the project, but at least when physically transferring code from brain to hard drive, and the lead I am working off of is inotify.


During this weeks FSCONS meeting jonaso jokingly suggested that I’d try to write an issue tracker in bash. (damn you! ;))

Of course my mind started wandering and although there is no code to back it up, I have a couple of rather interesting ideas about how to pull it off.

For this project, sqlite is the way to go, but I was somewhat worried about concurrent access which I probably shouldn’t be.

My tests indicate (oh yeah, so there exist code, just not any actual issue tracking code) that the sqlite3 library is intelligent enough to lock the file, and thus doesn’t allow concurrent access.

I’ll still need to devise a way of detecting these locks, and have the second script stand in line and try again later, but that should be trivial.


Turning Vim into a modern Python IDE

Learning styles
From what I can gather, I am an assimilator. resistance is futile!

Cheat sheets!

The 9 secret burdens of being a Linux user

Big businesses acting out like this might very well get me to start boycotting them again…

String manipulation in bash

Seemingly nice way of doing HTTP requests in Python

Extending timetrack

Saturday, May 21st, 2011

There are at least three features I feel is currently lacking in my timetrack suite, and two of them should be more easily added than the third.

Monthly breakdown and tagging

Soonish there should be another add-on, presenting hours but broken down on a per month basis.

This would however necessitate an update of the timetrack storage format (I am leaning towards using SQLite).

Tagging is the other simple feature I feel is missing, and again, it would be a much simpler feat to accomplish if stored using SQLite.

The downside to this, of course, would be the dependency on SQLite. I really don’t like to introduce more dependencies than is necessary.

I am, unfortunately, not smart enough to figure out a better (plaintext) format that would be able to accommodate tags, at least not without making the parsing a bloody mess.

Automatic session detection

In addition to that, my introductory post to timetrack yielded a comment from archie which got me thinking. It really would be nice if the sessions started on their own.

I am thinking that for actual coding sessions, this shouldn’t be all that impossible.

For planning and design work (I am thinking mental modelling and time spent just grasping the concepts) it would be harder (and if I do go down the route with SQLite I suspect I’d need to create another script just for simple addition into the database after the fact.

However, for file-bound operations one could try to see if a similar approach to what fsniper is doing couldn’t be used. The technical details of fsniper is described as:

“fsniper uses inotify to watch for when a file is closed after being written to. This means utilities such as touch will cause the event to trigger.”

Most suggested uses of fsniper has always rotated around doing something to the file that was just modified, but from what I can tell, there shouldn’t be an reason that one couldn’t just execute any old script, doing just about anything, for any purpose, when a file in the correct directory has been modified.

This would all hinge on one small detail though: That there is some event in inotify similar to the one fsniper listens for, but for when a file is opened for writing. (This might however be indistinguishable from a file being opened for just reading, and then it would trigger on just about anything…)

Of course, this would also mean that we need some way of graphically asking the user if a session should be started (the script won’t be executed from a visible shell), and for that I am thinking about Zenity for that.

But the best thing about this is that this solution, with inotify, something fsniper-ish and Zenity would represent optional dependencies (iff/when I manage to get some working code for it)


Introducing timetrack

Wednesday, May 18th, 2011

Albeit already having mentioned timetrack in at least two posts, I feel it is time it got the introduction it deserves.

Timetrack is a suite of two (shell-)scripts (timetrack and timesummer) I hacked together an evening to help myself keeping track of the time I spend on various projects.

There are a couple of pre-existing softwares I could have used instead, most notably Hamster but two things got in the way of that:

  1. I don’t like the idea of using a full blown GUI for something so simple, and
  2. I don’t run Gnome

There are others, I am sure, and I did search the repositories for a CLI time-tracker, finding nothing. So I built a simple one myself.

The timetracker script does three things, and only these three things:

  1. If there is no active (open) session, create a new session
  2. If there is an active (open) session, close it down
  3. If a session has just been closed, ask the user what was done, calculate the length of the session, and document the session length, along with the user input

In short, timetrack tracks time

Once I had finished up timetrack, I realized that there was no way I was ever going to be energetic enough to sift through the timetrack file and calculate the combined number of hours and minutes, and that is how timesummer came to be. It sums up the times documented in the timetrack file.

Then I got to thinking, for some of these projects, I actually get paid, so for some of these projects, it would make sense to add in a calculation about how much I should charge people.

But as this isn’t something that would/should be done for every project, I got to thinking about creating an add-ons system, and I remembered an old blog post I’d read a couple of years back. It gave me some ideas, and after having consulted google about bash and introspection, I found out about compgen.

Now, to be fair, there are a whole host of limitations imposed on this solution (like how to name functions, both in order to find them, but also to avoid collisions, but if one instead considers it a rather barren API, it sortof makes sense.

With the first implementation of the add-on functionality, there really wasn’t a whole lot one could do to extend the script, as I didn’t use introspection, and just sourced every script in a given directory after having performed the bulk of the work in timesummer already. With the new approach however, there are five distinct phases, during each of which the add-on may chose to include a function for doing some work.

The phases, in order, are:

  1. initialization,
  2. pre-processing,
  3. processing,
  4. post-processing, and
  5. presentation

Phase #3 assumes that there is a loop in the master script which does some type of processing upon a list of items, all of which one might also want to do some other processing on, via add-ons.

One interesting add-on I might look into writing soon would be to differentiate between time spend programming, and time spent designing, and perhaps time spent in meetings, etc.

Going down the statistics road, gives me an idea for a better name instead of timesummer: timestats.

Of course, this would mean some type of change to timetrack, in order to confine a session down to a defined and quantifiable topic (i.e., it might be good to have each session tagged), and let the add-on work on tags instead of on human language (the user input).

This blog post has taken an interesting turn. Instead of me (just) announcing things, I have gotten ideas, as I write this, about what will come next in timetrack’s development. Pretty neat!


Sunday, May 15th, 2011

timetrack / timesummer

I wrote about timetrack / timesummer last week as well (and I still haven’t come up with a better name for timesummer) but as I added some new stuff to the script and wanted to give link love to the blog that gave me the means to add the features I’m writing about it again. So basically timetrack is all fine and dandy, it does its one thing and it does it rather well.

timesummer however works on a little higher level. While timetrack deals with one session at a time, and knows only of that one session while working with it, timesummer, which adds up time spent overall, could potentially do more.

However, because I was stupid enough to write that, the only example of potential expansion I can come up with is the one example add-on which I have implemented.

It is a simple script which adds a cost calculation to the output. In any case, the way to do this is with generic shell hooks and this has proven quite nifty, so I will be sure to work with these more in the future.

I have come to realize that this is too simplistic an approach, because it is adding limitations to what an add-on could do. So I am working on a slightly more complex solution (which fortunately, it seems right now, won’t make the add-ons all that more complex. Expect an update within the next week.


The makers schedule
In theory, this seems like a pretty sound idea, and I am thinking about trying it out now while I am still unconstrained enough to do so.

html5 web workers explained
A simple four step guide on how to understand html5 web workers (i.e. wrap your head around multi-threaded Javascripts in four steps)

Introducing passtore

Sunday, May 8th, 2011

First of all, I find it prudent to insert a HUGE disclaimer:

I have no formal education within the field of IT security, and there may, unbeknownst to me, be millions of ways to circumvent the security this suite offers.

Naturally I have tried to make it as safe as I can since I am using it myself, that said, I offer no guarantees that a determined aggressor couldn’t make short work of the protection offered.

If you know that there are threats aimed at you, you should probably also know that this software is not for you.

This is meant to be used by ordinary people like myself, who’d just like to improve the security of their various accounts and services by using unique, and probably longer and stronger, passwords for each and every service they subscribe or otherwise have access to.

passtore has worked well for me over the last 6+ months I have been using it, but mind you, to the best of my knowledge there are no determined efforts by an aggressor to compromise my security.

Behind the scenes passtore uses GPG to store passwords in a file ~/.gnupg/passwords.gpg, and optionally depends on xclip (for copying a password to the clipboard) and pwgen (for generating strong (long and full of entropy) random (well, as random as a deterministic system can make them) passwords).

As it is a CLI-based suite, it is also rather easily scriptable (not to the point of allowing full automation, the user will need to input the GPG privkey passphrase, but it has been successfully been plugged into other applications such as mutt, msmtp and offlineimap.

There are a couple of gotchas that one needs to be aware of for a moderately safe operation of these scripts:

  • The protection offered is not stronger than the strength of the passphrase securing your GPG private key
  • If the aggressor gets hold of ~/.gnupg/passwords.gpg and your GPG private key s/he could potentially brute-force it open offline in their own good time
  • If the aggressor can modify the scripts ({add,get,mod,del}pass) or the ~/.passtorerc s/he can compromise your security
  • If the user could modify your ~/.gnupg/passwords.gpg file, s/he can lock you out of all the places with passwords protected by passtore
  • If the aggressor could modify your ~/.passtorerc file, s/he could add another (unauthorized) recipient to the ~/.gnupg/passwords.gpg file
  • If the optional dependency xclip is used (getpass -c <host>) the password will be stored in the X clipboard until overwritten by something else
  • While unencrupted in the clipboard, there is a minute risk that swapping occurs, pushing the password onto the swap space; passtore does not perform any sort of harddisk or RAM scrubbing
  • If you forget the passphrase for your GPG private key, you won’t be able to unlock the ~/.gnupg/passwords.gpg file… ever
  • If either your GPG private key, or the ~/.gnupg/passwords.gpg file is corrupted, you are truly out of luck
  • Some services will seem to accept a long, special-charactered password, up until after you have actually changed it, and try to login, at which point you are locked out; morale of the story? MAKE SURE THAT THE EMAIL ADDRESS YOU PROVIDED IS A REAL ONE SO YOU CAN RESET THE PASSWORD!

Most of these issues can be handled by common sense and sane file permissions (0700 for the scripts, 0600 for the files), and also to not allow untrusted people onto your account.

Nevertheless, security is a hard topic to get right, so please do not use this software if your life could depend upon the correct and secure operation of it.

My previous way of handling passwords were thinking up a “base password” which I then modified slightly for each and every service.

Think along these lines: if “pizza” was my base password, “hotpizza” would be my hotmail password, while “goopizza” would be my google password. (In reality I used a longer base password than that.)

The primary problem with this was that if someone ever were to learn of the base password, they’d have the keys to my kingdom.

Since I am not in the business of divulging that sort of thing to anyone, you might incorrectly think that this is a safe way of doing it. You’d be wrong.

What would happen if I had been lured into signing up for an account with a new service which seemed legit, but which in reality was nothing more than a honeypot for username, email addresses and passwords?

Do you use different usernames on different services? Most of us don’t, and there may even be some value in not doing it (recognition/reputation of sorts from other services).

So even with my previous password system (it would of course have been a total bust if I used the same password everywhere) an aggressor could have figured out how to reverse engineer the base password and reconstruct it for other services.

Of course, given the amount of people who just use the same password everywhere, I don’t think they’d have bothered with my password at all, unless they were specifically targeting me, which is wholly unlikely as well.

But with passtore, I don’t even need to care or worry. If the site admin is a sleazebag, or incompetent/unlucky enough to have the database stolen by aggressors, or a “friend” tries to compromise an account, that’s as far as they’ll come.

Obtaining one password for one service gives them control over that service, nothing more (with the one obvious exception; if someone were to gain access to my email account password, they could reset the password on every service registered with that email address).

Be paranoid about your email passwords people! It is unfathomable to me how easily people hand over their usernames and passwords to their email accounts to sites like LinkedIn and Facebook.

Sure, they are “only” scanning your contacts for already present friends and any service that went beyond that would very quickly be found out and get a bad rep, and in all probability criminal charges brought up against them.

With that said, who knows if Facebook or LinkedIn, or any of the other social media sites out there who want you to divulge your email password to them in the name of contact building, stores you password, and if so for how long, and for what purpose.

passtore will let me use different passwords for different services, without making it hard on my memory. In doing so, it mitigates the effects it will have on my life if a single service is compromised.

passtore will keep my passwords safe from nosy siblings, friends and partners, and, depending on the strength of my GPG privkey passphrase, it would keep them safe from most determined aggressors as well.

Could Google bruteforce their way in? Probably.
A government funded agency? Definitely.

As I am not facing that type of opposition, and the only threat to me is to inadvertently entrust a service with a password, which the service providers may try to abuse, passtore works well for me.

The usual disclaimers apply, I assume no responsibility for any damages you might incur, if you lock up a whole host of passwords and have either your passwords.gpg file or your GPG private key corrupted, that is truly unfortunate, but I designed it to be as secure as I could make it. It is not meant to be recoverable or decryptable without these files, so please make sure that you have backups of them somewhere safe.

Again, be smart, be safe, and use it at your own risk.

passtore on