xref: /minix3/crypto/external/bsd/netpgp/dist/src/hkpclient/hkpc.c (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
1*ebfedea0SLionel Sambuc /*-
2*ebfedea0SLionel Sambuc  * Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
3*ebfedea0SLionel Sambuc  * All rights reserved.
4*ebfedea0SLionel Sambuc  *
5*ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
6*ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
7*ebfedea0SLionel Sambuc  * are met:
8*ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
9*ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
10*ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
11*ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
12*ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
13*ebfedea0SLionel Sambuc  *
14*ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15*ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*ebfedea0SLionel Sambuc  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*ebfedea0SLionel Sambuc  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18*ebfedea0SLionel Sambuc  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*ebfedea0SLionel Sambuc  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*ebfedea0SLionel Sambuc  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*ebfedea0SLionel Sambuc  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*ebfedea0SLionel Sambuc  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*ebfedea0SLionel Sambuc  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*ebfedea0SLionel Sambuc  */
25*ebfedea0SLionel Sambuc #include <sys/types.h>
26*ebfedea0SLionel Sambuc #include <sys/param.h>
27*ebfedea0SLionel Sambuc #include <sys/socket.h>
28*ebfedea0SLionel Sambuc 
29*ebfedea0SLionel Sambuc #include <netinet/in.h>
30*ebfedea0SLionel Sambuc 
31*ebfedea0SLionel Sambuc #include <errno.h>
32*ebfedea0SLionel Sambuc #include <inttypes.h>
33*ebfedea0SLionel Sambuc #include <netdb.h>
34*ebfedea0SLionel Sambuc #include <netpgp.h>
35*ebfedea0SLionel Sambuc #include <regex.h>
36*ebfedea0SLionel Sambuc #include <stdio.h>
37*ebfedea0SLionel Sambuc #include <stdlib.h>
38*ebfedea0SLionel Sambuc #include <string.h>
39*ebfedea0SLionel Sambuc #include <unistd.h>
40*ebfedea0SLionel Sambuc 
41*ebfedea0SLionel Sambuc #include "hkpc.h"
42*ebfedea0SLionel Sambuc 
43*ebfedea0SLionel Sambuc /* get a socket and connect it to the server */
44*ebfedea0SLionel Sambuc int
hkpc_connect(const char * hostname,const int port,const int fam)45*ebfedea0SLionel Sambuc hkpc_connect(const char *hostname, const int port, const int fam)
46*ebfedea0SLionel Sambuc {
47*ebfedea0SLionel Sambuc         struct addrinfo  hints;
48*ebfedea0SLionel Sambuc         struct addrinfo *res;
49*ebfedea0SLionel Sambuc         char             portstr[32];
50*ebfedea0SLionel Sambuc 	int		 sock;
51*ebfedea0SLionel Sambuc         int              rc = 0;
52*ebfedea0SLionel Sambuc 
53*ebfedea0SLionel Sambuc         (void) memset(&hints, 0, sizeof(hints));
54*ebfedea0SLionel Sambuc         hints.ai_family = (fam == 4) ? PF_INET : PF_INET6;
55*ebfedea0SLionel Sambuc         hints.ai_socktype = SOCK_STREAM;
56*ebfedea0SLionel Sambuc         (void) snprintf(portstr, sizeof(portstr), "%d", port);
57*ebfedea0SLionel Sambuc         if ((rc = getaddrinfo(hostname, portstr, &hints, &res)) != 0) {
58*ebfedea0SLionel Sambuc                 hints.ai_flags = 0;
59*ebfedea0SLionel Sambuc                 if ((rc = getaddrinfo(hostname, "hkp", &hints, &res)) != 0) {
60*ebfedea0SLionel Sambuc                         (void) fprintf(stderr, "getaddrinfo: %s",
61*ebfedea0SLionel Sambuc 					gai_strerror(rc));
62*ebfedea0SLionel Sambuc                         return -1;
63*ebfedea0SLionel Sambuc                 }
64*ebfedea0SLionel Sambuc         }
65*ebfedea0SLionel Sambuc 	if ((sock = socket((fam == 4) ? AF_INET : AF_INET6, SOCK_STREAM, 0)) < 0) {
66*ebfedea0SLionel Sambuc                 (void) fprintf(stderr, "socket failed %d\n", errno);
67*ebfedea0SLionel Sambuc                 freeaddrinfo(res);
68*ebfedea0SLionel Sambuc                 return -1;
69*ebfedea0SLionel Sambuc 	}
70*ebfedea0SLionel Sambuc         if ((rc = connect(sock, res->ai_addr, res->ai_addrlen)) < 0) {
71*ebfedea0SLionel Sambuc                 (void) fprintf(stderr, "connect failed %d\n", errno);
72*ebfedea0SLionel Sambuc                 freeaddrinfo(res);
73*ebfedea0SLionel Sambuc                 return -1;
74*ebfedea0SLionel Sambuc         }
75*ebfedea0SLionel Sambuc         freeaddrinfo(res);
76*ebfedea0SLionel Sambuc         if (rc < 0) {
77*ebfedea0SLionel Sambuc                 (void) fprintf(stderr, "connect() to %s:%d failed (rc %d)\n",
78*ebfedea0SLionel Sambuc 				hostname, port, rc);
79*ebfedea0SLionel Sambuc         }
80*ebfedea0SLionel Sambuc         return sock;
81*ebfedea0SLionel Sambuc }
82*ebfedea0SLionel Sambuc 
83*ebfedea0SLionel Sambuc #define MB(x)	((x) * 1024 * 1024)
84*ebfedea0SLionel Sambuc 
85*ebfedea0SLionel Sambuc /* get required info from the server */
86*ebfedea0SLionel Sambuc int
hkpc_get(char ** info,const char * server,const int port,const int family,const char * type,const char * userid)87*ebfedea0SLionel Sambuc hkpc_get(char **info, const char *server, const int port, const int family, const char *type, const char *userid)
88*ebfedea0SLionel Sambuc {
89*ebfedea0SLionel Sambuc 	char	buf[MB(1)];
90*ebfedea0SLionel Sambuc 	int	sock;
91*ebfedea0SLionel Sambuc 	int	cc;
92*ebfedea0SLionel Sambuc 	int	rc;
93*ebfedea0SLionel Sambuc 
94*ebfedea0SLionel Sambuc 	if ((sock = hkpc_connect(server, port, family)) < 0) {
95*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "hkpc_get: can't connect to server '%s'\n", server);
96*ebfedea0SLionel Sambuc 		return -1;
97*ebfedea0SLionel Sambuc 	}
98*ebfedea0SLionel Sambuc 	cc = snprintf(buf, sizeof(buf), "GET /pks/lookup?op=%s&search=%s&options=json", type, userid);
99*ebfedea0SLionel Sambuc 	if (write(sock, buf, cc) != cc) {
100*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "hkpc_get: short write\n");
101*ebfedea0SLionel Sambuc 		return -1;
102*ebfedea0SLionel Sambuc 	}
103*ebfedea0SLionel Sambuc 	for (cc = 0 ; (rc = read(sock, &buf[cc], sizeof(buf) - cc)) > 0 ; cc += rc) {
104*ebfedea0SLionel Sambuc 	}
105*ebfedea0SLionel Sambuc 	*info = calloc(1, cc + 1);
106*ebfedea0SLionel Sambuc 	(void) memcpy(*info, buf, cc);
107*ebfedea0SLionel Sambuc 	(*info)[cc] = 0x0;
108*ebfedea0SLionel Sambuc 	(void) close(sock);
109*ebfedea0SLionel Sambuc 	return cc;
110*ebfedea0SLionel Sambuc }
111*ebfedea0SLionel Sambuc 
112*ebfedea0SLionel Sambuc /* jump over http header, then pass the json to the key-formatting function */
113*ebfedea0SLionel Sambuc int
hkpc_print_key(FILE * fp,const char * op,const char * res)114*ebfedea0SLionel Sambuc hkpc_print_key(FILE *fp, const char *op, const char *res)
115*ebfedea0SLionel Sambuc {
116*ebfedea0SLionel Sambuc 	static regex_t	text;
117*ebfedea0SLionel Sambuc 	static int	compiled;
118*ebfedea0SLionel Sambuc 	regmatch_t	matches[10];
119*ebfedea0SLionel Sambuc 	int	 	ret;
120*ebfedea0SLionel Sambuc 
121*ebfedea0SLionel Sambuc 	if (!compiled) {
122*ebfedea0SLionel Sambuc 		compiled = 1;
123*ebfedea0SLionel Sambuc 		(void) regcomp(&text, "\r\n\r\n", REG_EXTENDED);
124*ebfedea0SLionel Sambuc 	}
125*ebfedea0SLionel Sambuc 	if (regexec(&text, res, 10, matches, 0) != 0) {
126*ebfedea0SLionel Sambuc 		return 0;
127*ebfedea0SLionel Sambuc 	}
128*ebfedea0SLionel Sambuc 	if (strcmp(op, "index") == 0 || strcmp(op, "vindex") == 0) {
129*ebfedea0SLionel Sambuc 		ret = netpgp_format_json(fp, &res[(int)matches[0].rm_eo], 1);
130*ebfedea0SLionel Sambuc 	} else {
131*ebfedea0SLionel Sambuc 		(void) fprintf(fp, "%s\n", &res[(int)matches[0].rm_eo]);
132*ebfedea0SLionel Sambuc 		ret = 1;
133*ebfedea0SLionel Sambuc 	}
134*ebfedea0SLionel Sambuc 	return ret;
135*ebfedea0SLionel Sambuc }
136