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.
261 lines
8.8 KiB
261 lines
8.8 KiB
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
|
|
#
|
|
# Session management
|
|
#
|
|
# 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 __future__ import absolute_import
|
|
import os
|
|
import datetime
|
|
import threading
|
|
import random
|
|
import pickle
|
|
from calculate.core.server.core_interfaces import CoreServiceInterface
|
|
from .cert_cmd import find_cert_id
|
|
|
|
|
|
class CoreWsdl(CoreServiceInterface):
|
|
sid_locker = threading.Lock()
|
|
|
|
# delete client session from file (close session)
|
|
@staticmethod
|
|
def del_sid_from_file(cls, sid):
|
|
try:
|
|
# temp file
|
|
sid_file = cls.sids_file
|
|
sid_file_t = sid_file + 'temp'
|
|
|
|
with cls.sid_locker:
|
|
fd = open(sid_file, 'r')
|
|
ft = open(sid_file_t, 'w')
|
|
while True:
|
|
try:
|
|
# read all on one record
|
|
list_sid = pickle.load(fd)
|
|
except (EOFError, IOError, KeyError):
|
|
break
|
|
# Leave all but removed
|
|
if sid != list_sid[0]:
|
|
pickle.dump(list_sid, ft)
|
|
fd.close()
|
|
ft.close()
|
|
|
|
# copy all from temp file
|
|
ft = open(sid_file_t, 'rb')
|
|
fd = open(sid_file, 'wb')
|
|
ft.seek(0)
|
|
fd.write(ft.read())
|
|
ft.close()
|
|
fd.close()
|
|
# delete temp file
|
|
os.unlink(sid_file_t)
|
|
return ['0']
|
|
except (IOError, EOFError, KeyError, OSError):
|
|
return ['1']
|
|
|
|
# find session id in file
|
|
@staticmethod
|
|
def find_sid_in_file(cls, sid):
|
|
sid_file = cls.sids_file
|
|
# create, if file not exists
|
|
with cls.sid_locker:
|
|
if not os.path.exists(sid_file):
|
|
temp = open(sid_file, 'w')
|
|
temp.close()
|
|
fd = open(sid_file, 'r')
|
|
while True:
|
|
try:
|
|
# read all on one record
|
|
list_sid = pickle.load(fd)
|
|
except (EOFError, IOError, KeyError):
|
|
break
|
|
# if session id found
|
|
if sid == list_sid[0]:
|
|
fd.close()
|
|
return 1
|
|
fd.close()
|
|
return 0
|
|
|
|
# add session id in file
|
|
@staticmethod
|
|
def add_sid_in_file(cls, sid, cert_id, lang):
|
|
# list Format (session number, cert number, time start session)
|
|
list_sid = [sid, cert_id, datetime.datetime.now()]
|
|
# session's file
|
|
if not os.path.exists(cls.sids):
|
|
os.mkdir(cls.sids)
|
|
sids_dir = cls.sids
|
|
sid_file = sids_dir + "/%d.sid" % sid
|
|
|
|
# create session's file
|
|
with cls.sid_locker:
|
|
fp = open(sid_file, 'w')
|
|
sid_list = [sid, 0, 0, lang]
|
|
pickle.dump(sid_list, fp)
|
|
fp.close()
|
|
|
|
# add session in list sessions
|
|
fd = open(cls.sids_file, 'a')
|
|
pickle.dump(list_sid, fd)
|
|
fd.close()
|
|
return 0
|
|
|
|
@staticmethod
|
|
def set_sid_lang(cls, sid, lang):
|
|
sids_dir = cls.sids
|
|
sid_file = os.path.join(sids_dir, "%d.sid" % sid)
|
|
with cls.sid_locker:
|
|
if not os.path.isfile(sid_file):
|
|
fp = open(sid_file, 'w')
|
|
fp.close()
|
|
fd = open(sid_file, 'r')
|
|
try:
|
|
list_sid = pickle.load(fd)
|
|
except (EOFError, KeyError, IOError):
|
|
list_sid = [sid, 0, 0, lang]
|
|
fd.close()
|
|
|
|
fp = open(sid_file, 'w')
|
|
list_sid[3] = lang
|
|
pickle.dump(list_sid, fp)
|
|
fp.close()
|
|
|
|
# issue number of new session (and registered its)
|
|
@staticmethod
|
|
def sid_cmp(cls, sid, cert_id, lang):
|
|
if sid < 0 or sid > cls.max_sid:
|
|
sid = 0
|
|
session = 1
|
|
# if session is new
|
|
if sid == 0:
|
|
while True:
|
|
new_sid = random.randint(1, cls.max_sid)
|
|
# flag = 1 - exists, 0 - missing in SID_FILE
|
|
if cls.find_sid_in_file(cls, new_sid) == 0:
|
|
cls.add_sid_in_file(cls, new_sid, cert_id, lang)
|
|
sid = new_sid
|
|
break
|
|
# if session is old
|
|
else:
|
|
# find number in file registered
|
|
# if not registered
|
|
if not cls.find_sid_in_file(cls, sid):
|
|
# add session id in file
|
|
cls.add_sid_in_file(cls, sid, cert_id, lang)
|
|
else:
|
|
cls.set_sid_lang(cls, sid, lang)
|
|
# set - old session
|
|
session = 0
|
|
|
|
# session id and flag (new or old) session
|
|
return [sid, session]
|
|
|
|
@staticmethod
|
|
def serv_init_session(cls, sid, lang):
|
|
day_cert = 600
|
|
cur_thread = threading.currentThread()
|
|
certificate = cur_thread.client_cert
|
|
if certificate is None:
|
|
return [-3], [0]
|
|
|
|
checked_id = find_cert_id(certificate, cls.data_path, cls.certbase)
|
|
try:
|
|
if int(checked_id) < 1:
|
|
return [-4], [0]
|
|
except ValueError:
|
|
return [-4], [0]
|
|
results = []
|
|
cert_id = checked_id
|
|
with open(cls.certbase) as fd:
|
|
t = fd.read()
|
|
# See each line
|
|
for line in t.splitlines():
|
|
# and each word in line
|
|
words = line.split()
|
|
# if in line present certificate id
|
|
if len(words) > 3:
|
|
if words[0] == checked_id:
|
|
results.append(checked_id)
|
|
date = datetime.datetime.strptime(
|
|
words[2] + ' ' + words[3], '%Y-%m-%d %H:%M:%S.%f')
|
|
d = datetime.datetime.now() - date
|
|
v = day_cert - d.days # How many days left certificate
|
|
if v < 0:
|
|
# Method deleted certificate
|
|
v = -2 # expiry date has passed
|
|
elif v > 60: # For a long time, is not displayed to
|
|
# the client
|
|
v = -1
|
|
results.append(v)
|
|
# return results
|
|
if not results:
|
|
return [-4], [0]
|
|
|
|
return results, cls.sid_cmp(cls, sid, cert_id, lang)
|
|
|
|
@staticmethod
|
|
def serv_sid_info(cls, sid):
|
|
""" Get information about sid """
|
|
cert_id = 0
|
|
results = []
|
|
sid_file = cls.sids_file
|
|
with cls.sid_locker:
|
|
fd = open(sid_file, 'r')
|
|
while 1:
|
|
try:
|
|
# read all on one record
|
|
list_sid = pickle.load(fd)
|
|
except (IOError, KeyError, EOFError):
|
|
break
|
|
# if sid found
|
|
if sid == list_sid[0]:
|
|
cert_id = list_sid[1]
|
|
fd.close()
|
|
|
|
# Get information about sid
|
|
if cert_id == 0:
|
|
return ["-1"]
|
|
|
|
with cls.sid_locker:
|
|
with open(cls.certbase) as fd:
|
|
t = fd.read()
|
|
# See each line
|
|
for line in t.splitlines():
|
|
# and each word in line
|
|
words = line.split()
|
|
# if in line present certificate id
|
|
if words[0] == str(cert_id):
|
|
# certificate id
|
|
results.append(words[0])
|
|
# Date issue certificate
|
|
results.append(words[2] + ' ' + words[3])
|
|
# ip
|
|
results.append(words[4])
|
|
# mac
|
|
results.append(words[5])
|
|
# client type
|
|
results.append(words[6])
|
|
if not os.path.exists(cls.sids):
|
|
os.makedirs(cls.sids)
|
|
sid_path = cls.sids + "/%d.sid" % sid
|
|
with open(sid_path) as fs:
|
|
# read info about session
|
|
sid_inf = pickle.load(fs)
|
|
# flag absence client
|
|
results.append(str(sid_inf[2]))
|
|
|
|
return results
|
|
return ["-2"]
|