/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1
/*  -*- coding: utf-8 -*- */
2
/*
237.2.24 by Teddy Hogeborn
* plugins.d/askpass-fifo.c: Fix name in header.
3
 * Mandos-client - get and decrypt data from a Mandos server
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
4
 *
5
 * This program is partly derived from an example program for an Avahi
6
 * service browser, downloaded from
7
 * <http://avahi.org/browser/examples/core-browse-services.c>.  This
8
 * includes the following functions: "resolve_callback",
9
 * "browse_callback", and parts of "main".
10
 * 
28 by Teddy Hogeborn
* server.conf: New file.
11
 * Everything else is
237.25.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
 * 
237.11.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() */
237.2.80 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
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
35
#endif	/* not _LARGEFILE_SOURCE */
237.2.80 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
237.7.239 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(),
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
43
				   stdout, ferror() */
237.7.136 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 */
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
46
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, srand(),
47
				   strtof(), abort() */
237.2.67 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() */
237.2.67 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,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
54
				   SOCK_STREAM, uid_t, gid_t, open(),
55
				   opendir(), DIR */
237.16.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,
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
58
				   inet_pton(), connect(),
59
				   getnameinfo() */
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
60
#include <fcntl.h>		/* open(), unlinkat() */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
61
#include <dirent.h>		/* opendir(), struct dirent, readdir()
62
				 */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
63
#include <inttypes.h>		/* PRIu16, PRIdMAX, intmax_t,
64
				   strtoimax() */
237.7.33 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 */
237.2.67 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(),
237.2.128 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
75
				   getuid(), getgid(), seteuid(),
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
76
				   setgid(), pause(), _exit(),
77
				   unlinkat() */
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
78
#include <arpa/inet.h>		/* inet_pton(), htons() */
237.2.67 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 */
237.2.70 by Teddy Hogeborn
Merge from Björn:
84
#include <signal.h>		/* sigemptyset(), sigaddset(),
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
85
				   sigaction(), SIGTERM, sig_atomic_t,
86
				   raise() */
237.2.162 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 */
237.16.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() */
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
91
#include <grp.h>		/* setgroups() */
237.22.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() */
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
96
#include <netdb.h>		/* getnameinfo(), NI_NUMERICHOST,
97
				   EAI_SYSTEM, gai_strerror() */
237.2.70 by Teddy Hogeborn
Merge from Björn:
98
237.2.56 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() */
237.2.71 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_* */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
120
#include <gnutls/openpgp.h>
237.16.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"
237.15.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";
237.7.228 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>";
269.1.1 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;
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
144
const char *hookdir = HOOKDIR;
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
145
int hookdir_fd = -1;
237.22.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
237.7.33 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;
237.7.145 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;
237.7.151 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
237.7.149 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
237.2.134 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){
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
181
  int e = errno;
237.7.33 by Teddy Hogeborn
Merge from Björn.
182
  fprintf(stderr, "Mandos plugin %s: ",
183
	  program_invocation_short_name);
237.7.82 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
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
188
__attribute__((format (gnu_printf, 2, 3), nonnull))
237.15.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
  
237.16.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));
237.7.170 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));
237.15.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
/*
237.2.71 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
 */
237.7.220 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,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
205
		 size_t buffer_capacity){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
206
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
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
    }
237.7.214 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
237.7.39 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 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
222
__attribute__((nonnull, warn_unused_result))
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
223
bool add_server(const char *ip, in_port_t port, AvahiIfIndex if_index,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
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");
237.11.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),
237.16.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");
237.7.258 by Teddy Hogeborn
mandos-client: Fix minor memory leak on memory full or clock failure.
237
    free(new_server);
237.11.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
  }
237.7.216 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");
237.7.262 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
237.7.258 by Teddy Hogeborn
mandos-client: Fix minor memory leak on memory full or clock failure.
251
    free(new_server);
237.7.216 by Teddy Hogeborn
Do not add a new server to server list if clock_gettime() fails
252
    return false;
253
  }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
254
  /* Special case of first server */
237.7.150 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;
237.7.150 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 {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
260
    /* Place the new server last in the list */
237.7.150 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;
237.7.150 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
  }
