How to unlock Gnome Keyring from Python running on a Cron Job?
Asked Answered
A

4

12

I'm hooking a Python script up to run with cron (on Ubuntu 12.04), but authentication is not working.

The cron script accesses a couple services, and has to provide credentials. Storing those credentials with keyring is easy as can be, except that when the cron job actually runs, the credentials can't be retrieved. The script fails out every time.

As nearly as I can tell, this has something to do with the environment cron runs in. I tracked down a set of posts which suggest that the key is having the script export DBUS_SESSION_BUS_ADDRESS. All well and good, I can get that address and, export it, and source it from Python fairly easily. But it simply generates a new error: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11. Setting DISPLAY=:0 has no effect.

So, has anybody figured out how to unlock gnome-keyring from Python running on a Cron job on Ubuntu 12.04?

Abidjan answered 7/1, 2014 at 18:23 Comment(0)
C
3

I'm sorry to say I don't have the answer, but I think I know a bit of what's going on based on an issue I'm dealing with. I'm trying to get a web application and cron script to use some code that stashes an oauth token for Google's API into a keyring using python-keyring.

No matter what I do, something about the environment the web app and cron job runs in requires manual intervention to unlock the keyring. That's quite impossible when your code is running in a non-interactive session. The problem persists when trying some tricks suggested in my research, like giving the process owner a login password that matches the keyring password and setting the keyring password to an empty string.

I will almost guarantee that your error stems from Gnome-Keyring trying to fire up an interactive (graphical) prompt and bombing because you can't do that from cron.

Cheyennecheyne answered 16/3, 2014 at 16:42 Comment(3)
Yes! This is consistent with my research as well. I've gotten some indication from the Internet that it's possible to get things configured to skip the (#$%! graphical) interactive prompt, but I haven't successfully managed it yet. So far, best I've got is a well protected, local config file for my script. Unsatisfying, to say the least.Abidjan
We never found a solution for elections.chicagotribune.com using our Tarbell (github.com/newsapps/flask-tarbell) library which uses oauth + keyring to access the Google drive api so I had to do a "poor mans cron" from an interactive shell.Cheyennecheyne
Our current thinking is that we're going to rewrite parts of our software to get the credentials from environment variables / command line flags in addition to the keyring. It's a downgrade in security but would be safe enough in the environment we work in -- we'd be in trouble if somebody could access our crontab even if it didn't have credentials saved in the clear.Cheyennecheyne
F
1

Adding:

PID=$(pgrep -u <replace with target userid> bash | head -n 1)
DBUS="$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/"$PID"/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//' )"
export DBUS_SESSION_BUS_ADDRESS=$DBUS

at the beginning of the script listed in the crontab worked for me. I still needed to unlock the keyring interactively once after a boot, but reboots are not frequent so it works ok.

(from https://forum.duplicacy.com/t/cron-job-failed-to-get-value-from-keyring/1238/3)

so the full script run by cron would be:

#! /usr/bin/bash

PID=$(pgrep -u <replace with target userid> bash | head -n 1)
DBUS="$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/"$PID"/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//' )"
export DBUS_SESSION_BUS_ADDRESS=$DBUS

/home/user/miniconda/conda run -n myenv python myscript.py

using an environment from conda. Or change the python invocation to however you set up python to be run.

Fivestar answered 20/1, 2023 at 21:21 Comment(0)
S
0

Install keychain:

sudo apt-get install keychain

Put it in your $HOME/.bash_profile :

if [ -z "$SSH_AUTH_SOCK" ] ; then
  eval `ssh-agent -s`
fi
eval `keychain --eval id_rsa`

It will ask your password at the first login, and will store your credentials until next reboot.

Insert it at the beginning of your cron script:

source $HOME/.keychain/${HOSTNAME}-sh

If you use other language such as python, call it from a wrapper script.

It works for me, I hope it helps you too.

Stockist answered 8/4, 2015 at 6:45 Comment(0)
G
0

A few years late here. But for those who encounter the same problem, I just found a solution in Come and Tech it. Basically one need to add the following code at the beginning of the python script

import os
os.environ['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/run/user/USERID/bus'
os.environ['DISPLAY'] = ':0'

and then the keyring can be accessed correctly. The value of 'USERID' can be obtained by the 'id' command in shell.

Gehrke answered 22/11, 2023 at 2:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.