/mandos/trunk

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