- client: if GUI RPC auth error, close the socket.

This prevents a DoS by sending <auth1> over and over,
    filling the send buffer and eventually causing the client to block.
- Unix build: if m4 missing, check for gm4


svn path=/trunk/boinc/; revision=15282
This commit is contained in:
David Anderson 2008-05-23 19:24:20 +00:00
parent 49eb1246cf
commit 8befa29f81
6 changed files with 43 additions and 10 deletions

View File

@ -90,6 +90,8 @@ check_version()
if test -f /usr/ccs/bin/m4
then
echo >/dev/null
elif check_version gm4 1.4; then
have_gm4=yes;
else
echo "Couldn't find a new-enough version of 'm4', please install one!";
exit 1;

View File

@ -4266,3 +4266,14 @@ David May 23 2008
sched/
sched_config.C,h
sched_send.C
David May 23 2008
- client: if GUI RPC auth error, close the socket.
This prevents a DoS by sending <auth1> over and over,
filling the send buffer and eventually causing the client to block.
- Unix build: if m4 missing, check for gm4
_autosetup
client/
gui_rpc_server.C,h
gui_rpc_server_ops.C

View File

@ -66,6 +66,8 @@ GUI_RPC_CONN::GUI_RPC_CONN(int s):
auth_needed = false;
au_ss_state = AU_SS_INIT;
au_mgr_state = AU_MGR_INIT;
got_auth1 = false;
got_auth2 = false;
}
GUI_RPC_CONN::~GUI_RPC_CONN() {
@ -414,6 +416,12 @@ void GUI_RPC_CONN_SET::got_select(FDSET_GROUP& fg) {
if (FD_ISSET(gr->sock, &fg.read_fds)) {
retval = gr->handle_rpc();
if (retval) {
if (log_flags.guirpc_debug) {
msg_printf(NULL, MSG_INFO,
"[guirpc_debug] error %d from handler, closing socket\n",
retval
);
}
delete gr;
iter = gui_rpcs.erase(iter);
continue;
@ -425,7 +433,9 @@ void GUI_RPC_CONN_SET::got_select(FDSET_GROUP& fg) {
void GUI_RPC_CONN_SET::close() {
if (log_flags.guirpc_debug) {
msg_printf(NULL, MSG_INFO, "[guirpc_debug] closing GUI RPC socket %d\n", lsock);
msg_printf(NULL, MSG_INFO,
"[guirpc_debug] closing GUI RPC listening socket %d\n", lsock
);
}
if (lsock >= 0) {
boinc_close_socket(lsock);

View File

@ -42,6 +42,10 @@ public:
char nonce[256];
bool auth_needed;
// if true, don't allow operations other than authentication
bool got_auth1;
bool got_auth2;
// keep track of whether we've got the 2 authentication msgs;
// don't accept more than one of each (to prevent DoS)
bool is_local;
// connection is from local host
int au_ss_state;
@ -55,7 +59,7 @@ public:
~GUI_RPC_CONN();
int handle_rpc();
void handle_auth1(MIOFILE&);
void handle_auth2(char*, MIOFILE&);
int handle_auth2(char*, MIOFILE&);
void handle_get_project_config(char* buf, MIOFILE& fout);
void handle_get_project_config_poll(char*, MIOFILE& fout);
void handle_lookup_account(char* buf, MIOFILE& fout);

View File

@ -68,20 +68,21 @@ void GUI_RPC_CONN::handle_auth1(MIOFILE& fout) {
fout.printf("<nonce>%s</nonce>\n", nonce);
}
void GUI_RPC_CONN::handle_auth2(char* buf, MIOFILE& fout) {
int GUI_RPC_CONN::handle_auth2(char* buf, MIOFILE& fout) {
char nonce_hash[256], nonce_hash_correct[256], buf2[256];
if (!parse_str(buf, "<nonce_hash>", nonce_hash, 256)) {
auth_failure(fout);
return;
return ERR_AUTHENTICATOR;
}
sprintf(buf2, "%s%s", nonce, gstate.gui_rpcs.password);
md5_block((const unsigned char*)buf2, (int)strlen(buf2), nonce_hash_correct);
if (strcmp(nonce_hash, nonce_hash_correct)) {
auth_failure(fout);
return;
return ERR_AUTHENTICATOR;
}
fout.printf("<authorized/>\n");
auth_needed = false;
return 0;
}
// client passes its version, but ignore it for now
@ -985,7 +986,7 @@ static void handle_set_cc_config(char* buf, MIOFILE& fout) {
int GUI_RPC_CONN::handle_rpc() {
char request_msg[4096];
int n;
int n, retval=0;
MIOFILE mf;
MFILE m;
char* p;
@ -1011,12 +1012,16 @@ int GUI_RPC_CONN::handle_rpc() {
mf.printf("<boinc_gui_rpc_reply>\n");
if (match_tag(request_msg, "<auth1")) {
if (got_auth1) return ERR_AUTHENTICATOR;
handle_auth1(mf);
got_auth1 = true;
} else if (match_tag(request_msg, "<auth2")) {
handle_auth2(request_msg, mf);
if (!got_auth1 || got_auth2) return ERR_AUTHENTICATOR;
retval = handle_auth2(request_msg, mf);
got_auth2 = true;
} else if (auth_needed && !is_local) {
auth_failure(mf);
retval = ERR_AUTHENTICATOR;
// operations that require authentication only for non-local clients start here.
// Use this only for information that should be available to people
@ -1058,6 +1063,7 @@ int GUI_RPC_CONN::handle_rpc() {
} else if (auth_needed) {
auth_failure(mf);
retval = ERR_AUTHENTICATOR;
} else if (match_tag(request_msg, "<project_nomorework")) {
handle_project_op(request_msg, mf, "nomorework");
} else if (match_tag(request_msg, "<project_allowmorework")) {
@ -1183,7 +1189,6 @@ int GUI_RPC_CONN::handle_rpc() {
}
free(p);
}
return 0;
return retval;
}
const char *BOINC_RCSID_7bf15dcb49="$Id$";

View File

@ -32,6 +32,7 @@ function friendly_name($p) {
case 'powerpc64-unknown-linux-gnu': return 'Linux/PowerPC64';
case 'windows_x86_64': return 'Windows/x86_64';
case 'powerpc64-ps3-linux-gnu': return 'Playstation3/Linux';
case 'x86_64-unknown-linux-gnu': return null;
}
if (strstr($p, "fubar")) return null;
return $p;