Annotation of embedaddon/strongswan/src/libcharon/plugins/ext_auth/ext_auth_listener.c, revision 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>