/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1
/*  -*- coding: utf-8 -*- */
2
/*
237.2.24 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
237.7.471 by Teddy Hogeborn
Update copyright year to 2018
12
 * Copyright © 2008-2018 Teddy Hogeborn
13
 * Copyright © 2008-2018 Björn Påhlsson
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
14
 * 
237.7.455 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
15
 * This file is part of Mandos.
16
 * 
17
 * Mandos is free software: you can redistribute it and/or modify it
18
 * under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation, either version 3 of the License, or
20
 * (at your option) any later version.
21
 * 
22
 * Mandos is distributed in the hope that it will be useful, but
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
23
 * WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25
 * General Public License for more details.
26
 * 
27
 * You should have received a copy of the GNU General Public License
237.7.455 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
28
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
29
 * 
237.11.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
30
 * Contact the authors at <mandos@recompile.se>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
31
 */
32
28 by Teddy Hogeborn
* server.conf: New file.
33
/* Needed by GPGME, specifically gpgme_data_seek() */
237.2.80 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
34
#ifndef _LARGEFILE_SOURCE
13 by Björn Påhlsson
Added following support:
35
#define _LARGEFILE_SOURCE
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
36
#endif	/* not _LARGEFILE_SOURCE */
237.2.80 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
37
#ifndef _FILE_OFFSET_BITS
13 by Björn Påhlsson
Added following support:
38
#define _FILE_OFFSET_BITS 64
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
39
#endif	/* not _FILE_OFFSET_BITS */
13 by Björn Påhlsson
Added following support:
40
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
41
#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY(), asprintf() */
24.1.10 by Björn Påhlsson
merge commit
42
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
43
#include <stdio.h>		/* fprintf(), stderr, fwrite(),
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
44
				   stdout, ferror() */
237.7.136 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Eliminate
45
#include <stdint.h> 		/* uint16_t, uint32_t, intptr_t */
24.1.26 by Björn Påhlsson
tally count of used symbols
46
#include <stddef.h>		/* NULL, size_t, ssize_t */
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
47
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, srand(),
48
				   strtof(), abort() */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
49
#include <stdbool.h>		/* bool, false, true */
237.7.321 by Teddy Hogeborn
mandos-client: Don't use memset().
50
#include <string.h>		/* strcmp(), strlen(), strerror(),
237.7.418 by Teddy Hogeborn
Show what signal, if any, made mandos-client exit.
51
				   asprintf(), strncpy(), strsignal()
52
				*/
237.2.67 by Teddy Hogeborn
Four new interrelated features:
53
#include <sys/ioctl.h>		/* ioctl */
24.1.26 by Björn Påhlsson
tally count of used symbols
54
#include <sys/types.h>		/* socket(), inet_pton(), sockaddr,
24.1.29 by Björn Påhlsson
Added more header file comments
55
				   sockaddr_in6, PF_INET6,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
56
				   SOCK_STREAM, uid_t, gid_t, open(),
57
				   opendir(), DIR */
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
58
#include <sys/stat.h>		/* open(), S_ISREG */
24.1.26 by Björn Påhlsson
tally count of used symbols
59
#include <sys/socket.h>		/* socket(), struct sockaddr_in6,
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
60
				   inet_pton(), connect(),
61
				   getnameinfo() */
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
62
#include <fcntl.h>		/* open(), unlinkat(), AT_REMOVEDIR */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
63
#include <dirent.h>		/* opendir(), struct dirent, readdir()
64
				 */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
65
#include <inttypes.h>		/* PRIu16, PRIdMAX, intmax_t,
66
				   strtoimax() */
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
67
#include <errno.h>		/* perror(), errno, EINTR, EINVAL,
68
				   EAI_SYSTEM, ENETUNREACH,
69
				   EHOSTUNREACH, ECONNREFUSED, EPROTO,
70
				   EIO, ENOENT, ENXIO, ENOMEM, EISDIR,
71
				   ENOTEMPTY,
237.7.33 by Teddy Hogeborn
Merge from Björn.
72
				   program_invocation_short_name */
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
73
#include <time.h>		/* nanosleep(), time(), sleep() */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
74
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
24.1.26 by Björn Påhlsson
tally count of used symbols
75
				   SIOCSIFFLAGS, if_indextoname(),
76
				   if_nametoindex(), IF_NAMESIZE */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
77
#include <netinet/in.h>		/* IN6_IS_ADDR_LINKLOCAL,
78
				   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
79
				*/
24.1.29 by Björn Påhlsson
Added more header file comments
80
#include <unistd.h>		/* close(), SEEK_SET, off_t, write(),
237.2.128 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
81
				   getuid(), getgid(), seteuid(),
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
82
				   setgid(), pause(), _exit(),
83
				   unlinkat() */
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
84
#include <arpa/inet.h>		/* inet_pton(), htons() */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
85
#include <iso646.h>		/* not, or, and */
24.1.29 by Björn Påhlsson
Added more header file comments
86
#include <argp.h>		/* struct argp_option, error_t, struct
87
				   argp_state, struct argp,
88
				   argp_parse(), ARGP_KEY_ARG,
89
				   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
237.2.70 by Teddy Hogeborn
Merge from Björn:
90
#include <signal.h>		/* sigemptyset(), sigaddset(),
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
91
				   sigaction(), SIGTERM, sig_atomic_t,
92
				   raise() */
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
93
#include <sysexits.h>		/* EX_OSERR, EX_USAGE, EX_UNAVAILABLE,
94
				   EX_NOHOST, EX_IOERR, EX_PROTOCOL */
237.16.3 by teddy at bsnet
* plugins.d/mandos-client.c: Prefix all printouts with "Mandos plugin
95
#include <sys/wait.h>		/* waitpid(), WIFEXITED(),
96
				   WEXITSTATUS(), WTERMSIG() */
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
97
#include <grp.h>		/* setgroups() */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
98
#include <argz.h>		/* argz_add_sep(), argz_next(),
99
				   argz_delete(), argz_append(),
100
				   argz_stringify(), argz_add(),
101
				   argz_count() */
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
102
#include <netdb.h>		/* getnameinfo(), NI_NUMERICHOST,
103
				   EAI_SYSTEM, gai_strerror() */
237.2.70 by Teddy Hogeborn
Merge from Björn:
104
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
105
#ifdef __linux__
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
106
#include <sys/klog.h> 		/* klogctl() */
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
107
#endif	/* __linux__ */
24.1.26 by Björn Påhlsson
tally count of used symbols
108
109
/* Avahi */
24.1.29 by Björn Påhlsson
Added more header file comments
110
/* All Avahi types, constants and functions
111
 Avahi*, avahi_*,
112
 AVAHI_* */
113
#include <avahi-core/core.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
114
#include <avahi-core/lookup.h>
24.1.29 by Björn Påhlsson
Added more header file comments
115
#include <avahi-core/log.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
116
#include <avahi-common/simple-watch.h>
117
#include <avahi-common/malloc.h>
118
#include <avahi-common/error.h>
119
120
/* GnuTLS */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
121
#include <gnutls/gnutls.h>	/* All GnuTLS types, constants and
122
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
123
				   gnutls_*
24.1.26 by Björn Påhlsson
tally count of used symbols
124
				   init_gnutls_session(),
24.1.29 by Björn Påhlsson
Added more header file comments
125
				   GNUTLS_* */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
126
#include <gnutls/openpgp.h>
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
127
			 /* gnutls_certificate_set_openpgp_key_file(),
128
			    GNUTLS_OPENPGP_FMT_BASE64 */
24.1.26 by Björn Påhlsson
tally count of used symbols
129
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
130
/* GPGME */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
131
#include <gpgme.h> 		/* All GPGME types, constants and
132
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
133
				   gpgme_*
24.1.26 by Björn Påhlsson
tally count of used symbols
134
				   GPGME_PROTOCOL_OpenPGP,
24.1.29 by Björn Påhlsson
Added more header file comments
135
				   GPG_ERR_NO_* */
13 by Björn Påhlsson
Added following support:
136
137
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
138
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
139
#define PATHDIR "/conf/conf.d/mandos"
140
#define SECKEY "seckey.txt"
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
141
#define PUBKEY "pubkey.txt"
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
142
#define HOOKDIR "/lib/mandos/network-hooks.d"
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
143
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
144
bool debug = false;
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
145
static const char mandos_protocol_version[] = "1";
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
146
const char *argp_program_version = "mandos-client " VERSION;
147
const char *argp_program_bug_address = "<mandos@recompile.se>";
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
148
static const char sys_class_net[] = "/sys/class/net";
149
char *connect_to = NULL;
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
150
const char *hookdir = HOOKDIR;
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
151
int hookdir_fd = -1;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
152
uid_t uid = 65534;
153
gid_t gid = 65534;
24.1.10 by Björn Påhlsson
merge commit
154
237.7.33 by Teddy Hogeborn
Merge from Björn.
155
/* Doubly linked list that need to be circularly linked when used */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
156
typedef struct server{
157
  const char *ip;
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
158
  in_port_t port;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
159
  AvahiIfIndex if_index;
160
  int af;
161
  struct timespec last_seen;
162
  struct server *next;
163
  struct server *prev;
164
} server;
165
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
166
/* Used for passing in values through the Avahi callback functions */
13 by Björn Påhlsson
Added following support:
167
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
168
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
169
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
170
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
171
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
172
  const char *priority;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
173
  gpgme_ctx_t ctx;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
174
  server *current_server;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
175
  char *interfaces;
176
  size_t interfaces_size;
