Projet

Général

Profil

Télécharger (4,82 ko) Statistiques
| Branche: | Révision:

univnautes-tools / pfPorts / strongswan / files / patch-xauth_generic.c @ f10fac17

1
--- src/libcharon/plugins/xauth_generic/xauth_generic.c.orig	2014-02-12 09:23:58.000000000 +0100
2
+++ src/libcharon/plugins/xauth_generic/xauth_generic.c	2014-02-12 09:50:09.000000000 +0100
3
@@ -13,10 +13,15 @@
4
  * for more details.
5
  */
6
 
7
+#include <sys/types.h>
8
+#include <sys/wait.h>
9
+
10
 #include "xauth_generic.h"
11
 
12
 #include <daemon.h>
13
 #include <library.h>
14
+#include <unistd.h>
15
+#include <errno.h>
16
 
17
 typedef struct private_xauth_generic_t private_xauth_generic_t;
18
 
19
@@ -41,6 +46,103 @@
20
 	identification_t *peer;
21
 };
22
 
23
+/**
24
+ * Add/Append to the environment pointer name=value pair
25
+ */
26
+static char *
27
+name_value_pair(const char *name, char *value)
28
+{
29
+	char *envitem;
30
+
31
+        envitem = malloc(strlen(name) + 1 + strlen(value) + 1);
32
+        if (envitem == NULL) {
33
+                DBG1(DBG_IKE,
34
+                    "Cannot allocate memory.");
35
+                return NULL;
36
+        }
37
+        sprintf(envitem, "%s=%s", name, value);
38
+
39
+        return envitem;
40
+}
41
+
42
+/**
43
+ * Convert configuration attribute content to a null-terminated string
44
+ */
45
+static void attr2string(char *buf, size_t len, chunk_t chunk)
46
+{
47
+	if (chunk.len && chunk.len < len)
48
+	{
49
+		snprintf(buf, len, "%.*s", (int)chunk.len, chunk.ptr);
50
+	}
51
+}
52
+
53
+/**
54
+ * Authenticate a username/password using script
55
+ */
56
+static bool
57
+authenticate(char *service, chunk_t username, chunk_t password, char *authcfg)
58
+{
59
+	pid_t pid, rpid;
60
+	char *envp[4] = { NULL, NULL, NULL, NULL };
61
+	char *argv[3] = { NULL, NULL, NULL };
62
+	char user[128] = "", pass[128] = "";
63
+	int envc = 4;
64
+	int ret;
65
+
66
+	attr2string(user, sizeof(user), username);
67
+	attr2string(pass, sizeof(pass), password);
68
+
69
+	envp[0] = name_value_pair("username", user);
70
+	envp[1] = name_value_pair("password", pass);
71
+	envp[2] = name_value_pair("authcfg", authcfg);
72
+	envp[3] = NULL;
73
+
74
+	argv[0] = service;
75
+	argv[1] = service;
76
+	argv[2] = NULL;
77
+
78
+	pid = fork();
79
+	switch (pid) {
80
+	case 0:
81
+		execve(argv[0], argv, envp);
82
+		DBG1(DBG_IKE, "XAUTH-SCRIPT failed to execute script '%s'.", service);
83
+		 _exit (127);
84
+		break;
85
+	case -1:
86
+		ret = -1;
87
+		break;
88
+	default:
89
+		do {
90
+                        rpid = waitpid (pid, &ret, 0);
91
+                } while (rpid == -1 && errno == EINTR);
92
+                if (rpid != pid)
93
+                        ret = -1;
94
+
95
+		break;
96
+	}
97
+
98
+	if (WIFEXITED(ret)) {
99
+                if (WEXITSTATUS(ret) > 0)
100
+                        ret = -1;
101
+                else
102
+                        ret = 0;
103
+        }
104
+	if (ret == 0)
105
+		DBG1(DBG_IKE, "XAuth-SCRIPT succeeded for user '%s'.", user);
106
+	else
107
+		DBG1(DBG_IKE, "XAuth-SCRIPT failed for user '%s' with return status: %d.",
108
+			 user, ret);
109
+
110
+	if (envp[0] != NULL)
111
+		free(envp[0]);
112
+	if (envp[1] != NULL)
113
+		free(envp[1]);
114
+	if (envp[2] != NULL)
115
+		free(envp[2]);
116
+
117
+	return ret;
118
+}
119
+
120
 METHOD(xauth_method_t, initiate_peer, status_t,
121
 	private_xauth_generic_t *this, cp_payload_t **out)
122
 {
123
@@ -137,6 +239,7 @@
124
 	chunk_t user = chunk_empty, pass = chunk_empty;
125
 	status_t status = FAILED;
126
 	int tried = 0;
127
+	char *service, *authcfg;
128
 
129
 	enumerator = in->create_attribute_enumerator(in);
130
 	while (enumerator->enumerate(enumerator, &attr))
131
@@ -176,29 +279,45 @@
132
 		pass.len -= 1;
133
 	}
134
 
135
-	enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
136
-										SHARED_EAP, this->server, this->peer);
137
-	while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
138
-	{
139
-		if (chunk_equals(shared->get_key(shared), pass))
140
-		{
141
+	/* XXX: Maybe support even FCGI calling here? */
142
+	service = lib->settings->get_str(lib->settings,
143
+		"%s.plugins.xauth-generic.script", NULL, lib->ns);
144
+	if (service) {
145
+		authcfg = lib->settings->get_str(lib->settings,
146
+			"%s.plugins.xauth-generic.authcfg",
147
+			NULL, lib->ns);
148
+		if (!authenticate(service, user, pass, authcfg))
149
 			status = SUCCESS;
150
-			break;
151
+		else {
152
+			DBG1(DBG_IKE, "Could not authenticate with XAuth secrets for '%Y' - '%Y' ",
153
+				 this->server, this->peer);
154
 		}
155
-		tried++;
156
-	}
157
-	enumerator->destroy(enumerator);
158
-	if (status != SUCCESS)
159
-	{
160
-		if (!tried)
161
+	} else {
162
+
163
+		enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
164
+											SHARED_EAP, this->server, this->peer);
165
+		while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
166
 		{
167
-			DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'",
168
-				 this->server, this->peer);
169
+			if (chunk_equals(shared->get_key(shared), pass))
170
+			{
171
+				status = SUCCESS;
172
+				break;
173
+			}
174
+			tried++;
175
 		}
176
-		else
177
+		enumerator->destroy(enumerator);
178
+		if (status != SUCCESS)
179
 		{
180
-			DBG1(DBG_IKE, "none of %d found XAuth secrets for '%Y' - '%Y' "
181
-				 "matched", tried, this->server, this->peer);
182
+			if (!tried)
183
+			{
184
+				DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'",
185
+					 this->server, this->peer);
186
+			}
187
+			else
188
+			{
189
+				DBG1(DBG_IKE, "none of %d found XAuth secrets for '%Y' - '%Y' "
190
+					 "matched", tried, this->server, this->peer);
191
+			}
192
 		}
193
 	}
194
 	return status;
(3-3/4)