1 /* $OpenBSD: sysdep.c,v 1.34 2005/05/04 10:05:02 hshoexer Exp $ */
2 /* $EOM: sysdep.c,v 1.9 2000/12/04 04:46:35 angelos Exp $ */
3
4 /*
5 * Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 * This code was written under funding by Ericsson Radio Systems.
30 */
31
32 #include <sys/errno.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "sysdep.h"
41
42 #include "app.h"
43 #include "log.h"
44 #include "monitor.h"
45 #include "util.h"
46
47
48 /* Force communication on socket FD to go in the clear. */
49 int
sysdep_cleartext(int fd,int af)50 sysdep_cleartext(int fd, int af)
51 {
52 int level, sw;
53 struct {
54 int ip_proto; /* IP protocol */
55 int auth_level;
56 int esp_trans_level;
57 int esp_network_level;
58 int ipcomp_level;
59 } optsw[] = {
60 {
61 IPPROTO_IP,
62 IP_AUTH_LEVEL,
63 IP_ESP_TRANS_LEVEL,
64 IP_ESP_NETWORK_LEVEL,
65 #ifdef IP_IPCOMP_LEVEL
66 IP_IPCOMP_LEVEL
67 #else
68 0
69 #endif
70 }, {
71 IPPROTO_IPV6,
72 IPV6_AUTH_LEVEL,
73 IPV6_ESP_TRANS_LEVEL,
74 IPV6_ESP_NETWORK_LEVEL,
75 #ifdef IPV6_IPCOMP_LEVEL
76 IPV6_IPCOMP_LEVEL
77 #else
78 0
79 #endif
80 },
81 };
82
83 if (app_none)
84 return 0;
85
86 switch (af) {
87 case AF_INET:
88 sw = 0;
89 break;
90 case AF_INET6:
91 sw = 1;
92 break;
93 default:
94 log_print("sysdep_cleartext: unsupported protocol family %d", af);
95 return -1;
96 }
97
98 /*
99 * Need to bypass system security policy, so I can send and
100 * receive key management datagrams in the clear.
101 */
102 level = IPSEC_LEVEL_BYPASS;
103 if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].auth_level,
104 (char *) &level, sizeof level) == -1) {
105 log_error("sysdep_cleartext: "
106 "setsockopt (%d, %d, IP_AUTH_LEVEL, ...) failed", fd,
107 optsw[sw].ip_proto);
108 return -1;
109 }
110 if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].esp_trans_level,
111 (char *) &level, sizeof level) == -1) {
112 log_error("sysdep_cleartext: "
113 "setsockopt (%d, %d, IP_ESP_TRANS_LEVEL, ...) failed", fd,
114 optsw[sw].ip_proto);
115 return -1;
116 }
117 if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].esp_network_level,
118 (char *) &level, sizeof level) == -1) {
119 log_error("sysdep_cleartext: "
120 "setsockopt (%d, %d, IP_ESP_NETWORK_LEVEL, ...) failed", fd,
121 optsw[sw].ip_proto);
122 return -1;
123 }
124 if (optsw[sw].ipcomp_level &&
125 monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].ipcomp_level,
126 (char *) &level, sizeof level) == -1 &&
127 errno != ENOPROTOOPT) {
128 log_error("sysdep_cleartext: "
129 "setsockopt (%d, %d, IP_IPCOMP_LEVEL, ...) failed,", fd,
130 optsw[sw].ip_proto);
131 return -1;
132 }
133 return 0;
134 }
135