#!/usr/bin/python
# @package      hubzero-vncproxyd-ws
# @file         hzvncproxyd-ws-config
# @author       Nicholas J. Kisseberth <nkissebe@purdue.edu>
# @copyright    Copyright (c) 2014-2015 HUBzero Foundation, LLC.
# @license      http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
#
# Copyright (c) 2014-2015 HUBzero Foundation, LLC.
#
# This file is part of: The HUBzero(R) Platform for Scientific Collaboration
#
# The HUBzero(R) Platform for Scientific Collaboration (HUBzero) is free
# software: you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software
# Foundation, version 3.
#
# HUBzero 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# HUBzero is a registered trademark of HUBzero Foundation, LLC.
#

import re, glob, string, ConfigParser, sys, MySQLdb, time, warnings, argparse, os, pwd, grp, subprocess, shutil
import hubzero.data.db
import hubzero.config.webconfig
import hubzero.utilities.misc
import _mysql_exceptions

debug = False

os.umask(0027)

def configureVncproxyd_ws(args):

    uid = os.geteuid()

    if uid != 0:            
        print 'hzvncproxyd-ws-config configure: must be run with root privileges'
        return 1

    if args.enable:
        return enableVncproxyd_ws(args)
    else:
        return disableVncproxyd_ws()


# For RHEL systems the init.d defaults directory is /etc/sysconfig
# This function will move the hzvncproxyd-ws file from /etc/default
# to /etc/sysconfig without overwriting any existing one in /etc/sysconfig

def fixInitDefault():
    print "checking for init.d configuration in /etc/sysconfig"
    if os.path.exists('/etc/sysconfig'):
        if os.path.exists('/etc/default/hzvncproxyd-ws'):
            if os.path.exists('/etc/sysconfig/hzvncproxyd-ws'):
                print "mv /etc/default/hzvncproxyd-ws /etc/sysconfig/hzvncproxyd-ws.old"
                shutil.move('/etc/default/hzvncproxyd-ws','/etc/sysconfig/hzvncproxyd-ws.old')
            else:
                print "mv /etc/default/hzvncproxyd-ws /etc/sysconfig/hzvncproxyd-ws"
                shutil.move('/etc/default/hzvncproxyd-ws','/etc/sysconfig/hzvncproxyd-ws')



