OpenSecurity/bin/opensecurity_tray.pyw
author Bartha Mihai <mihai.bartha@ait.ac.at>
Tue, 11 Nov 2014 16:19:03 +0100
changeset 249 5547ed24adf3
parent 246 49efb610d200
permissions -rwxr-xr-x
fixed small problem with format menu update
om@13
     1
# -*- coding: utf-8 -*-
om@13
     2
om@13
     3
# ------------------------------------------------------------
om@13
     4
# opensecurity-dialog
om@13
     5
# 
om@13
     6
# an opensecurity dialog
om@13
     7
#
om@13
     8
# Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
om@13
     9
#
oliver@240
    10
# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
om@13
    11
# 
om@13
    12
# 
oliver@240
    13
#     X-Net Services GmbH
oliver@240
    14
#     Elisabethstrasse 1
oliver@240
    15
#     4020 Linz
oliver@240
    16
#     AUSTRIA
oliver@240
    17
#     https://www.x-net.at
oliver@240
    18
# 
oliver@240
    19
#     AIT Austrian Institute of Technology
oliver@240
    20
#     Donau City Strasse 1
oliver@240
    21
#     1220 Wien
oliver@240
    22
#     AUSTRIA
oliver@240
    23
#     http://www.ait.ac.at
oliver@240
    24
# 
oliver@240
    25
# 
oliver@240
    26
# Licensed under the Apache License, Version 2.0 (the "License");
oliver@240
    27
# you may not use this file except in compliance with the License.
oliver@240
    28
# You may obtain a copy of the License at
oliver@240
    29
# 
oliver@240
    30
#    http://www.apache.org/licenses/LICENSE-2.0
oliver@240
    31
# 
oliver@240
    32
# Unless required by applicable law or agreed to in writing, software
oliver@240
    33
# distributed under the License is distributed on an "AS IS" BASIS,
oliver@240
    34
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
oliver@240
    35
# See the License for the specific language governing permissions and
oliver@240
    36
# limitations under the License.
om@13
    37
# ------------------------------------------------------------
om@13
    38
om@13
    39
om@13
    40
# ------------------------------------------------------------
om@13
    41
# imports
om@13
    42
om@13
    43
import argparse
oliver@165
    44
import json
om@13
    45
import os
om@13
    46
import subprocess
om@13
    47
import sys
oliver@145
    48
import urllib
om@42
    49
import urllib2
oliver@145
    50
import webbrowser
om@13
    51
om@13
    52
from PyQt4 import QtCore
om@13
    53
from PyQt4 import QtGui
om@13
    54
om@13
    55
# local
oliver@144
    56
import __init__ as opensecurity
oliver@144
    57
oliver@104
    58
if sys.platform == 'win32' or sys.platform == 'cygwin':
oliver@104
    59
    from cygwin import Cygwin
oliver@104
    60
oliver@136
    61
import opensecurity_client_restful_server 
BarthaM@234
    62
import proxy_getter
oliver@104
    63
from ui import AboutDialog
oliver@106
    64
from ui import ConfigureDialog
oliver@104
    65
from ui import opensecurity_rc
om@13
    66
om@13
    67
# ------------------------------------------------------------
om@13
    68
# code
om@13
    69
om@13
    70
om@42
    71
class OpenSecurityWait(QtGui.QDialog):
om@42
    72
om@42
    73
    """OpenSecurity: please wait ..."""
om@42
    74
    
om@42
    75
    def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags(0)):
om@42
    76
        super(OpenSecurityWait, self).__init__(parent, flags)
om@42
    77
        self.setWindowTitle('OpenSecurity')
om@42
    78
        self.setup_ui()
om@42
    79
        
om@42
    80
        
om@42
    81
    def setup_ui(self):
om@42
    82
        """Create the widgets."""
om@42
    83
        
om@42
    84
        lyMain = QtGui.QVBoxLayout(self)
om@42
    85
        lyMain.setContentsMargins(8, 8, 8, 8)
om@42
    86
        
om@42
    87
        # content area: left pixmap, right text
om@42
    88
        lbTitle = QtGui.QLabel('Creating secure subsystem. Please stand by ...')
om@42
    89
        lyMain.addWidget(lbTitle)
om@42
    90
        
om@42
    91
        self.setMinimumSize(400, 50)
