/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugin-runner.c

  • Committer: Teddy Hogeborn
  • Date: 2015-07-20 03:03:33 UTC
  • Revision ID: teddy@recompile.se-20150720030333-203m2aeblypcsfte
Bug fix for GnuTLS 3: be compatible with old 2048-bit DSA keys.

The mandos-keygen program in Mandos version 1.6.0 and older generated
2048-bit DSA keys, and when GnuTLS uses these it has trouble
connecting using the Mandos default priority string.  This was
previously fixed in Mandos 1.6.2, but the bug reappeared when using
GnuTLS 3, so the default priority string has to change again; this
time also the Mandos client has to change its default, so now the
server and the client should use the same default priority string:

SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256

* mandos (main/server_defaults): Changed default priority string.
* mandos-options.xml (/section/para[id="priority_compat"]): Removed.
  (/section/para[id="priority"]): Changed default priority string.
* mandos.conf ([DEFAULT]/priority): - '' -
* mandos.conf.xml (OPTIONS/priority): Refer to the id "priority"
                                      instead of "priority_compat".
* mandos.xml (OPTIONS/--priority): - '' -
* plugins.d/mandos-client.c (main): Changed default priority string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 * Mandos plugin runner - Run Mandos plugins
4
4
 *
5
 
 * Copyright © 2008-2018 Teddy Hogeborn
6
 
 * Copyright © 2008-2018 Björn Påhlsson
7
 
 * 
8
 
 * This file is part of Mandos.
9
 
 * 
10
 
 * Mandos is free software: you can redistribute it and/or modify it
11
 
 * under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation, either version 3 of the License, or
13
 
 * (at your option) any later version.
14
 
 * 
15
 
 * Mandos is distributed in the hope that it will be useful, but
 
5
 * Copyright © 2008-2014 Teddy Hogeborn
 
6
 * Copyright © 2008-2014 Björn Påhlsson
 
7
 * 
 
8
 * This program is free software: you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License as
 
10
 * published by the Free Software Foundation, either version 3 of the
 
11
 * License, or (at your option) any later version.
 
12
 * 
 
13
 * This program is distributed in the hope that it will be useful, but
16
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
16
 * General Public License for more details.
19
17
 * 
20
18
 * You should have received a copy of the GNU General Public License
21
 
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
 
19
 * along with this program.  If not, see
 
20
 * <http://www.gnu.org/licenses/>.
22
21
 * 
23
22
 * Contact the authors at <mandos@recompile.se>.
24
23
 */
38
37
#include <sys/select.h>         /* fd_set, select(), FD_ZERO(),
39
38
                                   FD_SET(), FD_ISSET(), FD_CLR */
40
39
#include <sys/wait.h>           /* wait(), waitpid(), WIFEXITED(),
41
 
                                   WEXITSTATUS(), WTERMSIG() */
 
40
                                   WEXITSTATUS(), WTERMSIG(),
 
41
                                   WCOREDUMP() */
42
42
#include <sys/stat.h>           /* struct stat, fstat(), S_ISREG() */
43
43
#include <iso646.h>             /* and, or, not */
44
44
#include <dirent.h>             /* struct dirent, scandirat() */
564
564
    case '?':                   /* --help */
565
565
      state->flags &= ~(unsigned int)ARGP_NO_EXIT; /* force exit */
566
566
      argp_state_help(state, state->out_stream, ARGP_HELP_STD_HELP);
567
 
      __builtin_unreachable();
568
567
    case -3:                    /* --usage */
569
568
      state->flags &= ~(unsigned int)ARGP_NO_EXIT; /* force exit */
570
569
      argp_state_help(state, state->out_stream,
571
570
                      ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
572
 
      __builtin_unreachable();
573
571
    case 'V':                   /* --version */
574
572
      fprintf(state->out_stream, "%s\n", argp_program_version);
575
573
      exit(EXIT_SUCCESS);
585
583
      if(arg[0] == '\0'){
586
584
        break;
587
585
      }
588
 
      /* FALLTHROUGH */
589
586
    default:
590
587
      return ARGP_ERR_UNKNOWN;
591
588
    }
704
701
        custom_argc += 1;
705
702
        {
706
703
          char **new_argv = realloc(custom_argv, sizeof(char *)
707
 
                                    * ((size_t)custom_argc + 1));
 
704
                                    * ((unsigned int)
 
705
                                       custom_argc + 1));
708
706
          if(new_argv == NULL){
709
707
            error(0, errno, "realloc");
710
708
            exitstatus = EX_OSERR;
796
794
  }
797
795
  
