/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1
/*  -*- coding: utf-8 -*- */
2
/*
261 by Teddy Hogeborn
* plugins.d/askpass-fifo.c: Fix name in header.
3
 * Mandos-client - get and decrypt data from a Mandos server
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
4
 *
5
 * This program is partly derived from an example program for an Avahi
6
 * service browser, downloaded from
7
 * <http://avahi.org/browser/examples/core-browse-services.c>.  This
8
 * includes the following functions: "resolve_callback",
9
 * "browse_callback", and parts of "main".
10
 * 
28 by Teddy Hogeborn
* server.conf: New file.
11
 * Everything else is
246 by Teddy Hogeborn
* README: Update copyright year; add "2009".
12
 * Copyright © 2008,2009 Teddy Hogeborn
13
 * Copyright © 2008,2009 Björn Påhlsson
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
14
 * 
15
 * This program is free software: you can redistribute it and/or
16
 * modify it under the terms of the GNU General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 * 
20
 * This program is distributed in the hope that it will be useful, but
21
 * WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23
 * General Public License for more details.
24
 * 
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program.  If not, see
27
 * <http://www.gnu.org/licenses/>.
28
 * 
31 by Teddy Hogeborn
* plugins.d/plugbasedclient.c: Update include file comments.
29
 * Contact the authors at <mandos@fukt.bsnet.se>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
30
 */
31
28 by Teddy Hogeborn
* server.conf: New file.
32
/* Needed by GPGME, specifically gpgme_data_seek() */
317 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
33
#ifndef _LARGEFILE_SOURCE
13 by Björn Påhlsson
Added following support:
34
#define _LARGEFILE_SOURCE
317 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
35
#endif
36
#ifndef _FILE_OFFSET_BITS
13 by Björn Påhlsson
Added following support:
37
#define _FILE_OFFSET_BITS 64
317 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
38
#endif
13 by Björn Påhlsson
Added following support:
39
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
40
#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY(), asprintf() */
24.1.10 by Björn Påhlsson
merge commit
41
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
42
#include <stdio.h>		/* fprintf(), stderr, fwrite(),
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
43
				   stdout, ferror(), remove() */
24.1.26 by Björn Påhlsson
tally count of used symbols
44
#include <stdint.h> 		/* uint16_t, uint32_t */
45
#include <stddef.h>		/* NULL, size_t, ssize_t */
24.1.29 by Björn Påhlsson
Added more header file comments
46
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, EXIT_FAILURE,
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
47
				   srand(), strtof() */
304 by Teddy Hogeborn
Four new interrelated features:
48
#include <stdbool.h>		/* bool, false, true */
24.1.29 by Björn Påhlsson
Added more header file comments
49
#include <string.h>		/* memset(), strcmp(), strlen(),
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
50
				   strerror(), asprintf(), strcpy() */
304 by Teddy Hogeborn
Four new interrelated features:
51
#include <sys/ioctl.h>		/* ioctl */
24.1.26 by Björn Påhlsson
tally count of used symbols
52
#include <sys/types.h>		/* socket(), inet_pton(), sockaddr,
24.1.29 by Björn Påhlsson
Added more header file comments
53
				   sockaddr_in6, PF_INET6,
304 by Teddy Hogeborn
Four new interrelated features:
54
				   SOCK_STREAM, uid_t, gid_t, open(),
55
				   opendir(), DIR */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
56
#include <sys/stat.h>		/* open() */
24.1.26 by Björn Påhlsson
tally count of used symbols
57
#include <sys/socket.h>		/* socket(), struct sockaddr_in6,
304 by Teddy Hogeborn
Four new interrelated features:
58
				   inet_pton(), connect() */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
59
#include <fcntl.h>		/* open() */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
60
#include <dirent.h>		/* opendir(), struct dirent, readdir()
61
				 */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
62
#include <inttypes.h>		/* PRIu16, PRIdMAX, intmax_t,
63
				   strtoimax() */
24.1.29 by Björn Påhlsson
Added more header file comments
64
#include <assert.h>		/* assert() */
65
#include <errno.h>		/* perror(), errno */
291 by Teddy Hogeborn
Merge from Björn:
66
#include <time.h>		/* nanosleep(), time() */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
67
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
24.1.26 by Björn Påhlsson
tally count of used symbols
68
				   SIOCSIFFLAGS, if_indextoname(),
69
				   if_nametoindex(), IF_NAMESIZE */
304 by Teddy Hogeborn
Four new interrelated features:
70
#include <netinet/in.h>		/* IN6_IS_ADDR_LINKLOCAL,
71
				   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
72
				*/
24.1.29 by Björn Påhlsson
Added more header file comments
73
#include <unistd.h>		/* close(), SEEK_SET, off_t, write(),
74
				   getuid(), getgid(), setuid(),
75
				   setgid() */
24.1.26 by Björn Påhlsson
tally count of used symbols
76
#include <arpa/inet.h>		/* inet_pton(), htons */
304 by Teddy Hogeborn
Four new interrelated features:
77
#include <iso646.h>		/* not, or, and */
24.1.29 by Björn Påhlsson
Added more header file comments
78
#include <argp.h>		/* struct argp_option, error_t, struct
79
				   argp_state, struct argp,
80
				   argp_parse(), ARGP_KEY_ARG,
81
				   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
307 by Teddy Hogeborn
Merge from Björn:
82
#include <signal.h>		/* sigemptyset(), sigaddset(),
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
83
				   sigaction(), SIGTERM, sigaction,
84
				   sig_atomic_t */
307 by Teddy Hogeborn
Merge from Björn:
85
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
86
#ifdef __linux__
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
87
#include <sys/klog.h> 		/* klogctl() */
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
88
#endif	/* __linux__ */
24.1.26 by Björn Påhlsson
tally count of used symbols
89
90
/* Avahi */
24.1.29 by Björn Påhlsson
Added more header file comments
91
/* All Avahi types, constants and functions
92
 Avahi*, avahi_*,
93
 AVAHI_* */
94
#include <avahi-core/core.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
95
#include <avahi-core/lookup.h>
24.1.29 by Björn Påhlsson
Added more header file comments
96
#include <avahi-core/log.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
97
#include <avahi-common/simple-watch.h>
98
#include <avahi-common/malloc.h>
99
#include <avahi-common/error.h>
100
101
/* GnuTLS */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
102
#include <gnutls/gnutls.h>	/* All GnuTLS types, constants and
103
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
104
				   gnutls_*
24.1.26 by Björn Påhlsson
tally count of used symbols
105
				   init_gnutls_session(),
24.1.29 by Björn Påhlsson
Added more header file comments
106
				   GNUTLS_* */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
107
#include <gnutls/openpgp.h>
108
			  /* gnutls_certificate_set_openpgp_key_file(),
24.1.29 by Björn Påhlsson
Added more header file comments
109
				   GNUTLS_OPENPGP_FMT_BASE64 */