om@42
    92
        self.resize(lyMain.minimumSize())
om@42
    93
om@42
    94
om@13
    95
class OpenSecurityTrayIcon(QtGui.QSystemTrayIcon):
om@13
    96
    
om@13
    97
    """This is the OpenSecuirty Tray Icon"""
om@13
    98
om@13
    99
    def __init__(self, icon, parent=None):
om@13
   100
        
om@13
   101
        super(OpenSecurityTrayIcon, self).__init__(icon, parent)
om@13
   102
        self.setup_ui()
oliver@207
   103
        self.activated.connect(self.activated_)
oliver@207
   104
       
oliver@207
   105
oliver@207
   106
    def activated_(self, reason):
oliver@207
   107
oliver@207
   108
        """the system tray icon was activated"""
oliver@207
   109
        self.refresh_format_menu()
oliver@207
   110
om@13
   111
        
om@13
   112
    def clicked_about(self):
om@13
   113
        """clicked about"""
oliver@104
   114
        d = AboutDialog()
oliver@104
   115
        d.exec_()
om@13
   116
om@37
   117
    def clicked_browser(self):
om@37
   118
        """wish for safe internet browsing"""
om@42
   119
        
oliver@104
   120
        if not (sys.platform == 'win32' or sys.platform == 'cygwin'):
oliver@104
   121
            QtGui.QMessageBox.critical(self.parent(), 'OpenSecurity Error', 'This action is not supported on this platform.\nSorry.')
oliver@104
   122
            return
oliver@193
   123
       
om@42
   124
        try:
om@42
   125
            # get a proper browsing VM
mb@110
   126
            Cygwin.start_X11()
oliver@144
   127
oliver@144
   128
            # TODO: HARDCODED ADDRESS OF OPENSECURITYD
BarthaM@213
   129
            proxy_support = urllib2.ProxyHandler({})
BarthaM@213
   130
            opener = urllib2.build_opener(proxy_support)
BarthaM@213
   131
            urllib2.install_opener(opener)
BarthaM@213
   132
BarthaM@213
   133
            req_data = ""
BarthaM@234
   134
            proxy = proxy_getter.getProxySettings()
BarthaM@213
   135
            if proxy:
BarthaM@213
   136
                req_data = '?' + urllib.urlencode(proxy) 
BarthaM@213
   137
            req = 'http://127.0.0.1:8080/browsing'+ req_data
BarthaM@213
   138
            browsing_vm = urllib2.urlopen(req).readline()
BarthaM@213
   139
            print('Called '+ req + ' got: ' + str(browsing_vm))
om@42
   140
        except:
om@42
   141
            QtGui.QApplication.instance().processEvents()
om@42
   142
            QtGui.QMessageBox.critical(None, 'Failed to invoke Safe Internet Browsing', 'OpenSecurity Error')
om@42
   143
            
om@42
   144
        QtGui.QApplication.instance().processEvents()
om@37
   145
            
om@37
   146
            
oliver@106
   147
    def clicked_configure(self):
oliver@106
   148
        """clicked configure"""
oliver@106
   149
        d = ConfigureDialog()
oliver@106
   150
        d.exec_()
oliver@106
   151
    
oliver@106
   152
om@13
   153
    def clicked_exit(self):
om@13
   154
        """clicked exit"""
mihai@238
   155
        #opensecurity_client_restful_server.stop()
om@13
   156
        sys.exit(0)
om@13
   157
    
om@13
   158
om@13
   159
    def clicked_launch_application(self):
om@13
   160
        """clicked the launch an application"""
oliver@104
   161
        dlg_launch_image = os.path.join(sys.path[0], 'ui', 'launch_dialog.py')
om@13
   162
        process_command = [sys.executable, dlg_launch_image]
oliver@165
   163
        process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
oliver@165
   164
        try:
oliver@165
   165
            stdout = process.communicate()[0]
oliver@165
   166
            j = json.loads(stdout)
oliver@165
   167
        except:
oliver@165
   168
            return
oliver@165
   169
oliver@165
   170
        try:
oliver@165
   171
            # get a proper browsing VM
oliver@165
   172
            Cygwin.start_X11()
oliver@165
   173
            # TODO: HARDCODED ADDRESS OF OPENSECURITYD
