Skip to content

Commit 2b40183

Browse files
committed
backport bug fix: start a new ssh-agent instance only if necessary (fixes bit-team#722)
1 parent 3bbe97b commit 2b40183

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Back In Time
22

33
Version 1.1.15
4+
* backport bug fix: start a new ssh-agent instance only if necessary (https://github.com/bit-team/backintime/issues/722)
45
* Fix bug: OSError when running backup-job from systemd (https://github.com/bit-team/backintime/issues/720)
56

67
Version 1.1.14

common/backintime

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,4 @@ else
2424
APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/common")
2525
fi
2626

27-
#starting a new ssh-agent all the time is just a workaround for
28-
#https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/841672
29-
#normally this should only be necessary if run as cronjob
30-
#and the user is not logged in
31-
ssh-agent python3 $APP_PATH/backintime.py "$@"
27+
python3 $APP_PATH/backintime.py "$@"

common/backintime.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import sys
2020
import gettext
2121
import argparse
22+
import subprocess
2223

2324
import config
2425
import logger
@@ -57,7 +58,15 @@ def take_snapshot_now_async( cfg ):
5758
cmd += '--debug '
5859
cmd += 'backup &'
5960

60-
os.system( cmd )
61+
# child process need to start it's own ssh-agent because otherwise
62+
# it would be lost without ssh-agent if parent will close
63+
env = os.environ.copy()
64+
for i in ('SSH_AUTH_SOCK', 'SSH_AGENT_PID'):
65+
try:
66+
del env[i]
67+
except:
68+
pass
69+
subprocess.Popen(cmd, env = env)
6170

6271
def take_snapshot( cfg, force = True ):
6372
'''take a new snapshot.

common/sshtools.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
import random
2323
import tempfile
2424
import socket
25+
import re
26+
import atexit
27+
import signal
2528
from time import sleep
2629

2730
import config
@@ -167,8 +170,42 @@ def post_umount_check(self):
167170
raise MountException( _('Error discription') ) if not"""
168171
return True
169172

173+
def startSshAgent(self):
174+
"""
175+
Start a new ``ssh-agent`` if it is not already running.
176+
177+
Raises:
178+
exceptions.MountException: if starting ``ssh-agent`` failed
179+
"""
180+
SOCK = 'SSH_AUTH_SOCK'
181+
PID = 'SSH_AGENT_PID'
182+
if os.getenv(SOCK, '') and os.getenv(PID, ''):
183+
logger.debug('ssh-agent already running. Skip starting a new one.', self)
184+
return
185+
sa = subprocess.Popen([tools.which('ssh-agent')],
186+
stdout = subprocess.PIPE,
187+
stderr = subprocess.PIPE,
188+
universal_newlines = True)
189+
out, err = sa.communicate()
190+
191+
if sa.returncode:
192+
raise MountException('Failed to start ssh-agent: [{}] {}'.format(sa.returncode, err))
193+
194+
m = re.match(r'{}=([^;]+);.*{}=(\d+);'.format(SOCK, PID), out, re.DOTALL)
195+
if m:
196+
logger.debug('ssh-agent started successful: {}={} | {}={}'.format(SOCK, m.group(1), PID, m.group(2)), self)
197+
os.environ[SOCK] = m.group(1)
198+
os.environ[PID] = m.group(2)
199+
atexit.register(os.kill, int(m.group(2)), signal.SIGKILL)
200+
else:
201+
raise MountException('No matching output from ssh-agent: {} | {}'.format(out, err))
202+
203+
170204
def unlock_ssh_agent(self, force = False):
171205
"""using askpass.py to unlock private key in ssh-agent"""
206+
207+
self.startSshAgent()
208+
172209
env = os.environ.copy()
173210
env['SSH_ASKPASS'] = 'backintime-askpass'
174211
env['ASKPASS_PROFILE_ID'] = self.profile_id

qt4/backintime-qt4

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,4 @@ else
2828
APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/qt4")
2929
fi
3030

31-
#if [ "x$SSH_AUTH_SOCK" = "x" ]; then
32-
# eval "$(ssh-agent)"
33-
#fi
34-
35-
ssh-agent python3 ${APP_PATH}/app.py "$@"
31+
python3 ${APP_PATH}/app.py "$@"

0 commit comments

Comments
 (0)