/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
237.1.2 by Teddy Hogeborn
Further steps towards a D-Bus server interface, plus minor syntax
1
/*  -*- coding: utf-8 -*- */
2
/*
261 by Teddy Hogeborn
* plugins.d/askpass-fifo.c: Fix name in header.
3
 * Usplash - Read a password from usplash and output it
237.1.2 by Teddy Hogeborn
Further steps towards a D-Bus server interface, plus minor syntax
4
 * 
679 by Teddy Hogeborn
Update copyright year.
5
 * Copyright © 2008-2014 Teddy Hogeborn
6
 * Copyright © 2008-2014 Björn Påhlsson
237.1.2 by Teddy Hogeborn
Further steps towards a D-Bus server interface, plus minor syntax
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
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * General Public License for more details.
17
 * 
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see
20
 * <http://www.gnu.org/licenses/>.
21
 * 
505.1.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
22
 * Contact the authors at <mandos@recompile.se>.
237.1.2 by Teddy Hogeborn
Further steps towards a D-Bus server interface, plus minor syntax
23
 */
24
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
25
#define _GNU_SOURCE		/* asprintf(), TEMP_FAILURE_RETRY() */
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
26
#include <signal.h>		/* sig_atomic_t, struct sigaction,
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
27
				   sigemptyset(), sigaddset(), SIGINT,
28
				   SIGHUP, SIGTERM, sigaction(),
29
				   SIG_IGN, kill(), SIGKILL */
30
#include <stdbool.h>		/* bool, false, true */
31
#include <fcntl.h>		/* open(), O_WRONLY, O_RDONLY */
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
32
#include <iso646.h>		/* and, or, not*/
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
33
#include <errno.h>		/* errno, EINTR */
24.1.155 by Björn Påhlsson
mandos server: Added debuglevel that adjust at what level information
34
#include <error.h>
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
35
#include <sys/types.h>		/* size_t, ssize_t, pid_t, DIR, struct
36
				   dirent */
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
37
#include <stddef.h>		/* NULL */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
38
#include <string.h>		/* strlen(), memcmp(), strerror() */
485 by Teddy Hogeborn
Merge from Björn.
39
#include <stdio.h>		/* asprintf(), vasprintf(), vprintf(),
40
				   fprintf() */
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
41
#include <unistd.h>		/* close(), write(), readlink(),
42
				   read(), STDOUT_FILENO, sleep(),
43
				   fork(), setuid(), geteuid(),
44
				   setsid(), chdir(), dup2(),
45
				   STDERR_FILENO, execv() */
264 by Teddy Hogeborn
* plugin-runner.c (main): Use "sscanf" instead of "strtol"; using the
46
#include <stdlib.h>		/* free(), EXIT_FAILURE, realloc(),
24.1.151 by Björn Påhlsson
New graphical boot supported: Plymouth
47
				   EXIT_SUCCESS, malloc(), _exit(),
