OpenSecurity/bin/launch.py
author om
Fri, 06 Dec 2013 12:10:30 +0100
changeset 14 c187aaceca32
parent 3 OpenSecurity/client/launch.py@65432e6c6042
child 16 e16d64b5e008
permissions -rwxr-xr-x
renamed "client" to "bin"
om@3
     1
#!/bin/env python
om@3
     2
# -*- coding: utf-8 -*-
om@3
     3
om@3
     4
# ------------------------------------------------------------
om@3
     5
# opensecurity-launcher
om@3
     6
# 
om@3
     7
# launches an application inside a VM
om@3
     8
#
om@3
     9
# Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
om@3
    10
#
om@3
    11
# Copyright (C) 2013 AIT Austrian Institute of Technology
om@3
    12
# AIT Austrian Institute of Technology GmbH
om@3
    13
# Donau-City-Strasse 1 | 1220 Vienna | Austria
om@3
    14
# http://www.ait.ac.at
om@3
    15
#
om@3
    16
# This program is free software; you can redistribute it and/or
om@3
    17
# modify it under the terms of the GNU General Public License
om@3
    18
# as published by the Free Software Foundation version 2.
om@3
    19
# 
om@3
    20
# This program is distributed in the hope that it will be useful,
om@3
    21
# but WITHOUT ANY WARRANTY; without even the implied warranty of
om@3
    22
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
om@3
    23
# GNU General Public License for more details.
om@3
    24
# 
om@3
    25
# You should have received a copy of the GNU General Public License
om@3
    26
# along with this program; if not, write to the Free Software
om@3
    27
# Foundation, Inc., 51 Franklin Street, Fifth Floor, 
om@3
    28
# Boston, MA  02110-1301, USA.
om@3
    29
# ------------------------------------------------------------
om@3
    30
om@3
    31
om@3
    32
# ------------------------------------------------------------
om@3
    33
# imports
om@3
    34
om@3
    35
import argparse
om@3
    36
import os
om@3
    37
import subprocess
om@3
    38
import sys
om@3
    39
om@3
    40
from PyQt4 import QtCore
om@3
    41
from PyQt4 import QtGui
om@3
    42
om@3
    43
# local
om@3
    44
from about import About
om@3
    45
from cygwin import Cygwin
om@3
    46
from environment import Environment
om@3
    47
import opensecurity_server
om@3
    48
om@3
    49
om@3
    50
# ------------------------------------------------------------
om@3
    51
# code
om@3
    52
om@3
    53
om@3
    54
class Chooser(QtGui.QDialog, object):
om@3
    55
    
om@3
    56
    """Ask the user what to launch."""
om@3
    57
    
om@3
    58
    def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags(0)):
om@3
    59
    
om@3
    60
        super(Chooser, self).__init__(parent, flags)
om@3
    61
        self.setWindowTitle('OpenSecuirty Launch Application')
om@3
    62
        self.setup_ui()
om@3
    63
        
om@3
    64
        # known vms and applications
om@3
    65
        self._apps, self_vms = [], []
om@3
    66
        
om@3
    67
        # positionate ourself central
om@3
    68
        screen = QtGui.QDesktopWidget().screenGeometry()
om@3
    69
        self.resize(self.geometry().width() * 1.25, self.geometry().height())
om@3
    70
        size = self.geometry()
om@3
    71
        self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
om@3
    72
        
om@3
    73
        # refresh vm and command input
om@3
    74
        self.refresh()
om@3
    75
        
om@3
    76
        
om@3
    77
    def app_get(self):
om@3
    78
        """The application of the user."""
om@3
    79
        a = str(self._cbApplication.currentText())
om@3
    80
        for app in self._apps:
om@3
    81
            if a == app['name']:
om@3
    82
                return app['command']
om@3
    83
        return a
om@3
    84
        
om@3
    85
    app = property(app_get)
om@3
    86
        
om@3
    87
om@3
    88
    def clicked_about(self):
om@3
    89
        """clicked the about button"""
om@3
    90
        dlgAbout = About()
om@3
    91
        dlgAbout.exec_()
om@3
    92
om@3
    93
om@3
    94
    def clicked_cancel(self):
om@3
    95
        """clicked the cancel button"""
om@3
    96
        self.reject()
om@3
    97
    
om@3
    98
om@3
    99
    def clicked_ok(self):
om@3
   100
        """clicked the ok button"""
om@3
   101
        self.accept()
om@3
   102
    
om@3
   103
    
om@3
   104
    def refresh(self):
om@3
   105
        """load the known vms and commands and adjust input fields"""
om@3
   106
        
om@3
   107
        self._apps = opensecurity_server.query_apps()
om@3
   108
        self._vms = opensecurity_server.query_vms()
om@3
   109
        
om@3
   110
        # add the VMs we know
