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>