1.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py Fri Apr 25 13:23:20 2014 +0200
1.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py Tue Apr 29 13:00:46 2014 +0200
1.3 @@ -32,6 +32,7 @@
1.4 # ------------------------------------------------------------
1.5 # imports
1.6
1.7 +import json
1.8 import os
1.9 import os.path
1.10 import subprocess
1.11 @@ -44,7 +45,6 @@
1.12
1.13 # local
1.14 from environment import Environment
1.15 -from notification import Notification
1.16
1.17
1.18 # ------------------------------------------------------------
1.19 @@ -56,8 +56,8 @@
1.20
1.21 """All the URLs we know mapping to class handler"""
1.22 opensecurity_urls = (
1.23 - #'/application', 'os_application',
1.24 '/credentials', 'os_credentials',
1.25 + '/keyfile', 'os_keyfile',
1.26 '/notification', 'os_notification',
1.27 '/password', 'os_password',
1.28 '/', 'os_root'
1.29 @@ -68,56 +68,8 @@
1.30 # code
1.31
1.32
1.33 -# class os_application:
1.34 -#
1.35 -# PRESUMLY DEAD CODE
1.36 -#
1.37 - # """OpenSecurity '/application' handler.
1.38 -
1.39 - # This is called on GET /application?vm=VM-ID&app=APP-ID
1.40 - # This tries to access the vm identified with the label VM-ID
1.41 - # and launched the application identified APP-ID
1.42 - # """
1.43 -
1.44 - # def GET(self):
1.45 -
1.46 - # # pick the arguments
1.47 - # args = web.input()
1.48 -
1.49 - # # we _need_ a vm
1.50 - # if not "vm" in args:
1.51 - # raise web.badrequest('no vm given')
1.52 -
1.53 - # # we _need_ a app
1.54 - # if not "command" in args:
1.55 - # raise web.badrequest('no app given')
1.56 -
1.57 - # # check if we do have valid vm
1.58 - # v = [v for v in vms if v['name'] == args.vm]
1.59 - # if len(v) == 0:
1.60 - # raise web.notfound('vm not found')
1.61 - # v = v[0]
1.62 -
1.63 - # # check if we do have a valid app
1.64 - # a = [a for a in apps if a['name'] == args.app]
1.65 - # if len(a) == 0:
1.66 - # raise web.notfound('app not found')
1.67 - # a = a[0]
1.68 -
1.69 - # # invoke launch with
1.70 - # res = "starting: launch " + v['user'] + " " + v['ip'] + " " + a['command']
1.71 +class os_credentials:
1.72
1.73 - # launch_image = os.path.join(sys.path[0], 'launch.py')
1.74 - # process_command = [sys.executable, launch_image, v['user'], v['ip'], a['command']]
1.75 - # process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.76 - # result = process.communicate()[0]
1.77 - # if process.returncode != 0:
1.78 - # return 'Launch of application aborted.'
1.79 -
1.80 - # return result
1.81 -
1.82 -
1.83 -class os_credentials:
1.84 """OpenSecurity '/credentials' handler.
1.85
1.86 This is called on GET /credentials?text=TEXT.
1.87 @@ -134,18 +86,56 @@
1.88 if not "text" in args:
1.89 raise web.badrequest('no text given')
1.90
1.91 - # invoke the user dialog as a subprocess
1.92 - dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
1.93 + # remember remote ip
1.94 + remote_ip = web.ctx.environ['REMOTE_ADDR']
1.95 +
1.96 + # create the process which queries the user
1.97 + dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.pyw')
1.98 process_command = [sys.executable, dlg_image, 'credentials', args.text]
1.99 - process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.100 - result = process.communicate()[0]
1.101 - if process.returncode != 0:
1.102 - return 'Credentials request has been aborted.'
1.103 + process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.104
1.105 - return result
1.106 + # run process result handling in seprate thread (not to block main one)
1.107 + bouncer = UserResultBouncer(process, remote_ip, '/credentials')
1.108 + bouncer.start()
1.109 +
1.110 + return 'user queried for credentials'
1.111 +
1.112 +
1.113 +class os_keyfile:
1.114 +
1.115 + """OpenSecurity '/keyfile' handler.
1.116 +
1.117 + This is called on GET /keyfile?text=TEXT.
1.118 + Ideally this should pop up a user dialog to insert his
1.119 + password along with a keyfile.
1.120 + """
1.121 +
1.122 + def GET(self):
1.123 +
1.124 + # pick the arguments
1.125 + args = web.input()
1.126 +
1.127 + # we _need_ a text
1.128 + if not "text" in args:
1.129 + raise web.badrequest('no text given')
1.130 +
1.131 + # remember remote ip
1.132 + remote_ip = web.ctx.environ['REMOTE_ADDR']
1.133 +
1.134 + # create the process which queries the user
1.135 + dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.pyw')
1.136 + process_command = [sys.executable, dlg_image, 'keyfile', args.text]
1.137 + process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.138 +
1.139 + # run process result handling in seprate thread (not to block main one)
1.140 + bouncer = UserResultBouncer(process, remote_ip, '/keyfile')
1.141 + bouncer.start()
1.142 +
1.143 + return 'user queried for password and keyfile'
1.144
1.145
1.146 class os_notification:
1.147 +
1.148 """OpenSecurity '/notification' handler.
1.149
1.150 This is called on GET /notification?msgtype=TYPE&text=TEXT.
1.151 @@ -157,14 +147,11 @@
1.152 # pick the arguments
1.153 args = web.input()
1.154
1.155 - if "message" in args:
1.156 - print args.message
1.157 -
1.158 # we _need_ a type
1.159 if not "msgtype" in args:
1.160 raise web.badrequest('no msgtype given')
1.161
1.162 - if not args.msgtype in Notification.TYPES:
1.163 + if not args.msgtype in ['information', 'warning', 'critical']:
1.164 raise web.badrequest('Unknown value for msgtype')
1.165
1.166 # we _need_ a text
1.167 @@ -175,47 +162,12 @@
1.168 dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
1.169 process_command = [sys.executable, dlg_image, 'notification-' + args.msgtype, args.text]
1.170 process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.171 +
1.172 return "Ok"
1.173
1.174 -class PasswordSender(threading.Thread):
1.175 - remote_ip = None
1.176 - args = None
1.177 - def __init__(self, remote_ip, args):
1.178 - threading.Thread.__init__(self)
1.179 - self.args = args
1.180 - self.remote_ip = remote_ip
1.181 -
1.182 - def stop(self):
1.183 - self.running = False
1.184 -
1.185 - def run(self):
1.186 - # invoke the user dialog as a subprocess
1.187 - dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
1.188 - process_command = [sys.executable, dlg_image, 'password', self.args.text]
1.189 - process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.190 - result = process.communicate()[0]
1.191 - if process.returncode != 0:
1.192 - print 'password request has been aborted.'
1.193 - return
1.194 -
1.195 - # all ok, tell send request back appropriate destination
1.196 - try:
1.197 - password = result.split(':')[1].split("'")[1]
1.198 - except:
1.199 - print 'error in password parsing'
1.200 - return
1.201 -
1.202 - url_addr = 'http://' + self.remote_ip + ':58080/password'
1.203 - url_data = urllib.urlencode({ 'password': password})
1.204 - url = url_addr + '?' + url_data
1.205 - req = urllib2.Request(url)
1.206 - try:
1.207 - res = urllib2.urlopen(req)
1.208 - except:
1.209 - print 'failed to contact: ' + url_addr
1.210 - return
1.211
1.212 class os_password:
1.213 +
1.214 """OpenSecurity '/password' handler.
1.215
1.216 This is called on GET /password?text=TEXT.
1.217 @@ -235,13 +187,20 @@
1.218 # remember remote ip
1.219 remote_ip = web.ctx.environ['REMOTE_ADDR']
1.220
1.221 - sender = PasswordSender(remote_ip, args)
1.222 - sender.start()
1.223 + # create the process which queries the user
1.224 + dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.pyw')
1.225 + process_command = [sys.executable, dlg_image, 'password', args.text]
1.226 + process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
1.227
1.228 - return 'password told'
1.229 + # run process result handling in seprate thread (not to block main one)
1.230 + bouncer = UserResultBouncer(process, remote_ip, '/password')
1.231 + bouncer.start()
1.232 +
1.233 + return 'user queried for password'
1.234
1.235
1.236 class os_root:
1.237 +
1.238 """OpenSecurity '/' handler"""
1.239
1.240 def GET(self):
1.241 @@ -271,6 +230,15 @@
1.242 NOTE: check yout taskbar, the dialog window may not pop up in front of your browser window.
1.243
1.244
1.245 +Request a combination of password and keyfile:
1.246 + (copy paste this into your browser's address field after the host:port)
1.247 +
1.248 + /keyfile?text=Your%20private%20RSA%20Keyfile%3A
1.249 +
1.250 + (eg.: http://127.0.0.1:8090//keyfile?text=Your%20private%20RSA%20Keyfile%3A)
1.251 + NOTE: check yout taskbar, the dialog window may not pop up in front of your browser window.
1.252 +
1.253 +
1.254 Start a Browser:
1.255 (copy paste this into your browser's address field after the host:port)
1.256
1.257 @@ -282,7 +250,57 @@
1.258 return res
1.259
1.260
1.261 +class UserResultBouncer(threading.Thread):
1.262 +
1.263 + """A class to spawn off user I/O waiting and push the data back to the requesting services."""
1.264 +
1.265 + def __init__(self, process, remote_ip, resource):
1.266 +
1.267 + """ctor"""
1.268 +
1.269 + threading.Thread.__init__(self)
1.270 + self._process = process
1.271 + self._remote_ip = remote_ip
1.272 + self._resource = resource
1.273 +
1.274 +
1.275 + def stop(self):
1.276 +
1.277 + """stop thread"""
1.278 + self.running = False
1.279 +
1.280 +
1.281 + def run(self):
1.282 +
1.283 + """run the thread"""
1.284 +
1.285 + # invoke the user dialog as a subprocess
1.286 + result = self._process.communicate()[0]
1.287 + if self._process.returncode != 0:
1.288 + print 'user request has been aborted.'
1.289 + return
1.290 +
1.291 + # all ok, tell send request back appropriate destination
1.292 + try:
1.293 + j = json.loads(result)
1.294 + except:
1.295 + print 'error in password parsing'
1.296 + return
1.297 +
1.298 + # TODO: it would be WAY easier and secure if we just
1.299 + # add the result json to a HTTP-POST here.
1.300 + url_addr = 'http://' + self._remote_ip + ':58080' + self._resource
1.301 + url = url_addr + '?' + urllib.urlencode(j)
1.302 + req = urllib2.Request(url)
1.303 + try:
1.304 + res = urllib2.urlopen(req)
1.305 + except:
1.306 + print 'failed to contact: ' + url_addr
1.307 + return
1.308 +
1.309 +
1.310 # start
1.311 if __name__ == "__main__":
1.312 server = web.application(opensecurity_urls, globals())
1.313 server.run()
1.314 +
2.1 --- a/OpenSecurity/bin/opensecurity_dialog.pyw Fri Apr 25 13:23:20 2014 +0200
2.2 +++ b/OpenSecurity/bin/opensecurity_dialog.pyw Tue Apr 29 13:00:46 2014 +0200
2.3 @@ -51,7 +51,7 @@
2.4
2.5 # parse command line
2.6 parser = argparse.ArgumentParser(description = 'OpenSecurity Dialog.')
2.7 - parser.add_argument('mode', metavar='MODE', help='dialog mode: \'password\', \'credentials\', \'notification-information\', \'notification-warning\' or \'notification-critical\'')
2.8 + parser.add_argument('mode', metavar='MODE', help='dialog mode: \'password\', \'credentials\', \'keyfile\', \'notification-information\', \'notification-warning\' or \'notification-critical\'')
2.9 parser.add_argument('text', metavar='TEXT', help='text to show')
2.10 args = parser.parse_args()
2.11
2.12 @@ -63,6 +63,9 @@
2.13 if args.mode == 'credentials':
2.14 d = CredentialsDialog(args.text)
2.15
2.16 + if args.mode == 'keyfile':
2.17 + d = KeyfileDialog(args.text)
2.18 +
2.19 if args.mode == 'notification-information':
2.20 d = NotificationDialog('OpenSecurity Information', args.text)
2.21
2.22 @@ -70,7 +73,7 @@
2.23 d = NotificationDialog('OpenSecurity Warning', args.text)
2.24
2.25 if args.mode == 'notification-critical':
2.26 - d = NotificationDialog('OpenSecurity Criticali Message', args.text)
2.27 + d = NotificationDialog('OpenSecurity Critical Message', args.text)
2.28
2.29 if not 'd' in locals():
2.30 sys.stderr.write('unknown mode. type --help for help\n')
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/OpenSecurity/bin/ui/KeyfileDialog.ui Tue Apr 29 13:00:46 2014 +0200
3.3 @@ -0,0 +1,174 @@
3.4 +<?xml version="1.0" encoding="UTF-8"?>
3.5 +<ui version="4.0">
3.6 + <class>KeyfileDialog</class>
3.7 + <widget class="QDialog" name="KeyfileDialog">
3.8 + <property name="geometry">
3.9 + <rect>
3.10 + <x>0</x>
3.11 + <y>0</y>
3.12 + <width>420</width>
3.13 + <height>120</height>
3.14 + </rect>
3.15 + </property>
3.16 + <property name="sizePolicy">
3.17 + <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
3.18 + <horstretch>0</horstretch>
3.19 + <verstretch>0</verstretch>
3.20 + </sizepolicy>
3.21 + </property>
3.22 + <property name="windowTitle">
3.23 + <string>OpenSecuirty Keyfile Request</string>
3.24 + </property>
3.25 + <property name="windowIcon">
3.26 + <iconset resource="opensecurity.qrc">
3.27 + <normaloff>:/opensecurity/gfx/opensecurity_icon_64.png</normaloff>:/opensecurity/gfx/opensecurity_icon_64.png</iconset>
3.28 + </property>
3.29 + <layout class="QVBoxLayout" name="lyMain">
3.30 + <item>
3.31 + <layout class="QHBoxLayout" name="lyContent">
3.32 + <property name="spacing">
3.33 + <number>16</number>
3.34 + </property>
3.35 + <item>
3.36 + <widget class="QLabel" name="lblIcon">
3.37 + <property name="text">
3.38 + <string/>
3.39 + </property>
3.40 + <property name="pixmap">
3.41 + <pixmap resource="opensecurity.qrc">:/opensecurity/gfx/opensecurity_icon_64.png</pixmap>
3.42 + </property>
3.43 + <property name="alignment">
3.44 + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
3.45 + </property>
3.46 + </widget>
3.47 + </item>
3.48 + <item>
3.49 + <layout class="QGridLayout" name="lyCredentials" rowstretch="0,0,0,0" columnstretch="0,0,0">
3.50 + <property name="spacing">
3.51 + <number>4</number>
3.52 + </property>
3.53 + <item row="0" column="0" colspan="2">
3.54 + <widget class="QLabel" name="lblText">
3.55 + <property name="text">
3.56 + <string>TextLabel</string>
3.57 + </property>
3.58 + </widget>
3.59 + </item>
3.60 + <item row="3" column="0" colspan="2">
3.61 + <widget class="QWidget" name="wdCredentialsSpacer" native="true"/>
3.62 + </item>
3.63 + <item row="1" column="0">
3.64 + <widget class="QLabel" name="lblPassword">
3.65 + <property name="text">
3.66 + <string>&Password:</string>
3.67 + </property>
3.68 + <property name="buddy">
3.69 + <cstring>edtPassword</cstring>
3.70 + </property>
3.71 + </widget>
3.72 + </item>
3.73 + <item row="2" column="0">
3.74 + <widget class="QLabel" name="lblKeyfile">
3.75 + <property name="text">
3.76 + <string>&Keyfile:</string>
3.77 + </property>
3.78 + <property name="buddy">
3.79 + <cstring>edtKeyfile</cstring>
3.80 + </property>
3.81 + </widget>
3.82 + </item>
3.83 + <item row="2" column="1">
3.84 + <widget class="QLineEdit" name="edtKeyfile"/>
3.85 + </item>
3.86 + <item row="2" column="2">
3.87 + <widget class="QToolButton" name="btnBrowse">
3.88 + <property name="text">
3.89 + <string>...</string>
3.90 + </property>
3.91 + </widget>
3.92 + </item>
3.93 + <item row="1" column="1" colspan="2">
3.94 + <widget class="QLineEdit" name="edtPassword">
3.95 + <property name="echoMode">
3.96 + <enum>QLineEdit::Password</enum>
3.97 + </property>
3.98 + </widget>
3.99 + </item>
3.100 + </layout>
3.101 + </item>
3.102 + </layout>
3.103 + </item>
3.104 + <item>
3.105 + <layout class="QHBoxLayout" name="lyButtons">
3.106 + <item>
3.107 + <spacer name="spButtons">
3.108 + <property name="orientation">
3.109 + <enum>Qt::Horizontal</enum>
3.110 + </property>
3.111 + <property name="sizeHint" stdset="0">
3.112 + <size>
3.113 + <width>40</width>
3.114 + <height>20</height>
3.115 + </size>
3.116 + </property>
3.117 + </spacer>
3.118 + </item>
3.119 + <item>
3.120 + <widget class="QPushButton" name="btnAbout">
3.121 + <property name="minimumSize">
3.122 + <size>
3.123 + <width>100</width>
3.124 + <height>0</height>
3.125 + </size>
3.126 + </property>
3.127 + <property name="text">
3.128 + <string>&About</string>
3.129 + </property>
3.130 + </widget>
3.131 + </item>
3.132 + <item>
3.133 + <widget class="QPushButton" name="btnCancel">
3.134 + <property name="minimumSize">
3.135 + <size>
3.136 + <width>100</width>
3.137 + <height>0</height>
3.138 + </size>
3.139 + </property>
3.140 + <property name="text">
3.141 + <string>&Cancel</string>
3.142 + </property>
3.143 + </widget>
3.144 + </item>
3.145 + <item>
3.146 + <widget class="QPushButton" name="btnOk">
3.147 + <property name="minimumSize">
3.148 + <size>
3.149 + <width>100</width>
3.150 + <height>0</height>
3.151 + </size>
3.152 + </property>
3.153 + <property name="text">
3.154 + <string>&Ok</string>
3.155 + </property>
3.156 + <property name="default">
3.157 + <bool>true</bool>
3.158 + </property>
3.159 + </widget>
3.160 + </item>
3.161 + </layout>
3.162 + </item>
3.163 + </layout>
3.164 + </widget>
3.165 + <tabstops>
3.166 + <tabstop>edtPassword</tabstop>
3.167 + <tabstop>edtKeyfile</tabstop>
3.168 + <tabstop>btnBrowse</tabstop>
3.169 + <tabstop>btnAbout</tabstop>
3.170 + <tabstop>btnCancel</tabstop>
3.171 + <tabstop>btnOk</tabstop>
3.172 + </tabstops>
3.173 + <resources>
3.174 + <include location="opensecurity.qrc"/>
3.175 + </resources>
3.176 + <connections/>
3.177 +</ui>
4.1 --- a/OpenSecurity/bin/ui/Makefile Fri Apr 25 13:23:20 2014 +0200
4.2 +++ b/OpenSecurity/bin/ui/Makefile Tue Apr 29 13:00:46 2014 +0200
4.3 @@ -5,6 +5,7 @@
4.4 ui_ConfigureDialog.py \
4.5 ui_CredentialsDialog.py \
4.6 ui_LaunchDialog.py \
4.7 + ui_KeyfileDialog.py \
4.8 ui_NotificationDialog.py \
4.9 ui_PasswordDialog.py
4.10
5.1 --- a/OpenSecurity/bin/ui/__init__.py Fri Apr 25 13:23:20 2014 +0200
5.2 +++ b/OpenSecurity/bin/ui/__init__.py Tue Apr 29 13:00:46 2014 +0200
5.3 @@ -35,6 +35,7 @@
5.4 from about_dialog import AboutDialog
5.5 from configure_dialog import ConfigureDialog
5.6 from credentials_dialog import CredentialsDialog
5.7 +from keyfile_dialog import KeyfileDialog
5.8 from launch_dialog import LaunchDialog
5.9 from notification_dialog import NotificationDialog
5.10 from password_dialog import PasswordDialog
5.11 @@ -45,6 +46,7 @@
5.12 'AboutDialog',
5.13 'ConfigureDialog',
5.14 'CredentialsDialog',
5.15 + 'KeyfileDialog',
5.16 'LaunchDialog',
5.17 'NotificationDialog',
5.18 'PasswordDialog'
6.1 --- a/OpenSecurity/bin/ui/credentials_dialog.py Fri Apr 25 13:23:20 2014 +0200
6.2 +++ b/OpenSecurity/bin/ui/credentials_dialog.py Tue Apr 29 13:00:46 2014 +0200
6.3 @@ -82,12 +82,12 @@
6.4
6.5 """Ok button has been clicked."""
6.6 sys.stdout.write('{ ')
6.7 - sys.stdout.write('\'user\': \'')
6.8 + sys.stdout.write('"user": "')
6.9 sys.stdout.write(self.ui.edtUser.text())
6.10 - sys.stdout.write('\', ')
6.11 - sys.stdout.write('\'password\': \'')
6.12 + sys.stdout.write('", ')
6.13 + sys.stdout.write('"password": "')
6.14 sys.stdout.write(self.ui.edtPassword.text())
6.15 - sys.stdout.write('\' ')
6.16 + sys.stdout.write('" ')
6.17 sys.stdout.write('}\n')
6.18 self.accept()
6.19
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/OpenSecurity/bin/ui/keyfile_dialog.py Tue Apr 29 13:00:46 2014 +0200
7.3 @@ -0,0 +1,132 @@
7.4 +#!/bin/env python
7.5 +# -*- coding: utf-8 -*-
7.6 +
7.7 +# ------------------------------------------------------------
7.8 +# keyfile_dialog.pyw
7.9 +#
7.10 +# the user should give us a keyfile
7.11 +#
7.12 +# Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
7.13 +#
7.14 +# Copyright (C) 2014 AIT Austrian Institute of Technology
7.15 +# AIT Austrian Institute of Technology GmbH
7.16 +# Donau-City-Strasse 1 | 1220 Vienna | Austria
7.17 +# http://www.ait.ac.at
7.18 +#
7.19 +# This program is free software; you can redistribute it and/or
7.20 +# modify it under the terms of the GNU General Public License
7.21 +# as published by the Free Software Foundation version 2.
7.22 +#
7.23 +# This program is distributed in the hope that it will be useful,
7.24 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
7.25 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.26 +# GNU General Public License for more details.
7.27 +#
7.28 +# You should have received a copy of the GNU General Public License
7.29 +# along with this program; if not, write to the Free Software
7.30 +# Foundation, Inc., 51 Franklin Street, Fifth Floor,
7.31 +# Boston, MA 02110-1301, USA.
7.32 +# ------------------------------------------------------------
7.33 +
7.34 +
7.35 +# ------------------------------------------------------------
7.36 +# imports
7.37 +
7.38 +import base64
7.39 +import sys
7.40 +
7.41 +from PyQt4 import QtCore
7.42 +from PyQt4 import QtGui
7.43 +
7.44 +from ui_KeyfileDialog import Ui_KeyfileDialog
7.45 +from about_dialog import AboutDialog
7.46 +
7.47 +
7.48 +# ------------------------------------------------------------
7.49 +# code
7.50 +
7.51 +
7.52 +class KeyfileDialog(QtGui.QDialog):
7.53 +
7.54 + """A dialog for letting the user pass on a password/keyfile combo"""
7.55 +
7.56 + def __init__(self, user_text = 'Please provide an approbitate password and keyfile to proceed:'):
7.57 +
7.58 + QtGui.QDialog.__init__(self)
7.59 +
7.60 + # setup the user interface
7.61 + self.ui = Ui_KeyfileDialog()
7.62 + self.ui.setupUi(self)
7.63 +
7.64 + # local members
7.65 + self._about_dialog = AboutDialog()
7.66 + self._open_file_dialog = QtGui.QFileDialog(self, 'Open Keyfile', QtCore.QDir.homePath(), 'All Files (*.*);;')
7.67 + self._open_file_dialog.setAcceptMode(QtGui.QFileDialog.AcceptOpen)
7.68 + self._open_file_dialog.setFileMode(QtGui.QFileDialog.ExistingFile)
7.69 +
7.70 + # connectors
7.71 + self.ui.lblText.setText(user_text)
7.72 + self.ui.btnAbout.clicked.connect(self.clicked_about)
7.73 + self.ui.btnCancel.clicked.connect(self.reject)
7.74 + self.ui.btnOk.clicked.connect(self.clicked_ok)
7.75 + self.ui.btnBrowse.clicked.connect(self.clicked_browse)
7.76 +
7.77 + # positionate ourself central
7.78 + screen = QtGui.QDesktopWidget().screenGeometry()
7.79 + size = self.geometry()
7.80 + self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
7.81 +
7.82 +
7.83 + def clicked_about(self):
7.84 +
7.85 + """About button has been clicked."""
7.86 + self._about_dialog.show()
7.87 +
7.88 +
7.89 + def clicked_browse(self):
7.90 +
7.91 + """Browse button has been clicked."""
7.92 + if self._open_file_dialog.exec_() == QtGui.QDialog.Accepted:
7.93 + self.ui.edtKeyfile.setText(self._open_file_dialog.selectedFiles()[0])
7.94 +
7.95 +
7.96 + def clicked_ok(self):
7.97 +
7.98 + """Ok button has been clicked."""
7.99 +
7.100 + # read the content of the keyfile
7.101 + keyfile_content = ''
7.102 + try:
7.103 + keyfile = open(self.ui.edtKeyfile.text(), 'r')
7.104 + keyfile_content = keyfile.read()
7.105 + except Exception as e:
7.106 + sys.stderr.write('failed to read keyfile content:\n' + str(e) + '\n')
7.107 + QtGui.QMessageBox.critical(self, 'Failed to read keyfile', str(e))
7.108 + return
7.109 +
7.110 + # turn into Base64
7.111 + keyfile_content_base64 = base64.b64encode(keyfile_content)
7.112 +
7.113 + sys.stdout.write('{ ')
7.114 + sys.stdout.write('"password": "')
7.115 + sys.stdout.write(self.ui.edtPassword.text())
7.116 + sys.stdout.write('", ')
7.117 + sys.stdout.write('"keyfile": "')
7.118 + sys.stdout.write(keyfile_content_base64)
7.119 + sys.stdout.write('" ')
7.120 + sys.stdout.write('}\n')
7.121 + self.accept()
7.122 +
7.123 +
7.124 + def set_user_text(user_text):
7.125 +
7.126 + """Set a text to explain which password we need."""
7.127 + self.ui.lblText.setText(user_text)
7.128 +
7.129 +
7.130 +if __name__ == "__main__":
7.131 + a = QtGui.QApplication(sys.argv)
7.132 + d = KeyfileDialog()
7.133 + d.show()
7.134 + sys.exit(a.exec_())
7.135 +
8.1 --- a/OpenSecurity/bin/ui/password_dialog.py Fri Apr 25 13:23:20 2014 +0200
8.2 +++ b/OpenSecurity/bin/ui/password_dialog.py Tue Apr 29 13:00:46 2014 +0200
8.3 @@ -47,7 +47,7 @@
8.4
8.5 class PasswordDialog(QtGui.QDialog):
8.6
8.7 - """A dialog for letting the user pass on a user/password combo"""
8.8 + """A dialog for letting the user type in a password"""
8.9
8.10 def __init__(self, user_text = 'Please provide an approbitate password to proceed:'):
8.11
8.12 @@ -82,9 +82,9 @@
8.13
8.14 """Ok button has been clicked."""
8.15 sys.stdout.write('{ ')
8.16 - sys.stdout.write('\'password\': \'')
8.17 + sys.stdout.write('"password": "')
8.18 sys.stdout.write(self.ui.edtPassword.text())
8.19 - sys.stdout.write('\' ')
8.20 + sys.stdout.write('" ')
8.21 sys.stdout.write('}\n')
8.22 self.accept()
8.23
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/OpenSecurity/bin/ui/ui_KeyfileDialog.py Tue Apr 29 13:00:46 2014 +0200
9.3 @@ -0,0 +1,115 @@
9.4 +# -*- coding: utf-8 -*-
9.5 +
9.6 +# Form implementation generated from reading ui file 'KeyfileDialog.ui'
9.7 +#
9.8 +# Created: Tue Apr 29 10:47:26 2014
9.9 +# by: PyQt4 UI code generator 4.10.3
9.10 +#
9.11 +# WARNING! All changes made in this file will be lost!
9.12 +
9.13 +from PyQt4 import QtCore, QtGui
9.14 +
9.15 +try:
9.16 + _fromUtf8 = QtCore.QString.fromUtf8
9.17 +except AttributeError:
9.18 + def _fromUtf8(s):
9.19 + return s
9.20 +
9.21 +try:
9.22 + _encoding = QtGui.QApplication.UnicodeUTF8
9.23 + def _translate(context, text, disambig):
9.24 + return QtGui.QApplication.translate(context, text, disambig, _encoding)
9.25 +except AttributeError:
9.26 + def _translate(context, text, disambig):
9.27 + return QtGui.QApplication.translate(context, text, disambig)
9.28 +
9.29 +class Ui_KeyfileDialog(object):
9.30 + def setupUi(self, KeyfileDialog):
9.31 + KeyfileDialog.setObjectName(_fromUtf8("KeyfileDialog"))
9.32 + KeyfileDialog.resize(420, 120)
9.33 + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
9.34 + sizePolicy.setHorizontalStretch(0)
9.35 + sizePolicy.setVerticalStretch(0)
9.36 + sizePolicy.setHeightForWidth(KeyfileDialog.sizePolicy().hasHeightForWidth())
9.37 + KeyfileDialog.setSizePolicy(sizePolicy)
9.38 + icon = QtGui.QIcon()
9.39 + icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
9.40 + KeyfileDialog.setWindowIcon(icon)
9.41 + self.lyMain = QtGui.QVBoxLayout(KeyfileDialog)
9.42 + self.lyMain.setObjectName(_fromUtf8("lyMain"))
9.43 + self.lyContent = QtGui.QHBoxLayout()
9.44 + self.lyContent.setSpacing(16)
9.45 + self.lyContent.setObjectName(_fromUtf8("lyContent"))
9.46 + self.lblIcon = QtGui.QLabel(KeyfileDialog)
9.47 + self.lblIcon.setText(_fromUtf8(""))
9.48 + self.lblIcon.setPixmap(QtGui.QPixmap(_fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")))
9.49 + self.lblIcon.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
9.50 + self.lblIcon.setObjectName(_fromUtf8("lblIcon"))
9.51 + self.lyContent.addWidget(self.lblIcon)
9.52 + self.lyCredentials = QtGui.QGridLayout()
9.53 + self.lyCredentials.setSpacing(4)
9.54 + self.lyCredentials.setObjectName(_fromUtf8("lyCredentials"))
9.55 + self.lblText = QtGui.QLabel(KeyfileDialog)
9.56 + self.lblText.setObjectName(_fromUtf8("lblText"))
9.57 + self.lyCredentials.addWidget(self.lblText, 0, 0, 1, 2)
9.58 + self.wdCredentialsSpacer = QtGui.QWidget(KeyfileDialog)
9.59 + self.wdCredentialsSpacer.setObjectName(_fromUtf8("wdCredentialsSpacer"))
9.60 + self.lyCredentials.addWidget(self.wdCredentialsSpacer, 3, 0, 1, 2)
9.61 + self.lblPassword = QtGui.QLabel(KeyfileDialog)
9.62 + self.lblPassword.setObjectName(_fromUtf8("lblPassword"))
9.63 + self.lyCredentials.addWidget(self.lblPassword, 1, 0, 1, 1)
9.64 + self.lblKeyfile = QtGui.QLabel(KeyfileDialog)
9.65 + self.lblKeyfile.setObjectName(_fromUtf8("lblKeyfile"))
9.66 + self.lyCredentials.addWidget(self.lblKeyfile, 2, 0, 1, 1)
9.67 + self.edtKeyfile = QtGui.QLineEdit(KeyfileDialog)
9.68 + self.edtKeyfile.setObjectName(_fromUtf8("edtKeyfile"))
9.69 + self.lyCredentials.addWidget(self.edtKeyfile, 2, 1, 1, 1)
9.70 + self.btnBrowse = QtGui.QToolButton(KeyfileDialog)
9.71 + self.btnBrowse.setObjectName(_fromUtf8("btnBrowse"))
9.72 + self.lyCredentials.addWidget(self.btnBrowse, 2, 2, 1, 1)
9.73 + self.edtPassword = QtGui.QLineEdit(KeyfileDialog)
9.74 + self.edtPassword.setEchoMode(QtGui.QLineEdit.Password)
9.75 + self.edtPassword.setObjectName(_fromUtf8("edtPassword"))
9.76 + self.lyCredentials.addWidget(self.edtPassword, 1, 1, 1, 2)
9.77 + self.lyContent.addLayout(self.lyCredentials)
9.78 + self.lyMain.addLayout(self.lyContent)
9.79 + self.lyButtons = QtGui.QHBoxLayout()
9.80 + self.lyButtons.setObjectName(_fromUtf8("lyButtons"))
9.81 + spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
9.82 + self.lyButtons.addItem(spacerItem)
9.83 + self.btnAbout = QtGui.QPushButton(KeyfileDialog)
9.84 + self.btnAbout.setMinimumSize(QtCore.QSize(100, 0))
9.85 + self.btnAbout.setObjectName(_fromUtf8("btnAbout"))
9.86 + self.lyButtons.addWidget(self.btnAbout)
9.87 + self.btnCancel = QtGui.QPushButton(KeyfileDialog)
9.88 + self.btnCancel.setMinimumSize(QtCore.QSize(100, 0))
9.89 + self.btnCancel.setObjectName(_fromUtf8("btnCancel"))
9.90 + self.lyButtons.addWidget(self.btnCancel)
9.91 + self.btnOk = QtGui.QPushButton(KeyfileDialog)
9.92 + self.btnOk.setMinimumSize(QtCore.QSize(100, 0))
9.93 + self.btnOk.setDefault(True)
9.94 + self.btnOk.setObjectName(_fromUtf8("btnOk"))
9.95 + self.lyButtons.addWidget(self.btnOk)
9.96 + self.lyMain.addLayout(self.lyButtons)
9.97 + self.lblPassword.setBuddy(self.edtPassword)
9.98 + self.lblKeyfile.setBuddy(self.edtKeyfile)
9.99 +
9.100 + self.retranslateUi(KeyfileDialog)
9.101 + QtCore.QMetaObject.connectSlotsByName(KeyfileDialog)
9.102 + KeyfileDialog.setTabOrder(self.edtPassword, self.edtKeyfile)
9.103 + KeyfileDialog.setTabOrder(self.edtKeyfile, self.btnBrowse)
9.104 + KeyfileDialog.setTabOrder(self.btnBrowse, self.btnAbout)
9.105 + KeyfileDialog.setTabOrder(self.btnAbout, self.btnCancel)
9.106 + KeyfileDialog.setTabOrder(self.btnCancel, self.btnOk)
9.107 +
9.108 + def retranslateUi(self, KeyfileDialog):
9.109 + KeyfileDialog.setWindowTitle(_translate("KeyfileDialog", "OpenSecuirty Keyfile Request", None))
9.110 + self.lblText.setText(_translate("KeyfileDialog", "TextLabel", None))
9.111 + self.lblPassword.setText(_translate("KeyfileDialog", "&Password:", None))
9.112 + self.lblKeyfile.setText(_translate("KeyfileDialog", "&Keyfile:", None))
9.113 + self.btnBrowse.setText(_translate("KeyfileDialog", "...", None))
9.114 + self.btnAbout.setText(_translate("KeyfileDialog", "&About", None))
9.115 + self.btnCancel.setText(_translate("KeyfileDialog", "&Cancel", None))
9.116 + self.btnOk.setText(_translate("KeyfileDialog", "&Ok", None))
9.117 +
9.118 +import opensecurity_rc