798
796
  if(debug){
799
 
    for(plugin *p = plugin_list; p != NULL; p = p->next){
 
797
    for(plugin *p = plugin_list; p != NULL; p=p->next){
800
798
      fprintf(stderr, "Plugin: %s has %d arguments\n",
801
799
              p->name ? p->name : "Global", p->argc - 1);
802
800
      for(char **a = p->argv; *a != NULL; a++){
811
809
  
812
810
  if(getuid() == 0){
813
811
    /* Work around Debian bug #633582:
814
 
       <https://bugs.debian.org/633582> */
 
812
       <http://bugs.debian.org/633582> */
815
813
    int plugindir_fd = open(/* plugindir or */ PDIR, O_RDONLY);
816
814
    if(plugindir_fd == -1){
817
815
      if(errno != ENOENT){
894
892
    return 1;
895
893
  }
896
894
  
 
895
#ifdef __GLIBC__
 
896
#if __GLIBC_PREREQ(2, 15)
897
897
  int numplugins = scandirat(dir_fd, ".", &direntries, good_name,
898
898
                             alphasort);
 
899
#else  /* not __GLIBC_PREREQ(2, 15) */
 
900
  int numplugins = scandir(plugindir != NULL ? plugindir : PDIR,
 
901
                           &direntries, good_name, alphasort);
 
902
#endif  /* not __GLIBC_PREREQ(2, 15) */
 
903
#else   /* not __GLIBC__ */
 
904
  int numplugins = scandir(plugindir != NULL ? plugindir : PDIR,
 
905
                           &direntries, good_name, alphasort);
 
906
#endif  /* not __GLIBC__ */
899
907
  if(numplugins == -1){
900
908
    error(0, errno, "Could not scan plugin dir");
901
909
    direntries = NULL;
1095
1103
    
1096
1104
    new_plugin->pid = pid;
1097
1105
    new_plugin->fd = pipefd[0];
1098
 
 
1099
 
    if(debug){
1100
 
      fprintf(stderr, "Plugin %s started (PID %" PRIdMAX ")\n",
1101
 
              new_plugin->name, (intmax_t) (new_plugin->pid));
1102
 
    }
1103
 
 
 
1106
    
1104
1107
    /* Unblock SIGCHLD so signal handler can be run if this process
1105
1108
       has already completed */
1106
1109
    ret = (int)TEMP_FAILURE_RETRY(sigprocmask(SIG_UNBLOCK,
1112
1115
      goto fallback;
1113
1116
    }
1114
1117
    
1115
 
    FD_SET(new_plugin->fd, &rfds_all);
 
1118
#if defined (__GNUC__) and defined (__GLIBC__)
 
1119
#if not __GLIBC_PREREQ(2, 16)
 
1120
#pragma GCC diagnostic push
 
1121
#pragma GCC diagnostic ignored "-Wsign-conversion"
 
1122
#endif
 
1123
#endif
 
1124
    FD_SET(new_plugin->fd, &rfds_all); /* Spurious warning from
 
1125
                                          -Wconversion in GNU libc
 
1126
                                          before 2.16 */
 
1127
#if defined (__GNUC__) and defined (__GLIBC__)
 
1128
#if not __GLIBC_PREREQ(2, 16)
 
1129
#pragma GCC diagnostic pop
 
1130
#endif
 
1131
#endif
1116
1132
    
1117
1133
    if(maxfd < new_plugin->fd){
1118
1134
      maxfd = new_plugin->fd;
1167
1183
                      (intmax_t) (proc->pid),
1168
1184
                      WTERMSIG(proc->status),
1169
1185
                      strsignal(WTERMSIG(proc->status)));
 
1186
            } else if(WCOREDUMP(proc->status)){
 
1187
              fprintf(stderr, "Plugin %s [%" PRIdMAX "] dumped"
 
1188
                      " core\n", proc->name, (intmax_t) (proc->pid));
1170
1189
            }
1171
1190
          }
1172
1191
          
1173
1192
          /* Remove the plugin */
1174
 
          FD_CLR(proc->fd, &rfds_all);
 
1193
#if defined (__GNUC__) and defined (__GLIBC__)
 
1194
#if not __GLIBC_PREREQ(2, 16)
 
1195
#pragma GCC diagnostic push
 
1196
#pragma GCC diagnostic ignored "-Wsign-conversion"
 
1197
#endif
 
1198
#endif
 
1199
          FD_CLR(proc->fd, &rfds_all); /* Spurious warning from
 
1200
                                          -Wconversion in GNU libc
 
1201
                                          before 2.16 */
 
1202
#if defined (__GNUC__) and defined (__GLIBC__)
 
1203
#if not __GLIBC_PREREQ(2, 16)
 
1204
#pragma GCC diagnostic pop
 
1205
#endif
 
1206
#endif
1175
1207
          
1176
1208
          /* Block signal while modifying process_list */
1177
1209
          ret = (int)TEMP_FAILURE_RETRY(sigprocmask
1217
1249
      }
1218
1250
      
1219
1251
      /* This process has not completed.  Does it have any output? */
1220
 
      if(proc->eof or not FD_ISSET(proc->fd, &rfds)){
 
1252
#if defined (__GNUC__) and defined (__GLIBC__)
 
1253
#if not __GLIBC_PREREQ(2, 16)
 
1254
#pragma GCC diagnostic push
 
1255
#pragma GCC diagnostic ignored "-Wsign-conversion"
 
1256
#endif
 
1257
#endif
 
1258
      if(proc->eof or not FD_ISSET(proc->fd, &rfds)){ /* Spurious
 
1259
                                                         warning from
 
1260
                                                         -Wconversion
 
1261
                                                         in GNU libc
 
1262
                                                         before
 
1263
                                                         2.16 */
 
1264
#if defined (__GNUC__) and defined (__GLIBC__)
 
1265
#if not __GLIBC_PREREQ(2, 16)
 
1266
#pragma GCC diagnostic pop
 
1267
#endif
 
1268
#endif
1221
1269
        /* This process had nothing to say at this time */
1222
1270
        proc = proc->next;
1223
1271
        continue;