
#include "captive.h"



int main( int argc, char *argv[] ) {
	GDBM_FILE dbf = NULL;
	datum key;
	datum content;

	char ip[IP_LEN];
	char mac[MAC_LEN];
	FILE *f;
	char buffer[500];

	int logged_on_flag = 0;
	char log_ip[IP_LEN], log_mac[MAC_LEN];
	int log_event;
	long log_time;
	char log_username[USERNAME_LEN];

	char client_username[USERNAME_LEN];

	int retval;
	time_t tp;

	time( &tp );

	printf( "Content-type: text/html\r\n\r\n" );

	/*  Get his IP address from the environment variable.  */

	strncpy( ip, getenv("REMOTE_ADDR"), IP_LEN );
	if( ip[0] == '\0' ) {
		/* don't know the client's IP address for some reason */
                post_to_log( EVENT_LOGIN_FAIL_NO_IP, "? [logoff attempt]", "?", "?", (long)tp );
		printf( "<html>Error - unable to get client's IP address from REMOTE_ADDR env variable.</html>\n" );
		exit(0);
	}

	/* Get the MAC address most recently associated with this IP from the
	   SW's dhcp lease file.  Finding, or not finding, the user's correct
	   MAC address here is key in preventing valid users with static IP
	   addresses from logging in. */
	retval = get_mac_from_dhcp_lease( ip, mac );
	if( retval != 1 ) {
		/* the client didn't get an IP address from the DHCP server */
                post_to_log( EVENT_LOGIN_FAIL_NO_MAC_IN_LEASE_FILE, "? [logoff attempt]", ip, "?", (long)tp );
		printf( "<html>Error %d<br>\nNo record of IP/MAC in access log.  This may be an error, or you may be attempting to logoff a privileged client.</html>\n", retval );
		exit(0);
	}

	/* Get most recent user to have logged in at that address, and see if he's still logged in. */


	strncpy( client_username, "[unknown]", USERNAME_LEN );
	f = fopen( "/var/smoothwall/mods/captive/log.txt", "r" );
	if( !f ) { printf( "Error opening log file.\n" ); exit(0); }
	fgets( buffer, 500, f );
	while( !feof(f) ) {

		sscanf( buffer, "%d\t%ld\t%s\t%s\t%s\n", &log_event, &log_time, log_username, log_ip, log_mac );

		if( (strncmp(ip,log_ip,IP_LEN) == 0) && (strncmp(mac,log_mac,MAC_LEN) == 0) ) {
			if( log_event == EVENT_LOGIN_SUCCESS ) {
				logged_on_flag = 1;
				strncpy( client_username, log_username, USERNAME_LEN );
			} else if( (log_event == EVENT_LOGOFF_TIMED) || (log_event == EVENT_LOGOFF_FORCED) || (log_event == EVENT_LOGOFF_ELECTIVE) ) {
				logged_on_flag = 0;

			}

		}


		fgets( buffer, 500, f );
	}

	if( logged_on_flag ) {
/*
		printf( "Logging off %s - currently logged on here<br>\n", client_username );
*/

		if( dbf == NULL ) dbf = gdbm_open( "/var/smoothwall/mods/captive/captivedb", 512, GDBM_WRITER, S_IRWXU, NULL );

		key.dptr = client_username;
		key.dsize = strlen( client_username );
		content = gdbm_fetch( dbf, key );
		if( content.dptr == NULL ) {
			printf( "The account %s does not exist.<br>\n", client_username );
			exit(0);
		} else {
			((userinfo *)content.dptr)->logged_in_now = 0;
			((userinfo *)content.dptr)->ip[0] = '\0';
			((userinfo *)content.dptr)->mac[0] = '\0';
			((userinfo *)content.dptr)->login_expires_at = 0;

			retval = gdbm_store( dbf, key, content, GDBM_REPLACE );
			if( retval == 0 ) {
				; /*printf( "The account %s has been logged off.<br>\n", client_username ); */
			} else {
				printf( "Error logging off \"%s\" - invalid key, content, or insertion flag / program may not have write access to captivedb.<br>\n", client_username );
			}
		}
		free( content.dptr );
		if( dbf != NULL ) gdbm_close( dbf );

		if( setuid(0) != 0 ) { printf( "<html>Error 5 (a)</html>\n" ); exit(0); }
		iptables_rule( IPTABLES_DEL, ip, mac );
		post_to_log( EVENT_LOGOFF_ELECTIVE, log_username, ip, mac, (long)tp );

		printfile( "/var/smoothwall/mods/captive/successful_logoff.html" );

	} else {
		printfile( "/var/smoothwall/mods/captive/failed_logoff.html" );
	}


	return 0;
}