48
				   getenv() */
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
49
#include <dirent.h>		/* opendir(), readdir(), closedir() */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
50
#include <inttypes.h>		/* intmax_t, strtoimax() */
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
51
#include <sys/stat.h>		/* struct stat, lstat(), S_ISLNK */
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
52
#include <sysexits.h>		/* EX_OSERR, EX_UNAVAILABLE */
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
53
#include <argz.h>		/* argz_count(), argz_extract() */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
54
#include <stdarg.h>		/* va_list, va_start(), ... */
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
55
56
sig_atomic_t interrupted_by_signal = 0;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
57
int signal_received;
58
const char usplash_name[] = "/sbin/usplash";
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
59
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
60
/* Function to use when printing errors */
533 by teddy at bsnet
* plugins.d/splashy.c (error_plus): Check format string.
61
__attribute__((format (gnu_printf, 3, 4)))
485 by Teddy Hogeborn
Merge from Björn.
62
void error_plus(int status, int errnum, const char *formatstring,
63
		...){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
64
  va_list ap;
65
  char *text;
66
  int ret;
67
  
68
  va_start(ap, formatstring);
69
  ret = vasprintf(&text, formatstring, ap);
670 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
70
  if(ret == -1){
485 by Teddy Hogeborn
Merge from Björn.
71
    fprintf(stderr, "Mandos plugin %s: ",
72
	    program_invocation_short_name);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
73
    vfprintf(stderr, formatstring, ap);
74
    fprintf(stderr, ": ");
75
    fprintf(stderr, "%s\n", strerror(errnum));
76
    error(status, errno, "vasprintf while printing error");
77
    return;
78
  }
79
  fprintf(stderr, "Mandos plugin ");
80
  error(status, errnum, "%s", text);
81
  free(text);
82
}
83
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
84
static void termination_handler(int signum){
85
  if(interrupted_by_signal){
86
    return;
87
  }
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
88
  interrupted_by_signal = 1;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
89
  signal_received = signum;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
90
}
91
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
92
static bool usplash_write(int *fifo_fd_r,
93
			  const char *cmd, const char *arg){
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
94
  /* 
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
95
   * usplash_write(&fd, "TIMEOUT", "15") will write "TIMEOUT 15\0"
96
   * usplash_write(&fd, "PULSATE", NULL) will write "PULSATE\0"
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
97
   * SEE ALSO
98
   *         usplash_write(8)
99
   */
100
  int ret;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
101
  if(*fifo_fd_r == -1){
102
    ret = open("/dev/.initramfs/usplash_fifo", O_WRONLY);
103
    if(ret == -1){
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
104
      return false;
105
    }
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
106
    *fifo_fd_r = ret;
107
  }
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
108
  
109
  const char *cmd_line;
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
110
  size_t cmd_line_len;
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
111
  char *cmd_line_alloc = NULL;
112
  if(arg == NULL){
113
    cmd_line = cmd;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
114
    cmd_line_len = strlen(cmd) + 1;
363 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
115
  } else {
116
    do {
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
117
      ret = asprintf(&cmd_line_alloc, "%s %s", cmd, arg);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
118
      if(ret == -1){
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
119
	int e = errno;
774 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
120
	close(*fifo_fd_r);
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
121
	errno = e;
122
	return false;
123
      }
363 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
124
    } while(ret == -1);
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
125
    cmd_line = cmd_line_alloc;
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
126
    cmd_line_len = (size_t)ret + 1;
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
127
  }
128
  
129
  size_t written = 0;
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
130
  ssize_t sret = 0;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
131
  while(written < cmd_line_len){
132
    sret = write(*fifo_fd_r, cmd_line + written,
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
133
		 cmd_line_len - written);
134
    if(sret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
135
      int e = errno;
774 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
136
      close(*fifo_fd_r);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
137
      free(cmd_line_alloc);
138
      errno = e;
139
      return false;
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
140
    }
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
141
    written += (size_t)sret;
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
142
  }
143
  free(cmd_line_alloc);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
144
  
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
145
  return true;
146
}
147
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
148
/* Create prompt string */
149
char *makeprompt(void){
150
  int ret = 0;
151
  char *prompt;
152
  const char *const cryptsource = getenv("cryptsource");
153
  const char *const crypttarget = getenv("crypttarget");
154
  const char prompt_start[] = "Enter passphrase to unlock the disk";
155
  
156
  if(cryptsource == NULL){
157
    if(crypttarget == NULL){
158
      ret = asprintf(&prompt, "%s: ", prompt_start);
159
    } else {
160
      ret = asprintf(&prompt, "%s (%s): ", prompt_start,
161
		     crypttarget);
162
    }
163
  } else {
164
    if(crypttarget == NULL){
165
      ret = asprintf(&prompt, "%s %s: ", prompt_start, cryptsource);
166
    } else {
167
      ret = asprintf(&prompt, "%s %s (%s): ", prompt_start,
168
		     cryptsource, crypttarget);
169
    }
170
  }
171
  if(ret == -1){
172
    return NULL;
173
  }
174
  return prompt;
175
}
176
177
pid_t find_usplash(char **cmdline_r, size_t *cmdline_len_r){
178
  int ret = 0;
179
  ssize_t sret = 0;
180
  char *cmdline = NULL;
181
  size_t cmdline_len = 0;
182
  DIR *proc_dir = opendir("/proc");
183
  if(proc_dir == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
184
    error_plus(0, errno, "opendir");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
185
    return -1;
186
  }
187
  errno = 0;
188
  for(struct dirent *proc_ent = readdir(proc_dir);
189
      proc_ent != NULL;
190
      proc_ent = readdir(proc_dir)){
191
    pid_t pid;
192
    {
193
      intmax_t tmpmax;
194
      char *tmp;
195
      tmpmax = strtoimax(proc_ent->d_name, &tmp, 10);
196
      if(errno != 0 or tmp == proc_ent->d_name or *tmp != '\0'
197
	 or tmpmax != (pid_t)tmpmax){
198
	/* Not a process */
199
	errno = 0;
200
	continue;
201
      }
202
      pid = (pid_t)tmpmax;
203
    }
204
    /* Find the executable name by doing readlink() on the
205
       /proc/<pid>/exe link */
206
    char exe_target[sizeof(usplash_name)];
207
    {
208
      /* create file name string */
209
      char *exe_link;
210
      ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name);
211
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
212
	error_plus(0, errno, "asprintf");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
213
	goto fail_find_usplash;
214
      }
215
      
216
      /* Check that it refers to a symlink owned by root:root */
217
      struct stat exe_stat;
218
      ret = lstat(exe_link, &exe_stat);
219
      if(ret == -1){
220
	if(errno == ENOENT){
221
	  free(exe_link);
222
	  continue;
223
	}
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
224
	error_plus(0, errno, "lstat");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
225
	free(exe_link);
226
	goto fail_find_usplash;
227
      }
228
      if(not S_ISLNK(exe_stat.st_mode)
229
	 or exe_stat.st_uid != 0
230
	 or exe_stat.st_gid != 0){
231
	free(exe_link);
232
	continue;
233
      }
234
	
235
      sret = readlink(exe_link, exe_target, sizeof(exe_target));
236
      free(exe_link);
237
    }