24.1.26 by Björn Påhlsson
tally count of used symbols
110
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
111
/* GPGME */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
112
#include <gpgme.h> 		/* All GPGME types, constants and
113
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
114
				   gpgme_*
24.1.26 by Björn Påhlsson
tally count of used symbols
115
				   GPGME_PROTOCOL_OpenPGP,
24.1.29 by Björn Påhlsson
Added more header file comments
116
				   GPG_ERR_NO_* */
13 by Björn Påhlsson
Added following support:
117
118
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
119
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
120
#define PATHDIR "/conf/conf.d/mandos"
121
#define SECKEY "seckey.txt"
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
122
#define PUBKEY "pubkey.txt"
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
123
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
124
bool debug = false;
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
125
static const char mandos_protocol_version[] = "1";
217 by Teddy Hogeborn
* .bzrignore: Added "man" directory (created by "make install-html").
126
const char *argp_program_version = "mandos-client " VERSION;
24.1.14 by Björn Påhlsson
mandosclient
127
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
24.1.10 by Björn Påhlsson
merge commit
128
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
129
/* Used for passing in values through the Avahi callback functions */
13 by Björn Påhlsson
Added following support:
130
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
131
  AvahiSimplePoll *simple_poll;
132
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
133
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
134
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
135
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
136
  const char *priority;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
137
  gpgme_ctx_t ctx;
24.1.9 by Björn Påhlsson
not working midwork...
138
} mandos_context;
13 by Björn Påhlsson
Added following support:
139
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
140
/* global context so signal handler can reach it*/
24.1.135 by Björn Påhlsson
Earlier signal handling
141
mandos_context mc = { .simple_poll = NULL, .server = NULL,
142
		      .dh_bits = 1024, .priority = "SECURE256"
143
		      ":!CTYPE-X.509:+CTYPE-OPENPGP" };
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
144
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
145
/*
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
146
 * Make additional room in "buffer" for at least BUFFER_SIZE more
147
 * bytes. "buffer_capacity" is how much is currently allocated,
148
 * "buffer_length" is how much is already used.
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
149
 */
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
150
size_t incbuffer(char **buffer, size_t buffer_length,
24.1.10 by Björn Påhlsson
merge commit
151
		  size_t buffer_capacity){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
152
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
24.1.12 by Björn Påhlsson
merge +
153
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
154
    if(buffer == NULL){
24.1.10 by Björn Påhlsson
merge commit
155
      return 0;
156
    }
157
    buffer_capacity += BUFFER_SIZE;
158
  }
159
  return buffer_capacity;
160
}
161
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
162
/* 
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
163
 * Initialize GPGME.
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
164
 */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
165
static bool init_gpgme(const char *seckey,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
166
		       const char *pubkey, const char *tempdir){
167
  int ret;
13 by Björn Påhlsson
Added following support:
168
  gpgme_error_t rc;
169
  gpgme_engine_info_t engine_info;
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
170
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
171
  
172
  /*
288 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use separate bool variable instead
173
   * Helper function to insert pub and seckey to the engine keyring.
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
174
   */
175
  bool import_key(const char *filename){
176
    int fd;
177
    gpgme_data_t pgp_data;
178
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
179
    fd = (int)TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
180
    if(fd == -1){
181
      perror("open");
182
      return false;
183
    }
184
    
185
    rc = gpgme_data_new_from_fd(&pgp_data, fd);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
186
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
187
      fprintf(stderr, "bad gpgme_data_new_from_fd: %s: %s\n",
188
	      gpgme_strsource(rc), gpgme_strerror(rc));
189
      return false;
190
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
191
    
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
192
    rc = gpgme_op_import(mc.ctx, pgp_data);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
193
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
194
      fprintf(stderr, "bad gpgme_op_import: %s: %s\n",
195
	      gpgme_strsource(rc), gpgme_strerror(rc));
196
      return false;
197
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
198
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
199
    ret = (int)TEMP_FAILURE_RETRY(close(fd));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
200
    if(ret == -1){
201
      perror("close");
202
    }
203
    gpgme_data_release(pgp_data);
204
    return true;
205
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
206
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
207
  if(debug){
307 by Teddy Hogeborn
Merge from Björn:
208
    fprintf(stderr, "Initializing GPGME\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
209
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
210
  
13 by Björn Påhlsson
Added following support:
211
  /* Init GPGME */
212
  gpgme_check_version(NULL);
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
213
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
214
  if(rc != GPG_ERR_NO_ERROR){
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
215
    fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
216
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
217
    return false;
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
218
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
219
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
220
    /* Set GPGME home directory for the OpenPGP engine only */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
221
  rc = gpgme_get_engine_info(&engine_info);
222
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
223
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
224
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
225
    return false;
13 by Björn Påhlsson
Added following support:
226
  }
227
  while(engine_info != NULL){
228
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
229
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
230
			    engine_info->file_name, tempdir);
13 by Björn Påhlsson
Added following support:
231
      break;
232
    }
233
    engine_info = engine_info->next;
234
  }
235
  if(engine_info == NULL){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
236
    fprintf(stderr, "Could not set GPGME home dir to %s\n", tempdir);
237
    return false;
238
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
239
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
240
  /* Create new GPGME "context" */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
241
  rc = gpgme_new(&(mc.ctx));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
242
  if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
243
    fprintf(stderr, "bad gpgme_new: %s: %s\n",
244
	    gpgme_strsource(rc), gpgme_strerror(rc));
245
    return false;
246
  }
247
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
248
  if(not import_key(pubkey) or not import_key(seckey)){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
249
    return false;
250
  }
251
  
252
  return true; 
253
}
254
255
/* 
256
 * Decrypt OpenPGP data.
257
 * Returns -1 on error
258
 */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
259
static ssize_t pgp_packet_decrypt(const char *cryptotext,
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
260
				  size_t crypto_size,
261
				  char **plaintext){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
262
  gpgme_data_t dh_crypto, dh_plain;
263
  gpgme_error_t rc;
264
  ssize_t ret;
265
  size_t plaintext_capacity = 0;
266
  ssize_t plaintext_length = 0;
267
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
268
  if(debug){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
269
    fprintf(stderr, "Trying to decrypt OpenPGP data\n");
13 by Björn Påhlsson
Added following support:
270
  }
271
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
272
  /* Create new GPGME data buffer from memory cryptotext */
273
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
274
			       0);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
275
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
276
    fprintf(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
277
	    gpgme_strsource(rc), gpgme_strerror(rc));
278
    return -1;
279
  }
280
  
281
  /* Create new empty GPGME data buffer for the plaintext */
282
  rc = gpgme_data_new(&dh_plain);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
283
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
284
    fprintf(stderr, "bad gpgme_data_new: %s: %s\n",
285
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
286
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
287
    return -1;
288
  }
289
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
290
  /* Decrypt data from the cryptotext data buffer to the plaintext
291
     data buffer */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