def enableVncproxyd_ws(args):

    print "configuring hubzero-vncproxyd-ws (enable)"

    fixInitDefault()

    try:
        grp.getgrnam('hzvncproxy')
    except KeyError:
        print 'Creating hzvncproxy group'

        adduser = ["/usr/sbin/groupadd", "--system", "hzvncproxy"]

        try:
            proc = subprocess.Popen(adduser, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
            procStdOut, procStdErr = proc.communicate()

            rc = proc.returncode

        except Exception, ex:   
            print ex
            raise
            #raise Exception('exShellCommand error ' + str(argArray) + ' ' + str(ex) + "\n" + traceback.format_exc())

        if rc != 0:
            print procStdOut
            print procStdErr
            return 1

    try:
        pwd.getpwnam('hzvncproxy')
    except KeyError:
        print 'Creating hzvncproxy user'

        adduser = ["/usr/sbin/useradd", "--system", "--home-dir" , "/var/lib/hzvncproxy", "--gid", "hzvncproxy", "--shell", "/bin/false", "--comment", "HUBzero VNC Proxy Service", "hzvncproxy"]

        try:
            proc = subprocess.Popen(adduser, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
            procStdOut, procStdErr = proc.communicate()

            rc = proc.returncode

        except Exception, ex:   
            print ex
            raise
            #raise Exception('exShellCommand error ' + str(argArray) + ' ' + str(ex) + "\n" + traceback.format_exc())

        if rc != 0:
            print procStdOut
            print procStdErr
            return 1

    try:
        h_uid = pwd.getpwnam('hzvncproxy').pw_uid
        h_gid = grp.getgrnam('hzvncproxy').gr_gid

        if not os.path.exists('/var/lib/hzvncproxy'):
            print "Creating /var/lib/hzvncproxy/"
            os.mkdir('/var/lib/hzvncproxy',0755)
            os.chown('/var/lib/hzvncproxy',h_uid,h_gid)
        if not os.path.exists('/etc/hzvncproxyd-ws'):
            print "Creating /etc/hzvncproxyd-ws/"
            os.mkdir('/etc/hzvncproxyd-ws',0755)
            os.chown('/etc/hzvncproxyd-ws',0,0)
        if not os.path.exists('/etc/hzvncproxyd-ws/targets'):
            print "Creating /etc/hzvncproxyd-ws/targest/"
            os.mkdir('/etc/hzvncproxyd-ws/targets',0750)
            os.chown('/etc/hzvncproxyd-ws/targets',h_uid,h_gid)
        if not os.path.exists('/var/log/hzvncproxyd-ws'):
            print "Creating /var/log/hzvncproxyd-ws"
            os.mkdir('/var/log/hzvncproxyd-ws',0750)
            os.chown('/var/log/hzvncproxyd-ws',h_uid,h_gid)
        if not os.path.exists('/var/log/hzvncproxyd-ws/daily'):
            print "Creating /var/log/hzvncproxyd-ws"
            os.mkdir('/var/log/hzvncproxyd-ws/daily',0750)
            os.chown('/var/log/hzvncproxyd-ws/daily',h_uid,h_gid)

        os.chown('/var/lib/hzvncproxy',h_uid,-1)
        os.chown('/etc/hzvncproxyd-ws',0,-1)
        os.chown('/etc/hzvncproxyd-ws/targets',h_uid,-1)
        os.chown('/var/log/hzvncproxyd-ws',h_uid,-1)
        os.chown('/var/log/hzvncproxyd-ws/daily',h_uid,-1)
        os.chmod('/var/log/hzvncproxyd-ws',0750)
        os.chmod('/var/log/hzvncproxyd-ws/daily',0750)

    except Exception as e:
        print "Unable to configure required directories"
        print e
        if debug:
            raise
        return 1

    filename = '/etc/hzvncproxyd-ws/targets/default.conf'

    print "configuring %s " % (filename)

    try:
        if not os.path.exists(filename):
            mode = 'w'
        else:
            mode = 'r+'

        with open(filename, mode) as f:
            ftxt = f.read()

            (txt, count) = re.subn(r'(?im)^\s*#.*$',r'',ftxt)
            (txt, count) = re.subn(r'(?im)^(?:[\t ]*(?:\r?\n|\r))+' ,'',txt)

            if len(txt) == 0:
                hzconfig = ConfigParser.ConfigParser()

                if hzconfig.read('/etc/hubzero.conf') == []:
                    print "Unable to continue, failed to read /etc/hubzero.conf."
                    return 1
                if hzconfig.has_option('DEFAULT','site'):
                    site = hzconfig.get('DEFAULT','site')
                else:
                    print "Unable to continue, failed to find default hub site in /etc/hubzero.conf"
                    return 2

                if hzconfig.has_option(site,'documentroot'):
                    document_root = hzconfig.get(site,'documentroot')
                else:
                    print "Unable to continue, no document root set for default site in /etc/hubzero.conf"
                    return 3

                data = { 'cmsconfig' : {} }

                try:
                    for m in re.finditer("\s*(?:var|public)\s+\$(\w+)\s*=\s*\'*(.*?)\'*\s*\;\s*", open(document_root + '/configuration.php','r').read()):
                        data['cmsconfig'][m.group(1)] = m.group(2).strip(" \'\"\t")
                except Exception as e:
                    print "Unable to continue, failed to read '" +  document_root + "/configuration.php'"
                    return 4

                if 'db' not in data['cmsconfig'] or 'user' not in data['cmsconfig'] or 'password' not in data['cmsconfig']:
                    print "Unable to continue, missing configuration in  '" +  document_root + "/configuration.php'"
                    return 5

                if data['cmsconfig']['db'] == '' or data['cmsconfig']['user']  == '' or data['cmsconfig']['password'] == '':
                    print "Unable to continue, invalid configuration in  '" +  document_root + "/configuration.php'"
                    return 6

                data['cmsconfig']['password'] = data['cmsconfig']['password'].replace(';','\;')

                f.seek(0)
                f.write(ftxt)
                f.write("*:%s:mysql:host=%s;user=%s;password=%s;db=%s\n" % (site, data['cmsconfig']['host'], data['cmsconfig']['user'], data['cmsconfig']['password'], data['cmsconfig']['db']))
                f.truncate()
                print "wrote %s" % (filename)
            else:
                print "already configured %s." % (filename)

            os.chown(filename,h_uid,h_gid)

            # For RHEL systems make sure we enable the init.d service
            print "configuring init.d service levels"
            try:
                if os.path.exists('/sbin/chkconfig'):
                    rc = subprocess.call(["/sbin/chkconfig", "hzvncproxyd-ws", "on"])
            except Exception as e:
                print "Unable to enable hzvncproxyd-ws init.d service"
                print e
                if debug:
                    raise
                return 2

    except Exception as e:
            print "Unable to configure %s" % (filename)
            print e
            if debug:
                raise
            return 1
 
    ###########################################33

    default_sslcertfile = '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem'
    default_sslkeyfile = '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key'
    ad_sslcertfile = None
    ad_sslkeyfile = None
    arg_sslcertfile = None
    arg_sslkeyfile = None
    sslkeyfile = None
    sslcertfile = None

    if args.sslcert != '':
        arg_sslcertfile = args.sslcert 

    if args.sslkey != '':
        arg_sslkeyfile = args.sslkey

    if os.path.exists(default_sslcertfile) and os.path.exists(default_sslkeyfile):
        ad_sslcertfile = default_sslcertfile
        ad_sslkeyfile = default_sslkeyfile

    elif os.path.exists('/etc/ssl/certs/ssl-cert-server.pem') and os.path.exists('/etc/ssl/certs/private/ssl-cert-server.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-server.pem"
        ad_sslkeyfile = "/etc/ssl/certs/private/ssl-cert-server.key"
    elif os.path.exists('/etc/ssl/certs/ssl-cert-server.crt') and os.path.exists('/etc/ssl/certs/private/ssl-cert-server.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-server.crt"
        ad_sslkeyfile = "/etc/ssl/certs/private/ssl-cert-server.key"
    elif os.path.exists('/etc/ssl/certs/ssl-cert-server.pem') and os.path.exists('/etc/ssl/private/ssl-cert-server.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-server.pem"
        ad_sslkeyfile = "/etc/ssl/private/ssl-cert-server.key"
    elif os.path.exists('/etc/ssl/certs/ssl-cert-server.crt') and os.path.exists('/etc/ssl/private/ssl-cert-server.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-server.crt"
        ad_sslkeyfile = "/etc/ssl/private/ssl-cert-server.key"
    elif os.path.exists('/etc/apache2/ssl/ssl-cert-server.pem') and os.path.exists('/etc/apache2/ssl/ssl-cert-server.key'):
        ad_sslcertfile = "/etc/apache2/ssl/ssl-cert-server.pem"
        ad_sslkeyfile = "/etc/apache2/ssl/ssl-cert-server.key"
    elif os.path.exists('/etc/apache2/ssl/ssl-cert-server.crt') and os.path.exists('/etc/apache2/ssl/ssl-cert-server.key'):
        ad_sslcertfile = "/etc/apache2/ssl/ssl-cert-server.crt"
        ad_sslkeyfile = "/etc/apache2/ssl/ssl-cert-server.key"

    elif os.path.exists('/etc/ssl/certs/server.pem') and os.path.exists('/etc/ssl/certs/private/server.key'):
        ad_sslcertfile = "/etc/ssl/certs/server.pem"
        ad_sslkeyfile = "/etc/ssl/certs/private/server.key"
    elif os.path.exists('/etc/ssl/certs/server.crt') and os.path.exists('/etc/ssl/certs/private/server.key'):
        ad_sslcertfile = "/etc/ssl/certs/server.crt"
        ad_sslkeyfile = "/etc/ssl/certs/private/server.key"
    elif os.path.exists('/etc/ssl/certs/server.pem') and os.path.exists('/etc/ssl/certs/server.key'):
        ad_sslcertfile = "/etc/ssl/certs/server.pem"
        ad_sslkeyfile = "/etc/ssl/private/server.key"
    elif os.path.exists('/etc/ssl/certs/server.crt') and os.path.exists('/etc/ssl/certs/server.key'):
        ad_sslcertfile = "/etc/ssl/certs/server.crt"
        ad_sslkeyfile = "/etc/ssl/certs/server.key"
    elif os.path.exists('/etc/apache2/ssl/server.pem') and os.path.exists('/etc/apache2/ssl/server.key'):
        ad_sslcertfile = "/etc/apache2/ssl/server.pem"
        ad_sslkeyfile = "/etc/apache2/ssl/server.key"
    elif os.path.exists('/etc/apache2/ssl/server.crt') and os.path.exists('/etc/apache2/ssl/server.key'):
        ad_sslcertfile = "/etc/apache2/ssl/server.crt"
        ad_sslkeyfile = "/etc/apache2/ssl/server.key"

    elif os.path.exists('/etc/ssl/certs/ssl-cert-snakeoil.pem') and os.path.exists('/etc/ssl/private/ssl-cert-snakeoil.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-snakeoil.pem"
        ad_sslkeyfile = "/etc/ssl/private/ssl-cert-snakeoil.key"
    elif os.path.exists('/etc/ssl/certs/ssl-cert-snakeoil.crt') and os.path.exists('/etc/ssl/private/ssl-cert-snakeoil.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-snakeoil.crt"
        ad_sslkeyfile = "/etc/ssl/private/ssl-cert-snakeoil.key"
    elif os.path.exists('/etc/ssl/certs/ssl-cert-snakeoil.pem') and os.path.exists('/etc/ssl/certs/private/ssl-cert-snakeoil.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-snakeoil.pem"
        ad_sslkeyfile = "/etc/ssl/certs/private/ssl-cert-snakeoil.key"
    elif os.path.exists('/etc/ssl/certs/ssl-cert-snakeoil.crt') and os.path.exists('/etc/ssl/certs/private/ssl-cert-snakeoil.key'):
        ad_sslcertfile = "/etc/ssl/certs/ssl-cert-snakeoil.crt"
        ad_sslkeyfile = "/etc/ssl/certs/private/ssl-cert-snakeoil.key"
    elif os.path.exists('/etc/ssl/certs/opensourcehub-selfsignedcert.crt') and os.path.exists('/etc/ssl/certs/private/opensourcehub-selfsignedcert.key'):
        ad_sslcertfile = "/etc/ssl/certs/opensourcehub-selfsignedcert.crt"
        ad_sslkeyfile = "/etc/ssl/certs/private/opensourcehub-selfsignedcert.key"

    if ad_sslcertfile != None and (arg_sslcertfile == None or arg_sslkeyfile == None):
        print "autodiscovering SSL certificates"

        h_uid = pwd.getpwnam('hzvncproxy').pw_uid
        h_gid = grp.getgrnam('hzvncproxy').gr_gid

        if (ad_sslcertfile != '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem'):
            print "copying SSL certificate [%s] to [%s]" % (ad_sslcertfile, '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem')
            shutil.copy2(ad_sslcertfile,"/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem")
        else:
            print "ssl certificate was already configured [%s]" % ('/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem')

        if (ad_sslkeyfile != '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key'):
            print "copying SSL certificate key [%s] to [%s]" % (ad_sslkeyfile, '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key')
            shutil.copy2(ad_sslkeyfile,"/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key")
        else:
            print "ssl key was already configured [%s]" % ('/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key')

        os.chmod('/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key', 0640)
        os.chown('/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key', h_uid, h_gid)

        os.chmod('/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem', 0640)
        os.chown('/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem', h_uid, h_gid)
 
        sslcertfile = '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.pem'
        sslkeyfile = '/etc/hzvncproxyd-ws/ssl-cert-hzvncproxyd-ws.key'

    else:
        sslcertfile = arg_sslcertfile
        sslkeyfile = arg_sslkeyfile

    default_port = None
    default_host = None
    default_encrypt = None
    wsproxy_host = None
    wsproxy_port = None
    wsproxy_encrypt = None
    arg_host = None
    arg_port = None
    arg_encrypt = None
    port = None
    host = None
    encrypt = None

    if sslcertfile and sslkeyfile:
       default_port = '8443'
       default_encrypt = True
    elif os.path.exists(default_sslcertfile) and os.path.exists(default_sslkeyfile):
       default_port = '8443'
       default_encrypt = True
    else:
       default_port = '8080'
       default_encrypt = False

    default_host = ''

    if os.path.exists("/etc/mw-client/mw-client.conf"):
        try:
            execfile('/etc/mw-client/mw-client.conf')
        except IOError, (errno, strerror):
            print "I/O error(%s): %s" % (errno, strerror)
            print "The configuration file /etc/mw-client/mw-client.conf needs to be readable"
            os._exit(1)

        try:
            wsproxy_port = SESSION_CONF['WS_PROXY_PORT']
        except:
            pass

        try:
            wsproxy_host = SESSION_CONF['WS_PROXY_SERVER']
        except:
            pass

    try:
       (arg_host, arg_port) = args.listen.split(":",1)
    except AttributeError, ValueError:
        pass

    if arg_port != None:
        port = arg_port
    elif wsproxy_port != None:
        port = wsproxy_port
    else:
        port = default_port

    port = str(port)

    if arg_host != None:
        host = arg_host
    elif wsproxy_host != None:
        host = wsproxy_host
    else:
        host = default_host

    ###########################################33

    if os.path.exists('/etc/sysconfig'):
        filename = '/etc/sysconfig/hzvncproxyd-ws'
    else:
        filename = '/etc/default/hzvncproxyd-ws'

    print "configuring %s " % (filename)

    try:

        if not os.path.exists(filename):
            mode = 'w+'
        else:
            mode = 'r+'

        if (port == default_port) and (host == default_host):
            listen = ''
        elif port == None and host != None:
            listen = "LISTEN=" + host
        elif port != None and host != None:
            listen = "LISTEN=" + host + ":" + port
        elif port != None:
            listen = "LISTEN=:" + port
        else:
            listen = ''        

        with open(filename, mode) as f:
            ftxt = f.read()
            txt = ftxt.split("\n")
            last_listen = -1
            last_certfile = -1
            last_keyfile = -1

            for i in range(0,len(txt)):
                if re.match(r'^SSL_CERTFILE\s*=\s*(.*)$',txt[i]):
                    last_certfile = i
                if re.match(r'^SSL_KEYFILE\s*=\s*(.*)$',txt[i]):
                    last_keyfile = i
                if re.match(r'^LISTEN\s*=\s*(.*)$',txt[i]):
                    last_listen = i

            if sslcertfile != None:
                if last_certfile > -1:
                    txt[last_certfile] = "SSL_CERTFILE=" + sslcertfile
                else:
                    txt.append("SSL_CERTFILE=" + sslcertfile)

            if sslkeyfile != None:
                if last_keyfile > -1:
                    txt[last_keyfile] = "SSL_KEYFILE=" + sslkeyfile
                else:
                    txt.append("SSL_KEYFILE=" + sslkeyfile)

            if listen != None:
                if last_listen > -1:
                    txt[last_listen] = listen
                else:
                    txt.append(listen)

            txt = '\n'.join(txt)

            if sslcertfile == None or sslcertfile == '' or sslcertfile == default_sslcertfile:
                txt = re.sub(r'(?im)^SSL_CERTFILE\s*=\s*(.*)(\n|$)','',txt)
            if sslkeyfile == None or sslkeyfile == '' or sslkeyfile == default_sslkeyfile:
                txt = re.sub(r'(?im)^SSL_KEYFILE\s*=\s*(.*)(\n|$)','',txt)
            if listen == None or listen == '':
                txt = re.sub(r'(?im)^LISTEN\s*=\s*(.*)(\n|$)','',txt)

            txt = txt.rstrip() + "\n"

            if txt == ftxt:
                print "%s was already configured." % (filename)
            else:
                f.seek(0)
                f.write(txt)
                f.truncate()
                print "%s configuration complete." % (filename)

    except Exception as e:
            print "Unable to configure %s" % (filename)
            print e
            raise
            if debug:
                raise
            return 1

    # Configure Middleware 1 Client (/etc/mw-client/mw-client.conf)
    #
    # If --listen was set on the command line then we need to
    # set the variables: wsproxy_port, wsproxy_host and wsproxy_encrypt
    #
    # If --listen was NOT set on the command line then
    # the values from this file were used so we don't need
    # to reconfigure file

    filename = '/etc/mw-client/mw-client.conf'

    print "configuring %s " % (filename)

    if os.path.exists(filename):
        try:
            with open(filename, 'r+') as f:
                ftxt = f.read()
                txt = ftxt.split("\n")
                last_wsproxy_port = -1
                last_wsproxy_host = -1
                last_wsproxy_encrypt = -1

                for i in range(0,len(txt)):
                    if re.match(r'^\s*wsproxy_port\s*=\s*(.*)$',txt[i]):
                        last_wsproxy_port = i
                    if re.match(r'^\s*wsproxy_host\s*=\s*(.*)$',txt[i]):
                        last_wsproxy_host = i
                    if re.match(r'^\s*wsproxy_encrypt\s*=\s*(.*)$',txt[i]):
                        last_wsproxy_encrypt = i

                if port != None:
                    if last_wsproxy_port > -1:
                        txt[last_wsproxy_port] = 'wsproxy_port=' + port
                    else:
                        txt.append('wsproxy_port=' + port)

                if host != None:
                    if last_wsproxy_host > -1:
                        txt[last_wsproxy_host] = 'wsproxy_host=' + host
                    else:
                        txt.append('wsproxy_host=' + host)

                if encrypt != None:
                    if last_wsproxy_encrypt > -1:
                        txt[last_wsproxy_encrypt] = 'wsproxy_encrypt=' + encrypt
                    else:
                        txt.append('wsproxy_encrypt=' + encrypt)

                txt = '\n'.join(txt).rstrip()
                txt += "\n" 

                if port == '' or port == None or port == default_port:
                    txt = re.sub(r'(?im)^\s*wsproxy_port\s*=\s*(.*)(\n|$)','',txt)
                if host == '' or host == None or host == default_host:
                    txt = re.sub(r'(?im)^\s*wsproxy_host\s*=\s*(.*)(\n|$)','',txt)
                if encrypt == '' or encrypt == None or encrypt == default_encrypt:
                    txt = re.sub(r'(?im)^\s*wsproxy_encrypt\s*=\s*(.*)(\n|$)','',txt)

                if txt == ftxt:
                    print "%s was already configured." % (filename)
                else:
                    f.seek(0)
                    f.write(txt)
                    f.truncate()
                    print "%s configuration complete." % (filename)

        except Exception as e:
            print "Unable to configure %s" % (filename)
            print e
            raise
            if debug:
                raise
            return 1

    else:
        print filename + " does not exist, nothing to do"

    filename = "/etc/firewall_on"

    if port == None or port == '':
        port = str(default_port)

    print "configuring " + filename

    if os.path.exists(filename):

        with open(filename, mode) as f:

            ftxt = f.read()
            newtxt = ftxt.rstrip() + "\n"

            if not re.search(r'^\s*iptables\s+\-A\s+INPUT\s+\-p\s+tcp\s+\-\-dport\s+' + port + '\s+\-j\s+ACCEPT',ftxt,re.MULTILINE):

                if re.search(r'^\s*iptables\s+\-A\s+INPUT\s+\-p\s+tcp\s+\-\-dport\s+(443|https)\s+\-j\s+ACCEPT',ftxt,re.MULTILINE):
                    newtxt += "iptables -A INPUT -p tcp --dport " + port + " -j ACCEPT # hzvncproxyd-ws\n"
                else:
                    print "Contents of /etc/firewall_on are unexpected"
                    print "Add a rule like:"
                    print "    iptables -A INPUT -p tcp --dport " + port + "-j ACCEPT"
                    print "to your iptables firewall to allow connectivity to the hzvncproxyd-ws port"

                if (ftxt != newtxt):
                    f.seek(0)
                    f.write(newtxt)
                    f.truncate()
                    f.close()
                    print "%s configuration complete." % (filename)
                else:
                    print "%s was already configured." % (filename)

            else:
                print "%s was already configured." % (filename)
    else:
        print filename + " does not exist, nothing to be done"

    if not isLiveIptablesPortOpen(port):
        openLiveIptablesPort(port)

    print "restarting hzvncproxyd-ws service"

    serviceInit('hzvncproxyd-ws', 'restart')

    print "configuring HUBzero CMS"

    dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
    dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
    dbName = hubzero.config.webconfig.getWebConfigDBName()
    db =  hubzero.data.db.MySQLConnection("localhost", dbName, dbUserName, dbPW)

    try:
        sql = 'UPDATE jos_extensions SET enabled = 1 WHERE type = "plugin" AND folder = "tools" AND element IN ("novnc");'
        db.query_rowcount(sql, None)
    except _mysql_exceptions.ProgrammingError as err:
        sql = 'UPDATE jos_plugins SET published = 1 WHERE folder = "tools" AND element IN ("novnc")'
        db.query_rowcount(sql, None)

    try:
        sql = 'UPDATE jos_extensions SET ordering = 0 WHERE type = "plugin" AND folder = "tools" AND element IN ("novnc");'
        db.query_rowcount(sql, None)
    except _mysql_exceptions.ProgrammingError as err:
        sql = 'UPDATE jos_plugins SET ordering = 0 WHERE folder = "tools" AND element IN ("novnc")'
        db.query_rowcount(sql, None)

    try:
        sql = 'UPDATE jos_extensions SET ordering = 1 WHERE type = "plugin" AND folder = "tools" AND ordering = 0 AND element IN ("java");'
        db.query_rowcount(sql, None)
    except _mysql_exceptions.ProgrammingError as err:
        sql = 'UPDATE jos_plugins SET ordering = 1 WHERE folder = "tools" AND ordering = 0 AND element IN ("java")'
        db.query_rowcount(sql, None)



def getLiveIptablesInputRules():
    iptables = ["/sbin/iptables", "-L", "INPUT", "-n"]

    try:
        proc = subprocess.Popen(iptables, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        procStdOut, procStdErr = proc.communicate()

        rc = proc.returncode

    except Exception, ex:
        raise

    if rc != 0:
        print procStdOut
        print procStdErr
        return None

    return procStdOut
   

def isLiveIptablesPortOpen(port = None):

    if port == None:
        print "No port specified, nothing to be done."
        return

    port = str(port)

    iptlist = getLiveIptablesInputRules()

    if iptlist == None:
        return None

    m = re.search(r'^ACCEPT\s+tcp.*?tcp\s+dpt:'+port,iptlist,re.MULTILINE)

    return m != None

def openLiveIptablesPort(port = None):

    if port == None:
        print "No port specified, nothing to be done."
        return

    port = str(port)

    print "Opening port " + port  + " on live iptables firewall"

    iptables = ["/sbin/iptables", "-A", "INPUT", "-p", "tcp", "--dport", port, "-j", "ACCEPT"]

    try:
        proc = subprocess.Popen(iptables, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        procStdOut, procStdErr = proc.communicate()

        rc = proc.returncode

    except Exception, ex:
        print ex
        raise
        #raise Exception('exShellCommand error ' + str(argArray) + ' ' + str(ex) + "\n" + traceback.format_exc())

    if rc != 0:
        print procStdOut
        print procStdErr
        return 1


def closeLiveIptablesPort(port = None):

    if port == None:
        print "No port specified, nothing to be done."
        return

    port = str(port)

    print "Closing port " + port + " on live iptables firewall"

    iptables = ["/sbin/iptables", "-D", "INPUT", "-p", "tcp", "--dport", port, "-j", "ACCEPT"]

    try:
        proc = subprocess.Popen(iptables, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        procStdOut, procStdErr = proc.communicate()

        rc = proc.returncode

    except Exception, ex:
        print ex
        raise
        #raise Exception('exShellCommand error ' + str(argArray) + ' ' + str(ex) + "\n" + traceback.format_exc())

    if rc != 0:
        print procStdOut
        print procStdErr
        return 1


    # -A OUTPUT -j LOG --log-prefix "EGRESS ALERT: " --log-level 7

    # capture current iptables
    # look for: ^ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8443"
    # if not found run
    # iptables -A INPUT -p tcp --dport 8443 -j ACCEPT

def disableVncproxyd_ws():
    print "configuring hubzero-vncproxyd-ws (disable)"

    fixInitDefault()

    if os.path.exists('/etc/sysconfig'):
        filename = '/etc/sysconfig/hzvncproxyd-ws'
    else:
        filename = '/etc/default/hzvncproxyd-ws'

    print "configuring %s " % (filename)

    try:

        if not os.path.exists(filename):
            mode = 'w+'
        else:
            mode = 'r+'

        with open(filename, mode) as f:
            ftxt = f.read()
            txt = ftxt.split("\n")

            if args.enable == None:
                enabled = None
            elif args.listen == False:
                enabled = '';
            else:
                enabled = "ENABLED=0"

            last_enabled = -1

            for i in range(0,len(txt)):
                if re.match(r'^ENABLED\s*=\s*(.*)$',txt[i]):
                    last_enabled = i

            if txt[len(txt)-1] <> "":
                txt.append("")

            if enabled <> None and enabled <> '':
                if last_enabled > -1:
                    txt[last_enabled] = enabled
                else:
                    txt.append(enabled)

            txt = '\n'.join(txt)

            if enabled == '':
                txt = re.sub(r'(?im)^ENABLED\s*=\s*(.*)(\n|$)','',txt)

            #print "============"
            #print txt,
            #print "============"

            if txt == ftxt:
                print "%s was already configured disabled." % (filename)
            else:
                f.seek(0)
                f.write(txt)
                f.truncate()
                print "%s configuration complete (disabled)." % (filename)

            # For RHEL systems make sure we disable the init.d service
            print "configuring init.d service levels"
            try:
                if os.path.exists('/sbin/chkconfig'):
                    rc = subprocess.call(["/sbin/chkconfig", "hzvncproxyd-ws", "off"])
            except Exception as e:
                print "Unable to disable hzvncproxyd-ws init.d service"
                print e
                if debug:
                    raise
                return 2

    except Exception as e:
            print "Unable to disable package through configuration file %s " % (filename)
            print e
            if debug:
                raise
            return 1

    return 0

def serviceInit(service, action = 'start', verbose = False):

    serviceScript = '/etc/init.d/' + service

    if verbose:
        print "checking " + serviceScript

    if not os.path.exists(serviceScript):
        print "missing " + serviceScript

    if verbose:
        print serviceScript + " " + action

    service = [serviceScript, action]

    try:
        proc = subprocess.Popen(service, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)

        procStdOut, procStdErr = proc.communicate()

        rc = proc.returncode

    except Exception, ex:
        print ex
        raise
        #raise Exception('exShellCommand error ' + str(argArray) + ' ' + str(ex) + "\n" + traceback.format_exc())

    if rc : print procStdErr

    return rc

parser = argparse.ArgumentParser(prog="hzvncproxyd-ws-config")
parser.add_argument('--debug', dest='debug', action='store_true', help='enable debugging output', default=False)

subparsers = parser.add_subparsers()

parser_configure = subparsers.add_parser('configure', help='configure hubzero-vncproxyd-ws package')
parser_configure.set_defaults(func=configureVncproxyd_ws)
action = parser_configure.add_mutually_exclusive_group(required=True)
action.add_argument('--enable', dest='enable', action='store_true', help='enable hubzero-vncproxyd-ws',default=True)
action.add_argument('--disable', dest='enable', action='store_false', help='disable hubzero-vncproxyd-ws configuration',default=False)
parser_configure.add_argument('--listen', dest='listen', action='store', help='host:port to lisent on',default=None)
parser_configure.add_argument('--ssl-cert', dest='sslcert', action='store', help='SSL Certificate File',nargs='?',const='')
parser_configure.add_argument('--ssl-key', dest='sslkey', action='store', help='SSL Certificate Key',nargs='?',const='')
args =  parser.parse_args()

debug = args.debug

ret = args.func(args)

sys.exit(ret)
