Watt-32 tcp/ip  2.2 dev-rel.10
pcsarp.c
Go to the documentation of this file.
1 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "wattcp.h"
20 #include "strings.h"
21 #include "netaddr.h"
22 #include "misc.h"
23 #include "pcdbug.h"
24 #include "pcconfig.h"
25 #include "pctcp.h"
26 #include "pcsed.h"
27 #include "pcpkt.h"
28 #include "pcarp.h"
29 #include "pcsarp.h"
30 
31 
32 #if defined(USE_SECURE_ARP)
33 /*
34  * OpenSSL include path should be in %INCLUDE% or %C_INCLUDE_PATH%.
35  */
36 #include <openssl/dsa.h>
37 #include <openssl/sha.h>
38 #include <openssl/rand.h>
39 #include <openssl/bio.h>
40 #include <openssl/evp.h>
41 
42 #if defined(USE_DEBUG)
43  #define SARP_DEBUG(level, args) \
44  do { \
45  if (sarp_debug >= level) { \
46  (*_printf) args; \
47  fflush (stdout); \
48  } \
49  } while (0)
50 #else
51  #define SARP_DEBUG(args, level) ((void)0)
52 #endif
53 
54 struct host_list {
55  DWORD ip; /* on host order */
56  eth_address mac;
57  BOOL secure;
58  DSA *dsa;
59  struct host_list *next;
60  };
61 
62 static void (W32_CALL *prev_cfg_hook) (const char*, const char*);
63 static void W32_CALL sarp_parse (const char *name, const char *value);
64 
65 static char *ca_keyfile = NULL;
66 static char *priv_keyfile = NULL;
67 static int sarp_debug = 0;
68 
69 static struct host_list *known_hosts = NULL;
70 static struct host_list *secure_hosts = NULL;
71 
72 static int sarp_receive (const struct sarp_Packet *sarp);
73 static int sarp_transmit (struct sarp_Packet *sarp);
74 
79 int sarp_init (void)
80 {
81  const char *rand = getenv ("RANDFILE");
82 
83  prev_cfg_hook = usr_init;
84  usr_init = sarp_parse;
85  _sarp_recv_hook = sarp_receive;
86  _sarp_xmit_hook = sarp_transmit;
87 
88  if (rand && FILE_EXIST(rand))
89  RAND_load_file (rand, -1);
90  else SARP_DEBUG (0, ("Warning: No random seed file found\n"));
91  return (0);
92 }
93 
94 static int read_ca_keyfile (const char *value)
95 {
96  DSA *dsa;
97 
98  DSA_free (dsa);
99 }
100 
101 static int read_priv_keyfile (const char *value)
102 {
103  FILE *fil;
104 
105  ca_keyfile = strdup (value);
106  if (!ca_keyfile)
107  return (0);
108 
109  fil = fopen (ca_keyfile, "rt");
110  if (!fil)
111  return (0);
112 
113 #if 0
114  priv = d2i_RSAPrivateKey_fp (fil, NULL);
115 #endif
116  fclose (fil);
117  return (1);
118 }
119 
120 static BOOL crypto_load_sarp_file (const char *pem_file, DSA **dsa)
121 {
122  FILE *fil = fopen (pem_file, "rt");
123 
124  *dsa = d2i_DSAPublicKey (NULL, raw, len);
125 
126  if (!crypto_verify_sign(message,strlen(message),sig,siglen,*dsa))
127  {
128  SARP_DEBUG (0, ("%s has illegal signature\n", pem_file));
129  DSA_free (*dsa);
130  return (FALSE);
131  }
132 }
133 
134 /*
135  * Parse "SECURE_HOST" 'value' "<IP>, <MAC>, <public-key-file>"
136  */
137 static int set_secure_host (const char *value)
138 {
139  struct host_list *host;
140  char ip[16], mac[21], pem_file[256];
141  DWORD ip_addr;
142  DSA *dsa;
143 
144  if (sscanf(value,"%15[^,],%20[^,],%255[^\r\n]", ip, mac, pem_file) != 3)
145  return (0);
146 
147  ip_addr = _inet_addr (ip);
148  if (!ip_addr)
149  return (0);
150 
151  host = calloc (sizeof(*host), 1);
152  if (!host)
153  return (0);
154 
155  if (!_inet_atoeth(mac, &host->mac) ||
156  !crypto_load_sarp_file(pem_file, &dsa))
157  {
158  free (host);
159  return (0);
160  }
161 
162  host->secure = TRUE;
163  host->ip = ip_addr;
164  host->dsa = dsa;
165  host->next = secure_hosts;
166  secure_hosts = host;
167  return (1);
168 }
169 
170 /*
171  * Parse "KNOWN_HOST" 'value' "<IP>, <MAC>"
172  */
173 static int set_known_host (const char *value, int value_len)
174 {
175  struct host_list *host;
176  char ip[16], mac[21];
177 
178  if (sscanf(value,"%15[^,],%20[^\r\n]", ip, mac) != 2)
179  return (0);
180 
181  host = calloc (sizeof(*host), 1);
182  if (!host)
183  return (0);
184 
185  if (!_inet_atoeth (mac, &host->mac))
186  {
187  free (host);
188  return (0);
189  }
190 
191  host->secure = FALSE;
192  host->ip = _inet_addr (ip);
193  host->next = known_hosts;
194  known_hosts = host;
195  return (1);
196 }
197 
198 
202 static void W32_CALL sarp_parse (const char *name, const char *value)
203 {
204  static const struct config_table sarp_cfg[] = {
205  { "CA_KEY", ARG_FUNC, (void*)read_ca_keyfile },
206  { "PRIV_KEY", ARG_FUNC, (void*)read_priv_keyfile },
207  { "SECURE_HOST", ARG_FUNC, (void*)set_secure_host },
208  { "KNOWN_HOST", ARG_FUNC, (void*)set_known_host },
209  { NULL, 0, NULL }
210  };
211 
212  if (!parse_config_table(&sarp_cfg[0], "SEC_ARP.", name, value) &&
213  prev_cfg_hook)
214  (*prev_cfg_hook) (name, value);
215 }
216 
220 static __inline BOOL is_secure_host (DWORD ip)
221 {
222  const struct host_list *host;
223 
224  for (host = secure_hosts; host; host = host->next)
225  if (host->ip == ip)
226  return (host->dsa != NULL);
227  return (FALSE);
228 }
229 
233 static __inline BOOL is_known_host (DWORD ip)
234 {
235  const struct host_list *host;
236 
237  for (host = known_hosts; host; host = host->next)
238  if (host->ip == ip)
239  return (TRUE);
240  return (FALSE);
241 }
242 
243 static int make_auth_Header (struct sarp_Packet *sarp)
244 {
245  ARGSUSED (sarp);
246  return (0);
247 }
248 
249 /*
250  * Called from _arp_handler() after HW-type and protocol (IPv4) is
251  * verified. Must completely replace _arp_handler().
252  */
253 static int sarp_receive (const struct sarp_Packet *sarp)
254 {
255  DWORD src_ip = ntohl (sarp->arp.srcIPAddr);
256 
257  if (!is_secure_host(src_ip) && !is_known_host(src_ip))
258  return (0); /* drop it */
259 
261  return (1);
262 }
263 
264 /*
265  * Called from arp_send(). Add any authentication header as needed.
266  * Return total length of what's need to be transmitted.
267  */
268 static int sarp_transmit (struct sarp_Packet *sarp)
269 {
270  DWORD dst_ip = ntohl (sarp->arp.dstIPAddr);
271  WORD len = sizeof (sarp->arp);
272 
273  if (!is_secure_host(dst_ip))
274  return (len); /* send as-is */
275 
276  memset (&sarp->auth, 0, sizeof(sarp->auth));
277  len += make_auth_Header (sarp);
278  return (len);
279 }
280 
284 void _sarp_debug_dump (void)
285 {
286 }
287 #endif /* USE_SECURE_ARP */
int W32_CALL parse_config_table(const struct config_table *tab, const char *section, const char *name, const char *value)
Parse the config-table and if a match is found for ('section'+'.
Definition: pcconfig.c:379
call convertion function
Definition: tcp.h:434
void _sarp_debug_dump(void)
Secure-ARP debug dump.
Definition: pcsarp.c:284
static int sarp_receive(const struct sarp_Packet *sarp)
Definition: pcsarp.c:253
static __inline BOOL is_known_host(DWORD ip)
Check if host is among the known hosts.
Definition: pcsarp.c:233
Core definitions.
Definition: ip.h:67
DWORD W32_CALL _inet_addr(const char *s)
Convert a string into an IP-address.
Definition: netaddr.c:69
int sarp_init(void)
Application must call this before sock_init() so we don't link in OpenSSL libs by default...
Definition: pcsarp.c:79
const char * _inet_atoeth(const char *src, eth_address *p_eth)
Parse string "ether-addr, ip-addr".
Definition: netaddr.c:205
static const char *static void W32_CALL sarp_parse(const char *name, const char *value)
Parser for "SEC_ARP.xx" keywords in WATTCP.CFG (or SARP.CFG).
Definition: pcsarp.c:202
static __inline BOOL is_secure_host(DWORD ip)
Check if host should use secure ARP.
Definition: pcsarp.c:220