292
  rc = gpgme_op_decrypt(mc.ctx, dh_crypto, dh_plain);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
293
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
294
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
295
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
296
    plaintext_length = -1;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
297
    if(debug){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
298
      gpgme_decrypt_result_t result;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
299
      result = gpgme_op_decrypt_result(mc.ctx);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
300
      if(result == NULL){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
301
	fprintf(stderr, "gpgme_op_decrypt_result failed\n");
302
      } else {
303
	fprintf(stderr, "Unsupported algorithm: %s\n",
304
		result->unsupported_algorithm);
305
	fprintf(stderr, "Wrong key usage: %u\n",
306
		result->wrong_key_usage);
307
	if(result->file_name != NULL){
308
	  fprintf(stderr, "File name: %s\n", result->file_name);
309
	}
310
	gpgme_recipient_t recipient;
311
	recipient = result->recipients;
349 by Teddy Hogeborn
* plugins.d/mandos-client.c (pgp_packet_decrypt): Remove redundant
312
	while(recipient != NULL){
313
	  fprintf(stderr, "Public key algorithm: %s\n",
314
		  gpgme_pubkey_algo_name(recipient->pubkey_algo));
315
	  fprintf(stderr, "Key ID: %s\n", recipient->keyid);
316
	  fprintf(stderr, "Secret key available: %s\n",
317
		  recipient->status == GPG_ERR_NO_SECKEY
318
		  ? "No" : "Yes");
319
	  recipient = recipient->next;
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
320
	}
321
      }
322
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
323
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
324
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
325
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
326
  if(debug){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
327
    fprintf(stderr, "Decryption of OpenPGP data succeeded\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
328
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
329
  
13 by Björn Påhlsson
Added following support:
330
  /* Seek back to the beginning of the GPGME plaintext data buffer */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
331
  if(gpgme_data_seek(dh_plain, (off_t)0, SEEK_SET) == -1){
24.1.92 by Björn Påhlsson
Several memory leaks detected by valgrind fixed
332
    perror("gpgme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
333
    plaintext_length = -1;
334
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
335
  }
336
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
337
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
338
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
339
    plaintext_capacity = incbuffer(plaintext,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
340
				      (size_t)plaintext_length,
24.1.12 by Björn Påhlsson
merge +
341
				      plaintext_capacity);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
342
    if(plaintext_capacity == 0){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
343
	perror("incbuffer");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
344
	plaintext_length = -1;
345
	goto decrypt_end;
13 by Björn Påhlsson
Added following support:
346
    }
347
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
348
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
349
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
350
    /* Print the data, if any */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
351
    if(ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
352
      /* EOF */
13 by Björn Påhlsson
Added following support:
353
      break;
354
    }
355
    if(ret < 0){
356
      perror("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
357
      plaintext_length = -1;
358
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
359
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
360
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
361
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
362
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
363
  if(debug){
364
    fprintf(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
365
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
366
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
367
    }
368
    fprintf(stderr, "\n");
369
  }
370
  
371
 decrypt_end:
372
  
373
  /* Delete the GPGME cryptotext data buffer */
374
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
375
  
376
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
377
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
378
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
379
}
380
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
381
static const char * safer_gnutls_strerror(int value){
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
382
  const char *ret = gnutls_strerror(value); /* Spurious warning from
383
					       -Wunreachable-code */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
384
  if(ret == NULL)
13 by Björn Påhlsson
Added following support:
385
    ret = "(unknown)";
386
  return ret;
387
}
388
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
389
/* GnuTLS log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
390
static void debuggnutls(__attribute__((unused)) int level,
391
			const char* string){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
392
  fprintf(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
393
}
394
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
395
static int init_gnutls_global(const char *pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
396
			      const char *seckeyfilename){
13 by Björn Påhlsson
Added following support:
397
  int ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
398
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
399
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
400
    fprintf(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
401
  }
24.1.29 by Björn Påhlsson
Added more header file comments
402
  
403
  ret = gnutls_global_init();
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
404
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
405
    fprintf(stderr, "GnuTLS global_init: %s\n",
406
	    safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
407
    return -1;
408
  }
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
409
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
410
  if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
411
    /* "Use a log level over 10 to enable all debugging options."
412
     * - GnuTLS manual
413
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
414
    gnutls_global_set_log_level(11);
415
    gnutls_global_set_log_function(debuggnutls);
416
  }
417
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
418
  /* OpenPGP credentials */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
419
  gnutls_certificate_allocate_credentials(&mc.cred);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
420
  if(ret != GNUTLS_E_SUCCESS){
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
421
    fprintf(stderr, "GnuTLS memory error: %s\n", /* Spurious warning
304 by Teddy Hogeborn
Four new interrelated features:
422
						    from
423
						    -Wunreachable-code
424
						 */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
425
	    safer_gnutls_strerror(ret));
426
    gnutls_global_deinit();
13 by Björn Påhlsson
Added following support:
427
    return -1;
428
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
429
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
430
  if(debug){
147 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Improved wording
431
    fprintf(stderr, "Attempting to use OpenPGP public key %s and"
432
	    " secret key %s as GnuTLS credentials\n", pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
433
	    seckeyfilename);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
434
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
435
  
13 by Björn Påhlsson
Added following support:
436
  ret = gnutls_certificate_set_openpgp_key_file
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
437
    (mc.cred, pubkeyfilename, seckeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
438
     GNUTLS_OPENPGP_FMT_BASE64);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
439
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
440
    fprintf(stderr,
441
	    "Error[%d] while reading the OpenPGP key pair ('%s',"
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
442
	    " '%s')\n", ret, pubkeyfilename, seckeyfilename);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
443
    fprintf(stderr, "The GnuTLS error is: %s\n",
13 by Björn Påhlsson
Added following support:
444
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
445
    goto globalfail;
13 by Björn Påhlsson
Added following support:
446
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
447
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
448
  /* GnuTLS server initialization */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
449
  ret = gnutls_dh_params_init(&mc.dh_params);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
450
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
451
    fprintf(stderr, "Error in GnuTLS DH parameter initialization:"
452
	    " %s\n", safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
453
    goto globalfail;
13 by Björn Påhlsson
Added following support:
454
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
455
  ret = gnutls_dh_params_generate2(mc.dh_params, mc.dh_bits);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
456
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
457
    fprintf(stderr, "Error in GnuTLS prime generation: %s\n",
458
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
459
    goto globalfail;
13 by Björn Påhlsson
Added following support:
460
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
461
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
462
  gnutls_certificate_set_dh_params(mc.cred, mc.dh_params);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
463
  
24.1.13 by Björn Påhlsson
mandosclient
464
  return 0;
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
465
  
24.1.20 by Björn Påhlsson
mandosclient
466
 globalfail:
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
467
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
468
  gnutls_certificate_free_credentials(mc.cred);
24.1.26 by Björn Påhlsson
tally count of used symbols
469
  gnutls_global_deinit();
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
470
  gnutls_dh_params_deinit(mc.dh_params);
24.1.20 by Björn Påhlsson
mandosclient
471
  return -1;
24.1.13 by Björn Påhlsson
mandosclient
472
}
473
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
474
static int init_gnutls_session(gnutls_session_t *session){
24.1.13 by Björn Påhlsson
mandosclient
475
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
476
  /* GnuTLS session creation */
477
  ret = gnutls_init(session, GNUTLS_SERVER);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
478
  if(ret != GNUTLS_E_SUCCESS){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
479
    fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
13 by Björn Påhlsson
Added following support:
480
	    safer_gnutls_strerror(ret));
481
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
482
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
483
  {
484
    const char *err;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
485
    ret = gnutls_priority_set_direct(*session, mc.priority, &err);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
486
    if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
487
      fprintf(stderr, "Syntax error at: %s\n", err);
488
      fprintf(stderr, "GnuTLS error: %s\n",
489
	      safer_gnutls_strerror(ret));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
490
      gnutls_deinit(*session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
491
      return -1;
492
    }
13 by Björn Påhlsson
Added following support:
493
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
494
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
495
  ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
496
			       mc.cred);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
497
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
498
    fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
13 by Björn Påhlsson
Added following support:
499
	    safer_gnutls_strerror(ret));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
500
    gnutls_deinit(*session);
13 by Björn Påhlsson
Added following support:
501
    return -1;
502
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
503
  
13 by Björn Påhlsson
Added following support:
504
  /* ignore client certificate if any. */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
505
  gnutls_certificate_server_set_request(*session,
506
					GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
507
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
508
  gnutls_dh_set_prime_bits(*session, mc.dh_bits);
13 by Björn Påhlsson
Added following support:
509
  
510
  return 0;
511
}
512
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
513
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
514
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
515
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
516
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
517
/* Called when a Mandos server is found */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
518
static int start_mandos_communication(const char *ip, uint16_t port,
24.1.9 by Björn Påhlsson
not working midwork...
519
				      AvahiIfIndex if_index,
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
520
				      int af){
13 by Björn Påhlsson
Added following support:
521
  int ret, tcp_sd;
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
522
  ssize_t sret;
304 by Teddy Hogeborn
Four new interrelated features:
523
  union {
524
    struct sockaddr_in in;
525
    struct sockaddr_in6 in6;
526
  } to;
13 by Björn Påhlsson
Added following support:
527
  char *buffer = NULL;
528
  char *decrypted_buffer;
529
  size_t buffer_length = 0;
530
  size_t buffer_capacity = 0;
531
  ssize_t decrypted_buffer_size;
24.1.10 by Björn Påhlsson
merge commit
532
  size_t written;
13 by Björn Påhlsson
Added following support:
533
  int retval = 0;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
534
  gnutls_session_t session;
304 by Teddy Hogeborn
Four new interrelated features:
535
  int pf;			/* Protocol family */
536
  
537
  switch(af){
538
  case AF_INET6:
539
    pf = PF_INET6;
540
    break;
541
  case AF_INET:
542
    pf = PF_INET;
543
    break;
544
  default:
545
    fprintf(stderr, "Bad address family: %d\n", af);
546
    return -1;
547
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
548
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
549
  ret = init_gnutls_session(&session);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
550
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
551
    return -1;
552
  }
553
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
554
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
555
    fprintf(stderr, "Setting up a TCP connection to %s, port %" PRIu16
60 by Teddy Hogeborn
* mandos-client.c (main): Cast pid_t to unsigned int before printing.
556
	    "\n", ip, port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
557
  }
13 by Björn Påhlsson
Added following support:
558
  
304 by Teddy Hogeborn
Four new interrelated features:
559
  tcp_sd = socket(pf, SOCK_STREAM, 0);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
560
  if(tcp_sd < 0){
13 by Björn Påhlsson
Added following support:
561
    perror("socket");
562
    return -1;
563
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
564
  
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
565
  memset(&to, 0, sizeof(to));
304 by Teddy Hogeborn
Four new interrelated features:
566
  if(af == AF_INET6){
325 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): "sin6_family"
567
    to.in6.sin6_family = (sa_family_t)af;
304 by Teddy Hogeborn
Four new interrelated features:
568
    ret = inet_pton(af, ip, &to.in6.sin6_addr);
569
  } else {			/* IPv4 */
570
    to.in.sin_family = (sa_family_t)af;
571
    ret = inet_pton(af, ip, &to.in.sin_addr);
572
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
573
  if(ret < 0 ){
13 by Björn Påhlsson
Added following support:
574
    perror("inet_pton");
575
    return -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
576
  }
13 by Björn Påhlsson
Added following support:
577
  if(ret == 0){
578
    fprintf(stderr, "Bad address: %s\n", ip);
579
    return -1;
580
  }
304 by Teddy Hogeborn
Four new interrelated features:
581
  if(af == AF_INET6){
582
    to.in6.sin6_port = htons(port); /* Spurious warnings from
583
				       -Wconversion and
584
				       -Wunreachable-code */
585
    
586
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
587
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
588
			      -Wunreachable-code*/
589
      if(if_index == AVAHI_IF_UNSPEC){
590
	fprintf(stderr, "An IPv6 link-local address is incomplete"
591
		" without a network interface\n");
592
	return -1;
593
      }
594
      /* Set the network interface number as scope */
595
      to.in6.sin6_scope_id = (uint32_t)if_index;
596
    }
597
  } else {
598
    to.in.sin_port = htons(port); /* Spurious warnings from
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
599
				     -Wconversion and
600
				     -Wunreachable-code */
304 by Teddy Hogeborn
Four new interrelated features:
601
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
602
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
603
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
604
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
605
      char interface[IF_NAMESIZE];
606
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
607
	perror("if_indextoname");
608
      } else {
609
	fprintf(stderr, "Connection to: %s%%%s, port %" PRIu16 "\n",
610
		ip, interface, port);
611
      }
612
    } else {
613
      fprintf(stderr, "Connection to: %s, port %" PRIu16 "\n", ip,
614
	      port);
615
    }
616
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
617
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
618
    const char *pcret;
619
    if(af == AF_INET6){
620
      pcret = inet_ntop(af, &(to.in6.sin6_addr), addrstr,
621
			sizeof(addrstr));
622
    } else {
623
      pcret = inet_ntop(af, &(to.in.sin_addr), addrstr,
624
			sizeof(addrstr));
625
    }
626
    if(pcret == NULL){
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
627
      perror("inet_ntop");
628
    } else {
629
      if(strcmp(addrstr, ip) != 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
630
	fprintf(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
631
      }
632
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
633
  }
13 by Björn Påhlsson
Added following support:
634
  
304 by Teddy Hogeborn
Four new interrelated features:
635
  if(af == AF_INET6){
636
    ret = connect(tcp_sd, &to.in6, sizeof(to));
637
  } else {
638
    ret = connect(tcp_sd, &to.in, sizeof(to)); /* IPv4 */
639
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
640
  if(ret < 0){
13 by Björn Påhlsson
Added following support:
641
    perror("connect");
642
    return -1;
643
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
644
  
24.1.12 by Björn Påhlsson
merge +
645
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
646
  written = 0;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
647
  while(true){
24.1.10 by Björn Påhlsson
merge commit
648
    size_t out_size = strlen(out);
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
649
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
24.1.10 by Björn Påhlsson
merge commit
650
				   out_size - written));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
651
    if(ret == -1){
24.1.10 by Björn Påhlsson
merge commit
652
      perror("write");
653
      retval = -1;
24.1.12 by Björn Påhlsson
merge +
654
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
655
    }
24.1.12 by Björn Påhlsson
merge +
656
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
657
    if(written < out_size){
658
      continue;
659
    } else {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
660
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
661
	written = 0;
662
	out = "\r\n";
663
      } else {
664
	break;
665
      }
666
    }
667
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
668
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
669
  if(debug){
670
    fprintf(stderr, "Establishing TLS session with %s\n", ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
671
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
672
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
673
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
674
  
24.1.29 by Björn Påhlsson
Added more header file comments
675
  do{
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
676
    ret = gnutls_handshake(session);
24.1.29 by Björn Påhlsson
Added more header file comments
677
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
678
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
679
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
680
    if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
681
      fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
682
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
683
    }
13 by Björn Påhlsson
Added following support:
684
    retval = -1;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
685
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
686
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
687
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
688
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
689
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
690
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
691
    fprintf(stderr, "Retrieving OpenPGP encrypted password from %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
692
	    ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
693
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
694
  
13 by Björn Påhlsson
Added following support:
695
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
696
    buffer_capacity = incbuffer(&buffer, buffer_length,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
697
				   buffer_capacity);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
698
    if(buffer_capacity == 0){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
699
      perror("incbuffer");
24.1.10 by Björn Påhlsson
merge commit
700
      retval = -1;
24.1.12 by Björn Påhlsson
merge +
701
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
702
    }
703
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
704
    sret = gnutls_record_recv(session, buffer+buffer_length,
705
			      BUFFER_SIZE);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
706
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
707
      break;
708
    }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
709
    if(sret < 0){
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
710
      switch(sret){
13 by Björn Påhlsson
Added following support:
711
      case GNUTLS_E_INTERRUPTED:
712
      case GNUTLS_E_AGAIN:
713
	break;
714
      case GNUTLS_E_REHANDSHAKE:
24.1.29 by Björn Påhlsson
Added more header file comments
715
	do{
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
716
	  ret = gnutls_handshake(session);
24.1.29 by Björn Påhlsson
Added more header file comments
717
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
718
	if(ret < 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
719
	  fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
720
	  gnutls_perror(ret);
13 by Björn Påhlsson
Added following support:
721
	  retval = -1;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
722
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
723
	}
724
	break;
725
      default:
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
726
	fprintf(stderr, "Unknown error while reading data from"
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
727
		" encrypted session with Mandos server\n");
13 by Björn Påhlsson
Added following support:
728
	retval = -1;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
729
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
730
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
731
      }
732
    } else {
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
733
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
734
    }
735
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
736
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
737
  if(debug){
738
    fprintf(stderr, "Closing TLS session\n");
739
  }
740
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
741
  gnutls_bye(session, GNUTLS_SHUT_RDWR);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
742
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
743
  if(buffer_length > 0){
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
744
    decrypted_buffer_size = pgp_packet_decrypt(buffer,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
745
					       buffer_length,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
746
					       &decrypted_buffer);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
747
    if(decrypted_buffer_size >= 0){
24.1.10 by Björn Påhlsson
merge commit
748
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
749
      while(written < (size_t) decrypted_buffer_size){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
750
	ret = (int)fwrite(decrypted_buffer + written, 1,
751
			  (size_t)decrypted_buffer_size - written,
752
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
753
	if(ret == 0 and ferror(stdout)){
754
	  if(debug){
755
	    fprintf(stderr, "Error writing encrypted data: %s\n",
756
		    strerror(errno));
757
	  }
758
	  retval = -1;
759
	  break;
760
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
761
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
762
      }
13 by Björn Påhlsson
Added following support:
763
      free(decrypted_buffer);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
764
    } else {
765
      retval = -1;
13 by Björn Påhlsson
Added following support:
766
    }
24.1.63 by Björn Påhlsson
merge + fallback bugg
767
  } else {
768
    retval = -1;
13 by Björn Påhlsson
Added following support:
769
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
770
  
771
  /* Shutdown procedure */
772
  
773
 mandos_end:
13 by Björn Påhlsson
Added following support:
774
  free(buffer);
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
775
  ret = (int)TEMP_FAILURE_RETRY(close(tcp_sd));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
776
  if(ret == -1){
777
    perror("close");
778
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
779
  gnutls_deinit(session);
13 by Björn Påhlsson
Added following support:
780
  return retval;
781
}
782
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
783
static void resolve_callback(AvahiSServiceResolver *r,
784
			     AvahiIfIndex interface,
304 by Teddy Hogeborn
Four new interrelated features:
785
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
786
			     AvahiResolverEvent event,
787
			     const char *name,
788
			     const char *type,
789
			     const char *domain,
790
			     const char *host_name,
791
			     const AvahiAddress *address,
792
			     uint16_t port,
793
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
794
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
795
			     flags,
307 by Teddy Hogeborn
Merge from Björn:
796
			     AVAHI_GCC_UNUSED void* userdata){
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
797
  assert(r);
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
798
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
799
  /* Called whenever a service has been resolved successfully or
800
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
801
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
802
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
803
  default:
804
  case AVAHI_RESOLVER_FAILURE:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
805
    fprintf(stderr, "(Avahi Resolver) Failed to resolve service '%s'"
806
	    " of type '%s' in domain '%s': %s\n", name, type, domain,
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
807
	    avahi_strerror(avahi_server_errno(mc.server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
808
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
809
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
810
  case AVAHI_RESOLVER_FOUND:
811
    {
812
      char ip[AVAHI_ADDRESS_STR_MAX];
813
      avahi_address_snprint(ip, sizeof(ip), address);
814
      if(debug){
60 by Teddy Hogeborn
* mandos-client.c (main): Cast pid_t to unsigned int before printing.
815
	fprintf(stderr, "Mandos server \"%s\" found on %s (%s, %"
268 by Teddy Hogeborn
Fixes for sscanf usage:
816
		PRIdMAX ") on port %" PRIu16 "\n", name, host_name,
817
		ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
818
      }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
819
      int ret = start_mandos_communication(ip, port, interface,
304 by Teddy Hogeborn
Four new interrelated features:
820
					   avahi_proto_to_af(proto));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
821
      if(ret == 0){
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
822
	avahi_simple_poll_quit(mc.simple_poll);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
823
      }
13 by Björn Påhlsson
Added following support:
824
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
825
  }
826
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
827
}
828
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
829
static void browse_callback(AvahiSServiceBrowser *b,
830
			    AvahiIfIndex interface,
831
			    AvahiProtocol protocol,
832
			    AvahiBrowserEvent event,
833
			    const char *name,
834
			    const char *type,
835
			    const char *domain,
836
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
837
			    flags,
307 by Teddy Hogeborn
Merge from Björn:
838
			    AVAHI_GCC_UNUSED void* userdata){
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
839
  assert(b);
24.1.9 by Björn Påhlsson
not working midwork...
840
  
841
  /* Called whenever a new services becomes available on the LAN or
842
     is removed from the LAN */
843
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
844
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
845
  default:
846
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
847
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
848
    fprintf(stderr, "(Avahi browser) %s\n",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
849
	    avahi_strerror(avahi_server_errno(mc.server)));
850
    avahi_simple_poll_quit(mc.simple_poll);
24.1.9 by Björn Påhlsson
not working midwork...
851
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
852
    
24.1.9 by Björn Påhlsson
not working midwork...
853
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
854
    /* We ignore the returned Avahi resolver object. In the callback
855
       function we free it. If the Avahi server is terminated before
856
       the callback function is called the Avahi server will free the
857
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
858
    
313 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
859
    if(avahi_s_service_resolver_new(mc.server, interface, protocol,
860
				    name, type, domain, protocol, 0,
861
				    resolve_callback, NULL) == NULL)
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
862
      fprintf(stderr, "Avahi: Failed to resolve service '%s': %s\n",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
863
	      name, avahi_strerror(avahi_server_errno(mc.server)));
24.1.9 by Björn Påhlsson
not working midwork...
864
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
865
    
24.1.9 by Björn Påhlsson
not working midwork...
866
  case AVAHI_BROWSER_REMOVE:
867
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
868
    
24.1.9 by Björn Påhlsson
not working midwork...
869
  case AVAHI_BROWSER_ALL_FOR_NOW:
870
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
871
    if(debug){
872
      fprintf(stderr, "No Mandos server found, still searching...\n");
873
    }
24.1.9 by Björn Påhlsson
not working midwork...
874
    break;
875
  }
13 by Björn Påhlsson
Added following support:
876
}
877
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
878
sig_atomic_t quit_now = 0;
879
24.1.135 by Björn Påhlsson
Earlier signal handling
880
/* stop main loop after sigterm has been called */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
881
static void handle_sigterm(__attribute__((unused)) int sig){
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
882
  if(quit_now){
883
    return;
884
  }
885
  quit_now = 1;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
886
  int old_errno = errno;
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
887
  if(mc.simple_poll != NULL){
888
    avahi_simple_poll_quit(mc.simple_poll);
889
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
890
  errno = old_errno;
891
}
892
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
893
int main(int argc, char *argv[]){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
894
  AvahiSServiceBrowser *sb = NULL;
895
  int error;
896
  int ret;
897
  intmax_t tmpmax;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
898
  char *tmp;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
899
  int exitcode = EXIT_SUCCESS;
900
  const char *interface = "eth0";
901
  struct ifreq network;
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
902
  int sd = -1;
903
  bool interface_taken_up = false;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
904
  uid_t uid;
905
  gid_t gid;
906
  char *connect_to = NULL;
907
  char tempdir[] = "/tmp/mandosXXXXXX";
908
  bool tempdir_created = false;
909
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
910
  const char *seckey = PATHDIR "/" SECKEY;
911
  const char *pubkey = PATHDIR "/" PUBKEY;
912
  
913
  bool gnutls_initialized = false;
914
  bool gpgme_initialized = false;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
915
  float delay = 2.5f;
916
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
917
  struct sigaction old_sigterm_action;
918
  struct sigaction sigterm_action = { .sa_handler = handle_sigterm };
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
919
  
920
  {
921
    struct argp_option options[] = {
922
      { .name = "debug", .key = 128,
923
	.doc = "Debug mode", .group = 3 },
924
      { .name = "connect", .key = 'c',
925
	.arg = "ADDRESS:PORT",
926
	.doc = "Connect directly to a specific Mandos server",
927
	.group = 1 },
928
      { .name = "interface", .key = 'i',
929
	.arg = "NAME",
304 by Teddy Hogeborn
Four new interrelated features:
930
	.doc = "Network interface that will be used to search for"
931
	" Mandos servers",
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
932
	.group = 1 },
933
      { .name = "seckey", .key = 's',
934
	.arg = "FILE",
935
	.doc = "OpenPGP secret key file base name",
936
	.group = 1 },
937
      { .name = "pubkey", .key = 'p',
938
	.arg = "FILE",
939
	.doc = "OpenPGP public key file base name",
940
	.group = 2 },
941
      { .name = "dh-bits", .key = 129,
942
	.arg = "BITS",
943
	.doc = "Bit length of the prime number used in the"
944
	" Diffie-Hellman key exchange",
945
	.group = 2 },
946
      { .name = "priority", .key = 130,
947
	.arg = "STRING",
948
	.doc = "GnuTLS priority string for the TLS handshake",
949
	.group = 1 },
950
      { .name = "delay", .key = 131,
951
	.arg = "SECONDS",
952
	.doc = "Maximum delay to wait for interface startup",
953
	.group = 2 },
954
      { .name = NULL }
955
    };
956
    
957
    error_t parse_opt(int key, char *arg,
958
		      struct argp_state *state){
959
      switch(key){
960
      case 128:			/* --debug */
961
	debug = true;
962
	break;
963
      case 'c':			/* --connect */
964
	connect_to = arg;
965
	break;
966
      case 'i':			/* --interface */
967
	interface = arg;
968
	break;
969
      case 's':			/* --seckey */
970
	seckey = arg;
971
	break;
972
      case 'p':			/* --pubkey */
973
	pubkey = arg;
974
	break;
975
      case 129:			/* --dh-bits */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
976
	errno = 0;
977
	tmpmax = strtoimax(arg, &tmp, 10);
978
	if(errno != 0 or tmp == arg or *tmp != '\0'
979
	   or tmpmax != (typeof(mc.dh_bits))tmpmax){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
980
	  fprintf(stderr, "Bad number of DH bits\n");
981
	  exit(EXIT_FAILURE);
982
	}
983
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
984
	break;
985
      case 130:			/* --priority */
986
	mc.priority = arg;
987
	break;
988
      case 131:			/* --delay */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
989
	errno = 0;
990
	delay = strtof(arg, &tmp);
991
	if(errno != 0 or tmp == arg or *tmp != '\0'){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
992
	  fprintf(stderr, "Bad delay\n");
993
	  exit(EXIT_FAILURE);
994
	}
995
	break;
996
      case ARGP_KEY_ARG:
997
	argp_usage(state);
998
      case ARGP_KEY_END:
999
	break;
1000
      default:
1001
	return ARGP_ERR_UNKNOWN;
1002
      }
1003
      return 0;
1004
    }
1005
    
1006
    struct argp argp = { .options = options, .parser = parse_opt,
1007
			 .args_doc = "",
1008
			 .doc = "Mandos client -- Get and decrypt"
1009
			 " passwords from a Mandos server" };
1010
    ret = argp_parse(&argp, argc, argv, 0, 0, NULL);
1011
    if(ret == ARGP_ERR_UNKNOWN){
1012
      fprintf(stderr, "Unknown error while parsing arguments\n");
1013
      exitcode = EXIT_FAILURE;
1014
      goto end;
1015
    }
1016
  }
1017
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1018
  if(not debug){
1019
    avahi_set_log_function(empty_log);
1020
  }
309 by Teddy Hogeborn
Merge from Björn:
1021
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1022
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
1023
     from the signal handler */
1024
  /* Initialize the pseudo-RNG for Avahi */
1025
  srand((unsigned int) time(NULL));
1026
  mc.simple_poll = avahi_simple_poll_new();
1027
  if(mc.simple_poll == NULL){
1028
    fprintf(stderr, "Avahi: Failed to create simple poll object.\n");
1029
    exitcode = EXIT_FAILURE;
1030
    goto end;
1031
  }
309 by Teddy Hogeborn
Merge from Björn:
1032
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1033
  sigemptyset(&sigterm_action.sa_mask);
309 by Teddy Hogeborn
Merge from Björn:
1034
  ret = sigaddset(&sigterm_action.sa_mask, SIGINT);
1035
  if(ret == -1){
1036
    perror("sigaddset");
1037
    exitcode = EXIT_FAILURE;
1038
    goto end;
1039
  }
1040
  ret = sigaddset(&sigterm_action.sa_mask, SIGHUP);
1041
  if(ret == -1){
1042
    perror("sigaddset");
1043
    exitcode = EXIT_FAILURE;
1044
    goto end;
1045
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
1046
  ret = sigaddset(&sigterm_action.sa_mask, SIGTERM);
1047
  if(ret == -1){
1048
    perror("sigaddset");
1049
    exitcode = EXIT_FAILURE;
1050
    goto end;
1051
  }
1052
  ret = sigaction(SIGTERM, &sigterm_action, &old_sigterm_action);
1053
  if(ret == -1){
1054
    perror("sigaction");
1055
    exitcode = EXIT_FAILURE;
1056
    goto end;
1057
  }  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1058
  
1059
  /* If the interface is down, bring it up */
304 by Teddy Hogeborn
Four new interrelated features:
1060
  if(interface[0] != '\0'){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1061
#ifdef __linux__
1062
    /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
1063
       messages to mess up the prompt */
1064
    ret = klogctl(8, NULL, 5);
304 by Teddy Hogeborn
Four new interrelated features:
1065
    bool restore_loglevel = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1066
    if(ret == -1){
304 by Teddy Hogeborn
Four new interrelated features:
1067
      restore_loglevel = false;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1068
      perror("klogctl");
1069
    }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1070
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1071
    
1072
    sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1073
    if(sd < 0){
1074
      perror("socket");
1075
      exitcode = EXIT_FAILURE;
1076
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1077
      if(restore_loglevel){
1078
	ret = klogctl(7, NULL, 0);
1079
	if(ret == -1){
1080
	  perror("klogctl");
1081
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1082
      }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1083
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1084
      goto end;
1085
    }
1086
    strcpy(network.ifr_name, interface);
1087
    ret = ioctl(sd, SIOCGIFFLAGS, &network);
1088
    if(ret == -1){
1089
      perror("ioctl SIOCGIFFLAGS");
1090
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1091
      if(restore_loglevel){
1092
	ret = klogctl(7, NULL, 0);
1093
	if(ret == -1){
1094
	  perror("klogctl");
1095
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1096
      }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1097
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1098
      exitcode = EXIT_FAILURE;
1099
      goto end;
1100
    }
1101
    if((network.ifr_flags & IFF_UP) == 0){
1102
      network.ifr_flags |= IFF_UP;
1103
      ret = ioctl(sd, SIOCSIFFLAGS, &network);
1104
      if(ret == -1){
1105
	perror("ioctl SIOCSIFFLAGS");
1106
	exitcode = EXIT_FAILURE;
1107
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1108
	if(restore_loglevel){
1109
	  ret = klogctl(7, NULL, 0);
1110
	  if(ret == -1){
1111
	    perror("klogctl");
1112
	  }
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
1113
	}
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1114
#endif	/* __linux__ */
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1115
	goto end;
1116
      }
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1117
      interface_taken_up = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1118
    }
1119
    /* sleep checking until interface is running */
1120
    for(int i=0; i < delay * 4; i++){
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1121
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
1122
      if(ret == -1){
1123
	perror("ioctl SIOCGIFFLAGS");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1124
      } else if(network.ifr_flags & IFF_RUNNING){
1125
	break;
1126
      }
1127
      struct timespec sleeptime = { .tv_nsec = 250000000 };
1128
      ret = nanosleep(&sleeptime, NULL);
1129
      if(ret == -1 and errno != EINTR){
1130
	perror("nanosleep");
1131
      }
1132
    }
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1133
    if(not interface_taken_up){
1134
      ret = (int)TEMP_FAILURE_RETRY(close(sd));
1135
      if(ret == -1){
1136
	perror("close");
1137
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1138
    }
1139
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1140
    if(restore_loglevel){
1141
      /* Restores kernel loglevel to default */
1142
      ret = klogctl(7, NULL, 0);
1143
      if(ret == -1){
1144
	perror("klogctl");
1145
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1146
    }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1147
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1148
  }
1149
  
1150
  uid = getuid();
1151
  gid = getgid();
1152
  
304 by Teddy Hogeborn
Four new interrelated features:
1153
  errno = 0;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1154
  setgid(gid);
1155
  if(ret == -1){
1156
    perror("setgid");
1157
  }
1158
  
1159
  ret = setuid(uid);
1160
  if(ret == -1){
1161
    perror("setuid");
1162
  }
1163
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1164
  ret = init_gnutls_global(pubkey, seckey);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1165
  if(ret == -1){
1166
    fprintf(stderr, "init_gnutls_global failed\n");
1167
    exitcode = EXIT_FAILURE;
1168
    goto end;
1169
  } else {
1170
    gnutls_initialized = true;
1171
  }
1172
  
1173
  if(mkdtemp(tempdir) == NULL){
1174
    perror("mkdtemp");
1175
    goto end;
1176
  }
1177
  tempdir_created = true;
1178
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1179
  if(not init_gpgme(pubkey, seckey, tempdir)){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1180
    fprintf(stderr, "init_gpgme failed\n");
1181
    exitcode = EXIT_FAILURE;
1182
    goto end;
1183
  } else {
1184
    gpgme_initialized = true;
1185
  }
1186
  
304 by Teddy Hogeborn
Four new interrelated features:
1187
  if(interface[0] != '\0'){
1188
    if_index = (AvahiIfIndex) if_nametoindex(interface);
1189
    if(if_index == 0){
1190
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
1191
      exitcode = EXIT_FAILURE;
1192
      goto end;
1193
    }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1194
  }
1195
  
1196
  if(connect_to != NULL){
1197
    /* Connect directly, do not use Zeroconf */
1198
    /* (Mainly meant for debugging) */
1199
    char *address = strrchr(connect_to, ':');
1200
    if(address == NULL){
1201
      fprintf(stderr, "No colon in address\n");
1202
      exitcode = EXIT_FAILURE;
1203
      goto end;
1204
    }
1205
    uint16_t port;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1206
    errno = 0;
1207
    tmpmax = strtoimax(address+1, &tmp, 10);
1208
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
1209
       or tmpmax != (uint16_t)tmpmax){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1210
      fprintf(stderr, "Bad port number\n");
1211
      exitcode = EXIT_FAILURE;
1212
      goto end;
1213
    }
1214
    port = (uint16_t)tmpmax;
1215
    *address = '\0';
1216
    address = connect_to;
304 by Teddy Hogeborn
Four new interrelated features:
1217
    /* Colon in address indicates IPv6 */
1218
    int af;
1219
    if(strchr(address, ':') != NULL){
1220
      af = AF_INET6;
1221
    } else {
1222
      af = AF_INET;
1223
    }
307 by Teddy Hogeborn
Merge from Björn:
1224
    ret = start_mandos_communication(address, port, if_index, af);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1225
    if(ret < 0){
1226
      exitcode = EXIT_FAILURE;
1227
    } else {
1228
      exitcode = EXIT_SUCCESS;
1229
    }
1230
    goto end;
1231
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
1232
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1233
  {
1234
    AvahiServerConfig config;
1235
    /* Do not publish any local Zeroconf records */
1236
    avahi_server_config_init(&config);
1237
    config.publish_hinfo = 0;
1238
    config.publish_addresses = 0;
1239
    config.publish_workstation = 0;
1240
    config.publish_domain = 0;
1241
    
1242
    /* Allocate a new server */
1243
    mc.server = avahi_server_new(avahi_simple_poll_get
1244
				 (mc.simple_poll), &config, NULL,
1245
				 NULL, &error);
1246
    
1247
    /* Free the Avahi configuration data */
1248
    avahi_server_config_free(&config);
1249
  }
1250
  
1251
  /* Check if creating the Avahi server object succeeded */
1252
  if(mc.server == NULL){
1253
    fprintf(stderr, "Failed to create Avahi server: %s\n",
1254
	    avahi_strerror(error));
1255
    exitcode = EXIT_FAILURE;
1256
    goto end;
1257
  }
1258
  
1259
  /* Create the Avahi service browser */
1260
  sb = avahi_s_service_browser_new(mc.server, if_index,
313 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
1261
				   AVAHI_PROTO_UNSPEC, "_mandos._tcp",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1262
				   NULL, 0, browse_callback, NULL);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1263
  if(sb == NULL){
1264
    fprintf(stderr, "Failed to create service browser: %s\n",
1265
	    avahi_strerror(avahi_server_errno(mc.server)));
1266
    exitcode = EXIT_FAILURE;
1267
    goto end;
1268
  }
307 by Teddy Hogeborn
Merge from Björn:
1269
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1270
  /* Run the main loop */
1271
  
1272
  if(debug){
1273
    fprintf(stderr, "Starting Avahi loop search\n");
1274
  }
1275
  
1276
  avahi_simple_poll_loop(mc.simple_poll);
1277
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1278
 end:
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1279
  
1280
  if(debug){
1281
    fprintf(stderr, "%s exiting\n", argv[0]);
1282
  }
1283
  
1284
  /* Cleanup things */
1285
  if(sb != NULL)
1286
    avahi_s_service_browser_free(sb);
1287
  
1288
  if(mc.server != NULL)
1289
    avahi_server_free(mc.server);
1290
  
1291
  if(mc.simple_poll != NULL)
1292
    avahi_simple_poll_free(mc.simple_poll);
1293
  
1294
  if(gnutls_initialized){
1295
    gnutls_certificate_free_credentials(mc.cred);
1296
    gnutls_global_deinit();
1297
    gnutls_dh_params_deinit(mc.dh_params);
1298
  }
1299
  
1300
  if(gpgme_initialized){
1301
    gpgme_release(mc.ctx);
1302
  }
1303
  
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1304
  /* Take down the network interface */
1305
  if(interface_taken_up){
1306
    ret = ioctl(sd, SIOCGIFFLAGS, &network);
1307
    if(ret == -1){
1308
      perror("ioctl SIOCGIFFLAGS");
1309
    } else if(network.ifr_flags & IFF_UP) {
1310
      network.ifr_flags &= ~IFF_UP; /* clear flag */
1311
      ret = ioctl(sd, SIOCSIFFLAGS, &network);
1312
      if(ret == -1){
1313
	perror("ioctl SIOCSIFFLAGS");
1314
      }
1315
    }
1316
    ret = (int)TEMP_FAILURE_RETRY(close(sd));
1317
    if(ret == -1){
1318
      perror("close");
1319
    }
1320
  }
1321
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1322
  /* Removes the temp directory used by GPGME */
1323
  if(tempdir_created){
1324
    DIR *d;
1325
    struct dirent *direntry;
1326
    d = opendir(tempdir);
1327
    if(d == NULL){
1328
      if(errno != ENOENT){
1329
	perror("opendir");
1330
      }
1331
    } else {
1332
      while(true){
1333
	direntry = readdir(d);
1334
	if(direntry == NULL){
1335
	  break;
1336
	}
1337
	/* Skip "." and ".." */
1338
	if(direntry->d_name[0] == '.'
1339
	   and (direntry->d_name[1] == '\0'
1340
		or (direntry->d_name[1] == '.'
1341
		    and direntry->d_name[2] == '\0'))){
1342
	  continue;
1343
	}
1344
	char *fullname = NULL;
1345
	ret = asprintf(&fullname, "%s/%s", tempdir,
1346
		       direntry->d_name);
1347
	if(ret < 0){
1348
	  perror("asprintf");
1349
	  continue;
1350
	}
1351
	ret = remove(fullname);
1352
	if(ret == -1){
1353
	  fprintf(stderr, "remove(\"%s\"): %s\n", fullname,
1354
		  strerror(errno));
1355
	}
1356
	free(fullname);
1357
      }
1358
      closedir(d);
1359
    }
1360
    ret = rmdir(tempdir);
1361
    if(ret == -1 and errno != ENOENT){
1362
      perror("rmdir");
1363
    }
1364
  }
1365
  
1366
  return exitcode;
13 by Björn Påhlsson
Added following support:
1367
}