237.11.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
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
272
__attribute__((nonnull, warn_unused_result))
237.7.221 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
  /*
237.2.51 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
   */
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
283
  bool import_key(const char * const filename){
237.2.124 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
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
    
237.3.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);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
295
    if(rc != GPG_ERR_NO_ERROR){
237.15.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",
237.16.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
    
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
301
    rc = gpgme_op_import(mc->ctx, pgp_data);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
302
    if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
303
      fprintf_plus(stderr, "bad gpgme_op_import: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
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
    
237.3.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
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
316
  if(debug){
237.15.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);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
323
  if(rc != GPG_ERR_NO_ERROR){
237.15.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",
237.16.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
  
237.7.40 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 */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
330
  rc = gpgme_get_engine_info(&engine_info);
331
  if(rc != GPG_ERR_NO_ERROR){
237.15.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",
237.16.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){
237.16.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" */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
351
  rc = gpgme_new(&(mc->ctx));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
352
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
353
    fprintf_plus(stderr, "Mandos plugin mandos-client: "
237.16.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
  
237.2.29 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
  
237.2.118 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
 */
237.7.220 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,
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
372
				  size_t crypto_size,
237.7.150 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
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
381
  if(debug){
237.15.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);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
388
  if(rc != GPG_ERR_NO_ERROR){
237.15.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",
237.16.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);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
396
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
397
    fprintf_plus(stderr, "Mandos plugin mandos-client: "
237.16.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 */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
406
  rc = gpgme_op_decrypt(mc->ctx, dh_crypto, dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
407
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
408
    fprintf_plus(stderr, "bad gpgme_op_decrypt: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
409
		 gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
410
    plaintext_length = -1;
237.2.29 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;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
413
      result = gpgme_op_decrypt_result(mc->ctx);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
414
      if(result == NULL){
237.15.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 {
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
417
	fprintf_plus(stderr, "Unsupported algorithm: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
418
		     result->unsupported_algorithm);
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
419
	fprintf_plus(stderr, "Wrong key usage: %u\n",
237.16.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){
237.15.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;
237.2.112 by Teddy Hogeborn
* plugins.d/mandos-client.c (pgp_packet_decrypt): Remove redundant
426
	while(recipient != NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
427
	  fprintf_plus(stderr, "Public key algorithm: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
428
		       gpgme_pubkey_algo_name
429
		       (recipient->pubkey_algo));
237.15.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",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
432
		       recipient->status == GPG_ERR_NO_SECKEY
433
		       ? "No" : "Yes");
237.2.112 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){
237.15.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 */
237.2.29 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,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
455
				   (size_t)plaintext_length,
456
				   plaintext_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
457
    if(plaintext_capacity == 0){
237.16.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 */
237.2.29 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){
237.15.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
237.7.220 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){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
498
  const char *ret = gnutls_strerror(value);
237.2.29 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 */
237.7.220 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){
237.15.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
237.7.220 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,
237.7.150 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){
237.15.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();
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
522
  if(ret != GNUTLS_E_SUCCESS){
237.16.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
  
237.2.29 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 */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
537
  ret = gnutls_certificate_allocate_credentials(&mc->cred);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
538
  if(ret != GNUTLS_E_SUCCESS){
237.16.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));
237.2.29 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){
237.15.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"
237.16.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
237.7.150 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);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
555
  if(ret != GNUTLS_E_SUCCESS){
237.15.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);
237.16.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 */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
565
  ret = gnutls_dh_params_init(&mc->dh_params);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
566
  if(ret != GNUTLS_E_SUCCESS){
237.16.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
  }
237.7.150 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);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
573
  if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
574
    fprintf_plus(stderr, "Error in GnuTLS prime generation: %s\n",
237.16.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
  
237.7.150 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
  
237.7.150 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();
237.7.150 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
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
591
__attribute__((nonnull, warn_unused_result))
237.7.150 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 */
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
596
  do {
597
    ret = gnutls_init(session, GNUTLS_SERVER);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
598
    if(quit_now){
599
      return -1;
600
    }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
601
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
602
  if(ret != GNUTLS_E_SUCCESS){
237.16.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;
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
610
    do {
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
611
      ret = gnutls_priority_set_direct(*session, mc->priority, &err);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
612
      if(quit_now){
613
	gnutls_deinit(*session);
614
	return -1;
615
      }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
616
    } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
617
    if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
618
      fprintf_plus(stderr, "Syntax error at: %s\n", err);
237.16.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));
237.2.29 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
  
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
626
  do {
627
    ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
628
				 mc->cred);
237.2.134 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
    }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
633
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
634
  if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
635
    fprintf_plus(stderr, "Error setting GnuTLS credentials: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
636
		 safer_gnutls_strerror(ret));
237.2.29 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. */
237.2.131 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
  
237.7.150 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
237.25.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
705
/* Helper function to add_local_route() and remove_local_route() */
706
__attribute__((nonnull, warn_unused_result))
707
static bool add_remove_local_route(const bool add,
708
				   const char *address,
709
				   AvahiIfIndex if_index){
710
  int ret;
711
  char helper[] = "mandos-client-iprouteadddel";
712
  char add_arg[] = "add";
713
  char remove_arg[] = "remove";
714
  char *pluginhelperdir = getenv("MANDOSPLUGINHELPERDIR");
715
  if(pluginhelperdir == NULL){
716
    if(debug){
717
      fprintf_plus(stderr, "MANDOSPLUGINHELPERDIR environment"
718
		   " variable not set; cannot run helper\n");
719
    }
720
    return false;
721
  }
722
  
723
  char interface[IF_NAMESIZE];
724
  if(if_indextoname((unsigned int)if_index, interface) == NULL){
725
    perror_plus("if_indextoname");
726
    return false;
727
  }
728
  
729
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
730
  if(devnull == -1){
731
    perror_plus("open(\"/dev/null\", O_RDONLY)");
732
    return false;
733
  }
734
  pid_t pid = fork();
735
  if(pid == 0){
736
    /* Child */
737
    /* Raise privileges */
738
    errno = raise_privileges_permanently();
739
    if(errno != 0){
740
      perror_plus("Failed to raise privileges");
741
      /* _exit(EX_NOPERM); */
742
    } else {
743
      /* Set group */
744
      errno = 0;
745
      ret = setgid(0);
746
      if(ret == -1){
747
	perror_plus("setgid");
748
	_exit(EX_NOPERM);
749
      }
750
      /* Reset supplementary groups */
751
      errno = 0;
752
      ret = setgroups(0, NULL);
753
      if(ret == -1){
754
	perror_plus("setgroups");
755
	_exit(EX_NOPERM);
756
      }
757
    }
758
    ret = dup2(devnull, STDIN_FILENO);
759
    if(ret == -1){
760
      perror_plus("dup2(devnull, STDIN_FILENO)");
761
      _exit(EX_OSERR);
762
    }
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
763
    ret = (int)TEMP_FAILURE_RETRY(close(devnull));
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
764
    if(ret == -1){
765
      perror_plus("close");
766
      _exit(EX_OSERR);
767
    }
768
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
769
    if(ret == -1){
770
      perror_plus("dup2(STDERR_FILENO, STDOUT_FILENO)");
771
      _exit(EX_OSERR);
772
    }
773
    int helperdir_fd = (int)TEMP_FAILURE_RETRY(open(pluginhelperdir,
774
						    O_RDONLY
775
						    | O_DIRECTORY
776
						    | O_PATH
777
						    | O_CLOEXEC));
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
778
    if(helperdir_fd == -1){
779
      perror_plus("open");
780
      _exit(EX_UNAVAILABLE);
781
    }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
782
    int helper_fd = (int)TEMP_FAILURE_RETRY(openat(helperdir_fd,
783
						   helper, O_RDONLY));
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
784
    if(helper_fd == -1){
785
      perror_plus("openat");
786
      _exit(EX_UNAVAILABLE);
787
    }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
788
    TEMP_FAILURE_RETRY(close(helperdir_fd));
789
#ifdef __GNUC__
790
#pragma GCC diagnostic push
791
#pragma GCC diagnostic ignored "-Wcast-qual"
792
#endif
793
    if(fexecve(helper_fd, (char *const [])
794
	       { helper, add ? add_arg : remove_arg, (char *)address,
795
		   interface, NULL }, environ) == -1){
796
#ifdef __GNUC__
797
#pragma GCC diagnostic pop
798
#endif
799
      perror_plus("fexecve");
800
      _exit(EXIT_FAILURE);
801
    }
802
  }
803
  if(pid == -1){
804
    perror_plus("fork");
805
    return false;
806
  }
807
  int status;
808
  pid_t pret = -1;
809
  errno = 0;
810
  do {
811
    pret = waitpid(pid, &status, 0);
812
    if(pret == -1 and errno == EINTR and quit_now){
813
      int errno_raising = 0;
814
      if((errno = raise_privileges()) != 0){
815
	errno_raising = errno;
816
	perror_plus("Failed to raise privileges in order to"
817
		    " kill helper program");
818
      }
819
      if(kill(pid, SIGTERM) == -1){
820
	perror_plus("kill");
821
      }
822
      if((errno_raising == 0) and (errno = lower_privileges()) != 0){
823
	perror_plus("Failed to lower privileges after killing"
824
		    " helper program");
825
      }
826
      return false;
827
    }
828
  } while(pret == -1 and errno == EINTR);
829
  if(pret == -1){
830
    perror_plus("waitpid");
831
    return false;
832
  }
833
  if(WIFEXITED(status)){
834
    if(WEXITSTATUS(status) != 0){
835
      fprintf_plus(stderr, "Error: iprouteadddel exited"
836
		   " with status %d\n", WEXITSTATUS(status));
837
      return false;
838
    }
839
    return true;
840
  }
841
  if(WIFSIGNALED(status)){
842
    fprintf_plus(stderr, "Error: iprouteadddel died by"
843
		 " signal %d\n", WTERMSIG(status));
844
    return false;
845
  }
846
  fprintf_plus(stderr, "Error: iprouteadddel crashed\n");
847
  return false;
848
}
849
850
__attribute__((nonnull, warn_unused_result))
851
static bool add_local_route(const char *address,
852
			    AvahiIfIndex if_index){
853
  return add_remove_local_route(true, address, if_index);
854
}
855
856
__attribute__((nonnull, warn_unused_result))
857
static bool remove_local_route(const char *address,
858
			       AvahiIfIndex if_index){
859
  return add_remove_local_route(false, address, if_index);
860
}
861
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
862
/* Called when a Mandos server is found */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
863
__attribute__((nonnull, warn_unused_result))
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
864
static int start_mandos_communication(const char *ip, in_port_t port,
24.1.9 by Björn Påhlsson
not working midwork...
865
				      AvahiIfIndex if_index,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
866
				      int af, mandos_context *mc){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
867
  int ret, tcp_sd = -1;
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
868
  ssize_t sret;
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
869
  struct sockaddr_storage to;
13 by Björn Påhlsson
Added following support:
870
  char *buffer = NULL;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
871
  char *decrypted_buffer = NULL;
13 by Björn Påhlsson
Added following support:
872
  size_t buffer_length = 0;
873
  size_t buffer_capacity = 0;
24.1.10 by Björn Påhlsson
merge commit
874
  size_t written;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
875
  int retval = -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
876
  gnutls_session_t session;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
877
  int pf;			/* Protocol family */
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
878
  bool route_added = false;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
879
  
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
880
  errno = 0;
881
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
882
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
883
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
884
    return -1;
885
  }
886
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
887
  switch(af){
888
  case AF_INET6:
889
    pf = PF_INET6;
890
    break;
891
  case AF_INET:
892
    pf = PF_INET;
893
    break;
894
  default:
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
895
    fprintf_plus(stderr, "Bad address family: %d\n", af);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
896
    errno = EINVAL;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
897
    return -1;
898
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
899
  
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
900
  /* If the interface is specified and we have a list of interfaces */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
901
  if(if_index != AVAHI_IF_UNSPEC and mc->interfaces != NULL){
902
    /* Check if the interface is one of the interfaces we are using */
903
    bool match = false;
904
    {
905
      char *interface = NULL;
906
      while((interface=argz_next(mc->interfaces, mc->interfaces_size,
907
				 interface))){
908
	if(if_nametoindex(interface) == (unsigned int)if_index){
909
	  match = true;
910
	  break;
911
	}
912
      }
913
    }
914
    if(not match){
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
915
      /* This interface does not match any in the list, so we don't
916
	 connect to the server */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
917
      if(debug){
918
	char interface[IF_NAMESIZE];
919
	if(if_indextoname((unsigned int)if_index, interface) == NULL){
920
	  perror_plus("if_indextoname");
921
	} else {
922
	  fprintf_plus(stderr, "Skipping server on non-used interface"
923
		       " \"%s\"\n",
924
		       if_indextoname((unsigned int)if_index,
925
				      interface));
926
	}
927
      }
928
      return -1;
929
    }
930
  }
931
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
932
  ret = init_gnutls_session(&session, mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
933
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
934
    return -1;
935
  }
936
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
937
  if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
938
    fprintf_plus(stderr, "Setting up a TCP connection to %s, port %"
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
939
		 PRIuMAX "\n", ip, (uintmax_t)port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
940
  }
13 by Björn Påhlsson
Added following support:
941
  
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
942
  tcp_sd = socket(pf, SOCK_STREAM | SOCK_CLOEXEC, 0);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
943
  if(tcp_sd < 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
944
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
945
    perror_plus("socket");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
946
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
947
    goto mandos_end;
948
  }
949
  
950
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
951
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
952
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
953
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
954
  
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
955
  memset(&to, 0, sizeof(to));
237.2.67 by Teddy Hogeborn
Four new interrelated features:
956
  if(af == AF_INET6){
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
957
    ((struct sockaddr_in6 *)&to)->sin6_family = (sa_family_t)af;
958
    ret = inet_pton(af, ip, &((struct sockaddr_in6 *)&to)->sin6_addr);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
959
  } else {			/* IPv4 */
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
960
    ((struct sockaddr_in *)&to)->sin_family = (sa_family_t)af;
961
    ret = inet_pton(af, ip, &((struct sockaddr_in *)&to)->sin_addr);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
962
  }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
963
  if(ret < 0 ){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
964
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
965
    perror_plus("inet_pton");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
966
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
967
    goto mandos_end;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
968
  }
13 by Björn Påhlsson
Added following support:
969
  if(ret == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
970
    int e = errno;
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
971
    fprintf_plus(stderr, "Bad address: %s\n", ip);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
972
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
973
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
974
  }
237.2.67 by Teddy Hogeborn
Four new interrelated features:
975
  if(af == AF_INET6){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
976
    ((struct sockaddr_in6 *)&to)->sin6_port = htons(port);
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
977
    if(IN6_IS_ADDR_LINKLOCAL
978
       (&((struct sockaddr_in6 *)&to)->sin6_addr)){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
979
      if(if_index == AVAHI_IF_UNSPEC){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
980
	fprintf_plus(stderr, "An IPv6 link-local address is"
981
		     " incomplete without a network interface\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
982
	errno = EINVAL;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
983
	goto mandos_end;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
984
      }
985
      /* Set the network interface number as scope */
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
986
      ((struct sockaddr_in6 *)&to)->sin6_scope_id = (uint32_t)if_index;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
987
    }
988
  } else {
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
989
    ((struct sockaddr_in *)&to)->sin_port = htons(port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
990
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
991
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
992
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
993
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
994
    goto mandos_end;
995
  }
996
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
997
  if(debug){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
998
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
999
      char interface[IF_NAMESIZE];
1000
      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.
1001
	perror_plus("if_indextoname");
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1002
      } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1003
	fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIuMAX
1004
		     "\n", ip, interface, (uintmax_t)port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1005
      }
1006
    } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1007
      fprintf_plus(stderr, "Connection to: %s, port %" PRIuMAX "\n",
1008
		   ip, (uintmax_t)port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1009
    }
1010
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
1011
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
1012
    if(af == AF_INET6){
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1013
      ret = getnameinfo((struct sockaddr *)&to,
1014
			sizeof(struct sockaddr_in6),
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1015
			addrstr, sizeof(addrstr), NULL, 0,
1016
			NI_NUMERICHOST);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1017
    } else {
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1018
      ret = getnameinfo((struct sockaddr *)&to,
1019
			sizeof(struct sockaddr_in),
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1020
			addrstr, sizeof(addrstr), NULL, 0,
1021
			NI_NUMERICHOST);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1022
    }
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1023
    if(ret == EAI_SYSTEM){
1024
      perror_plus("getnameinfo");
1025
    } else if(ret != 0) {
1026
      fprintf_plus(stderr, "getnameinfo: %s", gai_strerror(ret));
1027
    } else if(strcmp(addrstr, ip) != 0){
1028
      fprintf_plus(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
1029
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1030
  }
13 by Björn Påhlsson
Added following support:
1031
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1032
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1033
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1034
    goto mandos_end;
1035
  }
1036
  
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1037
  while(true){
1038
    if(af == AF_INET6){
1039
      ret = connect(tcp_sd, (struct sockaddr *)&to,
1040
		    sizeof(struct sockaddr_in6));
1041
    } else {
1042
      ret = connect(tcp_sd, (struct sockaddr *)&to, /* IPv4 */
1043
		    sizeof(struct sockaddr_in));
1044
    }
1045
    if(ret < 0){
1046
      if(errno == ENETUNREACH
1047
	 and if_index != AVAHI_IF_UNSPEC
1048
	 and connect_to == NULL
1049
	 and not route_added and
1050
	 ((af == AF_INET6 and not
1051
	   IN6_IS_ADDR_LINKLOCAL(&(((struct sockaddr_in6 *)
1052
				    &to)->sin6_addr)))
1053
	  or (af == AF_INET and
1054
	      /* Not a a IPv4LL address */
1055
	      (ntohl(((struct sockaddr_in *)&to)->sin_addr.s_addr)
1056
	       & 0xFFFF0000L) != 0xA9FE0000L))){
1057
	/* Work around Avahi bug - Avahi does not announce link-local
1058
	   addresses if it has a global address, so local hosts with
1059
	   *only* a link-local address (e.g. Mandos clients) cannot
1060
	   connect to a Mandos server announced by Avahi on a server
1061
	   host with a global address.  Work around this by retrying
1062
	   with an explicit route added with the server's address.
1063
	   
1064
	   Avahi bug reference:
1065
	   http://lists.freedesktop.org/archives/avahi/2010-February/001833.html
1066
	   https://bugs.debian.org/587961
1067
	*/
1068
	int e = errno;
1069
	route_added = add_local_route(ip, if_index);
1070
	if(route_added){
1071
	  continue;
1072
	}
1073
	errno = e;
1074
      }
1075
      if(errno != ECONNREFUSED or debug){
1076
	int e = errno;
1077
	perror_plus("connect");
1078
	errno = e;
1079
      }
1080
      goto mandos_end;
1081
    }
1082
    
1083
    if(quit_now){
1084
      errno = EINTR;
1085
      goto mandos_end;
1086
    }
1087
    break;
13 by Björn Påhlsson
Added following support:
1088
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1089
  
24.1.12 by Björn Påhlsson
merge +
1090
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
1091
  written = 0;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1092
  while(true){
24.1.10 by Björn Påhlsson
merge commit
1093
    size_t out_size = strlen(out);
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1094
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1095
					out_size - written));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1096
    if(ret == -1){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1097
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1098
      perror_plus("write");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1099
      errno = e;
24.1.12 by Björn Påhlsson
merge +
1100
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
1101
    }
24.1.12 by Björn Påhlsson
merge +
1102
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
1103
    if(written < out_size){
1104
      continue;
1105
    } else {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1106
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
1107
	written = 0;
1108
	out = "\r\n";
1109
      } else {
1110
	break;
1111
      }
1112
    }
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1113
  
1114
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1115
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1116
      goto mandos_end;
1117
    }
24.1.10 by Björn Påhlsson
merge commit
1118
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1119
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1120
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1121
    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
1122
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1123
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1124
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1125
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1126
    goto mandos_end;
1127
  }
1128
  
237.7.136 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Eliminate
1129
  /* This casting via intptr_t is to eliminate warning about casting
1130
     an int to a pointer type.  This is exactly how the GnuTLS Guile
1131
     function "set-session-transport-fd!" does it. */
1132
  gnutls_transport_set_ptr(session,
1133
			   (gnutls_transport_ptr_t)(intptr_t)tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1134
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1135
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1136
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1137
    goto mandos_end;
1138
  }
1139
  
237.2.126 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
1140
  do {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1141
    ret = gnutls_handshake(session);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1142
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1143
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1144
      goto mandos_end;
1145
    }
24.1.29 by Björn Påhlsson
Added more header file comments
1146
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
1147
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1148
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
1149
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1150
      fprintf_plus(stderr, "*** GnuTLS Handshake failed ***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1151
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
1152
    }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1153
    errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1154
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1155
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1156
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1157
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1158
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1159
  if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1160
    fprintf_plus(stderr, "Retrieving OpenPGP encrypted password from"
1161
		 " %s\n", ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1162
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1163
  
13 by Björn Påhlsson
Added following support:
1164
  while(true){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1165
    
1166
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1167
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1168
      goto mandos_end;
1169
    }
1170
    
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
1171
    buffer_capacity = incbuffer(&buffer, buffer_length,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1172
				buffer_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1173
    if(buffer_capacity == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1174
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1175
      perror_plus("incbuffer");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1176
      errno = e;
24.1.12 by Björn Påhlsson
merge +
1177
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
1178
    }
1179
    
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1180
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1181
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1182
      goto mandos_end;
1183
    }
1184
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1185
    sret = gnutls_record_recv(session, buffer+buffer_length,
1186
			      BUFFER_SIZE);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1187
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
1188
      break;
1189
    }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1190
    if(sret < 0){
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1191
      switch(sret){
13 by Björn Påhlsson
Added following support:
1192
      case GNUTLS_E_INTERRUPTED:
1193
      case GNUTLS_E_AGAIN:
1194
	break;
1195
      case GNUTLS_E_REHANDSHAKE:
237.2.126 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
1196
	do {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1197
	  ret = gnutls_handshake(session);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1198
	  
1199
	  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1200
	    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1201
	    goto mandos_end;
1202
	  }
24.1.29 by Björn Påhlsson
Added more header file comments
1203
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1204
	if(ret < 0){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1205
	  fprintf_plus(stderr, "*** GnuTLS Re-handshake failed "
1206
		       "***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1207
	  gnutls_perror(ret);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1208
	  errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1209
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
1210
	}
1211
	break;
1212
      default:
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1213
	fprintf_plus(stderr, "Unknown error while reading data from"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1214
		     " encrypted session with Mandos server\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1215
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1216
	errno = EIO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1217
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
1218
      }
1219
    } else {
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1220
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
1221
    }
1222
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1223
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1224
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1225
    fprintf_plus(stderr, "Closing TLS session\n");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1226
  }
1227
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1228
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1229
    errno = EINTR;
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
1230
    goto mandos_end;
1231
  }
1232
  
1233
  do {
1234
    ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
1235
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1236
      errno = EINTR;
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
1237
      goto mandos_end;
1238
    }
1239
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1240
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1241
  if(buffer_length > 0){
237.2.125 by Teddy Hogeborn
* plugin-runner.c (getplugin, add_environment, main): Handle EINTR
1242
    ssize_t decrypted_buffer_size;
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1243
    decrypted_buffer_size = pgp_packet_decrypt(buffer, buffer_length,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1244
					       &decrypted_buffer, mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1245
    if(decrypted_buffer_size >= 0){
237.2.124 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
1246
      
24.1.10 by Björn Påhlsson
merge commit
1247
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
1248
      while(written < (size_t) decrypted_buffer_size){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1249
	if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1250
	  errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1251
	  goto mandos_end;
1252
	}
1253
	
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1254
	ret = (int)fwrite(decrypted_buffer + written, 1,
1255
			  (size_t)decrypted_buffer_size - written,
1256
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1257
	if(ret == 0 and ferror(stdout)){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1258
	  int e = errno;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1259
	  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1260
	    fprintf_plus(stderr, "Error writing encrypted data: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1261
			 strerror(errno));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1262
	  }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1263
	  errno = e;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1264
	  goto mandos_end;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1265
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1266
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1267
      }
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1268
      retval = 0;
13 by Björn Påhlsson
Added following support:
1269
    }
1270
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1271
  
1272
  /* Shutdown procedure */
1273
  
1274
 mandos_end:
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1275
  {
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1276
    if(route_added){
1277
      if(not remove_local_route(ip, if_index)){
1278
	fprintf_plus(stderr, "Failed to remove local route to %s on"
1279
		     " interface %d", ip, if_index);
1280
      }
1281
    }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1282
    int e = errno;
1283
    free(decrypted_buffer);
1284
    free(buffer);
1285
    if(tcp_sd >= 0){
1286
      ret = (int)TEMP_FAILURE_RETRY(close(tcp_sd));
1287
    }
1288
    if(ret == -1){
1289
      if(e == 0){
1290
	e = errno;
1291
      }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1292
      perror_plus("close");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1293
    }
1294
    gnutls_deinit(session);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1295
    errno = e;
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1296
    if(quit_now){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1297
      errno = EINTR;
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1298
      retval = -1;
1299
    }
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1300
  }
13 by Björn Påhlsson
Added following support:
1301
  return retval;
1302
}
1303
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1304
__attribute__((nonnull))
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
1305
static void resolve_callback(AvahiSServiceResolver *r,
1306
			     AvahiIfIndex interface,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1307
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
1308
			     AvahiResolverEvent event,
1309
			     const char *name,
1310
			     const char *type,
1311
			     const char *domain,
1312
			     const char *host_name,
1313
			     const AvahiAddress *address,
1314
			     uint16_t port,
1315
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
1316
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
1317
			     flags,
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1318
			     void *mc){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1319
  if(r == NULL){
1320
    return;
1321
  }
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1322
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1323
  /* Called whenever a service has been resolved successfully or
1324
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1325
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1326
  if(quit_now){
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1327
    avahi_s_service_resolver_free(r);
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1328
    return;
1329
  }
1330
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1331
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1332
  default:
1333
  case AVAHI_RESOLVER_FAILURE:
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1334
    fprintf_plus(stderr, "(Avahi Resolver) Failed to resolve service "
1335
		 "'%s' of type '%s' in domain '%s': %s\n", name, type,
1336
		 domain,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1337
		 avahi_strerror(avahi_server_errno
1338
				(((mandos_context*)mc)->server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1339
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1340
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1341
  case AVAHI_RESOLVER_FOUND:
1342
    {
1343
      char ip[AVAHI_ADDRESS_STR_MAX];
1344
      avahi_address_snprint(ip, sizeof(ip), address);
1345
      if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1346
	fprintf_plus(stderr, "Mandos server \"%s\" found on %s (%s, %"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1347
		     PRIdMAX ") on port %" PRIu16 "\n", name,
1348
		     host_name, ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1349
      }
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1350
      int ret = start_mandos_communication(ip, (in_port_t)port,
1351
					   interface,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1352
					   avahi_proto_to_af(proto),
1353
					   mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1354
      if(ret == 0){
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1355
	avahi_simple_poll_quit(simple_poll);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1356
      } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1357
	if(not add_server(ip, (in_port_t)port, interface,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1358
			  avahi_proto_to_af(proto),
1359
			  &((mandos_context*)mc)->current_server)){
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
1360
	  fprintf_plus(stderr, "Failed to add server \"%s\" to server"
1361
		       " list\n", name);
1362
	}
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1363
      }
13 by Björn Påhlsson
Added following support:
1364
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1365
  }
1366
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
1367
}
1368
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1369
static void browse_callback(AvahiSServiceBrowser *b,
1370
			    AvahiIfIndex interface,
1371
			    AvahiProtocol protocol,
1372
			    AvahiBrowserEvent event,
1373
			    const char *name,
1374
			    const char *type,
1375
			    const char *domain,
1376
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
1377
			    flags,
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1378
			    void *mc){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1379
  if(b == NULL){
1380
    return;
1381
  }
24.1.9 by Björn Påhlsson
not working midwork...
1382
  
1383
  /* Called whenever a new services becomes available on the LAN or
1384
     is removed from the LAN */
1385
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1386
  if(quit_now){
1387
    return;
1388
  }
1389
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1390
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
1391
  default:
1392
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1393
    
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1394
    fprintf_plus(stderr, "(Avahi browser) %s\n",
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1395
		 avahi_strerror(avahi_server_errno
1396
				(((mandos_context*)mc)->server)));
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1397
    avahi_simple_poll_quit(simple_poll);
24.1.9 by Björn Påhlsson
not working midwork...
1398
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1399
    
24.1.9 by Björn Påhlsson
not working midwork...
1400
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1401
    /* We ignore the returned Avahi resolver object. In the callback
1402
       function we free it. If the Avahi server is terminated before
1403
       the callback function is called the Avahi server will free the
1404
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1405
    
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1406
    if(avahi_s_service_resolver_new(((mandos_context*)mc)->server,
1407
				    interface, protocol, name, type,
1408
				    domain, protocol, 0,
1409
				    resolve_callback, mc) == NULL)
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1410
      fprintf_plus(stderr, "Avahi: Failed to resolve service '%s':"
1411
		   " %s\n", name,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1412
		   avahi_strerror(avahi_server_errno
1413
				  (((mandos_context*)mc)->server)));
24.1.9 by Björn Påhlsson
not working midwork...
1414
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1415
    
24.1.9 by Björn Påhlsson
not working midwork...
1416
  case AVAHI_BROWSER_REMOVE:
1417
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1418
    
24.1.9 by Björn Påhlsson
not working midwork...
1419
  case AVAHI_BROWSER_ALL_FOR_NOW:
1420
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1421
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1422
      fprintf_plus(stderr, "No Mandos server found, still"
1423
		   " searching...\n");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1424
    }
24.1.9 by Björn Påhlsson
not working midwork...
1425
    break;
1426
  }
13 by Björn Påhlsson
Added following support:
1427
}
1428
237.7.33 by Teddy Hogeborn
Merge from Björn.
1429
/* Signal handler that stops main loop after SIGTERM */
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1430
static void handle_sigterm(int sig){
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1431
  if(quit_now){
1432
    return;
1433
  }
1434
  quit_now = 1;
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1435
  signal_received = sig;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1436
  int old_errno = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1437
  /* set main loop to exit */
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1438
  if(simple_poll != NULL){
1439
    avahi_simple_poll_quit(simple_poll);
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1440
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1441
  errno = old_errno;
1442
}
1443
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1444
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1445
bool get_flags(const char *ifname, struct ifreq *ifr){
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1446
  int ret;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1447
  error_t ret_errno;
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1448
  
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1449
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1450
  if(s < 0){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1451
    ret_errno = errno;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1452
    perror_plus("socket");
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1453
    errno = ret_errno;
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1454
    return false;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1455
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1456
  strcpy(ifr->ifr_name, ifname);
1457
  ret = ioctl(s, SIOCGIFFLAGS, ifr);
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1458
  if(ret == -1){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1459
    if(debug){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1460
      ret_errno = errno;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1461
      perror_plus("ioctl SIOCGIFFLAGS");
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1462
      errno = ret_errno;
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1463
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1464
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1465
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1466
  return true;
1467
}
1468
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1469
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1470
bool good_flags(const char *ifname, const struct ifreq *ifr){
1471
  
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1472
  /* Reject the loopback device */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1473
  if(ifr->ifr_flags & IFF_LOOPBACK){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1474
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1475
      fprintf_plus(stderr, "Rejecting loopback interface \"%s\"\n",
1476
		   ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1477
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1478
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1479
  }
1480
  /* Accept point-to-point devices only if connect_to is specified */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1481
  if(connect_to != NULL and (ifr->ifr_flags & IFF_POINTOPOINT)){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1482
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1483
      fprintf_plus(stderr, "Accepting point-to-point interface"
1484
		   " \"%s\"\n", ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1485
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1486
    return true;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1487
  }
1488
  /* Otherwise, reject non-broadcast-capable devices */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1489
  if(not (ifr->ifr_flags & IFF_BROADCAST)){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1490
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1491
      fprintf_plus(stderr, "Rejecting non-broadcast interface"
1492
		   " \"%s\"\n", ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1493
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1494
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1495
  }
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1496
  /* Reject non-ARP interfaces (including dummy interfaces) */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1497
  if(ifr->ifr_flags & IFF_NOARP){
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1498
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1499
      fprintf_plus(stderr, "Rejecting non-ARP interface \"%s\"\n",
1500
		   ifname);
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1501
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1502
    return false;
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1503
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1504
  
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1505
  /* Accept this device */
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1506
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1507
    fprintf_plus(stderr, "Interface \"%s\" is good\n", ifname);
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1508
  }
1509
  return true;
1510
}
1511
1512
/* 
1513
 * This function determines if a directory entry in /sys/class/net
1514
 * corresponds to an acceptable network device.
1515
 * (This function is passed to scandir(3) as a filter function.)
1516
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1517
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1518
int good_interface(const struct dirent *if_entry){
1519
  if(if_entry->d_name[0] == '.'){
1520
    return 0;
1521
  }
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1522
  
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1523
  struct ifreq ifr;
1524
  if(not get_flags(if_entry->d_name, &ifr)){
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1525
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1526
      fprintf_plus(stderr, "Failed to get flags for interface "
1527
		   "\"%s\"\n", if_entry->d_name);
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1528
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1529
    return 0;
1530
  }
1531
  
1532
  if(not good_flags(if_entry->d_name, &ifr)){
1533
    return 0;
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1534
  }
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1535
  return 1;
1536
}
1537
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1538
/* 
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1539
 * This function determines if a network interface is up.
1540
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1541
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1542
bool interface_is_up(const char *interface){
1543
  struct ifreq ifr;
1544
  if(not get_flags(interface, &ifr)){
1545
    if(debug){
1546
      fprintf_plus(stderr, "Failed to get flags for interface "
1547
		   "\"%s\"\n", interface);
1548
    }
1549
    return false;
1550
  }
1551
  
1552
  return (bool)(ifr.ifr_flags & IFF_UP);
1553
}
1554
1555
/* 
1556
 * This function determines if a network interface is running
1557
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1558
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1559
bool interface_is_running(const char *interface){
1560
  struct ifreq ifr;
1561
  if(not get_flags(interface, &ifr)){
1562
    if(debug){
1563
      fprintf_plus(stderr, "Failed to get flags for interface "
1564
		   "\"%s\"\n", interface);
1565
    }
1566
    return false;
1567
  }
1568
  
1569
  return (bool)(ifr.ifr_flags & IFF_RUNNING);
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1570
}
1571
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1572
__attribute__((nonnull, pure, warn_unused_result))
24.1.172 by Björn Påhlsson
using scandir instead of readdir
1573
int notdotentries(const struct dirent *direntry){
1574
  /* Skip "." and ".." */
1575
  if(direntry->d_name[0] == '.'
1576
     and (direntry->d_name[1] == '\0'
1577
	  or (direntry->d_name[1] == '.'
1578
	      and direntry->d_name[2] == '\0'))){
1579
    return 0;
1580
  }
1581
  return 1;
1582
}
1583
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1584
/* Is this directory entry a runnable program? */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1585
__attribute__((nonnull, warn_unused_result))
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1586
int runnable_hook(const struct dirent *direntry){
1587
  int ret;
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1588
  size_t sret;
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1589
  struct stat st;
1590
  
1591
  if((direntry->d_name)[0] == '\0'){
1592
    /* Empty name? */
1593
    return 0;
1594
  }
1595
  
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1596
  sret = strspn(direntry->d_name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1597
		"abcdefghijklmnopqrstuvwxyz"
1598
		"0123456789"
237.7.236 by Teddy Hogeborn
Minor bug fix in mandos-client: Allow periods in network hook names.
1599
		"_.-");
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1600
  if((direntry->d_name)[sret] != '\0'){
1601
    /* Contains non-allowed characters */
1602
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1603
      fprintf_plus(stderr, "Ignoring hook \"%s\" with bad name\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1604
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1605
    }
1606
    return 0;
1607
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1608
  
237.7.241 by Teddy Hogeborn
Make mandos-client use fstatat().
1609
  ret = fstatat(hookdir_fd, direntry->d_name, &st, 0);
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1610
  if(ret == -1){
1611
    if(debug){
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1612
      perror_plus("Could not stat hook");
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1613
    }
1614
    return 0;
1615
  }
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1616
  if(not (S_ISREG(st.st_mode))){
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1617
    /* Not a regular file */
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1618
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1619
      fprintf_plus(stderr, "Ignoring hook \"%s\" - not a file\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1620
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1621
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1622
    return 0;
1623
  }
1624
  if(not (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))){
1625
    /* Not executable */
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1626
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1627
      fprintf_plus(stderr, "Ignoring hook \"%s\" - not executable\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1628
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1629
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1630
    return 0;
1631
  }
237.16.12 by Teddy Hogeborn
* plugins.d/mandos-client.c (runnable_hook): Add debug output.
1632
  if(debug){
1633
    fprintf_plus(stderr, "Hook \"%s\" is acceptable\n",
1634
		 direntry->d_name);
1635
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1636
  return 1;
1637
}
1638
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1639
__attribute__((nonnull, warn_unused_result))
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1640
int avahi_loop_with_timeout(AvahiSimplePoll *s, int retry_interval,
1641
			    mandos_context *mc){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1642
  int ret;
1643
  struct timespec now;
1644
  struct timespec waited_time;
1645
  intmax_t block_time;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1646
  
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1647
  while(true){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1648
    if(mc->current_server == NULL){
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1649
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1650
	fprintf_plus(stderr, "Wait until first server is found."
1651
		     " No timeout!\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1652
      }
1653
      ret = avahi_simple_poll_iterate(s, -1);
1654
    } else {
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1655
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1656
	fprintf_plus(stderr, "Check current_server if we should run"
1657
		     " it, or wait\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1658
      }
1659
      /* the current time */
1660
      ret = clock_gettime(CLOCK_MONOTONIC, &now);
1661
      if(ret == -1){
1662
	perror_plus("clock_gettime");
1663
	return -1;
1664
      }
1665
      /* Calculating in ms how long time between now and server
1666
	 who we visted longest time ago. Now - last seen.  */
237.7.33 by Teddy Hogeborn
Merge from Björn.
1667
      waited_time.tv_sec = (now.tv_sec
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1668
			    - mc->current_server->last_seen.tv_sec);
237.7.33 by Teddy Hogeborn
Merge from Björn.
1669
      waited_time.tv_nsec = (now.tv_nsec
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1670
			     - mc->current_server->last_seen.tv_nsec);
237.7.33 by Teddy Hogeborn
Merge from Björn.
1671
      /* total time is 10s/10,000ms.
1672
	 Converting to s from ms by dividing by 1,000,
1673
	 and ns to ms by dividing by 1,000,000. */
1674
      block_time = ((retry_interval
1675
		     - ((intmax_t)waited_time.tv_sec * 1000))
1676
		    - ((intmax_t)waited_time.tv_nsec / 1000000));
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1677
      
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1678
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1679
	fprintf_plus(stderr, "Blocking for %" PRIdMAX " ms\n",
1680
		     block_time);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1681
      }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1682
      
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1683
      if(block_time <= 0){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1684
	ret = start_mandos_communication(mc->current_server->ip,
1685
					 mc->current_server->port,
1686
					 mc->current_server->if_index,
1687
					 mc->current_server->af, mc);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1688
	if(ret == 0){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1689
	  avahi_simple_poll_quit(s);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1690
	  return 0;
1691
	}
237.7.33 by Teddy Hogeborn
Merge from Björn.
1692
	ret = clock_gettime(CLOCK_MONOTONIC,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1693
			    &mc->current_server->last_seen);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1694
	if(ret == -1){
1695
	  perror_plus("clock_gettime");
1696
	  return -1;
1697
	}
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1698
	mc->current_server = mc->current_server->next;
237.7.33 by Teddy Hogeborn
Merge from Björn.
1699
	block_time = 0; 	/* Call avahi to find new Mandos
1700
				   servers, but don't block */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1701
      }
1702
      
1703
      ret = avahi_simple_poll_iterate(s, (int)block_time);
1704
    }
1705
    if(ret != 0){
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1706
      if(ret > 0 or errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1707
	return (ret != 1) ? ret : 0;
1708
      }
1709
    }
1710
  }
1711
}
1712
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1713
__attribute__((nonnull))
1714
void run_network_hooks(const char *mode, const char *interface,
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1715
		       const float delay){
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
1716
  struct dirent **direntries = NULL;
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1717
  if(hookdir_fd == -1){
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1718
    hookdir_fd = open(hookdir, O_RDONLY | O_DIRECTORY | O_PATH
1719
		      | O_CLOEXEC);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1720
    if(hookdir_fd == -1){
1721
      if(errno == ENOENT){
1722
	if(debug){
1723
	  fprintf_plus(stderr, "Network hook directory \"%s\" not"
1724
		       " found\n", hookdir);
1725
	}
1726
      } else {
1727
	perror_plus("open");
1728
      }
1729
      return;
1730
    }
1731
  }
1732
#ifdef __GLIBC__
1733
#if __GLIBC_PREREQ(2, 15)
1734
  int numhooks = scandirat(hookdir_fd, ".", &direntries,
1735
			   runnable_hook, alphasort);
1736
#else  /* not __GLIBC_PREREQ(2, 15) */
1737
  int numhooks = scandir(hookdir, &direntries, runnable_hook,
1738
			 alphasort);
1739
#endif	/* not __GLIBC_PREREQ(2, 15) */
1740
#else	/* not __GLIBC__ */
1741
  int numhooks = scandir(hookdir, &direntries, runnable_hook,
1742
			 alphasort);
1743
#endif	/* not __GLIBC__ */
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1744
  if(numhooks == -1){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1745
    perror_plus("scandir");
1746
    return;
1747
  }
1748
  struct dirent *direntry;
1749
  int ret;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1750
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
1751
  if(devnull == -1){
1752
    perror_plus("open(\"/dev/null\", O_RDONLY)");
1753
    return;
1754
  }
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1755
  for(int i = 0; i < numhooks; i++){
1756
    direntry = direntries[i];
1757
    if(debug){
1758
      fprintf_plus(stderr, "Running network hook \"%s\"\n",
1759
		   direntry->d_name);
1760
    }
1761
    pid_t hook_pid = fork();
1762
    if(hook_pid == 0){
1763
      /* Child */
1764
      /* Raise privileges */
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
1765
      errno = raise_privileges_permanently();
1766
      if(errno != 0){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1767
	perror_plus("Failed to raise privileges");
1768
	_exit(EX_NOPERM);
1769
      }
1770
      /* Set group */
1771
      errno = 0;
1772
      ret = setgid(0);
1773
      if(ret == -1){
1774
	perror_plus("setgid");
1775
	_exit(EX_NOPERM);
1776
      }
1777
      /* Reset supplementary groups */
1778
      errno = 0;
1779
      ret = setgroups(0, NULL);
1780
      if(ret == -1){
1781
	perror_plus("setgroups");
1782
	_exit(EX_NOPERM);
1783
      }
1784
      ret = setenv("MANDOSNETHOOKDIR", hookdir, 1);
1785
      if(ret == -1){
1786
	perror_plus("setenv");
1787
	_exit(EX_OSERR);
1788
      }
1789
      ret = setenv("DEVICE", interface, 1);
1790
      if(ret == -1){
1791
	perror_plus("setenv");
1792
	_exit(EX_OSERR);
1793
      }
1794
      ret = setenv("VERBOSITY", debug ? "1" : "0", 1);
1795
      if(ret == -1){
1796
	perror_plus("setenv");
1797
	_exit(EX_OSERR);
1798
      }
1799
      ret = setenv("MODE", mode, 1);
1800
      if(ret == -1){
1801
	perror_plus("setenv");
1802
	_exit(EX_OSERR);
1803
      }
1804
      char *delaystring;
1805
      ret = asprintf(&delaystring, "%f", (double)delay);
1806
      if(ret == -1){
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1807
	perror_plus("asprintf");
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1808
	_exit(EX_OSERR);
1809
      }
1810
      ret = setenv("DELAY", delaystring, 1);
1811
      if(ret == -1){
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1812
	free(delaystring);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1813
	perror_plus("setenv");
1814
	_exit(EX_OSERR);
1815
      }
1816
      free(delaystring);
1817
      if(connect_to != NULL){
1818
	ret = setenv("CONNECT", connect_to, 1);
1819
	if(ret == -1){
1820
	  perror_plus("setenv");
1821
	  _exit(EX_OSERR);
1822
	}
1823
      }
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1824
      int hook_fd = (int)TEMP_FAILURE_RETRY(openat(hookdir_fd,
1825
						   direntry->d_name,
1826
						   O_RDONLY));
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
1827
      if(hook_fd == -1){
1828
	perror_plus("openat");
1829
	_exit(EXIT_FAILURE);
1830
      }
1831
      if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){
1832
	perror_plus("close");
1833
	_exit(EXIT_FAILURE);
1834
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1835
      ret = dup2(devnull, STDIN_FILENO);
1836
      if(ret == -1){
1837
	perror_plus("dup2(devnull, STDIN_FILENO)");
1838
	_exit(EX_OSERR);
1839
      }
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1840
      ret = (int)TEMP_FAILURE_RETRY(close(devnull));
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1841
      if(ret == -1){
1842
	perror_plus("close");
1843
	_exit(EX_OSERR);
1844
      }
1845
      ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1846
      if(ret == -1){
1847
	perror_plus("dup2(STDERR_FILENO, STDOUT_FILENO)");
1848
	_exit(EX_OSERR);
1849
      }
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
1850
      if(fexecve(hook_fd, (char *const []){ direntry->d_name, NULL },
1851
		 environ) == -1){
237.7.240 by Teddy Hogeborn
Make mandos-client use fexecve().
1852
	perror_plus("fexecve");
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1853
	_exit(EXIT_FAILURE);
1854
      }
1855
    } else {
237.7.281 by Teddy Hogeborn
mandos-client: Bug fix: Check fork() return value.
1856
      if(hook_pid == -1){
1857
	perror_plus("fork");
1858
	free(direntry);
1859
	continue;
1860
      }
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1861
      int status;
1862
      if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){
1863
	perror_plus("waitpid");
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1864
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1865
	continue;
1866
      }
1867
      if(WIFEXITED(status)){
1868
	if(WEXITSTATUS(status) != 0){
1869
	  fprintf_plus(stderr, "Warning: network hook \"%s\" exited"
1870
		       " with status %d\n", direntry->d_name,
1871
		       WEXITSTATUS(status));
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1872
	  free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1873
	  continue;
1874
	}
1875
      } else if(WIFSIGNALED(status)){
1876
	fprintf_plus(stderr, "Warning: network hook \"%s\" died by"
1877
		     " signal %d\n", direntry->d_name,
1878
		     WTERMSIG(status));
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1879
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1880
	continue;
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1881
      } else {
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1882
	fprintf_plus(stderr, "Warning: network hook \"%s\""
1883
		     " crashed\n", direntry->d_name);
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1884
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1885
	continue;
1886
      }
1887
    }
1888
    if(debug){
1889
      fprintf_plus(stderr, "Network hook \"%s\" ran successfully\n",
1890
		   direntry->d_name);
1891
    }
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1892
    free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1893
  }
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
1894
  free(direntries);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
1895
  if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){
1896
    perror_plus("close");
1897
  } else {
1898
    hookdir_fd = -1;
1899
  }
1900
  close(devnull);
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1901
}
1902
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1903
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1904
error_t bring_up_interface(const char *const interface,
1905
			   const float delay){
1906
  error_t old_errno = errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1907
  int ret;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
1908
  struct ifreq network;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1909
  unsigned int if_index = if_nametoindex(interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
1910
  if(if_index == 0){
1911
    fprintf_plus(stderr, "No such interface: \"%s\"\n", interface);
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
1912
    errno = old_errno;
1913
    return ENXIO;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
1914
  }
1915
  
1916
  if(quit_now){
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
1917
    errno = old_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
1918
    return EINTR;
1919
  }
1920
  
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1921
  if(not interface_is_up(interface)){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1922
    error_t ret_errno = 0, ioctl_errno = 0;
1923
    if(not get_flags(interface, &network)){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1924
      ret_errno = errno;
1925
      fprintf_plus(stderr, "Failed to get flags for interface "
1926
		   "\"%s\"\n", interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1927
      errno = old_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1928
      return ret_errno;
1929
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1930
    network.ifr_flags |= IFF_UP; /* set flag */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1931
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1932
    int sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1933
    if(sd == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1934
      ret_errno = errno;
1935
      perror_plus("socket");
1936
      errno = old_errno;
1937
      return ret_errno;
1938
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1939
    
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1940
    if(quit_now){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1941
      ret = (int)TEMP_FAILURE_RETRY(close(sd));
1942
      if(ret == -1){
1943
	perror_plus("close");
1944
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1945
      errno = old_errno;
1946
      return EINTR;
1947
    }
1948
    
1949
    if(debug){
1950
      fprintf_plus(stderr, "Bringing up interface \"%s\"\n",
1951
		   interface);
1952
    }
1953
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1954
    /* Raise privileges */
1955
    ret_errno = raise_privileges();
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
1956
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
1957
      errno = ret_errno;
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
1958
      perror_plus("Failed to raise privileges");
1959
    }
1960
    
1961
#ifdef __linux__
1962
    int ret_linux;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1963
    bool restore_loglevel = false;
1964
    if(ret_errno == 0){
1965
      /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
1966
	 messages about the network interface to mess up the prompt */
1967
      ret_linux = klogctl(8, NULL, 5);
1968
      if(ret_linux == -1){
1969
	perror_plus("klogctl");
1970
      } else {
1971
	restore_loglevel = true;
1972
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1973
    }
1974
#endif	/* __linux__ */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1975
    int ret_setflags = ioctl(sd, SIOCSIFFLAGS, &network);
1976
    ioctl_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1977
#ifdef __linux__
1978
    if(restore_loglevel){
1979
      ret_linux = klogctl(7, NULL, 0);
1980
      if(ret_linux == -1){
1981
	perror_plus("klogctl");
1982
      }
1983
    }
1984
#endif	/* __linux__ */
1985
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1986
    /* If raise_privileges() succeeded above */
1987
    if(ret_errno == 0){
1988
      /* Lower privileges */
1989
      ret_errno = lower_privileges();
1990
      if(ret_errno != 0){
1991
	errno = ret_errno;
1992
	perror_plus("Failed to lower privileges");
1993
      }
1994
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1995
    
1996
    /* Close the socket */
1997
    ret = (int)TEMP_FAILURE_RETRY(close(sd));
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
1998
    if(ret == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1999
      perror_plus("close");
2000
    }
2001
    
2002
    if(ret_setflags == -1){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2003
      errno = ioctl_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2004
      perror_plus("ioctl SIOCSIFFLAGS +IFF_UP");
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2005
      errno = old_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2006
      return ioctl_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2007
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2008
  } else if(debug){
2009
    fprintf_plus(stderr, "Interface \"%s\" is already up; good\n",
2010
		 interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2011
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2012
  
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2013
  /* Sleep checking until interface is running.
2014
     Check every 0.25s, up to total time of delay */
2015
  for(int i=0; i < delay * 4; i++){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2016
    if(interface_is_running(interface)){
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2017
      break;
2018
    }
2019
    struct timespec sleeptime = { .tv_nsec = 250000000 };
2020
    ret = nanosleep(&sleeptime, NULL);
2021
    if(ret == -1 and errno != EINTR){
2022
      perror_plus("nanosleep");
2023
    }
2024
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2025
  
2026
  errno = old_errno;
2027
  return 0;
2028
}
2029
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2030
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2031
error_t take_down_interface(const char *const interface){
2032
  error_t old_errno = errno;
2033
  struct ifreq network;
2034
  unsigned int if_index = if_nametoindex(interface);
2035
  if(if_index == 0){
2036
    fprintf_plus(stderr, "No such interface: \"%s\"\n", interface);
2037
    errno = old_errno;
2038
    return ENXIO;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2039
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2040
  if(interface_is_up(interface)){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2041
    error_t ret_errno = 0, ioctl_errno = 0;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2042
    if(not get_flags(interface, &network) and debug){
2043
      ret_errno = errno;
2044
      fprintf_plus(stderr, "Failed to get flags for interface "
2045
		   "\"%s\"\n", interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2046
      errno = old_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2047
      return ret_errno;
2048
    }
2049
    network.ifr_flags &= ~(short)IFF_UP; /* clear flag */
2050
    
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2051
    int sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2052
    if(sd == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2053
      ret_errno = errno;
2054
      perror_plus("socket");
2055
      errno = old_errno;
2056
      return ret_errno;
2057
    }
2058
    
2059
    if(debug){
2060
      fprintf_plus(stderr, "Taking down interface \"%s\"\n",
2061
		   interface);
2062
    }
2063
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2064
    /* Raise privileges */
2065
    ret_errno = raise_privileges();
2066
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2067
      errno = ret_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2068
      perror_plus("Failed to raise privileges");
2069
    }
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2070
    
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2071
    int ret_setflags = ioctl(sd, SIOCSIFFLAGS, &network);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2072
    ioctl_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2073
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2074
    /* If raise_privileges() succeeded above */
2075
    if(ret_errno == 0){
2076
      /* Lower privileges */
2077
      ret_errno = lower_privileges();
2078
      if(ret_errno != 0){
2079
	errno = ret_errno;
2080
	perror_plus("Failed to lower privileges");
2081
      }
2082
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2083
    
2084
    /* Close the socket */
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2085
    int ret = (int)TEMP_FAILURE_RETRY(close(sd));
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2086
    if(ret == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2087
      perror_plus("close");
2088
    }
2089
    
2090
    if(ret_setflags == -1){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2091
      errno = ioctl_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2092
      perror_plus("ioctl SIOCSIFFLAGS -IFF_UP");
2093
      errno = old_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2094
      return ioctl_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2095
    }
2096
  } else if(debug){
2097
    fprintf_plus(stderr, "Interface \"%s\" is already down; odd\n",
2098
		 interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2099
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2100
  
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2101
  errno = old_errno;
2102
  return 0;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2103
}
2104
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
2105
int main(int argc, char *argv[]){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2106
  mandos_context mc = { .server = NULL, .dh_bits = 1024,
2107
			.priority = "SECURE256:!CTYPE-X.509:"
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2108
			"+CTYPE-OPENPGP", .current_server = NULL,
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2109
			.interfaces = NULL, .interfaces_size = 0 };
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2110
  AvahiSServiceBrowser *sb = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2111
  error_t ret_errno;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2112
  int ret;
2113
  intmax_t tmpmax;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2114
  char *tmp;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2115
  int exitcode = EXIT_SUCCESS;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2116
  char *interfaces_to_take_down = NULL;
2117
  size_t interfaces_to_take_down_size = 0;
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2118
  char run_tempdir[] = "/run/tmp/mandosXXXXXX";
2119
  char old_tempdir[] = "/tmp/mandosXXXXXX";
2120
  char *tempdir = NULL;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2121
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2122
  const char *seckey = PATHDIR "/" SECKEY;
2123
  const char *pubkey = PATHDIR "/" PUBKEY;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2124
  char *interfaces_hooks = NULL;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2125
  
2126
  bool gnutls_initialized = false;
2127
  bool gpgme_initialized = false;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2128
  float delay = 2.5f;
237.7.33 by Teddy Hogeborn
Merge from Björn.
2129
  double retry_interval = 10; /* 10s between trying a server and
2130
				 retrying the same server again */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2131
  
237.2.132 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
2132
  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
2133
  struct sigaction sigterm_action = { .sa_handler = handle_sigterm };
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2134
  
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2135
  uid = getuid();
2136
  gid = getgid();
2137
  
2138
  /* Lower any group privileges we might have, just to be safe */
2139
  errno = 0;
2140
  ret = setgid(gid);
2141
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2142
    perror_plus("setgid");
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2143
  }
2144
  
2145
  /* Lower user privileges (temporarily) */
2146
  errno = 0;
2147
  ret = seteuid(uid);
2148
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2149
    perror_plus("seteuid");
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2150
  }
2151
  
2152
  if(quit_now){
2153
    goto end;
2154
  }
2155
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2156
  {
2157
    struct argp_option options[] = {
2158
      { .name = "debug", .key = 128,
2159
	.doc = "Debug mode", .group = 3 },
2160
      { .name = "connect", .key = 'c',
2161
	.arg = "ADDRESS:PORT",
2162
	.doc = "Connect directly to a specific Mandos server",
2163
	.group = 1 },
2164
      { .name = "interface", .key = 'i',
2165
	.arg = "NAME",
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2166
	.doc = "Network interface that will be used to search for"
2167
	" Mandos servers",
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2168
	.group = 1 },
2169
      { .name = "seckey", .key = 's',
2170
	.arg = "FILE",
2171
	.doc = "OpenPGP secret key file base name",
2172
	.group = 1 },
2173
      { .name = "pubkey", .key = 'p',
2174
	.arg = "FILE",
2175
	.doc = "OpenPGP public key file base name",
2176
	.group = 2 },
2177
      { .name = "dh-bits", .key = 129,
2178
	.arg = "BITS",
2179
	.doc = "Bit length of the prime number used in the"
2180
	" Diffie-Hellman key exchange",
2181
	.group = 2 },
2182
      { .name = "priority", .key = 130,
2183
	.arg = "STRING",
2184
	.doc = "GnuTLS priority string for the TLS handshake",
2185
	.group = 1 },
2186
      { .name = "delay", .key = 131,
2187
	.arg = "SECONDS",
2188
	.doc = "Maximum delay to wait for interface startup",
2189
	.group = 2 },
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2190
      { .name = "retry", .key = 132,
2191
	.arg = "SECONDS",
237.17.1 by teddy at recompile
Add wireless network hook
2192
	.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.
2193
	.group = 2 },
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
2194
      { .name = "network-hook-dir", .key = 133,
2195
	.arg = "DIR",
2196
	.doc = "Directory where network hooks are located",
2197
	.group = 2 },
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2198
      /*
2199
       * These reproduce what we would get without ARGP_NO_HELP
2200
       */
2201
      { .name = "help", .key = '?',
2202
	.doc = "Give this help list", .group = -1 },
2203
      { .name = "usage", .key = -3,
2204
	.doc = "Give a short usage message", .group = -1 },
2205
      { .name = "version", .key = 'V',
2206
	.doc = "Print program version", .group = -1 },
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2207
      { .name = NULL }
2208
    };
2209
    
2210
    error_t parse_opt(int key, char *arg,
2211
		      struct argp_state *state){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2212
      errno = 0;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2213
      switch(key){
2214
      case 128:			/* --debug */
2215
	debug = true;
2216
	break;
2217
      case 'c':			/* --connect */
2218
	connect_to = arg;
2219
	break;
2220
      case 'i':			/* --interface */
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2221
	ret_errno = argz_add_sep(&mc.interfaces, &mc.interfaces_size,
2222
				 arg, (int)',');
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2223
	if(ret_errno != 0){
2224
	  argp_error(state, "%s", strerror(ret_errno));
2225
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2226
	break;
2227
      case 's':			/* --seckey */
2228
	seckey = arg;
2229
	break;
2230
      case 'p':			/* --pubkey */
2231
	pubkey = arg;
2232
	break;
2233
      case 129:			/* --dh-bits */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2234
	errno = 0;
2235
	tmpmax = strtoimax(arg, &tmp, 10);
2236
	if(errno != 0 or tmp == arg or *tmp != '\0'
2237
	   or tmpmax != (typeof(mc.dh_bits))tmpmax){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2238
	  argp_error(state, "Bad number of DH bits");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2239
	}
2240
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
2241
	break;
2242
      case 130:			/* --priority */
2243
	mc.priority = arg;
2244
	break;
2245
      case 131:			/* --delay */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2246
	errno = 0;
2247
	delay = strtof(arg, &tmp);
2248
	if(errno != 0 or tmp == arg or *tmp != '\0'){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2249
	  argp_error(state, "Bad delay");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2250
	}
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2251
      case 132:			/* --retry */
2252
	errno = 0;
2253
	retry_interval = strtod(arg, &tmp);
2254
	if(errno != 0 or tmp == arg or *tmp != '\0'
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2255
	   or (retry_interval * 1000) > INT_MAX
2256
	   or retry_interval < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2257
	  argp_error(state, "Bad retry interval");
2258
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2259
	break;
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
2260
      case 133:			/* --network-hook-dir */
2261
	hookdir = arg;
2262
	break;
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2263
	/*
2264
	 * These reproduce what we would get without ARGP_NO_HELP
2265
	 */
2266
      case '?':			/* --help */
2267
	argp_state_help(state, state->out_stream,
2268
			(ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2269
			& ~(unsigned int)ARGP_HELP_EXIT_OK);
2270
      case -3:			/* --usage */
2271
	argp_state_help(state, state->out_stream,
2272
			ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2273
      case 'V':			/* --version */
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2274
	fprintf_plus(state->out_stream, "%s\n", argp_program_version);
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2275
	exit(argp_err_exit_status);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2276
	break;
2277
      default:
2278
	return ARGP_ERR_UNKNOWN;
2279
      }
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2280
      return errno;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2281
    }
2282
    
2283
    struct argp argp = { .options = options, .parser = parse_opt,
2284
			 .args_doc = "",
2285
			 .doc = "Mandos client -- Get and decrypt"
2286
			 " passwords from a Mandos server" };
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2287
    ret = argp_parse(&argp, argc, argv,
2288
		     ARGP_IN_ORDER | ARGP_NO_HELP, 0, NULL);
2289
    switch(ret){
2290
    case 0:
2291
      break;
2292
    case ENOMEM:
2293
    default:
2294
      errno = ret;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2295
      perror_plus("argp_parse");
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2296
      exitcode = EX_OSERR;
2297
      goto end;
2298
    case EINVAL:
2299
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2300
      goto end;
2301
    }
2302
  }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2303
  
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2304
  {
237.7.35 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
2305
    /* Work around Debian bug #633582:
2306
       <http://bugs.debian.org/633582> */
2307
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2308
    /* Re-raise privileges */
2309
    ret_errno = raise_privileges();
2310
    if(ret_errno != 0){
2311
      errno = ret_errno;
2312
      perror_plus("Failed to raise privileges");
2313
    } else {
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2314
      struct stat st;
2315
      
2316
      if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
2317
	int seckey_fd = open(seckey, O_RDONLY);
2318
	if(seckey_fd == -1){
2319
	  perror_plus("open");
2320
	} else {
2321
	  ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
2322
	  if(ret == -1){
2323
	    perror_plus("fstat");
2324
	  } else {
2325
	    if(S_ISREG(st.st_mode)
2326
	       and st.st_uid == 0 and st.st_gid == 0){
2327
	      ret = fchown(seckey_fd, uid, gid);
2328
	      if(ret == -1){
2329
		perror_plus("fchown");
2330
	      }
2331
	    }
2332
	  }
2333
	  TEMP_FAILURE_RETRY(close(seckey_fd));
2334
	}
2335
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2336
      
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2337
      if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
2338
	int pubkey_fd = open(pubkey, O_RDONLY);
2339
	if(pubkey_fd == -1){
2340
	  perror_plus("open");
2341
	} else {
2342
	  ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
2343
	  if(ret == -1){
2344
	    perror_plus("fstat");
2345
	  } else {
2346
	    if(S_ISREG(st.st_mode)
2347
	       and st.st_uid == 0 and st.st_gid == 0){
2348
	      ret = fchown(pubkey_fd, uid, gid);
2349
	      if(ret == -1){
2350
		perror_plus("fchown");
2351
	      }
2352
	    }
2353
	  }
2354
	  TEMP_FAILURE_RETRY(close(pubkey_fd));
2355
	}
2356
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2357
      
237.16.11 by Teddy Hogeborn
* Makefile (run-client): Add "--network-hook-dir" option.
2358
      /* Lower privileges */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2359
      ret_errno = lower_privileges();
2360
      if(ret_errno != 0){
2361
	errno = ret_errno;
2362
	perror_plus("Failed to lower privileges");
2363
      }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2364
    }
2365
  }
2366
  
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2367
  /* Remove invalid interface names (except "none") */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2368
  {
2369
    char *interface = NULL;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2370
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2371
				 interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2372
      if(strcmp(interface, "none") != 0
2373
	 and if_nametoindex(interface) == 0){
2374
	if(interface[0] != '\0'){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2375
	  fprintf_plus(stderr, "Not using nonexisting interface"
2376
		       " \"%s\"\n", interface);
2377
	}
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2378
	argz_delete(&mc.interfaces, &mc.interfaces_size, interface);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2379
	interface = NULL;
2380
      }
2381
    }
2382
  }
2383
  
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2384
  /* Run network hooks */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2385
  {
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2386
    if(mc.interfaces != NULL){
2387
      interfaces_hooks = malloc(mc.interfaces_size);
237.7.147 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Set DEVICE environment
2388
      if(interfaces_hooks == NULL){
2389
	perror_plus("malloc");
2390
	goto end;
2391
      }
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2392
      memcpy(interfaces_hooks, mc.interfaces, mc.interfaces_size);
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2393
      argz_stringify(interfaces_hooks, mc.interfaces_size, (int)',');
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2394
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2395
    run_network_hooks("start", interfaces_hooks != NULL ?
2396
		      interfaces_hooks : "", delay);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2397
  }
2398
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2399
  if(not debug){
2400
    avahi_set_log_function(empty_log);
2401
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2402
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2403
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
2404
     from the signal handler */
2405
  /* Initialize the pseudo-RNG for Avahi */
2406
  srand((unsigned int) time(NULL));
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
2407
  simple_poll = avahi_simple_poll_new();
2408
  if(simple_poll == NULL){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2409
    fprintf_plus(stderr,
2410
		 "Avahi: Failed to create simple poll object.\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2411
    exitcode = EX_UNAVAILABLE;
24.1.135 by Björn Påhlsson
Earlier signal handling
2412
    goto end;
2413
  }
237.2.72 by Teddy Hogeborn
Merge from Björn:
2414
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2415
  sigemptyset(&sigterm_action.sa_mask);
237.2.72 by Teddy Hogeborn
Merge from Björn:
2416
  ret = sigaddset(&sigterm_action.sa_mask, SIGINT);
2417
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2418
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2419
    exitcode = EX_OSERR;
237.2.72 by Teddy Hogeborn
Merge from Björn:
2420
    goto end;
2421
  }
2422
  ret = sigaddset(&sigterm_action.sa_mask, SIGHUP);
2423
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2424
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2425
    exitcode = EX_OSERR;
237.2.72 by Teddy Hogeborn
Merge from Björn:
2426
    goto end;
2427
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
2428
  ret = sigaddset(&sigterm_action.sa_mask, SIGTERM);
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");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2431
    exitcode = EX_OSERR;
24.1.135 by Björn Påhlsson
Earlier signal handling
2432
    goto end;
2433
  }
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2434
  /* Need to check if the handler is SIG_IGN before handling:
2435
     | [[info:libc:Initial Signal Actions]] |
2436
     | [[info:libc:Basic Signal Handling]]  |
2437
  */
2438
  ret = sigaction(SIGINT, NULL, &old_sigterm_action);
2439
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2440
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2441
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2442
  }
2443
  if(old_sigterm_action.sa_handler != SIG_IGN){
2444
    ret = sigaction(SIGINT, &sigterm_action, NULL);
2445
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2446
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2447
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2448
      goto end;
2449
    }
2450
  }
2451
  ret = sigaction(SIGHUP, NULL, &old_sigterm_action);
2452
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2453
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2454
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2455
  }
2456
  if(old_sigterm_action.sa_handler != SIG_IGN){
2457
    ret = sigaction(SIGHUP, &sigterm_action, NULL);
2458
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2459
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2460
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2461
      goto end;
2462
    }
2463
  }
2464
  ret = sigaction(SIGTERM, NULL, &old_sigterm_action);
2465
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2466
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2467
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2468
  }
2469
  if(old_sigterm_action.sa_handler != SIG_IGN){
2470
    ret = sigaction(SIGTERM, &sigterm_action, NULL);
2471
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2472
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2473
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2474
      goto end;
2475
    }
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2476
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2477
  
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2478
  /* If no interfaces were specified, make a list */
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2479
  if(mc.interfaces == NULL){
237.7.247 by Teddy Hogeborn
Fix free() of possibly uninitialized pointer in mandos-client.
2480
    struct dirent **direntries = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2481
    /* Look for any good interfaces */
2482
    ret = scandir(sys_class_net, &direntries, good_interface,
2483
		  alphasort);
2484
    if(ret >= 1){
2485
      /* Add all found interfaces to interfaces list */
2486
      for(int i = 0; i < ret; ++i){
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2487
	ret_errno = argz_add(&mc.interfaces, &mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2488
			     direntries[i]->d_name);
2489
	if(ret_errno != 0){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2490
	  errno = ret_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2491
	  perror_plus("argz_add");
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2492
	  free(direntries[i]);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2493
	  continue;
2494
	}
2495
	if(debug){
2496
	  fprintf_plus(stderr, "Will use interface \"%s\"\n",
2497
		       direntries[i]->d_name);
2498
	}
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2499
	free(direntries[i]);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2500
      }
2501
      free(direntries);
2502
    } else {
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2503
      if(ret == 0){
2504
	free(direntries);
2505
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2506
      fprintf_plus(stderr, "Could not find a network interface\n");
2507
      exitcode = EXIT_FAILURE;
2508
      goto end;
2509
    }
2510
  }
2511
  
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
2512
  /* Bring up interfaces which are down, and remove any "none"s */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2513
  {
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2514
    char *interface = NULL;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2515
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2516
				 interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2517
      /* If interface name is "none", stop bringing up interfaces.
2518
	 Also remove all instances of "none" from the list */
2519
      if(strcmp(interface, "none") == 0){
2520
	argz_delete(&mc.interfaces, &mc.interfaces_size,
2521
		    interface);
2522
	interface = NULL;
2523
	while((interface = argz_next(mc.interfaces,
2524
				     mc.interfaces_size, interface))){
2525
	  if(strcmp(interface, "none") == 0){
2526
	    argz_delete(&mc.interfaces, &mc.interfaces_size,
2527
			interface);
2528
	    interface = NULL;
2529
	  }
2530
	}
2531
	break;
2532
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2533
      bool interface_was_up = interface_is_up(interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2534
      errno = bring_up_interface(interface, delay);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2535
      if(not interface_was_up){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2536
	if(errno != 0){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2537
	  perror_plus("Failed to bring up interface");
2538
	} else {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2539
	  errno = argz_add(&interfaces_to_take_down,
2540
			   &interfaces_to_take_down_size,
2541
			   interface);
2542
	  if(errno != 0){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2543
	    perror_plus("argz_add");
2544
	  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2545
	}
2546
      }
2547
    }
2548
    if(debug and (interfaces_to_take_down == NULL)){
2549
      fprintf_plus(stderr, "No interfaces were brought up\n");
237.2.128 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2550
    }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2551
  }
2552
  
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2553
  /* If we only got one interface, explicitly use only that one */
2554
  if(argz_count(mc.interfaces, mc.interfaces_size) == 1){
2555
    if(debug){
2556
      fprintf_plus(stderr, "Using only interface \"%s\"\n",
2557
		   mc.interfaces);
2558
    }
2559
    if_index = (AvahiIfIndex)if_nametoindex(mc.interfaces);
2560
  }
2561
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2562
  if(quit_now){
2563
    goto end;
2564
  }
2565
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2566
  ret = init_gnutls_global(pubkey, seckey, &mc);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2567
  if(ret == -1){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2568
    fprintf_plus(stderr, "init_gnutls_global failed\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2569
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2570
    goto end;
2571
  } else {
2572
    gnutls_initialized = true;
2573
  }
2574
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2575
  if(quit_now){
2576
    goto end;
2577
  }
2578
  
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2579
  /* Try /run/tmp before /tmp */
2580
  tempdir = mkdtemp(run_tempdir);
2581
  if(tempdir == NULL and errno == ENOENT){
2582
      if(debug){
2583
	fprintf_plus(stderr, "Tempdir %s did not work, trying %s\n",
2584
		     run_tempdir, old_tempdir);
2585
      }
2586
      tempdir = mkdtemp(old_tempdir);
2587
  }
2588
  if(tempdir == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2589
    perror_plus("mkdtemp");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2590
    goto end;
2591
  }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2592
  
2593
  if(quit_now){
2594
    goto end;
2595
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2596
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2597
  if(not init_gpgme(pubkey, seckey, tempdir, &mc)){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2598
    fprintf_plus(stderr, "init_gpgme failed\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2599
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2600
    goto end;
2601
  } else {
2602
    gpgme_initialized = true;
2603
  }
2604
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2605
  if(quit_now){
2606
    goto end;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2607
  }
2608
  
2609
  if(connect_to != NULL){
2610
    /* Connect directly, do not use Zeroconf */
2611
    /* (Mainly meant for debugging) */
2612
    char *address = strrchr(connect_to, ':');
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2613
    
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2614
    if(address == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2615
      fprintf_plus(stderr, "No colon in address\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2616
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2617
      goto end;
2618
    }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2619
    
2620
    if(quit_now){
2621
      goto end;
2622
    }
2623
    
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2624
    in_port_t port;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2625
    errno = 0;
2626
    tmpmax = strtoimax(address+1, &tmp, 10);
2627
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2628
       or tmpmax != (in_port_t)tmpmax){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2629
      fprintf_plus(stderr, "Bad port number\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2630
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2631
      goto end;
2632
    }
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2633
    
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2634
    if(quit_now){
2635
      goto end;
2636
    }
2637
    
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2638
    port = (in_port_t)tmpmax;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2639
    *address = '\0';
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2640
    /* Colon in address indicates IPv6 */
2641
    int af;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2642
    if(strchr(connect_to, ':') != NULL){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2643
      af = AF_INET6;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2644
      /* Accept [] around IPv6 address - see RFC 5952 */
2645
      if(connect_to[0] == '[' and address[-1] == ']')
2646
	{
2647
	  connect_to++;
2648
	  address[-1] = '\0';
2649
	}
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2650
    } else {
2651
      af = AF_INET;
2652
    }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2653
    address = connect_to;
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2654
    
2655
    if(quit_now){
2656
      goto end;
2657
    }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2658
    
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
2659
    while(not quit_now){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2660
      ret = start_mandos_communication(address, port, if_index, af,
2661
				       &mc);
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
2662
      if(quit_now or ret == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2663
	break;
2664
      }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2665
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2666
	fprintf_plus(stderr, "Retrying in %d seconds\n",
2667
		     (int)retry_interval);
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2668
      }
237.7.168 by Teddy Hogeborn
* plugin-runner.c (main): Bug fix; do not ignore return value of
2669
      sleep((unsigned int)retry_interval);
237.7.40 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
2670
    }
2671
    
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
2672
    if(not quit_now){
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2673
      exitcode = EXIT_SUCCESS;
2674
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2675
    
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2676
    goto end;
2677
  }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2678
  
2679
  if(quit_now){
2680
    goto end;
2681
  }
2682
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2683
  {
2684
    AvahiServerConfig config;
2685
    /* Do not publish any local Zeroconf records */
2686
    avahi_server_config_init(&config);
2687
    config.publish_hinfo = 0;
2688
    config.publish_addresses = 0;
2689
    config.publish_workstation = 0;
2690
    config.publish_domain = 0;
2691
    
2692
    /* Allocate a new server */
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
2693
    mc.server = avahi_server_new(avahi_simple_poll_get(simple_poll),
2694
				 &config, NULL, NULL, &ret_errno);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2695
    
2696
    /* Free the Avahi configuration data */
2697
    avahi_server_config_free(&config);
2698
  }
2699
  
2700
  /* Check if creating the Avahi server object succeeded */
2701
  if(mc.server == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2702
    fprintf_plus(stderr, "Failed to create Avahi server: %s\n",
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2703
		 avahi_strerror(ret_errno));
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2704
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2705
    goto end;
2706
  }
2707
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2708
  if(quit_now){
2709
    goto end;
2710
  }
2711
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2712
  /* Create the Avahi service browser */
2713
  sb = avahi_s_service_browser_new(mc.server, if_index,
237.2.76 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
2714
				   AVAHI_PROTO_UNSPEC, "_mandos._tcp",
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2715
				   NULL, 0, browse_callback,
2716
				   (void *)&mc);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2717
  if(sb == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2718
    fprintf_plus(stderr, "Failed to create service browser: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2719
		 avahi_strerror(avahi_server_errno(mc.server)));
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2720
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2721
    goto end;
2722
  }
237.2.70 by Teddy Hogeborn
Merge from Björn:
2723
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2724
  if(quit_now){
2725
    goto end;
2726
  }
2727
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2728
  /* Run the main loop */
2729
  
2730
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2731
    fprintf_plus(stderr, "Starting Avahi loop search\n");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2732
  }
237.7.235 by Teddy Hogeborn
White space fix only.
2733
  
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
2734
  ret = avahi_loop_with_timeout(simple_poll,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2735
				(int)(retry_interval * 1000), &mc);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2736
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2737
    fprintf_plus(stderr, "avahi_loop_with_timeout exited %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2738
		 (ret == 0) ? "successfully" : "with error");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2739
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2740
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
2741
 end:
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2742
  
2743
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2744
    fprintf_plus(stderr, "%s exiting\n", argv[0]);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2745
  }
2746
  
2747
  /* Cleanup things */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2748
  free(mc.interfaces);
2749
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2750
  if(sb != NULL)
2751
    avahi_s_service_browser_free(sb);
2752
  
2753
  if(mc.server != NULL)
2754
    avahi_server_free(mc.server);
2755
  
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
2756
  if(simple_poll != NULL)
2757
    avahi_simple_poll_free(simple_poll);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2758
  
2759
  if(gnutls_initialized){
2760
    gnutls_certificate_free_credentials(mc.cred);
2761
    gnutls_global_deinit();
2762
    gnutls_dh_params_deinit(mc.dh_params);
2763
  }
2764
  
2765
  if(gpgme_initialized){
2766
    gpgme_release(mc.ctx);
2767
  }
237.16.12 by Teddy Hogeborn
* plugins.d/mandos-client.c (runnable_hook): Add debug output.
2768
  
237.7.33 by Teddy Hogeborn
Merge from Björn.
2769
  /* Cleans up the circular linked list of Mandos servers the client
2770
     has seen */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2771
  if(mc.current_server != NULL){
2772
    mc.current_server->prev->next = NULL;
2773
    while(mc.current_server != NULL){
2774
      server *next = mc.current_server->next;
237.7.262 by Teddy Hogeborn
mandos-client: Fix mem free bug.
2775
#ifdef __GNUC__
2776
#pragma GCC diagnostic push
2777
#pragma GCC diagnostic ignored "-Wcast-qual"
2778
#endif
2779
      free((char *)(mc.current_server->ip));
2780
#ifdef __GNUC__
2781
#pragma GCC diagnostic pop
2782
#endif
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2783
      free(mc.current_server);
2784
      mc.current_server = next;
2785
    }
2786
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2787
  
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2788
  /* Re-raise privileges */
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2789
  {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2790
    ret_errno = raise_privileges();
2791
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2792
      errno = ret_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2793
      perror_plus("Failed to raise privileges");
2794
    } else {
2795
      
2796
      /* Run network hooks */
2797
      run_network_hooks("stop", interfaces_hooks != NULL ?
2798
			interfaces_hooks : "", delay);
2799
      
2800
      /* Take down the network interfaces which were brought up */
2801
      {
2802
	char *interface = NULL;
2803
	while((interface=argz_next(interfaces_to_take_down,
2804
				   interfaces_to_take_down_size,
2805
				   interface))){
2806
	  ret_errno = take_down_interface(interface);
2807
	  if(ret_errno != 0){
2808
	    errno = ret_errno;
2809
	    perror_plus("Failed to take down interface");
2810
	  }
2811
	}
2812
	if(debug and (interfaces_to_take_down == NULL)){
2813
	  fprintf_plus(stderr, "No interfaces needed to be taken"
2814
		       " down\n");
2815
	}
2816
      }
2817
    }
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2818
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2819
    ret_errno = lower_privileges_permanently();
2820
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2821
      errno = ret_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2822
      perror_plus("Failed to lower privileges permanently");
2823
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2824
  }
2825
  
2826
  free(interfaces_to_take_down);
2827
  free(interfaces_hooks);
237.2.113 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
2828
  
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2829
  /* Removes the GPGME temp directory and all files inside */
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2830
  if(tempdir != NULL){
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2831
    struct dirent **direntries = NULL;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2832
    int tempdir_fd = (int)TEMP_FAILURE_RETRY(open(tempdir, O_RDONLY
2833
						  | O_NOFOLLOW
2834
						  | O_DIRECTORY
2835
						  | O_PATH));
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
2836
    if(tempdir_fd == -1){
2837
      perror_plus("open");
2838
    } else {
237.7.243 by Teddy Hogeborn
Make mandos-client use more scandirat().
2839
#ifdef __GLIBC__
2840
#if __GLIBC_PREREQ(2, 15)
2841
      int numentries = scandirat(tempdir_fd, ".", &direntries,
2842
				 notdotentries, alphasort);
2843
#else  /* not __GLIBC_PREREQ(2, 15) */
2844
      int numentries = scandir(tempdir, &direntries, notdotentries,
2845
			       alphasort);
2846
#endif	/* not __GLIBC_PREREQ(2, 15) */
2847
#else	/* not __GLIBC__ */
2848
      int numentries = scandir(tempdir, &direntries, notdotentries,
2849
			       alphasort);
2850
#endif	/* not __GLIBC__ */
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2851
      if(numentries >= 0){
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
2852
	for(int i = 0; i < numentries; i++){
2853
	  ret = unlinkat(tempdir_fd, direntries[i]->d_name, 0);
2854
	  if(ret == -1){
2855
	    fprintf_plus(stderr, "unlinkat(open(\"%s\", O_RDONLY),"
2856
			 " \"%s\", 0): %s\n", tempdir,
2857
			 direntries[i]->d_name, strerror(errno));
2858
	  }
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2859
	  free(direntries[i]);
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
2860
	}
2861
	
2862
	/* need to clean even if 0 because man page doesn't specify */
2863
	free(direntries);
2864
	if(numentries == -1){
2865
	  perror_plus("scandir");
2866
	}
2867
	ret = rmdir(tempdir);
2868
	if(ret == -1 and errno != ENOENT){
2869
	  perror_plus("rmdir");
2870
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2871
      }
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
2872
      TEMP_FAILURE_RETRY(close(tempdir_fd));
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2873
    }
2874
  }
2875
  
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2876
  if(quit_now){
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2877
    sigemptyset(&old_sigterm_action.sa_mask);
2878
    old_sigterm_action.sa_handler = SIG_DFL;
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
2879
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
2880
					    &old_sigterm_action,
2881
					    NULL));
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2882
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2883
      perror_plus("sigaction");
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2884
    }
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
2885
    do {
2886
      ret = raise(signal_received);
2887
    } while(ret != 0 and errno == EINTR);
2888
    if(ret != 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2889
      perror_plus("raise");
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
2890
      abort();
2891
    }
2892
    TEMP_FAILURE_RETRY(pause());
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2893
  }
2894
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2895
  return exitcode;
13 by Björn Påhlsson
Added following support:
2896
}