Use Vdirsyncer with Netrc

2024-01-07

This article describes how-to use vdirsyncer with netrc authentication

Motivation

Over Christmas days, I came across a post on hunden's[1] website about caldav and cardav syncing in the terminal. That reminds me for fixing a long standing issue with my current setup. Currently, whenever I want to sync my calendar and tasks between my caldav server and my laptop I'm using the credentials stored in a keepass database. For accessing these credentials I wrote the following script that allows me to get the password for a given entry.

#!/bin/sh

entry="$1"
db="$HOME/SynologyDrive/references/sicherheit/20200617-priv.kdbx"

keepassxc-cli show -s "$db" "$entry" | grep Password | awk -F' ' '{print $2}'

I'm using this script mainly for vdirsyncer, where I configured it as a command for providing the password when needed.

password.fetch = ["command", "get-password", "abstellkammer.fritz.box:5000"] 

However, that approach requires to provide your masterkey to unlock the keepass database every time you want to synchronize. Hence, makes it a bad choice for using it in a automatic sync setup. In other words, I want to find a way to sync my tasks every three hours by a cron job without interactively providing a password.

The .netrc file

I'm using fdm for a long time which makes the fetching of mails a breathe. Fdm is using the .netrc file[2] for storing machine and login information. So, the basic idea is to re-use the .netrc file and put my caldav credentials there. For accessing the credentials for a given host I wrote the following python script.

#!/usr/bin/env python3

import netrc
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("host")
parser.add_argument("-l", "--login", action="store_true", help="get username for the given host")
parser.add_argument("-p", "--password", action="store_true", help="get password for the given host")
args = parser.parse_args()

def main():
    netrc_file = netrc.netrc()
    login, _, password = netrc_file.hosts.get(args.host)
    
    if args.login:
        print(f"{login}")
    elif args.password:
        print(f"{password}")
    else:
        print(f"{login}, {password}")
    

if __name__ == "__main__":
    main()

I've put the new script into my bin directory under PATH where I can use it in combination with vdirsyncer. Here is the modified configuration line.

password.fetch = ["command", "~/bin/netrc-get", "-p", "abstellkammer.fritz.box"]

As a last step. Let's activate the synchronization every three hours in my crontab file.

0 3 * * * vdirsyncer sync

References

[1] hunden's post abot caldav and cardav via terminal
[2] the .netrc file