Annotation of embedaddon/strongswan/src/libcharon/plugins/ext_auth/ext_auth_listener.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (c) 2014 Vyronas Tsingaras (vtsingaras@it.auth.gr)
3: * Copyright (C) 2014 Martin Willi
4: * Copyright (C) 2014 revosec AG
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
24:
25: /* for vasprintf() */
26: #define _GNU_SOURCE
27: #include "ext_auth_listener.h"
28:
29: #include <daemon.h>
30: #include <utils/process.h>
31:
32: #include <stdio.h>
33: #include <unistd.h>
34:
35: typedef struct private_ext_auth_listener_t private_ext_auth_listener_t;
36:
37: /**
38: * Private data of an ext_auth_listener_t object.
39: */
40: struct private_ext_auth_listener_t {
41:
42: /**
43: * Public ext_auth_listener_listener_t interface.
44: */
45: ext_auth_listener_t public;
46:
47: /**
48: * Path to authorization program
49: */
50: char *script;
51: };
52:
53: /**
54: * Allocate and push a format string to the environment
55: */
56: static bool push_env(char *envp[], u_int count, char *fmt, ...)
57: {
58: int i = 0;
59: char *str;
60: va_list args;
61:
62: while (envp[i])
63: {
64: if (++i + 1 >= count)
65: {
66: return FALSE;
67: }
68: }
69: va_start(args, fmt);
70: if (vasprintf(&str, fmt, args) >= 0)
71: {
72: envp[i] = str;
73: }
74: va_end(args);
75: return envp[i] != NULL;
76: }
77:
78: /**
79: * Free all allocated environment strings
80: */
81: static void free_env(char *envp[])
82: {
83: int i;
84:
85: for (i = 0; envp[i]; i++)
86: {
87: free(envp[i]);
88: }
89: }
90:
91: METHOD(listener_t, authorize, bool,
92: private_ext_auth_listener_t *this, ike_sa_t *ike_sa,
93: bool final, bool *success)
94: {
95: if (final)
96: {
97: FILE *shell;
98: process_t *process;
99: char *envp[32] = {};
100: int out, retval;
101:
102: *success = FALSE;
103:
104: push_env(envp, countof(envp), "IKE_UNIQUE_ID=%u",
105: ike_sa->get_unique_id(ike_sa));
106: push_env(envp, countof(envp), "IKE_NAME=%s",
107: ike_sa->get_name(ike_sa));
108:
109: push_env(envp, countof(envp), "IKE_LOCAL_HOST=%H",
110: ike_sa->get_my_host(ike_sa));
111: push_env(envp, countof(envp), "IKE_REMOTE_HOST=%H",
112: ike_sa->get_other_host(ike_sa));
113:
114: push_env(envp, countof(envp), "IKE_LOCAL_ID=%Y",
115: ike_sa->get_my_id(ike_sa));
116: push_env(envp, countof(envp), "IKE_REMOTE_ID=%Y",
117: ike_sa->get_other_id(ike_sa));
118:
119: if (ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED) ||
120: ike_sa->has_condition(ike_sa, COND_XAUTH_AUTHENTICATED))
121: {
122: push_env(envp, countof(envp), "IKE_REMOTE_EAP_ID=%Y",
123: ike_sa->get_other_eap_id(ike_sa));
124: }
125:
126: process = process_start_shell(envp, NULL, &out, NULL,
127: "2>&1 %s", this->script);
128: if (process)
129: {
130: shell = fdopen(out, "r");
131: if (shell)
132: {
133: while (TRUE)
134: {
135: char resp[128], *e;
136:
137: if (fgets(resp, sizeof(resp), shell) == NULL)
138: {
139: if (ferror(shell))
140: {
141: DBG1(DBG_CFG, "error reading from ext-auth script");
142: }
143: break;
144: }
145: else
146: {
147: e = resp + strlen(resp);
148: if (e > resp && e[-1] == '\n')
149: {
150: e[-1] = '\0';
151: }
152: DBG1(DBG_CHD, "ext-auth: %s", resp);
153: }
154: }
155: fclose(shell);
156: }
157: else
158: {
159: close(out);
160: }
161: if (process->wait(process, &retval))
162: {
163: if (retval == EXIT_SUCCESS)
164: {
165: *success = TRUE;
166: }
167: else
168: {
169: DBG1(DBG_CFG, "rejecting IKE_SA for ext-auth result: %d",
170: retval);
171: }
172: }
173: }
174: free_env(envp);
175: }
176: return TRUE;
177: }
178:
179: METHOD(ext_auth_listener_t, destroy, void,
180: private_ext_auth_listener_t *this)
181: {
182: free(this);
183: }
184:
185: /**
186: * See header
187: */
188: ext_auth_listener_t *ext_auth_listener_create(char *script)
189: {
190: private_ext_auth_listener_t *this;
191:
192: INIT(this,
193: .public = {
194: .listener = {
195: .authorize = _authorize,
196: },
197: .destroy = _destroy,
198: },
199: .script = script,
200: );
201:
202: return &this->public;
203: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>