om@3
   111
        self._cbApplication.clear()
om@3
   112
        for app in self._apps:
om@3
   113
            self._cbApplication.addItem(app['name'])
om@3
   114
        
om@3
   115
        # add the commands we know
om@3
   116
        self._cbVM.clear()
om@3
   117
        for vm in self._vms:
om@3
   118
            self._cbVM.addItem(vm['name'])
om@3
   119
        
om@3
   120
        
om@3
   121
    def setup_ui(self):
om@3
   122
        """Create the widgets."""
om@3
   123
        
om@3
   124
        lyMain = QtGui.QVBoxLayout(self)
om@3
   125
        lyMain.setContentsMargins(8, 8, 8, 8)
om@3
   126
        
om@3
   127
        # content area: left pixmap, right text
om@3
   128
        lyContent = QtGui.QHBoxLayout()
om@3
   129
        lyMain.addLayout(lyContent)
om@3
   130
        
om@3
   131
        # pixmap
om@3
   132
        lbPix = QtGui.QLabel()
om@3
   133
        lbPix.setPixmap(QtGui.QPixmapCache.find('opensecurity_icon_64'))
om@3
   134
        lyContent.addWidget(lbPix, 0, QtCore.Qt.Alignment(QtCore.Qt.AlignTop + QtCore.Qt.AlignHCenter))
om@3
   135
        lyContent.addSpacing(16)
om@3
   136
        
om@3
   137
        # launch ...
om@3
   138
        lyLaunch = QtGui.QGridLayout()
om@3
   139
        lyContent.addLayout(lyLaunch)
om@3
   140
        lbTitle = QtGui.QLabel('Specify details for application to launch.')
om@3
   141
        lyLaunch.addWidget(lbTitle, 0, 0, 1, 2)
om@3
   142
        
om@3
   143
        lbVM = QtGui.QLabel('&VM-ID:')
om@3
   144
        lyLaunch.addWidget(lbVM, 1, 0)
om@3
   145
        self._cbVM = QtGui.QComboBox()
om@3
   146
        self._cbVM.setEditable(True)
om@3
   147
        self._cbVM.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
om@3
   148
        lyLaunch.addWidget(self._cbVM, 1, 1)
om@3
   149
        lbVM.setBuddy(self._cbVM)
om@3
   150
        
om@3
   151
        lbApplication = QtGui.QLabel('&Application:')
om@3
   152
        lyLaunch.addWidget(lbApplication, 2, 0)
om@3
   153
        self._cbApplication = QtGui.QComboBox()
om@3
   154
        self._cbApplication.setEditable(True)
om@3
   155
        self._cbApplication.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
om@3
   156
        lyLaunch.addWidget(self._cbApplication, 2, 1)
om@3
   157
        lbApplication.setBuddy(self._cbApplication)
om@3
   158
        
om@3
   159
        lyLaunch.addWidget(QtGui.QWidget(), 3, 0, 1, 2)
om@3
   160
        lyLaunch.setColumnStretch(1, 1)
om@3
   161
        lyLaunch.setRowStretch(3, 1)
om@3
   162
        
om@3
   163
        lyMain.addStretch(1)
om@3
   164
        
om@3
   165
        # buttons
om@3
   166
        lyButton = QtGui.QHBoxLayout()
om@3
   167
        lyMain.addLayout(lyButton)
om@3
   168
        
om@3
   169
        lyButton.addStretch(1)
om@3
   170
        btnOk = QtGui.QPushButton('&Ok', self)
om@3
   171
        btnOk.setDefault(True)
om@3
   172
        btnOk.setMinimumWidth(100)
om@3
   173
        lyButton.addWidget(btnOk)
om@3
   174
        btnCancel = QtGui.QPushButton('&Cancel', self)
om@3
   175
        btnCancel.setMinimumWidth(100)
om@3
   176
        lyButton.addWidget(btnCancel)
om@3
   177
        btnAbout = QtGui.QPushButton('&About', self)
om@3
   178
        btnAbout.setMinimumWidth(100)
om@3
   179
        lyButton.addWidget(btnAbout)
om@3
   180
        
om@3
   181
        button_width = max(btnOk.width(), btnCancel.width(), btnAbout.width())
om@3
   182
        btnOk.setMinimumWidth(button_width)
om@3
   183
        btnCancel.setMinimumWidth(button_width)
om@3
   184
        btnAbout.setMinimumWidth(button_width)
om@3
   185
        
om@3
   186
        # reduce to the max
om@3
   187
        self.resize(lyMain.minimumSize())
om@3
   188
        
om@3
   189
        # connectors
om@3
   190
        btnOk.clicked.connect(self.clicked_ok)
om@3
   191
        btnCancel.clicked.connect(self.clicked_cancel)
om@3
   192
        btnAbout.clicked.connect(self.clicked_about)
