From 5f25e3be7fcf3ee007b6343a8800a5d124b88429 Mon Sep 17 00:00:00 2001 From: bobbyhopere Date: Sat, 12 Aug 2017 16:36:43 +0200 Subject: [PATCH] anti-brute force for RPC Server --- libtransmission/rpc-server.c | 46 +++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/libtransmission/rpc-server.c b/libtransmission/rpc-server.c index 013682572..dd617dd36 100644 --- a/libtransmission/rpc-server.c +++ b/libtransmission/rpc-server.c @@ -560,12 +560,31 @@ static void handle_request(struct evhttp_request* req, void* arg) if (req != NULL && req->evcon != NULL) { + static int attempts = 0; char const* auth; char* user = NULL; char* pass = NULL; evhttp_add_header(req->output_headers, "Server", MY_REALM); + if (attempts == 100) + { + send_simple_response (req, 403, + "Too many unsuccessful login attempts. " + "Please restart transmission-daemon."); + return; + } + + if (!isAddressAllowed(server, req->remote_host)) + { + send_simple_response(req, 403, + "

Unauthorized IP Address.

" + "

Either disable the IP address whitelist or add your address to it.

" + "

If you're editing settings.json, see the 'rpc-whitelist' and 'rpc-whitelist-enabled' entries.

" + "

If you're still using ACLs, use a whitelist instead. See the transmission-daemon manpage for details.

"); + return; + } + auth = evhttp_find_header(req->input_headers, "Authorization"); if (auth != NULL && evutil_ascii_strncasecmp(auth, "basic ", 6) == 0) @@ -587,21 +606,26 @@ static void handle_request(struct evhttp_request* req, void* arg) } } - if (!isAddressAllowed(server, req->remote_host)) - { - send_simple_response(req, 403, - "

Unauthorized IP Address.

" - "

Either disable the IP address whitelist or add your address to it.

" - "

If you're editing settings.json, see the 'rpc-whitelist' and 'rpc-whitelist-enabled' entries.

" - "

If you're still using ACLs, use a whitelist instead. See the transmission-daemon manpage for details.

"); - } - else if (server->isPasswordEnabled && (pass == NULL || user == NULL || strcmp(server->username, user) != 0 || + if (server->isPasswordEnabled && (pass == NULL || user == NULL || strcmp(server->username, user) != 0 || !tr_ssha1_matches(server->password, pass))) { evhttp_add_header(req->output_headers, "WWW-Authenticate", "Basic realm=\"" MY_REALM "\""); - send_simple_response(req, 401, "Unauthorized User"); + attempts++; + char* unauthuser = tr_strdup_printf( + "Unauthorized User. " + "%i unsuccessful login attempts.", + attempts); + send_simple_response(req, 401, unauthuser); + tr_free (unauthuser); + tr_free (user); + return; } - else if (strncmp(req->uri, server->url, strlen(server->url)) != 0) + else + { + attempts = 0; + } + + if (strncmp(req->uri, server->url, strlen(server->url)) != 0) { char* location = tr_strdup_printf("%sweb/", server->url); evhttp_add_header(req->output_headers, "Location", location);