#!/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 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') 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: client = Client_suds(url, transport=HTTPSClientCertTransport \ (CERT_KEY, CERT_FILE, path_to_cert, password=key_passwd, 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, 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 (_('Not found method 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) if args.session_list: wait_thread.stop() client_session_list(client) 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) method_parser = get_method_argparser(view, args) wait_thread.stop() sys.stdout.write("\b") sys.stdout.flush() method_parser.print_help() 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: 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 is terminated') elif result == -1: print _("Certificate not found in server database") elif result == -2: print _("Session doesn't belong to your certificate") elif result == 1: print _("It was not possible to kill 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 _("cannot 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() print _('Password is invalid') # delete password from daemon list clear_password(host, port) get_name_flag = False if e: wait_thread.stop() 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 Exception, e: wait_thread.stop() if type(e.message) != int: if e.message: print e.message else: print e 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 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 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() print _('Password is invalid') # delete password from daemon list clear_password(host, port) return 1 if e: wait_thread.stop() 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 Exception, e: wait_thread.stop() if type(e.message) != int: if e.message: print e.message else: print e 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 Exception, e: print _("Exception: %s") %e tb.print_exc() wait_thread.stop()