om@3
   193
om@3
   194
        
om@3
   195
    def user_get(self):
om@3
   196
        """The user of the vm of choice."""
om@3
   197
        v = str(self._cbVM.currentText())
om@3
   198
        for vm in self._vms:
om@3
   199
            if v == vm['name']:
om@3
   200
                return vm['user']
om@3
   201
        return v
om@3
   202
        
om@3
   203
    user = property(user_get)
om@3
   204
    
om@3
   205
    
om@3
   206
    def vm_get(self):
om@3
   207
        """The vm of choice."""
om@3
   208
        v = str(self._cbVM.currentText())
om@3
   209
        for vm in self._vms:
om@3
   210
            if v == vm['name']:
om@3
   211
                return vm['ip']
om@3
   212
        return v
om@3
   213
        
om@3
   214
    vm = property(vm_get)
om@3
   215
        
om@3
   216
        
om@3
   217
def ask_user():
om@3
   218
    """ask the user for VM and app to start"""
om@3
   219
    
om@3
   220
    # launch Qt
om@3
   221
    app = QtGui.QApplication(sys.argv)
om@3
   222
    
om@3
   223
    # prebuild the pixmap cache: fetch all jpg, png and jpeg images and load them
om@3
   224
    image_path = os.path.join(Environment("OpenSecurity").data_path, '..', 'gfx')
om@3
   225
    for file in os.listdir(image_path):
om@3
   226
        if file.lower().rpartition('.')[2] in ('jpg', 'png', 'jpeg'):
om@3
   227
            QtGui.QPixmapCache.insert(file.lower().rpartition('.')[0], QtGui.QPixmap(os.path.join(image_path, file)))
om@3
   228
            
om@3
   229
    # we should have now our application icon
om@3
   230
    app.setWindowIcon(QtGui.QIcon(QtGui.QPixmapCache.find('opensecurity_icon_64')))
om@3
   231
    
om@3
   232
    # pop up the dialog
om@3
   233
    dlg = Chooser()
om@3
   234
    dlg.show()
om@3
   235
    app.exec_()
om@3
   236
    
om@3
   237
    if dlg.result() == QtGui.QDialog.Accepted:
om@3
   238
        return dlg.user, dlg.vm, dlg.app
om@3
   239
om@3
   240
    return '', '', ''
om@3
   241
    
om@3
   242
om@3
   243
def main():
om@3
   244
    """entry point"""
om@3
   245
    
om@3
   246
    # parse command line
om@3
   247
    parser = argparse.ArgumentParser(description = 'OpenSecurity Launcher: run application in VM')
om@3
   248
    parser.add_argument('user', metavar='USER', help='USER on Virtual Machine', nargs='?', type=str, default='')
om@3
   249
    parser.add_argument('ip', metavar='IP', help='IP of Virtual Machine', nargs='?', type=str, default='')
om@3
   250
    parser.add_argument('command', metavar='COMMAND', help='Full path of command and arguments to start inside VM', nargs='?', type=str, default='')
om@3
   251
    args = parser.parse_args()
om@3
   252
    
om@3
   253
    # we must have at least all or none set
om@3
   254
    set_user = args.user != ''
om@3
   255
    set_ip = args.ip != ''
om@3
   256
    set_command = args.command != ''
om@3
   257
    set_ALL = set_user and set_ip and set_command
om@3
   258
    set_NONE = (not set_user) and (not set_ip) and (not set_command)
om@3
   259
    if (not set_ALL) and (not set_NONE):
om@3
   260
        sys.stderr.write("Please specify user, ip and command or none.\n")
om@3
   261
        sys.stderr.write("Type '--help' for help.\n")
om@3
   262
        sys.exit(1)
om@3
   263
        
om@3
   264
    # check if we need to ask the user
om@3
   265
    if set_NONE:
om@3
   266
        args.user, args.ip, args.command = ask_user()
om@3
   267
        
om@3
   268
    # still no IP? --> no chance, over and out!
om@3
   269
    if args.ip == '':
om@3
   270
        sys.exit(0)
om@3
   271
        
om@3
   272
    # ensure we have our X11 running
om@3
   273
    Cygwin.start_X11()
om@3
   274
    
om@3
   275
    # the SSH command
om@3
   276
    user_at_guest = args.user + '@' + args.ip
om@3
   277
    ssh = 'DISPLAY=:0 /usr/bin/ssh -Y ' + user_at_guest + ' ' + args.command
om@3
   278
    print(ssh)
om@3
   279
    
om@3
   280
    # off we go!
om@3
   281
    Cygwin()(['/bin/bash', '--login', '-i', '-c', ssh], None, None, None)
om@3
   282
om@3
   283
    
om@3
   284
# start
om@3
   285
if __name__ == "__main__":
om@3
   286
    main()
om@3
   287