/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*  -*- coding: utf-8 -*- */
/*
 * Askpass-FIFO - Read a password from a FIFO and output it
 * 
 * Copyright © 2008,2009 Teddy Hogeborn
 * Copyright © 2008,2009 Björn Påhlsson
 * 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 * 
 * Contact the authors at <https://www.fukt.bsnet.se/~belorn/> and
 * <https://www.fukt.bsnet.se/~teddy/>.
 */

#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY() */
#include <sys/types.h>		/* ssize_t */
#include <sys/stat.h>		/* mkfifo(), S_IRUSR, S_IWUSR */
#include <iso646.h>		/* and */
#include <errno.h>		/* errno, EEXIST */
#include <stdio.h>		/* perror() */
#include <stdlib.h>		/* EXIT_FAILURE, NULL, size_t, free(), 
				   realloc(), EXIT_SUCCESS */
#include <fcntl.h>		/* open(), O_RDONLY */
#include <unistd.h>		/* read(), close(), write(),
				   STDOUT_FILENO */


int main(__attribute__((unused))int argc,
	 __attribute__((unused))char **argv){
  int ret = 0;
  ssize_t sret;
  
  /* Create FIFO */
  const char passfifo[] = "/lib/cryptsetup/passfifo";
  ret = (int)TEMP_FAILURE_RETRY(mkfifo(passfifo, S_IRUSR | S_IWUSR));
  if(ret == -1 and errno != EEXIST){
    perror("mkfifo");
    return EXIT_FAILURE;
  }
  
  /* Open FIFO */
  int fifo_fd = (int)TEMP_FAILURE_RETRY(open(passfifo, O_RDONLY));
  if(fifo_fd == -1){
    perror("open");
    return EXIT_FAILURE;
  }
  
  /* Read from FIFO */
  char *buf = NULL;
  size_t buf_len = 0;
  {
    size_t buf_allocated = 0;
    const size_t blocksize = 1024;
    do{
      if(buf_len + blocksize > buf_allocated){
	char *tmp = realloc(buf, buf_allocated + blocksize);
	if(tmp == NULL){
	  perror("realloc");
	  free(buf);
	  return EXIT_FAILURE;
	}
	buf = tmp;
	buf_allocated += blocksize;
      }
      sret = TEMP_FAILURE_RETRY(read(fifo_fd, buf + buf_len,
				     buf_allocated - buf_len));
      if(sret == -1){
	perror("read");
	free(buf);
	return EXIT_FAILURE;
      }
      buf_len += (size_t)sret;
    }while(sret != 0);
  }
  
  /* Close FIFO */
  TEMP_FAILURE_RETRY(close(fifo_fd));
  
  /* Print password to stdout */
  size_t written = 0;
  while(written < buf_len){
    sret = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buf + written,
				    buf_len - written));
    if(sret == -1){
      perror("write");
      free(buf);
      return EXIT_FAILURE;
    }
    written += (size_t)sret;
  }
  free(buf);
  
  return EXIT_SUCCESS;
}