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.
calculate-utils-3-console/pym/console/application/cl_client.py

569 lines
19 KiB

#-*- coding: utf-8 -*-
# Copyright 2012-2013 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 calculate.core.server.local_call import Display, Methods
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 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 function import MessageReceiver, MessageDispatcher, clear, _print, \
get_view_params
from calculate.lib.utils.files import makeDirectory, readLinesFile
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_console3',sys.modules[__name__])
def get_message_receiver(client):
return MessageReceiver(client, MessageDispatcher(Methods()), Display())
def get_entire_message_receiver(client, pid):
return MessageReceiver.from_entire(client, pid,
MessageDispatcher(Methods()), Display())
def client_signal(client):
Vars = DataVarsCore()
Vars.importCore()
Vars.flIniFile()
try:
client_active = Vars.Get('core.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()
self._pause = threading.Event()
self._paused = 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)
while self.paused() and not self.stopped():
self._paused.set()
if self.stopped():
sys.stdout.write("\b")
sys.stdout.flush()
return 0
def pause(self):
self._pause.set()
while not self._paused.is_set():
self._paused.clear()
sys.stdout.write("\r")
sys.stdout.flush()
def resume(self):
self._pause.clear()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
def paused(self):
return self._pause.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:
port = args.port or clVarsCore.Get('core.cl_core_port')
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)
return 0
try:
client.frame_period = clVarsCore.Get('core.cl_core_get_frame_period')
except:
client.frame_period = 2
if args.pid_res:
wait_thread.stop()
mr = get_entire_message_receiver(client, args.pid_res)
if mr:
mr.get_messages()
if not args.keep_result:
client.service.clear_pid_cache(client.sid, args.pid_res)
return 0
else:
return 1
if args.pid_kill:
wait_thread.stop()
from pid_information import client_pid_kill
return client_pid_kill(client, args.pid_kill)
retCode = 0
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,
onlyhelp = 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:
method_result = call_method(client, args, unknown_args, wait_thread)
mr = get_message_receiver(client)
if method_result:
client.no_progress = args.no_progress
try:
mr.analysis(method_result)
#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 terminate the process")
mr.analysis(method_result)
except Exception, e:
_print(e.message)
try:
mess = method_result[0][0]
pid = int(mess.message)
except:
return 1
retCode = \
1 if int(client.service.pid_info(client.sid,pid)[0][1]) else 0
if not args.keep_result:
client.service.clear_pid_cache(client.sid, pid)
client.service.clear_method_cache(client.sid, args.method)
wait_thread.stop()
return retCode
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 or clVarsCore.GetInteger('core.cl_core_port')
host = args.host
path_to_cert = args.path_to_cert
if not path_to_cert:
path_to_cert = clVarsCore.Get('core.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 'CRL 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:%s/?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 + _("Manually interrupted")
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 + _("Manually interrupted")
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 + _("Manually interrupted")
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 + _("Manually interrupted")
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 + _("Manually interrupted")
except Exception, e:
print _("Exception: %s") %e
tb.print_exc()
wait_thread.stop()