diff options
-rw-r--r-- | database/eurephiadb.c | 2 | ||||
-rw-r--r-- | database/eurephiadb_driver.h | 44 | ||||
-rw-r--r-- | database/sqlite/administration/lastlog.c | 14 | ||||
-rw-r--r-- | database/sqlite/administration/useraccount.c | 13 | ||||
-rw-r--r-- | database/sqlite/edb-sqlite.c | 75 | ||||
-rw-r--r-- | database/sqlite/sql-schema-delta-2.sql | 48 | ||||
-rw-r--r-- | database/sqlite/sql-schema.sql | 5 | ||||
-rw-r--r-- | plugin/CMakeLists.txt | 4 | ||||
-rw-r--r-- | plugin/eurephia.c | 7 | ||||
-rw-r--r-- | plugin/firewall/eurephiafw.c | 3 | ||||
-rw-r--r-- | plugin/firewall/eurephiafw_helpers.c | 1 | ||||
-rw-r--r-- | xslt/eurephiadm/lastlog.xsl | 2 |
12 files changed, 182 insertions, 36 deletions
diff --git a/database/eurephiadb.c b/database/eurephiadb.c index 7046dae..3b1c751 100644 --- a/database/eurephiadb.c +++ b/database/eurephiadb.c @@ -116,6 +116,8 @@ int eDBlink_init(eurephiaCTX *ctx, const char *dbdriver, const int minver) "to upgrade eurephia to take advantage of newer features in the driver."); case 4: + eDBregister_login2 = eGetSym(ctx, ctx->eurephia_driver, "eDBregister_login2"); + eDBget_accessprofile = eGetSym(ctx, ctx->eurephia_driver, "eDBget_accessprofile"); eDBauth_GetAuthMethod = eGetSym(ctx, ctx->eurephia_driver, "eDBauth_GetAuthMethod"); eDBget_plugins = eGetSym(ctx, ctx->eurephia_driver, "eDBget_plugins"); eDBadminPlugins = eGetSym(ctx, ctx->eurephia_driver, "eDBadminPlugins"); diff --git a/database/eurephiadb_driver.h b/database/eurephiadb_driver.h index fa0cf35..b7154ea 100644 --- a/database/eurephiadb_driver.h +++ b/database/eurephiadb_driver.h @@ -214,6 +214,34 @@ void EUREPHIA_DRIVERAPI_FUNC(eDBregister_attempt)(eurephiaCTX *ctx, int type, in * Registers a client login. This happens after the client has been authenticated successfully, * when OpenVPN does the OPENVPN_PLUGIN_CLIENT_CONNECT call to the eurephia-auth plug-in. * + * This function replaces eDBregister_login() + * + * @version API version level 4 + * @param ctx eurephiaCTX + * @param skey eurephiaSESSION. A login must be connected to an opened eurephia session. + * @param certid Certificate ID of the clients user certificate + * @param uid User id of the client + * @param accessprofile Access profile ID - to log the firewall profile the user used. + * May be -1 if not used/logged + * @param proto String containing protocol used for the connection (udp, tcp) + * @param remipaddr Clients remote IP address + * @param remport The port the client is connecting from + * + * @return Returns 1 on success, otherwise 0. + */ +int EUREPHIA_DRIVERAPI_FUNC(eDBregister_login2)(eurephiaCTX *ctx, eurephiaSESSION *skey, + const int certid, const int uid, const int accessprofile, + const char *proto, const char *remipaddr, const char *remport); + + +/** + * Registers a client login. This happens after the client has been authenticated successfully, + * when OpenVPN does the OPENVPN_PLUGIN_CLIENT_CONNECT call to the eurephia-auth plug-in. + * + * This should now only be a wrapper around eDBregister_login2() to provide backwards API support + * for API version 3 and older. The VPN IP address are no longer stored in the openvpn_lastlog table, + * but saved by using the eDBregister_vpnclientaddr() function. + * * @version API version level 1 * @param ctx eurephiaCTX * @param skey eurephiaSESSION. A login must be connected to an opened eurephia session. @@ -233,6 +261,7 @@ int EUREPHIA_DRIVERAPI_FUNC(eDBregister_login)(eurephiaCTX *ctx, eurephiaSESSION const char *vpnipaddr, const char *vpnipmask); + /** * Registers the MAC address of the clients TAP interface. This function is called when * OpenVPN does the OPENVPN_PLUGIN_LEARN_ADDRESS call to the eurephia-auth plug-in. @@ -299,6 +328,21 @@ int EUREPHIA_DRIVERAPI_FUNC(eDBregister_logout)(eurephiaCTX *ctx, eurephiaSESSIO */ char * EUREPHIA_DRIVERAPI_FUNC(eDBget_firewall_profile) (eurephiaCTX *ctx, eurephiaSESSION *session); + +/** + * Retrieves the accessprofile reference ID from the user/certs link table for a given + * UID and certID. This is used for tracking which firewall profile was used when storing + * it in the lastlog table. + * + * @version API version level 4 + * @param ctx eurephiaCTX + * @param session eurephiaSESSION + * + * @return Returns an a positive integer when reference was found. Otherwise -1 is returned. + */ +int EUREPHIA_DRIVERAPI_FUNC(eDBget_accessprofile) (eurephiaCTX *ctx, const int uid, const int certid); + + /** * Retrieve a list of IP addresses found in the IP address blacklist table. * diff --git a/database/sqlite/administration/lastlog.c b/database/sqlite/administration/lastlog.c index 8f2edbc..d5f4b61 100644 --- a/database/sqlite/administration/lastlog.c +++ b/database/sqlite/administration/lastlog.c @@ -92,15 +92,17 @@ xmlDoc *eDBadminGetLastlog(eurephiaCTX *ctx, xmlDoc *srch_xml, const char *sortk // Query the database, find the user defined in the user map res = sqlite_query_mapped(ctx, SQL_SELECT, - "SELECT llid, ll.certid, protocol, remotehost, remoteport, macaddr," - " vpnipaddr, vpnipmask, sessionstatus, sessionkey," + "SELECT llid, ll.certid, protocol, remotehost, remoteport," + " macaddr, ip4addr, ip6addr," + " sessionstatus, ll.sessionkey," " locdt(login), locdt(logout)," " session_duration, locdt(session_deleted)," - " bytes_sent, bytes_received, uicid, accessprofile," + " bytes_sent, bytes_received, uicid, ll.accessprofile," " access_descr, fw_profile, depth, lower(digest)," " common_name, organisation, email, username, ll.uid" " FROM openvpn_lastlog ll" - " LEFT JOIN openvpn_usercerts USING (uid, certid)" + " JOIN openvpn_vpnaddr_history ovh ON (ovh.sessionkey = ll.sessionkey)" + " LEFT JOIN openvpn_usercerts ouc ON (ouc.uid = ll.uid AND ouc.certid = ll.certid)" " LEFT JOIN openvpn_accesses USING (accessprofile)" " LEFT JOIN openvpn_users users ON( ll.uid = users.uid)" " LEFT JOIN openvpn_certificates cert ON (ll.certid = cert.certid)", @@ -134,8 +136,8 @@ xmlDoc *eDBadminGetLastlog(eurephiaCTX *ctx, xmlDoc *srch_xml, const char *sortk sqlite_xml_value(tmp1, XML_NODE, "remote_host", res, i, 3); sqlite_xml_value(tmp1, XML_NODE, "remote_port", res, i, 4); sqlite_xml_value(tmp1, XML_NODE, "vpn_macaddr", res, i, 5); - sqlite_xml_value(tmp1, XML_NODE, "vpn_ipaddr" , res, i, 6); - sqlite_xml_value(tmp1, XML_NODE, "vpn_netmask", res, i, 7); + sqlite_xml_value(tmp1, XML_NODE, "vpn_ipv4addr", res, i, 6); + sqlite_xml_value(tmp1, XML_NODE, "vpn_ipv6addr", res, i, 7); tmp1 = sqlite_xml_value(sess, XML_NODE, "username", res, i, 25); sqlite_xml_value(tmp1, XML_ATTR, "uid", res, i, 26); diff --git a/database/sqlite/administration/useraccount.c b/database/sqlite/administration/useraccount.c index 37303b7..db527ed 100644 --- a/database/sqlite/administration/useraccount.c +++ b/database/sqlite/administration/useraccount.c @@ -233,17 +233,18 @@ static xmlDoc *useracc_view(eurephiaCTX *ctx, unsigned int infoType, qres = sqlite_query(ctx, "SELECT llid, ll.certid,protocol,remotehost,remoteport,macaddr," - " vpnipaddr, vpnipmask, sessionstatus, sessionkey," + " ip4addr, ip6addr, sessionstatus, ll.sessionkey," " locdt(login), locdt(logout)," " session_duration, locdt(session_deleted)," - " bytes_sent, bytes_received, uicid, accessprofile," + " bytes_sent, bytes_received, uicid, ll.accessprofile," " access_descr, fw_profile, depth, lower(digest)," " common_name, organisation, email" " FROM openvpn_lastlog ll" - " LEFT JOIN openvpn_usercerts USING (uid, certid)" + " JOIN openvpn_vpnaddr_history ovh ON (ovh.sessionkey = ll.sessionkey)" + " LEFT JOIN openvpn_usercerts ouc ON (ouc.uid = ll.uid AND ouc.certid = ll.certid)" " LEFT JOIN openvpn_accesses USING (accessprofile)" " LEFT JOIN openvpn_certificates cert ON(ll.certid=cert.certid)" - " WHERE uid = '%i' ORDER BY login, logout", uid); + " WHERE ll.uid = '%i' ORDER BY login, logout", uid); if( sqlite_query_status(qres) != dbSUCCESS ) { eurephia_log(ctx, LOG_ERROR, 0, "Querying the lastlog failed"); @@ -279,8 +280,8 @@ static xmlDoc *useracc_view(eurephiaCTX *ctx, unsigned int infoType, sqlite_xml_value(tmp1, XML_NODE, "remote_host", qres, i, 3); sqlite_xml_value(tmp1, XML_NODE, "remote_port", qres, i, 4); sqlite_xml_value(tmp1, XML_NODE, "vpn_macaddr", qres, i, 5); - sqlite_xml_value(tmp1, XML_NODE, "vpn_ipaddr" , qres, i, 6); - sqlite_xml_value(tmp1, XML_NODE, "vpn_netmask", qres, i, 7); + sqlite_xml_value(tmp1, XML_NODE, "vpn_ipv4addr" , qres, i, 6); + sqlite_xml_value(tmp1, XML_NODE, "vpn_ipv6addr", qres, i, 7); tmp1 = xmlNewChild(sess, NULL, (xmlChar *) "certificate", NULL); assert( tmp1 != NULL ); diff --git a/database/sqlite/edb-sqlite.c b/database/sqlite/edb-sqlite.c index b35d00d..6e33267 100644 --- a/database/sqlite/edb-sqlite.c +++ b/database/sqlite/edb-sqlite.c @@ -688,19 +688,18 @@ void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value free_nullsafe(ctx, blid); } - /** - * @copydoc eDBregister_login() + * @copydoc eDBregister_login2() */ -int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid, const int uid, - const char *proto, const char *remipaddr, const char *remport, - const char *vpnipaddr, const char *vpnipmask) +int eDBregister_login2(eurephiaCTX *ctx, eurephiaSESSION *skey, + const int certid, const int uid, const int accessprofile, + const char *proto, const char *remipaddr, const char *remport) { dbresult *res = NULL; int ret = 0; - DEBUG(ctx, 20, "Function call: eDBregister_login(ctx, '%s', %i, %i, '%s','%s','%s','%s','%s')", - skey->sessionkey, certid, uid, proto, remipaddr, remport, vpnipaddr, vpnipmask); + DEBUG(ctx, 20, "Function call: eDBregister_login2(ctx, '%s', %i, %i, '%s','%s','%s')", + skey->sessionkey, certid, uid, proto, remipaddr, remport); if( skey->sessionstatus != SESSION_NEW ) { eurephia_log(ctx, LOG_ERROR, 5, "Not a new session, will not register it again"); @@ -708,16 +707,17 @@ int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid, } res = sqlite_query(ctx, - "INSERT INTO openvpn_lastlog (uid, certid, " + "INSERT INTO openvpn_lastlog (uid, certid, accessprofile," " protocol, remotehost, remoteport," - " vpnipaddr, vpnipmask," " sessionstatus, sessionkey, login) " - "VALUES (%i, %i, '%q','%q','%q','%q','%q', 1,'%q', CURRENT_TIMESTAMP)", - uid, certid, proto, remipaddr, remport, vpnipaddr, vpnipmask, skey->sessionkey); + "VALUES (%i,%i,%i,'%q','%q','%q',1,'%q',CURRENT_TIMESTAMP)", + uid, certid, accessprofile, + proto, remipaddr, remport, + skey->sessionkey); if( sqlite_query_status(res) != dbSUCCESS ) { eurephia_log(ctx, LOG_FATAL, 0, "Could not insert new session into openvpn_lastlog"); sqlite_log_error(ctx, res); - ret = 0; + ret = 1; } else { skey->sessionstatus = SESSION_REGISTERED; ret = 1; @@ -728,6 +728,22 @@ int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid, } /** + * @copydoc eDBregister_login() + * Just a function wrapper to support both the old and the newer eDBregister_login2() functions. + */ +int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid, const int uid, + const char *proto, const char *remipaddr, const char *remport, + const char *vpnipaddr, const char *vpnipmask) +{ + DEBUG(ctx, 20, "Function call: eDBregister_login(ctx, '%s', %i, %i, '%s','%s','%s','%s','%s')", + skey->sessionkey, certid, uid, proto, remipaddr, remport, vpnipaddr, vpnipmask); + eurephia_log(ctx, LOG_WARNING, 1, + "Using deprecated eDBregister_login() call, please update the eurephia-auth.so plug-in. " + "VPN IP address/mask will not be saved."); + return eDBregister_login2(ctx, skey, certid, uid, -1, proto, remipaddr, remport); +} + +/** * @copydoc eDBregister_vpnmacaddr() */ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const char *macaddr) @@ -810,11 +826,10 @@ int eDBregister_vpnclientaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const } sqlite_free_results(res); - // Update lastlog to reflect last used MAC address for the session + // Update lastlog with a "connection open" status res = sqlite_query(ctx, - "UPDATE openvpn_lastlog SET sessionstatus = 2, macaddr = '%q', vpnipaddr = '%q', vpnipv6addr = '%q' " + "UPDATE openvpn_lastlog SET sessionstatus = 2 " " WHERE sessionkey = '%q' AND sessionstatus = 1", - (macaddr ? macaddr : ""), (vpnip4addr ? vpnip4addr : ""), (vpnip6addr ? vpnip6addr : ""), session->sessionkey); if( sqlite_query_status(res) == dbSUCCESS ) { // TAP mode: Save the MAC address in the session values register - needed for the destroy session @@ -825,7 +840,7 @@ int eDBregister_vpnclientaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const ret = 1; } } else { - eurephia_log(ctx, LOG_FATAL, 0, "Could not update lastlog with new VPN client addresses for session"); + eurephia_log(ctx, LOG_FATAL, 0, "Could not update the session status in the lastlog"); sqlite_log_error(ctx, res); ret = 0; } @@ -1247,6 +1262,34 @@ char *eDBget_firewall_profile(eurephiaCTX *ctx, eurephiaSESSION *session) /** + * @copydoc eDBget_accessprofile() + */ +int eDBget_accessprofile(eurephiaCTX *ctx, const int uid, const int certid) +{ + int ret = -1; + dbresult *res = NULL; + + DEBUG(ctx, 20, "Function call: eDBget_firewall_profile_id(ctx, %i, %i)", uid, certid); + + res = sqlite_query(ctx, + "SELECT accessprofile " + " FROM openvpn_usercerts " + " WHERE uid = %i AND certid = %i", + uid, certid); + if( sqlite_query_status(res) == dbSUCCESS ) { + ret = atoi_nullsafe(sqlite_get_value(res, 0, 0)); + } else { + eurephia_log(ctx, LOG_FATAL, 0, "Could not retrieve access profile for uid %i and certid %i", + uid, certid); + sqlite_log_error(ctx, res); + ret = -1; + } + sqlite_free_results(res); + return ret; +} + + +/** * @copydoc eDBget_blacklisted_ip() */ eurephiaVALUES *eDBget_blacklisted_ip(eurephiaCTX *ctx) { diff --git a/database/sqlite/sql-schema-delta-2.sql b/database/sqlite/sql-schema-delta-2.sql new file mode 100644 index 0000000..52ca9ab --- /dev/null +++ b/database/sqlite/sql-schema-delta-2.sql @@ -0,0 +1,48 @@ +-- +-- eurephia database schema for SQLite3 +-- +-- This SQL scripts updates the previous SQL schema to the +-- new schema needed by edb-sqlite v1.4 +-- +-- GPLv2 only - Copyright (C) 2012 +-- David Sommerseth <dazo@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; version 2 +-- of the License. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-- + +ALTER TABLE openvpn_lastlog RENAME TO openvpn_lastlog_old; +DROP INDEX openvpn_lastlog_sessionkey; + +CREATE TABLE openvpn_lastlog ( + uid integer , + certid integer , + accessprofile integer , + protocol varchar(4) NOT NULL, + remotehost varchar(128) NOT NULL, + remoteport integer NOT NULL, + sessionstatus integer NOT NULL DEFAULT 0, + sessionkey varchar(128) , + login timestamp , + logout timestamp , + session_deleted timestamp , + session_duration timestamp, + bytes_sent integer , + bytes_received integer , + llid integer PRIMARY KEY AUTOINCREMENT +); + +INSERT INTO openvpn_lastlog SELECT uid, certid, NULL, protocol, remotehost, remoteport, sessionstatus, sessionkey, login, logout, session_deleted, session_duration, bytes_sent, bytes_received, llid FROM openvpn_lastlog_old; +UPDATE sqlite_sequence SET seq = (SELECT max(llid) FROM openvpn_lastlog) WHERE name = 'openvpn_lastlog'; +CREATE UNIQUE INDEX openvpn_lastlog_sessionkey ON openvpn_lastlog(sessionkey); diff --git a/database/sqlite/sql-schema.sql b/database/sqlite/sql-schema.sql index 899c95b..746d84f 100644 --- a/database/sqlite/sql-schema.sql +++ b/database/sqlite/sql-schema.sql @@ -79,13 +79,10 @@ CREATE TABLE openvpn_accesses ( CREATE TABLE openvpn_lastlog ( uid integer , certid integer , + accessprofile integer , protocol varchar(4) NOT NULL, remotehost varchar(128) NOT NULL, remoteport integer NOT NULL, - macaddr varchar(20) , - vpnipaddr varchar(32) NOT NULL, - vpnipmask varchar(32) NOT NULL, - vpnipv6addr varchar(48) , sessionstatus integer NOT NULL DEFAULT 0, sessionkey varchar(128) , login timestamp , diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 49aa132..38b0076 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -82,6 +82,10 @@ IF(ENABLE_EUREPHIADM) REMOVE_DEFINITIONS(-DENABLE_EUREPHIADM) ENDIF(ENABLE_EUREPHIADM) +# Only allow MADV_DONTFORK on Linux +IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + SET(COMPILE_DEFINITIONS HAVE_MADVDONTFORK) +ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # Build rule for eurephia-auth.so ADD_LIBRARY(eurephia-auth MODULE diff --git a/plugin/eurephia.c b/plugin/eurephia.c index 3392724..946422f 100644 --- a/plugin/eurephia.c +++ b/plugin/eurephia.c @@ -630,7 +630,7 @@ int eurephia_connect(eurephiaCTX *ctx, const char **env) { eurephiaSESSION *session = NULL; char *digest, *cname, *uname, *vpnipaddr, *vpnipmask, *remipaddr, *remport, *proto, *tlsid; - int certid = 0, uid = 0, ret = 0; + int certid = 0, uid = 0, accprofile = -1, ret = 0; certinfo *ci = NULL; DEBUG(ctx, 10, "** Function call: eurephia_connect(...)"); @@ -680,9 +680,10 @@ int eurephia_connect(eurephiaCTX *ctx, const char **env) { free_certinfo(ci); // Register the session login - ret = eDBregister_login(ctx, session, certid, uid, proto, remipaddr, remport, vpnipaddr, vpnipmask); + accprofile = eDBget_accessprofile(ctx, uid, certid); + ret = eDBregister_login2(ctx, session, certid, accprofile, uid, proto, remipaddr, remport); eDBfree_session(ctx, session); - eurephia_log(ctx, LOG_INFO, 1, "User '%s' logged in", uname); + eurephia_log(ctx, LOG_INFO, 1, "User '%s' connected", uname); free_nullsafe(ctx, proto); free_nullsafe(ctx, remport); diff --git a/plugin/firewall/eurephiafw.c b/plugin/firewall/eurephiafw.c index 6b2bf24..d74a383 100644 --- a/plugin/firewall/eurephiafw.c +++ b/plugin/firewall/eurephiafw.c @@ -37,6 +37,7 @@ #include <unistd.h> #include <sys/mman.h> #include <sys/wait.h> +#include <signal.h> #include <time.h> #include <errno.h> #include <assert.h> @@ -236,8 +237,10 @@ void eFW_StartFirewall(eurephiaCTX *ctx, const int daemon, const int logredir) { return; } +#if HAVE_MADVDONTFORK // Make sure that these variables are not available in the child madvise(ctx, sizeof(eurephiaCTX), MADV_DONTFORK); +#endif // Start a new process (should run with root permissions) - which will do the firewall work if( (ctx->fwcfg->fwproc_pid = fork()) < 0 ) { diff --git a/plugin/firewall/eurephiafw_helpers.c b/plugin/firewall/eurephiafw_helpers.c index 728e507..b779925 100644 --- a/plugin/firewall/eurephiafw_helpers.c +++ b/plugin/firewall/eurephiafw_helpers.c @@ -34,6 +34,7 @@ #include <string.h> #include <errno.h> #include <unistd.h> +#include <fcntl.h> #include <semaphore.h> #include <mqueue.h> diff --git a/xslt/eurephiadm/lastlog.xsl b/xslt/eurephiadm/lastlog.xsl index 0cb1d40..b4369e9 100644 --- a/xslt/eurephiadm/lastlog.xsl +++ b/xslt/eurephiadm/lastlog.xsl @@ -169,7 +169,7 @@ </xsl:call-template> <xsl:text> </xsl:text> <xsl:call-template name="right-align"> - <xsl:with-param name="value" select="connection/vpn_ipaddr"/> + <xsl:with-param name="value" select="connection/vpn_ipv4addr"/> <xsl:with-param name="width" select="19"/> </xsl:call-template> <xsl:text> </xsl:text> |