diff options
-rw-r--r-- | plugin/firewall/eurephiafw.c | 161 | ||||
-rw-r--r-- | plugin/firewall/eurephiafw.h | 6 | ||||
-rw-r--r-- | plugin/firewall/eurephiafw_struct.h | 32 |
3 files changed, 142 insertions, 57 deletions
diff --git a/plugin/firewall/eurephiafw.c b/plugin/firewall/eurephiafw.c index 471e6e8..5d4e519 100644 --- a/plugin/firewall/eurephiafw.c +++ b/plugin/firewall/eurephiafw.c @@ -38,6 +38,7 @@ #include <sys/mman.h> #include <sys/wait.h> #include <time.h> +#include <errno.h> #include <assert.h> #define EUREPHIA_FWINTF @@ -137,8 +138,10 @@ int eFW_load(eurephiaCTX *ctx, const char *intf) { void eFW_StartFirewall(eurephiaCTX *ctx) { struct mq_attr mqattr; eurephiaCTX *shadowctx = NULL; - char buf[1026], *fwdest = NULL; + eFWupdateRequest updreq; + char *fwdest = NULL; unsigned int prio; + int mqres = 0; ctx->fwcfg = (eurephiaFWINTF *) malloc_nullsafe(ctx, sizeof(eurephiaFWINTF)+2); @@ -184,7 +187,6 @@ void eFW_StartFirewall(eurephiaCTX *ctx) { // Setup where to send the blacklisted IP addresses - default is to drop them. ctx->fwcfg->fwblacklist_sendto = eGet_value(ctx->dbc->config, "firewall_blacklist_send_to"); if( ctx->fwcfg->fwblacklist_sendto == NULL ) { - ctx->fwcfg->fwblacklist_sendto = strdup("DROP\0"); eurephia_log(ctx, LOG_INFO, 2,"Blacklisted IP addresses will be dropped immediately"); } else { eurephia_log(ctx, LOG_INFO, 2,"Blacklisted IP addresses will be sent to '%s'", @@ -230,6 +232,7 @@ void eFW_StartFirewall(eurephiaCTX *ctx) { // Flush the message queue for old messages if( mq_getattr((*ctx->fwcfg).thrdata.msgq, &mqattr) == 0 ) { long i; + char buf[1026]; memset(&buf, 0, 1026); if( mqattr.mq_curmsgs > 0 ) { @@ -258,28 +261,43 @@ void eFW_StartFirewall(eurephiaCTX *ctx) { eurephia_log(ctx, LOG_INFO, 2, "eFW interface initialised."); // Initialise the chain - memset(&buf, 0, 1026); - snprintf(buf, 1024, "I %s", fwdest); - if( mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1) == -1 ) { - eurephia_log(ctx, LOG_ERROR, 0, "Could not request firewall initialisation of the %s chain: %s", + memset(&updreq, 0, sizeof(eFWupdateRequest)); + updreq.mode = fwINITIALISE; + strncpy(updreq.rule_destination, fwdest, 64); + mqres = mq_send((*ctx->fwcfg).thrdata.msgq, + (const char *)&updreq, sizeof(eFWupdateRequest), 1); + if( mqres < 1 ) { + eurephia_log(ctx, LOG_ERROR, 0, + "Could not request firewall initialisation of the %s chain: %s", fwdest, strerror(errno)); }; if( ctx->fwcfg->fwblacklist != NULL ) { eurephiaVALUES *blacklisted = NULL, *p = NULL; + eFWupdateRequest updreq; + // Flushing firewall blacklist chain - snprintf(buf, 1024, "F %s", ctx->fwcfg->fwblacklist); - if( mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1) == -1 ) { + memset(&updreq, 0, sizeof(eFWupdateRequest)); + updreq.mode = fwFLUSH; + strncpy(updreq.rule_destination, ctx->fwcfg->fwblacklist, 64); + errno = 0; + mqres = mq_send((*ctx->fwcfg).thrdata.msgq, + (const char *)&updreq, sizeof(eFWupdateRequest), 1); + if( mqres < 1 ) { eurephia_log(ctx, LOG_ERROR, 0, "Could not request flushing of the %s chain: %s", ctx->fwcfg->fwblacklist, strerror(errno)); }; // Registering already blacklisted IP addresses into the proper firewall chain + memset(&updreq, 0, sizeof(eFWupdateRequest)); + updreq.mode = fwBLACKLIST; blacklisted = eDBget_blacklisted_ip(ctx); p = blacklisted; while( p != NULL ) { if( p->val != NULL ) { - eFW_UpdateFirewall(ctx, FWRULE_BLACKLIST, p->val, ctx->fwcfg->fwblacklist, NULL); + memset(&updreq.ipaddress, 0, 36); + strncpy(updreq.ipaddress, p->val, 34); + eFW_UpdateFirewall(ctx, &updreq); } p = p->next; } @@ -294,8 +312,10 @@ void eFW_StartFirewall(eurephiaCTX *ctx) { * @param ctx eurephiaCTX */ void eFW_StopFirewall(eurephiaCTX *ctx) { - char buf[520], *fwdest = NULL; + char *fwdest = NULL; + eFWupdateRequest updreq; struct timespec tsp; + int mqres = 0; if( ctx->fwcfg == NULL ) { return; @@ -307,24 +327,33 @@ void eFW_StopFirewall(eurephiaCTX *ctx) { // we don't unintentionally some accesses open fwdest = eGet_value(ctx->dbc->config, "firewall_destination"); if( fwdest != NULL ) { - memset(&buf, 0, 520); - snprintf(buf, 512, "F %s", fwdest); - if( mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1) == -1 ) { + memset(&updreq, 0, sizeof(eFWupdateRequest)); + updreq.mode = fwFLUSH; + strncpy(updreq.rule_destination, fwdest, 64); + + errno = 0; + mqres = mq_send((*ctx->fwcfg).thrdata.msgq, + (const char *)&updreq, sizeof(eFWupdateRequest), 1); + if( mqres < 1 ) { eurephia_log(ctx, LOG_CRITICAL, 0, "Could not request firewall flushing of the %s chain: %s", fwdest, strerror(errno)); }; } else { eurephia_log(ctx, LOG_CRITICAL, 0, "firewall_destination not set in config. Will not flush " - "firewall before shutting down the firewall interface."); + "firewall before shutting down the firewall interface."); } // Send shutdown message to the firewall module process - memset(&buf, 0, 520); - snprintf(buf, 512, "FWSHUTDOWN%c", 0); - if( mq_send((*ctx->fwcfg).thrdata.msgq, buf, 11, 1) == -1 ) { - eurephia_log(ctx, LOG_PANIC, 0, "Could not initiate shutdown on eFW module: %s", strerror(errno)); + memset(&updreq, 0, sizeof(eFWupdateRequest)); + updreq.mode = fwSHUTDOWN; + errno = 0; + mqres = mq_send((*ctx->fwcfg).thrdata.msgq, + (const char *)&updreq, sizeof(eFWupdateRequest), 1); + if( mqres < 1 ) { + eurephia_log(ctx, LOG_PANIC, 0, + "Could not initiate shutdown on eFW module: %s", strerror(errno)); kill(ctx->fwcfg->fwproc_pid, SIGABRT); } @@ -367,17 +396,14 @@ void eFW_StopFirewall(eurephiaCTX *ctx) { * Requests an update of the firewall rules * * @param ctx eurephiaCTX - * @param mode int value which can be FWRULE_ADD, FWRULE_DELETE, FWRULE_BLACKLIST - * @param addr The address of the rule to be changed (IP address or MAC address) - * @param fwdest The firewall destination, where the rule is (to be) found. - * @param fwprofile The firewall profile the user is defined to make use of. + * @param request eFWupdateRequest struct with the needed firewall information * * @return Returns 1 on success, otherwise 0. */ -int eFW_UpdateFirewall(eurephiaCTX *ctx, int mode, - const char *addr, const char *fwdest, const char *fwprofile) { - char buf[1026]; +int eFW_UpdateFirewall(eurephiaCTX *ctx, eFWupdateRequest *request ) { char *blchk = NULL; + unsigned int prio = 0; + int mqres = 0; if( (*ctx->fwcfg).thrdata.fw_command == NULL ) { eurephia_log(ctx, LOG_FATAL, 0, "Function call: eFW_UpdateFirewall() -- " @@ -385,43 +411,86 @@ int eFW_UpdateFirewall(eurephiaCTX *ctx, int mode, return 0; } - memset(&buf, 0, 1026); - switch( mode ) { - case FWRULE_ADD: - eurephia_log(ctx, LOG_INFO, 3, - "Function call: eFW_UpdateFirewall(ctx, %s, '%.18s', '%s', '%s')", - "ADD", addr, fwdest, fwprofile); - snprintf(buf, 1024, "A %.18s %s %s", addr, fwdest, fwprofile); - mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1); - return 1; + if( (request == NULL) || (strlen_nullsafe(request->rule_destination) < 1) ) { + eurephia_log(ctx, LOG_PANIC, 0, "eFW_UpdateFirewall: Invalid update request"); + return 0; + } - case FWRULE_DELETE: + switch( request->mode ) { + case fwADD: + prio = 11; + case fwDELETE: + if( (strlen_nullsafe(request->macaddress) < 1) + && (strlen_nullsafe(request->ipaddress) < 1) ) { + eurephia_log(ctx, LOG_ERROR, 0, + "eFW_UpdateFirewall: No MAC address nor IP address was given received"); + return 1; + } + if( prio == 0 ) { + prio = 12; // It's a delete request, it's not as important as other messages + } eurephia_log(ctx, LOG_INFO, 3, "Function call: eFW_UpdateFirewall(ctx, %s, '%.18s', '%s', '%s')", - "DELETE", addr, fwdest, fwprofile); - snprintf(buf, 1024, "D %.18s %s %s", addr, fwdest, fwprofile); - mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1); + (request->mode == fwADD ? "ADD" : "DELETE"), + request->macaddress, + request->rule_destination, + request->goto_destination); + errno = 0; + mqres = mq_send((*ctx->fwcfg).thrdata.msgq, + (const char *)request, sizeof(eFWupdateRequest), prio); + if( mqres < 0 ) { + eurephia_log(ctx, LOG_CRITICAL, 0, + "eFW_updateFirewall: Failed to send update request - %s", + strerror(errno)); + return 0; + } return 1; - case FWRULE_BLACKLIST: + case fwBLACKLIST: + if( strlen_nullsafe(request->ipaddress) < 1) { + eurephia_log(ctx, LOG_ERROR, 0, + "eFW_UpdateFirewall: No IP address given for blacklist"); + return 1; + } eurephia_log(ctx, LOG_INFO, 3, "Function call: eFW_UpdateFirewall(ctx, %s, '%.34s','%s', NULL)", - "BLACKLIST", addr, fwdest); + "BLACKLIST", request->ipaddress, request->rule_destination); // Check if IP address is already registered as blacklisted - if( (blchk = eGet_value(ctx->fwcfg->blacklisted, addr)) == NULL ) { - snprintf(buf, 1024, "B %.34s %s %s", addr, fwdest, ctx->fwcfg->fwblacklist_sendto); - mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1); - eAdd_value(ctx, ctx->fwcfg->blacklisted, addr, fwdest); + if( (blchk = eGet_value(ctx->fwcfg->blacklisted, request->ipaddress)) == NULL ) { + // Setup rule destinations + strncpy(request->rule_destination, ctx->fwcfg->fwblacklist, 64); + if( ctx->fwcfg->fwblacklist_sendto != NULL ) { + strncpy(request->goto_destination, ctx->fwcfg->fwblacklist_sendto, 64); + } else { + strncpy(request->goto_destination, "DROP\0", 6); + } + + errno = 0; + mqres = mq_send((*ctx->fwcfg).thrdata.msgq, + (const char *)request, sizeof(eFWupdateRequest), prio); + if( mqres < 0 ) { + eurephia_log(ctx, LOG_CRITICAL, 0, + "eFW_updateFirewall: Failed to send update request - %s", + strerror(errno)); + return 0; + } + eAdd_value(ctx, ctx->fwcfg->blacklisted, + request->ipaddress, request->rule_destination); } else { eurephia_log(ctx, LOG_INFO, 5, "IP address already blacklisted in '%s'", blchk); } return 1; + case fwFLUSH: + case fwINITIALISE: + eurephia_log(ctx, LOG_ERROR, 5, "eFW_UpdateFirewall: Unsupported update request"); + return 0; + default: eurephia_log(ctx, LOG_CRITICAL, 0, - "Function call: eFW_UpdateFirewall(ctx, %s, '%s') - UNKNOWN MODE", "(unknown)", - addr); + "Function call: eFW_UpdateFirewall(ctx, %s, '%s') - UNKNOWN MODE", + "(unknown)", request->macaddress); return 0; } } diff --git a/plugin/firewall/eurephiafw.h b/plugin/firewall/eurephiafw.h index 860411b..d0b762e 100644 --- a/plugin/firewall/eurephiafw.h +++ b/plugin/firewall/eurephiafw.h @@ -32,15 +32,11 @@ #ifndef EUREPHIAFW_H_ #define EUREPHIAFW_H_ -#define FWRULE_ADD 0x101 /**< Add a new firewall rule */ -#define FWRULE_DELETE 0x102 /**< Delete an existing firewall rule */ -#define FWRULE_BLACKLIST 0x103 /**< Blacklist an IP address in the firewall */ - int eFW_load(eurephiaCTX *ctx, const char *intf); int eFW_unload(eurephiaCTX *ctx); void eFW_StartFirewall(eurephiaCTX *ctx); void eFW_StopFirewall(eurephiaCTX *ctx); -int eFW_UpdateFirewall(eurephiaCTX *ctx, int mode, const char *macaddr, const char *fwdest, const char *fwprofile); +int eFW_UpdateFirewall(eurephiaCTX *ctx, eFWupdateRequest *request); #endif /* !EUREPHIAFW_H_ */ diff --git a/plugin/firewall/eurephiafw_struct.h b/plugin/firewall/eurephiafw_struct.h index dc7df59..10fd630 100644 --- a/plugin/firewall/eurephiafw_struct.h +++ b/plugin/firewall/eurephiafw_struct.h @@ -29,8 +29,8 @@ */ -#ifndef EUREPHIAFW_STRUCT_H_ -#define EUREPHIAFW_STRUCT_H_ +#ifndef EUREPHIAFW_STRUCT_H_ +#define EUREPHIAFW_STRUCT_H_ #include <mqueue.h> #include <semaphore.h> @@ -53,12 +53,32 @@ typedef struct { * Definition of the eurephiaFWINTF struct */ typedef struct { - efw_threaddata thrdata; /**< Process related information */ - pid_t fwproc_pid; /**< Contains the PID of the firewall process */ + efw_threaddata thrdata; /**< Process related information */ + pid_t fwproc_pid; /**< Contains the PID of the firewall process */ char *fwblacklist; /**< Which fw dest. blacklisted IP addr should be registered into */ - char *fwblacklist_sendto; /**< Which fw dest. blacklisted IP addr should forward their hits to. t */ + char *fwblacklist_sendto; /**< Which fw dest. blacklisted IP addr should forward their hits to */ eurephiaVALUES *blacklisted; /**< Contains all IP addresses we have blacklisted */ } eurephiaFWINTF; -#endif /* !EUREPHIAFW_STRUCT_H_ */ + +/** + * Valid firewall modes to be passed over the POSIX MQ queue + */ +typedef enum {fwADD, /**< Add a new VPN client to the firewall VPN chain */ + fwDELETE, /**< Delete an existing VPN client from the firewall VPN chain */ + fwBLACKLIST, /**< Blacklist an IP address */ + fwFLUSH, /**< Flush the firewall VPN chain */ + fwINITIALISE, /**< Initialiase the firewall VPN chain */ + fwSHUTDOWN, /**< Initialiase the firewall VPN chain */ +} eFWmode; + +typedef struct { + eFWmode mode; /**< Defines what the update will do with the firewall (mandatory) */ + char ipaddress[36]; /**< IP address to include (used by fwADD,fwDELETE and fwBLACKLIST) */ + char macaddress[19]; /**< VPN MAC address (used by fwADD and fwDELETE) */ + char rule_destination[66]; /**< Where this new rule will be inserted (mandatory) */ + char goto_destination[66]; /**< Where matching rules should go next (used by fwBLACKLIST) */ +} eFWupdateRequest; + +#endif /* !EUREPHIAFW_STRUCT_H_ */ |