mirror of https://github.com/BOINC/boinc.git
- 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:
parent
49eb1246cf
commit
8befa29f81
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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$";
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue