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