Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added basic libsecret support to autostart + new utility to add and update libsecret passwords #114

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions docs/man/openvpn3-secretmanager.8.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
=================
openvpn3-secretmanager
=================

------------------------------------------------------
OpenVPN 3 secure credentials storage manager
------------------------------------------------------

:Manual section: 8
:Manual group: OpenVPN 3 Linux

SYNOPSIS
========
| ``openvpn3-secretmanager``
| ``openvpn3-secretmanager`` ``-h`` | ``--help``


DESCRIPTION
===========
The **openvpn3-secretmanager** utility is used to store and modify openvpn
passwords securely for use during autloaded user-auth sessions


OPTIONS
=======

-h, --help Prints usage information and exits.



BACKGROUND
==========
By default there is no secure way to store auth-user login credentials
for autostart sessions - This utility adds an easy way to add new
passwords to the system as well as provide a key for access.


USE
==========
The utility will ask for a password for storage, This password is your
user-auth password, after storage of the password the utility will return
a key. This key is used in place of a password in the .autoload to allow
libsecret to fetch the password from secure storage.



SEE ALSO
========

``openvpn3-autoload``\(1)


22 changes: 21 additions & 1 deletion src/python/openvpn3-autoload
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import time
from pathlib import Path
import openvpn3
from openvpn3 import StatusMajor, StatusMinor
import gi
gi.require_version('Secret', '1')
from gi.repository import Secret

# Add the traceback module if we're in debugging mode.
# This will allow dumping of tracebacks when exceptions happens
Expand Down Expand Up @@ -239,6 +242,15 @@ def start_tunnel(sessmgr, cfgobj, autoload):

ready = False
conn_started = False


#libsecret schema
OpenVPN3_LINUX = Secret.Schema.new('OpenVPN.Store',
Secret.SchemaFlags.NONE,
{
'Key': Secret.SchemaAttributeType.STRING,
}
)
while not ready:
try:
# See of the backend process is ready to start a connection
Expand Down Expand Up @@ -276,7 +288,15 @@ def start_tunnel(sessmgr, cfgobj, autoload):
sess.Disconnect()
raise Exception('The .autoload config for "%s" is lacking details for "%s". Auto-start '
'ignored.' % (cfgn, varn))
ui.ProvideInput(userauth[varn])
if autoload['libsecret'] == True:
#Only looks to see if it exists, Won't throw error if it doesn't to ensure backwards compatibilityi
if varn=='password':
string_password = Secret.password_lookup_sync(OpenVPN3_LINUX, {'Key': userauth[varn]}, None)
ui.ProvideInput(string_password)
else:
ui.ProvideInput(userauth[varn])
else:
ui.ProvideInput(userauth[varn])

# If the VPN backend doesn't reply soon enough, try again in a bit
elif (err.find('org.freedesktop.DBus.Error.NoReply') > -1
Expand Down
88 changes: 88 additions & 0 deletions src/python/openvpn3-secretmanager
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/python3
# OpenVPN 3 Linux client -- Next generation OpenVPN client
#
# Copyright (C) 2017 - 2018 OpenVPN Inc. <sales@openvpn.net>
# Copyright (C) 2017 - 2018 David Sommerseth <davids@openvpn.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, version 3 of the
# License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#

##
# @file openvpn3-secretmanager
#
# @brief This is a command line interface to allow adding and updating of libsecret
# credentials for use with openvpn3-autoload


import argparse
import getpass
import random
import string
import gi
gi.require_version('Secret', '1')
from gi.repository import Secret


#Each stored password has a set of attributes which are later used to lookup the password.
#The names and types of the attributes are defined in a schema. The schema is usually defined once globally.

OpenVPN3_LINUX = Secret.Schema.new('OpenVPN.Store',
Secret.SchemaFlags.NONE,
{
'Key': Secret.SchemaAttributeType.STRING,
}
)

def GenerateKey():
return ''.join(random.choices(string.ascii_lowercase, k=16))

def store_credentials():
Key=GenerateKey()
Password = getpass.getpass('Password: ')
Secret.password_store_sync(OpenVPN3_LINUX, {'Key': Key}, Secret.COLLECTION_DEFAULT,
'OpenVPN Password', Password, None)
print('Key for use in conf.autoload (Or to update your credentials later): "%s"' % Key)
def update_credentials():
Key = input('Key: ')
Password = getpass.getpass('Password: ')
#Updates credentials by removing old ones and replacing with updated ones.
#Returns True when success
removed_password = Secret.password_clear_sync(OpenVPN3_LINUX, {'Key': Key}, None)
if removed_password == False:
print('Failed to remove existing Password, Do they exist?')
exit()
Secret.password_store_sync(OpenVPN3_LINUX, {'Key': Key}, Secret.COLLECTION_DEFAULT,
'OpenVPN Password', Password, None)
print('Updated password for ' + Key)

if __name__ == '__main__':
parser = argparse.ArgumentParser()
subp = parser.add_subparsers(dest='subparser')
store_credentials_parser = subp.add_parser('store', help='Stores new OpenVPN credentials.')
update_credentials_parser = subp.add_parser('update', help='Updates existing OpenVPN credentials.')
args = parser.parse_args()
if args.subparser == 'store':
store_credentials()
elif args.subparser == 'update':
update_credentials()