mud/lib/secure/daemon/inet.c
2020-09-06 05:43:07 -07:00

194 lines
4.3 KiB
C

/* /secure/daemon/inet.c
* From the Dead Souls Mud Library
* A daemon to handle the start and stop of inet servers
* Created by Descartes of Borg 961219
* Version: @(#) inet.c 1.1@(#)
* Last modified: 96/12/19
*/
#include <lib.h>
#include <save.h>
inherit LIB_DAEMON;
class service {
int PortOffset;
string SocketClass;
int SocketType;
}
private static mapping Servers = ([]);
private mapping Services = ([]);
mapping BlockedIps = ([]);
int eventStartServer(string svc);
int eventStopServer(string svc);
void validate(){
if(!master()->valid_apply(({ "SECURE", "ASSIST" }))){
string offender = identify(previous_object(-1));
debug("INET_D SECURITY VIOLATION: "+offender+" ",get_stack(),"red");
log_file("security", "\n"+timestamp()+" INET_D breach: "+offender+" "+get_stack());
error("INET_D SECURITY VIOLATION: "+offender+" "+get_stack());
}
}
void eventBlockIp(string ip){
log_file("security", "\n"+timestamp()+" INET_D ip block: "+ip+"\n");
if(ip != "*.*" && member_array(ip, keys(BlockedIps)) == -1){
BlockedIps[ip] = time();
eventSave();
}
}
string *GetBlockedIps(){
return keys(BlockedIps);
}
mapping eventClearBlockedIps(){
validate();
BlockedIps = ([]);
log_file("security", "\n"+timestamp()+" INET_D all IP's unblocked.\n");
eventSave();
return copy(BlockedIps);
}
mapping GetServers() {
return copy(Servers);
}
int GetServer(string str){
if(Servers[str]) return 1;
return 0;
}
int GetService(string str){
if(Services[str]) return 1;
return 0;
}
mapping GetServices() {
return copy(Services);
}
int AddService(string name, int port_offset, string socket_class, int type) {
class service s = new(class service);
if( !master()->valid_apply(({})) ) {
return 0;
}
s->PortOffset = port_offset;
s->SocketClass = socket_class;
s->SocketType = type;
Services[name] = s;
if( !eventSave() ) {
return 0;
}
Servers[name] = new(LIB_SERVER, query_host_port()+port_offset, type,
socket_class);
return 1;
}
int RemoveService(string name) {
if( !master()->valid_apply() ) {
return 0;
}
if( Servers[name] ) {
Servers[name]->eventShutdown();
}
map_delete(Servers, name);
map_delete(Services, name);
return eventSave();
}
varargs int eventRestartServer(string svc, int forced) {
if( !eventStopServer(svc) ) {
if(!forced) return 0;
}
if( !eventStartServer(svc) ) {
if(!forced) return 0;
}
return 1;
}
int eventStartServer(string svc) {
class service s = Services[svc];
object ob = Servers[svc];
if( !master()->valid_apply(({})) ) {
return 0;
}
if( ob ) {
return 0;
}
if( !s ) {
return 0;
}
ob = new(LIB_SERVER, query_host_port()+s->PortOffset, s->SocketType,
s->SocketClass);
if( ob ) {
Servers[svc] = ob;
return 1;
}
else {
return 0;
}
}
int eventStopServer(string svc) {
object ob = Servers[svc];
if( !master()->valid_apply(({})) ) {
return 0;
}
if( !ob ) {
return 0;
}
ob->eventShutdown();
map_delete(Servers, svc);
if( ob ) {
return 0;
}
else {
return 1;
}
}
static void create() {
SetSaveFile(SAVE_INET);
daemon::create();
if(!BlockedIps) BlockedIps = ([]);
SetNoClean(1);
set_heart_beat(10);
foreach(string svc, class service s in Services) {
Servers[svc] = new(LIB_SERVER, query_host_port() + s->PortOffset,
s->SocketType, s->SocketClass);
}
}
int eventDestruct(){
object *servers = filter(objects(), (: base_name($1) == LIB_SERVER :) );
eventSave();
foreach(object server in servers){
if(server && clonep(server)) server->eventDestruct();
if(server && clonep(server)) destruct(server);
}
return daemon::eventDestruct();
}
void heart_beat(){
validate();
foreach(mixed key, mixed val in BlockedIps){
if((time() - val) > 60) map_delete(BlockedIps, key);
}
}
int GetServicePort(string str){
int ret;
int offset;
if(Services[str]) offset = Services[str]->PortOffset;
ret = query_host_port() + offset;
return ret;
}