#-*- 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 '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 + _("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()