summaryrefslogtreecommitdiffstats
path: root/ipa-client
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2011-10-20 11:29:26 -0400
committerRob Crittenden <rcritten@redhat.com>2011-12-12 17:36:45 -0500
commit2d6eeb205e196cc6556f832555e74968619c0f1e (patch)
tree181ae3111506bd2f6dc9eda172f262b14e613e00 /ipa-client
parentda4b4fc4d9ef42f8ca46d5b5f405b93ba84f07d0 (diff)
downloadfreeipa-2d6eeb205e196cc6556f832555e74968619c0f1e.tar.gz
freeipa-2d6eeb205e196cc6556f832555e74968619c0f1e.tar.xz
freeipa-2d6eeb205e196cc6556f832555e74968619c0f1e.zip
Require an HTTP Referer header in the server. Send one in ipa tools.
This is to prevent a Cross-Site Request Forgery (CSRF) attack where a rogue server tricks a user who was logged into the FreeIPA management interface into visiting a specially-crafted URL where the attacker could perform FreeIPA oonfiguration changes with the privileges of the logged-in user. https://bugzilla.redhat.com/show_bug.cgi?id=747710
Diffstat (limited to 'ipa-client')
-rwxr-xr-xipa-client/ipa-install/ipa-client-install4
-rw-r--r--ipa-client/ipa-join.c41
2 files changed, 41 insertions, 4 deletions
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index e763d07a7..8e945ce90 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -264,6 +264,9 @@ def uninstall(options, env, quiet=False):
if not options.on_master and os.path.exists('/etc/ipa/default.conf'):
emit_quiet(quiet, "Unenrolling client from IPA server")
join_args = ["/usr/sbin/ipa-join", "--unenroll", "-h", hostname]
+ if options.debug:
+ join_args.append("-d")
+ env['XMLRPC_TRACE_CURL'] = 'yes'
(stdout, stderr, returncode) = run(join_args, raiseonerr=False, env=env)
if returncode != 0:
emit_quiet(quiet, "Unenrolling host failed: %s" % stderr)
@@ -1037,6 +1040,7 @@ def install(options, env, fstore, statestore):
join_args = ["/usr/sbin/ipa-join", "-s", cli_server, "-b", realm_to_suffix(cli_realm)]
if options.debug:
join_args.append("-d")
+ env['XMLRPC_TRACE_CURL'] = 'yes'
if options.hostname:
join_args.append("-h")
join_args.append(options.hostname)
diff --git a/ipa-client/ipa-join.c b/ipa-client/ipa-join.c
index 6a8523135..c174e2c15 100644
--- a/ipa-client/ipa-join.c
+++ b/ipa-client/ipa-join.c
@@ -19,6 +19,7 @@
#define _GNU_SOURCE
+#include "config.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
@@ -40,7 +41,6 @@
#include "ipa-client-common.h"
#define NAME "ipa-join"
-#define VERSION "1.0"
#define JOIN_OID "2.16.840.1.113730.3.8.10.3"
@@ -119,12 +119,32 @@ static int check_perms(const char *keytab)
}
/*
+ * There is no API in xmlrpc-c to set arbitrary headers but we can fake it
+ * by using a specially-crafted User-Agent string.
+ *
+ * The caller is responsible for freeing the return value.
+ */
+char *
+set_user_agent(const char *ipaserver) {
+ int ret;
+ char *user_agent = NULL;
+
+ ret = asprintf(&user_agent, "%s/%s\r\nReferer: https://%s/ipa/xml\r\nX-Original-User-Agent:", NAME, VERSION, ipaserver);
+ if (ret == -1) {
+ fprintf(stderr, _("Out of memory!"));
+ return NULL;
+ }
+ return user_agent;
+}
+
+/*
* Make an XML-RPC call to methodName. This uses the curl client to make
* a connection over SSL using the CA cert that should have been installed
* by ipa-client-install.
*/
static void
-callRPC(xmlrpc_env * const envP,
+callRPC(char * user_agent,
+ xmlrpc_env * const envP,
xmlrpc_server_info * const serverInfoP,
const char * const methodName,
xmlrpc_value * const paramArrayP,
@@ -149,6 +169,7 @@ callRPC(xmlrpc_env * const envP,
curlXportParmsP->no_ssl_verifypeer = 1;
curlXportParmsP->no_ssl_verifyhost = 1;
curlXportParmsP->cainfo = "/etc/ipa/ca.crt";
+ curlXportParmsP->user_agent = user_agent;
/* Enable GSSAPI credentials delegation */
curlXportParmsP->gssapi_delegation = 1;
@@ -523,6 +544,7 @@ join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **pri
xmlrpc_value *hostdnP = NULL;
const char *krblastpwdchange = NULL;
char * url = NULL;
+ char * user_agent = NULL;
int rval = 0;
int ret;
@@ -575,7 +597,11 @@ join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **pri
xmlrpc_array_append_item(&env, paramArrayP, optionsP);
xmlrpc_DECREF(optionsP);
- callRPC(&env, serverInfoP, "join", paramArrayP, &resultP);
+ if ((user_agent = set_user_agent(ipaserver)) == NULL) {
+ rval = 3;
+ goto cleanup;
+ }
+ callRPC(user_agent, &env, serverInfoP, "join", paramArrayP, &resultP);
if (handle_fault(&env)) {
rval = 17;
goto cleanup_xmlrpc;
@@ -640,6 +666,7 @@ cleanup:
if (resultP) xmlrpc_DECREF(resultP);
cleanup_xmlrpc:
+ free(user_agent);
free(url);
free((char *)krblastpwdchange);
xmlrpc_env_clean(&env);
@@ -676,6 +703,7 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, int
xmlrpc_server_info * serverInfoP = NULL;
xmlrpc_value *princP = NULL;
char * url = NULL;
+ char * user_agent = NULL;
if (server) {
ipaserver = strdup(server);
@@ -817,7 +845,11 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, int
xmlrpc_array_append_item(&env, paramArrayP, argArrayP);
xmlrpc_DECREF(paramP);
- callRPC(&env, serverInfoP, "host_disable", paramArrayP, &resultP);
+ if ((user_agent = set_user_agent(ipaserver)) == NULL) {
+ rval = 3;
+ goto cleanup;
+ }
+ callRPC(user_agent, &env, serverInfoP, "host_disable", paramArrayP, &resultP);
if (handle_fault(&env)) {
rval = 17;
goto cleanup;
@@ -845,6 +877,7 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, int
cleanup:
+ free(user_agent);
if (keytab) krb5_kt_close(krbctx, keytab);
free((char *)principal);
free((char *)ipaserver);