238
    /* Compare executable name */
239
    if((sret != ((ssize_t)sizeof(exe_target)-1))
240
       or (memcmp(usplash_name, exe_target,
241
		  sizeof(exe_target)-1) != 0)){
242
      /* Not it */
243
      continue;
244
    }
245
    /* Found usplash */
246
    /* Read and save the command line of usplash in "cmdline" */
247
    {
248
      /* Open /proc/<pid>/cmdline  */
249
      int cl_fd;
250
      {
251
	char *cmdline_filename;
252
	ret = asprintf(&cmdline_filename, "/proc/%s/cmdline",
253
		       proc_ent->d_name);
254
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
255
	  error_plus(0, errno, "asprintf");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
256
	  goto fail_find_usplash;
257
	}
258
	cl_fd = open(cmdline_filename, O_RDONLY);
259
	free(cmdline_filename);
260
	if(cl_fd == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
261
	  error_plus(0, errno, "open");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
262
	  goto fail_find_usplash;
263
	}
264
      }
265
      size_t cmdline_allocated = 0;
266
      char *tmp;
267
      const size_t blocksize = 1024;
268
      do {
269
	/* Allocate more space? */
270
	if(cmdline_len + blocksize > cmdline_allocated){
271
	  tmp = realloc(cmdline, cmdline_allocated + blocksize);
272
	  if(tmp == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
273
	    error_plus(0, errno, "realloc");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
274
	    close(cl_fd);
275
	    goto fail_find_usplash;
276
	  }
277
	  cmdline = tmp;
278
	  cmdline_allocated += blocksize;
279
	}
280
	/* Read data */
281
	sret = read(cl_fd, cmdline + cmdline_len,
282
		    cmdline_allocated - cmdline_len);
283
	if(sret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
284
	  error_plus(0, errno, "read");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
285
	  close(cl_fd);
286
	  goto fail_find_usplash;
287
	}
288
	cmdline_len += (size_t)sret;
289
      } while(sret != 0);
290
      ret = close(cl_fd);
291
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
292
	error_plus(0, errno, "close");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
293
	goto fail_find_usplash;
294
      }
295
    }
296
    /* Close directory */
297
    ret = closedir(proc_dir);
298
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
299
      error_plus(0, errno, "closedir");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
300
      goto fail_find_usplash;
301
    }
302
    /* Success */
303
    *cmdline_r = cmdline;
304
    *cmdline_len_r = cmdline_len;
305
    return pid;
306
  }
307
  
308
 fail_find_usplash:
309
  
