summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--blacklist.c55
-rw-r--r--blacklist.h7
-rw-r--r--options.h5
-rw-r--r--svr-auth.c2
-rw-r--r--svr-main.c6
6 files changed, 75 insertions, 2 deletions
diff --git a/Makefile.in b/Makefile.in
index fc17c1f..ff23022 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -25,7 +25,7 @@ COMMONOBJS=dbutil.o buffer.o \
SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \
svr-authpasswd.o svr-authpubkey.o svr-session.o svr-service.o \
svr-chansession.o svr-runopts.o svr-agentfwd.o svr-main.o svr-x11fwd.o\
- svr-tcpfwd.o svr-authpam.o
+ svr-tcpfwd.o svr-authpam.o blacklist.o
CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \
cli-session.o cli-service.o cli-runopts.o cli-chansession.o \
diff --git a/blacklist.c b/blacklist.c
new file mode 100644
index 0000000..ea4998d
--- /dev/null
+++ b/blacklist.c
@@ -0,0 +1,55 @@
+#include "includes.h"
+#include "options.h"
+#include "dbutil.h"
+
+#define LINE_LENGTH 50
+
+int is_blacklisted (char *remote_ip) {
+
+ char sz_tmp[LINE_LENGTH];
+ FILE *fp_blacklist = NULL;
+
+ fp_blacklist = fopen(BLACKLISTFILE, "r");
+ if (fp_blacklist == NULL) {
+ /* TODO: this could spew log messages. */
+ dropbear_log(LOG_INFO, "Could not open blacklist %s for reading.", BLACKLISTFILE);
+ } else {
+ while (fgets(sz_tmp, LINE_LENGTH - 1, fp_blacklist) != NULL) {
+ if (strlen(sz_tmp) > 0) {
+ sz_tmp[strlen(sz_tmp)-1] = '\0';
+ if (!strcmp(sz_tmp, remote_ip)) {
+ dropbear_log(LOG_INFO, "IP %s is forbidden!", remote_ip);
+ fclose (fp_blacklist);
+ return 1;
+ }
+ }
+ }
+ fclose (fp_blacklist);
+ }
+ return 0;
+}
+
+void blacklist (char *addrstring)
+{
+ int i;
+ FILE *fp_blacklist = NULL;
+ char *remote_ip = NULL;
+
+ remote_ip = m_strdup (addrstring);
+ i = strlen (remote_ip);
+ /* This may not be IPv6 safe if addrstring doesn't have a :port suffix */
+ while (i--) {
+ if (remote_ip[i] == ':') {
+ remote_ip[i] = '\0';
+ break;
+ }
+ }
+ dropbear_log (LOG_INFO, "Blacklisting %s", remote_ip);
+ if ((fp_blacklist = fopen (BLACKLISTFILE, "a")) == NULL) {
+ dropbear_log (LOG_INFO, "Could not open blacklist %s for appending", BLACKLISTFILE);
+ } else {
+ fprintf (fp_blacklist, "%s\n", remote_ip);
+ fclose (fp_blacklist);
+ }
+ m_free (remote_ip);
+}
diff --git a/blacklist.h b/blacklist.h
new file mode 100644
index 0000000..c1045f5
--- /dev/null
+++ b/blacklist.h
@@ -0,0 +1,7 @@
+#ifndef _BLACKLIST_H_
+#define _BLACKLIST_H_
+
+int is_blacklisted (char *remote_ip);
+void blacklist (char *addrstring);
+
+#endif
diff --git a/options.h b/options.h
index 0349fa9..813d706 100644
--- a/options.h
+++ b/options.h
@@ -22,6 +22,9 @@
#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key"
#endif
+/* File to store blacklisted IPs */
+#define BLACKLISTFILE "/var/dropbear/blacklist"
+
/* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens
* on chosen ports and keeps accepting connections. This is the default.
*
@@ -174,7 +177,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
/* Maximum number of failed authentication tries (server option) */
#ifndef MAX_AUTH_TRIES
-#define MAX_AUTH_TRIES 10
+#define MAX_AUTH_TRIES 2
#endif
/* The file to store the daemon's process ID, for shutdown scripts etc */
diff --git a/svr-auth.c b/svr-auth.c
index f0fca38..e3ad8f4 100644
--- a/svr-auth.c
+++ b/svr-auth.c
@@ -33,6 +33,7 @@
#include "packet.h"
#include "auth.h"
#include "runopts.h"
+#include "blacklist.h"
static void authclear();
static int checkusername(unsigned char *username, unsigned int userlen);
@@ -338,6 +339,7 @@ void send_msg_userauth_failure(int partial, int incrfail) {
} else {
userstr = ses.authstate.printableuser;
}
+ blacklist(svr_ses.addrstring);
dropbear_exit("Max auth tries reached - user '%s' from %s",
userstr, svr_ses.addrstring);
}
diff --git a/svr-main.c b/svr-main.c
index e06eb5e..03e05c3 100644
--- a/svr-main.c
+++ b/svr-main.c
@@ -28,6 +28,7 @@
#include "buffer.h"
#include "signkey.h"
#include "runopts.h"
+#include "blacklist.h"
static size_t listensockets(int *sock, size_t sockcount, int *maxfd);
static void sigchld_handler(int dummy);
@@ -254,6 +255,11 @@ void main_noinetd() {
}
}
+ if (is_blacklisted(getaddrstring(&remoteaddr, 0)) == 1) {
+ close(childsock);
+ continue;
+ }
+
if (num_unauthed_total >= MAX_UNAUTH_CLIENTS
|| num_unauthed_for_addr >= MAX_UNAUTH_PER_IP) {
goto out;