home *** CD-ROM | disk | FTP | other *** search
- /*
- ** SECURITY
- **
- ** HTTP Wrapper for the Security Management Routines
- **
- ** Confidential Property of Tod Sambar
- ** (c) Copyright Tod Sambar 1996-1997
- ** All rights reserved.
- **
- **
- ** Public Functions:
- **
- ** security_init
- ** security_exit
- ** security_request
- ** security_connect
- ** security_filter
- **
- ** Note:
- ** By default, all objects placed in the sysadmin folder (under docs)
- ** are required to have system administrator access. All other
- ** security features are implemented through external event handlers.
- **
- ** History:
- ** Chg# Date Description Resp
- ** ---- ------- ------------------------------------------------------- ----
- ** 4FEB97 Created sambar
- ** 23APR97 Added network connect security sambar
- ** 09APR97 Added AD/site security filtering sambar
- ** 07JUL97 Added multiple users/groups on the security line sambar
- ** 13SEP98 Modified to send filtered.htm file on proxy denial sambar
- ** 31DEC98 Added Mail security filtering sambar
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <string.h>
- #include <ctype.h>
- #include <security.h>
-
- #ifndef WIN32
- #define stricmp strcasecmp
- #define strnicmp strncasecmp
- extern int strcasecmp(const char *, const char *);
- extern int strncasecmp(const char *, const char *, int);
- extern char *strdup(const char *);
- #endif /* WIN32 */
-
- /*
- ** Local Functions
- */
- SA_RETCODE security__load(SA_CTX *ctx, SA_VOID *argp,
- SA_CHAR *name, SA_CHAR *value);
-
- /*
- ** Show-security RPC parameters
- */
- static SA_RPCPARAM showsecp [] =
- {
- { "type", 1, "Security filter to show." }
- };
-
- /*
- ** Local Structures
- */
- typedef struct security__entry
- {
- SA_INT id;
- SA_CHAR *symbol;
- SA_CHAR *descr;
-
- } SECURITY_ENTRY;
-
- /*
- ** Local Defines
- */
- #define DENIED_HEADER "HTTP/1.0 404 Request denied.\nContent-type: text/html\n\n"
-
- static SECURITY_ENTRY Security_entries[] =
- {
- { SECURITY_REDIRECT, "redirect",
- "URI to Redirect / URL to Redirect to" },
- { SECURITY_RESTRICT, "restrict",
- "URI to Restrict / User or Group granted access" },
- { SECURITY_DENY, "deny",
- "IP to deny access to / URL to redirect offending hosts to" },
- { SECURITY_HTTPACCEPT, "httpaccept",
- "IP addresses to accept HTTP hosts from" },
- { SECURITY_HTTPDENY, "httpdeny",
- "IP addresses of hosts to deny HTTP access to" },
- { SECURITY_FTPACCEPT, "ftpaccept",
- "IP addresses to accept FTP hosts from" },
- { SECURITY_FTPDENY, "ftpdeny",
- "IP addresses of hosts to deny FTP access to" },
- { SECURITY_PROXYACCEPT, "proxyaccept",
- "IP addresses to accept Proxy hosts from" },
- { SECURITY_PROXYDENY, "proxydeny",
- "IP addresses of hosts to deny Proxy access to" },
- { SECURITY_HOSTFILTER, "hostfilter",
- "Hosts to restrict proxy requests from (AD/Content filtering)" },
- { SECURITY_URLFILTER, "urlfilter",
- "URLs to restrict proxy requests from (AD/Content filtering)" },
- { SECURITY_IPRESTRICT, "iprestrict",
- "URI to Restrict / IP Address(s) to grant access" },
- { SECURITY_HOSTRESTRICT, "hostrestrict",
- "Hosts to restrict proxy requests to (WWW kiosks)" },
- { SECURITY_URLRESTRICT, "urlrestrict",
- "URLs to restrict proxy requests to (WWW kiosks)" },
- { SECURITY_MAILACCEPT, "mailaccept",
- "IP addresses to accept Mail (SMTP/POP3/IMAP4) hosts from" },
- { SECURITY_MAILDENY, "maildeny",
- "IP addresses of hosts to deny Mail (SMTP/POP3/IMAP4) access to" },
- { SECURITY_DNSACCEPT, "dnsaccept",
- "IP addresses to accept DNS requests from" },
- { SECURITY_DNSDENY, "dnsdeny",
- "IP addresses of hosts to deny DNS access to" },
- { SECURITY_SIPACCEPT, "sipaccept",
- "IP addresses to accept SIP requests from" },
- { SECURITY_SIPDENY, "sipdeny",
- "IP addresses of hosts to deny SIP access to" },
- { SECURITY_HOSTREDIRECT, "hostredirect",
- "Hosts to redirect requests to (vhost management)" },
- { SECURITY_SITEREDIRECT, "siteredirect",
- "Hosts to redirect requests to; original URL is appended" },
- { SECURITY_TFTPACCEPT, "tftpaccept",
- "IP addresses to accept TFTP requests from" },
- { SECURITY_TFTPDENY, "tftpdeny",
- "IP addresses of hosts to deny TFTP access to" },
- };
-
- #define NUM_ENTRIES sizeof(Security_entries) / sizeof(SECURITY_ENTRY)
- static SECURITY *Entries[NUM_ENTRIES];
- static SECURITY *TmpEntries[NUM_ENTRIES];
-
-
-
- /*
- ** SECURITY_INIT
- **
- ** Initialize the Security Rules for use by the Sambar Server plugins.
- ** Rules are only loaded at application initialization time and (as this
- ** is a threaded application) cannot be modified without a restart of
- ** the server (or mutexing).
- **
- **
- ** Parameters:
- ** sactx Sambar Server context
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_init(sactx)
- SA_CTX *sactx;
- {
- SA_INT i;
- SA_CHAR buffer[256];
-
- /*
- ** Load the security rules from the security.ini file
- */
- for (i = 0; i < NUM_ENTRIES; i++)
- {
- TmpEntries[i] = (SECURITY *)NULL;
-
- if (sa_props_load(sactx, "security.ini",
- Security_entries[i].symbol, &Security_entries[i].id,
- (SA_PROPFUNC)security__load) != SA_SUCCEED)
- {
- sprintf(buffer, "Failure loading [%s] security section.",
- Security_entries[i].symbol);
- sa_log2(sactx, SA_LOG_ERROR, buffer);
- }
-
- Entries[i] = TmpEntries[i];
- }
-
- /* Initialize the "showsec" RPC */
- if (sa_cmd_init(sactx, "showsec",
- showsecp, sizeof(showsecp) / sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ADMIN, "Security rule display.",
- (SA_VOID *)security_showsec) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_ERROR, "Unable to initialize Security RPCs");
- return (SA_FAIL);
- }
-
- if (sa_cmd_init(sactx, "reloadsec", (SA_RPCPARAM *)NULL, 0,
- SA_AUTHORIZATION_ADMIN, "Reload security rules.",
- (SA_VOID *)security_reload) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_ERROR, "Unable to initialize Security RPCs");
- return (SA_FAIL);
- }
-
- sa_log2(sactx, SA_LOG_TRACE, "Security Interfaces Initialized");
-
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY_EXIT
- **
- ** Free the Security Rules.
- **
- ** Parameters:
- ** sactx Sambar Server context
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_exit(sactx)
- SA_CTX *sactx;
- {
- SA_INT i;
- SECURITY *snext;
- SECURITY *security;
- ENTRY *enext;
- ENTRY *entry;
-
- /*
- ** Free the security rules previously loaded from the security.ini file
- */
- for (i = 0; i < NUM_ENTRIES; i++)
- {
- security = Entries[i];
- while (security != (SECURITY *)NULL)
- {
- snext = security->next;
- free(security->name);
-
- entry = security->entries;
- while (entry != (ENTRY *)NULL)
- {
- enext = entry->next;
- free(entry->value);
- free(entry);
- entry = enext;
- }
-
- free(security);
- security = snext;
- }
- }
-
- sa_log2(sactx, SA_LOG_TRACE, "Security Interfaces Exited");
-
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY_REQUEST
- **
- ** Determine if the request should be fulfilled.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Client connection handle.
- ** uri The URI associated with the request.
- ** urilen The length of the URI string.
- ** params The parameters associated with the request.
- ** infop The error status returned on failure.
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_request(sactx, saconn, uri, urilen, params, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_CHAR *uri;
- SA_INT urilen;
- SA_PARAMS *params;
- SA_INT *infop;
- {
- SA_INT pwdlen;
- SA_INT namelen;
- SA_BOOL ntauth;
- SA_BOOL sqlauth;
- SA_BOOL radiusauth;
- SA_BOOL found;
- SA_BOOL status;
- ENTRY *entry;
- SECURITY *security;
- SA_CHAR name[512];
- SA_CHAR pwd[60];
- SA_CHAR tmp[1024];
- SA_PASSWD passwd;
-
- ntauth = 0;
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_NTAUTH, tmp, 30,
- (SA_INT *)NULL) == SA_SUCCEED)
- {
- if (stricmp(tmp, "true") == 0)
- ntauth = 1;
- }
-
- radiusauth = 0;
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_RADIUSAUTH, tmp, 30,
- (SA_INT *)NULL) == SA_SUCCEED)
- {
- if (stricmp(tmp, "true") == 0)
- radiusauth = 1;
- }
-
- sqlauth = 0;
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SQLAUTH, tmp, 30,
- (SA_INT *)NULL) == SA_SUCCEED)
- {
- if (stricmp(tmp, "true") == 0)
- sqlauth = 1;
- }
-
- /*
- ** REDIRECT
- */
- security = Entries[SECURITY_REDIRECT];
- while (security != (SECURITY *)NULL)
- {
- if ((urilen >= security->namelen) &&
- (strnicmp(uri, security->name, security->namelen) == 0))
- {
- *infop = SA_E_REDIRECT;
- entry = security->entries;
- (SA_VOID)sa_conn_redirect(saconn, entry->value,
- "Request redirected.", SA_NULLTERM);
- return (SA_FAIL);
- }
-
- security = security->next;
- }
-
- /*
- ** RESTRICT
- */
- security = Entries[SECURITY_RESTRICT];
- while (security != (SECURITY *)NULL)
- {
- if ((urilen >= security->namelen) &&
- (strnicmp(uri, security->name, security->namelen) == 0))
- {
- if (sa_conn_props(saconn, SA_GET, SA_CONNPROP_NAME, name, 60,
- &namelen) != SA_SUCCEED)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
-
- /* Get the password and verify the match */
- if (sa_conn_props(saconn, SA_GET, SA_CONNPROP_PASSWORD, pwd, 60,
- &pwdlen) != SA_SUCCEED)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
-
- /*
- ** Now lookup the name/password in the passwd file or
- ** NT Domain or Radius Server (depending on configuration).
- */
- if ((ntauth) || (radiusauth))
- {
- if (sa_passwd_verify(sactx, name, namelen, pwd, pwdlen, &status)
- != SA_SUCCEED)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
-
- if (!status)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
- }
- else if (sqlauth)
- {
- if (sa_passwd_sqlauth(sactx, saconn, name, namelen, pwd, pwdlen,
- &passwd) != SA_SUCCEED)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
- }
- else
- {
- if (sa_passwd_lookup(sactx, name, namelen, &passwd)
- != SA_SUCCEED)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
-
- if (pwdlen != passwd.passwordlen)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
-
- if ((pwdlen > 0) &&
- (memcmp(passwd.password, pwd, pwdlen) != 0))
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
- }
-
- /*
- ** Lastly, verify the security entry(s) match either the name
- ** or group name of the user.
- */
- found = 0;
- entry = security->entries;
- while ((!found) && (entry != (ENTRY *)NULL))
- {
- /* Match with the username? */
- if ((namelen == entry->valuelen) &&
- (memcmp(entry->value, name, namelen) == 0))
- {
- found = 1;
- continue;
- }
-
- /* Match with the user group? */
- if ((!ntauth) && (!radiusauth) &&
- (passwd.grouplen == entry->valuelen) &&
- (memcmp(entry->value, passwd.group, passwd.grouplen) == 0))
- {
- found = 1;
- continue;
- }
-
- entry = entry->next;
- }
-
- if (!found)
- {
- *infop = SA_E_INVALIDLOGIN;
- return (SA_FAIL);
- }
-
- /*
- ** Finally, if a full "user" should be created (with server-side
- ** state), do so here.
- */
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_AUTHLOGINS, tmp, 30,
- (SA_INT *)NULL) == SA_SUCCEED)
- {
- if ((strcmp(tmp, "true") == 0) &&
- (sa_conn_login(saconn, name, namelen, pwd, pwdlen, infop)
- != SA_SUCCEED))
- {
- return (SA_FAIL);
- }
- }
- }
-
- security = security->next;
- }
-
- /*
- ** DENY
- */
- if ((Entries[SECURITY_DENY] != (SECURITY *)NULL) &&
- (sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
- &namelen) == SA_SUCCEED))
- {
- security = Entries[SECURITY_DENY];
- while (security != (SECURITY *)NULL)
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- name, strlen(name)) == 0)
- {
- entry = security->entries;
- *infop = SA_E_REDIRECT;
- (SA_VOID)sa_conn_redirect(saconn, entry->value,
- "Request redirected.", SA_NULLTERM);
- return (SA_FAIL);
- }
-
- security = security->next;
- }
- }
-
- /*
- ** IP-RESTRICT
- */
- security = Entries[SECURITY_IPRESTRICT];
- while (security != (SECURITY *)NULL)
- {
- if ((urilen >= security->namelen) &&
- (strnicmp(uri, security->name, security->namelen) == 0))
- {
- /* Get the IP address of the client. */
- if (sa_conn_props(saconn, SA_GET, SA_CONNPROP_IPADDR, name, 60,
- &namelen) != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- /*
- ** Lastly, verify the security entry(s) match the IP
- ** address of the client.
- */
- found = 0;
- entry = security->entries;
- while ((!found) && (entry != (ENTRY *)NULL))
- {
- if (sa_wildcmp(sactx, entry->value, entry->valuelen,
- name, namelen) == 0)
- {
- found = 1;
- continue;
- }
-
- entry = entry->next;
- }
-
- if (!found)
- {
- *infop = SA_E_FORBIDDEN;
- return (SA_FAIL);
- }
- }
-
- security = security->next;
- }
-
- /*
- ** HOSTREDIRECT
- */
- security = Entries[SECURITY_HOSTREDIRECT];
- if ((security != (SECURITY *)NULL) &&
- (sa_conn_props(saconn, SA_GET, SA_CONNPROP_REQUESTHOST, name, 60,
- &namelen) == SA_SUCCEED))
- {
- while (security != (SECURITY *)NULL)
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- name, namelen) == 0)
- {
- entry = security->entries;
- *infop = SA_E_REDIRECT;
- (SA_VOID)sa_conn_redirect(saconn, entry->value,
- "Request redirected.", SA_NULLTERM);
- return (SA_FAIL);
- }
-
- security = security->next;
- }
- }
-
- /*
- ** SITEREDIRECT
- */
- security = Entries[SECURITY_SITEREDIRECT];
- if ((security != (SECURITY *)NULL) &&
- (sa_conn_props(saconn, SA_GET, SA_CONNPROP_REQUESTHOST, name, 60,
- &namelen) == SA_SUCCEED))
- {
- while (security != (SECURITY *)NULL)
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- name, namelen) == 0)
- {
- if (sa_conn_props(saconn, SA_GET, SA_CONNPROP_URL, name,
- 500, &namelen) != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- entry = security->entries;
- if (namelen + strlen(entry->value) > 1000)
- return (SA_FAIL);
-
- *infop = SA_E_REDIRECT;
- sprintf(tmp, "%s%s", entry->value, name);
- (SA_VOID)sa_conn_redirect(saconn, tmp,
- "Request redirected.", SA_NULLTERM);
- return (SA_FAIL);
- }
-
- security = security->next;
- }
- }
-
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY_CONNECT
- **
- ** Determine if the connection should be allowed.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** ipaddr The IP address of the client requesting a connection.
- ** servertype The server the client is attempting to connect to.
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_connect(sactx, ipaddr, servertype)
- SA_CTX *sactx;
- SA_CHAR *ipaddr;
- SA_INT servertype;
- {
- SA_INT denyid;
- SA_INT acceptid;
- SA_INT ipaddrlen;
- SA_BOOL found;
- SA_CHAR *server;
- SA_CHAR *desc;
- SECURITY *security;
- SA_CHAR buffer[512];
-
- /* Initialization */
- ipaddrlen = strlen(ipaddr);
-
- switch((int)servertype)
- {
- case SA_SERVERTYPE_HTTP:
- server = "HTTP";
- denyid = SECURITY_HTTPDENY;
- acceptid = SECURITY_HTTPACCEPT;
- break;
-
- case SA_SERVERTYPE_FTP:
- server = "FTP";
- denyid = SECURITY_FTPDENY;
- acceptid = SECURITY_FTPACCEPT;
- break;
-
- case SA_SERVERTYPE_HTTPPROXY:
- case SA_SERVERTYPE_SMTPPROXY:
- case SA_SERVERTYPE_POP3PROXY:
- case SA_SERVERTYPE_IMAP4PROXY:
- case SA_SERVERTYPE_BRIDGEPROXY:
- case SA_SERVERTYPE_NNTPPROXY:
- case SA_SERVERTYPE_FTPPROXY:
- case SA_SERVERTYPE_SOCKSPROXY:
- case SA_SERVERTYPE_TELNETPROXY:
- case SA_SERVERTYPE_REALPROXY:
- case SA_SERVERTYPE_TCPPROXY:
- case SA_SERVERTYPE_UDPPROXY:
- server = "PROXY";
- denyid = SECURITY_PROXYDENY;
- acceptid = SECURITY_PROXYACCEPT;
- break;
-
- case SA_SERVERTYPE_SMTP:
- case SA_SERVERTYPE_POP3:
- case SA_SERVERTYPE_IMAP4:
- server = "Mail";
- denyid = SECURITY_MAILDENY;
- acceptid = SECURITY_MAILACCEPT;
- break;
-
- case SA_SERVERTYPE_DNS:
- server = "DNS";
- denyid = SECURITY_DNSDENY;
- acceptid = SECURITY_DNSACCEPT;
- break;
-
- case SA_SERVERTYPE_SIP:
- server = "SIP";
- denyid = SECURITY_SIPDENY;
- acceptid = SECURITY_SIPACCEPT;
- break;
-
- case SA_SERVERTYPE_TFTP:
- server = "TFTP";
- denyid = SECURITY_TFTPDENY;
- acceptid = SECURITY_TFTPACCEPT;
- break;
-
- default:
- sprintf(buffer, "NETCONNECT: Unrecognized server (%ld)", servertype);
- sa_log2(sactx, SA_LOG_ERROR, buffer);
- return (SA_FAIL);
- }
-
- /*
- ** NETACCEPT
- **
- ** The client must be in the accept list.
- */
- found = 0;
- security = Entries[acceptid];
- while ((!found) && (security != (SECURITY *)NULL))
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- ipaddr, ipaddrlen) == 0)
- {
- found = 1;
- continue;
- }
-
- security = security->next;
- }
-
- if (!found)
- {
- sprintf(buffer,
- "NETCONNECT: Client %s not in accept list for server %s.",
- ipaddr, server);
- sa_log2(sactx, SA_LOG_WARN, buffer);
- return (SA_FAIL);
- }
-
- /*
- ** NETDENY
- **
- ** The client cannot be in the deny list.
- */
- security = Entries[denyid];
- while (security != (SECURITY *)NULL)
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- ipaddr, ipaddrlen) == 0)
- {
- desc = "unknown";
- if (security->entries != (ENTRY *)NULL)
- desc = security->entries->value;
-
- sprintf(buffer,
- "NETCONNECT: Client %s is in deny list for server %s [%s].",
- ipaddr, server, desc);
- sa_log2(sactx, SA_LOG_WARN, buffer);
- return (SA_FAIL);
- }
-
- security = security->next;
- }
-
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY_FILTER
- **
- ** Filter all HTTP Proxy requests.
- **
- ** If the requested URL is found in the [httpfilter] section, either
- ** return the file specified in the file in response to the request,
- ** or return a 404 request denied message if no file is specified.
- **
- ** If the requested URL is NOT found in the [httprestrict] section,
- ** return a 404 request denied message.
- **
- ** If the requested URL is found in the [urlfilter] section,
- ** return a 404 request denied message.
- **
- **
- ** Parameters:
- ** sactx Sambar Server context
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_filter(sactx, saconn, host, hostlen, url, urllen)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_CHAR *host;
- SA_INT hostlen;
- SA_CHAR *url;
- SA_INT urllen;
- {
- SA_INT i;
- SA_INT len;
- SA_INT urlcaselen;
- SA_BOOL found;
- ENTRY *entry;
- SECURITY *security;
- SA_CHAR urlcase[1024];
- SA_CHAR buffer[2048];
-
- /*
- ** Convert the host and URL to lower case.
- */
- for (i = 0; i < hostlen; i++)
- host[i] = tolower(host[i]);
-
- urlcaselen = 0;
- while ((urlcaselen < urllen) && (urlcaselen < 1000))
- {
- urlcase[urlcaselen] = tolower(url[urlcaselen]);
- urlcaselen++;
- }
-
- urlcase[urlcaselen] = '\0';
-
- security = Entries[SECURITY_HOSTFILTER];
- while (security != (SECURITY *)NULL)
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- host, hostlen) == 0)
- {
- (SA_VOID)sa_send_header(saconn, DENIED_HEADER, SA_NULLTERM);
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, buffer,
- 1000, &len) == SA_SUCCEED)
- {
- strcat(buffer, "\\messages\\filtered.htm");
- (SA_VOID)sa_send_file(saconn, buffer);
- }
-
- entry = security->entries;
- if ((entry != (ENTRY *)NULL) &&
- (hostlen + entry->valuelen < 1000))
- {
- sprintf(buffer, "HTTPPROXY: Host %s blocked by filter: %s",
- host, entry->value);
- sa_log2(sactx, SA_LOG_WARN, buffer);
- }
-
- return (SA_FAIL);
- }
-
- security = security->next;
- }
-
- security = Entries[SECURITY_URLFILTER];
- while (security != (SECURITY *)NULL)
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- urlcase, urlcaselen) == 0)
- {
- (SA_VOID)sa_send_header(saconn, DENIED_HEADER, SA_NULLTERM);
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, buffer,
- 1000, &len) == SA_SUCCEED)
- {
- strcat(buffer, "\\messages\\filtered.htm");
- (SA_VOID)sa_send_file(saconn, buffer);
- }
-
- entry = security->entries;
- if ((entry != (ENTRY *)NULL) &&
- (urlcaselen + entry->valuelen < 900))
- {
- sprintf(buffer, "HTTPPROXY: URL blocked by filter '%s' : ",
- entry->value);
- strcat(buffer, urlcase);
- sa_log2(sactx, SA_LOG_WARN, buffer);
- }
-
- return (SA_FAIL);
- }
-
- security = security->next;
- }
-
- /*
- ** If a [hostrestrict] entry is found, the host must match
- ** an entry on the list provided or it will be denied.
- */
- security = Entries[SECURITY_HOSTRESTRICT];
- if (security != (SECURITY *)NULL)
- {
- found = 0;
- while ((!found) && (security != (SECURITY *)NULL))
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- host, hostlen) == 0)
- {
- found = 1;
- continue;
- }
-
- security = security->next;
- }
-
- if (!found)
- {
- (SA_VOID)sa_send_header(saconn, DENIED_HEADER, SA_NULLTERM);
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, buffer,
- 1000, &len) == SA_SUCCEED)
- {
- strcat(buffer, "\\messages\\filtered.htm");
- (SA_VOID)sa_send_file(saconn, buffer);
- }
- else
- {
- sprintf(buffer,
- "<!-- HTTPPROXY: Host '%s' not on [hostrestrict] list -->",
- host);
- (SA_VOID)sa_conn_send(saconn, buffer, SA_NULLTERM);
- }
-
- sprintf(buffer, "HTTPPROXY: Host '%s' not on [hostrestrict] list",
- host);
- sa_log2(sactx, SA_LOG_WARN, buffer);
- return (SA_FAIL);
- }
- }
-
- /*
- ** If a [urlrestrict] entry is found, the URL must match
- ** an entry on the list provided or it will be denied.
- */
- security = Entries[SECURITY_URLRESTRICT];
- if (security != (SECURITY *)NULL)
- {
- found = 0;
- while ((!found) && (security != (SECURITY *)NULL))
- {
- if (sa_wildcmp(sactx, security->name, security->namelen,
- urlcase, urlcaselen) == 0)
- {
- found = 1;
- continue;
- }
-
- security = security->next;
- }
-
- if (!found)
- {
- (SA_VOID)sa_send_header(saconn, DENIED_HEADER, SA_NULLTERM);
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, buffer,
- 1000, &len) == SA_SUCCEED)
- {
- strcat(buffer, "\\messages\\filtered.htm");
- (SA_VOID)sa_send_file(saconn, buffer);
- }
- else
- {
- strcpy(buffer,
- "<!-- HTTPPROXY: URL not on [urlrestrict] list : ");
- strcat(buffer, urlcase);
- strcat(buffer, " -->");
- (SA_VOID)sa_conn_send(saconn, buffer, SA_NULLTERM);
- }
-
- strcpy(buffer, "HTTPPROXY: URL not on [urlrestrict] list : ");
- strcat(buffer, urlcase);
- sa_log2(sactx, SA_LOG_WARN, buffer);
- return (SA_FAIL);
- }
- }
-
- /* HTTP Request should be allowed through. */
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY__LOAD
- **
- ** Load a single security rule.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** argp Security parameter.
- ** name Left hand argument.
- ** value Right hand argument.
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE
- security__load(sactx, argp, name, value)
- SA_CTX *sactx;
- SA_VOID *argp;
- SA_CHAR *name;
- SA_CHAR *value;
- {
- SA_INT pos;
- SA_INT head;
- SA_INT valuelen;
- ENTRY *entry;
- SECURITY *security;
-
- security = (SECURITY *)malloc(sizeof(SECURITY));
- if (security == (SECURITY *)NULL)
- return (SA_FAIL);
-
- memset(security, 0, sizeof(SECURITY));
- security->namelen = strlen(name);
- valuelen = strlen(value);
-
- if (security->namelen == 0)
- return (SA_FAIL);
-
- /* Is a value required? */
- if ((valuelen == 0) &&
- (*(SA_INT *)argp != SECURITY_DENY) &&
- (*(SA_INT *)argp != SECURITY_HTTPACCEPT) &&
- (*(SA_INT *)argp != SECURITY_HTTPDENY) &&
- (*(SA_INT *)argp != SECURITY_FTPACCEPT) &&
- (*(SA_INT *)argp != SECURITY_FTPDENY) &&
- (*(SA_INT *)argp != SECURITY_MAILACCEPT) &&
- (*(SA_INT *)argp != SECURITY_MAILDENY) &&
- (*(SA_INT *)argp != SECURITY_DNSACCEPT) &&
- (*(SA_INT *)argp != SECURITY_DNSDENY) &&
- (*(SA_INT *)argp != SECURITY_SIPACCEPT) &&
- (*(SA_INT *)argp != SECURITY_SIPDENY) &&
- (*(SA_INT *)argp != SECURITY_TFTPACCEPT) &&
- (*(SA_INT *)argp != SECURITY_TFTPDENY) &&
- (*(SA_INT *)argp != SECURITY_HOSTFILTER) &&
- (*(SA_INT *)argp != SECURITY_IPRESTRICT) &&
- (*(SA_INT *)argp != SECURITY_URLRESTRICT) &&
- (*(SA_INT *)argp != SECURITY_URLFILTER))
- {
- return (SA_FAIL);
- }
-
- security->name = strdup(name);
-
- /* Restriction & IP-restriction lists have multiple entries */
- if ((*(SA_INT *)argp == SECURITY_RESTRICT) ||
- (*(SA_INT *)argp == SECURITY_IPRESTRICT))
- {
- pos = 0;
- while (pos < valuelen)
- {
- head = pos;
- while ((pos < valuelen) && !isspace(value[pos]))
- pos++;
-
- value[pos] = '\0';
-
- entry = (ENTRY *)malloc(sizeof(ENTRY));
- if (entry == (ENTRY *)NULL)
- return (SA_FAIL);
-
- memset(entry, 0, sizeof(ENTRY));
- entry->value = strdup(&value[head]);
- entry->valuelen = pos - head;;
- entry->next = security->entries;
- security->entries = entry;
-
- pos++;
- while ((pos < valuelen) && isspace(value[pos]))
- pos++;
- }
- }
- else
- {
- entry = (ENTRY *)malloc(sizeof(ENTRY));
- if (entry == (ENTRY *)NULL)
- return (SA_FAIL);
-
- memset(entry, 0, sizeof(ENTRY));
- entry->valuelen = valuelen;
- entry->value = strdup(value);
- security->entries = entry;
- }
-
- security->next = TmpEntries[*(SA_INT *)argp];
- TmpEntries[*(SA_INT *)argp] = security;
-
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY_SHOWSEC
- **
- ** Show the security associated with a particular symbol.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_showsec(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT i;
- SA_BOOL found;
- SA_INT datalen;
- SA_CHAR *data;
- ENTRY *entry;
- SECURITY *security;
- SA_CHAR buffer[1024];
-
- if ((sa_param(sactx, saparams, "type", &data, &datalen) != SA_SUCCEED)
- || (datalen == 0) || (datalen > 64))
- {
- /* No report type given */
- return (SA_SUCCEED);
- }
-
- i = 0;
- found = 0;
- while ((i < NUM_ENTRIES) && (!found))
- {
- if (strcmp(Security_entries[i].symbol, (SA_CHAR *)data) == 0)
- found = 1;
- else
- i++;
- }
-
- if (!found)
- {
- *infop = SA_E_INVALIDDATA;
- return (SA_FAIL);
- }
-
- sprintf(buffer, "<FONT SIZE=+1><B>%s</B></FONT><P>\n",
- Security_entries[i].descr);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- security = Entries[i];
- if (security == (SECURITY *)NULL)
- {
- if (sa_conn_send(saconn, "<I>No Security Controls defined.",
- SA_NULLTERM) != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- return (SA_SUCCEED);
- }
-
- if (sa_conn_send(saconn, "<TABLE border=1 cellspacing=4>\n", SA_NULLTERM)
- != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- while (security != (SECURITY *)NULL)
- {
- sprintf(buffer, "<TR><TD>%s</TD><TD>", security->name);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- entry = security->entries;
- while (entry != (ENTRY *)NULL)
- {
- sprintf(buffer, "%s ", entry->value);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- entry = entry->next;
- }
-
- if (sa_conn_send(saconn, "</TD></TR>\n", SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- security = security->next;
- }
-
- if (sa_conn_send(saconn, "</TABLE>\n", SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-
- /*
- ** SECURITY_RELOAD
- **
- ** Reload the security rules.
- ** Note: The final step (swapping security rules) should be mutexed.
- ** It results in a memory leak and could lead to request failure.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- security_reload(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- SA_INT i;
- SA_CHAR buffer[255];
-
- for (i = 0; i < NUM_ENTRIES; i++)
- {
- TmpEntries[i] = (SECURITY *)NULL;
-
- if (sa_props_load(sactx, "security.ini",
- Security_entries[i].symbol, &Security_entries[i].id,
- (SA_PROPFUNC)security__load) != SA_SUCCEED)
- {
- sprintf(buffer, "Failure loading [%s] security section.",
- Security_entries[i].symbol);
- sa_log2(sactx, SA_LOG_ERROR, buffer);
- *infop = SA_E_INTERNALSYSTEM;
- return (SA_FAIL);
- }
- }
-
- /* Swap the security rules (leaks memory) */
- for (i = 0; i < NUM_ENTRIES; i++)
- Entries[i] = TmpEntries[i];
-
- return (SA_SUCCEED);
- }
-