/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() */
313
313
__attribute__((nonnull))
314
314
static void free_plugin(plugin *plugin_node){
315
315
  
316
 
  for(char **arg = (plugin_node->argv)+1; *arg != NULL; arg++){
 
316
  for(char **arg = plugin_node->argv; *arg != NULL; arg++){
317
317
    free(*arg);
318
318
  }
319
 
  free(plugin_node->name);
320
319
  free(plugin_node->argv);
321
320
  for(char **env = plugin_node->environ; *env != NULL; env++){
322
321
    free(*env);
565
564
    case '?':                   /* --help */
566
565
      state->flags &= ~(unsigned int)ARGP_NO_EXIT; /* force exit */
567
566
      argp_state_help(state, state->out_stream, ARGP_HELP_STD_HELP);
568
 
      __builtin_unreachable();
569
567
    case -3:                    /* --usage */
570
568
      state->flags &= ~(unsigned int)ARGP_NO_EXIT; /* force exit */
571
569
      argp_state_help(state, state->out_stream,
572
570
                      ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
573
 
      __builtin_unreachable();
574
571
    case 'V':                   /* --version */
575
572
      fprintf(state->out_stream, "%s\n", argp_program_version);
576
573
      exit(EXIT_SUCCESS);
586
583
      if(arg[0] == '\0'){
587
584
        break;
588
585
      }
589
 
      /* FALLTHROUGH */
590
586
    default:
591
587
      return ARGP_ERR_UNKNOWN;
592
588
    }
705
701
        custom_argc += 1;
706
702
        {
707
703
          char **new_argv = realloc(custom_argv, sizeof(char *)
708
 
                                    * ((size_t)custom_argc + 1));
 
704
                                    * ((unsigned int)
 
705
                                       custom_argc + 1));
709
706
          if(new_argv == NULL){
710
707
            error(0, errno, "realloc");
711
708
            exitstatus = EX_OSERR;
797
794
  }
798
795
  
799
796
  if(debug){
800
 
    for(plugin *p = plugin_list; p != NULL; p = p->next){
 
797
    for(plugin *p = plugin_list; p != NULL; p=p->next){
801
798
      fprintf(stderr, "Plugin: %s has %d arguments\n",
802
799
              p->name ? p->name : "Global", p->argc - 1);
803
800
      for(char **a = p->argv; *a != NULL; a++){
812
809
  
813
810
  if(getuid() == 0){
814
811
    /* Work around Debian bug #633582:
815
 
       <https://bugs.debian.org/633582> */
 
812
       <http://bugs.debian.org/633582> */
816
813
    int plugindir_fd = open(/* plugindir or */ PDIR, O_RDONLY);
817
814
    if(plugindir_fd == -1){
818
815
      if(errno != ENOENT){
895
892
    return 1;
896
893
  }
897
894
  
 
895
#ifdef __GLIBC__
 
896
#if __GLIBC_PREREQ(2, 15)
898
897
  int numplugins = scandirat(dir_fd, ".", &direntries, good_name,
899
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__ */
900
907
  if(numplugins == -1){
901
908
    error(0, errno, "Could not scan plugin dir");
902
909
    direntries = NULL;
1096
1103
    
1097
1104
    new_plugin->pid = pid;
1098
1105
    new_plugin->fd = pipefd[0];
1099
 
 
1100
 
    if(debug){
1101
 
      fprintf(stderr, "Plugin %s started (PID %" PRIdMAX ")\n",
1102
 
              new_plugin->name, (intmax_t) (new_plugin->pid));
1103
 
    }
1104
 
 
 
1106
    
1105
1107
    /* Unblock SIGCHLD so signal handler can be run if this process
1106
1108
       has already completed */
1107
1109
    ret = (int)TEMP_FAILURE_RETRY(sigprocmask(SIG_UNBLOCK,
1113
1115
      goto fallback;
1114
1116
    }
1115
1117
    
1116
 
    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
1117
1132
    
1118
1133
    if(maxfd < new_plugin->fd){
1119
1134
      maxfd = new_plugin->fd;
1168
1183
                      (intmax_t) (proc->pid),
1169
1184
                      WTERMSIG(proc->status),
1170
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));
1171
1189
            }
1172
1190
          }
1173
1191
          
1174
1192
          /* Remove the plugin */
1175
 
          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
1176
1207
          
1177
1208
          /* Block signal while modifying process_list */
1178
1209
          ret = (int)TEMP_FAILURE_RETRY(sigprocmask
1218
1249
      }
1219
1250
      
1220
1251
      /* This process has not completed.  Does it have any output? */
1221
 
      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
1222
1269
        /* This process had nothing to say at this time */
1223
1270
        proc = proc->next;
1224
1271
        continue;