def disconnect(self): try: is_chap = self.settings.config.portal.chap in (1, "1", "chap") userIp = self.current_user.ipaddr nas = self.get_nas(self.current_user.nasaddr) ac_addr = nas['ip_addr'] ac_port = int(nas['ac_port']) secret = utils.safestr(nas['bas_secret']) _vendor = utils.safestr(nas['portal_vendor']) if _vendor not in ('cmccv1', 'cmccv2', 'huaweiv1', 'huaweiv2'): defer.returnValue("not support vendor %s" % _vendor) send_portal = functools.partial(client.send, secret, log=self.syslog, debug=self.settings.debug, vendor=_vendor) vendor = client.PortalClient.vendors.get(_vendor) logout_req = vendor.proto.newReqLogout(userIp, secret, chap=is_chap) logout_resp = yield send_portal(data=logout_req, host=ac_addr, port=ac_port) if logout_resp.errCode > 0: _err_msg = u"{0},{1}".format( vendor.mod.AckLogoutErrs[logout_resp.errCode], utils.safeunicode(logout_resp.get_text_info()[0] or "")) logger.error(_err_msg) defer.returnValue("disconnect done!") except Exception as err: defer.returnValue(err)
def process(self, *args, **kwargs): with make_db(self.db) as db: try: nas_list = db.query(models.TrBas) for nas in nas_list: if not nas.dns_name: continue results, _, _ = yield client.lookupAddress(nas.dns_name) if not results: logger.info("domain {0} resolver empty".format( nas.dns_name)) if results[0].type == dns.A: ipaddr = ".".join( str(i) for i in struct.unpack( "BBBB", results[0].payload.address)) if ipaddr: nas.ip_addr = ipaddr db.commit() logger.info( "domain {0} resolver {1} success".format( nas.dns_name, ipaddr)) else: logger.info("domain {0} no ip address,{1}".format( nas.dns_name, repr(results))) except Exception as err: logger.error('ddns process error %s' % utils.safeunicode(err.message)) defer.returnValue(60)
def parse_form_request(self): try: print self.get_params() return apiutils.parse_form_request(self.settings.config.system.secret, self.get_params()) except Exception as err: logger.error(u"api authorize parse error, %s" % utils.safeunicode(traceback.format_exc())) raise ValueError(u"Error: %s" % utils.safeunicode(err.message))
def disconnect(self): try: is_chap=self.settings.config.portal.chap in (1, "1", "chap") userIp = self.current_user.ipaddr nas = self.get_nas(self.current_user.nasaddr) ac_addr = nas['ip_addr'] ac_port = int(nas['ac_port']) secret = utils.safestr(nas['bas_secret']) _vendor= utils.safestr(nas['portal_vendor']) if _vendor not in ('cmccv1','cmccv2','huaweiv1','huaweiv2'): defer.returnValue("not support vendor %s"%_vendor) send_portal = functools.partial( client.send, secret, log=self.syslog, debug=self.settings.debug, vendor=_vendor ) vendor = client.PortalClient.vendors.get(_vendor) logout_req = vendor.proto.newReqLogout(userIp, secret,chap=is_chap) logout_resp = yield send_portal(data=logout_req, host=ac_addr, port=ac_port) if logout_resp.errCode > 0: _err_msg=u"{0},{1}".format( vendor.mod.AckLogoutErrs[logout_resp.errCode], utils.safeunicode(logout_resp.get_text_info()[0] or "") ) logger.error( _err_msg) defer.returnValue("disconnect done!") except Exception as err: defer.returnValue(err)
def process(self, *args, **kwargs): self.logtimes() with make_db(self.db) as db: try: nodes = db.query(models.TrNode) for node in nodes: online_count = db.query(models.TrOnline.id).filter( models.TrOnline.account_number == models.TrAccount.account_number, models.TrAccount.customer_id == models.TrCustomer.customer_id, models.TrCustomer.node_id == node.id).count() stat = models.TrOnlineStat() stat.node_id = node.id stat.stat_time = int(time.time()) stat.total = online_count db.add(stat) # clean expire data _time = int(time.time()) - (86400 * 2) db.query(models.TrOnlineStat).filter( models.TrOnlineStat.stat_time < _time).delete() db.commit() logger.info("online stat task done") except Exception as err: db.rollback() logger.error('online_stat_job err,%s' % (str(err))) return self.get_notify_interval()
def process(self, *args, **kwargs): self.logtimes() next_interval = self.get_notify_interval() backup_path = self.config.database.backup_path backup_file = "trdb_cron_backup_%s.json.gz" % utils.gen_backep_id() try: self.db_backup.dumpdb(os.path.join(backup_path, backup_file)) logger.info(u"数据备份完成,下次执行还需等待 %s" % (self.format_time(next_interval))) except Exception as err: logger.error(u"数据备份失败,%s, 下次执行还需等待 %s" % (repr(err), self.format_time(next_interval))) logger.exception(err) try: bak_list = [ bd for bd in os.listdir(backup_path) if 'trdb_cron_backup' in bd ] if len(bak_list) > 7: logger.info("find expire backup file and remove") _count = 0 for fname in bak_list: fpath = os.path.join(backup_path, fname) if (time.time() - os.path.getctime(fpath)) / (3600 * 24) > 14: os.remove(fpath) _count += 1 logger.info("remove expire backup file %s" % fpath) logger.info("remove expire backup file total %s" % _count) except Exception as err: logger.exception(err) return next_interval
def process(self, *args, **kwargs): next_interval = self.get_notify_interval() user_total = 0 online_total = 0 with make_db(self.db) as db: try: user_total = db.query(models.TrAccount).count() online_total = db.query(models.TrOnline).count() except Exception as err: pass try: api_url = "https://www.toughcloud.net/api/v1/ping" api_token = yield tools.get_sys_token() params = dict( token=api_token, app="toughradius", ver=__version__, release=self.config.system.get('release',"standard"), unum=user_total, onum=online_total, dist=' '.join(pf.linux_distribution()), ) param_str = urlencode(params) resp = yield httpclient.fetch(api_url+"?"+param_str,followRedirect=True) logger.info("toughcloud ping resp code: %s"%resp.code) except Exception as err: logger.error(err) defer.returnValue(next_interval)
def acctounting(self): if self.is_online(self.request.nas_addr, self.request.acct_session_id): return logger.error('online %s is exists' % self.request.acct_session_id) if not self.account: dispatch.pub(UNLOCK_ONLINE_EVENT, self.request.account_number, self.request.nas_addr, self.request.acct_session_id, async=True) return logger.error('user %s not exists' % self.request.account_number) online = Storage(account_number=self.request.account_number, nas_addr=self.request.nas_addr, acct_session_id=self.request.acct_session_id, acct_start_time=datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"), framed_ipaddr=self.request.framed_ipaddr, mac_addr=self.request.mac_addr or '', nas_port_id=self.request.nas_port_id, billing_times=0, input_total=0, output_total=0, start_source=STATUS_TYPE_START) self.add_online(online) logger.info('%s Accounting start request, add new online' % online.account_number)
def processAcct(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAcctPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccountingRequest: raise PacketError('non-AccountingRequest packet on authentication socket') if not req.VerifyAcctRequest(): raise PacketError('VerifyAcctRequest error') reply = req.CreateReply() status_type = req.get_acct_status_type() if status_type in self.acct_class: acct_func = self.acct_class[status_type](self,req.get_ticket()).acctounting reactor.callLater(0.1,acct_func) return reply except Exception as err: errstr = 'RadiusError:Dropping invalid acct packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) logger.error(errstr) import traceback traceback.print_exc()
def process(self): conn = self.db() try: nas_list = conn.query(models.TrwBas) for nas in nas_list: if not nas.dns_name: continue results, _, _ = yield client.lookupAddress(nas.dns_name) if not results: logger.error("domain {0} resolver empty".format( nas.dns_name)) if results[0].type == dns.A: ipaddr = ".".join( str(i) for i in struct.unpack( "BBBB", results[0].payload.address)) if ipaddr: nas.ip_addr = ipaddr conn.commit() logger.info("domain {0} resolver {1} success".format( nas.dns_name, ipaddr)) else: logger.info("domain {0} no ip address,{1}".format( nas.dns_name, repr(results))) except Exception as err: logger.error('ddns process error %s' % utils.safeunicode(err.message)) finally: conn.close() reactor.callLater( 60, self.process, )
def process(self, *args, **kwargs): self.logtimes() next_interval = self.get_notify_interval() backup_path = self.config.database.backup_path backup_file = "trdb_cron_backup_%s.json.gz" % utils.gen_backep_id() try: self.db_backup.dumpdb(os.path.join(backup_path, backup_file)) logger.info(u"数据备份完成,下次执行还需等待 %s"%(self.format_time(next_interval)) ) except Exception as err: logger.error(u"数据备份失败,%s, 下次执行还需等待 %s"%( repr(err), self.format_time(next_interval)) ) logger.exception(err) try: bak_list = [ bd for bd in os.listdir(backup_path) if 'trdb_cron_backup' in bd] if len(bak_list) > 7: logger.info("find expire backup file and remove") _count = 0 for fname in bak_list: fpath = os.path.join(backup_path, fname) if (time.time() - os.path.getctime(fpath)) > 14: os.remove(fpath) _count += 1 logger.info("remove expire backup file %s"%fpath) logger.info("remove expire backup file total %s"%_count) except Exception as err: logger.exception(err) return next_interval
def onSendError(self,err, disconnect_req): if disconnect_req and self.db.query(models.TrOnline).filter_by( nas_addr=disconnect_req.nas_addr, acct_session_id=disconnect_req.acct_session_id).count() > 0: radius_acct_stop.RadiusAcctStop( self.dbengine,self.mcache,self.aes, disconnect_req).acctounting() logger.error(u"send disconnect done! %s" % err.getErrorMessage())
def process(self, *args, **kwargs): with make_db(self.db) as db: try: nodes = db.query(models.TrNode) for node in nodes: online_count = ( db.query(models.TrOnline.id) .filter( models.TrOnline.account_number == models.TrAccount.account_number, models.TrAccount.customer_id == models.TrCustomer.customer_id, models.TrCustomer.node_id == node.id, ) .count() ) stat = models.TrOnlineStat() stat.node_id = node.id stat.stat_time = int(time.time()) stat.total = online_count db.add(stat) db.commit() logger.info("online stat task done") except Exception as err: db.rollback() logger.error("online_stat_job err,%s" % (str(err))) return 120.0
def event_toughcloud_mail_account_open(self, userinfo): """ toughCloud mail api open notify without password event """ if not userinfo: return if not userinfo.get('email'): logger.error('user email is None exit') return try: api_secret = self.get_param_value("toughcloud_license") service_mail = self.get_param_value("toughcloud_service_mail") if not service_mail: return api_token = yield tools.get_sys_token() params = dict( token=api_token.strip(), action='email', mailto=userinfo.get('email'), tplname=self.MAIL_TPLNAME, customer=utils.safestr(userinfo.get('realname')), username=userinfo.get('account_number'), product=utils.safestr(userinfo.get('product_name')), expire=userinfo.get('expire_date'), service_call=self.get_param_value("toughcloud_service_call", ''), service_mail=service_mail, nonce=str(int(time.time())) ) params['sign'] = apiutils.make_sign(api_secret.strip(), params.values()) resp = yield httpclient.fetch(self.MAIL_APIURL, postdata=urlencode(params)) logger.info(resp.body) logger.info('open account send email without password success') except Exception as err: logger.exception(err)
def load_events(event_path=None, pkg_prefix=None, excludes=[], event_params={}): _excludes = ["__init__", "settings"] + excludes evs = set(os.path.splitext(it)[0] for it in os.listdir(event_path)) evs = [it for it in evs if it not in _excludes] for ev in evs: try: sub_module = os.path.join(event_path, ev) if os.path.isdir(sub_module): # logger.info('load sub event %s' % ev) load_events( event_path=sub_module, pkg_prefix="{0}.{1}".format(pkg_prefix, ev), excludes=excludes, event_params=event_params, ) _ev = "{0}.{1}".format(pkg_prefix, ev) # logger.info('load_event %s with params:%s' % (_ev,repr(event_params))) robj = importlib.import_module(_ev) if hasattr(robj, "evobj"): dispatch.register(robj.evobj) if hasattr(robj, "__call__"): dispatch.register(robj.__call__(**event_params)) except Exception as err: logger.error("%s, skip module %s.%s" % (str(err), pkg_prefix, ev)) import traceback traceback.print_exc() continue
def process(self, *args, **kwargs): self.logtimes() with make_db(self.db) as db: try: onlines = db.query(models.TrOnline) for online in onlines: acct_start_time = datetime.datetime.strptime( online.acct_start_time, '%Y-%m-%d %H:%M:%S') nowdate = datetime.datetime.now() dt = nowdate - acct_start_time online_times = dt.total_seconds() max_session_time = int( self.get_param_value('radius_max_session_timeout', 86400)) if online_times > (max_session_time): logger.info( "online %s overtime, system auto disconnect this online" % online.account_number) dispatch.pub(UNLOCK_ONLINE_EVENT, online.account_number, online.nas_addr, online.acct_session_id, async=True) logger.info("online overtime check task done") except Exception as err: db.rollback() logger.error('online overtime check job err,%s' % (str(err))) return self.get_notify_interval()
def process(self, *args, **kwargs): next_interval = self.get_notify_interval() user_total = 0 online_total = 0 with make_db(self.db) as db: try: user_total = db.query(models.TrAccount).count() online_total = db.query(models.TrOnline).count() except Exception as err: pass try: api_url = "https://www.toughcloud.net/api/v1/ping" api_token = yield tools.get_sys_token() params = dict( token=api_token, app="toughradius", ver=__version__, release=self.config.system.get('release', "standard"), unum=user_total, onum=online_total, dist=' '.join(pf.linux_distribution()), ) param_str = urlencode(params) resp = yield httpclient.fetch(api_url + "?" + param_str, followRedirect=True) logger.info("toughcloud ping resp code: %s" % resp.code) except Exception as err: logger.error(err) defer.returnValue(next_interval)
def process(self): conn = self.db() try: nas_list = conn.query(models.TrwBas) for nas in nas_list: if not nas.dns_name: continue results, _, _ = yield client.lookupAddress(nas.dns_name) if not results: logger.error("domain {0} resolver empty".format(nas.dns_name)) if results[0].type == dns.A: ipaddr = ".".join(str(i) for i in struct.unpack("BBBB", results[0].payload.address)) if ipaddr: nas.ip_addr = ipaddr conn.commit() logger.info("domain {0} resolver {1} success".format(nas.dns_name,ipaddr)) else: logger.info("domain {0} no ip address,{1}".format(nas.dns_name, repr(results))) except Exception as err: logger.error('ddns process error %s' % utils.safeunicode(err.message)) finally: conn.close() reactor.callLater(60, self.process, )
def process(self, *args, **kwargs): self.logtimes() with make_db(self.db) as db: try: nodes = db.query(models.TrNode) for node in nodes: r = db.query( func.sum(models.TrOnline.input_total).label("input_total"), func.sum(models.TrOnline.output_total).label("output_total") ).filter( models.TrOnline.account_number == models.TrAccount.account_number, models.TrAccount.customer_id == models.TrCustomer.customer_id, models.TrCustomer.node_id == node.id ).first() if r and all([r.input_total,r.output_total]): stat = models.TrFlowStat() stat.node_id = node.id stat.stat_time = int(time.time()) stat.input_total = r.input_total stat.output_total = r.output_total db.add(stat) # clean expire data _time = int(time.time()) - (86400 * 2) db.query(models.TrFlowStat).filter(models.TrFlowStat.stat_time < _time).delete() db.commit() logger.info("flow stat task done") except Exception as err: db.rollback() logger.error('flow_stat_job err,%s'%(str(err))) return self.get_notify_interval()
def load_events(event_path=None, pkg_prefix=None, excludes=[], event_params={}): _excludes = ['__init__', 'settings'] + excludes evs = set(os.path.splitext(it)[0] for it in os.listdir(event_path)) evs = [it for it in evs if it not in _excludes] for ev in evs: try: sub_module = os.path.join(event_path, ev) if os.path.isdir(sub_module): # logger.info('load sub event %s' % ev) load_events( event_path=sub_module, pkg_prefix="{0}.{1}".format(pkg_prefix, ev), excludes=excludes, event_params=event_params, ) _ev = "{0}.{1}".format(pkg_prefix, ev) # logger.info('load_event %s with params:%s' % (_ev,repr(event_params))) robj = importlib.import_module(_ev) if hasattr(robj, 'evobj'): dispatch.register(robj.evobj) if hasattr(robj, '__call__'): dispatch.register(robj.__call__(**event_params)) except Exception as err: logger.error("%s, skip module %s.%s" % (str(err), pkg_prefix, ev)) import traceback traceback.print_exc() continue
def process(self, *args, **kwargs): with make_db(self.db) as db: try: nodes = db.query(models.TrNode) for node in nodes: r = db.query( func.sum( models.TrOnline.input_total).label("input_total"), func.sum(models.TrOnline.output_total).label( "output_total")).filter( models.TrOnline.account_number == models.TrAccount.account_number, models.TrAccount.customer_id == models.TrCustomer.customer_id, models.TrCustomer.node_id == node.id).first() if r and all([r.input_total, r.output_total]): stat = models.TrFlowStat() stat.node_id = node.id stat.stat_time = int(time.time()) stat.input_total = r.input_total stat.output_total = r.output_total db.add(stat) db.commit() logger.info("flow stat task done") except Exception as err: db.rollback() logger.error('flow_stat_job err,%s' % (str(err))) return 120.0
def event_toughcloud_sms_account_open(self, userinfo): """ toughCloud sms api open notify event """ if not userinfo: return if not userinfo.get('phone'): logger.error('user phone is None exit') return api_secret = self.get_param_value("toughcloud_license") api_token = yield tools.get_sys_token() params = dict( token=api_token.strip(), action='sms', tplname=self.SMS_TPLNAME, phone=userinfo.get('phone'), customer=utils.safestr(userinfo.get('realname')), username=userinfo.get('account_number'), product=utils.safestr(userinfo.get('product_name')), password=userinfo.get('password'), expire=userinfo.get('expire_date'), nonce=str(int(time.time())) ) params['sign'] = apiutils.make_sign(api_secret.strip(), params.values()) try: resp = yield httpclient.fetch(self.SMS_APIURL, postdata=urlencode(params)) logger.info(resp.body) logger.info('open account send short message success') except Exception as err: logger.exception(err)
def event_toughcloud_sms_account_open(self, userinfo): """ toughCloud sms api open notify event """ if not userinfo: return if not userinfo.get('phone'): logger.error('user phone is None exit') return api_secret = self.get_param_value("toughcloud_license") api_token = yield tools.get_sys_token() params = dict(token=api_token.strip(), action='sms', tplname=self.SMS_TPLNAME, phone=userinfo.get('phone'), customer=utils.safestr(userinfo.get('realname')), username=userinfo.get('account_number'), product=utils.safestr(userinfo.get('product_name')), password=userinfo.get('password'), expire=userinfo.get('expire_date'), nonce=str(int(time.time()))) params['sign'] = apiutils.make_sign(api_secret.strip(), params.values()) try: resp = yield httpclient.fetch(self.SMS_APIURL, postdata=urlencode(params)) logger.info(resp.body) logger.info('open account send short message success') except Exception as err: logger.exception(err)
def event_toughcloud_mail_account_open(self, userinfo): """ toughCloud mail api open notify without password event """ if not userinfo: return if not userinfo.get('email'): logger.error('user email is None exit') return try: api_secret = self.get_param_value("toughcloud_license") service_mail = self.get_param_value("toughcloud_service_mail") if not service_mail: return api_token = yield tools.get_sys_token() params = dict(token=api_token.strip(), action='email', mailto=userinfo.get('email'), tplname=self.MAIL_TPLNAME, customer=utils.safestr(userinfo.get('realname')), username=userinfo.get('account_number'), product=utils.safestr(userinfo.get('product_name')), expire=userinfo.get('expire_date'), service_call=self.get_param_value( "toughcloud_service_call", ''), service_mail=service_mail, nonce=str(int(time.time()))) params['sign'] = apiutils.make_sign(api_secret.strip(), params.values()) resp = yield httpclient.fetch(self.MAIL_APIURL, postdata=urlencode(params)) logger.info(resp.body) logger.info('open account send email without password success') except Exception as err: logger.exception(err)
def parse_request(self): try: return apiutils.parse_request(self.settings.config.system.secret, self.request.body) except Exception as err: logger.error(u"api authorize parse error, %s" % utils.safeunicode(traceback.format_exc())) raise ValueError(u"Error: %s" % utils.safeunicode(err.message))
def get(self): try: ret = self.superrpc.supervisor.reloadConfig() logger.info(ret) except: logger.error(traceback.format_exc()) self.render_json(code=0, msg=u"正在重载服务配置")
def get(self): try: ret = self.superrpc.supervisor.restart() logger.info(ret) except: logger.error(traceback.format_exc()) self.render_json(code=0, msg=u"正在重启服务")
def get(self): try: name = self.get_argument("name", None) if 'worker' in name: name = 'worker:' + name ret = self.superrpc.supervisor.stopProcess(name) logger.info(ret) except: logger.error(traceback.format_exc()) self.render_json(code=0, msg=u"停止服务完成")
def process(self, *args, **kwargs): try: self.statdata.run_stat() if self.cache.get(radius_statcache_key): self.cache.update(radius_statcache_key,self.statdata) else: self.cache.set(radius_statcache_key,self.statdata) except Exception as err: logger.error('radius stat process error %s' % utils.safeunicode(err.message)) return 10.0
def process(self, *args, **kwargs): # self.logtimes() try: self.statdata.run_stat() self.cache.update(radius_statcache_key, self.statdata) if self.flow_stat: self.cache.set(flow_statcache_key, self.flow_stat) except Exception as err: logger.error('radius stat process error %s' % utils.safeunicode(err.message)) return 10.0
def init_route_permit(self): with make_db(self.db) as conn: try: oprs = conn.query(models.TrOperator) for opr in oprs: if opr.operator_type > 0: for rule in self.db.query(models.TrOperatorRule).filter_by(operator_name=opr.operator_name): permit.bind_opr(rule.operator_name, rule.rule_path) elif opr.operator_type == 0: # 超级管理员授权所有 permit.bind_super(opr.operator_name) except Exception as err: logger.error("init route error , %s" % str(err))
def init_route_permit(self): with make_db(self.db) as conn: try: oprs = conn.query(models.TlOperator) for opr in oprs: if opr.operator_type > 0: for rule in self.db.query(models.TlOperatorRule).filter_by(operator_name=opr.operator_name): permit.bind_opr(rule.operator_name, rule.rule_path) elif opr.operator_type == 0: # 超级管理员授权所有 permit.bind_super(opr.operator_name) except Exception as err: logger.error("init route error , %s" % str(err))
def process(self, *args, **kwargs): try: self.statdata.run_stat() if self.cache.get(radius_statcache_key): self.cache.update(radius_statcache_key, self.statdata) else: self.cache.set(radius_statcache_key, self.statdata) except Exception as err: logger.error('radius stat process error %s' % utils.safeunicode(err.message)) return 10.0
def processAcct(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError( '[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAcctPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)), vendor_id=vendor_id) self.do_stat(req.code, req.get_acct_status_type()) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccountingRequest: raise PacketError( 'non-AccountingRequest packet on authentication socket') if not req.VerifyAcctRequest(): raise PacketError('VerifyAcctRequest error') reply = req.CreateReply() self.pusher.push(msgpack.packb([reply.ReplyPacket(), host, port])) self.do_stat(reply.code) logger.info("[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) status_type = req.get_acct_status_type() if status_type in self.acct_class: ticket = req.get_ticket() if not ticket.get('nas_addr'): ticket['nas_addr'] = host acct_func = self.acct_class[status_type](self.db_engine, self.mcache, None, ticket).acctounting reactor.callLater(0.1, acct_func) else: logger.error('status_type <%s> not support' % status_type) except Exception as err: self.do_stat(0) errstr = 'RadiusError:Dropping invalid acct packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) logger.error(errstr) import traceback traceback.print_exc()
def process(self, *args, **kwargs): next_interval = self.get_notify_interval() try: api_url = "https://www.toughcloud.net/api/v1/ping" api_token = yield tools.get_sys_token() param_str = urlencode({'token':api_token}) resp = yield httpclient.fetch(api_url+"?"+param_str,followRedirect=True) logger.info("toughcloud ping resp code: %s"%resp.code) if resp.code == 200: self.cache.set(toughcloud_ping_key,resp.body,expire=3600) except Exception as err: logger.error(err) defer.returnValue(next_interval)
def get(self): try: logfile = self.get_argument("logfile", "/var/toughee/manage.log") self.render_json(code=0, msg=u"ok", log=self.log_query(logfile)) except: logger.error(traceback.format_exc()) self.render_json(code=1, msg=u"err", log=u"read logger error:<br><br>%s" % traceback.format_exc())
def process(self, *args, **kwargs): next_interval = self.get_notify_interval() try: api_url = "https://www.toughcloud.net/api/v1/ping" api_token = yield tools.get_sys_token() param_str = urlencode({'token': api_token}) resp = yield httpclient.fetch(api_url + "?" + param_str, followRedirect=True) logger.info("toughcloud ping resp code: %s" % resp.code) if resp.code == 200: self.cache.set(toughcloud_ping_key, resp.body, expire=3600) except Exception as err: logger.error(err) defer.returnValue(next_interval)
def billing(self, online): product = self.get_product_by_id(self.account.product_id) if not product: logger.error('product <%s> not exists' % self.account.product_id) return if product.product_policy not in (PPTimes, BOTimes, PPFlow, BOFlows): self.update_online(self.request.nas_addr, self.request.acct_session_id, billing_times=self.request.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total()) else: self.bill_funcs[product.product_policy](online, product)
def billing(self, online): product = self.get_product_by_id(self.account.product_id) if not product: logger.error('product <%s> not exists' % self.account.product_id) return if product.product_policy not in (PPTimes,BOTimes,PPFlow,BOFlows): self.update_online(self.request.nas_addr, self.request.acct_session_id, billing_times=self.request.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total()) else: self.bill_funcs[product.product_policy](online, product)
def check_sign(api_secret, msg): """ >>> check_sign("123456",dict(code=1,s='2',msg=u'中文',sign='33C9065427EECA3490C5642C99165145')) True """ if "sign" not in msg: return False sign = msg['sign'] params = [utils.safestr(msg[k]) for k in msg if k != 'sign'] local_sign = make_sign(api_secret, params) result = (sign == local_sign) if not result: logger.error("check_sign failure, sign:%s != local_sign:%s" %(sign,local_sign)) return result
def get_error_html(self, status_code=500, **kwargs): logger.error("http error : [status_code:{0}], {1}".format(status_code, utils.safestr(kwargs))) if self.settings.debug: traceback.print_exc() if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': return self.render_json(code=1, msg=u"%s:服务器处理失败,请联系管理员" % status_code) if status_code == 404: return self.render_error(msg=u"404:页面不存在") elif status_code == 403: return self.render_error(msg=u"403:非法的请求") elif status_code == 500: return self.render_error(msg=u"500:服务器处理失败,请联系管理员") else: return self.render_error(msg=u"%s:服务器处理失败,请联系管理员" % status_code)
def acctounting(self): if not self.account: dispatch.pub(UNLOCK_ONLINE_EVENT, self.request.account_number,self.request.nas_addr, self.request.acct_session_id,async=True) return logger.error( "[Acct] Received an accounting update request but user[%s] not exists"% self.request.account_number) ticket = Storage(**self.request) online = self.get_online(ticket.nas_addr,ticket.acct_session_id) if not online: sessiontime = ticket.acct_session_time updatetime = datetime.datetime.now() _starttime = updatetime - datetime.timedelta(seconds=sessiontime) online = Storage( account_number = self.account.account_number, nas_addr = ticket.nas_addr, acct_session_id = ticket.acct_session_id, acct_start_time = _starttime.strftime( "%Y-%m-%d %H:%M:%S"), framed_ipaddr = ticket.framed_ipaddr, mac_addr = ticket.mac_addr or '', nas_port_id = ticket.nas_port_id or '', billing_times = ticket.acct_session_time, input_total = self.get_input_total(), output_total = self.get_output_total(), start_source = STATUS_TYPE_UPDATE ) self.add_online(online) self.billing(online) logger.info('%s Accounting update request, update online'% self.account.account_number)
def acctounting(self): if not self.account: dispatch.pub(UNLOCK_ONLINE_EVENT, self.request.account_number, self.request.nas_addr, self.request.acct_session_id, async=True) return logger.error( "[Acct] Received an accounting update request but user[%s] not exists" % self.request.account_number) ticket = Storage(**self.request) online = self.get_online(ticket.nas_addr, ticket.acct_session_id) if not online: sessiontime = ticket.acct_session_time updatetime = datetime.datetime.now() _starttime = updatetime - datetime.timedelta(seconds=sessiontime) online = Storage( account_number=self.account.account_number, nas_addr=ticket.nas_addr, acct_session_id=ticket.acct_session_id, acct_start_time=_starttime.strftime("%Y-%m-%d %H:%M:%S"), framed_ipaddr=ticket.framed_ipaddr, mac_addr=ticket.mac_addr or '', nas_port_id=ticket.nas_port_id, billing_times=ticket.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total(), start_source=STATUS_TYPE_UPDATE) self.add_online(online) self.billing(online) logger.info('%s Accounting update request, update online' % self.account.account_number)
def acctounting(self): if not self.account: return logger.error( "[Acct] Received an accounting update request but user[%s] not exists"% self.request.account_number) ticket = Storage(**self.request) _datetime = datetime.datetime.now() online = self.get_online(ticket.nas_addr,ticket.acct_session_id) if not online: session_time = ticket.acct_session_time stop_time = _datetime.strftime( "%Y-%m-%d %H:%M:%S") start_time = (_datetime - datetime.timedelta(seconds=int(session_time))).strftime( "%Y-%m-%d %H:%M:%S") ticket.acct_start_time = start_time ticket.acct_stop_time = stop_time ticket.start_source= STATUS_TYPE_STOP ticket.stop_source = STATUS_TYPE_STOP self.add_ticket(ticket) else: self.del_online(ticket.nas_addr,ticket.acct_session_id) ticket.acct_start_time = online.acct_start_time ticket.acct_stop_time= _datetime.strftime( "%Y-%m-%d %H:%M:%S") ticket.start_source = online.start_source ticket.stop_source = STATUS_TYPE_STOP self.add_ticket(ticket) self.billing(online) logger.info('%s Accounting stop request, remove online'% self.account.account_number)
def processAcct(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAcctPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) self.do_stat(req.code, req.get_acct_status_type()) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccountingRequest: raise PacketError('non-AccountingRequest packet on authentication socket') if not req.VerifyAcctRequest(): raise PacketError('VerifyAcctRequest error') reply = req.CreateReply() self.pusher.push(msgpack.packb([reply.ReplyPacket(),host,port])) self.do_stat(reply.code) logger.info("[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) status_type = req.get_acct_status_type() if status_type in self.acct_class: ticket = req.get_ticket() if not ticket.get('nas_addr'): ticket['nas_addr'] = host acct_func = self.acct_class[status_type]( self.db_engine,self.mcache,None,ticket).acctounting reactor.callLater(0.1,acct_func) else: logger.error('status_type <%s> not support' % status_type) except Exception as err: self.do_stat(0) errstr = 'RadiusError:Dropping invalid acct packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) logger.error(errstr) import traceback traceback.print_exc()
def process(self, *args, **kwargs): self.logtimes() next_interval = self.get_notify_interval() with make_db(self.db) as db: try: _days = int(self.get_param_value("system_ticket_expire_days",30)) td = datetime.timedelta(days=_days) _now = datetime.datetime.now() edate = (_now - td).strftime("%Y-%m-%d 23:59:59") db.query(models.TrTicket).filter(models.TrTicket.acct_stop_time < edate).delete() db.commit() logger.info(u"上网数据清理完成,下次执行还需等待 %s"%(self.format_time(next_interval)) ) except: logger.error(u"上网数据清理失败,%s, 下次执行还需等待 %s"%( repr(err), self.format_time(next_interval)) ) logger.exception(err) return next_interval
def check_sign(api_secret, msg): """ >>> check_sign("123456",dict(code=1,s='2',msg=u'中文',sign='33C9065427EECA3490C5642C99165145')) True """ if "sign" not in msg: return False sign = msg['sign'] params = [ utils.safestr(msg[k]) for k in msg if k != 'sign' and msg[k] is not None ] local_sign = make_sign(api_secret, params) result = (sign == local_sign) if not result: logger.error("check_sign failure, sign:%s != local_sign:%s" % (sign, local_sign)) return result
def process(self, *args, **kwargs): self.logtimes() with make_db(self.db) as db: try: dstr = "%s 00:00:00" % datetime.datetime.now().strftime("%Y-%m-%d") startstat = datetime.datetime.strptime(dstr, "%Y-%m-%d %H:%M:%S") online_count = db.query(models.TrOnline.id).count() olstat = self.cache.get(online_statcache_key) or [] for ol in olstat: stat_time = datetime.datetime.fromtimestamp(ol[0]/1000.0) if stat_time < startstat: olstat.remove(ol) olstat.append( (int(time.time()*1000),online_count) ) self.cache.update(online_statcache_key,olstat) logger.info("online stat task done") except Exception as err: logger.error('online_stat_job err,%s'%(str(err))) return 120.0
def load_handlers(handler_path=None, pkg_prefix=None, excludes=[]): _excludes = ["__init__", "base", ".svn", ".DS_Store", "views"] + excludes hds = set(os.path.splitext(it)[0] for it in os.listdir(handler_path)) hds = [it for it in hds if it not in _excludes] for hd in hds: try: sub_module = os.path.join(handler_path, hd) if os.path.isdir(sub_module): # logger.info('load sub module %s' % hd) load_handlers(handler_path=sub_module, pkg_prefix="{0}.{1}".format(pkg_prefix, hd), excludes=excludes) _hd = "{0}.{1}".format(pkg_prefix, hd) # logger.info('load_module %s' % _hd) importlib.import_module(_hd) except Exception as err: logger.error("%s, skip module %s.%s" % (str(err), pkg_prefix, hd)) import traceback traceback.print_exc() continue
def get(self): try: name = self.get_argument("name", None) if 'worker' in name: name = 'worker:' + name ret = self.superrpc.system.multicall([ { 'methodName': 'supervisor.stopProcess', 'params': [name] }, { 'methodName': 'supervisor.startProcess', 'params': [name] }, ]) logger.info(ret) except: logger.error(traceback.format_exc()) self.render_json(code=0, msg=u"重启服务完成")
def load_handlers(handler_path=None, pkg_prefix=None, excludes=[]): _excludes = ['__init__', 'base', '.svn', '.DS_Store', 'views'] + excludes hds = set(os.path.splitext(it)[0] for it in os.listdir(handler_path)) hds = [it for it in hds if it not in _excludes] for hd in hds: try: sub_module = os.path.join(handler_path, hd) if os.path.isdir(sub_module): # logger.info('load sub module %s' % hd) load_handlers(handler_path=sub_module, pkg_prefix="{0}.{1}".format(pkg_prefix, hd), excludes=excludes) _hd = "{0}.{1}".format(pkg_prefix, hd) # logger.info('load_module %s' % _hd) importlib.import_module(_hd) except Exception as err: logger.error("%s, skip module %s.%s" % (str(err), pkg_prefix, hd)) import traceback traceback.print_exc() continue
def acctounting(self): if self.is_online(self.request.nas_addr,self.request.acct_session_id): return logger.error('online %s is exists' % self.request.acct_session_id) if not self.account: return logger.error('user %s not exists' % self.request.account_number) online = Storage( account_number = self.request.account_number, nas_addr = self.request.nas_addr, acct_session_id = self.request.acct_session_id, acct_start_time = datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"), framed_ipaddr = self.request.framed_ipaddr, mac_addr = self.request.mac_addr or '', nas_port_id = self.request.nas_port_id, billing_times = 0, input_total = 0, output_total = 0, start_source = STATUS_TYPE_START ) self.add_online(online) logger.info('%s Accounting start request, add new online'%online.account_number)
def process(self, *args, **kwargs): with make_db(self.db) as db: try: onlines = db.query(models.TrOnline) for online in onlines: acct_start_time = datetime.datetime.strptime(online.acct_start_time, '%Y-%m-%d %H:%M:%S') nowdate = datetime.datetime.now() dt = nowdate - acct_start_time online_times = dt.total_seconds() max_session_time = int(self.get_param_value('radius_max_session_timeout',86400)) if online_times > (max_session_time): logger.info("online %s overtime, system auto disconnect this online"%online.account_number) dispatch.pub(UNLOCK_ONLINE_EVENT, online.account_number, online.nas_addr, online.acct_session_id,async=True) logger.info("online overtime check task done") except Exception as err: db.rollback() logger.error('online overtime check job err,%s'%(str(err))) return 3600.0
def process(self, *args, **kwargs): self.logtimes() next_interval = self.get_notify_interval() try: logger.info("start process expire notify task") _ndays = self.get_param_value("expire_notify_days") _now = datetime.datetime.now() _date = (datetime.datetime.now() + datetime.timedelta( days=int(_ndays))).strftime("%Y-%m-%d") with make_db(self.db) as db: expire_query = db.query( models.TrCustomer.mobile, models.TrCustomer.realname, models.TrProduct.product_name, models.TrAccount.account_number, models.TrAccount.install_address, models.TrAccount.expire_date, models.TrAccount.password ).filter( models.TrCustomer.customer_id == models.TrAccount.customer_id, models.TrAccount.product_id == models.TrProduct.id, models.TrAccount.expire_date <= _date, models.TrAccount.expire_date >= _now.strftime("%Y-%m-%d"), models.TrAccount.status == 1 ) for userinfo in expire_query: self.trigger_notify(userinfo) logger.info(u"到期通知任务已执行(%s个已通知)。下次执行还需等待 %s"% ( expire_query.count(),self.format_time(next_interval)) ) except Exception as err: logger.error(u"到期通知任务执行失败,%s。下次执行还需等待 %s"%( repr(err),self.format_time(next_interval))) return next_interval
def process(self, *args, **kwargs): with make_db(self.db) as db: try: nas_list = db.query(models.TrBas) for nas in nas_list: if not nas.dns_name: continue results, _, _ = yield client.lookupAddress(nas.dns_name) if not results: logger.info("domain {0} resolver empty".format(nas.dns_name)) if results[0].type == dns.A: ipaddr = ".".join(str(i) for i in struct.unpack("BBBB", results[0].payload.address)) if ipaddr: nas.ip_addr = ipaddr db.commit() logger.info("domain {0} resolver {1} success".format(nas.dns_name,ipaddr)) else: logger.info("domain {0} no ip address,{1}".format(nas.dns_name, repr(results))) except Exception as err: logger.error('ddns process error %s' % utils.safeunicode(err.message)) defer.returnValue(60)
ac_addr = nas['ip_addr'] ac_port = int(nas['ac_port']) secret = utils.safestr(nas['bas_secret']) _vendor= utils.safestr(nas['portal_vendor']) if _vendor not in ('cmccv1','cmccv2','huaweiv1','huaweiv2'): self.render_error(msg=u"AC server portal_vendor {0} not support ".format(_vendor)) return vendor = client.PortalClient.vendors.get(_vendor) req = vendor.proto( secret=secret, packet=datagram, source=(host, port) ) logger.info("Received portal packet from %s:%s: %s"%(host,port,utils.safestr(req))) if req.type in self.actions: self.actions[req.type](req, vendor, secret, (host, port)) else: logger.error('Not support packet from ac host ' + host) except Exception as err: logger.error('Dropping invalid packet from %s: %s' % ((host, port), utils.safestr(err))) def run(config, dbengine=None, log=None): app = PortalListen(config, dbengine=dbengine, log=log) reactor.listenUDP(int(config.portal.listen), app,interface=config.portal.host)
def processAuth(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAuthPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) self.do_stat(req.code) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccessRequest: raise PacketError('non-AccessRequest packet on authentication socket') reply = req.CreateReply() reply.vendor_id = req.vendor_id aaa_request = dict( account_number=req.get_user_name(), domain=req.get_domain(), macaddr=req.client_mac, nasaddr=req.get_nas_addr(), vlanid1=req.vlanid1, vlanid2=req.vlanid2 ) auth_resp = RadiusAuth(self.db_engine,self.mcache,self.aes,aaa_request).authorize() if auth_resp['code'] > 0: reply['Reply-Message'] = auth_resp['msg'] reply.code = packet.AccessReject return reply if 'bypass' in auth_resp and int(auth_resp['bypass']) == 0: is_pwd_ok = True else: is_pwd_ok = req.is_valid_pwd(auth_resp.get('passwd')) if not is_pwd_ok: reply['Reply-Message'] = "password not match" reply.code = packet.AccessReject return reply else: if u"input_rate" in auth_resp and u"output_rate" in auth_resp: reply = rate_process.process( reply, input_rate=auth_resp['input_rate'], output_rate=auth_resp['output_rate']) attrs = auth_resp.get("attrs") or {} for attr_name in attrs: try: # todo: May have a type matching problem reply.AddAttribute(utils.safestr(attr_name), attrs[attr_name]) except Exception as err: errstr = "RadiusError:current radius cannot support attribute {0},{1}".format( attr_name,utils.safestr(err.message)) logger.error(errstr) for attr, attr_val in req.resp_attrs.iteritems(): reply[attr] = attr_val reply['Reply-Message'] = 'success!' reply.code = packet.AccessAccept if not req.VerifyReply(reply): raise PacketError('VerifyReply error') return reply except Exception as err: self.do_stat(0) errstr = 'RadiusError:Dropping invalid auth packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) logger.error(errstr) import traceback traceback.print_exc()