/* honeypotsh.c - Honey Pot Shell
   © 2017 Perette Barell d/b/a Devious Fish
   Released under the MIT license.

   Before using this, consider the security implications of what you are
   doing.  While the honeypot will snare those using ssh, is there some
   other method that creates a hole, such as legacy ftp?  Think through
   what you're doing.

   Consider also the PermitUserEnvironment setting for sshd_config.

   To use:
   - Compile (cc -o honeypotsh honeypotsh.c)
   - Mark executable either setuid or setgid to an account capable of
   writing to /etc/hosts.deny.
   - Make sure hosts.deny exists and is utilized by your platform.
   - Add a couple of users using well-known default credentials,
   and set their shell to the honeypotsh executable.

   Now, when someone attempts to hack your system with these credentials,
   their IP gets banned.

   Be sure to test this after installation!  And before you do, have a login
   session open so you can remove your IP from /etc/hosts.deny after it gets
   added by your testing.

   If SSH_CLIENT isn't supported on your system, you may want to try
   SSH_CONNECTION instead.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>

int main (int argc, char **argv) {
	FILE *denials = fopen ("/etc/hosts.deny", "a");
	if (!denials) {
		perror ("hosts.deny");
		exit (1);
	}
	const char *host = getenv ("SSH_CLIENT");
	if (!host) {
		fprintf (stderr, "SSH_CLIENT not set\n");
		exit (1);
	}
	const char *end_host = strchr (host, ' ');
	if (!end_host) {
		fprintf (stderr, "SSH_CLIENT value mangled\n");
		exit (1);
	}

	time_t now = time (NULL);
	char *username = getlogin();
	fprintf (denials, "\n# Next line added by honeypotsh user %s at %s"
			  "ALL : %.*s\n",
			  username ? username : "[unknown user]", ctime (&now),
			  (int) (end_host - host), host);
	fclose (denials);
	printf ("Thanks for visiting our honeypot!  Have a nice day.\n");

	/* Kill parent process, which is sshd. */
	pid_t parent = getppid();
	/* Don't kill init/launchd/systemd if sshd already died. */
	if (parent != 1) {
		/* Give it time to send thank-you message. */
		sleep (1);
		kill (parent, SIGTERM);
		sleep (1);
		kill (parent, SIGKILL);
	}

	return 0;
}


