1.1 --- a/OpenSecurity/bin/credentials.py Mon Dec 09 11:52:43 2013 +0100
1.2 +++ b/OpenSecurity/bin/credentials.py Mon Dec 09 14:44:41 2013 +0100
1.3 @@ -107,7 +107,7 @@
1.4
1.5 # text ...
1.6 lyText = QtGui.QGridLayout()
1.7 - lyContent.addLayout(lyText)
1.8 + lyContent.addLayout(lyText, 1)
1.9 self.lbText = QtGui.QLabel()
1.10 lyText.addWidget(self.lbText, 0, 0, 1, 2)
1.11
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/OpenSecurity/bin/notification.py Mon Dec 09 14:44:41 2013 +0100
2.3 @@ -0,0 +1,151 @@
2.4 +#!/bin/env python
2.5 +# -*- coding: utf-8 -*-
2.6 +
2.7 +# ------------------------------------------------------------
2.8 +# notification-dialog
2.9 +#
2.10 +# show the user an opensecurity specific message box
2.11 +#
2.12 +# Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
2.13 +#
2.14 +# Copyright (C) 2013 AIT Austrian Institute of Technology
2.15 +# AIT Austrian Institute of Technology GmbH
2.16 +# Donau-City-Strasse 1 | 1220 Vienna | Austria
2.17 +# http://www.ait.ac.at
2.18 +#
2.19 +# This program is free software; you can redistribute it and/or
2.20 +# modify it under the terms of the GNU General Public License
2.21 +# as published by the Free Software Foundation version 2.
2.22 +#
2.23 +# This program is distributed in the hope that it will be useful,
2.24 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
2.25 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.26 +# GNU General Public License for more details.
2.27 +#
2.28 +# You should have received a copy of the GNU General Public License
2.29 +# along with this program; if not, write to the Free Software
2.30 +# Foundation, Inc., 51 Franklin Street, Fifth Floor,
2.31 +# Boston, MA 02110-1301, USA.
2.32 +# ------------------------------------------------------------
2.33 +
2.34 +
2.35 +# ------------------------------------------------------------
2.36 +# imports
2.37 +
2.38 +import sys
2.39 +
2.40 +from PyQt4 import QtCore
2.41 +from PyQt4 import QtGui
2.42 +
2.43 +# local
2.44 +from about import About
2.45 +
2.46 +
2.47 +# ------------------------------------------------------------
2.48 +# code
2.49 +
2.50 +class Notification(QtGui.QDialog):
2.51 +
2.52 + """Show the user an OpenSecurity specific notification."""
2.53 +
2.54 + TYPES = ['information', 'warning', 'critical']
2.55 +
2.56 + def __init__(self, msgtype, text, parent = None, flags = QtCore.Qt.WindowFlags(0)):
2.57 +
2.58 + # super call and widget init
2.59 + super(Notification, self).__init__(parent, flags)
2.60 + self.setWindowTitle('OpenSecuirty Notification')
2.61 + self.setup_ui(msgtype)
2.62 +
2.63 + # positionate ourself central
2.64 + screen = QtGui.QDesktopWidget().screenGeometry()
2.65 + self.resize(self.geometry().width() * 1.25, self.geometry().height())
2.66 + size = self.geometry()
2.67 + self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
2.68 +
2.69 + # fix up text
2.70 + if msgtype in Notification.TYPES:
2.71 +
2.72 + typetext = {
2.73 + 'information': 'OpenSecurity information',
2.74 + 'warning': '<b>OpenSecurity warning</b>',
2.75 + 'critical': '<b>OpenSecurity critical error</b>'
2.76 + }
2.77 + self.lbMsgType.setText(typetext[msgtype])
2.78 +
2.79 + captiontext = {
2.80 + 'information': 'OpenSecurity: Information',
2.81 + 'warning': 'OpenSecurity: Warning',
2.82 + 'critical': 'OpenSecurity: Critical'
2.83 + }
2.84 + self.setWindowTitle(captiontext[msgtype])
2.85 +
2.86 + else:
2.87 + raise ValueError('unknown msgtype')
2.88 +
2.89 + self.lbText.setText(text)
2.90 +
2.91 +
2.92 + def clicked_about(self):
2.93 + """clicked the about button"""
2.94 + dlgAbout = About()
2.95 + dlgAbout.exec_()
2.96 +
2.97 +
2.98 + def clicked_ok(self):
2.99 + """clicked the ok button"""
2.100 + self.accept()
2.101 +
2.102 +
2.103 + def setup_ui(self, msgtype):
2.104 +
2.105 + """Create the widgets."""
2.106 +
2.107 + lyMain = QtGui.QVBoxLayout(self)
2.108 + lyMain.setContentsMargins(8, 8, 8, 8)
2.109 +
2.110 + # content area: left pixmap, right text
2.111 + lyContent = QtGui.QHBoxLayout()
2.112 + lyMain.addLayout(lyContent)
2.113 +
2.114 + # pixmap
2.115 + lbPix = QtGui.QLabel()
2.116 + lbPix.setPixmap(QtGui.QPixmapCache.find('opensecurity_icon_64'))
2.117 + lyContent.addWidget(lbPix, 0, QtCore.Qt.Alignment(QtCore.Qt.AlignTop + QtCore.Qt.AlignHCenter))
2.118 + lyContent.addSpacing(16)
2.119 +
2.120 + # text ...
2.121 + lyText = QtGui.QVBoxLayout()
2.122 + lyContent.addLayout(lyText, 1)
2.123 +
2.124 + self.lbMsgType = QtGui.QLabel()
2.125 + lyText.addWidget(self.lbMsgType)
2.126 + self.lbText = QtGui.QLabel()
2.127 + lyText.addWidget(self.lbText)
2.128 + lyText.addStretch(1)
2.129 +
2.130 + lyMain.addStretch(1)
2.131 +
2.132 + # buttons
2.133 + lyButton = QtGui.QHBoxLayout()
2.134 + lyMain.addLayout(lyButton)
2.135 +
2.136 + lyButton.addStretch(1)
2.137 + btnOk = QtGui.QPushButton('&Ok', self)
2.138 + btnOk.setDefault(True)
2.139 + btnOk.setMinimumWidth(100)
2.140 + lyButton.addWidget(btnOk)
2.141 + btnAbout = QtGui.QPushButton('&About', self)
2.142 + btnAbout.setMinimumWidth(100)
2.143 + lyButton.addWidget(btnAbout)
2.144 +
2.145 + button_width = max(btnOk.width(), btnAbout.width())
2.146 + btnOk.setMinimumWidth(button_width)
2.147 + btnAbout.setMinimumWidth(button_width)
2.148 +
2.149 + # reduce to the max
2.150 + self.resize(lyMain.minimumSize())
2.151 +
2.152 + # connectors
2.153 + btnOk.clicked.connect(self.clicked_ok)
2.154 + btnAbout.clicked.connect(self.clicked_about)
3.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py Mon Dec 09 11:52:43 2013 +0100
3.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py Mon Dec 09 14:44:41 2013 +0100
3.3 @@ -36,10 +36,13 @@
3.4 import os.path
3.5 import subprocess
3.6 import sys
3.7 +import urllib
3.8 +import urllib2
3.9 import web
3.10
3.11 # local
3.12 from environment import Environment
3.13 +from notification import Notification
3.14 import opensecurity_server
3.15
3.16
3.17 @@ -54,6 +57,7 @@
3.18 opensecurity_urls = (
3.19 '/application', 'os_application',
3.20 '/credentials', 'os_credentials',
3.21 + '/notification', 'os_notification',
3.22 '/password', 'os_password',
3.23 '/', 'os_root'
3.24 )
3.25 @@ -78,11 +82,11 @@
3.26
3.27 # we _need_ a vm
3.28 if not "vm" in args:
3.29 - raise web.badrequest()
3.30 + raise web.badrequest('no vm given')
3.31
3.32 # we _need_ a app
3.33 if not "app" in args:
3.34 - raise web.badrequest()
3.35 + raise web.badrequest('no app given')
3.36
3.37 apps = opensecurity_server.query_apps()
3.38 vms = opensecurity_server.query_vms()
3.39 @@ -125,13 +129,13 @@
3.40 # pick the arguments
3.41 args = web.input()
3.42
3.43 - # we _need_ a device id
3.44 + # we _need_ a text
3.45 if not "text" in args:
3.46 - raise web.badrequest()
3.47 + raise web.badrequest('no text given')
3.48
3.49 # invoke the user dialog as a subprocess
3.50 - dlg_credentials_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
3.51 - process_command = [sys.executable, dlg_credentials_image, 'credentials', args.text]
3.52 + dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
3.53 + process_command = [sys.executable, dlg_image, 'credentials', args.text]
3.54 process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
3.55 result = process.communicate()[0]
3.56 if process.returncode != 0:
3.57 @@ -140,6 +144,36 @@
3.58 return result
3.59
3.60
3.61 +class os_notification:
3.62 + """OpenSecurity '/notification' handler.
3.63 +
3.64 + This is called on GET /notification?msgtype=TYPE&text=TEXT.
3.65 + This will pop up an OpenSecurity notifcation window
3.66 + """
3.67 +
3.68 + def GET(self):
3.69 +
3.70 + # pick the arguments
3.71 + args = web.input()
3.72 +
3.73 + # we _need_ a type
3.74 + if not "msgtype" in args:
3.75 + raise web.badrequest('no msgtype given')
3.76 +
3.77 + if not args.msgtype in Notification.TYPES:
3.78 + raise web.badrequest('Unknown value for msgtype')
3.79 +
3.80 + # we _need_ a text
3.81 + if not "text" in args:
3.82 + raise web.badrequest('no text given')
3.83 +
3.84 + # invoke the user dialog as a subprocess
3.85 + dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
3.86 + process_command = [sys.executable, dlg_image, 'notification-' + args.msgtype, args.text]
3.87 + process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
3.88 + return "Ok"
3.89 +
3.90 +
3.91 class os_password:
3.92 """OpenSecurity '/password' handler.
3.93
3.94 @@ -153,19 +187,45 @@
3.95 # pick the arguments
3.96 args = web.input()
3.97
3.98 - # we _need_ a device id
3.99 + # we _need_ a text
3.100 if not "text" in args:
3.101 - raise web.badrequest()
3.102 + raise web.badrequest('no text given')
3.103
3.104 + # remember remote ip
3.105 + remote_ip = web.ctx.environ['REMOTE_ADDR']
3.106 +
3.107 # invoke the user dialog as a subprocess
3.108 - dlg_credentials_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
3.109 - process_command = [sys.executable, dlg_credentials_image, 'password', args.text]
3.110 + dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
3.111 + process_command = [sys.executable, dlg_image, 'password', args.text]
3.112 process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
3.113 result = process.communicate()[0]
3.114 if process.returncode != 0:
3.115 return 'password request has been aborted.'
3.116
3.117 - return result
3.118 + # all ok, tell send request back appropriate destination
3.119 +
3.120 + # the returned value of the dialog is a jason object like
3.121 + # "{ 'password': 'THE_PASSWORD' }"
3.122 + # so we _could_ call eval(...) on this.
3.123 + #
3.124 + # However, anyone malicious enough _could_ encode a certain
3.125 + # "password" making some nasty things within that eval code. :(
3.126 + #
3.127 + # So this is plain old-school string hacking then ...
3.128 + try:
3.129 + password = result.split(':')[1].split("'")[1]
3.130 + except:
3.131 + raise web.internalerror('error in password parsing')
3.132 +
3.133 + url_addr = 'http://' + remote_ip + ':58080/password'
3.134 + url_data = urllib.urlencode({ 'password': password})
3.135 + req = urllib2.Request(url = url_addr + '?' + url_data)
3.136 + try:
3.137 + res = urllib2.urlopen(req)
3.138 + except:
3.139 + raise web.internalerror('failed to contact: ' + url_addr)
3.140 +
3.141 + return 'password told'
3.142
3.143
3.144 class os_root:
4.1 --- a/OpenSecurity/bin/opensecurity_dialog.py Mon Dec 09 11:52:43 2013 +0100
4.2 +++ b/OpenSecurity/bin/opensecurity_dialog.py Mon Dec 09 14:44:41 2013 +0100
4.3 @@ -42,6 +42,7 @@
4.4 # local
4.5 from credentials import Credentials
4.6 from environment import Environment
4.7 +from notification import Notification
4.8 from password import Password
4.9
4.10
4.11 @@ -53,7 +54,7 @@
4.12
4.13 # parse command line
4.14 parser = argparse.ArgumentParser(description = 'OpenSecurity Dialog.')
4.15 - parser.add_argument('mode', metavar='MODE', help='dialog mode: \'password\' or \'credentials\'')
4.16 + parser.add_argument('mode', metavar='MODE', help='dialog mode: \'password\', \'credentials\', \'notification-information\', \'notification-warning\' or \'notification-critical\'')
4.17 parser.add_argument('text', metavar='TEXT', help='text to show')
4.18 args = parser.parse_args()
4.19
4.20 @@ -75,6 +76,18 @@
4.21 if args.mode == 'credentials':
4.22 dlg = Credentials(args.text)
4.23
4.24 + if args.mode == 'notification-information':
4.25 + dlg = Notification('information', args.text)
4.26 +
4.27 + if args.mode == 'notification-warning':
4.28 + dlg = Notification('warning', args.text)
4.29 +
4.30 + if args.mode == 'notification-critical':
4.31 + dlg = Notification('critical', args.text)
4.32 +
4.33 + if not 'dlg' in locals():
4.34 + raise ValueError('unknown mode. type --help for help')
4.35 +
4.36 # pop up the dialog
4.37 dlg.show()
4.38 app.exec_()
5.1 --- a/OpenSecurity/bin/password.py Mon Dec 09 11:52:43 2013 +0100
5.2 +++ b/OpenSecurity/bin/password.py Mon Dec 09 14:44:41 2013 +0100
5.3 @@ -105,7 +105,7 @@
5.4
5.5 # text ...
5.6 lyText = QtGui.QVBoxLayout()
5.7 - lyContent.addLayout(lyText)
5.8 + lyContent.addLayout(lyText, 1)
5.9 self.lbText = QtGui.QLabel()
5.10 lyText.addWidget(self.lbText)
5.11 lyPassword = QtGui.QHBoxLayout()
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/OpenSecurity/test/get-notification.bat Mon Dec 09 14:44:41 2013 +0100
6.3 @@ -0,0 +1,4 @@
6.4 +@echo off
6.5 +..\cygwin\bin\curl --get --data-urlencode "msgtype=information" --data-urlencode "text=Alle Daten wurden vernichtet." http://127.0.0.1:8090/notification
6.6 +..\cygwin\bin\curl --get --data-urlencode "msgtype=warning" --data-urlencode "text=Christkind in PDF entdeckt." http://127.0.0.1:8090/notification
6.7 +..\cygwin\bin\curl --get --data-urlencode "msgtype=critical" --data-urlencode "text=Influenza.Win7 im Bootsektor." http://127.0.0.1:8090/notification