#pragma module SIP_CONF "SIP_CONF-1-C" #define __MODULE__ "SIP_CONF" /* **++ ** FACILITY: SIP Server for OpenVMS ** ** MODULE DESCRIPTION: ** ** This module contains routines to process & load SIP configuration. ** ** AUTHORS: Ruslan R. Laishev ** ** ** CREATION DATE: 27-APR-2009 ** ** ** MODIFICATION HISTORY: ** ** 24-FEB-2010 RRL Added PATH verb. ** 16-MAR-2010 RRL Added ENABLE /INTRUSION=(DETECTION,PREVENTION) ** **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "regex.h" #define __NEW_STARLET 1 #include "sipdef.h" #include "sip_msg.h" #include "macros.h" extern SIP_CONF conf; struct FAB fab; struct RAB rab; $DESCRIPTOR (dsc_wild, "%*"); /* ** CLI STUFF */ extern void *SIP_CONF_CLD; $DESCRIPTOR(p_p1, "P1"); $DESCRIPTOR(p_p2, "P2"); $DESCRIPTOR(q_domain, "DOMAIN"); $DESCRIPTOR(q_proxy, "PROXY"); $DESCRIPTOR(q_bot, "BOT"); $DESCRIPTOR(q_pass, "PASS"); $DESCRIPTOR(q_regex, "REGEX"); $DESCRIPTOR(q_ids, "INTRUSION.DETECTION"); $DESCRIPTOR(q_ips, "INTRUSION.PREVENTION"); $DESCRIPTOR(q_raddb, "AUTH.RADDB"); $DESCRIPTOR(q_radius, "AUTH.RADIUS"); $DESCRIPTOR(q_acpt, "AUTH.ACCEPT"); $DESCRIPTOR(q_rjct, "AUTH.REJECT"); int lineno = 0; static int __sip_conf_open (void) { int status; char SIP_CONFIG [] = "SIP_CONFIG"; fab = cc$rms_fab; fab.fab$b_fac = FAB$M_GET; fab.fab$b_shr = FAB$M_SHRGET; fab.fab$l_fna = SIP_CONFIG; fab.fab$b_fns = sizeof(SIP_CONFIG) -1; fab.fab$l_dna = ".CONF"; fab.fab$b_dns = 4; rab = cc$rms_rab; rab.rab$l_fab = &fab; if ( (1 & (status = sys$open(&fab))) ) status = sys$connect(&rab); return status; } static int __sip_conf_close (void) { return sys$close(&fab); } static int __sip_conf_get ( struct dsc$descriptor *outs, struct dsc$descriptor *pmts, unsigned short *len ) { int status; char buf [ 1024 ]; /* ** Some setup of variables */ *len = 0; lineno++; rab.rab$w_usz = sizeof(buf); rab.rab$l_ubf = buf; if ( RMS$_EOF == (status = sys$get(&rab)) ) return status; else if ( !( 1 & status) ) lib$signal(status,rab.rab$l_stv); *len = rab.rab$w_rsz; return str$copy_r (outs,len,&buf); } int _sip_conf_path (void) { int status,sz = 0; char buf [ 128 ],*cp; struct dsc$descriptor junk; SIP_PATH *path,*pathp; struct sockaddr_in *dst; struct hostent *hp; /* ** P1 - Path pattern */ INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&p_p1,&junk,&sz))) || !(1 & (status = _sip_getvm(&path,sizeof(SIP_PATH)))) ) return status; if ( *junk.dsc$a_pointer == '\"' ) { sz -= 2; junk.dsc$a_pointer++; } memcpy(path->path_r_path.asc_t_asc,junk.dsc$a_pointer, path->path_r_path.asc_b_asc = sz); /* ** /REGEX or /DOMAIN or /BOTH ? */ path->path_v_regex = (CLI$_PRESENT == cli$present(&q_regex)); path->path_v_domain = (CLI$_PRESENT == cli$present(&q_domain)); path->path_v_bot = (CLI$_PRESENT == cli$present(&q_bot)); if ( path->path_v_regex ) { if ( cp = re_compile_pattern(junk.dsc$a_pointer,sz,&path->path_b_regex) ) return _sip_log(SIP_ERRRE,sz,junk.dsc$a_pointer,cp); } else path->path_v_wild = (0 != str$find_first_in_set(&junk,&dsc_wild)); /* ** P2 - IP name/address, OpenVMS mailbox name, etc... */ INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&p_p2,&junk,&sz))) ) return status; if ( *junk.dsc$a_pointer == '\"' ) { sz -= 2; junk.dsc$a_pointer++; } memcpy(path->path_r_via.asc_t_asc,junk.dsc$a_pointer, path->path_r_via.asc_b_asc = sz); if ( !path->path_v_bot ) { buf[sz] = '\0'; dst = (struct sockaddr_in *)&path->path_q_dst; if ( -1 != (status = inet_addr(buf)) ) dst->sin_addr.s_addr = inet_addr(buf); else if ( hp = gethostbyname(buf) ) dst->sin_addr.s_addr = *(int *)hp->h_addr; else return SS$_NOSUCHNODE; dst->sin_port = htons(SIP$PORT_SIP); } /* ** Add path to path-list */ if ( !conf.conf_a_path ) conf.conf_a_path = path; else { for ( pathp = conf.conf_a_path; pathp->path_a_next; pathp = pathp->path_a_next); pathp->path_a_next = path; } return _sip_log(SIP_ADDPATH,&path->path_r_path,sz,buf); } int _sip_conf_ena (void) { conf.conf_v_ips= (CLI$_PRESENT == cli$present(&q_ips)); conf.conf_v_ids= (CLI$_PRESENT == cli$present(&q_ids)); return SS$_NORMAL; } int _sip_conf_realm (void) { int status,sz = 0; char buf [ 512 ]; struct dsc$descriptor junk; SIP_REALM *realm; struct sockaddr_in *dst; struct hostent *hp; /* ** Realm name */ INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&p_p1,&junk,&sz))) || !(1 & (status = _sip_getvm(&realm,sizeof(SIP_REALM)))) ) return status; if ( *junk.dsc$a_pointer == '\"' ) { sz -= 2; junk.dsc$a_pointer++; } realm->realm_r_realm.asc_b_asc = sz; memcpy(realm->realm_r_realm.asc_t_asc,junk.dsc$a_pointer, realm->realm_r_realm.asc_b_asc); realm->realm_a_next = conf.conf_a_realm; conf.conf_a_realm = realm; /* ** /PASS */ realm->realm_v_pass = (CLI$_PRESENT == cli$present(&q_pass)); /* ** /FORWARD=DOMAIN */ if ( !(realm->realm_v_domain = (CLI$_PRESENT == cli$present(&q_domain))) ) { /* ** /FORWARD=PROXY */ INIT_SDESC(junk,sizeof(buf),buf); if ( CLI$_PRESENT == (status = cli$present (&q_proxy)) ) { if ( !(1 & (status = cli$get_value(&q_proxy,&junk,&sz))) ) return status; } else return SS$_NORMAL; realm->realm_v_proxy = 1; } buf[sz] = '\0'; dst = (struct sockaddr_in *)&realm->realm_q_dst; if ( -1 != (status = inet_addr(buf)) ) dst->sin_addr.s_addr = inet_addr(buf); else if ( hp = gethostbyname(buf) ) dst->sin_addr.s_addr = *(int *)hp->h_addr; dst->sin_port = htons(SIP$PORT_SIP); return SS$_NORMAL; } int _sip_conf_host (void) { int status,sz = 0; char buf [ 512 ]; struct dsc$descriptor junk; /* ** Realm name */ INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&p_p1,&junk,&sz))) ) return status; if ( *junk.dsc$a_pointer == '\"' ) { sz -= 2; junk.dsc$a_pointer++; } memcpy(conf.conf_r_host.asc_t_asc,junk.dsc$a_pointer, conf.conf_r_host.asc_b_asc = sz); return SS$_NORMAL; } int _sip_conf (void) { int status; if ( !(1 & (status = __sip_conf_open())) ) { _sip_log(SIP_ERRCONF,lineno,status); return status; } /* ** Processing configuration file */ while ( RMS$_EOF != (status = cli$dcl_parse (0,&SIP_CONF_CLD,__sip_conf_get,__sip_conf_get,0)) ) { if ( status != CLI$_NORMAL ) continue; /* ** Call a dispatcher routine to process configuration line */ if (! (1 & (status = cli$dispatch())) && $VMS_STATUS_SEVERITY(status) > STS$K_ERROR ) _sip_log(SIP_ERRCONF,lineno,status); } /* ** Close file, and return status */ __sip_conf_close(); return (status == RMS$_EOF?SS$_NORMAL:status); }