oliver@165
   174
            url = 'http://127.0.0.1:8080/sdvms/' + j['vm'] + '/application' + j['application']
oliver@165
   175
            result = urllib2.urlopen(url).readline()
oliver@165
   176
        except:
oliver@165
   177
            pass 
om@13
   178
            
om@13
   179
            
oliver@144
   180
    def clicked_mail(self):
oliver@145
   181
        
oliver@144
   182
        """clicked mail"""
oliver@145
   183
        address = 'feedback@opensecurity.at'
oliver@145
   184
        subject = 'Feedback zu OpenSecurity V' + opensecurity.__version__
oliver@145
   185
oliver@145
   186
        if sys.platform == 'linux2':
oliver@145
   187
            subprocess.Popen(['xdg-email', '--subject', subject, address])
oliver@145
   188
        elif sys.platform == 'win32' or sys.platform == 'cygwin':
oliver@145
   189
            mail_url = 'mailto:' + urllib.quote(address, '@') + '?' + urllib.quote('subject=' + subject)
oliver@148
   190
            subprocess.Popen(['cmd', '/C', 'start', mail_url])
oliver@207
   191
   
oliver@207
   192
oliver@207
   193
    def format_drive(self):
oliver@207
   194
oliver@207
   195
        """format drive clicked (the sender should a QAction created with refresh_format_menu)"""
oliver@207
   196
        try:
oliver@207
   197
oliver@207
   198
            # fiddle the IP of the VM controlling the VM
oliver@207
   199
            s = self.sender()
oliver@207
   200
            ip = str(s.text().split('\\\\')[1])
oliver@207
   201
oliver@207
   202
            # invoke the format drive dialog
oliver@207
   203
            dlg_format_drive = os.path.join(sys.path[0], 'ui', 'format_drive_dialog.py')
oliver@207
   204
            process_command = [sys.executable, dlg_format_drive, ip]
oliver@207
   205
            process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
oliver@207
   206
oliver@207
   207
            stdout = process.communicate()[0]
oliver@207
   208
oliver@207
   209
        except:
oliver@207
   210
            pass
oliver@207
   211
oliver@207
   212
oliver@207
   213
    def refresh_format_menu(self):
oliver@207
   214
oliver@207
   215
        """create a new list of format 'drives'"""
oliver@207
   216
        self._menu_format.clear()
oliver@207
   217
        a = self._menu_format.addAction('<No Drive given>')
oliver@207
   218
        a.setEnabled(False)
oliver@207
   219
oliver@207
   220
        try:
oliver@207
   221
oliver@207
   222
            # get machines
oliver@207
   223
            machines = json.load(urllib2.urlopen('http://127.0.0.1:8080/sdvms'))
oliver@207
   224
            if len(machines) == 0:
oliver@207
   225
                return
oliver@207
   226
oliver@207
   227
            self._icon_network = QtGui.QIcon()
oliver@207
   228
            self._icon_network.addPixmap(QtGui.QPixmap(":/opensecurity/gfx/network-workgroup.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
oliver@207
   229
mihai@244
   230
            self._menu_format.clear()
mihai@244
   231
                                
oliver@207
   232
            for m in machines:
oliver@215
   233
mihai@244
   234
                properties = json.load(urllib2.urlopen('http://127.0.0.1:8080/sdvms/' + m))
mihai@244
   235
                if 'USBAttachedUUID1' in properties and properties['USBAttachedUUID1'] != None: 
mihai@244
   236
                    a = self._menu_format.addAction(m + '\\\\' + machines[m])
mihai@244
   237
                    a.setIcon(self._icon_network)
mihai@244
   238
                    a.triggered.connect(self.format_drive)
oliver@207
   239
oliver@207
   240
        except:
oliver@207
   241
            pass
oliver@207
   242
oliver@144
   243
om@13
   244
    def setup_ui(self):
om@13
   245
        """create the user interface
om@13
   246
        As for the system tray this is 'just' the context menu.
om@13
   247
        """
om@13
   248
    
om@13
   249
        # define the tray icon menu
om@13
   250
        menu = QtGui.QMenu(self.parent())
om@13
   251
        self.setContextMenu(menu)
om@13
   252
        
om@13
   253
        # add known apps
oliver@104
   254
        self.acBrowser = QtGui.QAction('Secure Browsing', self.parent())
oliver@104
   255
        icon = QtGui.QIcon()
oliver@106
   256
        icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_browsing_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
oliver@104
   257
        self.acBrowser.setIcon(icon)
oliver@104
   258
        menu.addAction(self.acBrowser)
om@37
   259
        menu.addSeparator()
om@13
   260
        
om@13
   261
        # add standard menu items
oliver@104
   262
        self.acLaunch = QtGui.QAction('Launch Application', self.parent())
oliver@104
   263
        icon = QtGui.QIcon()
oliver@106
   264
        icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_launch_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
oliver@104
   265
        self.acLaunch.setIcon(icon)
oliver@104
   266
        menu.addAction(self.acLaunch)
oliver@106
   267
        self.acConfigure = QtGui.QAction('Configuration', self.parent())
oliver@106
   268
        icon = QtGui.QIcon()
oliver@106
   269
        icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_configure_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
oliver@106
   270
        self.acConfigure.setIcon(icon)
oliver@106
   271
        menu.addAction(self.acConfigure)
om@13
   272
        menu.addSeparator()
oliver@104
   273
oliver@207
   274
        self._menu_format = menu.addMenu('Format')
oliver@207
   275
        menu.addSeparator()
oliver@207
   276
oliver@144
   277
        self.acMail = menu.addAction('Send feedback mail')
oliver@144
   278
        icon = QtGui.QIcon()
oliver@144
   279
        icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_mail_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
oliver@144
   280
        self.acMail.setIcon(icon)
oliver@104
   281
        self.acAbout = menu.addAction('About')
oliver@215
   282
        
oliver@215
   283
        # diabled as of TICKET #11
oliver@215
   284
        # self.acExit = menu.addAction('Exit')
oliver@144
   285
       
oliver@104
   286
        self.acBrowser.triggered.connect(self.clicked_browser)
oliver@104
   287
        self.acLaunch.triggered.connect(self.clicked_launch_application)
oliver@106
   288
        self.acConfigure.triggered.connect(self.clicked_configure)
oliver@104
   289
        self.acAbout.triggered.connect(self.clicked_about)
oliver@215
   290
oliver@215
   291
        # disabled as for TICKET #11
oliver@215
   292
        # self.acExit.triggered.connect(self.clicked_exit)
oliver@144
   293
        self.acMail.triggered.connect(self.clicked_mail)
om@13
   294
        
oliver@136
   295
om@13
   296
def main():
om@13
   297
    
oliver@136
   298
    # parse arguments
oliver@136
   299
    parser = argparse.ArgumentParser(description = 'OpenSecurity Tray Icon.')
oliver@136
   300
    parser.add_argument('-p', '--port', type=int, default=8090, help='port number of the REST API this instance will listen on.')
oliver@136
   301
    args = parser.parse_args()
oliver@136
   302
oliver@136
   303
    # get up Qt
oliver@104
   304
    a = QtGui.QApplication(sys.argv)
om@13
   305
oliver@136
   306
    # enforce singelton process
oliver@136
   307
    if opensecurity_client_restful_server.is_already_running(args.port):
oliver@136
   308
        QtGui.QMessageBox.critical(None, 'OpenSecurity Error', 'OpenSecurity Tray Instance already launched.\nClose previous instance first.')
oliver@136
   309
        sys.exit(1)
oliver@136
   310
oliver@136
   311
    # start serving
oliver@136
   312
    opensecurity_client_restful_server.serve(args.port, True)
oliver@136
   313
oliver@136
   314
    # init tray icon widget
om@13
   315
    w = QtGui.QWidget()
oliver@104
   316
    icon = QtGui.QIcon()
oliver@104
   317
    icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
oliver@104
   318
    trayIcon = OpenSecurityTrayIcon(icon)
oliver@193
   319
    opensecurity_client_restful_server.tray_icon = trayIcon
om@13
   320
oliver@136
   321
    # go!
om@13
   322
    trayIcon.show()
oliver@104
   323
    a.setQuitOnLastWindowClosed(False)
oliver@104
   324
    sys.exit(a.exec_())
om@13
   325
   
om@13
   326
om@13
   327
# start
om@13
   328
if __name__ == "__main__":
om@13
   329
    main()
om@13
   330