Annotation of embedaddon/strongswan/src/charon-nm/charon-nm.c, revision 1.1.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>