310
  free(cmdline);
311
  if(proc_dir != NULL){
312
    int e = errno;
313
    closedir(proc_dir);
314
    errno = e;
315
  }
316
  return 0;
317
}
318
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
319
int main(__attribute__((unused))int argc,
320
	 __attribute__((unused))char **argv){
321
  int ret = 0;
322
  ssize_t sret;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
323
  int fifo_fd = -1;
324
  int outfifo_fd = -1;
325
  char *buf = NULL;
326
  size_t buf_len = 0;
327
  pid_t usplash_pid = -1;
328
  bool usplash_accessed = false;
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
329
  int status = EXIT_FAILURE;	/* Default failure exit status */
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
330
  
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
331
  char *prompt = makeprompt();
332
  if(prompt == NULL){
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
333
    status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
334
    goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
335
  }
336
  
337
  /* Find usplash process */
338
  char *cmdline = NULL;
339
  size_t cmdline_len = 0;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
340
  usplash_pid = find_usplash(&cmdline, &cmdline_len);
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
341
  if(usplash_pid == 0){
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
342
    status = EX_UNAVAILABLE;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
343
    goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
344
  }
345
  
346
  /* Set up the signal handler */
347
  {
348
    struct sigaction old_action,
349
      new_action = { .sa_handler = termination_handler,
350
		     .sa_flags = 0 };
351
    sigemptyset(&new_action.sa_mask);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
352
    ret = sigaddset(&new_action.sa_mask, SIGINT);
353
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
354
      error_plus(0, errno, "sigaddset");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
355
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
356
      goto failure;
357
    }
358
    ret = sigaddset(&new_action.sa_mask, SIGHUP);
359
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
360
      error_plus(0, errno, "sigaddset");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
361
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
362
      goto failure;
363
    }
364
    ret = sigaddset(&new_action.sa_mask, SIGTERM);
365
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
366
      error_plus(0, errno, "sigaddset");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
367
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
368
      goto failure;
369
    }
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
370
    ret = sigaction(SIGINT, NULL, &old_action);
371
    if(ret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
372
      if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
373
	error_plus(0, errno, "sigaction");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
374
	status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
375
      }
376
      goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
377
    }
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
378
    if(old_action.sa_handler != SIG_IGN){
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
379
      ret = sigaction(SIGINT, &new_action, NULL);
380
      if(ret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
381
	if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
382
	  error_plus(0, errno, "sigaction");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
383
	  status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
384
	}
385
	goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
386
      }
387
    }
388
    ret = sigaction(SIGHUP, NULL, &old_action);
389
    if(ret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
390
      if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
391
	error_plus(0, errno, "sigaction");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
392
	status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
393
      }
394
      goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
395
    }
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
396
    if(old_action.sa_handler != SIG_IGN){
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
397
      ret = sigaction(SIGHUP, &new_action, NULL);
398
      if(ret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
399
	if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
400
	  error_plus(0, errno, "sigaction");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
401
	  status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
402
	}
403
	goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
404
      }
405
    }
406
    ret = sigaction(SIGTERM, NULL, &old_action);
407
    if(ret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
408
      if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
409
	error_plus(0, errno, "sigaction");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
410
	status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
411
      }
412
      goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
413
    }
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
414
    if(old_action.sa_handler != SIG_IGN){
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
415
      ret = sigaction(SIGTERM, &new_action, NULL);
416
      if(ret == -1){
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
417
	if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
418
	  error_plus(0, errno, "sigaction");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
419
	  status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
420
	}
421
	goto failure;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
422
      }
423
    }
424
  }
425
  
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
426
  usplash_accessed = true;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
427
  /* Write command to FIFO */
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
428
  if(not usplash_write(&fifo_fd, "TIMEOUT", "0")){
429
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
430
      error_plus(0, errno, "usplash_write");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
431
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
432
    }
433
    goto failure;
434
  }
435
  
436
  if(interrupted_by_signal){
437
    goto failure;
438
  }
439
  
440
  if(not usplash_write(&fifo_fd, "INPUTQUIET", prompt)){
441
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
442
      error_plus(0, errno, "usplash_write");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
443
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
444
    }
445
    goto failure;
446
  }
447
  
448
  if(interrupted_by_signal){
449
    goto failure;
450
  }
