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-core/core/server/cl_server.py

307 lines
9.9 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.
import sys, os
import socket, ssl
from cherrypy.wsgiserver import CherryPyWSGIServer, WSGIPathInfoDispatcher
from cherrypy.wsgiserver.ssl_pyopenssl import pyOpenSSLAdapter
from OpenSSL.SSL import Error as SSLError
from OpenSSL import SSL
import OpenSSL
import importlib
from signal import SIGTERM
import threading
from calculate.lib.datavars import DataVars
from calculate.core.datavars import DataVarsCore
from clean import clean
import cert_cmd
import bootstrap
from func import initialization
from server_class import ClApplication
class OpenSSLAdapter (pyOpenSSLAdapter):
#def check_cert(self, cert):
#if cert == None:
#return -1
#cert_id = 0
#from func import find_cert_id
#find_cert_id(cert, self.data_path, self.certbase)
## open database with certificates
#if not os.path.exists(self.certbase):
#fc = open(self.certbase,"w")
#fc.close()
#fc = open(self.certbase,"r")
#while 1:
#try:
## read all on one record
#cert_dict = pickle.load(fc)
#except:
#break
## if input and cert from database equal
#if cert == cert_dict["cert"]:
## get certificate id
#cert_id = cert_dict["Id"]
#fc.close()
#return cert_id
def verify_func(self, connection, x509, errnum, errdepth, ok):
# get client certificate
curThread = threading.currentThread()
#print '#######################',errdepth,'####################################'
#if not OpenSSL.crypto.dump_certificate \
#(OpenSSL.crypto.FILETYPE_PEM, x509) in self.ca_certs:
#print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
#return 0
if errdepth == 0:
curThread.client_cert = OpenSSL.crypto.dump_certificate \
(OpenSSL.crypto.FILETYPE_PEM, x509)
#cert = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
#curThread.client_cert)
#subject = cert.get_subject()
#if ok:
#try:
#country = len (subject.get_components()) - 1
#language = 1
#curThread.lang = subject.get_components()[country][language]
#except:
#curThread.lang = "En"
else:
curThread.client_cert = None
return ok
def get_context(self):
"""Return an SSL.Context from self attributes."""
# See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442473
c = SSL.Context(SSL.SSLv23_METHOD)
c.use_privatekey_file(self.private_key)
c.set_verify(SSL.VERIFY_PEER, self.verify_func)
if self.certificate_chain:
c.load_verify_locations(self.certificate_chain)
c.use_certificate_file(self.certificate)
return c
def main(*args, **keywords):
# For cleaning of sessions at server reboot
args = cert_cmd.parse()
# translate
if args.lang:
translate(args.lang)
debug = args.debug
import logging
import logging.handlers
if not os.path.exists('/var/log/calculate'):
os.makedirs('/var/log/calculate')
LOG_FILENAME = '/var/log/calculate/logging_cl_core_server.out'
file_logger = logging.getLogger('MyLogger')
file_logger.setLevel(logging.DEBUG)
# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
LOG_FILENAME, maxBytes=10000000, backupCount=3)
file_logger.addHandler(handler)
# debug
if debug:
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('soaplib.wsgi')
logger.setLevel(logging.DEBUG)
port = args.port
ob = DataVarsApi()
ob.importApi()
# set var env
ob.flIniFile()
cl_wsdl = ob.Get('cl_wsdl')
data_path = ob.Get('cl_core_data')
certbase = ob.Get('cl_core_database')
serv_certbase = ob.Get('cl_core_serv_database')
rights = ob.Get('cl_core_rights')
group_rights = ob.Get('cl_core_group_rights')
sids = ob.Get('cl_core_sids_path')
pids = ob.Get('cl_core_pids_path')
sids_pids = ob.Get('cl_core_sids_pids')
sids_file = ob.Get('cl_core_sids_file')
pids_file = ob.Get('cl_core_pids_file')
max_sid = ob.Get('cl_core_max_sid')
max_pid = ob.Get('cl_core_max_pid')
cert_path = ob.Get('cl_core_cert_path')
cert = ob.Get('cl_core_cert')
key = ob.Get('cl_core_key')
cl_ver = ob.Get('cl_ver')
# delete all sid and pid informations file
clean(sids_file, pids_file, sids_pids, sids, pids)
cert_cmd.create_path(data_path, certbase, rights, group_rights)
#####################
''' view information about client certificates '''
if args.version:
print cl_ver
return 0
if args.bootstrap_user_name:
bootstrap.init(cert, key, cert_path, data_path, certbase, args, port,\
args.bootstrap_user_name)
return 0
if args.revoke_cert_id:
cert_cmd.revoke_signed_cert(args.revoke_cert_id, data_path, cert_path)
return 0
if args.host or args.gen_root_cert or args.root_host or args.use_root_cert:
cert_cmd.check_server_certificate(cert, key, cert_path, args, port)
return 0
if args.id_client_req:
cert_cmd.sing_req_by_server(args.id_client_req, cert_path, data_path)
return 0
if args.Id:
cert_cmd.view_cert(args, certbase, data_path, rights, group_rights)
return 0
if args.cert_id:
cert_cmd.view_signed_cert(args, serv_certbase, data_path)
return 0
if args.req_id:
cert_cmd.view_client_request(args, certbase, data_path)
return 0
# Sign request by root certificate
if args.id_server_req:
cert_cmd.sing_req_by_root(args, cert_path, data_path)
return 0
if args.id_del_req:
cert_cmd.del_request(args.id_del_req, serv_certbase, data_path)
return 0
#####################
# importing other modules
other_mod = initialization(cl_wsdl)
#try:
pack = "calculate.core.server"
func_metaclass = importlib.import_module('%s.func_metaclass' %pack)
other_mod.append(func_metaclass.Func_MetaClass)
from calculate.core.server.cl_vers_api import VERS
other_mod.append(VERS)
from calculate.core.server.baseClass import Basic
other_mod.append(Basic)
other_mod.append(object)
# make server metaclass
CombinedServerClass = type ("CombinedServerClass", tuple(other_mod), {})
App = ClApplication([CombinedServerClass],'tns', log = file_logger)
tc = App.get_service(CombinedServerClass)
# set all path
tc.set_paths (data_path, certbase, serv_certbase, rights, group_rights, \
sids, pids, sids_pids, sids_file, pids_file, max_sid, \
max_pid, cert_path, cert, key)
max_num = 99999999
dispatcher = WSGIPathInfoDispatcher( { '' : App } )
server = CherryPyWSGIServer(('0.0.0.0', port), dispatcher,\
numthreads = 10, max = max_num, request_queue_size = max_num)
print _("listening to https://0.0.0.0:%d") % (port)
print _("wsdl is at: https://0.0.0.0:%d/?wsdl") %(port)
ca_cert = cert_path + "/ca_root.crt"
if not os.path.exists (ca_cert):
ca_cert = None
sslAdapter = OpenSSLAdapter(cert, key, ca_cert)
sslAdapter.certbase = certbase
server.ssl_adapter = sslAdapter
server.certbase = certbase
server.serv_certbase = serv_certbase
server.rights = rights
server.group_rights = group_rights
server.sids = sids
server.pids = pids
server.sids_file = sids_file
server.pids_file = pids_file
server.data_path = data_path
server.cert_path = cert_path
server.ssl_certificate = cert
server.ssl_private_key = key
try:
print _("Server start")
server.start()
except KeyboardInterrupt, SIGTERM:
try:
tc.killall()
except KeyboardInterrupt:
pass
print _("\nServer stopping")
server.stop()
sys.exit(0)
except socket.error, e:
print e
except SSLError, e:
print '\n',_('Server certificate not found')#, e
print _('use cl-core with key --gen-cert-by HOST '
'(--get-cert-from HOST) '
'or --use-root-as-server)')
except KeyboardInterrupt:
pass
server.stop()
sys.exit(0)
def translate(lang = None):
import locale
import gettext
if lang:
try:
language = gettext.translation ('cl_core', languages = [lang])
language.install()
return 0
except:
print "lang %s not supported!" %str(lang)
try:
current_locale, encoding = locale.getdefaultlocale()
language = gettext.translation ('cl_core', \
languages = [current_locale] )
language.install()
return 0
except:
language = gettext.translation ('cl_core', languages = ['en'] )
language.install()
return 0
#print _("set locale"), current_locale