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