/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 plugbasedclient.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-02 10:48:24 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080802104824-fx0miwp9o4g9r31e
* plugbasedclient.c (struct process): New fields "eof", "completed",
                                      and "status".
  (handle_sigchld): New function.
  (main): Initialize "dir" to NULL to only closedir() it if necessary.
          Move "process_list" to be a global variable to be accessible
          by "handle_sigchld".  Make "handle_sigchld" handle SIGCHLD.
          Remove redundant check for NULL "dir".  Free "filename" when
          no longer used.  Block SIGCHLD around fork()/exec().
          Restore normal signals in child.  Only loop while running
          processes exist.  Print process buffer when the process is
          done and it has emitted EOF, not when it only emits EOF.
          Remove processes from list which exit non-cleanly.  In
          cleaning up, closedir() if necessary.  Bug fix: set next
          pointer correctly when freeing process list.

* plugins.d/passprompt.c (main): Do not ignore SIGQUIT.

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
                                   struct argp_state, struct argp,
51
51
                                   argp_parse() */
52
52
 
53
 
#define BUFFER_SIZE 256
54
 
 
55
53
struct process;
56
54
 
57
55
typedef struct process{
74
72
  struct plugin *next;
75
73
} plugin;
76
74
 
77
 
static plugin *getplugin(char *name, plugin **plugin_list){
 
75
plugin *getplugin(char *name, plugin **plugin_list){
78
76
  for (plugin *p = *plugin_list; p != NULL; p = p->next){
79
77
    if ((p->name == name)
80
78
        or (p->name and name and (strcmp(p->name, name) == 0))){
103
101
  return new_plugin;
104
102
}
105
103
 
106
 
static void addargument(plugin *p, char *arg){
 
104
void addargument(plugin *p, char *arg){
107
105
  p->argv[p->argc] = arg;
108
106
  p->argv = realloc(p->argv, sizeof(char *) * (size_t)(p->argc + 2));
109
107
  if (p->argv == NULL){
119
117
 * Descriptor Flags".
120
118
 * *Note File Descriptor Flags:(libc)Descriptor Flags.
121
119
 */
122
 
static int set_cloexec_flag(int fd)
 
120
int set_cloexec_flag(int fd)
123
121
{
124
122
  int ret = fcntl(fd, F_GETFD, 0);
125
123
  /* If reading the flags failed, return error indication now. */
130
128
  return fcntl(fd, F_SETFD, ret | FD_CLOEXEC);
131
129
}
132
130
 
 
131
#define BUFFER_SIZE 256
 
132
 
133
133
const char *argp_program_version = "plugbasedclient 0.9";
134
134
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
135
135
 
142
142
  int status;
143
143
  pid_t pid = wait(&status);
144
144
  while(proc != NULL and proc->pid != pid){
145
 
    proc = proc->next;
 
145
    proc = proc->next;    
146
146
  }
147
147
  if(proc == NULL){
148
148
    /* Process not found in process list */
160
160
  struct stat st;
161
161
  fd_set rfds_all;
162
162
  int ret, maxfd = 0;
163
 
  uid_t uid = 65534;
164
 
  gid_t gid = 65534;
165
163
  bool debug = false;
166
164
  int exitstatus = EXIT_SUCCESS;
167
 
  struct sigaction old_sigchld_action;
168
 
  struct sigaction sigchld_action = { .sa_handler = handle_sigchld,
169
 
                                      .sa_flags = SA_NOCLDSTOP };
170
 
  char *plus_options = NULL;
171
 
  char **plus_argv = NULL;
172
165
  
173
166
  /* Establish a signal handler */
 
167
  struct sigaction old_sigchld_action,
 
168
    sigchld_action = { .sa_handler = handle_sigchld,
 
169
                       .sa_flags = SA_NOCLDSTOP };
174
170
  sigemptyset(&sigchld_action.sa_mask);
175
171
  ret = sigaddset(&sigchld_action.sa_mask, SIGCHLD);
176
172
  if(ret < 0){
197
193
    { .name = "plugin-dir", .key = 128,
198
194
      .arg = "DIRECTORY",
199
195
      .doc = "Specify a different plugin directory", .group = 2 },
200
 
    { .name = "userid", .key = 129,
201
 
      .arg = "ID", .flags = 0,
202
 
      .doc = "User ID the plugins will run as", .group = 2 },
203
 
    { .name = "groupid", .key = 130,
204
 
      .arg = "ID", .flags = 0,
205
 
      .doc = "Group ID the plugins will run as", .group = 2 },
206
 
    { .name = "debug", .key = 131,
 
196
    { .name = "debug", .key = 129,
207
197
      .doc = "Debug mode", .group = 3 },
208
198
    { .name = NULL }
209
199
  };
219
209
        do{
220
210
          addargument(getplugin(NULL, plugins), p);
221
211
          p = strtok(NULL, ",");
222
 
        } while (p != NULL);
 
212
        } while (p);
223
213
      }
224
214
      break;
225
215
    case 'o':
226
216
      if (arg != NULL){
227
217
        char *name = strtok(arg, ":");
228
218
        char *p = strtok(NULL, ":");
229
 
        if(p != NULL){
 
219
        if(p){
230
220
          p = strtok(p, ",");
231
221
          do{
232
222
            addargument(getplugin(name, plugins), p);
233
223
            p = strtok(NULL, ",");
234
 
          } while (p != NULL);
 
224
          } while (p);
235
225
        }
236
226
      }
237
227
      break;
244
234
      plugindir = arg;
245
235
      break;
246
236
    case 129:
247
 
      uid = (uid_t)strtol(arg, NULL, 10);
248
 
      break;
249
 
    case 130:
250
 
      gid = (gid_t)strtol(arg, NULL, 10);
251
 
      break;
252
 
    case 131:
253
237
      debug = true;
254
238
      break;
255
239
    case ARGP_KEY_ARG:
256
 
      if(plus_options != NULL or arg == NULL or arg[0] != '+'){
257
 
        argp_usage (state);
258
 
      }
259
 
      plus_options = arg;
 
240
      argp_usage (state);
260
241
      break;
261
242
    case ARGP_KEY_END:
262
243
      break;
269
250
  plugin *plugin_list = NULL;
270
251
  
271
252
  struct argp argp = { .options = options, .parser = parse_opt,
272
 
                       .args_doc = "[+PLUS_SEPARATED_OPTIONS]",
 
253
                       .args_doc = "",
273
254
                       .doc = "Mandos plugin runner -- Run plugins" };
274
255
  
275
 
  argp_parse (&argp, argc, argv, 0, 0, &plugin_list);  
276
 
  
277
 
  if(plus_options){
278
 
    /* This is a mangled argument in the form of
279
 
     "+--option+--other-option=parameter+--yet-another-option", etc */
280
 
    /* Make new argc and argv vars, and call argp_parse() again. */
281
 
    plus_options++;             /* skip the first '+' character */
282
 
    const char delims[] = "+";
283
 
    char *arg;
284
 
    int new_argc = 1;
285
 
    plus_argv = malloc(sizeof(char*) * 2);
286
 
    if(plus_argv == NULL){
287
 
      perror("malloc");
288
 
      exitstatus = EXIT_FAILURE;
289
 
      goto end;
290
 
    }
291
 
    plus_argv[0] = argv[0];
292
 
    plus_argv[1] = NULL;
293
 
    arg = strtok(plus_options, delims); /* Get first argument */
294
 
    while(arg != NULL){
295
 
      new_argc++;
296
 
      plus_argv = realloc(plus_argv, sizeof(char *)
297
 
                         * ((unsigned int) new_argc + 1));
298
 
      if(plus_argv == NULL){
299
 
        perror("malloc");
300
 
        exitstatus = EXIT_FAILURE;
301
 
        goto end;
302
 
      }
303
 
      plus_argv[new_argc-1] = arg;
304
 
      plus_argv[new_argc] = NULL;
305
 
      arg = strtok(NULL, delims); /* Get next argument */
306
 
    }
307
 
    argp_parse (&argp, new_argc, plus_argv, 0, 0, &plugin_list);  
308
 
  }
 
256
  argp_parse (&argp, argc, argv, 0, 0, &plugin_list);
309
257
  
310
258
  if(debug){
311
259
    for(plugin *p = plugin_list; p != NULL; p=p->next){
317
265
    }
318
266
  }
319
267
  
320
 
  ret = setuid(uid);
321
 
  if (ret == -1){
322
 
    perror("setuid");
323
 
  }
324
 
  
325
 
  setgid(gid);
326
 
  if (ret == -1){
327
 
    perror("setgid");
328
 
  }
329
 
  
330
268
  dir = opendir(plugindir);
331
269
  if(dir == NULL){
332
270
    perror("Could not open plugin dir");
662
600
  /* Restore old signal handler */
663
601
  sigaction(SIGCHLD, &old_sigchld_action, NULL);
664
602
  
665
 
  free(plus_argv);
666
 
  
667
603
  /* Free the plugin list */
668
604
  for(plugin *next; plugin_list != NULL; plugin_list = next){
669
605
    next = plugin_list->next;