📄 gateas.cc
字号:
/*************************************************************************\* Copyright (c) 2002 The University of Chicago, as Operator of Argonne* National Laboratory.* Copyright (c) 2002 Berliner Speicherring-Gesellschaft fuer Synchrotron-* Strahlung mbH (BESSY).* Copyright (c) 2002 The Regents of the University of California, as* Operator of Los Alamos National Laboratory.* This file is distributed subject to a Software License Agreement found* in the file LICENSE that is included with this distribution. \*************************************************************************//*+********************************************************************* * * File: gateAs.cc * Project: CA Proxy Gateway * * Descr.: Access Security part - handles all Gateway configuration: * - Reads PV list file * - Reads Access Security file * * Author(s): J. Kowalkowski, J. Anderson, K. Evans (APS) * R. Lange (BESSY) * *********************************************************************-*/#define DEBUG_DELAY 0#define DEBUG_AS 0#define DEBUG_ACCESS 0#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#ifdef WIN32# define strcasecmp stricmp# include <string.h>#else# include <unistd.h># include <string.h>#endif#include "tsSLList.h"#include <epicsVersion.h>#include "gateAs.h"#include "gateResources.h"void gateAsCa(void);void gateAsCaClear(void);const char* gateAs::default_group = "DEFAULT";const char* gateAs::default_pattern = "*";unsigned char gateAs::eval_order = GATE_ALLOW_FIRST;aitBool gateAs::rules_installed = aitFalse;aitBool gateAs::use_default_rules = aitFalse;FILE* gateAs::rules_fd = NULL;// extern "C" wrappers needed for callbacksextern "C" { static void clientCallback(ASCLIENTPVT p, asClientStatus s) { gateAsClient::clientCallback(p, s); } static int readFunc(char* buf, int max_size) { return gateAs::readFunc(buf, max_size); }}// pattern PV name pattern (regex)// realname Real name substitution pattern// asg ASG// asl ASLgateAsEntry::gateAsEntry(const char* pattern, const char* realname, const char* asg, int asl) : pattern(pattern), alias(realname), group(asg), level(asl), asmemberpvt(NULL){ // Set pointers in the pattern buffer pat_buff.buffer=NULL; pat_buff.translate=NULL; pat_buff.fastmap=NULL; // Initialize registers re_set_registers(&pat_buff,®s,0,0,0);}gateAsEntry::~gateAsEntry(void){ // Free allocated stuff in the pattern buffer regfree(&pat_buff); // Free allocted stuff in registers if(regs.start) free(regs.start); if(regs.end) free(regs.end); regs.num_regs=0;}long gateAsEntry::removeMember(void){ long rc=0; if(asmemberpvt) { rc=asRemoveMember(&asmemberpvt); if(rc == S_asLib_clientsExist) { printf("Cannot remove member because client exists for:\n"); printf(" %-30s %-16s %d ",pattern,group,level); } asmemberpvt=NULL; } return rc;}void gateAsEntry::getRealName(const char* pv, char* rname, int len){ char c; int in, ir, j, n; if (alias) { // Build real name from substitution pattern ir = 0; for (in=0; ir<len; in++) { if ((c = alias[in]) == '\\') { c = alias[++in]; if(c >= '0' && c <= '9') { n = c - '0'; if(regs.start[n] >= 0) { for(j=regs.start[n]; ir<len && j<regs.end[n]; j++) rname[ir++] = pv[j]; if(ir==len) { rname[ir-1] = '\0'; break; } } continue; } } rname[ir++] = c; if(c) continue; else break; } if(ir==len) rname[ir-1] = '\0'; gateDebug4(6,"gateAsEntry::getRealName() PV %s matches %s -> alias %s" " yields real name %s\n", pv, pattern, alias, rname); } else { // Not an alias: PV name _is_ real name strncpy(rname, pv, len); } return;}aitBool gateAsEntry::init(gateAsList& n, int line) { if (compilePattern(line)==aitFalse) return aitFalse; n.add(*this); if (group == NULL || asAddMember(&asmemberpvt,(char*)group) != 0) { asmemberpvt = NULL; } else { asPutMemberPvt(asmemberpvt,this); } return aitTrue;} #ifdef USE_DENYFROMaitBool gateAsEntry::init(const char* host, // Host name to deny tsHash<gateAsList>& h, // Where this entry is added to gateHostList& hl, // Where a new key should be added int line) { // Line number gateAsList* l; if(compilePattern(line)==aitFalse) return aitFalse; if(h.find(host,l)==0) { l->add(*this); } else { l = new gateAsList; l->add(*this); h.add(host,*l); hl.add(*(new gateAsHost(host))); } return aitTrue;}#endifaitBool gateAsEntry::compilePattern(int line) { const char *err; pat_buff.translate=0; pat_buff.fastmap=0; pat_buff.allocated=0; pat_buff.buffer=0; if((err = re_compile_pattern(pattern, strlen(pattern), &pat_buff))) { fprintf(stderr,"Line %d: Error in regexp %s : %s\n", line, pattern, err); return aitFalse; } return aitTrue;}gateAsClient::gateAsClient(void) : asclientpvt(NULL), asentry(NULL), user_arg(NULL), user_func(NULL){}gateAsClient::gateAsClient(gateAsEntry *pEntry, const char *user, const char *host) : asclientpvt(NULL), asentry(pEntry), user_arg(NULL), user_func(NULL){ if(pEntry&&asAddClient(&asclientpvt,pEntry->asmemberpvt,pEntry->level, (char*)user,(char*)host) == 0) { asPutClientPvt(asclientpvt,this); }#if DEBUG_DELAY gateAsClient *v=this; printf("%s gateAsClient::gateAsClient pattern=%s user_func=%d\n", timeStamp(), v->asentry?(v->asentry->pattern?v->asentry->pattern:"[NULL pattern]"):"[NULL entry]", v->user_func);#endif // Callback is called if rights are changed by rereading the // access file, etc. Callback will be called once right now, but // won't do anything since the user_func is NULL. The user_func // is set in gateChan::gateChan. asRegisterClientCallback(asclientpvt,::clientCallback);#if DEBUG_DELAY printf("%s gateAsClient::gateAsClient finished\n", timeStamp());#endif}gateAsClient::~gateAsClient(void){ // client callback if(asclientpvt) asRemoveClient(&asclientpvt); asclientpvt=NULL;}void gateAsClient::clientCallback(ASCLIENTPVT p, asClientStatus /*s*/){ gateAsClient* pClient = (gateAsClient*)asGetClientPvt(p);#if DEBUG_DELAY printf("%s gateAsClient::clientCallback pattern=%s user_func=%d\n", timeStamp(), pClient->asentry?(pClient->asentry->pattern? pClient->asentry->pattern:"[NULL pattern]"):"[NULL entry]", pClient->user_func);#endif if(pClient->user_func) pClient->user_func(pClient->user_arg);}gateAs::gateAs(const char* lfile, const char* afile)#ifdef USE_DENYFROM : denyFromListUsed(false)#endif{ // These are static only so they can be used in readFunc. Be // careful about having two instances of this class as when // rereading access security. These variables will be valid for // the last instance only. default_group = "DEFAULT"; default_pattern = "*"; eval_order = GATE_ALLOW_FIRST; rules_installed = aitFalse; use_default_rules = aitFalse; rules_fd = NULL; if(afile) { if(initialize(afile)) fprintf(stderr,"Failed to install access security file %s\n",afile); } readPvList(lfile);}gateAs::~gateAs(void){#ifdef USE_DENYFROM// Probably OK but not checked for reinitializing all of access// security including the pvlist.# error DENY FROM implementation should be checked here tsSLIter<gateAsHost> pi = host_list.firstIter(); gateAsList* l; gateAsHost *pNode; while(pi.pointer()) { pNode=pi.pointer(); deny_from_table.remove(pNode->host,l); deleteAsList(*l); }#endif clearAsList(deny_list); clearAsList(allow_list); clearAsList(line_list);}// Remove the items from the list and delete themvoid gateAs::clearAsList(gateAsList& list){ while(list.first()) { gateAsEntry *pe=list.get(); if(pe) { // Remove the member from access security pe->removeMember(); delete pe; } }}// Remove the items from the list and delete themvoid gateAs::clearAsList(gateLineList& list){ while(list.first()) { gateAsLine *pl=list.get(); if(pl) delete pl; }}gateAsEntry* gateAs::findEntryInList(const char* pv, gateAsList& list) const{ tsSLIter<gateAsEntry> pi = list.firstIter(); while(pi.pointer()) { if(re_match(&pi->pat_buff,pv,strlen(pv),0,&pi->regs) == (int)strlen(pv)) break; pi++; } return pi.pointer();}int gateAs::readPvList(const char* lfile){ int lev; int line=0; FILE* fd; char inbuf[GATE_MAX_PVLIST_LINE_LENGTH]; const char *pattern,*rname,*hname; char *cmd,*asg,*asl,*ptr; gateAsEntry* pe; gateAsLine* pl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -