Annotation of embedaddon/strongswan/src/charon-nm/charon-nm.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2012 Tobias Brunner
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include <stdio.h>
        !            17: #include <syslog.h>
        !            18: #include <signal.h>
        !            19: #include <sys/types.h>
        !            20: #include <unistd.h>
        !            21: #include <errno.h>
        !            22: 
        !            23: #include <daemon.h>
        !            24: 
        !            25: #include <library.h>
        !            26: #include <utils/backtrace.h>
        !            27: #include <threading/thread.h>
        !            28: 
        !            29: #include <nm/nm_backend.h>
        !            30: 
        !            31: /**
        !            32:  * Default user and group
        !            33:  */
        !            34: #ifndef IPSEC_USER
        !            35: #define IPSEC_USER NULL
        !            36: #endif
        !            37: 
        !            38: #ifndef IPSEC_GROUP
        !            39: #define IPSEC_GROUP NULL
        !            40: #endif
        !            41: 
        !            42: /**
        !            43:  * Hook in library for debugging messages
        !            44:  */
        !            45: extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
        !            46: 
        !            47: /**
        !            48:  * Simple logging hook for library logs, using syslog output
        !            49:  */
        !            50: static void dbg_syslog(debug_t group, level_t level, char *fmt, ...)
        !            51: {
        !            52:        if (level <= 1)
        !            53:        {
        !            54:                char buffer[8192], groupstr[4];
        !            55:                va_list args;
        !            56: 
        !            57:                va_start(args, fmt);
        !            58:                /* write in memory buffer first */
        !            59:                vsnprintf(buffer, sizeof(buffer), fmt, args);
        !            60:                /* cache group name */
        !            61:                snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
        !            62:                syslog(LOG_DAEMON|LOG_INFO, "00[%s] %s", groupstr, buffer);
        !            63:                va_end(args);
        !            64:        }
        !            65: }
        !            66: 
        !            67: /**
        !            68:  * Run the daemon and handle unix signals
        !            69:  */
        !            70: static void run()
        !            71: {
        !            72:        sigset_t set;
        !            73: 
        !            74:        /* handle SIGINT and SIGTERM in this handler */
        !            75:        sigemptyset(&set);
        !            76:        sigaddset(&set, SIGINT);
        !            77:        sigaddset(&set, SIGTERM);
        !            78:        sigprocmask(SIG_BLOCK, &set, NULL);
        !            79: 
        !            80:        while (TRUE)
        !            81:        {
        !            82:                int sig;
        !            83: 
        !            84:                sig = sigwaitinfo(&set, NULL);
        !            85:                if (sig == -1)
        !            86:                {
        !            87:                        if (errno == EINTR)
        !            88:                        {       /* ignore signals we didn't wait for */
        !            89:                                continue;
        !            90:                        }
        !            91:                        DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(errno));
        !            92:                        return;
        !            93:                }
        !            94:                switch (sig)
        !            95:                {
        !            96:                        case SIGINT:
        !            97:                        {
        !            98:                                DBG1(DBG_DMN, "signal of type SIGINT received. Shutting down");
        !            99:                                charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
        !           100:                                return;
        !           101:                        }
        !           102:                        case SIGTERM:
        !           103:                        {
        !           104:                                DBG1(DBG_DMN, "signal of type SIGTERM received. Shutting down");
        !           105:                                charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
        !           106:                                return;
        !           107:                        }
        !           108:                }
        !           109:        }
        !           110: }
        !           111: 
        !           112: #ifndef DISABLE_SIGNAL_HANDLER
        !           113: /**
        !           114:  * Handle SIGSEGV/SIGILL signals raised by threads
        !           115:  */
        !           116: static void segv_handler(int signal)
        !           117: {
        !           118:        backtrace_t *backtrace;
        !           119: 
        !           120:        DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
        !           121:        backtrace = backtrace_create(2);
        !           122:        backtrace->log(backtrace, stderr, TRUE);
        !           123:        backtrace->destroy(backtrace);
        !           124: 
        !           125:        DBG1(DBG_DMN, "killing ourself, received critical signal");
        !           126:        abort();
        !           127: }
        !           128: #endif /* DISABLE_SIGNAL_HANDLER */
        !           129: 
        !           130: /**
        !           131:  * Lookup UID and GID
        !           132:  */
        !           133: static bool lookup_uid_gid()
        !           134: {
        !           135:        char *name;
        !           136: 
        !           137:        name = lib->settings->get_str(lib->settings, "charon-nm.user",
        !           138:                                                                  IPSEC_USER);
        !           139:        if (name && !lib->caps->resolve_uid(lib->caps, name))
        !           140:        {
        !           141:                return FALSE;
        !           142:        }
        !           143:        name = lib->settings->get_str(lib->settings, "charon-nm.group",
        !           144:                                                                  IPSEC_GROUP);
        !           145:        if (name && !lib->caps->resolve_gid(lib->caps, name))
        !           146:        {
        !           147:                return FALSE;
        !           148:        }
        !           149:        return TRUE;
        !           150: }
        !           151: 
        !           152: /**
        !           153:  * Main function, starts NetworkManager backend.
        !           154:  */
        !           155: int main(int argc, char *argv[])
        !           156: {
        !           157:        struct sigaction action;
        !           158:        int status = SS_RC_INITIALIZATION_FAILED;
        !           159: 
        !           160:        /* logging for library during initialization, as we have no bus yet */
        !           161:        dbg = dbg_syslog;
        !           162: 
        !           163:        /* LD causes a crash probably due to Glib */
        !           164:        setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
        !           165: 
        !           166:        /* initialize library */
        !           167:        if (!library_init(NULL, "charon-nm"))
        !           168:        {
        !           169:                library_deinit();
        !           170:                exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
        !           171:        }
        !           172: 
        !           173:        if (lib->integrity &&
        !           174:                !lib->integrity->check_file(lib->integrity, "charon-nm", argv[0]))
        !           175:        {
        !           176:                dbg_syslog(DBG_DMN, 1, "integrity check of charon-nm failed");
        !           177:                library_deinit();
        !           178:                exit(SS_RC_DAEMON_INTEGRITY);
        !           179:        }
        !           180: 
        !           181:        if (!libcharon_init())
        !           182:        {
        !           183:                dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm");
        !           184:                goto deinit;
        !           185:        }
        !           186: 
        !           187:        if (!lookup_uid_gid())
        !           188:        {
        !           189:                dbg_syslog(DBG_DMN, 1, "invalid uid/gid - aborting charon-nm");
        !           190:                goto deinit;
        !           191:        }
        !           192: 
        !           193:        /* make sure we log to the DAEMON facility by default */
        !           194:        lib->settings->set_int(lib->settings, "charon-nm.syslog.daemon.default",
        !           195:                lib->settings->get_int(lib->settings,
        !           196:                                                           "charon-nm.syslog.daemon.default", 1));
        !           197:        charon->load_loggers(charon);
        !           198: 
        !           199:        /* default to random ports to avoid conflicts with regular charon */
        !           200:        lib->settings->set_default_str(lib->settings, "charon-nm.port", "0");
        !           201:        lib->settings->set_default_str(lib->settings, "charon-nm.port_nat_t", "0");
        !           202: 
        !           203:        DBG1(DBG_DMN, "Starting charon NetworkManager backend (strongSwan "VERSION")");
        !           204:        if (lib->integrity)
        !           205:        {
        !           206:                DBG1(DBG_DMN, "integrity tests enabled:");
        !           207:                DBG1(DBG_DMN, "lib    'libstrongswan': passed file and segment integrity tests");
        !           208:                DBG1(DBG_DMN, "lib    'libcharon': passed file and segment integrity tests");
        !           209:                DBG1(DBG_DMN, "daemon 'charon-nm': passed file integrity test");
        !           210:        }
        !           211: 
        !           212:        /* register NM backend to be loaded with plugins */
        !           213:        nm_backend_register();
        !           214: 
        !           215:        /* initialize daemon */
        !           216:        if (!charon->initialize(charon,
        !           217:                        lib->settings->get_str(lib->settings, "charon-nm.load", PLUGINS)))
        !           218:        {
        !           219:                DBG1(DBG_DMN, "initialization failed - aborting charon-nm");
        !           220:                goto deinit;
        !           221:        }
        !           222:        lib->plugins->status(lib->plugins, LEVEL_CTRL);
        !           223: 
        !           224:        if (!lib->caps->drop(lib->caps))
        !           225:        {
        !           226:                DBG1(DBG_DMN, "capability dropping failed - aborting charon-nm");
        !           227:                goto deinit;
        !           228:        }
        !           229: 
        !           230:        /* add handler for fatal signals,
        !           231:         * INT and TERM are handled by sigwaitinfo() in run() */
        !           232:        action.sa_flags = 0;
        !           233:        sigemptyset(&action.sa_mask);
        !           234:        sigaddset(&action.sa_mask, SIGINT);
        !           235:        sigaddset(&action.sa_mask, SIGTERM);
        !           236: 
        !           237:        /* optionally let the external system handle fatal signals */
        !           238: #ifndef DISABLE_SIGNAL_HANDLER
        !           239:        action.sa_handler = segv_handler;
        !           240:        sigaction(SIGSEGV, &action, NULL);
        !           241:        sigaction(SIGILL, &action, NULL);
        !           242:        sigaction(SIGBUS, &action, NULL);
        !           243: #endif /* DISABLE_SIGNAL_HANDLER */
        !           244: 
        !           245:        action.sa_handler = SIG_IGN;
        !           246:        sigaction(SIGPIPE, &action, NULL);
        !           247: 
        !           248:        pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
        !           249: 
        !           250:        /* start daemon (i.e. the threads in the thread-pool) */
        !           251:        charon->start(charon);
        !           252: 
        !           253:        /* main thread goes to run loop */
        !           254:        run();
        !           255: 
        !           256:        status = 0;
        !           257: 
        !           258: deinit:
        !           259:        libcharon_deinit();
        !           260:        library_deinit();
        !           261:        return status;
        !           262: }
        !           263: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>