You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
527 lines
18 KiB
527 lines
18 KiB
#!/usr/bin/python
|
|
#-*- coding: utf-8 -*-
|
|
|
|
# Copyright 2012 Calculate Ltd. http://www.calculate-linux.org
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from sudsds import WebFault
|
|
from sudsds.transport import TransportError
|
|
|
|
from client_class import Client_suds
|
|
import traceback as tb
|
|
import time, logging
|
|
import os, sys
|
|
import threading, urllib2
|
|
from function import analysis, clear, get_entire_frame, get_view_params
|
|
from pid_information import client_list_methods
|
|
from cert_func import client_post_auth, client_post_request, client_get_cert,\
|
|
client_post_cert, get_password_from_daemon, clear_password
|
|
from sid_func import session_clean, client_session_info, client_session_list
|
|
from cert_verify import get_CRL, VerifyError
|
|
|
|
import M2Crypto, OpenSSL
|
|
from calculate.core.datavars import DataVarsCore
|
|
from client_class import HTTPSClientCertTransport
|
|
from methods_func import call_method, get_method_argparser, parse, get_view
|
|
from calculate.lib.utils.files import makeDirectory, readLinesFile
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
setLocalTranslate('calculate_console',sys.modules[__name__])
|
|
|
|
def client_signal(client):
|
|
Vars = DataVarsCore()
|
|
Vars.importCore()
|
|
Vars.flIniFile()
|
|
try:
|
|
client_active = Vars.Get('cl_core_client_active_period')
|
|
except:
|
|
client_active = 15
|
|
while True:
|
|
if os.path.exists(client.SID_FILE) :
|
|
fi = open(client.SID_FILE, 'r')
|
|
temp = fi.read()
|
|
fi.close()
|
|
sid = int(temp)
|
|
else:
|
|
sid = 0
|
|
try:
|
|
client.service.active_client(sid)
|
|
except:
|
|
print _('no connection to the server!')
|
|
raise Exception(1)
|
|
time.sleep(float(client_active))
|
|
|
|
class StoppableThread(threading.Thread):
|
|
def __init__(self):
|
|
super(StoppableThread, self).__init__()
|
|
self._stop = threading.Event()
|
|
|
|
def run(self):
|
|
l = ['|','/','-','\\','|','/','-','\\']
|
|
i = 0
|
|
while True:
|
|
for i in l:
|
|
sys.stdout.write("\r\r" + i)
|
|
sys.stdout.flush()
|
|
time.sleep(.1)
|
|
if self.stopped():
|
|
sys.stdout.write("\b")
|
|
sys.stdout.flush()
|
|
return 0
|
|
|
|
def stop(self):
|
|
self._stop.set()
|
|
|
|
def stopped(self):
|
|
return self._stop.isSet()
|
|
|
|
def connect_with_cert(cert, path_to_cert, url, args, wait_thread, clVarsCore,
|
|
crypto_Error, Connect_Error):
|
|
flag_thread_start = False
|
|
cert_name = cert
|
|
CERT_FILE = os.path.join(path_to_cert, cert_name + '.crt')
|
|
CERT_KEY = os.path.join(path_to_cert, cert_name + '.key')
|
|
if not os.path.isfile(CERT_FILE) or not os.path.isfile(CERT_KEY):
|
|
Connect_Error = 1
|
|
return (None, 1, crypto_Error, False, None)
|
|
client = None
|
|
|
|
bio = M2Crypto.BIO.openfile(CERT_KEY)
|
|
rsa = M2Crypto.m2.rsa_read_key(bio._ptr(),lambda *unused: None)
|
|
if not rsa:
|
|
store_passwd = get_password_from_daemon(args.host, args.port,
|
|
wait_thread)
|
|
if 'store_passwd' in locals():
|
|
key_passwd = store_passwd
|
|
else:
|
|
key_passwd = None
|
|
try:
|
|
ca_certs = os.path.join(path_to_cert, 'ca/ca_root.crt')
|
|
client = Client_suds(url, transport=HTTPSClientCertTransport \
|
|
(CERT_KEY, CERT_FILE, path_to_cert, password=key_passwd,
|
|
ca_certs = ca_certs, wait_thread = wait_thread))
|
|
if not wait_thread.isAlive():
|
|
wait_thread = StoppableThread()
|
|
flag_thread_start = True
|
|
wait_thread.start()
|
|
client.wsdl.services[0].setlocation(url)
|
|
client.set_parameters (path_to_cert, CERT_FILE, CERT_KEY)
|
|
wait_thread.stop()
|
|
client_post_cert(client, clVarsCore)
|
|
Connect_Error = 0
|
|
except VerifyError, e:
|
|
Connect_Error = 1
|
|
except OpenSSL.crypto.Error, e:
|
|
Connect_Error = 1
|
|
crypto_Error = 1
|
|
except urllib2.URLError, e:
|
|
Connect_Error = 1
|
|
except Exception, e:
|
|
if e.message == 3:
|
|
wait_thread.stop()
|
|
sys.exit(1)
|
|
Connect_Error = 1
|
|
if flag_thread_start:
|
|
wait_thread.stop()
|
|
return (client, Connect_Error, crypto_Error,
|
|
True if 'store_passwd' in locals() else False,
|
|
e if 'e' in locals() else None)
|
|
|
|
def get_server_hostname(host, path_to_cert):
|
|
compliance_file = os.path.join(path_to_cert, 'compliance_server_names')
|
|
if not os.path.isfile(compliance_file):
|
|
fd = open(compliance_file, 'w')
|
|
fd.close()
|
|
for line in readLinesFile(compliance_file):
|
|
adress, server_hostname = line.split(' ',1)
|
|
if adress == host:
|
|
return server_hostname
|
|
return None
|
|
|
|
def add_server_hostname(host, path_to_cert, server_hostname):
|
|
try:
|
|
compliance_file = os.path.join(path_to_cert, 'compliance_server_names')
|
|
if not os.path.isfile(compliance_file):
|
|
fd = open(compliance_file, 'w')
|
|
fd.close()
|
|
temp_file = ''
|
|
find_flag = False
|
|
for line in readLinesFile(compliance_file):
|
|
adress, temp_server_hostname = line.split(' ',1)
|
|
if adress == host:
|
|
temp_file += "%s %s\n" %(adress, server_hostname)
|
|
find_flag = True
|
|
else:
|
|
temp_file += line+'\n'
|
|
if not find_flag:
|
|
temp_file += "%s %s\n" %(host, server_hostname)
|
|
fd = open(compliance_file, 'w')
|
|
fd.write(temp_file)
|
|
fd.close()
|
|
return True
|
|
except Exception, e:
|
|
print e
|
|
return False
|
|
|
|
def https_server(client, args, unknown_args, url, clVarsCore, wait_thread):
|
|
client_post_auth(client)
|
|
|
|
# sym_link = os.path.basename(sys.argv[0])
|
|
# if sym_link != 'cl-console':
|
|
# wait_thread.stop()
|
|
# results = client.service.get_methods(client.sid, 'console')
|
|
# find_flag = False
|
|
# if hasattr (results, 'stringArray'):
|
|
# for _array in results.stringArray:
|
|
# if _array.string[0] == sym_link:
|
|
# args.method = _array.string[1]
|
|
# find_flag = True
|
|
# break
|
|
# if not find_flag:
|
|
# _print (_('Method not found for %s') %sym_link)
|
|
|
|
if args.stop_consoled:
|
|
wait_thread.stop()
|
|
os.system('cl-consoled --stop')
|
|
return 0
|
|
|
|
if args.session_clean:
|
|
wait_thread.stop()
|
|
session_clean(client)
|
|
|
|
if args.session_info or args.session_num_info:
|
|
wait_thread.stop()
|
|
client_session_info(client, args.session_num_info)
|
|
return 0
|
|
|
|
if args.session_list:
|
|
wait_thread.stop()
|
|
client_session_list(client)
|
|
return 0
|
|
|
|
if args.list_pid:
|
|
wait_thread.stop()
|
|
if args.dump:
|
|
from pid_information import client_pid_info
|
|
client_pid_info(client)
|
|
else:
|
|
from pid_information import client_list_pid
|
|
client_list_pid(client)
|
|
|
|
if args.pid_res:
|
|
wait_thread.stop()
|
|
get_entire_frame(client, args.pid_res)
|
|
return 0
|
|
|
|
if args.pid_kill:
|
|
wait_thread.stop()
|
|
from pid_information import client_pid_kill
|
|
return client_pid_kill(client, args.pid_kill)
|
|
|
|
if not args.method:
|
|
wait_thread.stop()
|
|
client_list_methods(client)
|
|
return 1
|
|
|
|
elif args.method and args.help:
|
|
view_params = get_view_params(client, args.method + '_view',
|
|
step = None, expert = True)
|
|
view = get_view(client, args.method, client.sid, view_params)
|
|
wait_thread.stop()
|
|
sys.stdout.write("\b")
|
|
sys.stdout.flush()
|
|
method_parser = get_method_argparser(view, args)
|
|
method_parser.print_help()
|
|
client.service.clear_method_cache(client.sid, args.method)
|
|
|
|
else:
|
|
try:
|
|
client.frame_period = clVarsCore.Get('cl_core_get_frame_period')
|
|
except:
|
|
client.frame_period = 2
|
|
method_result = call_method(client, args, wait_thread)
|
|
if method_result:
|
|
client.no_progress = args.no_progress
|
|
try:
|
|
analysis(client, client.sid, method_result)
|
|
except urllib2.URLError, e:
|
|
_print (e)
|
|
except KeyboardInterrupt:
|
|
try:
|
|
print
|
|
mess = method_result[0][0]
|
|
pid = int(mess.message)
|
|
result = client.service.pid_kill(pid, client.sid)
|
|
if result in [0,2]:
|
|
print _('Process terminated')
|
|
elif result == -1:
|
|
print _("Certificate not found on the server")
|
|
elif result == -2:
|
|
print _("Session not matching your certificate")
|
|
elif result == 1:
|
|
print _("Failed to kill the process")
|
|
# get_entire_frame(client, pid)
|
|
analysis(client, client.sid, method_result)
|
|
except Exception, e:
|
|
_print (e.message)
|
|
|
|
try:
|
|
mess = method_result[0][0]
|
|
pid = int(mess.message)
|
|
except:
|
|
return 1
|
|
|
|
client.service.clear_pid_cache(client.sid, pid)
|
|
client.service.clear_method_cache(client.sid, args.method)
|
|
wait_thread.stop()
|
|
return 0
|
|
|
|
def main(wait_thread):
|
|
parser = parse()
|
|
args, unknown_args = parser.parse_known_args()
|
|
wait_thread.start()
|
|
|
|
# if os.path.basename(sys.argv[0]) != 'cl-console':
|
|
# args.method = '_temp_'
|
|
# args.host = 'localhost'
|
|
|
|
if not args.method and args.help:
|
|
wait_thread.stop()
|
|
sys.stdout.write('\r')
|
|
sys.stdout.flush()
|
|
parser.print_help()
|
|
return 0
|
|
|
|
if not args.method:
|
|
if unknown_args:
|
|
wait_thread.stop()
|
|
sys.stdout.write('\r')
|
|
sys.stdout.flush()
|
|
args = parser.parse_args()
|
|
|
|
logging.basicConfig(level=logging.FATAL)
|
|
logging.getLogger('sudsds.client').setLevel(logging.FATAL)
|
|
logging.getLogger('sudsds.transport').setLevel(logging.FATAL)
|
|
logging.getLogger('sudsds.transport.http').setLevel(logging.FATAL)
|
|
logging.getLogger('sudsds.umx.typed').setLevel(logging.ERROR)
|
|
|
|
clVarsCore = DataVarsCore()
|
|
clVarsCore.importCore()
|
|
clVarsCore.flIniFile()
|
|
|
|
homePath = clVarsCore.Get('ur_home_path')
|
|
|
|
port = args.port
|
|
host = args.host
|
|
path_to_cert = args.path_to_cert
|
|
if not path_to_cert:
|
|
path_to_cert = clVarsCore.Get('cl_client_cert_dir')
|
|
path_to_cert = path_to_cert.replace("~",homePath)
|
|
|
|
for dirs in ['', 'ca', 'trusted']:
|
|
dir_path = os.path.join(path_to_cert, dirs)
|
|
if not os.path.isdir(dir_path):
|
|
if not makeDirectory(dir_path):
|
|
wait_thread.stop()
|
|
sys.stdout.write('\r')
|
|
sys.stdout.flush()
|
|
print _("Failed to create directory %s") %dir_path
|
|
return 1
|
|
|
|
if args.update_crl:
|
|
wait_thread.stop()
|
|
getCRL = threading.Thread(target=get_CRL, args = (path_to_cert, ))
|
|
getCRL.start()
|
|
getCRL.join()
|
|
print 'GRL updated'
|
|
return 0
|
|
|
|
if args.by_host:
|
|
wait_thread.stop()
|
|
client_post_request (path_to_cert, args)
|
|
return 0
|
|
if args.from_host:
|
|
wait_thread.stop()
|
|
client_get_cert (path_to_cert, args)
|
|
return 0
|
|
|
|
url = "https://%s:%d/?wsdl" %(host, port)
|
|
|
|
clear()
|
|
serv_hostname = get_server_hostname(host, path_to_cert)
|
|
get_name_flag = False
|
|
if serv_hostname:
|
|
Connect_Error = 1
|
|
crypto_Error = 0
|
|
client, Connect_Error, crypto_Error, passwd_flag, e = \
|
|
connect_with_cert (serv_hostname, path_to_cert, url, args,
|
|
wait_thread, clVarsCore, crypto_Error, Connect_Error)
|
|
if not wait_thread.isAlive():
|
|
wait_thread = StoppableThread()
|
|
wait_thread.start()
|
|
get_name_flag = True
|
|
if Connect_Error:
|
|
if crypto_Error and passwd_flag:
|
|
wait_thread.stop()
|
|
sys.stdout.write('\r')
|
|
sys.stdout.flush()
|
|
print _('Invalid password')
|
|
# delete password from daemon list
|
|
clear_password(host, port)
|
|
elif e:
|
|
wait_thread.stop()
|
|
if type(e.message) != int:
|
|
print _('Error: '), e
|
|
get_name_flag = False
|
|
|
|
if get_name_flag:
|
|
try:
|
|
client.port = port
|
|
return_val = 1
|
|
try:
|
|
return_val = https_server(client, args, unknown_args, url, \
|
|
clVarsCore, wait_thread)
|
|
except urllib2.URLError, e:
|
|
print _('Error: '), e
|
|
except KeyboardInterrupt:
|
|
wait_thread.stop()
|
|
red = '\n'+'\033[31m * \033[0m'
|
|
print red + _('Interrupted by the user')
|
|
except Exception, e:
|
|
wait_thread.stop()
|
|
if type(e.message) != int:
|
|
if e.message:
|
|
print e.message
|
|
elif e.args:
|
|
print e
|
|
# tb.print_exc()
|
|
return 1
|
|
wait_thread.stop()
|
|
return return_val
|
|
except WebFault, f:
|
|
print _("Exception: %s") %f
|
|
_print (f.fault)
|
|
except TransportError, te:
|
|
print _("Exception: %s") %te
|
|
except KeyboardInterrupt:
|
|
wait_thread.stop()
|
|
red = '\n'+'\033[31m * \033[0m'
|
|
print red + _('Interrupted by the user')
|
|
except Exception, e:
|
|
print _("Exception: %s") %e
|
|
tb.print_exc()
|
|
wait_thread.stop()
|
|
|
|
try:
|
|
client = Client_suds(url, \
|
|
transport = HTTPSClientCertTransport(None,None, path_to_cert))
|
|
client.wsdl.services[0].setlocation(url)
|
|
server_host_name = client.service.get_server_host_name()
|
|
if not add_server_hostname(host, path_to_cert, server_host_name):
|
|
print 'compliance_file write error!'
|
|
del (client)
|
|
except urllib2.URLError, e:
|
|
wait_thread.stop()
|
|
print '\b' + _('Failed to connect')+':', e
|
|
return 1
|
|
except KeyboardInterrupt:
|
|
wait_thread.stop()
|
|
red = '\n'+'\033[31m * \033[0m'
|
|
print red + _('Interrupted by the user')
|
|
|
|
try:
|
|
import glob
|
|
all_cert_list = glob.glob(os.path.join(path_to_cert, '*.crt'))
|
|
fit_cert_list = []
|
|
for client_cert_path in all_cert_list:
|
|
client_cert = client_cert_path.replace(path_to_cert, '')
|
|
client_cert_name = client_cert.replace('.crt', '')
|
|
if server_host_name.endswith(client_cert_name):
|
|
fit_cert_list.append(client_cert_name)
|
|
fit_cert_list.sort(key = len)
|
|
Connect_Error = 1
|
|
crypto_Error = 0
|
|
e = None
|
|
|
|
for i in range (0, len(fit_cert_list)):
|
|
cert_name = fit_cert_list.pop()
|
|
client, Connect_Error, crypto_Error, passwd_flag, e = \
|
|
connect_with_cert (cert_name, path_to_cert, url, args,
|
|
wait_thread, clVarsCore, crypto_Error, Connect_Error)
|
|
if not wait_thread.isAlive():
|
|
wait_thread = StoppableThread()
|
|
wait_thread.start()
|
|
|
|
if Connect_Error == 0:
|
|
break
|
|
|
|
#If the certificate file misses
|
|
if Connect_Error:
|
|
if crypto_Error and passwd_flag:
|
|
wait_thread.stop()
|
|
sys.stdout.write('\r')
|
|
sys.stdout.flush()
|
|
print _('Invalid password')
|
|
# delete password from daemon list
|
|
clear_password(host, port)
|
|
return 1
|
|
elif e:
|
|
wait_thread.stop()
|
|
if type(e.message) != int:
|
|
print _('Error: '), e
|
|
return 1
|
|
|
|
CERT_FILE = None
|
|
CERT_KEY = None
|
|
client = Client_suds(url, transport = HTTPSClientCertTransport \
|
|
(CERT_KEY, CERT_FILE, path_to_cert))
|
|
client.wsdl.services[0].setlocation(url)
|
|
client.set_parameters (path_to_cert, CERT_FILE, CERT_KEY)
|
|
|
|
client.port = port
|
|
return_val = 1
|
|
try:
|
|
return_val = https_server(client, args, unknown_args, url, \
|
|
clVarsCore, wait_thread)
|
|
except urllib2.URLError, e:
|
|
print _('Error: '), e
|
|
except KeyboardInterrupt:
|
|
wait_thread.stop()
|
|
red = '\n'+'\033[31m * \033[0m'
|
|
print red + _('Interrupted by the user')
|
|
except Exception, e:
|
|
wait_thread.stop()
|
|
if type(e.message) != int:
|
|
if e.message:
|
|
print e.message
|
|
elif e.args:
|
|
print e
|
|
# tb.print_exc()
|
|
return 1
|
|
wait_thread.stop()
|
|
return return_val
|
|
#----------------------------------------------------
|
|
except WebFault, f:
|
|
print _("Exception: %s") %f
|
|
_print (f.fault)
|
|
except TransportError, te:
|
|
print _("Exception: %s") %te
|
|
except KeyboardInterrupt:
|
|
wait_thread.stop()
|
|
red = '\n'+'\033[31m * \033[0m'
|
|
print red + _('Interrupted by the user')
|
|
except Exception, e:
|
|
print _("Exception: %s") %e
|
|
tb.print_exc()
|
|
wait_thread.stop()
|