24.1.9 by Björn Påhlsson
not working midwork...
177
} mandos_context;
13 by Björn Påhlsson
Added following support:
178
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
179
/* global so signal handler can reach it*/
180
AvahiSimplePoll *simple_poll;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
181
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
182
sig_atomic_t quit_now = 0;
183
int signal_received = 0;
184
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
185
/* Function to use when printing errors */
186
void perror_plus(const char *print_text){
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
187
  int e = errno;
237.7.33 by Teddy Hogeborn
Merge from Björn.
188
  fprintf(stderr, "Mandos plugin %s: ",
189
	  program_invocation_short_name);
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
190
  errno = e;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
191
  perror(print_text);
192
}
193
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
194
__attribute__((format (gnu_printf, 2, 3), nonnull))
237.15.4 by Björn Påhlsson
New convinence error printer: fprintf_plus
195
int fprintf_plus(FILE *stream, const char *format, ...){
196
  va_list ap;
197
  va_start (ap, format);
198
  
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
199
  TEMP_FAILURE_RETRY(fprintf(stream, "Mandos plugin %s: ",
200
			     program_invocation_short_name));
237.7.170 by Teddy Hogeborn
* debian/control (Build-Depends): Depend on debhelper 8.9.7 for using
201
  return (int)TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
237.15.4 by Björn Påhlsson
New convinence error printer: fprintf_plus
202
}
203
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
204
/*
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
205
 * Make additional room in "buffer" for at least BUFFER_SIZE more
206
 * bytes. "buffer_capacity" is how much is currently allocated,
207
 * "buffer_length" is how much is already used.
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
208
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
209
__attribute__((nonnull, warn_unused_result))
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
210
size_t incbuffer(char **buffer, size_t buffer_length,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
211
		 size_t buffer_capacity){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
212
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
213
    char *new_buf = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
214
    if(new_buf == NULL){
215
      int old_errno = errno;
216
      free(*buffer);
217
      errno = old_errno;
218
      *buffer = NULL;
24.1.10 by Björn Påhlsson
merge commit
219
      return 0;
220
    }
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
221
    *buffer = new_buf;
24.1.10 by Björn Påhlsson
merge commit
222
    buffer_capacity += BUFFER_SIZE;
223
  }
224
  return buffer_capacity;
225
}
226
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
227
/* Add server to set of servers to retry periodically */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
228
__attribute__((nonnull, warn_unused_result))
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
229
bool add_server(const char *ip, in_port_t port, AvahiIfIndex if_index,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
230
		int af, server **current_server){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
231
  int ret;
232
  server *new_server = malloc(sizeof(server));
233
  if(new_server == NULL){
234
    perror_plus("malloc");
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
235
    return false;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
236
  }
237
  *new_server = (server){ .ip = strdup(ip),
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
238
			  .port = port,
239
			  .if_index = if_index,
240
			  .af = af };
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
241
  if(new_server->ip == NULL){
242
    perror_plus("strdup");
237.7.258 by Teddy Hogeborn
mandos-client: Fix minor memory leak on memory full or clock failure.
243
    free(new_server);
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
244
    return false;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
245
  }
237.7.216 by Teddy Hogeborn
Do not add a new server to server list if clock_gettime() fails
246
  ret = clock_gettime(CLOCK_MONOTONIC, &(new_server->last_seen));
247
  if(ret == -1){
248
    perror_plus("clock_gettime");
237.7.262 by Teddy Hogeborn
mandos-client: Fix mem free bug.
249
#ifdef __GNUC__
250
#pragma GCC diagnostic push
251
#pragma GCC diagnostic ignored "-Wcast-qual"
252
#endif
253
    free((char *)(new_server->ip));
254
#ifdef __GNUC__
255
#pragma GCC diagnostic pop
256
#endif
237.7.258 by Teddy Hogeborn
mandos-client: Fix minor memory leak on memory full or clock failure.
257
    free(new_server);
237.7.216 by Teddy Hogeborn
Do not add a new server to server list if clock_gettime() fails
258
    return false;
259
  }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
260
  /* Special case of first server */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
261
  if(*current_server == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
262
    new_server->next = new_server;
263
    new_server->prev = new_server;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
264
    *current_server = new_server;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
265
  } else {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
266
    /* Place the new server last in the list */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
267
    new_server->next = *current_server;
268
    new_server->prev = (*current_server)->prev;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
269
    new_server->prev->next = new_server;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
270
    (*current_server)->prev = new_server;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
271
  }
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
272
  return true;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
273
}
274
237.7.499 by Teddy Hogeborn
mandos-client: Set system clock if necessary
275
/* Set effective uid to 0, return errno */
276
__attribute__((warn_unused_result))
277
int raise_privileges(void){
278
  int old_errno = errno;
279
  int ret = 0;
280
  if(seteuid(0) == -1){
281
    ret = errno;
282
  }
283
  errno = old_errno;
284
  return ret;
285
}
286
287
/* Set effective and real user ID to 0.  Return errno. */
288
__attribute__((warn_unused_result))
289
int raise_privileges_permanently(void){
290
  int old_errno = errno;
291
  int ret = raise_privileges();
292
  if(ret != 0){
293
    errno = old_errno;
294
    return ret;
295
  }
296
  if(setuid(0) == -1){
297
    ret = errno;
298
  }
299
  errno = old_errno;
300
  return ret;
301
}
302
303
/* Set effective user ID to unprivileged saved user ID */
304
__attribute__((warn_unused_result))
305
int lower_privileges(void){
306
  int old_errno = errno;
307
  int ret = 0;
308
  if(seteuid(uid) == -1){
309
    ret = errno;
310
  }
311
  errno = old_errno;
312
  return ret;
313
}
314
315
/* Lower privileges permanently */
316
__attribute__((warn_unused_result))
317
int lower_privileges_permanently(void){
318
  int old_errno = errno;
319
  int ret = 0;
320
  if(setuid(uid) == -1){
321
    ret = errno;
322
  }
323
  errno = old_errno;
324
  return ret;
325
}
326
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
327
/* 
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
328
 * Initialize GPGME.
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
329
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
330
__attribute__((nonnull, warn_unused_result))
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
331
static bool init_gpgme(const char * const seckey,
332
		       const char * const pubkey,
333
		       const char * const tempdir,
334
		       mandos_context *mc){
13 by Björn Påhlsson
Added following support:
335
  gpgme_error_t rc;
336
  gpgme_engine_info_t engine_info;
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
337
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
338
  /*
237.2.51 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use separate bool variable instead
339
   * 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.
340
   */
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
341
  bool import_key(const char * const filename){
237.2.124 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
342
    int ret;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
343
    int fd;
344
    gpgme_data_t pgp_data;
345
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
346
    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.
347
    if(fd == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
348
      perror_plus("open");
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
349
      return false;
350
    }
351
    
237.7.499 by Teddy Hogeborn
mandos-client: Set system clock if necessary
352
    /* Workaround for systems without a real-time clock; see also
353
       Debian bug #894495: <https://bugs.debian.org/894495> */
354
    do {
355
      {
356
	time_t currtime = time(NULL);
357
	if(currtime != (time_t)-1){
358
	  struct tm tm;
359
	  if(gmtime_r(&currtime, &tm) == NULL) {
360
	    perror_plus("gmtime_r");
361
	    break;
362
	  }
363
	  if(tm.tm_year != 70 or tm.tm_mon != 0){
364
	    break;
365
	  }
366
	  if(debug){
367
	    fprintf_plus(stderr, "System clock is January 1970");
368
	  }
369
	} else {
370
	  if(debug){
371
	    fprintf_plus(stderr, "System clock is invalid");
372
	  }
373
	}
374
      }
375
      struct stat keystat;
376
      ret = fstat(fd, &keystat);
377
      if(ret != 0){
378
	perror_plus("fstat");
379
	break;
380
      }
381
      ret = raise_privileges();
382
      if(ret != 0){
383
	errno = ret;
384
	perror_plus("Failed to raise privileges");
385
	break;
386
      }
387
      if(debug){
388
	fprintf_plus(stderr,
389
		     "Setting system clock to key file mtime");
390
      }
391
      time_t keytime = keystat.st_mtim.tv_sec;
392
      if(stime(&keytime) != 0){
393
	perror_plus("stime");
394
      }
395
      ret = lower_privileges();
396
      if(ret != 0){
397
	errno = ret;
398
	perror_plus("Failed to lower privileges");
399
      }
400
    } while(false);
401
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
402
    rc = gpgme_data_new_from_fd(&pgp_data, fd);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
403
    if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
404
      fprintf_plus(stderr, "bad gpgme_data_new_from_fd: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
405
		   gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
406
      return false;
407
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
408
    
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
409
    rc = gpgme_op_import(mc->ctx, pgp_data);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
410
    if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
411
      fprintf_plus(stderr, "bad gpgme_op_import: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
412
		   gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
413
      return false;
414
    }
237.7.495 by Teddy Hogeborn
Check for and report GPGME key import errors
415
    {
416
      gpgme_import_result_t import_result
417
	= gpgme_op_import_result(mc->ctx);
418
      if((import_result->imported < 1
419
	  or import_result->not_imported > 0)
420
	 and import_result->unchanged == 0){
421
	fprintf_plus(stderr, "bad gpgme_op_import_results:\n");
422
	fprintf_plus(stderr,
423
		     "The total number of considered keys: %d\n",
424
		     import_result->considered);
425
	fprintf_plus(stderr,
426
		     "The number of keys without user ID: %d\n",
427
		     import_result->no_user_id);
428
	fprintf_plus(stderr,
429
		     "The total number of imported keys: %d\n",
430
		     import_result->imported);
431
	fprintf_plus(stderr, "The number of imported RSA keys: %d\n",
432
		     import_result->imported_rsa);
433
	fprintf_plus(stderr, "The number of unchanged keys: %d\n",
434
		     import_result->unchanged);
435
	fprintf_plus(stderr, "The number of new user IDs: %d\n",
436
		     import_result->new_user_ids);
437
	fprintf_plus(stderr, "The number of new sub keys: %d\n",
438
		     import_result->new_sub_keys);
439
	fprintf_plus(stderr, "The number of new signatures: %d\n",
440
		     import_result->new_signatures);
441
	fprintf_plus(stderr, "The number of new revocations: %d\n",
442
		     import_result->new_revocations);
443
	fprintf_plus(stderr,
444
		     "The total number of secret keys read: %d\n",
445
		     import_result->secret_read);
446
	fprintf_plus(stderr,
447
		     "The number of imported secret keys: %d\n",
448
		     import_result->secret_imported);
449
	fprintf_plus(stderr,
450
		     "The number of unchanged secret keys: %d\n",
451
		     import_result->secret_unchanged);
452
	fprintf_plus(stderr, "The number of keys not imported: %d\n",
453
		     import_result->not_imported);
454
	for(gpgme_import_status_t import_status
455
	      = import_result->imports;
456
	    import_status != NULL;
457
	    import_status = import_status->next){
458
	  fprintf_plus(stderr, "Import status for key: %s\n",
459
		       import_status->fpr);
460
	  if(import_status->result != GPG_ERR_NO_ERROR){
461
	    fprintf_plus(stderr, "Import result: %s: %s\n",
462
			 gpgme_strsource(import_status->result),
463
			 gpgme_strerror(import_status->result));
464
	  }
465
	  fprintf_plus(stderr, "Key status:\n");
466
	  fprintf_plus(stderr,
467
		       import_status->status & GPGME_IMPORT_NEW
468
		       ? "The key was new.\n"
469
		       : "The key was not new.\n");
470
	  fprintf_plus(stderr,
471
		       import_status->status & GPGME_IMPORT_UID
472
		       ? "The key contained new user IDs.\n"
473
		       : "The key did not contain new user IDs.\n");
474
	  fprintf_plus(stderr,
475
		       import_status->status & GPGME_IMPORT_SIG
476
		       ? "The key contained new signatures.\n"
477
		       : "The key did not contain new signatures.\n");
478
	  fprintf_plus(stderr,
479
		       import_status->status & GPGME_IMPORT_SUBKEY
480
		       ? "The key contained new sub keys.\n"
481
		       : "The key did not contain new sub keys.\n");
482
	  fprintf_plus(stderr,
483
		       import_status->status & GPGME_IMPORT_SECRET
484
		       ? "The key contained a secret key.\n"
485
		       : "The key did not contain a secret key.\n");
486
	}
487
	return false;
488
      }
489
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
490
    
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
491
    ret = close(fd);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
492
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
493
      perror_plus("close");
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
494
    }
495
    gpgme_data_release(pgp_data);
496
    return true;
497
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
498
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
499
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
500
    fprintf_plus(stderr, "Initializing GPGME\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
501
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
502
  
13 by Björn Påhlsson
Added following support:
503
  /* Init GPGME */
504
  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.
505
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
506
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
507
    fprintf_plus(stderr, "bad gpgme_engine_check_version: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
508
		 gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
509
    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.
510
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
511
  
237.7.40 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
512
  /* Set GPGME home directory for the OpenPGP engine only */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
513
  rc = gpgme_get_engine_info(&engine_info);
514
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
515
    fprintf_plus(stderr, "bad gpgme_get_engine_info: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
516
		 gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
517
    return false;
13 by Björn Påhlsson
Added following support:
518
  }
519
  while(engine_info != NULL){
520
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
521
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
522
			    engine_info->file_name, tempdir);
13 by Björn Påhlsson
Added following support:
523
      break;
524
    }
525
    engine_info = engine_info->next;
526
  }
527
  if(engine_info == NULL){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
528
    fprintf_plus(stderr, "Could not set GPGME home dir to %s\n",
529
		 tempdir);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
530
    return false;
531
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
532
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
533
  /* Create new GPGME "context" */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
534
  rc = gpgme_new(&(mc->ctx));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
535
  if(rc != GPG_ERR_NO_ERROR){
237.7.494 by Teddy Hogeborn
Remove duplicate "Mandos plugin mandos-client:" in error output
536
    fprintf_plus(stderr, "bad gpgme_new: %s: %s\n",
537
		 gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
538
    return false;
539
  }
540
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
541
  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.
542
    return false;
543
  }
544
  
237.2.118 by Teddy Hogeborn
* mandos: White-space fixes only.
545
  return true;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
546
}
547
548
/* 
549
 * Decrypt OpenPGP data.
550
 * Returns -1 on error
551
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
552
__attribute__((nonnull, warn_unused_result))
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
553
static ssize_t pgp_packet_decrypt(const char *cryptotext,
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
554
				  size_t crypto_size,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
555
				  char **plaintext,
556
				  mandos_context *mc){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
557
  gpgme_data_t dh_crypto, dh_plain;
558
  gpgme_error_t rc;
559
  ssize_t ret;
560
  size_t plaintext_capacity = 0;
561
  ssize_t plaintext_length = 0;
562
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
563
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
564
    fprintf_plus(stderr, "Trying to decrypt OpenPGP data\n");
13 by Björn Påhlsson
Added following support:
565
  }
566
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
567
  /* Create new GPGME data buffer from memory cryptotext */
568
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
569
			       0);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
570
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
571
    fprintf_plus(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
572
		 gpgme_strsource(rc), gpgme_strerror(rc));
13 by Björn Påhlsson
Added following support:
573
    return -1;
574
  }
575
  
576
  /* Create new empty GPGME data buffer for the plaintext */
