/opensource.apple.com/source/fetchmail/fetchmail-7/fetchmail/socket.c
C | 1063 lines | 896 code | 109 blank | 58 comment | 74 complexity | 6d1d5f475eb9c2cfe063f4cbf5f19e74 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, GPL-2.0, BSD-3-Clause, GPL-3.0, MPL-2.0, LGPL-2.0, LGPL-2.1, CC-BY-SA-3.0, IPL-1.0, ISC, AGPL-1.0, AGPL-3.0, JSON, Apache-2.0, 0BSD
Large files files are truncated, but you can click here to view the full file
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <title>socket.c</title>
- <style type="text/css">
- .enscript-comment { font-style: italic; color: rgb(178,34,34); }
- .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
- .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
- .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
- .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
- .enscript-string { font-weight: bold; color: rgb(188,143,143); }
- .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
- .enscript-type { font-weight: bold; color: rgb(34,139,34); }
- .enscript-highlight { text-decoration: underline; color: 0; }
- </style>
- </head>
- <body id="top">
- <h1 style="margin:8px;" id="f1">socket.c <span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
- <hr/>
- <div></div>
- <pre>
- <span class="enscript-comment">/*
- * socket.c -- socket library functions
- *
- * Copyright 1998 by Eric S. Raymond.
- * For license terms, see the file COPYING in this directory.
- */</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"config.h"</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><stdio.h></span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><errno.h></span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><string.h></span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><ctype.h></span> <span class="enscript-comment">/* isspace() */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_MEMORY_H</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><memory.h></span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_MEMORY_H */</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><sys/types.h></span>
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_NET_SOCKET_H</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><sys/socket.h></span>
- #<span class="enscript-reference">else</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><net/socket.h></span>
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><sys/un.h></span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><netinet/in.h></span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_ARPA_INET_H</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><arpa/inet.h></span>
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><netdb.h></span>
- #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">STDC_HEADERS</span>)
- #<span class="enscript-reference">include</span> <span class="enscript-string"><stdlib.h></span>
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_UNISTD_H</span>)
- #<span class="enscript-reference">include</span> <span class="enscript-string"><unistd.h></span>
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_STDARG_H</span>)
- #<span class="enscript-reference">include</span> <span class="enscript-string"><stdarg.h></span>
- #<span class="enscript-reference">else</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><varargs.h></span>
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"socket.h"</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"fetchmail.h"</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"i18n.h"</span>
- <span class="enscript-comment">/* Defines to allow BeOS and Cygwin to play nice... */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
- <span class="enscript-type">static</span> <span class="enscript-type">char</span> peeked;
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_close</span>(a) closesocket(a)
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_write</span>(a,b,c) send(a,b,c,0)
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_peek</span>(a,b,c) recv(a,b,c,0)
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_read</span>(a,b,c) recv(a,b,c,0)
- #<span class="enscript-reference">else</span>
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_close</span>(a) close(a)
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_write</span>(a,b,c) write(a,b,c)
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_peek</span>(a,b,c) recv(a,b,c, MSG_PEEK)
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__CYGWIN__</span>
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_read</span>(a,b,c) cygwin_read(a,b,c)
- <span class="enscript-type">static</span> ssize_t <span class="enscript-function-name">cygwin_read</span>(<span class="enscript-type">int</span> sock, <span class="enscript-type">void</span> *buf, size_t count);
- #<span class="enscript-reference">else</span> <span class="enscript-comment">/* ! __CYGWIN__ */</span>
- #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_read</span>(a,b,c) read(a,b,c)
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* __CYGWIN__ */</span>
- #<span class="enscript-reference">endif</span>
- <span class="enscript-comment">/* We need to define h_errno only if it is not already */</span>
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">h_errno</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_RES_SEARCH</span>
- <span class="enscript-comment">/* some versions of FreeBSD should declare this but don't */</span>
- <span class="enscript-type">extern</span> <span class="enscript-type">int</span> h_errno;
- #<span class="enscript-reference">else</span>
- <span class="enscript-comment">/* pretend we have h_errno to avoid some #ifdef's later */</span>
- <span class="enscript-type">static</span> <span class="enscript-type">int</span> h_errno;
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* ndef h_errno */</span>
- <span class="enscript-type">extern</span> <span class="enscript-type">int</span> mailserver_socket_temp; <span class="enscript-comment">/* Socket to close if connect timeout */</span>
- #<span class="enscript-reference">if</span> <span class="enscript-variable-name">NET_SECURITY</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><net/security.h></span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* NET_SECURITY */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKETPAIR</span>
- <span class="enscript-type">char</span> *<span class="enscript-type">const</span> *<span class="enscript-function-name">parse_plugin</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *plugin, <span class="enscript-type">const</span> <span class="enscript-type">char</span> *host, <span class="enscript-type">const</span> <span class="enscript-type">char</span> *service)
- { <span class="enscript-type">const</span> <span class="enscript-type">char</span> **argvec;
- <span class="enscript-type">const</span> <span class="enscript-type">char</span> *c, *p;
- <span class="enscript-type">char</span> *cp, *plugin_copy;
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> plugin_copy_len;
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> plugin_offset = 0, plugin_copy_offset = 0;
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> i, s = 2 * <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">char</span>*), host_count = 0, service_count = 0;
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> plugin_len = strlen(plugin);
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> host_len = strlen(host);
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> service_len = strlen(service);
- <span class="enscript-keyword">for</span> (c = p = plugin; *c; c++)
- { <span class="enscript-keyword">if</span> (isspace(*c) && !isspace(*p))
- s += <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">char</span>*);
- <span class="enscript-keyword">if</span> (*p == <span class="enscript-string">'%'</span> && *c == <span class="enscript-string">'h'</span>)
- host_count++;
- <span class="enscript-keyword">if</span> (*p == <span class="enscript-string">'%'</span> && *c == <span class="enscript-string">'p'</span>)
- service_count++;
- p = c;
- }
- plugin_copy_len = plugin_len + host_len * host_count + service_len * service_count;
- plugin_copy = malloc(plugin_copy_len + 1);
- <span class="enscript-keyword">if</span> (!plugin_copy)
- {
- report(stderr, GT_(<span class="enscript-string">"fetchmail: malloc failed\n"</span>));
- <span class="enscript-keyword">return</span> NULL;
- }
- <span class="enscript-keyword">while</span> (plugin_copy_offset < plugin_copy_len)
- { <span class="enscript-keyword">if</span> ((plugin[plugin_offset] == <span class="enscript-string">'%'</span>) && (plugin[plugin_offset + 1] == <span class="enscript-string">'h'</span>))
- { strcpy(plugin_copy + plugin_copy_offset, host);
- plugin_offset += 2;
- plugin_copy_offset += host_len;
- }
- <span class="enscript-keyword">else</span> <span class="enscript-keyword">if</span> ((plugin[plugin_offset] == <span class="enscript-string">'%'</span>) && (plugin[plugin_offset + 1] == <span class="enscript-string">'p'</span>))
- { strcpy(plugin_copy + plugin_copy_offset, service);
- plugin_offset += 2;
- plugin_copy_offset += service_len;
- }
- <span class="enscript-keyword">else</span>
- { plugin_copy[plugin_copy_offset] = plugin[plugin_offset];
- plugin_offset++;
- plugin_copy_offset++;
- }
- }
- plugin_copy[plugin_copy_len] = 0;
- argvec = malloc(s);
- <span class="enscript-keyword">if</span> (!argvec)
- {
- report(stderr, GT_(<span class="enscript-string">"fetchmail: malloc failed\n"</span>));
- <span class="enscript-keyword">return</span> NULL;
- }
- memset(argvec, 0, s);
- <span class="enscript-keyword">for</span> (c = p = plugin_copy, i = 0; *c; c++)
- { <span class="enscript-keyword">if</span> ((!isspace(*c)) && (c == p ? 1 : isspace(*p))) {
- argvec[i] = c;
- i++;
- }
- p = c;
- }
- <span class="enscript-keyword">for</span> (cp = plugin_copy; *cp; cp++)
- { <span class="enscript-keyword">if</span> (isspace(*cp))
- *cp = 0;
- }
- <span class="enscript-keyword">return</span> (<span class="enscript-type">char</span> *<span class="enscript-type">const</span>*)argvec;
- }
- <span class="enscript-type">static</span> <span class="enscript-type">int</span> <span class="enscript-function-name">handle_plugin</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *host,
- <span class="enscript-type">const</span> <span class="enscript-type">char</span> *service, <span class="enscript-type">const</span> <span class="enscript-type">char</span> *plugin)
- <span class="enscript-comment">/* get a socket mediated through a given external command */</span>
- {
- <span class="enscript-type">int</span> fds[2];
- <span class="enscript-type">char</span> *<span class="enscript-type">const</span> *argvec;
- <span class="enscript-comment">/*
- * The author of this code, Felix von Leitner <<a href="mailto:felix@convergence.de">felix@convergence.de</a>>, says:
- * he chose socketpair() instead of pipe() because socketpair creates
- * bidirectional sockets while allegedly some pipe() implementations don't.
- */</span>
- <span class="enscript-keyword">if</span> (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
- {
- report(stderr, GT_(<span class="enscript-string">"fetchmail: socketpair failed\n"</span>));
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-keyword">switch</span> (fork()) {
- <span class="enscript-keyword">case</span> <span class="enscript-reference">-1</span>:
- <span class="enscript-comment">/* error */</span>
- report(stderr, GT_(<span class="enscript-string">"fetchmail: fork failed\n"</span>));
- <span class="enscript-keyword">return</span> -1;
- <span class="enscript-keyword">break</span>;
- <span class="enscript-keyword">case</span> <span class="enscript-reference">0</span>: <span class="enscript-comment">/* child */</span>
- <span class="enscript-comment">/* fds[1] is the parent's end; close it for proper EOF
- ** detection */</span>
- (<span class="enscript-type">void</span>) close(fds[1]);
- <span class="enscript-keyword">if</span> ( (dup2(fds[0],0) == -1) || (dup2(fds[0],1) == -1) ) {
- report(stderr, GT_(<span class="enscript-string">"dup2 failed\n"</span>));
- exit(1);
- }
- <span class="enscript-comment">/* fds[0] is now connected to 0 and 1; close it */</span>
- (<span class="enscript-type">void</span>) close(fds[0]);
- <span class="enscript-keyword">if</span> (outlevel >= O_VERBOSE)
- report(stderr, GT_(<span class="enscript-string">"running %s (host %s service %s)\n"</span>), plugin, host, service);
- argvec = parse_plugin(plugin,host,service);
- execvp(*argvec, argvec);
- report(stderr, GT_(<span class="enscript-string">"execvp(%s) failed\n"</span>), *argvec);
- exit(0);
- <span class="enscript-keyword">break</span>;
- <span class="enscript-reference">default</span>: <span class="enscript-comment">/* parent */</span>
- <span class="enscript-comment">/* NOP */</span>
- <span class="enscript-keyword">break</span>;
- }
- <span class="enscript-comment">/* fds[0] is the child's end; close it for proper EOF detection */</span>
- (<span class="enscript-type">void</span>) close(fds[0]);
- <span class="enscript-keyword">return</span> fds[1];
- }
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SOCKETPAIR */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__UNUSED__</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string"><sys/time.h></span>
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockCheckOpen</span>(<span class="enscript-type">int</span> fd)
- <span class="enscript-comment">/* poll given socket; is it selectable? */</span>
- {
- fd_set r, w, e;
- <span class="enscript-type">int</span> rt;
- <span class="enscript-type">struct</span> timeval tv;
-
- <span class="enscript-keyword">for</span> (;;)
- {
- FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
- FD_SET(fd, &e);
-
- tv.tv_sec = 0; tv.tv_usec = 0;
- rt = select(fd+1, &r, &w, &e, &tv);
- <span class="enscript-keyword">if</span> (rt == -1 && (errno != EAGAIN && errno != EINTR))
- <span class="enscript-keyword">return</span> 0;
- <span class="enscript-keyword">if</span> (rt != -1)
- <span class="enscript-keyword">return</span> 1;
- }
- }
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* __UNUSED__ */</span>
- <span class="enscript-type">int</span> <span class="enscript-function-name">UnixOpen</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *path)
- {
- <span class="enscript-type">int</span> sock = -1;
- <span class="enscript-type">struct</span> sockaddr_un ad;
- memset(&ad, 0, <span class="enscript-keyword">sizeof</span>(ad));
- ad.sun_family = AF_UNIX;
- strncpy(ad.sun_path, path, <span class="enscript-keyword">sizeof</span>(ad.sun_path)-1);
- sock = socket( AF_UNIX, SOCK_STREAM, 0 );
- <span class="enscript-keyword">if</span> (sock < 0)
- {
- h_errno = 0;
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout
- * because it can be closed.
- */</span>
- mailserver_socket_temp = sock;
-
- <span class="enscript-keyword">if</span> (connect(sock, (<span class="enscript-type">struct</span> sockaddr *) &ad, <span class="enscript-keyword">sizeof</span>(ad)) < 0)
- {
- <span class="enscript-type">int</span> olderr = errno;
- fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
- h_errno = 0;
- errno = olderr;
- sock = -1;
- }
-
- <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
- mailserver_socket_temp = -1;
- <span class="enscript-keyword">return</span> sock;
- }
- #<span class="enscript-reference">if</span> <span class="enscript-variable-name">INET6_ENABLE</span>
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockOpen</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *host, <span class="enscript-type">const</span> <span class="enscript-type">char</span> *service, <span class="enscript-type">const</span> <span class="enscript-type">char</span> *options,
- <span class="enscript-type">const</span> <span class="enscript-type">char</span> *plugin)
- {
- <span class="enscript-type">struct</span> addrinfo *ai, *ai0, req;
- <span class="enscript-type">int</span> i;
- #<span class="enscript-reference">if</span> <span class="enscript-variable-name">NET_SECURITY</span>
- <span class="enscript-type">void</span> *request = NULL;
- <span class="enscript-type">int</span> requestlen;
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* NET_SECURITY */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKETPAIR</span>
- <span class="enscript-keyword">if</span> (plugin)
- <span class="enscript-keyword">return</span> handle_plugin(host,service,plugin);
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SOCKETPAIR */</span>
- memset(&req, 0, <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">struct</span> addrinfo));
- req.ai_socktype = SOCK_STREAM;
- <span class="enscript-keyword">if</span> (getaddrinfo(host, service, &req, &ai0)) {
- report(stderr, GT_(<span class="enscript-string">"fetchmail: getaddrinfo(%s.%s)\n"</span>), host,service);
- <span class="enscript-keyword">return</span> -1;
- }
- #<span class="enscript-reference">if</span> <span class="enscript-variable-name">NET_SECURITY</span>
- <span class="enscript-keyword">if</span> (!options)
- requestlen = 0;
- <span class="enscript-keyword">else</span>
- <span class="enscript-keyword">if</span> (net_security_strtorequest((<span class="enscript-type">char</span> *)options, &request, &requestlen))
- <span class="enscript-keyword">goto</span> <span class="enscript-reference">ret</span>;
- i = inner_connect(ai0, request, requestlen, NULL, NULL, <span class="enscript-string">"fetchmail"</span>, NULL);
- <span class="enscript-keyword">if</span> (request)
- free(request);
- <span class="enscript-reference">ret</span>:
- #<span class="enscript-reference">else</span> <span class="enscript-comment">/* NET_SECURITY */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_INNER_CONNECT</span>
- i = inner_connect(ai0, NULL, 0, NULL, NULL, <span class="enscript-string">"fetchmail"</span>, NULL);
- <span class="enscript-keyword">if</span> (i >= 0)
- <span class="enscript-keyword">break</span>;
- #<span class="enscript-reference">else</span>
- i = -1;
- <span class="enscript-keyword">for</span> (ai = ai0; ai; ai = ai->ai_next) {
- i = socket(ai->ai_family, ai->ai_socktype, 0);
- <span class="enscript-keyword">if</span> (i < 0)
- <span class="enscript-keyword">continue</span>;
- <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout
- * because it can be closed.
- */</span>
- mailserver_socket_temp = i;
- <span class="enscript-keyword">if</span> (connect(i, (<span class="enscript-type">struct</span> sockaddr *) ai->ai_addr, ai->ai_addrlen) < 0) {
- fm_close(i);
- i = -1;
- <span class="enscript-keyword">continue</span>;
- }
-
- <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
- mailserver_socket_temp = -1;
-
- <span class="enscript-keyword">break</span>;
- }
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* NET_SECURITY */</span>
- freeaddrinfo(ai0);
- <span class="enscript-keyword">return</span> i;
- }
- #<span class="enscript-reference">else</span> <span class="enscript-comment">/* INET6_ENABLE */</span>
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">INADDR_NONE</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">INADDR_BROADCAST</span>
- #<span class="enscript-reference">define</span> <span class="enscript-variable-name">INADDR_NONE</span> INADDR_BROADCAST
- #<span class="enscript-reference">else</span>
- #<span class="enscript-reference">define</span> <span class="enscript-variable-name">INADDR_NONE</span> -1
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockOpen</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *host, <span class="enscript-type">int</span> clientPort, <span class="enscript-type">const</span> <span class="enscript-type">char</span> *options,
- <span class="enscript-type">const</span> <span class="enscript-type">char</span> *plugin)
- {
- <span class="enscript-type">int</span> sock = -1; <span class="enscript-comment">/* pacify -Wall */</span>
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
- <span class="enscript-type">unsigned</span> <span class="enscript-type">long</span> inaddr;
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
- <span class="enscript-type">struct</span> sockaddr_in ad, **pptr;
- <span class="enscript-type">struct</span> hostent *hp;
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKETPAIR</span>
- <span class="enscript-keyword">if</span> (plugin) {
- <span class="enscript-type">char</span> buf[10];
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SNPRINTF</span>
- snprintf(buf, <span class="enscript-keyword">sizeof</span>(buf), <span class="enscript-comment">/* Yeah, paranoic. So what? :P */</span>
- #<span class="enscript-reference">else</span>
- sprintf(buf,
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SNPRINTF */</span>
- <span class="enscript-string">"%d"</span>,clientPort);
- <span class="enscript-keyword">return</span> handle_plugin(host,buf,plugin);
- }
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SOCKETPAIR */</span>
- memset(&ad, 0, <span class="enscript-keyword">sizeof</span>(ad));
- ad.sin_family = AF_INET;
- <span class="enscript-comment">/* we'll accept a quad address */</span>
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
- inaddr = inet_addr((<span class="enscript-type">char</span>*)host);
- <span class="enscript-keyword">if</span> (inaddr != INADDR_NONE)
- {
- memcpy(&ad.sin_addr, &inaddr, <span class="enscript-keyword">sizeof</span>(inaddr));
- #<span class="enscript-reference">else</span>
- <span class="enscript-keyword">if</span> (inet_aton(host, &ad.sin_addr))
- {
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
- ad.sin_port = htons(clientPort);
- sock = socket(AF_INET, SOCK_STREAM, 0);
- <span class="enscript-keyword">if</span> (sock < 0)
- {
- h_errno = 0;
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout because
- * it can be closed
- */</span>
- mailserver_socket_temp = sock;
-
- <span class="enscript-keyword">if</span> (connect(sock, (<span class="enscript-type">struct</span> sockaddr *) &ad, <span class="enscript-keyword">sizeof</span>(ad)) < 0)
- {
- <span class="enscript-type">int</span> olderr = errno;
- fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
- h_errno = 0;
- errno = olderr;
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
- mailserver_socket_temp = -1;
-
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
- }
- #<span class="enscript-reference">else</span>
- }
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
- <span class="enscript-keyword">else</span> {
- hp = gethostbyname((<span class="enscript-type">char</span>*)host);
- <span class="enscript-keyword">if</span> (hp == NULL)
- {
- errno = 0;
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/*
- * Add a check to make sure the address has a valid IPv4 or IPv6
- * length. This prevents buffer spamming by a broken DNS.
- */</span>
- <span class="enscript-keyword">if</span>(hp->h_length != 4 && hp->h_length != 8)
- {
- h_errno = errno = 0;
- report(stderr,
- GT_(<span class="enscript-string">"fetchmail: illegal address length received for host %s\n"</span>),host);
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/*
- * Try all addresses of a possibly multihomed host until we get
- * a successful connect or until we run out of addresses.
- */</span>
- pptr = (<span class="enscript-type">struct</span> sockaddr_in **)hp->h_addr_list;
- <span class="enscript-keyword">for</span>(; *pptr != NULL; pptr++)
- {
- sock = socket(AF_INET, SOCK_STREAM, 0);
- <span class="enscript-keyword">if</span> (sock < 0)
- {
- h_errno = 0;
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout because
- * it can be closed
- */</span>
- mailserver_socket_temp = sock;
-
- ad.sin_port = htons(clientPort);
- memcpy(&ad.sin_addr, *pptr, <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">struct</span> in_addr));
- <span class="enscript-keyword">if</span> (connect(sock, (<span class="enscript-type">struct</span> sockaddr *) &ad, <span class="enscript-keyword">sizeof</span>(ad)) == 0) {
- <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
- mailserver_socket_temp = -1;
- <span class="enscript-keyword">break</span>; <span class="enscript-comment">/* success */</span>
- }
- fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
- memset(&ad, 0, <span class="enscript-keyword">sizeof</span>(ad));
- ad.sin_family = AF_INET;
- }
- <span class="enscript-keyword">if</span>(*pptr == NULL)
- {
- <span class="enscript-type">int</span> olderr = errno;
- fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
- h_errno = 0;
- errno = olderr;
- <span class="enscript-keyword">return</span> -1;
- }
- }
- <span class="enscript-keyword">return</span>(sock);
- }
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* INET6_ENABLE */</span>
- #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_STDARG_H</span>)
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockPrintf</span>(<span class="enscript-type">int</span> sock, <span class="enscript-type">const</span> <span class="enscript-type">char</span>* format, ...)
- {
- #<span class="enscript-reference">else</span>
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockPrintf</span>(sock,format,va_alist)
- <span class="enscript-type">int</span> sock;
- <span class="enscript-type">char</span> *format;
- va_dcl {
- #<span class="enscript-reference">endif</span>
- va_list ap;
- <span class="enscript-type">char</span> buf[8192];
- #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_STDARG_H</span>)
- va_start(ap, format) ;
- #<span class="enscript-reference">else</span>
- va_start(ap);
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_VSNPRINTF</span>
- vsnprintf(buf, <span class="enscript-keyword">sizeof</span>(buf), format, ap);
- #<span class="enscript-reference">else</span>
- vsprintf(buf, format, ap);
- #<span class="enscript-reference">endif</span>
- va_end(ap);
- <span class="enscript-keyword">return</span> SockWrite(sock, buf, strlen(buf));
- }
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"openssl/ssl.h"</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"openssl/err.h"</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"openssl/pem.h"</span>
- #<span class="enscript-reference">include</span> <span class="enscript-string">"openssl/x509.h"</span>
- <span class="enscript-type">static</span> SSL_CTX *_ctx = NULL;
- <span class="enscript-type">static</span> SSL *_ssl_context[FD_SETSIZE];
- SSL *SSLGetContext( <span class="enscript-type">int</span> );
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockWrite</span>(<span class="enscript-type">int</span> sock, <span class="enscript-type">char</span> *buf, <span class="enscript-type">int</span> len)
- {
- <span class="enscript-type">int</span> n, wrlen = 0;
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- SSL *ssl;
- #<span class="enscript-reference">endif</span>
- <span class="enscript-keyword">while</span> (len)
- {
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- <span class="enscript-keyword">if</span>( NULL != ( ssl = SSLGetContext( sock ) ) )
- n = SSL_write(ssl, buf, len);
- <span class="enscript-keyword">else</span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
- n = fm_write(sock, buf, len);
- <span class="enscript-keyword">if</span> (n <= 0)
- <span class="enscript-keyword">return</span> -1;
- len -= n;
- wrlen += n;
- buf += n;
- }
- <span class="enscript-keyword">return</span> wrlen;
- }
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockRead</span>(<span class="enscript-type">int</span> sock, <span class="enscript-type">char</span> *buf, <span class="enscript-type">int</span> len)
- {
- <span class="enscript-type">char</span> *newline, *bp = buf;
- <span class="enscript-type">int</span> n;
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- SSL *ssl;
- #<span class="enscript-reference">endif</span>
- <span class="enscript-keyword">if</span> (--len < 1)
- <span class="enscript-keyword">return</span>(-1);
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
- <span class="enscript-keyword">if</span> (peeked != 0){
- (*bp) = peeked;
- bp++;
- len--;
- peeked = 0;
- }
- #<span class="enscript-reference">endif</span>
- <span class="enscript-keyword">do</span> {
- <span class="enscript-comment">/*
- * The reason for these gymnastics is that we want two things:
- * (1) to read \n-terminated lines,
- * (2) to return the true length of data read, even if the
- * data coming in has embedded NULS.
- */</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- <span class="enscript-keyword">if</span>( NULL != ( ssl = SSLGetContext( sock ) ) ) {
- <span class="enscript-comment">/* Hack alert! */</span>
- <span class="enscript-comment">/* OK... SSL_peek works a little different from MSG_PEEK
- Problem is that SSL_peek can return 0 if there
- is no data currently available. If, on the other
- hand, we loose the socket, we also get a zero, but
- the SSL_read then SEGFAULTS! To deal with this,
- we'll check the error code any time we get a return
- of zero from SSL_peek. If we have an error, we bail.
- If we don't, we read one character in SSL_read and
- loop. This should continue to work even if they
- later change the behavior of SSL_peek
- to "fix" this problem... :-( */</span>
- <span class="enscript-keyword">if</span> ((n = SSL_peek(ssl, bp, len)) < 0) {
- (<span class="enscript-type">void</span>)SSL_get_error(ssl, n);
- <span class="enscript-keyword">return</span>(-1);
- }
- <span class="enscript-keyword">if</span>( 0 == n ) {
- <span class="enscript-comment">/* SSL_peek says no data... Does he mean no data
- or did the connection blow up? If we got an error
- then bail! */</span>
- <span class="enscript-keyword">if</span>( 0 != ( n = SSL_get_error(ssl, n) ) ) {
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/* We didn't get an error so read at least one
- character at this point and loop */</span>
- n = 1;
- <span class="enscript-comment">/* Make sure newline start out NULL!
- * We don't have a string to pass through
- * the strchr at this point yet */</span>
- newline = NULL;
- } <span class="enscript-keyword">else</span> <span class="enscript-keyword">if</span> ((newline = memchr(bp, <span class="enscript-string">'\n'</span>, n)) != NULL)
- n = newline - bp + 1;
- <span class="enscript-comment">/* Matthias Andree: SSL_read can return 0, in that case
- * we must cal SSL_get_error to figure if there was
- * an error or just a "no data" condition */</span>
- <span class="enscript-keyword">if</span> ((n = SSL_read(ssl, bp, n)) <= 0) {
- <span class="enscript-keyword">if</span> ((n = SSL_get_error(ssl, n))) {
- <span class="enscript-keyword">return</span>(-1);
- }
- }
- <span class="enscript-comment">/* Check for case where our single character turned out to
- * be a newline... (It wasn't going to get caught by
- * the strchr above if it came from the hack... ). */</span>
- <span class="enscript-keyword">if</span>( NULL == newline && 1 == n && <span class="enscript-string">'\n'</span> == *bp ) {
- <span class="enscript-comment">/* Got our newline - this will break
- out of the loop now */</span>
- newline = bp;
- }
- }
- <span class="enscript-keyword">else</span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
- {
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
- <span class="enscript-keyword">if</span> ((n = fm_read(sock, bp, 1)) <= 0)
- #<span class="enscript-reference">else</span>
- <span class="enscript-keyword">if</span> ((n = fm_peek(sock, bp, len)) <= 0)
- #<span class="enscript-reference">endif</span>
- <span class="enscript-keyword">return</span> (-1);
- <span class="enscript-keyword">if</span> ((newline = memchr(bp, <span class="enscript-string">'\n'</span>, n)) != NULL)
- n = newline - bp + 1;
- #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">__BEOS__</span>
- <span class="enscript-keyword">if</span> ((n = fm_read(sock, bp, n)) == -1)
- <span class="enscript-keyword">return</span>(-1);
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* __BEOS__ */</span>
- }
- bp += n;
- len -= n;
- } <span class="enscript-keyword">while</span>
- (!newline && len);
- *bp = <span class="enscript-string">'\0'</span>;
- <span class="enscript-keyword">return</span> bp - buf;
- }
- <span class="enscript-type">int</span> <span class="enscript-function-name">SockPeek</span>(<span class="enscript-type">int</span> sock)
- <span class="enscript-comment">/* peek at the next socket character without actually reading it */</span>
- {
- <span class="enscript-type">int</span> n;
- <span class="enscript-type">char</span> ch;
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- SSL *ssl;
- #<span class="enscript-reference">endif</span>
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- <span class="enscript-keyword">if</span>( NULL != ( ssl = SSLGetContext( sock ) ) ) {
- n = SSL_peek(ssl, &ch, 1);
- <span class="enscript-keyword">if</span> (n < 0) {
- (<span class="enscript-type">void</span>)SSL_get_error(ssl, n);
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-keyword">if</span>( 0 == n ) {
- <span class="enscript-comment">/* This code really needs to implement a "hold back"
- * to simulate a functioning SSL_peek()... sigh...
- * Has to be coordinated with the read code above.
- * Next on the list todo... */</span>
- <span class="enscript-comment">/* SSL_peek says 0... Does that mean no data
- or did the connection blow up? If we got an error
- then bail! */</span>
- <span class="enscript-keyword">if</span>( 0 != ( n = SSL_get_error(ssl, n) ) ) {
- <span class="enscript-keyword">return</span> -1;
- }
- <span class="enscript-comment">/* Haven't seen this case actually occur, but...
- if the problem in SockRead can occur, this should
- be possible... Just not sure what to do here.
- This should be a safe "punt" the "peek" but don't
- "punt" the "session"... */</span>
- <span class="enscript-keyword">return</span> 0; <span class="enscript-comment">/* Give him a '\0' character */</span>
- }
- }
- <span class="enscript-keyword">else</span>
- #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
- n = fm_peek(sock, &ch, 1);
- <span class="enscript-keyword">if</span> (n == -1)
- <span class="enscript-keyword">return</span> -1;
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
- peeked = ch;
- #<span class="enscript-reference">endif</span>
- <span class="enscript-keyword">return</span>(ch);
- }
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
- <span class="enscript-type">static</span> <span class="enscript-type">char</span> *_ssl_server_cname = NULL;
- <span class="enscript-type">static</span> <span class="enscript-type">int</span> _check_fp;
- <span class="enscript-type">static</span> <span class="enscript-type">char</span> *_check_digest;
- <span class="enscript-type">static</span> <span class="enscript-type">char</span> *_server_label;
- <span class="enscript-type">static</span> <span class="enscript-type">int</span> _depth0ck;
- SSL *<span class="enscript-function-name">SSLGetContext</span>( <span class="enscript-type">int</span> sock )
- {
- <span class="enscript-comment">/* If SSLOpen has never initialized - just return NULL */</span>
- <span class="enscript-keyword">if</span>( NULL == _ctx )
- <span class="enscript-keyword">return</span> NULL;
- <span class="enscript-keyword">if</span>( sock < 0 || sock > FD_SETSIZE )
- <span class="enscript-keyword">return</span> NULL;
- <span class="enscript-keyword">return</span> _ssl_context[sock];
- }
- <span class="enscript-type">int</span> <span class="enscript-function-name">SSL_verify_callback</span>( <span class="enscript-type">int</span> ok_return, X509_STORE_CTX *ctx, <span class="enscript-type">int</span> strict )
- {
- <span class="enscript-type">char</span> buf[257];
- X509 *x509_cert;
- <span class="enscript-type">int</span> err, depth;
- <span class="enscript-type">unsigned</span> <span class="enscript-type">char</span> digest[EVP_MAX_MD_SIZE];
- <span class="enscript-type">char</span> text[EVP_MAX_MD_SIZE * 3 + 1], *tp, *te;
- EVP_MD *digest_tp;
- <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> dsz, i, esz;
- X509_NAME *subj, *issuer;
- x509_cert = X509_STORE_CTX_get_current_cert(ctx);
- err = X509_STORE_CTX_get_error(ctx);
- depth = X509_STORE_CTX_get_error_depth(ctx);
- subj = X509_get_subject_name(x509_cert);
- issuer = X509_get_issuer_name(x509_cert);
- <span class="enscript-keyword">if</span> (depth == 0) {
- _depth0ck = 1;
-
- <span class="enscript-keyword">if</span> (outlevel == O_VERBOSE) {
- <span class="enscript-keyword">if</span> ((i = X509_NAME_get_text_by_NID(issuer, NID_organizationName, buf, <span class="enscript-keyword">sizeof</span>(buf))) != -1) {
- report(stdout, GT_(<span class="enscript-string">"Issuer Organization: %s\n"</span>), buf);
- <span class="enscript-keyword">if</span> (i >= <span class="enscript-keyword">sizeof</span>(buf) - 1)
- report(stdout, GT_(<span class="enscript-string">"Warning: Issuer Organization Name too long (possibly truncated).\n"</span>));
- } <span class="enscript-keyword">else</span>
- report(stdout, GT_(<span class="enscript-string">"Unknown Organization\n"</span>));
- <span class="enscript-keyword">if</span> ((i = X509_NAME_get_text_by_NID(issuer, NID_commonName, buf, <span class="enscript-keyword">sizeof</span>(buf))) != -1) {
- report(stdout, GT_(<span class="enscript-string">"Issuer CommonName: %s\n"</span>), buf);
- <span class="enscript-keyword">if</span> (i >= <span class="enscript-keyword">sizeof</span>(buf) - 1)
- report(stdout, GT_(<span class="enscript-string">"Warning: Issuer CommonName too long (possibly truncated).\n"</span>));
- } <span class="enscript-keyword">else</span>
- report(stdout, GT_(<span class="enscript-string">"Unknown Issuer CommonName\n"</span>));
- }
- <span class="enscript-keyword">if</span> ((i = X509_NAME_get_text_by_NID(subj, NID_commonName, buf, <span class="enscript-keyword">sizeof</span>(buf))) != -1) {
- <span class="enscript-keyword">if</span> (outlevel == O_VERBOSE)
- report(stdout, GT_(<span class="enscript-string">"Server CommonName: %s\n"</span>), buf);
- <span class="enscript-keyword">if</span> (i >= <span class="enscript-keyword">sizeof</span>(buf) - 1) {
- <span class="enscript-comment">/* Possible truncation. In this case, this is a DNS name, so this
- * is really bad. We do not tolerate this even in the non-strict case. */</span>
- report(stderr, GT_(<span class="enscript-string">"Bad certificate: Subject CommonName too long!\n"</span>));
- <span class="enscript-keyword">return</span> (0);
- }
- <span class="enscript-keyword">if</span> (_ssl_server_cname != NULL) {
- <span class="enscript-type">char</span> *p1 = buf;
- <span class="enscript-type">char</span> *p2 = _ssl_server_cname;
- <span class="enscript-type">int</span> n;
-
- <span class="enscript-keyword">if</span> (*p1 == <span class="enscript-string">'*'</span>) {
- ++p1;
- n = strlen(p2) - strlen(p1);
- <span class="enscript-keyword">if</span> (n >= 0)
- p2 += n;
- }
- <span class="enscript-keyword">if</span> (0 != strcasecmp(p1, p2)) {
- report(stderr,
- GT_(<span class="enscript-string">"Server CommonName mismatch: %s != %s\n"</span>),
- buf, _ssl_server_cname );
- <span class="enscript-keyword">if</span> (ok_return && strict)
- <span class="enscript-keyword">return</span> (0);
- }
- } <span class="enscript-keyword">else</span> <span class="enscript-keyword">if</span> (ok_return && strict) {
- report(stderr, GT_(<span class="enscript-string">"Server name not set, could not verify certificate!\n"</span>));
- <span class="enscript-keyword">return</span> (0);
- }
- } <span class="enscript-keyword">else</span> {
- <span class="enscript-keyword">if</span> (outlevel == O_VERBOSE)
- report(stdout, GT_(<span class="enscript-string">"Unknown Server CommonName\n"</span>));
- <span class="enscript-keyword">if</span> (ok_return && strict) {
- report(stderr, GT_(<span class="enscript-string">"Server name not specified in certificate!\n"</span>));
- <span class="enscript-keyword">return</span> (0);
- }
- }
- <span class="enscript-comment">/* Print the finger print. Note that on errors, we might print it more than once
- * normally; we kluge around that by using a global variable. */</span>
- <span class="enscript-keyword">if</span> (_check_fp) {
- _check_fp = 0;
- digest_tp = EVP_md5();
- <span class="enscript-keyword">if</span> (digest_tp == NULL) {
- report(stderr, GT_(<span class="enscript-string">"EVP_md5() failed!\n"</span>));
- <span class="enscript-keyword">return</span> (0);
- }
- <span class="enscript-keyword">if</span> (!X509_digest(x509_cert, digest_tp, digest, &dsz)) {
- report(stderr, GT_(<span class="enscript-string">"Out of memory!\n"</span>));
- <span class="enscript-keyword">return</span> (0);
- }
- tp = text;
- te = text + <span class="enscript-keyword">sizeof</span>(text);
- <span class="enscript-keyword">for</span> (i = 0; i < dsz; i++) {
- #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SNPRINTF</span>
- esz = snprintf(tp, te - tp, i > 0 ? <span class="enscript-string">":%02X"</span> : <span class="enscript-string">"%02X"</span>, digest[i]);
- #<span class="enscript-reference">else</span>
- esz = sprintf(tp, i > 0 ? <span class="enscript-string">":%02X"</span> : <span class="enscript-string">"%02X"</span>, digest[i]);
- #<span class="enscript-reference">endif</span>
- <span class="enscript-keyword">if</span> (esz >= te - tp) {
- report(stderr, GT_(<span class="enscript-string">"Digest text buffer too small!\n"</span>));
- <span class="enscript-keyword">return</span> (0);
- }
- tp += esz;
- }
- <span class="enscript-keyword">if</span> (outlevel > O_NORMAL)
- report(stdout, GT_(<span class="enscript-string">"%s key fingerprint: %s\n"</span>), _server_label, text);
- <span class="enscript-keyword">if</span> (_check_digest != NULL) {
- <span class="enscript-keyword">if</span> (strcmp(text, _check_digest) == 0) {
- <span class="enscript-keyword">if</span> (outlevel > O_NORMAL)
- report(stdout, GT_(<span class="enscript-string">"%s fingerprints match.\n"</span>), _server_label);
- } <span class="enscript-keyword">else</span> {
- <span class="enscript-keyword">if</span> (outlevel > O_SILENT)
- report(stderr, GT_(<span class="enscript-string">"%s fingerprints do not match!\n"</span>), _server_label);
- <span class="enscript-keyword">return</span> (0);
- }
- }
- }
- }
- <span class="enscript-keyword">if</span> (err != X509_V_OK && (strict || outlevel == O_VERBOSE)) {
- report(strict ? stderr : stdout, GT_(<span class="enscript-string">"Warning: server certificate verification: %s\n"</span>), X509_verify_cert_error_string(err));
- <span class="enscript-comment">/* We gave the error code, but maybe we can add some more details for debugging */</span>
- <span class="enscript-keyword">switch</span> (err) {
- <span class="enscript-keyword">case</span> <span class="en…
Large files files are truncated, but you can click here to view the full file