nutcpc.c

Go to the documentation of this file.
00001 /*
00002  ** Copyright 2004-2008 - INL
00003  ** Written by Eric Leblond <eric.leblond@inl.fr>
00004  **            Vincent Deffontaines <vincent@inl.fr>
00005  ** INL http://www.inl.fr/
00006  **
00007  ** $Id: nutcpc.c 5287 2008-11-21 16:09:26Z pollux $
00008  **
00009  ** This program is free software; you can redistribute it and/or modify
00010  ** it under the terms of the GNU General Public License as published by
00011  ** the Free Software Foundation, version 3 of the License.
00012  **
00013  ** This program is distributed in the hope that it will be useful,
00014  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  ** GNU General Public License for more details.
00017  **
00018  ** You should have received a copy of the GNU General Public License
00019  ** along with this program; if not, write to the Free Software
00020  ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 /* Enable GNU extensions: getline() from stdio.h */
00024 #include "nufw_source.h"
00025 
00026 #include <config.h>
00027 #include "../lib/nuclient.h"
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <errno.h>
00033 #include <locale.h>
00034 #include <sys/resource.h>       /* setrlimit() */
00035 #include <langinfo.h>
00036 #include <stdarg.h>
00037 #include <signal.h>
00038 #include <sys/ioctl.h>
00039 #include <sys/stat.h>   /* mkdir() */
00040 #include <sys/types.h>  /* mkdir() */
00041 #include <termios.h>    /* tcgetattr() */
00042 #include "proto.h"
00043 #include "security.h"
00044 #include "debug.h"
00045 #define NUTCPC_VERSION PACKAGE_VERSION " $Revision: 5287 $"
00046 
00047 #ifdef FREEBSD
00048 #include <sys/syslimits.h>      /* PATH_MAX */
00049 #include <readpassphrase.h>
00050 #endif
00051 
00052 #define MAX_RETRY_TIME 30
00053 
00054 #include <nubase.h>
00055 #include <nussl.h>
00056 
00057 struct termios orig;
00058 nuauth_session_t *session = NULL;
00059 nuclient_error_t *err = NULL;
00060 struct sigaction old_sigterm;
00061 struct sigaction old_sigint;
00062 int forced_reconnect = 0;
00063 int connected;
00064 static int suppress_ca_warning = 0;
00065 static int suppress_fqdn_verif = 0;
00066 
00067 void panic(const char *fmt, ...)
00068 #ifdef __GNUC__
00069         __attribute__((__format__(printf,1,2)))
00070 #endif
00071 ;
00072 
00073 typedef struct {
00074         char port[10];          
00075         unsigned long interval; 
00076         unsigned char donotuselock;     
00077         char srv_addr[512];     
00078         char password[100];
00079         char nuauthdn[512];
00080         unsigned char debug_mode;       
00081         int tempo;              
00082         char *certfile;
00083         char *keyfile;
00084         char *cafile;
00085         char *crlfile;
00086         char *pkcs12file;
00087         char *pkcs12password;
00088         char *krb5_service;
00089 } nutcpc_context_t;
00090 
00095 void panic(const char *fmt, ...)
00096 {
00097         va_list args;
00098         va_start(args, fmt);
00099         printf("\n");
00100         printf("Fatal error: ");
00101         vprintf(fmt, args);
00102         printf("\n");
00103         fflush(stdout);
00104         exit(EXIT_FAILURE);
00105         va_end(args);
00106 }
00107 
00111 char *compute_run_pid()
00112 {
00113         char path_dir[254];
00114         char *home = nu_get_home_dir();
00115         if (home == NULL)
00116                 return NULL;
00117         secure_snprintf(path_dir, sizeof(path_dir), "%s/.nufw", home);
00118         if (access(path_dir, R_OK) != 0) {
00119                 printf("Creating directory \"%s\"\n", path_dir);
00120                 if (mkdir(path_dir, S_IRWXU) != 0) {
00121                         printf("Could not create directory \"%s\" (%s)\n", path_dir, strerror(errno));
00122                 }
00123         }
00124         secure_snprintf(path_dir, sizeof(path_dir), "%s/.nufw/nutcpc", home);
00125         free(home);
00126         return strdup(path_dir);
00127 }
00128 
00132 int test_nutcpc(pid_t *pid)
00133 {
00134         FILE *fd;
00135         int ok = EXIT_FAILURE;
00136         char *runpid = compute_run_pid();
00137 
00138         if (runpid) {
00139                 fd = fopen(runpid, "r");
00140                 if (fd) {
00141                         fscanf(fd, "%d", pid);
00142                         fclose(fd);
00144                         ok = EXIT_SUCCESS;
00145                 }
00146                 free(runpid);
00147         }
00148         return ok;
00149 }
00150 
00157 void kill_nutcpc()
00158 {
00159         pid_t pid;
00160 
00161         if (test_nutcpc(&pid) == EXIT_SUCCESS) {
00162                 int ret;
00163                 char *runpid = compute_run_pid();
00164                 ret = kill(pid, SIGTERM);
00165                 if (ret == 0) {
00166                         printf("nutcpc process killed (pid %lu)\n",
00167                                         (unsigned long) pid);
00168                         unlink(runpid);
00169                         free(runpid);
00170                         exit(EXIT_SUCCESS);
00171                 } else {
00172                         switch (errno) {
00173                                 case ESRCH:
00174                                         printf("Process does not exist: removing pid file\n");
00175                                         unlink(runpid);
00176                                         break;
00177                                 case EINVAL:
00178                                 case EPERM:
00179                                 default:
00180                                         printf("Bad return from kill\n");
00181                         }
00182                         free(runpid);
00183                         exit(EXIT_FAILURE);
00184                 }
00185         } else {
00186                 printf("No nutcpc seems to be running\n");
00187                 exit(EXIT_FAILURE);
00188         }
00189         exit(EXIT_SUCCESS);
00190 }
00191 
00200 void leave_client()
00201 {
00202         char *runpid;
00203         struct termios term;
00204 
00205         /* restore ECHO mode */
00206         if (tcgetattr(fileno(stdin), &term) == 0) {
00207                 term.c_lflag |= ECHO;
00208                 (void) tcsetattr(fileno(stdin), TCSAFLUSH, &term);
00209         }
00210 
00211         if (session) {
00212                 nu_client_delete(session);
00213         }
00214 
00215         runpid = compute_run_pid();
00216         if (runpid != NULL) {
00217                 unlink(runpid);
00218                 free(runpid);
00219         }
00220         nu_client_global_deinit();
00221         nu_client_error_destroy(err);
00222 }
00223 
00230 void exit_clean()
00231 {
00232         /* reinstall old signal handlers */
00233         (void) sigaction(SIGINT, &old_sigint, NULL);
00234         (void) sigaction(SIGTERM, &old_sigterm, NULL);
00235 
00236         /* quit nutcpc */
00237         printf("\nQuit client\n");
00238         leave_client();
00239         exit(EXIT_SUCCESS);
00240 }
00241 
00242 #ifdef FREEBSD
00243 ssize_t getline(char **lineptr, size_t * n, FILE * stream)
00244 {
00245         char *line;
00246         size_t len;
00247 
00248         /* call fgetln(): read line from stdin */
00249         line = fgetln(stream, &len);
00250         if (!line)
00251                 return -1;
00252 
00253         /* buffer need to grow up? */
00254         if (len >= *n) {
00255                 char *tmp = realloc(*lineptr, len + 1);
00256                 if (tmp == NULL) {
00257                         printf("Not enough memory\n");
00258                         return -1;
00259                 }
00260                 *lineptr = tmp;
00261                 *n = len + 1;
00262         }
00263         memcpy(*lineptr, line, len);
00264         (*lineptr)[len] = 0;
00265         return len;
00266 }
00267 #endif
00268 
00269 #ifndef FREEBSD
00270 
00278 ssize_t my_getpass(char **lineptr, size_t * linelen)
00279 {
00280         struct termios new;
00281         int nread;
00282 
00283         /* Turn echoing off and fail if we can't. */
00284         if (tcgetattr(fileno(stdin), &orig) != 0)
00285                 return -1;
00286         new = orig;
00287         new.c_lflag &= ~ECHO;
00288         if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0)
00289                 return -1;
00290 
00291         /* Read the password. */
00292         nread = getline(lineptr, linelen, stdin);
00293 
00294         /* Restore terminal. */
00295         (void) tcsetattr(fileno(stdin), TCSAFLUSH, &orig);
00296 
00297         /* remove new line if needed */
00298         if (0 < nread) {
00299                 char *line = *lineptr;
00300                 if (line[nread - 1] == '\n') {
00301                         line[nread - 1] = '\0';
00302                         nread--;
00303                 }
00304         }
00305         printf("\n");
00306         return nread;
00307 }
00308 #endif
00309 
00316 char *get_password()
00317 {
00318         size_t password_size = 32;
00319         char *new_pass;
00320         char *question = "Enter password: ";
00321 #ifdef FREEBSD
00322         char *ret;
00323 #else
00324         int ret;
00325 #endif
00326 
00327         new_pass = (char *) calloc(password_size, sizeof(char));
00328 #ifdef FREEBSD
00329         ret =
00330             readpassphrase(question, new_pass, password_size,
00331                            RPP_REQUIRE_TTY);
00332         if (ret == NULL) {
00333                 fprintf(stderr, "unable to read passphrase");
00334         }
00335 #else
00336         printf("%s", question);
00337         ret = my_getpass(&new_pass, &password_size);
00338         if (ret < 0) {
00339                 free(new_pass);
00340                 printf("Problem when getting password\n");
00341                 return NULL;
00342         }
00343 #endif
00344         return new_pass;
00345 }
00346 
00353 char *get_username()
00354 {
00355         char *username;
00356         int nread;
00357         size_t username_size = 32;
00358 
00359         printf("Enter username: ");
00360         username = (char *) calloc(username_size, sizeof(char));
00361         nread = getline(&username, &username_size, stdin);
00362         if (nread < 0) {
00363                 free(username);
00364                 printf("Problem when reading username\n");
00365                 return NULL;
00366         }
00367         if (0 < nread && username[nread - 1] == '\n') {
00368                 username[nread - 1] = 0;
00369         }
00370         return username;
00371 }
00372 
00376 static void usage(void)
00377 {
00378         fprintf(stderr, "usage: nutcpc -U username -H host\n");
00379         fprintf(stderr, "\n");
00380         fprintf(stderr, "Options:\n");
00381         fprintf(stderr, "  -k: kill active client\n");
00382         fprintf(stderr, "  -c: check if there is an active client\n");
00383         fprintf(stderr, "  -l: don't create lock file\n");
00384         fprintf(stderr, "  -V: display version\n");
00385         fprintf(stderr, "\n");
00386         fprintf(stderr, "Certificate options:\n");
00387         fprintf(stderr, "  -C CERTFILE: PEM certificate filename\n");
00388         fprintf(stderr, "  -A AUTHFILE: PEM authority certificate filename\n");
00389         fprintf(stderr, "  -K KEYFILE:  PEM RSA private key filename\n");
00390         fprintf(stderr, "  -S PKCS12FILE: PKCS12 key/certificate filename\n");
00391         fprintf(stderr, "  -W PKCS12PASS: PKCS12 password\n");
00392         fprintf(stderr, "  -R CRLFILE: crl filename\n");
00393         fprintf(stderr, "  -Q: suppress warning if no certificate authority is configured\n");
00394         fprintf(stderr, "  -N: suppress error if server FQDN does not match certificate CN.\n");
00395         fprintf(stderr, "\n");
00396         fprintf(stderr, "SASL options:\n");
00397         fprintf(stderr, "  -Z SERVICE: Kerberos service name (nuauth)\n");
00398         fprintf(stderr, "\n");
00399         fprintf(stderr, "Other options:\n");
00400         fprintf(stderr, "  -p PORT: nuauth port number\n");
00401         fprintf(stderr, "  -a AUTH_DN: authentication domain name\n");
00402         fprintf(stderr, "  -I INTERVAL: check interval in milliseconds\n");
00403         fprintf(stderr, "  -q: do not display running nutcpc options on \"ps\"\n");
00404         fprintf(stderr, "  -P PASSWORD: specify password (only for debug purpose)\n");
00405         fprintf(stderr, "  -d: debug mode (don't go to foreground, daemon)\n");
00406         fprintf(stderr, "\n");
00407         exit(EXIT_FAILURE);
00408 }
00409 
00410 void process_hup(int signum)
00411 {
00412         forced_reconnect = 1;
00413         nu_client_reset(session);
00414         connected = 0;
00415 }
00416 
00422 void install_signals()
00423 {
00424         struct sigaction action;
00425         action.sa_handler = exit_clean;
00426         sigemptyset(&(action.sa_mask));
00427         action.sa_flags = 0;
00428 
00429         /* install handlers */
00430         if (sigaction(SIGINT, &action, &old_sigint) != 0) {
00431                 fprintf(stderr, "Unable to install SIGINT signal handler!\n");
00432                 exit(EXIT_FAILURE);
00433         }
00434         if (sigaction(SIGTERM, &action, &old_sigterm) != 0) {
00435                 fprintf(stderr, "Unable to install SIGTERM signal handler!\n");
00436                 exit(EXIT_FAILURE);
00437         }
00438         memset(&action, 0, sizeof(action));
00439         action.sa_handler = &process_hup;
00440         action.sa_flags = SIGHUP;
00441 
00442         if (sigaction(SIGHUP, &action, NULL) != 0)
00443         {
00444                 fprintf(stderr, "Warning : Unable to install SIGHUP signal handler!\n");
00445         }
00446 }
00447 
00451 void daemonize_process(nutcpc_context_t * context, char *runpid)
00452 {
00453         pid_t p;
00454 
00455         /* 1st fork */
00456         p = fork();
00457         if (p < 0) {
00458                 fprintf(stderr, "nutcpc: fork failure: %s\n",
00459                         strerror(errno));
00460                 exit(EXIT_FAILURE);
00461         }
00462 
00463         /* kill 1st process (keep 2nd) */
00464         if (p != 0) {
00465                 exit(0);
00466         }
00467 
00468         /* 2nd fork */
00469         p = fork();
00470         if (p < 0) {
00471                 fprintf(stderr, "nutcpc: fork falure: %s\n",
00472                         strerror(errno));
00473                 exit(EXIT_FAILURE);
00474         }
00475 
00476         /* kill 2nd process (keep 3rd) */
00477         if (p != 0) {
00478                 fprintf(stderr, "nutcpc started (pid %d)\n", (int) p);
00479                 if (context->donotuselock == 0) {
00480                         FILE *RunD;
00481                         RunD = fopen(runpid, "w");
00482                         free(runpid);
00483                         fprintf(RunD, "%d", p);
00484                         fclose(RunD);
00485                 }
00486                 exit(EXIT_SUCCESS);
00487         }
00488 
00489         /* Fix process user identifier, close stdin, stdout, stderr,
00490          * set currente directory to root directory */
00491         setsid();
00492         (void) chdir("/");
00493         ioctl(STDIN_FILENO, TIOCNOTTY, NULL);
00494         (void) close(STDIN_FILENO);
00495         (void) close(STDOUT_FILENO);
00496         (void) close(STDERR_FILENO);
00497         setpgid(0, 0);
00498 }
00499 
00500 void wipe(void *data, size_t datalen)
00501 {
00502         memset(data, 0, datalen);
00503 }
00504 
00509 void display_cert(nuauth_session_t* session)
00510 {
00511         char* infos = nu_client_get_cert_infos(session);
00512         printf("User certificate:\n%s\n", infos ? infos : "None");
00513         free(infos);
00514         infos = nu_client_get_server_cert_infos(session);
00515         printf("Server certificate:\n%s\n", infos ? infos : "None");
00516         free(infos);
00517 }
00518 
00519 
00525 nuauth_session_t *do_connect(nutcpc_context_t * context, char *username)
00526 {
00527         nuauth_session_t *session;
00528 
00529         session = nu_client_new_callback(get_username, get_password, 1, err);
00530         if (session == NULL) {
00531                 printf("Problem during session callback init\n");
00532                 return NULL;
00533         }
00534 
00535         if (username) {
00536                 nu_client_set_username(session, username);
00537                 free(username);
00538         }
00539         if (context->password[0] != 0) {
00540                 nu_client_set_password(session, context->password);
00541         }
00542 
00543         nu_client_set_debug(session, context->debug_mode);
00544 
00545         /* Set hostname from libnuclient if it wasn't specified by the user */
00546         if(*context->port == '\0')
00547         {
00548                 if(nu_client_default_port())
00549                         SECURE_STRNCPY(context->port, nu_client_default_port(),
00550                                sizeof(context->port));
00551                 else
00552                         SECURE_STRNCPY(context->port, USERPCKT_SERVICE,
00553                                        sizeof(context->port));
00554         }
00555 
00556         if(*context->srv_addr == '\0')
00557         {
00558                 if(nu_client_default_hostname())
00559                         SECURE_STRNCPY(context->srv_addr, nu_client_default_hostname(),
00560                                sizeof(context->srv_addr));
00561                 else
00562                         SECURE_STRNCPY(context->srv_addr, NUAUTH_IP,
00563                                        sizeof(context->srv_addr));
00564         }
00565 
00566         if (context->pkcs12file) {
00567                 if (!nu_client_set_pkcs12(session, context->pkcs12file, context->pkcs12password, err)) {
00568                         goto init_failed;
00569                 }
00570         }
00571         else {
00572                 if (!nu_client_set_key(session, context->keyfile, context->certfile, err)) {
00573                         goto init_failed;
00574                 }
00575         }
00576 
00577         if (!nu_client_set_ca(session, context->cafile, err)) {
00578                 goto init_failed;
00579         }
00580 
00581         nu_client_set_ca_suppress_warning(session,suppress_ca_warning);
00582         if (suppress_fqdn_verif)
00583                 nu_client_set_fqdn_suppress_verif(session, 1);
00584 
00585         if (context->nuauthdn) {
00586                 if (!nu_client_set_nuauth_cert_dn(session,
00587                                                   context->nuauthdn,
00588                                                   err)) {
00589                         goto init_failed;
00590                 }
00591         }
00592 
00593         if (!context->crlfile)
00594                 context->crlfile = (char *)nu_client_default_tls_crl();
00595         if (context->crlfile) {
00596                 if (!nu_client_set_crlfile(session, context->crlfile, err)) {
00597                         goto init_failed;
00598                 }
00599         }
00600 
00601         if (context->krb5_service) {
00602                 if (!nu_client_set_krb5_service(session, context->krb5_service)) {
00603                         nu_client_delete(session);
00604                         fprintf(stderr, "Unable to setup Kerberos5 service\n");
00605                         return NULL;
00606                 }
00607         }
00608 
00609         if (!nu_client_connect(session, context->srv_addr, context->port, err)) {
00610                 goto init_failed;
00611         }
00612         return session;
00613 init_failed:
00614 
00615         printf("Initialization error: %s\n", nu_client_strerror(session, err));
00616         nu_client_delete(session);
00617         return NULL;
00618 }
00619 
00623 void main_loop(nutcpc_context_t * context)
00624 {
00625         int connected = 1;
00626         int ret;
00627         for (;;) {
00628                 if (!connected) {
00629                         if (forced_reconnect == 0) {
00630                                 usleep((unsigned long) context->tempo * 1000000);
00631                         } else {
00632                                 context->tempo = 1;
00633                                 forced_reconnect = 0;
00634                         }
00635                         if (context->tempo < MAX_RETRY_TIME) {
00636                                 context->tempo *= 2;
00637                         }
00638 
00639                         /* try to reconnect to nuauth */
00640                         if (nu_client_connect
00641                                         (session, context->srv_addr, context->port,
00642                                          err) != 0) {
00643                                 connected = 1;
00644                                 context->tempo = 1;     /* second */
00645                         } else {
00646                                 printf("Reconnection error: %s\n",
00647                                                 nu_client_strerror(session, err));
00648                                 nu_client_reset(session);
00649                         }
00650                 } else {
00651                         forced_reconnect = 0;
00652                         ret = nu_client_check(session, err);
00653                         if (ret < 0) {
00654                                 /* on error: reset the session */
00655                                 nu_client_reset(session);
00656                                 connected = 0;
00657                                 printf("%s\n", nu_client_strerror(session, err));
00658                         }
00659                 }
00660         }
00661 }
00662 
00669 char* copy_filename(char* name)
00670 {
00671         char cwd[PATH_MAX];
00672         char buffer[PATH_MAX];
00673         int ok;
00674         char* ret;
00675         if (name[0] != '/') {
00676                 ret = getcwd(cwd, sizeof(cwd));
00677                 if (!ret) {
00678                         printf("Unable to get current working directory\n");
00679                         return NULL;
00680                 }
00681                 ok = secure_snprintf(buffer, sizeof(buffer), "%s/%s", cwd, name);
00682                 if (!ok) {
00683                         printf("Unable to copy filename\n");
00684                         return NULL;
00685                 }
00686                 RETURN_NO_LOG strdup(buffer);
00687         } else {
00688                 RETURN_NO_LOG strdup(name);
00689         }
00690 }
00691 
00695 void parse_cmdline_options(int argc, char **argv,
00696                            nutcpc_context_t * context, char **username)
00697 {
00698         int ch;
00699         int index;
00700         int stealth = 0;
00701 
00702         /* set default values */
00703         context->interval = 100;
00704         context->donotuselock = 0;
00705         context->debug_mode = 0;
00706         context->tempo = 1;
00707 
00708         /* Parse all command line arguments */
00709         opterr = 0;
00710         while ((ch = getopt(argc, argv, "kcldqNQVu:H:I:U:p:P:a:K:C:A:R:W:S:Z:")) != -1) {
00711                 switch (ch) {
00712                 case 'H':
00713                         SECURE_STRNCPY(context->srv_addr, optarg,
00714                                        sizeof(context->srv_addr));
00715                         break;
00716                 case 'P':
00717                         SECURE_STRNCPY(context->password, optarg,
00718                                        sizeof(context->password));
00719                         stealth = 1;
00720                         break;
00721                 case 'd':
00722                         context->debug_mode = 1;
00723                         break;
00724                 case 'I':
00725                         context->interval = atoi(optarg);
00726                         if (context->interval == 0) {
00727                                 fprintf(stderr, "nutcpc: bad interval\n");
00728                                 exit(EXIT_FAILURE);
00729                         }
00730                         break;
00731                 case 'l':
00732                         context->donotuselock = 1;
00733                         break;
00734                 case 'U':
00735                         *username = strdup(optarg);
00736                         break;
00737                 case 'c': {
00738                                   pid_t pid;
00739                                   if (test_nutcpc(&pid) == EXIT_SUCCESS) {
00740                                           printf("nutcpc already running (pid %u)\n",
00741                                                  pid);
00742                                           exit(EXIT_SUCCESS);
00743                                   }
00744                                   printf("No running nutcpc\n");
00745                                   exit(EXIT_FAILURE);
00746                           }
00747                         break;
00748                 case 'k':
00749                         kill_nutcpc();
00750                         break;
00751                 case 'V':
00752                         printf("nutcpc (version " NUTCPC_VERSION ")\n");
00753                         exit(0);
00754                 case 'p':
00755                         SECURE_STRNCPY(context->port, optarg,
00756                                        sizeof(context->port));
00757                         break;
00758                 case 'q':
00759                         stealth = 1;
00760                         break;
00761                 case 'N':
00762                         suppress_fqdn_verif = 1;
00763                         break;
00764                 case 'Q':
00765                         suppress_ca_warning = 1;
00766                         break;
00767                 case 'a':
00768                         SECURE_STRNCPY(context->nuauthdn, optarg,
00769                                        sizeof(context->nuauthdn));
00770                         break;
00771                 case 'C':
00772                         context->certfile = copy_filename(optarg);
00773                         break;
00774                 case 'K':
00775                         context->keyfile = copy_filename(optarg);
00776                         break;
00777                 case 'A':
00778                         context->cafile = copy_filename(optarg);
00779                         break;
00780                 case 'R':
00781                         context->crlfile = copy_filename(optarg);
00782                         break;
00783                 case 'S':
00784                         context->pkcs12file = copy_filename(optarg);
00785                         break;
00786                 case 'W':
00787                         context->pkcs12password = strdup(optarg);
00788                         break;
00789                 case 'Z':
00790                         context->krb5_service = strdup(optarg);
00791                         break;
00792                 default:
00793                         usage();
00794                 }
00795         }
00796         if (context->password[0] != 0 && !context->debug_mode) {
00797                 fprintf(stderr,
00798                         "Don't use -P option outside debugging, it's not safe!\n");
00799                 exit(EXIT_FAILURE);
00800         }
00801 
00802         if ((context->keyfile || context->certfile) && (context->pkcs12file || context->pkcs12password))
00803         {
00804                 fprintf(stderr, "Don't mix PKCS12 options with X509/RSA options.\n");
00805                 exit(EXIT_FAILURE);
00806         }
00807 
00808         /* fill argument with nul byte */
00809         if (stealth == 1) {
00810                 for (index = argc; 1 < index; index--) {
00811                         memset(argv[index - 1], '\0',
00812                                strlen(argv[index - 1]));
00813                 }
00814         }
00815 }
00816 
00820 void init_library(nutcpc_context_t * context, char *username)
00821 {
00822         struct rlimit core_limit;
00823 
00824         /* Avoid creation of core file which may contains username and password */
00825         if (!context->debug_mode && getrlimit(RLIMIT_CORE, &core_limit) == 0) {
00826                 core_limit.rlim_cur = 0;
00827                 setrlimit(RLIMIT_CORE, &core_limit);
00828         }
00829 
00830         /* Prepare error structure */
00831         if (nu_client_error_init(&err) != 0) {
00832                 printf("Cannot init error structure!\n");
00833                 exit(EXIT_FAILURE);
00834         }
00835 
00836         /* global libnuclient init */
00837         if (!nu_client_global_init(err)) {
00838                 printf("Unable to initiate nuclient library!\n");
00839                 printf("Problem: %s\n", nu_client_strerror(session, err));
00840                 exit(EXIT_FAILURE);
00841         }
00842 
00843         /* options specificied on command line are taken prior
00844          * to options from configuration file
00845          */
00846         suppress_fqdn_verif |= nu_client_default_suppress_fqdn_verif();
00847         if (!context->cafile)
00848                 context->cafile = (char *)nu_client_default_tls_ca();
00849         if (!context->certfile)
00850                 context->certfile = (char *)nu_client_default_tls_cert();
00851         if (!context->keyfile)
00852                 context->keyfile = (char *)nu_client_default_tls_key();
00853 
00854         /* Init. library */
00855         printf("Connecting to NuFW gateway (%s)\n", context->srv_addr);
00856         session = do_connect(context, username);
00857 
00858         if (session) {
00859                 display_cert(session);
00860         }
00861 
00862         /* Library failure? */
00863         if (session == NULL) {
00864                 printf("Unable to initiate connection to NuFW gateway\n");
00865                 if (err->error != 0)
00866                         printf("Problem: %s\n", nu_client_strerror(session, err));
00867                 printf("Authentication failed (check parameters)\n");
00868                 exit(EXIT_FAILURE);
00869         }
00870 }
00871 
00872 int main(int argc, char **argv)
00873 {
00874         char *runpid = compute_run_pid();
00875         char *username = NULL;
00876         char *default_username = NULL;
00877         nutcpc_context_t context;
00878         memset(&context, 0, sizeof(context));
00879 
00880         default_username = nu_get_user_name();
00881 
00882         /* needed by iconv */
00883         setlocale(LC_ALL, "");
00884 
00885         if (!nu_check_version(NUCLIENT_VERSION)) {
00886                 fprintf(stderr,
00887                         "Wrong version of libnuclient (%s instead of %s)\n",
00888                         nu_get_version(), NUCLIENT_VERSION);
00889                 exit(EXIT_FAILURE);
00890         }
00891 
00892         if (runpid == NULL) {
00893                 fprintf(stderr, "Can not determine runpid, leaving\n");
00894                 exit(EXIT_FAILURE);
00895         }
00896 
00897 
00898 
00899         /* parse command line options */
00900         parse_cmdline_options(argc, argv, &context, &username);
00901 
00902         if (!context.debug_mode) {
00903                 if (context.donotuselock == 0) {
00904                         if (!access(runpid, R_OK)) {
00905                                 FILE *fd;
00906                                 printf("Lock file found: %s\n", runpid);
00907                                 if ((fd = fopen(runpid, "r"))) {
00908                                         char line[20];
00909                                         if (fgets(line, 19, fd)) {
00910                                                 pid_t pid =
00911                                                     (pid_t) atoi(line);
00912                                                 fclose(fd);
00913                                                 if (kill(pid, 0)) {
00914                                                         printf
00915                                                             ("No running process, starting anyway (deleting lockfile)\n");
00916                                                         unlink(runpid);
00917                                                 } else {
00918                                                         printf
00919                                                             ("Kill existing process with \"-k\" or ignore it with \"-l\" option\n");
00920                                                         exit(EXIT_FAILURE);
00921                                                 }
00922                                         }
00923                                 }
00924                         }
00925                 }
00926         }
00927 
00928         install_signals();
00929 
00930         if (!username)
00931                 username = default_username;
00932 
00933         init_library(&context, username);
00934 
00935         /*
00936          * Become a daemon by double-forking and detaching completely from
00937          * the terminal.
00938          */
00939 
00940         if (!context.debug_mode) {
00941                 daemonize_process(&context, runpid);
00942         } else {
00943                 fprintf(stderr,
00944                         "nutcpc " NUTCPC_VERSION " started (debug)\n");
00945         }
00946         free(runpid);
00947 
00948         main_loop(&context);
00949         leave_client();
00950         exit(EXIT_SUCCESS);
00951 }

Generated on Sat Nov 22 04:00:37 2008 for NuFW by  doxygen 1.4.7