577
  rc = gpgme_data_new(&dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
578
  if(rc != GPG_ERR_NO_ERROR){
237.7.494 by Teddy Hogeborn
Remove duplicate "Mandos plugin mandos-client:" in error output
579
    fprintf_plus(stderr, "bad gpgme_data_new: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
580
		 gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
581
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
582
    return -1;
583
  }
584
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
585
  /* Decrypt data from the cryptotext data buffer to the plaintext
586
     data buffer */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
587
  rc = gpgme_op_decrypt(mc->ctx, dh_crypto, dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
588
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
589
    fprintf_plus(stderr, "bad gpgme_op_decrypt: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
590
		 gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
591
    plaintext_length = -1;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
592
    if(debug){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
593
      gpgme_decrypt_result_t result;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
594
      result = gpgme_op_decrypt_result(mc->ctx);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
595
      if(result == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
596
	fprintf_plus(stderr, "gpgme_op_decrypt_result failed\n");
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
597
      } else {
237.7.492 by Teddy Hogeborn
Don't print NULL string pointers in error message output
598
	if(result->unsupported_algorithm != NULL) {
599
	  fprintf_plus(stderr, "Unsupported algorithm: %s\n",
600
		       result->unsupported_algorithm);
601
	}
237.7.493 by Teddy Hogeborn
Print a boolean more readably in error message output
602
	fprintf_plus(stderr, "Wrong key usage: %s\n",
603
		     result->wrong_key_usage ? "Yes" : "No");
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
604
	if(result->file_name != NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
605
	  fprintf_plus(stderr, "File name: %s\n", result->file_name);
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
606
	}
237.7.496 by Teddy Hogeborn
Minor code cleanup
607
608
	for(gpgme_recipient_t r = result->recipients; r != NULL;
609
	    r = r->next){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
610
	  fprintf_plus(stderr, "Public key algorithm: %s\n",
237.7.496 by Teddy Hogeborn
Minor code cleanup
611
		       gpgme_pubkey_algo_name(r->pubkey_algo));
612
	  fprintf_plus(stderr, "Key ID: %s\n", r->keyid);
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
613
	  fprintf_plus(stderr, "Secret key available: %s\n",
237.7.496 by Teddy Hogeborn
Minor code cleanup
614
		       r->status == GPG_ERR_NO_SECKEY ? "No" : "Yes");
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
615
	}
616
      }
617
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
618
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
619
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
620
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
621
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
622
    fprintf_plus(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
623
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
624
  
13 by Björn Påhlsson
Added following support:
625
  /* Seek back to the beginning of the GPGME plaintext data buffer */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
626
  if(gpgme_data_seek(dh_plain, (off_t)0, SEEK_SET) == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
627
    perror_plus("gpgme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
628
    plaintext_length = -1;
629
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
630
  }
631
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
632
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
633
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
634
    plaintext_capacity = incbuffer(plaintext,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
635
				   (size_t)plaintext_length,
636
				   plaintext_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
637
    if(plaintext_capacity == 0){
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
638
      perror_plus("incbuffer");
639
      plaintext_length = -1;
640
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
641
    }
642
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
643
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
644
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
645
    /* Print the data, if any */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
646
    if(ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
647
      /* EOF */
13 by Björn Påhlsson
Added following support:
648
      break;
649
    }
650
    if(ret < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
651
      perror_plus("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
652
      plaintext_length = -1;
653
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
654
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
655
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
656
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
657
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
658
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
659
    fprintf_plus(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
660
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
661
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
662
    }
663
    fprintf(stderr, "\n");
664
  }
665
  
666
 decrypt_end:
667
  
668
  /* Delete the GPGME cryptotext data buffer */
669
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
670
  
671
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
672
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
673
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
674
}
675
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
676
__attribute__((warn_unused_result, const))
677
static const char *safe_string(const char *str){
678
  if(str == NULL)
679
    return "(unknown)";
680
  return str;
681
}
682
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
683
__attribute__((warn_unused_result))
684
static const char *safer_gnutls_strerror(int value){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
685
  const char *ret = gnutls_strerror(value);
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
686
  return safe_string(ret);
13 by Björn Påhlsson
Added following support:
687
}
688
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
689
/* GnuTLS log function callback */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
690
__attribute__((nonnull))
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
691
static void debuggnutls(__attribute__((unused)) int level,
692
			const char* string){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
693
  fprintf_plus(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
694
}
695
237.7.359 by Teddy Hogeborn
Client: Remove an incorrect "nonnull" attribute
696
__attribute__((nonnull(1, 2, 4), warn_unused_result))
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
697
static int init_gnutls_global(const char *pubkeyfilename,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
698
			      const char *seckeyfilename,
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
699
			      const char *dhparamsfilename,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
700
			      mandos_context *mc){
13 by Björn Påhlsson
Added following support:
701
  int ret;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
702
  unsigned int uret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
703
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
704
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
705
    fprintf_plus(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
706
  }
24.1.29 by Björn Påhlsson
Added more header file comments
707
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
708
  if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
709
    /* "Use a log level over 10 to enable all debugging options."
710
     * - GnuTLS manual
711
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
712
    gnutls_global_set_log_level(11);
713
    gnutls_global_set_log_function(debuggnutls);
714
  }
715
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
716
  /* OpenPGP credentials */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
717
  ret = gnutls_certificate_allocate_credentials(&mc->cred);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
718
  if(ret != GNUTLS_E_SUCCESS){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
719
    fprintf_plus(stderr, "GnuTLS memory error: %s\n",
720
		 safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
721
    return -1;
722
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
723
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
724
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
725
    fprintf_plus(stderr, "Attempting to use OpenPGP public key %s and"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
726
		 " secret key %s as GnuTLS credentials\n",
727
		 pubkeyfilename,
728
		 seckeyfilename);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
729
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
730
  
13 by Björn Påhlsson
Added following support:
731
  ret = gnutls_certificate_set_openpgp_key_file
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
732
    (mc->cred, pubkeyfilename, seckeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
733
     GNUTLS_OPENPGP_FMT_BASE64);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
734
  if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
735
    fprintf_plus(stderr,
736
		 "Error[%d] while reading the OpenPGP key pair ('%s',"
737
		 " '%s')\n", ret, pubkeyfilename, seckeyfilename);
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
738
    fprintf_plus(stderr, "The GnuTLS error is: %s\n",
739
		 safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
740
    goto globalfail;
13 by Björn Påhlsson
Added following support:
741
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
742
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
743
  /* GnuTLS server initialization */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
744
  ret = gnutls_dh_params_init(&mc->dh_params);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
745
  if(ret != GNUTLS_E_SUCCESS){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
746
    fprintf_plus(stderr, "Error in GnuTLS DH parameter"
747
		 " initialization: %s\n",
748
		 safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
749
    goto globalfail;
13 by Björn Påhlsson
Added following support:
750
  }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
751
  /* If a Diffie-Hellman parameters file was given, try to use it */
752
  if(dhparamsfilename != NULL){
753
    gnutls_datum_t params = { .data = NULL, .size = 0 };
754
    do {
755
      int dhpfile = open(dhparamsfilename, O_RDONLY);
756
      if(dhpfile == -1){
757
	perror_plus("open");
758
	dhparamsfilename = NULL;
759
	break;
760
      }
761
      size_t params_capacity = 0;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
762
      while(true){
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
763
	params_capacity = incbuffer((char **)&params.data,
764
				    (size_t)params.size,
765
				    (size_t)params_capacity);
766
	if(params_capacity == 0){
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
767
	  perror_plus("incbuffer");
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
768
	  free(params.data);
769
	  params.data = NULL;
770
	  dhparamsfilename = NULL;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
771
	  break;
772
	}
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
773
	ssize_t bytes_read = read(dhpfile,
774
				  params.data + params.size,
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
775
				  BUFFER_SIZE);
776
	/* EOF */
777
	if(bytes_read == 0){
778
	  break;
779
	}
780
	/* check bytes_read for failure */
781
	if(bytes_read < 0){
782
	  perror_plus("read");
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
783
	  free(params.data);
784
	  params.data = NULL;
785
	  dhparamsfilename = NULL;
786
	  break;
787
	}
788
	params.size += (unsigned int)bytes_read;
789
      }
237.7.489 by Teddy Hogeborn
Check return values from newly added close() calls
790
      ret = close(dhpfile);
791
      if(ret == -1){
792
	perror_plus("close");
793
      }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
794
      if(params.data == NULL){
795
	dhparamsfilename = NULL;
796
      }
797
      if(dhparamsfilename == NULL){
798
	break;
799
      }
800
      ret = gnutls_dh_params_import_pkcs3(mc->dh_params, &params,
801
					  GNUTLS_X509_FMT_PEM);
802
      if(ret != GNUTLS_E_SUCCESS){
803
	fprintf_plus(stderr, "Failed to parse DH parameters in file"
804
		     " \"%s\": %s\n", dhparamsfilename,
805
		     safer_gnutls_strerror(ret));
806
	dhparamsfilename = NULL;
807
      }
237.7.425 by Teddy Hogeborn
Fix bug where Mandos client would crash on exit
808
      free(params.data);
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
809
    } while(false);
810
  }
811
  if(dhparamsfilename == NULL){
812
    if(mc->dh_bits == 0){
813
      /* Find out the optimal number of DH bits */
814
      /* Try to read the private key file */
815
      gnutls_datum_t buffer = { .data = NULL, .size = 0 };
816
      do {
817
	int secfile = open(seckeyfilename, O_RDONLY);
818
	if(secfile == -1){
819
	  perror_plus("open");
820
	  break;
821
	}
822
	size_t buffer_capacity = 0;
823
	while(true){
824
	  buffer_capacity = incbuffer((char **)&buffer.data,
825
				      (size_t)buffer.size,
826
				      (size_t)buffer_capacity);
827
	  if(buffer_capacity == 0){
828
	    perror_plus("incbuffer");
829
	    free(buffer.data);
830
	    buffer.data = NULL;
831
	    break;
832
	  }
833
	  ssize_t bytes_read = read(secfile,
834
				    buffer.data + buffer.size,
835
				    BUFFER_SIZE);
836
	  /* EOF */
837
	  if(bytes_read == 0){
838
	    break;
839
	  }
840
	  /* check bytes_read for failure */
841
	  if(bytes_read < 0){
842
	    perror_plus("read");
843
	    free(buffer.data);
844
	    buffer.data = NULL;
845
	    break;
846
	  }
847
	  buffer.size += (unsigned int)bytes_read;
848
	}
849
	close(secfile);
850
      } while(false);
851
      /* If successful, use buffer to parse private key */
852
      gnutls_sec_param_t sec_param = GNUTLS_SEC_PARAM_ULTRA;
853
      if(buffer.data != NULL){
854
	{
855
	  gnutls_openpgp_privkey_t privkey = NULL;
856
	  ret = gnutls_openpgp_privkey_init(&privkey);
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
857
	  if(ret != GNUTLS_E_SUCCESS){
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
858
	    fprintf_plus(stderr, "Error initializing OpenPGP key"
859
			 " structure: %s",
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
860
			 safer_gnutls_strerror(ret));
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
861
	    free(buffer.data);
862
	    buffer.data = NULL;
863
	  } else {
864
	    ret = gnutls_openpgp_privkey_import
865
	      (privkey, &buffer, GNUTLS_OPENPGP_FMT_BASE64, "", 0);
866
	    if(ret != GNUTLS_E_SUCCESS){
867
	      fprintf_plus(stderr, "Error importing OpenPGP key : %s",
868
			   safer_gnutls_strerror(ret));
869
	      privkey = NULL;
870
	    }
871
	    free(buffer.data);
872
	    buffer.data = NULL;
873
	    if(privkey != NULL){
874
	      /* Use private key to suggest an appropriate
875
		 sec_param */
876
	      sec_param = gnutls_openpgp_privkey_sec_param(privkey);
877
	      gnutls_openpgp_privkey_deinit(privkey);
878
	      if(debug){
879
		fprintf_plus(stderr, "This OpenPGP key implies using"
880
			     " a GnuTLS security parameter \"%s\".\n",
881
			     safe_string(gnutls_sec_param_get_name
882
					 (sec_param)));
883
	      }
884
	    }
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
885
	  }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
886
	}
887
	if(sec_param == GNUTLS_SEC_PARAM_UNKNOWN){
888
	  /* Err on the side of caution */
889
	  sec_param = GNUTLS_SEC_PARAM_ULTRA;
890
	  if(debug){
891
	    fprintf_plus(stderr, "Falling back to security parameter"
892
			 " \"%s\"\n",
893
			 safe_string(gnutls_sec_param_get_name
894
				     (sec_param)));
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
895
	  }
896
	}
897
      }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
898
      uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
899
      if(uret != 0){
900
	mc->dh_bits = uret;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
901
	if(debug){
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
902
	  fprintf_plus(stderr, "A \"%s\" GnuTLS security parameter"
903
		       " implies %u DH bits; using that.\n",
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
904
		       safe_string(gnutls_sec_param_get_name
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
905
				   (sec_param)),
906
		       mc->dh_bits);
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
907
	}
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
908
      } else {
909
	fprintf_plus(stderr, "Failed to get implied number of DH"
910
		     " bits for security parameter \"%s\"): %s\n",
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
911
		     safe_string(gnutls_sec_param_get_name
912
				 (sec_param)),
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
913
		     safer_gnutls_strerror(ret));
914
	goto globalfail;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
915
      }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
916
    } else if(debug){
917
      fprintf_plus(stderr, "DH bits explicitly set to %u\n",
918
		   mc->dh_bits);
919
    }
920
    ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
921
    if(ret != GNUTLS_E_SUCCESS){
922
      fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
923
		   " bits): %s\n", mc->dh_bits,
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
924
		   safer_gnutls_strerror(ret));
925
      goto globalfail;
926
    }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
927
  }
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
928
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
929
  
24.1.13 by Björn Påhlsson
mandosclient
930
  return 0;
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
931
  
24.1.20 by Björn Påhlsson
mandosclient
932
 globalfail:
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
933
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
934
  gnutls_certificate_free_credentials(mc->cred);
935
  gnutls_dh_params_deinit(mc->dh_params);
24.1.20 by Björn Påhlsson
mandosclient
936
  return -1;
24.1.13 by Björn Påhlsson
mandosclient
937
}
938
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
939
__attribute__((nonnull, warn_unused_result))
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
940
static int init_gnutls_session(gnutls_session_t *session,
941
			       mandos_context *mc){
24.1.13 by Björn Påhlsson
mandosclient
942
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
943
  /* GnuTLS session creation */
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
944
  do {
945
    ret = gnutls_init(session, GNUTLS_SERVER);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
946
    if(quit_now){
947
      return -1;
948
    }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
949
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
950
  if(ret != GNUTLS_E_SUCCESS){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
951
    fprintf_plus(stderr,
952
		 "Error in GnuTLS session initialization: %s\n",
953
		 safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
954
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
955
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
956
  {
957
    const char *err;
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
958
    do {
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
959
      ret = gnutls_priority_set_direct(*session, mc->priority, &err);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
960
      if(quit_now){
961
	gnutls_deinit(*session);
962
	return -1;
963
      }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
964
    } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
965
    if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
966
      fprintf_plus(stderr, "Syntax error at: %s\n", err);
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
967
      fprintf_plus(stderr, "GnuTLS error: %s\n",
968
		   safer_gnutls_strerror(ret));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
969
      gnutls_deinit(*session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
970
      return -1;
971
    }
13 by Björn Påhlsson
Added following support:
972
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
973
  
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
974
  do {
975
    ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
976
				 mc->cred);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
977
    if(quit_now){
978
      gnutls_deinit(*session);
979
      return -1;
980
    }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
981
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
982
  if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
983
    fprintf_plus(stderr, "Error setting GnuTLS credentials: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
984
		 safer_gnutls_strerror(ret));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
985
    gnutls_deinit(*session);
13 by Björn Påhlsson
Added following support:
986
    return -1;
987
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
988
  
13 by Björn Påhlsson
Added following support:
989
  /* ignore client certificate if any. */
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
990
  gnutls_certificate_server_set_request(*session, GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
991
  
992
  return 0;
993
}
994
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
995
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
996
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
997
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
998
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
999
/* Helper function to add_local_route() and delete_local_route() */
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1000
__attribute__((nonnull, warn_unused_result))
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1001
static bool add_delete_local_route(const bool add,
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1002
				   const char *address,
1003
				   AvahiIfIndex if_index){
1004
  int ret;
1005
  char helper[] = "mandos-client-iprouteadddel";
1006
  char add_arg[] = "add";
237.25.4 by Teddy Hogeborn
Add plugin for mandos-client to add and delete local routes.
1007
  char delete_arg[] = "delete";
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1008
  char debug_flag[] = "--debug";
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1009
  char *pluginhelperdir = getenv("MANDOSPLUGINHELPERDIR");
1010
  if(pluginhelperdir == NULL){
1011
    if(debug){
1012
      fprintf_plus(stderr, "MANDOSPLUGINHELPERDIR environment"
1013
		   " variable not set; cannot run helper\n");
1014
    }
1015
    return false;
1016
  }
1017
  
1018
  char interface[IF_NAMESIZE];
1019
  if(if_indextoname((unsigned int)if_index, interface) == NULL){
1020
    perror_plus("if_indextoname");
1021
    return false;
1022
  }
1023
  
1024
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
1025
  if(devnull == -1){
1026
    perror_plus("open(\"/dev/null\", O_RDONLY)");
1027
    return false;
1028
  }
1029
  pid_t pid = fork();
1030
  if(pid == 0){
1031
    /* Child */
1032
    /* Raise privileges */
1033
    errno = raise_privileges_permanently();
1034
    if(errno != 0){
1035
      perror_plus("Failed to raise privileges");
1036
      /* _exit(EX_NOPERM); */
1037
    } else {
1038
      /* Set group */
1039
      errno = 0;
1040
      ret = setgid(0);
1041
      if(ret == -1){
1042
	perror_plus("setgid");
1043
	_exit(EX_NOPERM);
1044
      }
1045
      /* Reset supplementary groups */
1046
      errno = 0;
1047
      ret = setgroups(0, NULL);
1048
      if(ret == -1){
1049
	perror_plus("setgroups");
1050
	_exit(EX_NOPERM);
1051
      }
1052
    }
1053
    ret = dup2(devnull, STDIN_FILENO);
1054
    if(ret == -1){
1055
      perror_plus("dup2(devnull, STDIN_FILENO)");
1056
      _exit(EX_OSERR);
1057
    }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
1058
    ret = close(devnull);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1059
    if(ret == -1){
1060
      perror_plus("close");
1061
      _exit(EX_OSERR);
1062
    }
1063
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1064
    if(ret == -1){
1065
      perror_plus("dup2(STDERR_FILENO, STDOUT_FILENO)");
1066
      _exit(EX_OSERR);
1067
    }
1068
    int helperdir_fd = (int)TEMP_FAILURE_RETRY(open(pluginhelperdir,
1069
						    O_RDONLY
1070
						    | O_DIRECTORY
1071
						    | O_PATH
1072
						    | O_CLOEXEC));
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1073
    if(helperdir_fd == -1){
1074
      perror_plus("open");
1075
      _exit(EX_UNAVAILABLE);
1076
    }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1077
    int helper_fd = (int)TEMP_FAILURE_RETRY(openat(helperdir_fd,
1078
						   helper, O_RDONLY));
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1079
    if(helper_fd == -1){
1080
      perror_plus("openat");
237.7.323 by Teddy Hogeborn
plugin-runner: Minor fix: close helperdir before exiting in fork.
1081
      close(helperdir_fd);
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1082
      _exit(EX_UNAVAILABLE);
1083
    }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
1084
    close(helperdir_fd);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1085
#ifdef __GNUC__
1086
#pragma GCC diagnostic push
1087
#pragma GCC diagnostic ignored "-Wcast-qual"
1088
#endif
1089
    if(fexecve(helper_fd, (char *const [])
237.25.4 by Teddy Hogeborn
Add plugin for mandos-client to add and delete local routes.
1090
	       { helper, add ? add_arg : delete_arg, (char *)address,
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1091
		   interface, debug ? debug_flag : NULL, NULL },
1092
	       environ) == -1){
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1093
#ifdef __GNUC__
1094
#pragma GCC diagnostic pop
1095
#endif
1096
      perror_plus("fexecve");
1097
      _exit(EXIT_FAILURE);
1098
    }
1099
  }
1100
  if(pid == -1){
1101
    perror_plus("fork");
1102
    return false;
1103
  }
1104
  int status;
1105
  pid_t pret = -1;
1106
  errno = 0;
1107
  do {
1108
    pret = waitpid(pid, &status, 0);
1109
    if(pret == -1 and errno == EINTR and quit_now){
1110
      int errno_raising = 0;
1111
      if((errno = raise_privileges()) != 0){
1112
	errno_raising = errno;
1113
	perror_plus("Failed to raise privileges in order to"
1114
		    " kill helper program");
1115
      }
1116
      if(kill(pid, SIGTERM) == -1){
1117
	perror_plus("kill");
1118
      }
1119
      if((errno_raising == 0) and (errno = lower_privileges()) != 0){
1120
	perror_plus("Failed to lower privileges after killing"
1121
		    " helper program");
1122
      }
1123
      return false;
1124
    }
1125
  } while(pret == -1 and errno == EINTR);
1126
  if(pret == -1){
1127
    perror_plus("waitpid");
1128
    return false;
1129
  }
1130
  if(WIFEXITED(status)){
1131
    if(WEXITSTATUS(status) != 0){
1132
      fprintf_plus(stderr, "Error: iprouteadddel exited"
1133
		   " with status %d\n", WEXITSTATUS(status));
1134
      return false;
1135
    }
1136
    return true;
1137
  }
1138
  if(WIFSIGNALED(status)){
1139
    fprintf_plus(stderr, "Error: iprouteadddel died by"
1140
		 " signal %d\n", WTERMSIG(status));
1141
    return false;
1142
  }
1143
  fprintf_plus(stderr, "Error: iprouteadddel crashed\n");
1144
  return false;
1145
}
1146
1147
__attribute__((nonnull, warn_unused_result))
1148
static bool add_local_route(const char *address,
1149
			    AvahiIfIndex if_index){
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1150
  if(debug){
1151
    fprintf_plus(stderr, "Adding route to %s\n", address);
1152
  }
1153
  return add_delete_local_route(true, address, if_index);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1154
}
1155
1156
__attribute__((nonnull, warn_unused_result))
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1157
static bool delete_local_route(const char *address,
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1158
			       AvahiIfIndex if_index){
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1159
  if(debug){
1160
    fprintf_plus(stderr, "Removing route to %s\n", address);
1161
  }
1162
  return add_delete_local_route(false, address, if_index);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1163
}
1164
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1165
/* Called when a Mandos server is found */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1166
__attribute__((nonnull, warn_unused_result))
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1167
static int start_mandos_communication(const char *ip, in_port_t port,
24.1.9 by Björn Påhlsson
not working midwork...
1168
				      AvahiIfIndex if_index,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1169
				      int af, mandos_context *mc){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1170
  int ret, tcp_sd = -1;
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1171
  ssize_t sret;
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1172
  struct sockaddr_storage to;
13 by Björn Påhlsson
Added following support:
1173
  char *buffer = NULL;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1174
  char *decrypted_buffer = NULL;
13 by Björn Påhlsson
Added following support:
1175
  size_t buffer_length = 0;
1176
  size_t buffer_capacity = 0;
24.1.10 by Björn Påhlsson
merge commit
1177
  size_t written;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1178
  int retval = -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1179
  gnutls_session_t session;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1180
  int pf;			/* Protocol family */
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1181
  bool route_added = false;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1182
  
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1183
  errno = 0;
1184
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1185
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1186
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1187
    return -1;
1188
  }
1189
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1190
  switch(af){
1191
  case AF_INET6:
1192
    pf = PF_INET6;
1193
    break;
1194
  case AF_INET:
1195
    pf = PF_INET;
1196
    break;
1197
  default:
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1198
    fprintf_plus(stderr, "Bad address family: %d\n", af);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1199
    errno = EINVAL;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1200
    return -1;
1201
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1202
  
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
1203
  /* If the interface is specified and we have a list of interfaces */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
1204
  if(if_index != AVAHI_IF_UNSPEC and mc->interfaces != NULL){
1205
    /* Check if the interface is one of the interfaces we are using */
1206
    bool match = false;
1207
    {
1208
      char *interface = NULL;
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
1209
      while((interface = argz_next(mc->interfaces,
1210
				   mc->interfaces_size,
1211
				   interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
1212
	if(if_nametoindex(interface) == (unsigned int)if_index){
1213
	  match = true;
1214
	  break;
1215
	}
1216
      }
1217
    }
1218
    if(not match){
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
1219
      /* This interface does not match any in the list, so we don't
1220
	 connect to the server */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
1221
      if(debug){
1222
	char interface[IF_NAMESIZE];
1223
	if(if_indextoname((unsigned int)if_index, interface) == NULL){
1224
	  perror_plus("if_indextoname");
1225
	} else {
1226
	  fprintf_plus(stderr, "Skipping server on non-used interface"
1227
		       " \"%s\"\n",
1228
		       if_indextoname((unsigned int)if_index,
1229
				      interface));
1230
	}
1231
      }
1232
      return -1;
1233
    }
1234
  }
1235
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1236
  ret = init_gnutls_session(&session, mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1237
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1238
    return -1;
1239
  }
1240
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1241
  if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1242
    fprintf_plus(stderr, "Setting up a TCP connection to %s, port %"
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1243
		 PRIuMAX "\n", ip, (uintmax_t)port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1244
  }
13 by Björn Påhlsson
Added following support:
1245
  
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1246
  tcp_sd = socket(pf, SOCK_STREAM | SOCK_CLOEXEC, 0);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1247
  if(tcp_sd < 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1248
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1249
    perror_plus("socket");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1250
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1251
    goto mandos_end;
1252
  }
1253
  
1254
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1255
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1256
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1257
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1258
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1259
  if(af == AF_INET6){
237.7.321 by Teddy Hogeborn
mandos-client: Don't use memset().
1260
    struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&to;
1261
    *to6 = (struct sockaddr_in6){ .sin6_family = (sa_family_t)af };
1262
    ret = inet_pton(af, ip, &to6->sin6_addr);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1263
  } else {			/* IPv4 */
237.7.321 by Teddy Hogeborn
mandos-client: Don't use memset().
1264
    struct sockaddr_in *to4 = (struct sockaddr_in *)&to;
1265
    *to4 = (struct sockaddr_in){ .sin_family = (sa_family_t)af };
1266
    ret = inet_pton(af, ip, &to4->sin_addr);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1267
  }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1268
  if(ret < 0 ){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1269
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1270
    perror_plus("inet_pton");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1271
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1272
    goto mandos_end;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1273
  }
13 by Björn Påhlsson
Added following support:
1274
  if(ret == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1275
    int e = errno;
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1276
    fprintf_plus(stderr, "Bad address: %s\n", ip);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1277
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1278
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1279
  }
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1280
  if(af == AF_INET6){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1281
    ((struct sockaddr_in6 *)&to)->sin6_port = htons(port);
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1282
    if(IN6_IS_ADDR_LINKLOCAL
1283
       (&((struct sockaddr_in6 *)&to)->sin6_addr)){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1284
      if(if_index == AVAHI_IF_UNSPEC){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1285
	fprintf_plus(stderr, "An IPv6 link-local address is"
1286
		     " incomplete without a network interface\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1287
	errno = EINVAL;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1288
	goto mandos_end;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1289
      }
1290
      /* Set the network interface number as scope */
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1291
      ((struct sockaddr_in6 *)&to)->sin6_scope_id = (uint32_t)if_index;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1292
    }
1293
  } else {
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1294
    ((struct sockaddr_in *)&to)->sin_port = htons(port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1295
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1296
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1297
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1298
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1299
    goto mandos_end;
1300
  }
1301
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1302
  if(debug){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1303
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
1304
      char interface[IF_NAMESIZE];
1305
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1306
	perror_plus("if_indextoname");
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1307
      } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1308
	fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIuMAX
1309
		     "\n", ip, interface, (uintmax_t)port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1310
      }
1311
    } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1312
      fprintf_plus(stderr, "Connection to: %s, port %" PRIuMAX "\n",
1313
		   ip, (uintmax_t)port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1314
    }
1315
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
1316
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
1317
    if(af == AF_INET6){
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1318
      ret = getnameinfo((struct sockaddr *)&to,
1319
			sizeof(struct sockaddr_in6),
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1320
			addrstr, sizeof(addrstr), NULL, 0,
1321
			NI_NUMERICHOST);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1322
    } else {
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1323
      ret = getnameinfo((struct sockaddr *)&to,
1324
			sizeof(struct sockaddr_in),
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1325
			addrstr, sizeof(addrstr), NULL, 0,
1326
			NI_NUMERICHOST);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1327
    }
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1328
    if(ret == EAI_SYSTEM){
1329
      perror_plus("getnameinfo");
1330
    } else if(ret != 0) {
1331
      fprintf_plus(stderr, "getnameinfo: %s", gai_strerror(ret));
1332
    } else if(strcmp(addrstr, ip) != 0){
1333
      fprintf_plus(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
1334
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1335
  }
13 by Björn Påhlsson
Added following support:
1336
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1337
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1338
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1339
    goto mandos_end;
1340
  }
1341
  
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1342
  while(true){
1343
    if(af == AF_INET6){
1344
      ret = connect(tcp_sd, (struct sockaddr *)&to,
1345
		    sizeof(struct sockaddr_in6));
1346
    } else {
1347
      ret = connect(tcp_sd, (struct sockaddr *)&to, /* IPv4 */
1348
		    sizeof(struct sockaddr_in));
1349
    }
1350
    if(ret < 0){
237.7.338 by Teddy Hogeborn
Bug fix: Add local route also when host is unreachable.
1351
      if(((errno == ENETUNREACH) or (errno == EHOSTUNREACH))
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1352
	 and if_index != AVAHI_IF_UNSPEC
1353
	 and connect_to == NULL
1354
	 and not route_added and
1355
	 ((af == AF_INET6 and not
1356
	   IN6_IS_ADDR_LINKLOCAL(&(((struct sockaddr_in6 *)
1357
				    &to)->sin6_addr)))
1358
	  or (af == AF_INET and
1359
	      /* Not a a IPv4LL address */
1360
	      (ntohl(((struct sockaddr_in *)&to)->sin_addr.s_addr)
1361
	       & 0xFFFF0000L) != 0xA9FE0000L))){
1362
	/* Work around Avahi bug - Avahi does not announce link-local
1363
	   addresses if it has a global address, so local hosts with
1364
	   *only* a link-local address (e.g. Mandos clients) cannot
1365
	   connect to a Mandos server announced by Avahi on a server
1366
	   host with a global address.  Work around this by retrying
1367
	   with an explicit route added with the server's address.
1368
	   
1369
	   Avahi bug reference:
237.7.416 by Teddy Hogeborn
Change all http:// URLs to https:// wherever possible.
1370
	   https://lists.freedesktop.org/archives/avahi/2010-February/001833.html
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1371
	   https://bugs.debian.org/587961
1372
	*/
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1373
	if(debug){
1374
	  fprintf_plus(stderr, "Mandos server unreachable, trying"
1375
		       " direct route\n");
1376
	}
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1377
	int e = errno;
1378
	route_added = add_local_route(ip, if_index);
1379
	if(route_added){
1380
	  continue;
1381
	}
1382
	errno = e;
1383
      }
1384
      if(errno != ECONNREFUSED or debug){
1385
	int e = errno;
1386
	perror_plus("connect");
1387
	errno = e;
1388
      }
1389
      goto mandos_end;
1390
    }
1391
    
1392
    if(quit_now){
1393
      errno = EINTR;
1394
      goto mandos_end;
1395
    }
1396
    break;
13 by Björn Påhlsson
Added following support:
1397
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1398
  
24.1.12 by Björn Påhlsson
merge +
1399
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
1400
  written = 0;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1401
  while(true){
24.1.10 by Björn Påhlsson
merge commit
1402
    size_t out_size = strlen(out);
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1403
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1404
					out_size - written));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1405
    if(ret == -1){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1406
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1407
      perror_plus("write");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1408
      errno = e;
24.1.12 by Björn Påhlsson
merge +
1409
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
1410
    }
24.1.12 by Björn Påhlsson
merge +
1411
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
1412
    if(written < out_size){
1413
      continue;
1414
    } else {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1415
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
1416
	written = 0;
1417
	out = "\r\n";
1418
      } else {
1419
	break;
1420
      }
1421
    }
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1422
  
1423
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1424
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1425
      goto mandos_end;
1426
    }
24.1.10 by Björn Påhlsson
merge commit
1427
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1428
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1429
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1430
    fprintf_plus(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
1431
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1432
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1433
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1434
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1435
    goto mandos_end;
1436
  }
1437
  
237.7.136 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Eliminate
1438
  /* This casting via intptr_t is to eliminate warning about casting
1439
     an int to a pointer type.  This is exactly how the GnuTLS Guile
1440
     function "set-session-transport-fd!" does it. */
1441
  gnutls_transport_set_ptr(session,
1442
			   (gnutls_transport_ptr_t)(intptr_t)tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1443
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1444
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1445
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1446
    goto mandos_end;
1447
  }
1448
  
237.2.126 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
1449
  do {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1450
    ret = gnutls_handshake(session);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1451
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1452
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1453
      goto mandos_end;
1454
    }
24.1.29 by Björn Påhlsson
Added more header file comments
1455
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
1456
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1457
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
1458
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1459
      fprintf_plus(stderr, "*** GnuTLS Handshake failed ***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1460
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
1461
    }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1462
    errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1463
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1464
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1465
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1466
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1467
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1468
  if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1469
    fprintf_plus(stderr, "Retrieving OpenPGP encrypted password from"
1470
		 " %s\n", ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1471
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1472
  
13 by Björn Påhlsson
Added following support:
1473
  while(true){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1474
    
1475
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1476
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1477
      goto mandos_end;
1478
    }
1479
    
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
1480
    buffer_capacity = incbuffer(&buffer, buffer_length,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1481
				buffer_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1482
    if(buffer_capacity == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1483
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1484
      perror_plus("incbuffer");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1485
      errno = e;
24.1.12 by Björn Påhlsson
merge +
1486
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
1487
    }
1488
    
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1489
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1490
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1491
      goto mandos_end;
1492
    }
1493
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1494
    sret = gnutls_record_recv(session, buffer+buffer_length,
1495
			      BUFFER_SIZE);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1496
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
1497
      break;
1498
    }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1499
    if(sret < 0){
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1500
      switch(sret){
13 by Björn Påhlsson
Added following support:
1501
      case GNUTLS_E_INTERRUPTED:
1502
      case GNUTLS_E_AGAIN:
1503
	break;
1504
      case GNUTLS_E_REHANDSHAKE:
237.2.126 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
1505
	do {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1506
	  ret = gnutls_handshake(session);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1507
	  
1508
	  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1509
	    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1510
	    goto mandos_end;
1511
	  }
24.1.29 by Björn Påhlsson
Added more header file comments
1512
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1513
	if(ret < 0){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1514
	  fprintf_plus(stderr, "*** GnuTLS Re-handshake failed "
1515
		       "***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1516
	  gnutls_perror(ret);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1517
	  errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1518
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
1519
	}
1520
	break;
1521
      default:
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1522
	fprintf_plus(stderr, "Unknown error while reading data from"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1523
		     " encrypted session with Mandos server\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1524
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1525
	errno = EIO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1526
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
1527
      }
1528
    } else {
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1529
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
1530
    }
1531
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1532
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1533
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1534
    fprintf_plus(stderr, "Closing TLS session\n");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1535
  }
1536
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1537
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1538
    errno = EINTR;
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
1539
    goto mandos_end;
1540
  }
1541
  
1542
  do {
1543
    ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
1544
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1545
      errno = EINTR;
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
1546
      goto mandos_end;
1547
    }
1548
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1549
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1550
  if(buffer_length > 0){
237.2.125 by Teddy Hogeborn
* plugin-runner.c (getplugin, add_environment, main): Handle EINTR
1551
    ssize_t decrypted_buffer_size;
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1552
    decrypted_buffer_size = pgp_packet_decrypt(buffer, buffer_length,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1553
					       &decrypted_buffer, mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1554
    if(decrypted_buffer_size >= 0){
237.2.124 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
1555
      
237.7.414 by Teddy Hogeborn
mandos-client: Bug fix: flush stdout to detect write errors.
1556
      clearerr(stdout);
24.1.10 by Björn Påhlsson
merge commit
1557
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
1558
      while(written < (size_t) decrypted_buffer_size){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1559
	if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1560
	  errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1561
	  goto mandos_end;
1562
	}
1563
	
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1564
	ret = (int)fwrite(decrypted_buffer + written, 1,
1565
			  (size_t)decrypted_buffer_size - written,
1566
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1567
	if(ret == 0 and ferror(stdout)){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1568
	  int e = errno;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1569
	  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1570
	    fprintf_plus(stderr, "Error writing encrypted data: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1571
			 strerror(errno));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1572
	  }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1573
	  errno = e;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1574
	  goto mandos_end;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1575
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1576
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1577
      }
237.7.414 by Teddy Hogeborn
mandos-client: Bug fix: flush stdout to detect write errors.
1578
      ret = fflush(stdout);
1579
      if(ret != 0){
1580
	int e = errno;
1581
	if(debug){
1582
	  fprintf_plus(stderr, "Error writing encrypted data: %s\n",
1583
		       strerror(errno));
1584
	}
1585
	errno = e;
1586
	goto mandos_end;
1587
      }
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1588
      retval = 0;
13 by Björn Påhlsson
Added following support:
1589
    }
1590
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1591
  
1592
  /* Shutdown procedure */
1593
  
1594
 mandos_end:
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1595
  {
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1596
    if(route_added){
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1597
      if(not delete_local_route(ip, if_index)){
1598
	fprintf_plus(stderr, "Failed to delete local route to %s on"
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1599
		     " interface %d", ip, if_index);
1600
      }
1601
    }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1602
    int e = errno;
1603
    free(decrypted_buffer);
1604
    free(buffer);
1605
    if(tcp_sd >= 0){
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
1606
      ret = close(tcp_sd);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1607
    }
1608
    if(ret == -1){
1609
      if(e == 0){
1610
	e = errno;
1611
      }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1612
      perror_plus("close");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1613
    }
1614
    gnutls_deinit(session);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1615
    errno = e;
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1616
    if(quit_now){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1617
      errno = EINTR;
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1618
      retval = -1;
1619
    }
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1620
  }
13 by Björn Påhlsson
Added following support:
1621
  return retval;
1622
}
1623
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
1624
static void resolve_callback(AvahiSServiceResolver *r,
1625
			     AvahiIfIndex interface,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1626
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
1627
			     AvahiResolverEvent event,
1628
			     const char *name,
1629
			     const char *type,
1630
			     const char *domain,
1631
			     const char *host_name,
1632
			     const AvahiAddress *address,
1633
			     uint16_t port,
1634
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
1635
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
1636
			     flags,
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1637
			     void *mc){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1638
  if(r == NULL){
1639
    return;
1640
  }
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1641
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1642
  /* Called whenever a service has been resolved successfully or
1643
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1644
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1645
  if(quit_now){
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1646
    avahi_s_service_resolver_free(r);
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1647
    return;
1648
  }
1649
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1650
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1651
  default:
1652
  case AVAHI_RESOLVER_FAILURE:
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1653
    fprintf_plus(stderr, "(Avahi Resolver) Failed to resolve service "
1654
		 "'%s' of type '%s' in domain '%s': %s\n", name, type,
1655
		 domain,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1656
		 avahi_strerror(avahi_server_errno
1657
				(((mandos_context*)mc)->server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1658
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1659
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1660
  case AVAHI_RESOLVER_FOUND:
1661
    {
1662
      char ip[AVAHI_ADDRESS_STR_MAX];
1663
      avahi_address_snprint(ip, sizeof(ip), address);
1664
      if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1665
	fprintf_plus(stderr, "Mandos server \"%s\" found on %s (%s, %"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1666
		     PRIdMAX ") on port %" PRIu16 "\n", name,
1667
		     host_name, ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1668
      }
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1669
      int ret = start_mandos_communication(ip, (in_port_t)port,
1670
					   interface,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1671
					   avahi_proto_to_af(proto),
1672
					   mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1673
      if(ret == 0){
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1674
	avahi_simple_poll_quit(simple_poll);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1675
      } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1676
	if(not add_server(ip, (in_port_t)port, interface,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1677
			  avahi_proto_to_af(proto),
1678
			  &((mandos_context*)mc)->current_server)){
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
1679
	  fprintf_plus(stderr, "Failed to add server \"%s\" to server"
1680
		       " list\n", name);
1681
	}
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1682
      }
13 by Björn Påhlsson
Added following support:
1683
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1684
  }
1685
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
1686
}
1687
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1688
static void browse_callback(AvahiSServiceBrowser *b,
1689
			    AvahiIfIndex interface,
1690
			    AvahiProtocol protocol,
1691
			    AvahiBrowserEvent event,
1692
			    const char *name,
1693
			    const char *type,
1694
			    const char *domain,
1695
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
1696
			    flags,
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1697
			    void *mc){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1698
  if(b == NULL){
1699
    return;
1700
  }
24.1.9 by Björn Påhlsson
not working midwork...
1701
  
1702
  /* Called whenever a new services becomes available on the LAN or
1703
     is removed from the LAN */
1704
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1705
  if(quit_now){
1706
    return;
1707
  }
1708
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1709
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
1710
  default:
1711
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1712
    
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1713
    fprintf_plus(stderr, "(Avahi browser) %s\n",
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1714
		 avahi_strerror(avahi_server_errno
1715
				(((mandos_context*)mc)->server)));
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1716
    avahi_simple_poll_quit(simple_poll);
24.1.9 by Björn Påhlsson
not working midwork...
1717
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1718
    
24.1.9 by Björn Påhlsson
not working midwork...
1719
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1720
    /* We ignore the returned Avahi resolver object. In the callback
1721
       function we free it. If the Avahi server is terminated before
1722
       the callback function is called the Avahi server will free the
1723
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1724
    
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1725
    if(avahi_s_service_resolver_new(((mandos_context*)mc)->server,
1726
				    interface, protocol, name, type,
1727
				    domain, protocol, 0,
1728
				    resolve_callback, mc) == NULL)
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1729
      fprintf_plus(stderr, "Avahi: Failed to resolve service '%s':"
1730
		   " %s\n", name,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1731
		   avahi_strerror(avahi_server_errno
1732
				  (((mandos_context*)mc)->server)));
24.1.9 by Björn Påhlsson
not working midwork...
1733
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1734
    
24.1.9 by Björn Påhlsson
not working midwork...
1735
  case AVAHI_BROWSER_REMOVE:
1736
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1737
    
24.1.9 by Björn Påhlsson
not working midwork...
1738
  case AVAHI_BROWSER_ALL_FOR_NOW:
1739
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1740
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1741
      fprintf_plus(stderr, "No Mandos server found, still"
1742
		   " searching...\n");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1743
    }
24.1.9 by Björn Påhlsson
not working midwork...
1744
    break;
1745
  }
13 by Björn Påhlsson
Added following support:
1746
}
1747
237.7.33 by Teddy Hogeborn
Merge from Björn.
1748
/* Signal handler that stops main loop after SIGTERM */
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1749
static void handle_sigterm(int sig){
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1750
  if(quit_now){
1751
    return;
1752
  }
1753
  quit_now = 1;
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1754
  signal_received = sig;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1755
  int old_errno = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1756
  /* set main loop to exit */
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1757
  if(simple_poll != NULL){
1758
    avahi_simple_poll_quit(simple_poll);
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1759
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1760
  errno = old_errno;
1761
}
1762
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1763
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1764
bool get_flags(const char *ifname, struct ifreq *ifr){
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1765
  int ret;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1766
  int old_errno;
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1767
  
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1768
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1769
  if(s < 0){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1770
    old_errno = errno;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1771
    perror_plus("socket");
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1772
    errno = old_errno;
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1773
    return false;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1774
  }
237.7.346 by Teddy Hogeborn
plugins.d/mandos-client.c (get_flags): Use strncpy(), not strcpy().
1775
  strncpy(ifr->ifr_name, ifname, IF_NAMESIZE);
1776
  ifr->ifr_name[IF_NAMESIZE-1] = '\0'; /* NUL terminate */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1777
  ret = ioctl(s, SIOCGIFFLAGS, ifr);
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1778
  if(ret == -1){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1779
    if(debug){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1780
      old_errno = errno;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1781
      perror_plus("ioctl SIOCGIFFLAGS");
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1782
      errno = old_errno;
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1783
    }
237.7.489 by Teddy Hogeborn
Check return values from newly added close() calls
1784
    if((close(s) == -1) and debug){
1785
      old_errno = errno;
1786
      perror_plus("close");
1787
      errno = old_errno;
1788
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1789
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1790
  }
237.7.489 by Teddy Hogeborn
Check return values from newly added close() calls
1791
  if((close(s) == -1) and debug){
1792
    old_errno = errno;
1793
    perror_plus("close");
1794
    errno = old_errno;
1795
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1796
  return true;
1797
}
1798
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1799
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1800
bool good_flags(const char *ifname, const struct ifreq *ifr){
1801
  
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1802
  /* Reject the loopback device */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1803
  if(ifr->ifr_flags & IFF_LOOPBACK){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1804
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1805
      fprintf_plus(stderr, "Rejecting loopback interface \"%s\"\n",
1806
		   ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1807
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1808
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1809
  }
1810
  /* Accept point-to-point devices only if connect_to is specified */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1811
  if(connect_to != NULL and (ifr->ifr_flags & IFF_POINTOPOINT)){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1812
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1813
      fprintf_plus(stderr, "Accepting point-to-point interface"
1814
		   " \"%s\"\n", ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1815
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1816
    return true;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1817
  }
1818
  /* Otherwise, reject non-broadcast-capable devices */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1819
  if(not (ifr->ifr_flags & IFF_BROADCAST)){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1820
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1821
      fprintf_plus(stderr, "Rejecting non-broadcast interface"
1822
		   " \"%s\"\n", ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1823
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1824
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1825
  }
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1826
  /* Reject non-ARP interfaces (including dummy interfaces) */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1827
  if(ifr->ifr_flags & IFF_NOARP){
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1828
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1829
      fprintf_plus(stderr, "Rejecting non-ARP interface \"%s\"\n",
1830
		   ifname);
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1831
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1832
    return false;
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1833
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1834
  
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1835
  /* Accept this device */
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1836
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1837
    fprintf_plus(stderr, "Interface \"%s\" is good\n", ifname);
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1838
  }
1839
  return true;
1840
}
1841
1842
/* 
1843
 * This function determines if a directory entry in /sys/class/net
1844
 * corresponds to an acceptable network device.
1845
 * (This function is passed to scandir(3) as a filter function.)
1846
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1847
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1848
int good_interface(const struct dirent *if_entry){
1849
  if(if_entry->d_name[0] == '.'){
1850
    return 0;
1851
  }
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1852
  
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1853
  struct ifreq ifr;
1854
  if(not get_flags(if_entry->d_name, &ifr)){
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1855
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1856
      fprintf_plus(stderr, "Failed to get flags for interface "
1857
		   "\"%s\"\n", if_entry->d_name);
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1858
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1859
    return 0;
1860
  }
1861
  
1862
  if(not good_flags(if_entry->d_name, &ifr)){
1863
    return 0;
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1864
  }
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1865
  return 1;
1866
}
1867
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1868
/* 
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1869
 * This function determines if a network interface is up.
1870
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1871
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1872
bool interface_is_up(const char *interface){
1873
  struct ifreq ifr;
1874
  if(not get_flags(interface, &ifr)){
1875
    if(debug){
1876
      fprintf_plus(stderr, "Failed to get flags for interface "
1877
		   "\"%s\"\n", interface);
1878
    }
1879
    return false;
1880
  }
1881
  
1882
  return (bool)(ifr.ifr_flags & IFF_UP);
1883
}
1884
1885
/* 
1886
 * This function determines if a network interface is running
1887
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1888
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1889
bool interface_is_running(const char *interface){
1890
  struct ifreq ifr;
1891
  if(not get_flags(interface, &ifr)){
1892
    if(debug){
1893
      fprintf_plus(stderr, "Failed to get flags for interface "
1894
		   "\"%s\"\n", interface);
1895
    }
1896
    return false;
1897
  }
1898
  
1899
  return (bool)(ifr.ifr_flags & IFF_RUNNING);
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1900
}
1901
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1902
__attribute__((nonnull, pure, warn_unused_result))
24.1.172 by Björn Påhlsson
using scandir instead of readdir
1903
int notdotentries(const struct dirent *direntry){
1904
  /* Skip "." and ".." */
1905
  if(direntry->d_name[0] == '.'
1906
     and (direntry->d_name[1] == '\0'
1907
	  or (direntry->d_name[1] == '.'
1908
	      and direntry->d_name[2] == '\0'))){
1909
    return 0;
1910
  }
1911
  return 1;
1912
}
1913
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1914
/* Is this directory entry a runnable program? */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1915
__attribute__((nonnull, warn_unused_result))
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1916
int runnable_hook(const struct dirent *direntry){
1917
  int ret;
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1918
  size_t sret;
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1919
  struct stat st;
1920
  
1921
  if((direntry->d_name)[0] == '\0'){
1922
    /* Empty name? */
1923
    return 0;
1924
  }
1925
  
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1926
  sret = strspn(direntry->d_name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1927
		"abcdefghijklmnopqrstuvwxyz"
1928
		"0123456789"
237.7.236 by Teddy Hogeborn
Minor bug fix in mandos-client: Allow periods in network hook names.
1929
		"_.-");
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1930
  if((direntry->d_name)[sret] != '\0'){
1931
    /* Contains non-allowed characters */
1932
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1933
      fprintf_plus(stderr, "Ignoring hook \"%s\" with bad name\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1934
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1935
    }
1936
    return 0;
1937
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1938
  
237.7.241 by Teddy Hogeborn
Make mandos-client use fstatat().
1939
  ret = fstatat(hookdir_fd, direntry->d_name, &st, 0);
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1940
  if(ret == -1){
1941
    if(debug){
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1942
      perror_plus("Could not stat hook");
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1943
    }
1944
    return 0;
1945
  }
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1946
  if(not (S_ISREG(st.st_mode))){
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1947
    /* Not a regular file */
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1948
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1949
      fprintf_plus(stderr, "Ignoring hook \"%s\" - not a file\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1950
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1951
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1952
    return 0;
1953
  }
1954
  if(not (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))){
1955
    /* Not executable */
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1956
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1957
      fprintf_plus(stderr, "Ignoring hook \"%s\" - not executable\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1958
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1959
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1960
    return 0;
1961
  }
237.16.12 by Teddy Hogeborn
* plugins.d/mandos-client.c (runnable_hook): Add debug output.
1962
  if(debug){
1963
    fprintf_plus(stderr, "Hook \"%s\" is acceptable\n",
1964
		 direntry->d_name);
1965
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1966
  return 1;
1967
}
1968
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1969
__attribute__((nonnull, warn_unused_result))
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1970
int avahi_loop_with_timeout(AvahiSimplePoll *s, int retry_interval,
1971
			    mandos_context *mc){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1972
  int ret;
1973
  struct timespec now;
1974
  struct timespec waited_time;
1975
  intmax_t block_time;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1976
  
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1977
  while(true){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1978
    if(mc->current_server == NULL){
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1979
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1980
	fprintf_plus(stderr, "Wait until first server is found."
1981
		     " No timeout!\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1982
      }
1983
      ret = avahi_simple_poll_iterate(s, -1);
1984
    } else {
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1985
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1986
	fprintf_plus(stderr, "Check current_server if we should run"
1987
		     " it, or wait\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1988
      }
1989
      /* the current time */
1990
      ret = clock_gettime(CLOCK_MONOTONIC, &now);
1991
      if(ret == -1){
1992
	perror_plus("clock_gettime");
1993
	return -1;
1994
      }
1995
      /* Calculating in ms how long time between now and server
1996
	 who we visted longest time ago. Now - last seen.  */
237.7.33 by Teddy Hogeborn
Merge from Björn.
1997
      waited_time.tv_sec = (now.tv_sec
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1998
			    - mc->current_server->last_seen.tv_sec);
237.7.33 by Teddy Hogeborn
Merge from Björn.
1999
      waited_time.tv_nsec = (now.tv_nsec
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2000
			     - mc->current_server->last_seen.tv_nsec);
237.7.33 by Teddy Hogeborn
Merge from Björn.
2001
      /* total time is 10s/10,000ms.
2002
	 Converting to s from ms by dividing by 1,000,
2003
	 and ns to ms by dividing by 1,000,000. */
2004
      block_time = ((retry_interval
2005
		     - ((intmax_t)waited_time.tv_sec * 1000))
2006
		    - ((intmax_t)waited_time.tv_nsec / 1000000));
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2007
      
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
2008
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2009
	fprintf_plus(stderr, "Blocking for %" PRIdMAX " ms\n",
2010
		     block_time);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2011
      }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2012
      
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2013
      if(block_time <= 0){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2014
	ret = start_mandos_communication(mc->current_server->ip,
2015
					 mc->current_server->port,
2016
					 mc->current_server->if_index,
2017
					 mc->current_server->af, mc);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2018
	if(ret == 0){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2019
	  avahi_simple_poll_quit(s);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2020
	  return 0;
2021
	}
237.7.33 by Teddy Hogeborn
Merge from Björn.
2022
	ret = clock_gettime(CLOCK_MONOTONIC,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2023
			    &mc->current_server->last_seen);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2024
	if(ret == -1){
2025
	  perror_plus("clock_gettime");
2026
	  return -1;
2027
	}
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2028
	mc->current_server = mc->current_server->next;
237.7.33 by Teddy Hogeborn
Merge from Björn.
2029
	block_time = 0; 	/* Call avahi to find new Mandos
2030
				   servers, but don't block */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2031
      }
2032
      
2033
      ret = avahi_simple_poll_iterate(s, (int)block_time);
2034
    }
2035
    if(ret != 0){
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
2036
      if(ret > 0 or errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2037
	return (ret != 1) ? ret : 0;
2038
      }
2039
    }
2040
  }
2041
}
2042
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2043
__attribute__((nonnull))
2044
void run_network_hooks(const char *mode, const char *interface,
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2045
		       const float delay){
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2046
  struct dirent **direntries = NULL;
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2047
  if(hookdir_fd == -1){
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2048
    hookdir_fd = open(hookdir, O_RDONLY | O_DIRECTORY | O_PATH
2049
		      | O_CLOEXEC);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2050
    if(hookdir_fd == -1){
2051
      if(errno == ENOENT){
2052
	if(debug){
2053
	  fprintf_plus(stderr, "Network hook directory \"%s\" not"
2054
		       " found\n", hookdir);
2055
	}
2056
      } else {
2057
	perror_plus("open");
2058
      }
2059
      return;
2060
    }
2061
  }
237.7.483 by Teddy Hogeborn
Client: Bug fix: Possible memory leak if failing to open /dev/null
2062
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
2063
  if(devnull == -1){
2064
    perror_plus("open(\"/dev/null\", O_RDONLY)");
2065
    return;
2066
  }
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2067
  int numhooks = scandirat(hookdir_fd, ".", &direntries,
2068
			   runnable_hook, alphasort);
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2069
  if(numhooks == -1){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2070
    perror_plus("scandir");
237.7.483 by Teddy Hogeborn
Client: Bug fix: Possible memory leak if failing to open /dev/null
2071
    close(devnull);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2072
    return;
2073
  }
2074
  struct dirent *direntry;
2075
  int ret;
2076
  for(int i = 0; i < numhooks; i++){
2077
    direntry = direntries[i];
2078
    if(debug){
2079
      fprintf_plus(stderr, "Running network hook \"%s\"\n",
2080
		   direntry->d_name);
2081
    }
2082
    pid_t hook_pid = fork();
2083
    if(hook_pid == 0){
2084
      /* Child */
2085
      /* Raise privileges */
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2086
      errno = raise_privileges_permanently();
2087
      if(errno != 0){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2088
	perror_plus("Failed to raise privileges");
2089
	_exit(EX_NOPERM);
2090
      }
2091
      /* Set group */
2092
      errno = 0;
2093
      ret = setgid(0);
2094
      if(ret == -1){
2095
	perror_plus("setgid");
2096
	_exit(EX_NOPERM);
2097
      }
2098
      /* Reset supplementary groups */
2099
      errno = 0;
2100
      ret = setgroups(0, NULL);
2101
      if(ret == -1){
2102
	perror_plus("setgroups");
2103
	_exit(EX_NOPERM);
2104
      }
2105
      ret = setenv("MANDOSNETHOOKDIR", hookdir, 1);
2106
      if(ret == -1){
2107
	perror_plus("setenv");
2108
	_exit(EX_OSERR);
2109
      }
2110
      ret = setenv("DEVICE", interface, 1);
2111
      if(ret == -1){
2112
	perror_plus("setenv");
2113
	_exit(EX_OSERR);
2114
      }
2115
      ret = setenv("VERBOSITY", debug ? "1" : "0", 1);
2116
      if(ret == -1){
2117
	perror_plus("setenv");
2118
	_exit(EX_OSERR);
2119
      }
2120
      ret = setenv("MODE", mode, 1);
2121
      if(ret == -1){
2122
	perror_plus("setenv");
2123
	_exit(EX_OSERR);
2124
      }
2125
      char *delaystring;
2126
      ret = asprintf(&delaystring, "%f", (double)delay);
2127
      if(ret == -1){
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2128
	perror_plus("asprintf");
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2129
	_exit(EX_OSERR);
2130
      }
2131
      ret = setenv("DELAY", delaystring, 1);
2132
      if(ret == -1){
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2133
	free(delaystring);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2134
	perror_plus("setenv");
2135
	_exit(EX_OSERR);
2136
      }
2137
      free(delaystring);
2138
      if(connect_to != NULL){
2139
	ret = setenv("CONNECT", connect_to, 1);
2140
	if(ret == -1){
2141
	  perror_plus("setenv");
2142
	  _exit(EX_OSERR);
2143
	}
2144
      }
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
2145
      int hook_fd = (int)TEMP_FAILURE_RETRY(openat(hookdir_fd,
2146
						   direntry->d_name,
2147
						   O_RDONLY));
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
2148
      if(hook_fd == -1){
2149
	perror_plus("openat");
2150
	_exit(EXIT_FAILURE);
2151
      }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2152
      if(close(hookdir_fd) == -1){
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
2153
	perror_plus("close");
2154
	_exit(EXIT_FAILURE);
2155
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2156
      ret = dup2(devnull, STDIN_FILENO);
2157
      if(ret == -1){
2158
	perror_plus("dup2(devnull, STDIN_FILENO)");
2159
	_exit(EX_OSERR);
2160
      }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2161
      ret = close(devnull);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2162
      if(ret == -1){
2163
	perror_plus("close");
2164
	_exit(EX_OSERR);
2165
      }
2166
      ret = dup2(STDERR_FILENO, STDOUT_FILENO);
2167
      if(ret == -1){
2168
	perror_plus("dup2(STDERR_FILENO, STDOUT_FILENO)");
2169
	_exit(EX_OSERR);
2170
      }
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
2171
      if(fexecve(hook_fd, (char *const []){ direntry->d_name, NULL },
2172
		 environ) == -1){
237.7.240 by Teddy Hogeborn
Make mandos-client use fexecve().
2173
	perror_plus("fexecve");
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2174
	_exit(EXIT_FAILURE);
2175
      }
2176
    } else {
237.7.281 by Teddy Hogeborn
mandos-client: Bug fix: Check fork() return value.
2177
      if(hook_pid == -1){
2178
	perror_plus("fork");
2179
	free(direntry);
2180
	continue;
2181
      }
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2182
      int status;
2183
      if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){
2184
	perror_plus("waitpid");
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2185
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2186
	continue;
2187
      }
2188
      if(WIFEXITED(status)){
2189
	if(WEXITSTATUS(status) != 0){
2190
	  fprintf_plus(stderr, "Warning: network hook \"%s\" exited"
2191
		       " with status %d\n", direntry->d_name,
2192
		       WEXITSTATUS(status));
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2193
	  free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2194
	  continue;
2195
	}
2196
      } else if(WIFSIGNALED(status)){
2197
	fprintf_plus(stderr, "Warning: network hook \"%s\" died by"
2198
		     " signal %d\n", direntry->d_name,
2199
		     WTERMSIG(status));
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2200
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2201
	continue;
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2202
      } else {
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2203
	fprintf_plus(stderr, "Warning: network hook \"%s\""
2204
		     " crashed\n", direntry->d_name);
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2205
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2206
	continue;
2207
      }
2208
    }
2209
    if(debug){
2210
      fprintf_plus(stderr, "Network hook \"%s\" ran successfully\n",
2211
		   direntry->d_name);
2212
    }
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2213
    free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2214
  }
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2215
  free(direntries);
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2216
  if(close(hookdir_fd) == -1){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2217
    perror_plus("close");
2218
  } else {
2219
    hookdir_fd = -1;
2220
  }
2221
  close(devnull);
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2222
}
2223
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2224
__attribute__((nonnull, warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2225
int bring_up_interface(const char *const interface,
2226
		       const float delay){
2227
  int old_errno = errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2228
  int ret;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2229
  struct ifreq network;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2230
  unsigned int if_index = if_nametoindex(interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2231
  if(if_index == 0){
2232
    fprintf_plus(stderr, "No such interface: \"%s\"\n", interface);
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2233
    errno = old_errno;
2234
    return ENXIO;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2235
  }
2236
  
2237
  if(quit_now){
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2238
    errno = old_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2239
    return EINTR;
2240
  }
2241
  
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2242
  if(not interface_is_up(interface)){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2243
    int ret_errno = 0;
2244
    int ioctl_errno = 0;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2245
    if(not get_flags(interface, &network)){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2246
      ret_errno = errno;
2247
      fprintf_plus(stderr, "Failed to get flags for interface "
2248
		   "\"%s\"\n", interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2249
      errno = old_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2250
      return ret_errno;
2251
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2252
    network.ifr_flags |= IFF_UP; /* set flag */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2253
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2254
    int sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
2255
    if(sd == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2256
      ret_errno = errno;
2257
      perror_plus("socket");
2258
      errno = old_errno;
2259
      return ret_errno;
2260
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2261
    
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2262
    if(quit_now){
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2263
      ret = close(sd);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2264
      if(ret == -1){
2265
	perror_plus("close");
2266
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2267
      errno = old_errno;
2268
      return EINTR;
2269
    }
2270
    
2271
    if(debug){
2272
      fprintf_plus(stderr, "Bringing up interface \"%s\"\n",
2273
		   interface);
2274
    }
2275
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2276
    /* Raise privileges */
2277
    ret_errno = raise_privileges();
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2278
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2279
      errno = ret_errno;
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2280
      perror_plus("Failed to raise privileges");
2281
    }
2282
    
2283
#ifdef __linux__
2284
    int ret_linux;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2285
    bool restore_loglevel = false;
2286
    if(ret_errno == 0){
2287
      /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
2288
	 messages about the network interface to mess up the prompt */
2289
      ret_linux = klogctl(8, NULL, 5);
2290
      if(ret_linux == -1){
2291
	perror_plus("klogctl");
2292
      } else {
2293
	restore_loglevel = true;
2294
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2295
    }
2296
#endif	/* __linux__ */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2297
    int ret_setflags = ioctl(sd, SIOCSIFFLAGS, &network);
2298
    ioctl_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2299
#ifdef __linux__
2300
    if(restore_loglevel){
2301
      ret_linux = klogctl(7, NULL, 0);
2302
      if(ret_linux == -1){
2303
	perror_plus("klogctl");
2304
      }
2305
    }
2306
#endif	/* __linux__ */
2307
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2308
    /* If raise_privileges() succeeded above */
2309
    if(ret_errno == 0){
2310
      /* Lower privileges */
2311
      ret_errno = lower_privileges();
2312
      if(ret_errno != 0){
2313
	errno = ret_errno;
2314
	perror_plus("Failed to lower privileges");
2315
      }
2316
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2317
    
2318
    /* Close the socket */
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2319
    ret = close(sd);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2320
    if(ret == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2321
      perror_plus("close");
2322
    }
2323
    
2324
    if(ret_setflags == -1){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2325
      errno = ioctl_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2326
      perror_plus("ioctl SIOCSIFFLAGS +IFF_UP");
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2327
      errno = old_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2328
      return ioctl_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2329
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2330
  } else if(debug){
2331
    fprintf_plus(stderr, "Interface \"%s\" is already up; good\n",
2332
		 interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2333
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2334
  
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2335
  /* Sleep checking until interface is running.
2336
     Check every 0.25s, up to total time of delay */
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
2337
  for(int i = 0; i < delay * 4; i++){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2338
    if(interface_is_running(interface)){
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2339
      break;
2340
    }
2341
    struct timespec sleeptime = { .tv_nsec = 250000000 };
2342
    ret = nanosleep(&sleeptime, NULL);
2343
    if(ret == -1 and errno != EINTR){
2344
      perror_plus("nanosleep");
2345
    }
2346
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2347
  
2348
  errno = old_errno;
2349
  return 0;
2350
}
2351
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2352
__attribute__((nonnull, warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2353
int take_down_interface(const char *const interface){
2354
  int old_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2355
  struct ifreq network;
2356
  unsigned int if_index = if_nametoindex(interface);
2357
  if(if_index == 0){
2358
    fprintf_plus(stderr, "No such interface: \"%s\"\n", interface);
2359
    errno = old_errno;
2360
    return ENXIO;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2361
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2362
  if(interface_is_up(interface)){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2363
    int ret_errno = 0;
2364
    int ioctl_errno = 0;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2365
    if(not get_flags(interface, &network) and debug){
2366
      ret_errno = errno;
2367
      fprintf_plus(stderr, "Failed to get flags for interface "
2368
		   "\"%s\"\n", interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2369
      errno = old_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2370
      return ret_errno;
2371
    }
2372
    network.ifr_flags &= ~(short)IFF_UP; /* clear flag */
2373
    
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2374
    int sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2375
    if(sd == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2376
      ret_errno = errno;
2377
      perror_plus("socket");
2378
      errno = old_errno;
2379
      return ret_errno;
2380
    }
2381
    
2382
    if(debug){
2383
      fprintf_plus(stderr, "Taking down interface \"%s\"\n",
2384
		   interface);
2385
    }
2386
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2387
    /* Raise privileges */
2388
    ret_errno = raise_privileges();
2389
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2390
      errno = ret_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2391
      perror_plus("Failed to raise privileges");
2392
    }
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2393
    
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2394
    int ret_setflags = ioctl(sd, SIOCSIFFLAGS, &network);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2395
    ioctl_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2396
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2397
    /* If raise_privileges() succeeded above */
2398
    if(ret_errno == 0){
2399
      /* Lower privileges */
2400
      ret_errno = lower_privileges();
2401
      if(ret_errno != 0){
2402
	errno = ret_errno;
2403
	perror_plus("Failed to lower privileges");
2404
      }
2405
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2406
    
2407
    /* Close the socket */
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2408
    int ret = close(sd);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2409
    if(ret == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2410
      perror_plus("close");
2411
    }
2412
    
2413
    if(ret_setflags == -1){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2414
      errno = ioctl_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2415
      perror_plus("ioctl SIOCSIFFLAGS -IFF_UP");
2416
      errno = old_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2417
      return ioctl_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2418
    }
2419
  } else if(debug){
2420
    fprintf_plus(stderr, "Interface \"%s\" is already down; odd\n",
2421
		 interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2422
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2423
  
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2424
  errno = old_errno;
2425
  return 0;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2426
}
2427
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
2428
int main(int argc, char *argv[]){
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
2429
  mandos_context mc = { .server = NULL, .dh_bits = 0,
237.7.325 by Teddy Hogeborn
Bug fix for GnuTLS 3: be compatible with old 2048-bit DSA keys.
2430
			.priority = "SECURE256:!CTYPE-X.509"
2431
			":+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256",
2432
			.current_server = NULL, .interfaces = NULL,
2433
			.interfaces_size = 0 };
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2434
  AvahiSServiceBrowser *sb = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2435
  error_t ret_errno;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2436
  int ret;
2437
  intmax_t tmpmax;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2438
  char *tmp;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2439
  int exitcode = EXIT_SUCCESS;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2440
  char *interfaces_to_take_down = NULL;
2441
  size_t interfaces_to_take_down_size = 0;
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2442
  char run_tempdir[] = "/run/tmp/mandosXXXXXX";
2443
  char old_tempdir[] = "/tmp/mandosXXXXXX";
2444
  char *tempdir = NULL;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2445
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2446
  const char *seckey = PATHDIR "/" SECKEY;
2447
  const char *pubkey = PATHDIR "/" PUBKEY;
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2448
  const char *dh_params_file = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2449
  char *interfaces_hooks = NULL;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2450
  
2451
  bool gnutls_initialized = false;
2452
  bool gpgme_initialized = false;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2453
  float delay = 2.5f;
237.7.33 by Teddy Hogeborn
Merge from Björn.
2454
  double retry_interval = 10; /* 10s between trying a server and
2455
				 retrying the same server again */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2456
  
237.2.132 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
2457
  struct sigaction old_sigterm_action = { .sa_handler = SIG_DFL };
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
2458
  struct sigaction sigterm_action = { .sa_handler = handle_sigterm };
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2459
  
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2460
  uid = getuid();
2461
  gid = getgid();
2462
  
2463
  /* Lower any group privileges we might have, just to be safe */
2464
  errno = 0;
2465
  ret = setgid(gid);
2466
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2467
    perror_plus("setgid");
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2468
  }
2469
  
2470
  /* Lower user privileges (temporarily) */
2471
  errno = 0;
2472
  ret = seteuid(uid);
2473
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2474
    perror_plus("seteuid");
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2475
  }
2476
  
2477
  if(quit_now){
2478
    goto end;
2479
  }
2480
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2481
  {
2482
    struct argp_option options[] = {
2483
      { .name = "debug", .key = 128,
2484
	.doc = "Debug mode", .group = 3 },
2485
      { .name = "connect", .key = 'c',
2486
	.arg = "ADDRESS:PORT",
2487
	.doc = "Connect directly to a specific Mandos server",
2488
	.group = 1 },
2489
      { .name = "interface", .key = 'i',
2490
	.arg = "NAME",
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2491
	.doc = "Network interface that will be used to search for"
2492
	" Mandos servers",
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2493
	.group = 1 },
2494
      { .name = "seckey", .key = 's',
2495
	.arg = "FILE",
2496
	.doc = "OpenPGP secret key file base name",
2497
	.group = 1 },
2498
      { .name = "pubkey", .key = 'p',
2499
	.arg = "FILE",
2500
	.doc = "OpenPGP public key file base name",
2501
	.group = 2 },
2502
      { .name = "dh-bits", .key = 129,
2503
	.arg = "BITS",
2504
	.doc = "Bit length of the prime number used in the"
2505
	" Diffie-Hellman key exchange",
2506
	.group = 2 },
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2507
      { .name = "dh-params", .key = 134,
2508
	.arg = "FILE",
2509
	.doc = "PEM-encoded PKCS#3 file with pre-generated parameters"
2510
	" for the Diffie-Hellman key exchange",
2511
	.group = 2 },
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2512
      { .name = "priority", .key = 130,
2513
	.arg = "STRING",
2514
	.doc = "GnuTLS priority string for the TLS handshake",
2515
	.group = 1 },
2516
      { .name = "delay", .key = 131,
2517
	.arg = "SECONDS",
2518
	.doc = "Maximum delay to wait for interface startup",
2519
	.group = 2 },
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2520
      { .name = "retry", .key = 132,
2521
	.arg = "SECONDS",
237.17.1 by teddy at recompile
Add wireless network hook
2522
	.doc = "Retry interval used when denied by the Mandos server",
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2523
	.group = 2 },
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
2524
      { .name = "network-hook-dir", .key = 133,
2525
	.arg = "DIR",
2526
	.doc = "Directory where network hooks are located",
2527
	.group = 2 },
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2528
      /*
2529
       * These reproduce what we would get without ARGP_NO_HELP
2530
       */
2531
      { .name = "help", .key = '?',
2532
	.doc = "Give this help list", .group = -1 },
2533
      { .name = "usage", .key = -3,
2534
	.doc = "Give a short usage message", .group = -1 },
2535
      { .name = "version", .key = 'V',
2536
	.doc = "Print program version", .group = -1 },
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2537
      { .name = NULL }
2538
    };
2539
    
2540
    error_t parse_opt(int key, char *arg,
2541
		      struct argp_state *state){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2542
      errno = 0;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2543
      switch(key){
2544
      case 128:			/* --debug */
2545
	debug = true;
2546
	break;
2547
      case 'c':			/* --connect */
2548
	connect_to = arg;
2549
	break;
2550
      case 'i':			/* --interface */
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2551
	ret_errno = argz_add_sep(&mc.interfaces, &mc.interfaces_size,
2552
				 arg, (int)',');
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2553
	if(ret_errno != 0){
2554
	  argp_error(state, "%s", strerror(ret_errno));
2555
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2556
	break;
2557
      case 's':			/* --seckey */
2558
	seckey = arg;
2559
	break;
2560
      case 'p':			/* --pubkey */
2561
	pubkey = arg;
2562
	break;
2563
      case 129:			/* --dh-bits */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2564
	errno = 0;
2565
	tmpmax = strtoimax(arg, &tmp, 10);
2566
	if(errno != 0 or tmp == arg or *tmp != '\0'
2567
	   or tmpmax != (typeof(mc.dh_bits))tmpmax){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2568
	  argp_error(state, "Bad number of DH bits");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2569
	}
2570
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
2571
	break;
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2572
      case 134:			/* --dh-params */
2573
	dh_params_file = arg;
2574
	break;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2575
      case 130:			/* --priority */
2576
	mc.priority = arg;
2577
	break;
2578
      case 131:			/* --delay */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2579
	errno = 0;
2580
	delay = strtof(arg, &tmp);
2581
	if(errno != 0 or tmp == arg or *tmp != '\0'){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2582
	  argp_error(state, "Bad delay");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2583
	}
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2584
      case 132:			/* --retry */
2585
	errno = 0;
2586
	retry_interval = strtod(arg, &tmp);
2587
	if(errno != 0 or tmp == arg or *tmp != '\0'
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2588
	   or (retry_interval * 1000) > INT_MAX
2589
	   or retry_interval < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2590
	  argp_error(state, "Bad retry interval");
2591
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2592
	break;
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
2593
      case 133:			/* --network-hook-dir */
2594
	hookdir = arg;
2595
	break;
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2596
	/*
2597
	 * These reproduce what we would get without ARGP_NO_HELP
2598
	 */
2599
      case '?':			/* --help */
2600
	argp_state_help(state, state->out_stream,
2601
			(ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2602
			& ~(unsigned int)ARGP_HELP_EXIT_OK);
2603
      case -3:			/* --usage */
2604
	argp_state_help(state, state->out_stream,
2605
			ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2606
      case 'V':			/* --version */
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2607
	fprintf_plus(state->out_stream, "%s\n", argp_program_version);
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2608
	exit(argp_err_exit_status);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2609
	break;
2610
      default:
2611
	return ARGP_ERR_UNKNOWN;
2612
      }
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2613
      return errno;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2614
    }
2615
    
2616
    struct argp argp = { .options = options, .parser = parse_opt,
2617
			 .args_doc = "",
2618
			 .doc = "Mandos client -- Get and decrypt"
2619
			 " passwords from a Mandos server" };
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2620
    ret_errno = argp_parse(&argp, argc, argv,
2621
			   ARGP_IN_ORDER | ARGP_NO_HELP, 0, NULL);
2622
    switch(ret_errno){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2623
    case 0:
2624
      break;
2625
    case ENOMEM:
2626
    default:
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2627
      errno = ret_errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2628
      perror_plus("argp_parse");
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2629
      exitcode = EX_OSERR;
2630
      goto end;
2631
    case EINVAL:
2632
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2633
      goto end;
2634
    }
2635
  }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2636
  
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2637
  {
237.7.35 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
2638
    /* Work around Debian bug #633582:
237.7.416 by Teddy Hogeborn
Change all http:// URLs to https:// wherever possible.
2639
       <https://bugs.debian.org/633582> */
237.7.35 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
2640
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2641
    /* Re-raise privileges */
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2642
    ret = raise_privileges();
2643
    if(ret != 0){
2644
      errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2645
      perror_plus("Failed to raise privileges");
2646
    } else {
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2647
      struct stat st;
2648
      
2649
      if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
2650
	int seckey_fd = open(seckey, O_RDONLY);
2651
	if(seckey_fd == -1){
2652
	  perror_plus("open");
2653
	} else {
2654
	  ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
2655
	  if(ret == -1){
2656
	    perror_plus("fstat");
2657
	  } else {
2658
	    if(S_ISREG(st.st_mode)
2659
	       and st.st_uid == 0 and st.st_gid == 0){
2660
	      ret = fchown(seckey_fd, uid, gid);
2661
	      if(ret == -1){
2662
		perror_plus("fchown");
2663
	      }
2664
	    }
2665
	  }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2666
	  close(seckey_fd);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2667
	}
2668
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2669
      
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2670
      if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
2671
	int pubkey_fd = open(pubkey, O_RDONLY);
2672
	if(pubkey_fd == -1){
2673
	  perror_plus("open");
2674
	} else {
2675
	  ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
2676
	  if(ret == -1){
2677
	    perror_plus("fstat");
2678
	  } else {
2679
	    if(S_ISREG(st.st_mode)
2680
	       and st.st_uid == 0 and st.st_gid == 0){
2681
	      ret = fchown(pubkey_fd, uid, gid);
2682
	      if(ret == -1){
2683
		perror_plus("fchown");
2684
	      }
2685
	    }
2686
	  }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2687
	  close(pubkey_fd);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2688
	}
2689
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2690
      
237.7.324 by Teddy Hogeborn
mandos-client: Bug fix: don't crash if --dh-params was not used.
2691
      if(dh_params_file != NULL
2692
	 and strcmp(dh_params_file, PATHDIR "/dhparams.pem" ) == 0){
237.7.313 by Teddy Hogeborn
Install client Diffie-Hellman parameters into initramfs.
2693
	int dhparams_fd = open(dh_params_file, O_RDONLY);
2694
	if(dhparams_fd == -1){
2695
	  perror_plus("open");
2696
	} else {
2697
	  ret = (int)TEMP_FAILURE_RETRY(fstat(dhparams_fd, &st));
2698
	  if(ret == -1){
2699
	    perror_plus("fstat");
2700
	  } else {
2701
	    if(S_ISREG(st.st_mode)
2702
	       and st.st_uid == 0 and st.st_gid == 0){
2703
	      ret = fchown(dhparams_fd, uid, gid);
2704
	      if(ret == -1){
2705
		perror_plus("fchown");
2706
	      }
2707
	    }
2708
	  }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2709
	  close(dhparams_fd);
237.7.313 by Teddy Hogeborn
Install client Diffie-Hellman parameters into initramfs.
2710
	}
2711
      }
2712
      
237.16.11 by Teddy Hogeborn
* Makefile (run-client): Add "--network-hook-dir" option.
2713
      /* Lower privileges */
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2714
      ret = lower_privileges();
2715
      if(ret != 0){
2716
	errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2717
	perror_plus("Failed to lower privileges");
2718
      }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2719
    }
2720
  }
2721
  
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2722
  /* Remove invalid interface names (except "none") */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2723
  {
2724
    char *interface = NULL;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2725
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2726
				 interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2727
      if(strcmp(interface, "none") != 0
2728
	 and if_nametoindex(interface) == 0){
2729
	if(interface[0] != '\0'){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2730
	  fprintf_plus(stderr, "Not using nonexisting interface"
2731
		       " \"%s\"\n", interface);
2732
	}
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2733
	argz_delete(&mc.interfaces, &mc.interfaces_size, interface);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2734
	interface = NULL;
2735
      }
2736
    }
2737
  }
2738
  
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2739
  /* Run network hooks */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2740
  {
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2741
    if(mc.interfaces != NULL){
2742
      interfaces_hooks = malloc(mc.interfaces_size);
237.7.147 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Set DEVICE environment
2743
      if(interfaces_hooks == NULL){
2744
	perror_plus("malloc");
2745
	goto end;
2746
      }
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2747
      memcpy(interfaces_hooks, mc.interfaces, mc.interfaces_size);
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2748
      argz_stringify(interfaces_hooks, mc.interfaces_size, (int)',');
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2749
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2750
    run_network_hooks("start", interfaces_hooks != NULL ?
2751
		      interfaces_hooks : "", delay);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2752
  }
2753
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2754
  if(not debug){
2755
    avahi_set_log_function(empty_log);
2756
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2757
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2758
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
2759
     from the signal handler */
2760
  /* Initialize the pseudo-RNG for Avahi */
2761
  srand((unsigned int) time(NULL));
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
2762
  simple_poll = avahi_simple_poll_new();
2763
  if(simple_poll == NULL){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2764
    fprintf_plus(stderr,
2765
		 "Avahi: Failed to create simple poll object.\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2766
    exitcode = EX_UNAVAILABLE;
24.1.135 by Björn Påhlsson
Earlier signal handling
2767
    goto end;
2768
  }
237.2.72 by Teddy Hogeborn
Merge from Björn:
2769
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2770
  sigemptyset(&sigterm_action.sa_mask);
237.2.72 by Teddy Hogeborn
Merge from Björn:
2771
  ret = sigaddset(&sigterm_action.sa_mask, SIGINT);
2772
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2773
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2774
    exitcode = EX_OSERR;
237.2.72 by Teddy Hogeborn
Merge from Björn:
2775
    goto end;
2776
  }
2777
  ret = sigaddset(&sigterm_action.sa_mask, SIGHUP);
2778
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2779
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2780
    exitcode = EX_OSERR;
237.2.72 by Teddy Hogeborn
Merge from Björn:
2781
    goto end;
2782
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
2783
  ret = sigaddset(&sigterm_action.sa_mask, SIGTERM);
2784
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2785
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2786
    exitcode = EX_OSERR;
24.1.135 by Björn Påhlsson
Earlier signal handling
2787
    goto end;
2788
  }
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2789
  /* Need to check if the handler is SIG_IGN before handling:
2790
     | [[info:libc:Initial Signal Actions]] |
2791
     | [[info:libc:Basic Signal Handling]]  |
2792
  */
2793
  ret = sigaction(SIGINT, NULL, &old_sigterm_action);
2794
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2795
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2796
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2797
  }
2798
  if(old_sigterm_action.sa_handler != SIG_IGN){
2799
    ret = sigaction(SIGINT, &sigterm_action, NULL);
2800
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2801
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2802
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2803
      goto end;
2804
    }
2805
  }
2806
  ret = sigaction(SIGHUP, NULL, &old_sigterm_action);
2807
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2808
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2809
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2810
  }
2811
  if(old_sigterm_action.sa_handler != SIG_IGN){
2812
    ret = sigaction(SIGHUP, &sigterm_action, NULL);
2813
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2814
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2815
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2816
      goto end;
2817
    }
2818
  }
2819
  ret = sigaction(SIGTERM, NULL, &old_sigterm_action);
2820
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2821
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2822
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2823
  }
2824
  if(old_sigterm_action.sa_handler != SIG_IGN){
2825
    ret = sigaction(SIGTERM, &sigterm_action, NULL);
2826
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2827
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2828
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2829
      goto end;
2830
    }
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2831
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2832
  
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2833
  /* If no interfaces were specified, make a list */
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2834
  if(mc.interfaces == NULL){
237.7.247 by Teddy Hogeborn
Fix free() of possibly uninitialized pointer in mandos-client.
2835
    struct dirent **direntries = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2836
    /* Look for any good interfaces */
2837
    ret = scandir(sys_class_net, &direntries, good_interface,
2838
		  alphasort);
2839
    if(ret >= 1){
2840
      /* Add all found interfaces to interfaces list */
2841
      for(int i = 0; i < ret; ++i){
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2842
	ret_errno = argz_add(&mc.interfaces, &mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2843
			     direntries[i]->d_name);
2844
	if(ret_errno != 0){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2845
	  errno = ret_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2846
	  perror_plus("argz_add");
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2847
	  free(direntries[i]);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2848
	  continue;
2849
	}
2850
	if(debug){
2851
	  fprintf_plus(stderr, "Will use interface \"%s\"\n",
2852
		       direntries[i]->d_name);
2853
	}
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2854
	free(direntries[i]);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2855
      }
2856
      free(direntries);
2857
    } else {
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2858
      if(ret == 0){
2859
	free(direntries);
2860
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2861
      fprintf_plus(stderr, "Could not find a network interface\n");
2862
      exitcode = EXIT_FAILURE;
2863
      goto end;
2864
    }
2865
  }
2866
  
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
2867
  /* Bring up interfaces which are down, and remove any "none"s */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2868
  {
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2869
    char *interface = NULL;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2870
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2871
				 interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2872
      /* If interface name is "none", stop bringing up interfaces.
2873
	 Also remove all instances of "none" from the list */
2874
      if(strcmp(interface, "none") == 0){
2875
	argz_delete(&mc.interfaces, &mc.interfaces_size,
2876
		    interface);
2877
	interface = NULL;
2878
	while((interface = argz_next(mc.interfaces,
2879
				     mc.interfaces_size, interface))){
2880
	  if(strcmp(interface, "none") == 0){
2881
	    argz_delete(&mc.interfaces, &mc.interfaces_size,
2882
			interface);
2883
	    interface = NULL;
2884
	  }
2885
	}
2886
	break;
2887
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2888
      bool interface_was_up = interface_is_up(interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2889
      errno = bring_up_interface(interface, delay);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2890
      if(not interface_was_up){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2891
	if(errno != 0){
237.7.315 by Teddy Hogeborn
plugins.d/mandos-client.c (main): See why it failed to bring up interface.
2892
	  fprintf_plus(stderr, "Failed to bring up interface \"%s\":"
2893
		       " %s\n", interface, strerror(errno));
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2894
	} else {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2895
	  errno = argz_add(&interfaces_to_take_down,
2896
			   &interfaces_to_take_down_size,
2897
			   interface);
2898
	  if(errno != 0){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2899
	    perror_plus("argz_add");
2900
	  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2901
	}
2902
      }
2903
    }
2904
    if(debug and (interfaces_to_take_down == NULL)){
2905
      fprintf_plus(stderr, "No interfaces were brought up\n");
237.2.128 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2906
    }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2907
  }
2908
  
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2909
  /* If we only got one interface, explicitly use only that one */
2910
  if(argz_count(mc.interfaces, mc.interfaces_size) == 1){
2911
    if(debug){
2912
      fprintf_plus(stderr, "Using only interface \"%s\"\n",
2913
		   mc.interfaces);
2914
    }
2915
    if_index = (AvahiIfIndex)if_nametoindex(mc.interfaces);
2916
  }
2917
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2918
  if(quit_now){
2919
    goto end;
2920
  }
2921
  
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2922
  ret = init_gnutls_global(pubkey, seckey, dh_params_file, &mc);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2923
  if(ret == -1){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2924
    fprintf_plus(stderr, "init_gnutls_global failed\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2925
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2926
    goto end;
2927
  } else {
2928
    gnutls_initialized = true;
2929
  }
2930
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2931
  if(quit_now){
2932
    goto end;
2933
  }
2934
  
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2935
  /* Try /run/tmp before /tmp */
2936
  tempdir = mkdtemp(run_tempdir);
2937
  if(tempdir == NULL and errno == ENOENT){
2938
      if(debug){
2939
	fprintf_plus(stderr, "Tempdir %s did not work, trying %s\n",
2940
		     run_tempdir, old_tempdir);
2941
      }
2942
      tempdir = mkdtemp(old_tempdir);
2943
  }
2944
  if(tempdir == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2945
    perror_plus("mkdtemp");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2946
    goto end;
2947
  }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2948
  
2949
  if(quit_now){
2950
    goto end;
2951
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2952
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2953
  if(not init_gpgme(pubkey, seckey, tempdir, &mc)){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2954
    fprintf_plus(stderr, "init_gpgme failed\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2955
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2956
    goto end;
2957
  } else {
2958
    gpgme_initialized = true;
2959
  }
2960
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2961
  if(quit_now){
2962
    goto end;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2963
  }
2964
  
2965
  if(connect_to != NULL){
2966
    /* Connect directly, do not use Zeroconf */
2967
    /* (Mainly meant for debugging) */
2968
    char *address = strrchr(connect_to, ':');
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2969
    
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2970
    if(address == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2971
      fprintf_plus(stderr, "No colon in address\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2972
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2973
      goto end;
2974
    }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2975
    
2976
    if(quit_now){
2977
      goto end;
2978
    }
2979
    
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2980
    in_port_t port;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2981
    errno = 0;
2982
    tmpmax = strtoimax(address+1, &tmp, 10);
2983
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2984
       or tmpmax != (in_port_t)tmpmax){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2985
      fprintf_plus(stderr, "Bad port number\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2986
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2987
      goto end;
2988
    }
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2989
    
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2990
    if(quit_now){
2991
      goto end;
2992
    }
2993
    
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2994
    port = (in_port_t)tmpmax;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2995
    *address = '\0';
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2996
    /* Colon in address indicates IPv6 */
2997
    int af;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2998
    if(strchr(connect_to, ':') != NULL){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2999
      af = AF_INET6;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
3000
      /* Accept [] around IPv6 address - see RFC 5952 */
3001
      if(connect_to[0] == '[' and address[-1] == ']')
3002
	{
3003
	  connect_to++;
3004
	  address[-1] = '\0';
3005
	}
237.2.67 by Teddy Hogeborn
Four new interrelated features:
3006
    } else {
3007
      af = AF_INET;
3008
    }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
3009
    address = connect_to;
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
3010
    
3011
    if(quit_now){
3012
      goto end;
3013
    }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
3014
    
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
3015
    while(not quit_now){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
3016
      ret = start_mandos_communication(address, port, if_index, af,
3017
				       &mc);
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
3018
      if(quit_now or ret == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
3019
	break;
3020
      }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
3021
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
3022
	fprintf_plus(stderr, "Retrying in %d seconds\n",
3023
		     (int)retry_interval);
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
3024
      }
237.7.168 by Teddy Hogeborn
* plugin-runner.c (main): Bug fix; do not ignore return value of
3025
      sleep((unsigned int)retry_interval);
237.7.40 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
3026
    }
3027
    
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
3028
    if(not quit_now){
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3029
      exitcode = EXIT_SUCCESS;
3030
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
3031
    
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3032
    goto end;
3033
  }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
3034
  
3035
  if(quit_now){
3036
    goto end;
3037
  }
3038
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3039
  {
3040
    AvahiServerConfig config;
3041
    /* Do not publish any local Zeroconf records */
3042
    avahi_server_config_init(&config);
3043
    config.publish_hinfo = 0;
3044
    config.publish_addresses = 0;
3045
    config.publish_workstation = 0;
3046
    config.publish_domain = 0;
3047
    
3048
    /* Allocate a new server */
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
3049
    mc.server = avahi_server_new(avahi_simple_poll_get(simple_poll),
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3050
				 &config, NULL, NULL, &ret);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3051
    
3052
    /* Free the Avahi configuration data */
3053
    avahi_server_config_free(&config);
3054
  }
3055
  
3056
  /* Check if creating the Avahi server object succeeded */
3057
  if(mc.server == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3058
    fprintf_plus(stderr, "Failed to create Avahi server: %s\n",
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3059
		 avahi_strerror(ret));
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
3060
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3061
    goto end;
3062
  }
3063
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
3064
  if(quit_now){
3065
    goto end;
3066
  }
3067
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3068
  /* Create the Avahi service browser */
3069
  sb = avahi_s_service_browser_new(mc.server, if_index,
237.2.76 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
3070
				   AVAHI_PROTO_UNSPEC, "_mandos._tcp",
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
3071
				   NULL, 0, browse_callback,
3072
				   (void *)&mc);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3073
  if(sb == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3074
    fprintf_plus(stderr, "Failed to create service browser: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
3075
		 avahi_strerror(avahi_server_errno(mc.server)));
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
3076
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3077
    goto end;
3078
  }
237.2.70 by Teddy Hogeborn
Merge from Björn:
3079
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
3080
  if(quit_now){
3081
    goto end;
3082
  }
3083
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3084
  /* Run the main loop */
3085
  
3086
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3087
    fprintf_plus(stderr, "Starting Avahi loop search\n");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3088
  }
237.7.235 by Teddy Hogeborn
White space fix only.
3089
  
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
3090
  ret = avahi_loop_with_timeout(simple_poll,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
3091
				(int)(retry_interval * 1000), &mc);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3092
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3093
    fprintf_plus(stderr, "avahi_loop_with_timeout exited %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
3094
		 (ret == 0) ? "successfully" : "with error");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3095
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3096
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
3097
 end:
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3098
  
3099
  if(debug){
237.7.418 by Teddy Hogeborn
Show what signal, if any, made mandos-client exit.
3100
    if(signal_received){
3101
      fprintf_plus(stderr, "%s exiting due to signal %d: %s\n",
3102
		   argv[0], signal_received,
3103
		   strsignal(signal_received));
3104
    } else {
3105
      fprintf_plus(stderr, "%s exiting\n", argv[0]);
3106
    }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3107
  }
3108
  
3109
  /* Cleanup things */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
3110
  free(mc.interfaces);
3111
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3112
  if(sb != NULL)
3113
    avahi_s_service_browser_free(sb);
3114
  
3115
  if(mc.server != NULL)
3116
    avahi_server_free(mc.server);
3117
  
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
3118
  if(simple_poll != NULL)
3119
    avahi_simple_poll_free(simple_poll);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3120
  
3121
  if(gnutls_initialized){
3122
    gnutls_certificate_free_credentials(mc.cred);
3123
    gnutls_dh_params_deinit(mc.dh_params);
3124
  }
3125
  
3126
  if(gpgme_initialized){
3127
    gpgme_release(mc.ctx);
3128
  }
237.16.12 by Teddy Hogeborn
* plugins.d/mandos-client.c (runnable_hook): Add debug output.
3129
  
237.7.33 by Teddy Hogeborn
Merge from Björn.
3130
  /* Cleans up the circular linked list of Mandos servers the client
3131
     has seen */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3132
  if(mc.current_server != NULL){
3133
    mc.current_server->prev->next = NULL;
3134
    while(mc.current_server != NULL){
3135
      server *next = mc.current_server->next;
237.7.262 by Teddy Hogeborn
mandos-client: Fix mem free bug.
3136
#ifdef __GNUC__
3137
#pragma GCC diagnostic push
3138
#pragma GCC diagnostic ignored "-Wcast-qual"
3139
#endif
3140
      free((char *)(mc.current_server->ip));
3141
#ifdef __GNUC__
3142
#pragma GCC diagnostic pop
3143
#endif
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3144
      free(mc.current_server);
3145
      mc.current_server = next;
3146
    }
3147
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3148
  
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3149
  /* Re-raise privileges */
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
3150
  {
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3151
    ret = raise_privileges();
3152
    if(ret != 0){
3153
      errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3154
      perror_plus("Failed to raise privileges");
3155
    } else {
3156
      
3157
      /* Run network hooks */
3158
      run_network_hooks("stop", interfaces_hooks != NULL ?
3159
			interfaces_hooks : "", delay);
3160
      
3161
      /* Take down the network interfaces which were brought up */
3162
      {
3163
	char *interface = NULL;
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
3164
	while((interface = argz_next(interfaces_to_take_down,
3165
				     interfaces_to_take_down_size,
3166
				     interface))){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3167
	  ret = take_down_interface(interface);
3168
	  if(ret != 0){
3169
	    errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3170
	    perror_plus("Failed to take down interface");
3171
	  }
3172
	}
3173
	if(debug and (interfaces_to_take_down == NULL)){
3174
	  fprintf_plus(stderr, "No interfaces needed to be taken"
3175
		       " down\n");
3176
	}
3177
      }
3178
    }
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
3179
    
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3180
    ret = lower_privileges_permanently();
3181
    if(ret != 0){
3182
      errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3183
      perror_plus("Failed to lower privileges permanently");
3184
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
3185
  }
3186
  
3187
  free(interfaces_to_take_down);
3188
  free(interfaces_hooks);
237.2.113 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
3189
  
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3190
  void clean_dir_at(int base, const char * const dirname,
3191
		    uintmax_t level){
3192
    struct dirent **direntries = NULL;
3193
    int dret;
3194
    int dir_fd = (int)TEMP_FAILURE_RETRY(openat(base, dirname,
3195
						O_RDONLY
3196
						| O_NOFOLLOW
3197
						| O_DIRECTORY
3198
						| O_PATH));
3199
    if(dir_fd == -1){
3200
      perror_plus("open");
237.7.484 by Teddy Hogeborn
Client: Bug fix: Don't try to clean directory which fails to open
3201
      return;
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3202
    }
3203
    int numentries = scandirat(dir_fd, ".", &direntries,
3204
			       notdotentries, alphasort);
3205
    if(numentries >= 0){
3206
      for(int i = 0; i < numentries; i++){
3207
	if(debug){
3208
	  fprintf_plus(stderr, "Unlinking \"%s/%s\"\n",
3209
		       dirname, direntries[i]->d_name);
3210
	}
3211
	dret = unlinkat(dir_fd, direntries[i]->d_name, 0);
3212
	if(dret == -1){
3213
	  if(errno == EISDIR){
3214
	      dret = unlinkat(dir_fd, direntries[i]->d_name,
3215
			      AT_REMOVEDIR);
3216
	  }	    
3217
	  if((dret == -1) and (errno == ENOTEMPTY)
3218
	     and (strcmp(direntries[i]->d_name, "private-keys-v1.d")
3219
		  == 0) and (level == 0)){
3220
	    /* Recurse only in this special case */
3221
	    clean_dir_at(dir_fd, direntries[i]->d_name, level+1);
3222
	    dret = 0;
3223
	  }
237.7.482 by Teddy Hogeborn
Client: Don't print failures to remove nonexisting files.
3224
	  if((dret == -1) and (errno != ENOENT)){
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3225
	    fprintf_plus(stderr, "unlink(\"%s/%s\"): %s\n", dirname,
3226
			 direntries[i]->d_name, strerror(errno));
3227
	  }
3228
	}
3229
	free(direntries[i]);
3230
      }
3231
      
3232
      /* need to clean even if 0 because man page doesn't specify */
3233
      free(direntries);
3234
      dret = unlinkat(base, dirname, AT_REMOVEDIR);
3235
      if(dret == -1 and errno != ENOENT){
3236
	perror_plus("rmdir");
3237
      }
3238
    } else {
3239
      perror_plus("scandirat");
3240
    }
3241
    close(dir_fd);
3242
  }
3243
  
24.1.172 by Björn Påhlsson
using scandir instead of readdir
3244
  /* Removes the GPGME temp directory and all files inside */
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
3245
  if(tempdir != NULL){
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3246
    clean_dir_at(-1, tempdir, 0);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3247
  }
3248
  
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3249
  if(quit_now){
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
3250
    sigemptyset(&old_sigterm_action.sa_mask);
3251
    old_sigterm_action.sa_handler = SIG_DFL;
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
3252
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
3253
					    &old_sigterm_action,
3254
					    NULL));
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3255
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3256
      perror_plus("sigaction");
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3257
    }
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
3258
    do {
3259
      ret = raise(signal_received);
3260
    } while(ret != 0 and errno == EINTR);
3261
    if(ret != 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3262
      perror_plus("raise");
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
3263
      abort();
3264
    }
3265
    TEMP_FAILURE_RETRY(pause());
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3266
  }
3267
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3268
  return exitcode;
13 by Björn Påhlsson
Added following support:
3269
}