451
  
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
452
  free(prompt);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
453
  prompt = NULL;
454
  
455
  /* Read reply from usplash */
456
  /* Open FIFO */
457
  outfifo_fd = open("/dev/.initramfs/usplash_outfifo", O_RDONLY);
458
  if(outfifo_fd == -1){
459
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
460
      error_plus(0, errno, "open");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
461
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
462
    }
463
    goto failure;
464
  }
465
  
466
  if(interrupted_by_signal){
467
    goto failure;
468
  }
469
  
470
  /* Read from FIFO */
471
  size_t buf_allocated = 0;
472
  const size_t blocksize = 1024;
473
  do {
474
    /* Allocate more space */
475
    if(buf_len + blocksize > buf_allocated){
476
      char *tmp = realloc(buf, buf_allocated + blocksize);
477
      if(tmp == NULL){
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
478
	if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
479
	  error_plus(0, errno, "realloc");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
480
	  status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
481
	}
482
	goto failure;
483
      }
484
      buf = tmp;
485
      buf_allocated += blocksize;
486
    }
487
    sret = read(outfifo_fd, buf + buf_len,
488
		buf_allocated - buf_len);
489
    if(sret == -1){
490
      if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
491
	error_plus(0, errno, "read");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
492
	status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
493
      }
774 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
494
      close(outfifo_fd);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
495
      goto failure;
496
    }
497
    if(interrupted_by_signal){
498
      break;
499
    }
500
    
501
    buf_len += (size_t)sret;
502
  } while(sret != 0);
503
  ret = close(outfifo_fd);
504
  if(ret == -1){
505
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
506
      error_plus(0, errno, "close");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
507
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
508
    }
509
    goto failure;
510
  }
511
  outfifo_fd = -1;
512
  
513
  if(interrupted_by_signal){
514
    goto failure;
515
  }
516
  
517
  if(not usplash_write(&fifo_fd, "TIMEOUT", "15")){
518
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
519
      error_plus(0, errno, "usplash_write");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
520
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
521
    }
522
    goto failure;
523
  }
524
  
525
  if(interrupted_by_signal){
526
    goto failure;
527
  }
528
  
529
  ret = close(fifo_fd);
530
  if(ret == -1){
531
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
532
      error_plus(0, errno, "close");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
533
      status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
534
    }
535
    goto failure;
536
  }
537
  fifo_fd = -1;
538
  
539
  /* Print password to stdout */
540
  size_t written = 0;
541
  while(written < buf_len){
542
    do {
543
      sret = write(STDOUT_FILENO, buf + written, buf_len - written);
544
      if(sret == -1){
545
	if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
546
	  error_plus(0, errno, "write");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
547
	  status = EX_OSERR;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
548
	}
549
	goto failure;
550
      }
551
    } while(sret == -1);
552
    
553
    if(interrupted_by_signal){
554
      goto failure;
555
    }
556
    written += (size_t)sret;
557
  }
558
  free(buf);
559
  buf = NULL;
560
  
561
  if(interrupted_by_signal){
562
    goto failure;
563
  }
564
  
565
  free(cmdline);
566
  return EXIT_SUCCESS;
567
  
568
 failure:
569
  
570
  free(buf);
571
  
572
  free(prompt);
573
  
574
  /* If usplash was never accessed, we can stop now */
575
  if(not usplash_accessed){
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
576
    return status;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
577
  }
578
  
579
  /* Close FIFO */
580
  if(fifo_fd != -1){
774 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
581
    ret = close(fifo_fd);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
582
    if(ret == -1 and errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
583
      error_plus(0, errno, "close");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
584
    }
585
    fifo_fd = -1;
586
  }
587
  
588
  /* Close output FIFO */
589
  if(outfifo_fd != -1){
774 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
590
    ret = close(outfifo_fd);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
591
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
592
      error_plus(0, errno, "close");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
593
    }
594
  }
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
595
  
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
596
  /* Create argv for new usplash*/
432 by teddy at bsnet
* plugins.d/usplash.c (main): BUG FIX: allocate space for the final
597
  char **cmdline_argv = malloc((argz_count(cmdline, cmdline_len) + 1)
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
598
			       * sizeof(char *)); /* Count args */
599
  if(cmdline_argv == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
600
    error_plus(0, errno, "malloc");
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
601
    return status;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
602
  }
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
603
  argz_extract(cmdline, cmdline_len, cmdline_argv); /* Create argv */
604
  
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
605
  /* Kill old usplash */
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
606
  kill(usplash_pid, SIGTERM);
607
  sleep(2);
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
608
  while(kill(usplash_pid, 0) == 0){
609
    kill(usplash_pid, SIGKILL);
610
    sleep(1);
611
  }
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
612
  
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
613
  pid_t new_usplash_pid = fork();
614
  if(new_usplash_pid == 0){
615
    /* Child; will become new usplash process */
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
616
    
617
    /* Make the effective user ID (root) the only user ID instead of
265 by Teddy Hogeborn
* plugin-runner.c (main): Bug fix; do not accept a "d" character after
618
       the real user ID (_mandos) */
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
619
    ret = setuid(geteuid());
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
620
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
621
      error_plus(0, errno, "setuid");
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
622
    }
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
623
    
624
    setsid();
625
    ret = chdir("/");
24.1.148 by Björn Påhlsson
half working on-demand password and approved code
626
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
627
      error_plus(0, errno, "chdir");
24.1.148 by Björn Påhlsson
half working on-demand password and approved code
628
      _exit(EX_OSERR);
629
    }
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
630
/*     if(fork() != 0){ */
631
/*       _exit(EXIT_SUCCESS); */
632
/*     } */
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
633
    ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */
634
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
635
      error_plus(0, errno, "dup2");
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
636
      _exit(EX_OSERR);
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
637
    }
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
638
    
639
    execv(usplash_name, cmdline_argv);
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
640
    if(not interrupted_by_signal){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
641
      error_plus(0, errno, "execv");
223 by Teddy Hogeborn
* .bzrignore (plugins.d/askpass-fifo): Added.
642
    }
213 by Teddy Hogeborn
* plugins.d/usplash.c (main): Bug fix: Do not free "cmdline" too soon.
643
    free(cmdline);
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
644
    free(cmdline_argv);
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
645
    _exit(EX_OSERR);
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
646
  }
213 by Teddy Hogeborn
* plugins.d/usplash.c (main): Bug fix: Do not free "cmdline" too soon.
647
  free(cmdline);
212 by Teddy Hogeborn
* plugins.d/usplash.c (usplash_write): Move "cmd_line_len" up.
648
  free(cmdline_argv);
210 by Teddy Hogeborn
* debian/mandos-client.postinst: Change home directory to
649
  sleep(2);
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
650
  if(not usplash_write(&fifo_fd, "PULSATE", NULL)){
651
    if(errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
652
      error_plus(0, errno, "usplash_write");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
653
    }
654
  }
655
  
656
  /* Close FIFO (again) */
373 by Teddy Hogeborn
* plugins.d/usplash.c (main): Bug fix: only close FIFO if opened.
657
  if(fifo_fd != -1){
774 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
658
    ret = close(fifo_fd);
373 by Teddy Hogeborn
* plugins.d/usplash.c (main): Bug fix: only close FIFO if opened.
659
    if(ret == -1 and errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
660
      error_plus(0, errno, "close");
373 by Teddy Hogeborn
* plugins.d/usplash.c (main): Bug fix: only close FIFO if opened.
661
    }
662
    fifo_fd = -1;
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
663
  }
664
  
665
  if(interrupted_by_signal){
666
    struct sigaction signal_action = { .sa_handler = SIG_DFL };
667
    sigemptyset(&signal_action.sa_mask);
668
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
669
					    &signal_action, NULL));
670
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
671
      error_plus(0, errno, "sigaction");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
672
    }
673
    do {
674
      ret = raise(signal_received);
675
    } while(ret != 0 and errno == EINTR);
676
    if(ret != 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
677
      error_plus(0, errno, "raise");
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
678
      abort();
679
    }
680
    TEMP_FAILURE_RETRY(pause());
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
681
  }
682
  
396 by Teddy Hogeborn
* plugins.d/usplash.c: Use <sysexits.h> exit codes.
683
  return status;
208 by Teddy Hogeborn
* Makefile (PLUGINS): Added "plugins.d/usplash".
684
}