PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/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

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <title>socket.c</title>
  6. <style type="text/css">
  7. .enscript-comment { font-style: italic; color: rgb(178,34,34); }
  8. .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
  9. .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
  10. .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
  11. .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
  12. .enscript-string { font-weight: bold; color: rgb(188,143,143); }
  13. .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
  14. .enscript-type { font-weight: bold; color: rgb(34,139,34); }
  15. .enscript-highlight { text-decoration: underline; color: 0; }
  16. </style>
  17. </head>
  18. <body id="top">
  19. <h1 style="margin:8px;" id="f1">socket.c&nbsp;&nbsp;&nbsp;<span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
  20. <hr/>
  21. <div></div>
  22. <pre>
  23. <span class="enscript-comment">/*
  24. * socket.c -- socket library functions
  25. *
  26. * Copyright 1998 by Eric S. Raymond.
  27. * For license terms, see the file COPYING in this directory.
  28. */</span>
  29. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;config.h&quot;</span>
  30. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;stdio.h&gt;</span>
  31. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;errno.h&gt;</span>
  32. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;string.h&gt;</span>
  33. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;ctype.h&gt;</span> <span class="enscript-comment">/* isspace() */</span>
  34. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_MEMORY_H</span>
  35. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;memory.h&gt;</span>
  36. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_MEMORY_H */</span>
  37. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/types.h&gt;</span>
  38. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_NET_SOCKET_H</span>
  39. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/socket.h&gt;</span>
  40. #<span class="enscript-reference">else</span>
  41. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;net/socket.h&gt;</span>
  42. #<span class="enscript-reference">endif</span>
  43. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/un.h&gt;</span>
  44. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;netinet/in.h&gt;</span>
  45. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_ARPA_INET_H</span>
  46. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;arpa/inet.h&gt;</span>
  47. #<span class="enscript-reference">endif</span>
  48. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;netdb.h&gt;</span>
  49. #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">STDC_HEADERS</span>)
  50. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;stdlib.h&gt;</span>
  51. #<span class="enscript-reference">endif</span>
  52. #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_UNISTD_H</span>)
  53. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;unistd.h&gt;</span>
  54. #<span class="enscript-reference">endif</span>
  55. #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_STDARG_H</span>)
  56. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;stdarg.h&gt;</span>
  57. #<span class="enscript-reference">else</span>
  58. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;varargs.h&gt;</span>
  59. #<span class="enscript-reference">endif</span>
  60. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;socket.h&quot;</span>
  61. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;fetchmail.h&quot;</span>
  62. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;i18n.h&quot;</span>
  63. <span class="enscript-comment">/* Defines to allow BeOS and Cygwin to play nice... */</span>
  64. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
  65. <span class="enscript-type">static</span> <span class="enscript-type">char</span> peeked;
  66. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_close</span>(a) closesocket(a)
  67. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_write</span>(a,b,c) send(a,b,c,0)
  68. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_peek</span>(a,b,c) recv(a,b,c,0)
  69. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_read</span>(a,b,c) recv(a,b,c,0)
  70. #<span class="enscript-reference">else</span>
  71. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_close</span>(a) close(a)
  72. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_write</span>(a,b,c) write(a,b,c)
  73. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_peek</span>(a,b,c) recv(a,b,c, MSG_PEEK)
  74. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__CYGWIN__</span>
  75. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_read</span>(a,b,c) cygwin_read(a,b,c)
  76. <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);
  77. #<span class="enscript-reference">else</span> <span class="enscript-comment">/* ! __CYGWIN__ */</span>
  78. #<span class="enscript-reference">define</span> <span class="enscript-function-name">fm_read</span>(a,b,c) read(a,b,c)
  79. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* __CYGWIN__ */</span>
  80. #<span class="enscript-reference">endif</span>
  81. <span class="enscript-comment">/* We need to define h_errno only if it is not already */</span>
  82. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">h_errno</span>
  83. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_RES_SEARCH</span>
  84. <span class="enscript-comment">/* some versions of FreeBSD should declare this but don't */</span>
  85. <span class="enscript-type">extern</span> <span class="enscript-type">int</span> h_errno;
  86. #<span class="enscript-reference">else</span>
  87. <span class="enscript-comment">/* pretend we have h_errno to avoid some #ifdef's later */</span>
  88. <span class="enscript-type">static</span> <span class="enscript-type">int</span> h_errno;
  89. #<span class="enscript-reference">endif</span>
  90. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* ndef h_errno */</span>
  91. <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>
  92. #<span class="enscript-reference">if</span> <span class="enscript-variable-name">NET_SECURITY</span>
  93. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;net/security.h&gt;</span>
  94. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* NET_SECURITY */</span>
  95. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKETPAIR</span>
  96. <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)
  97. { <span class="enscript-type">const</span> <span class="enscript-type">char</span> **argvec;
  98. <span class="enscript-type">const</span> <span class="enscript-type">char</span> *c, *p;
  99. <span class="enscript-type">char</span> *cp, *plugin_copy;
  100. <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> plugin_copy_len;
  101. <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> plugin_offset = 0, plugin_copy_offset = 0;
  102. <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;
  103. <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> plugin_len = strlen(plugin);
  104. <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> host_len = strlen(host);
  105. <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> service_len = strlen(service);
  106. <span class="enscript-keyword">for</span> (c = p = plugin; *c; c++)
  107. { <span class="enscript-keyword">if</span> (isspace(*c) &amp;&amp; !isspace(*p))
  108. s += <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">char</span>*);
  109. <span class="enscript-keyword">if</span> (*p == <span class="enscript-string">'%'</span> &amp;&amp; *c == <span class="enscript-string">'h'</span>)
  110. host_count++;
  111. <span class="enscript-keyword">if</span> (*p == <span class="enscript-string">'%'</span> &amp;&amp; *c == <span class="enscript-string">'p'</span>)
  112. service_count++;
  113. p = c;
  114. }
  115. plugin_copy_len = plugin_len + host_len * host_count + service_len * service_count;
  116. plugin_copy = malloc(plugin_copy_len + 1);
  117. <span class="enscript-keyword">if</span> (!plugin_copy)
  118. {
  119. report(stderr, GT_(<span class="enscript-string">&quot;fetchmail: malloc failed\n&quot;</span>));
  120. <span class="enscript-keyword">return</span> NULL;
  121. }
  122. <span class="enscript-keyword">while</span> (plugin_copy_offset &lt; plugin_copy_len)
  123. { <span class="enscript-keyword">if</span> ((plugin[plugin_offset] == <span class="enscript-string">'%'</span>) &amp;&amp; (plugin[plugin_offset + 1] == <span class="enscript-string">'h'</span>))
  124. { strcpy(plugin_copy + plugin_copy_offset, host);
  125. plugin_offset += 2;
  126. plugin_copy_offset += host_len;
  127. }
  128. <span class="enscript-keyword">else</span> <span class="enscript-keyword">if</span> ((plugin[plugin_offset] == <span class="enscript-string">'%'</span>) &amp;&amp; (plugin[plugin_offset + 1] == <span class="enscript-string">'p'</span>))
  129. { strcpy(plugin_copy + plugin_copy_offset, service);
  130. plugin_offset += 2;
  131. plugin_copy_offset += service_len;
  132. }
  133. <span class="enscript-keyword">else</span>
  134. { plugin_copy[plugin_copy_offset] = plugin[plugin_offset];
  135. plugin_offset++;
  136. plugin_copy_offset++;
  137. }
  138. }
  139. plugin_copy[plugin_copy_len] = 0;
  140. argvec = malloc(s);
  141. <span class="enscript-keyword">if</span> (!argvec)
  142. {
  143. report(stderr, GT_(<span class="enscript-string">&quot;fetchmail: malloc failed\n&quot;</span>));
  144. <span class="enscript-keyword">return</span> NULL;
  145. }
  146. memset(argvec, 0, s);
  147. <span class="enscript-keyword">for</span> (c = p = plugin_copy, i = 0; *c; c++)
  148. { <span class="enscript-keyword">if</span> ((!isspace(*c)) &amp;&amp; (c == p ? 1 : isspace(*p))) {
  149. argvec[i] = c;
  150. i++;
  151. }
  152. p = c;
  153. }
  154. <span class="enscript-keyword">for</span> (cp = plugin_copy; *cp; cp++)
  155. { <span class="enscript-keyword">if</span> (isspace(*cp))
  156. *cp = 0;
  157. }
  158. <span class="enscript-keyword">return</span> (<span class="enscript-type">char</span> *<span class="enscript-type">const</span>*)argvec;
  159. }
  160. <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,
  161. <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)
  162. <span class="enscript-comment">/* get a socket mediated through a given external command */</span>
  163. {
  164. <span class="enscript-type">int</span> fds[2];
  165. <span class="enscript-type">char</span> *<span class="enscript-type">const</span> *argvec;
  166. <span class="enscript-comment">/*
  167. * The author of this code, Felix von Leitner &lt;<a href="mailto:felix@convergence.de">felix@convergence.de</a>&gt;, says:
  168. * he chose socketpair() instead of pipe() because socketpair creates
  169. * bidirectional sockets while allegedly some pipe() implementations don't.
  170. */</span>
  171. <span class="enscript-keyword">if</span> (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
  172. {
  173. report(stderr, GT_(<span class="enscript-string">&quot;fetchmail: socketpair failed\n&quot;</span>));
  174. <span class="enscript-keyword">return</span> -1;
  175. }
  176. <span class="enscript-keyword">switch</span> (fork()) {
  177. <span class="enscript-keyword">case</span> <span class="enscript-reference">-1</span>:
  178. <span class="enscript-comment">/* error */</span>
  179. report(stderr, GT_(<span class="enscript-string">&quot;fetchmail: fork failed\n&quot;</span>));
  180. <span class="enscript-keyword">return</span> -1;
  181. <span class="enscript-keyword">break</span>;
  182. <span class="enscript-keyword">case</span> <span class="enscript-reference">0</span>: <span class="enscript-comment">/* child */</span>
  183. <span class="enscript-comment">/* fds[1] is the parent's end; close it for proper EOF
  184. ** detection */</span>
  185. (<span class="enscript-type">void</span>) close(fds[1]);
  186. <span class="enscript-keyword">if</span> ( (dup2(fds[0],0) == -1) || (dup2(fds[0],1) == -1) ) {
  187. report(stderr, GT_(<span class="enscript-string">&quot;dup2 failed\n&quot;</span>));
  188. exit(1);
  189. }
  190. <span class="enscript-comment">/* fds[0] is now connected to 0 and 1; close it */</span>
  191. (<span class="enscript-type">void</span>) close(fds[0]);
  192. <span class="enscript-keyword">if</span> (outlevel &gt;= O_VERBOSE)
  193. report(stderr, GT_(<span class="enscript-string">&quot;running %s (host %s service %s)\n&quot;</span>), plugin, host, service);
  194. argvec = parse_plugin(plugin,host,service);
  195. execvp(*argvec, argvec);
  196. report(stderr, GT_(<span class="enscript-string">&quot;execvp(%s) failed\n&quot;</span>), *argvec);
  197. exit(0);
  198. <span class="enscript-keyword">break</span>;
  199. <span class="enscript-reference">default</span>: <span class="enscript-comment">/* parent */</span>
  200. <span class="enscript-comment">/* NOP */</span>
  201. <span class="enscript-keyword">break</span>;
  202. }
  203. <span class="enscript-comment">/* fds[0] is the child's end; close it for proper EOF detection */</span>
  204. (<span class="enscript-type">void</span>) close(fds[0]);
  205. <span class="enscript-keyword">return</span> fds[1];
  206. }
  207. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SOCKETPAIR */</span>
  208. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__UNUSED__</span>
  209. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/time.h&gt;</span>
  210. <span class="enscript-type">int</span> <span class="enscript-function-name">SockCheckOpen</span>(<span class="enscript-type">int</span> fd)
  211. <span class="enscript-comment">/* poll given socket; is it selectable? */</span>
  212. {
  213. fd_set r, w, e;
  214. <span class="enscript-type">int</span> rt;
  215. <span class="enscript-type">struct</span> timeval tv;
  216. <span class="enscript-keyword">for</span> (;;)
  217. {
  218. FD_ZERO(&amp;r); FD_ZERO(&amp;w); FD_ZERO(&amp;e);
  219. FD_SET(fd, &amp;e);
  220. tv.tv_sec = 0; tv.tv_usec = 0;
  221. rt = select(fd+1, &amp;r, &amp;w, &amp;e, &amp;tv);
  222. <span class="enscript-keyword">if</span> (rt == -1 &amp;&amp; (errno != EAGAIN &amp;&amp; errno != EINTR))
  223. <span class="enscript-keyword">return</span> 0;
  224. <span class="enscript-keyword">if</span> (rt != -1)
  225. <span class="enscript-keyword">return</span> 1;
  226. }
  227. }
  228. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* __UNUSED__ */</span>
  229. <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)
  230. {
  231. <span class="enscript-type">int</span> sock = -1;
  232. <span class="enscript-type">struct</span> sockaddr_un ad;
  233. memset(&amp;ad, 0, <span class="enscript-keyword">sizeof</span>(ad));
  234. ad.sun_family = AF_UNIX;
  235. strncpy(ad.sun_path, path, <span class="enscript-keyword">sizeof</span>(ad.sun_path)-1);
  236. sock = socket( AF_UNIX, SOCK_STREAM, 0 );
  237. <span class="enscript-keyword">if</span> (sock &lt; 0)
  238. {
  239. h_errno = 0;
  240. <span class="enscript-keyword">return</span> -1;
  241. }
  242. <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout
  243. * because it can be closed.
  244. */</span>
  245. mailserver_socket_temp = sock;
  246. <span class="enscript-keyword">if</span> (connect(sock, (<span class="enscript-type">struct</span> sockaddr *) &amp;ad, <span class="enscript-keyword">sizeof</span>(ad)) &lt; 0)
  247. {
  248. <span class="enscript-type">int</span> olderr = errno;
  249. fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
  250. h_errno = 0;
  251. errno = olderr;
  252. sock = -1;
  253. }
  254. <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
  255. mailserver_socket_temp = -1;
  256. <span class="enscript-keyword">return</span> sock;
  257. }
  258. #<span class="enscript-reference">if</span> <span class="enscript-variable-name">INET6_ENABLE</span>
  259. <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,
  260. <span class="enscript-type">const</span> <span class="enscript-type">char</span> *plugin)
  261. {
  262. <span class="enscript-type">struct</span> addrinfo *ai, *ai0, req;
  263. <span class="enscript-type">int</span> i;
  264. #<span class="enscript-reference">if</span> <span class="enscript-variable-name">NET_SECURITY</span>
  265. <span class="enscript-type">void</span> *request = NULL;
  266. <span class="enscript-type">int</span> requestlen;
  267. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* NET_SECURITY */</span>
  268. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKETPAIR</span>
  269. <span class="enscript-keyword">if</span> (plugin)
  270. <span class="enscript-keyword">return</span> handle_plugin(host,service,plugin);
  271. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SOCKETPAIR */</span>
  272. memset(&amp;req, 0, <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">struct</span> addrinfo));
  273. req.ai_socktype = SOCK_STREAM;
  274. <span class="enscript-keyword">if</span> (getaddrinfo(host, service, &amp;req, &amp;ai0)) {
  275. report(stderr, GT_(<span class="enscript-string">&quot;fetchmail: getaddrinfo(%s.%s)\n&quot;</span>), host,service);
  276. <span class="enscript-keyword">return</span> -1;
  277. }
  278. #<span class="enscript-reference">if</span> <span class="enscript-variable-name">NET_SECURITY</span>
  279. <span class="enscript-keyword">if</span> (!options)
  280. requestlen = 0;
  281. <span class="enscript-keyword">else</span>
  282. <span class="enscript-keyword">if</span> (net_security_strtorequest((<span class="enscript-type">char</span> *)options, &amp;request, &amp;requestlen))
  283. <span class="enscript-keyword">goto</span> <span class="enscript-reference">ret</span>;
  284. i = inner_connect(ai0, request, requestlen, NULL, NULL, <span class="enscript-string">&quot;fetchmail&quot;</span>, NULL);
  285. <span class="enscript-keyword">if</span> (request)
  286. free(request);
  287. <span class="enscript-reference">ret</span>:
  288. #<span class="enscript-reference">else</span> <span class="enscript-comment">/* NET_SECURITY */</span>
  289. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_INNER_CONNECT</span>
  290. i = inner_connect(ai0, NULL, 0, NULL, NULL, <span class="enscript-string">&quot;fetchmail&quot;</span>, NULL);
  291. <span class="enscript-keyword">if</span> (i &gt;= 0)
  292. <span class="enscript-keyword">break</span>;
  293. #<span class="enscript-reference">else</span>
  294. i = -1;
  295. <span class="enscript-keyword">for</span> (ai = ai0; ai; ai = ai-&gt;ai_next) {
  296. i = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, 0);
  297. <span class="enscript-keyword">if</span> (i &lt; 0)
  298. <span class="enscript-keyword">continue</span>;
  299. <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout
  300. * because it can be closed.
  301. */</span>
  302. mailserver_socket_temp = i;
  303. <span class="enscript-keyword">if</span> (connect(i, (<span class="enscript-type">struct</span> sockaddr *) ai-&gt;ai_addr, ai-&gt;ai_addrlen) &lt; 0) {
  304. fm_close(i);
  305. i = -1;
  306. <span class="enscript-keyword">continue</span>;
  307. }
  308. <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
  309. mailserver_socket_temp = -1;
  310. <span class="enscript-keyword">break</span>;
  311. }
  312. #<span class="enscript-reference">endif</span>
  313. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* NET_SECURITY */</span>
  314. freeaddrinfo(ai0);
  315. <span class="enscript-keyword">return</span> i;
  316. }
  317. #<span class="enscript-reference">else</span> <span class="enscript-comment">/* INET6_ENABLE */</span>
  318. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
  319. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">INADDR_NONE</span>
  320. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">INADDR_BROADCAST</span>
  321. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">INADDR_NONE</span> INADDR_BROADCAST
  322. #<span class="enscript-reference">else</span>
  323. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">INADDR_NONE</span> -1
  324. #<span class="enscript-reference">endif</span>
  325. #<span class="enscript-reference">endif</span>
  326. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
  327. <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,
  328. <span class="enscript-type">const</span> <span class="enscript-type">char</span> *plugin)
  329. {
  330. <span class="enscript-type">int</span> sock = -1; <span class="enscript-comment">/* pacify -Wall */</span>
  331. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
  332. <span class="enscript-type">unsigned</span> <span class="enscript-type">long</span> inaddr;
  333. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
  334. <span class="enscript-type">struct</span> sockaddr_in ad, **pptr;
  335. <span class="enscript-type">struct</span> hostent *hp;
  336. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKETPAIR</span>
  337. <span class="enscript-keyword">if</span> (plugin) {
  338. <span class="enscript-type">char</span> buf[10];
  339. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SNPRINTF</span>
  340. snprintf(buf, <span class="enscript-keyword">sizeof</span>(buf), <span class="enscript-comment">/* Yeah, paranoic. So what? :P */</span>
  341. #<span class="enscript-reference">else</span>
  342. sprintf(buf,
  343. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SNPRINTF */</span>
  344. <span class="enscript-string">&quot;%d&quot;</span>,clientPort);
  345. <span class="enscript-keyword">return</span> handle_plugin(host,buf,plugin);
  346. }
  347. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_SOCKETPAIR */</span>
  348. memset(&amp;ad, 0, <span class="enscript-keyword">sizeof</span>(ad));
  349. ad.sin_family = AF_INET;
  350. <span class="enscript-comment">/* we'll accept a quad address */</span>
  351. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
  352. inaddr = inet_addr((<span class="enscript-type">char</span>*)host);
  353. <span class="enscript-keyword">if</span> (inaddr != INADDR_NONE)
  354. {
  355. memcpy(&amp;ad.sin_addr, &amp;inaddr, <span class="enscript-keyword">sizeof</span>(inaddr));
  356. #<span class="enscript-reference">else</span>
  357. <span class="enscript-keyword">if</span> (inet_aton(host, &amp;ad.sin_addr))
  358. {
  359. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
  360. ad.sin_port = htons(clientPort);
  361. sock = socket(AF_INET, SOCK_STREAM, 0);
  362. <span class="enscript-keyword">if</span> (sock &lt; 0)
  363. {
  364. h_errno = 0;
  365. <span class="enscript-keyword">return</span> -1;
  366. }
  367. <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout because
  368. * it can be closed
  369. */</span>
  370. mailserver_socket_temp = sock;
  371. <span class="enscript-keyword">if</span> (connect(sock, (<span class="enscript-type">struct</span> sockaddr *) &amp;ad, <span class="enscript-keyword">sizeof</span>(ad)) &lt; 0)
  372. {
  373. <span class="enscript-type">int</span> olderr = errno;
  374. fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
  375. h_errno = 0;
  376. errno = olderr;
  377. <span class="enscript-keyword">return</span> -1;
  378. }
  379. <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
  380. mailserver_socket_temp = -1;
  381. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">HAVE_INET_ATON</span>
  382. }
  383. #<span class="enscript-reference">else</span>
  384. }
  385. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* HAVE_INET_ATON */</span>
  386. <span class="enscript-keyword">else</span> {
  387. hp = gethostbyname((<span class="enscript-type">char</span>*)host);
  388. <span class="enscript-keyword">if</span> (hp == NULL)
  389. {
  390. errno = 0;
  391. <span class="enscript-keyword">return</span> -1;
  392. }
  393. <span class="enscript-comment">/*
  394. * Add a check to make sure the address has a valid IPv4 or IPv6
  395. * length. This prevents buffer spamming by a broken DNS.
  396. */</span>
  397. <span class="enscript-keyword">if</span>(hp-&gt;h_length != 4 &amp;&amp; hp-&gt;h_length != 8)
  398. {
  399. h_errno = errno = 0;
  400. report(stderr,
  401. GT_(<span class="enscript-string">&quot;fetchmail: illegal address length received for host %s\n&quot;</span>),host);
  402. <span class="enscript-keyword">return</span> -1;
  403. }
  404. <span class="enscript-comment">/*
  405. * Try all addresses of a possibly multihomed host until we get
  406. * a successful connect or until we run out of addresses.
  407. */</span>
  408. pptr = (<span class="enscript-type">struct</span> sockaddr_in **)hp-&gt;h_addr_list;
  409. <span class="enscript-keyword">for</span>(; *pptr != NULL; pptr++)
  410. {
  411. sock = socket(AF_INET, SOCK_STREAM, 0);
  412. <span class="enscript-keyword">if</span> (sock &lt; 0)
  413. {
  414. h_errno = 0;
  415. <span class="enscript-keyword">return</span> -1;
  416. }
  417. <span class="enscript-comment">/* Socket opened saved. Usefull if connect timeout because
  418. * it can be closed
  419. */</span>
  420. mailserver_socket_temp = sock;
  421. ad.sin_port = htons(clientPort);
  422. memcpy(&amp;ad.sin_addr, *pptr, <span class="enscript-keyword">sizeof</span>(<span class="enscript-type">struct</span> in_addr));
  423. <span class="enscript-keyword">if</span> (connect(sock, (<span class="enscript-type">struct</span> sockaddr *) &amp;ad, <span class="enscript-keyword">sizeof</span>(ad)) == 0) {
  424. <span class="enscript-comment">/* No connect timeout, then no need to set mailserver_socket_temp */</span>
  425. mailserver_socket_temp = -1;
  426. <span class="enscript-keyword">break</span>; <span class="enscript-comment">/* success */</span>
  427. }
  428. fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
  429. memset(&amp;ad, 0, <span class="enscript-keyword">sizeof</span>(ad));
  430. ad.sin_family = AF_INET;
  431. }
  432. <span class="enscript-keyword">if</span>(*pptr == NULL)
  433. {
  434. <span class="enscript-type">int</span> olderr = errno;
  435. fm_close(sock); <span class="enscript-comment">/* don't use SockClose, no traffic yet */</span>
  436. h_errno = 0;
  437. errno = olderr;
  438. <span class="enscript-keyword">return</span> -1;
  439. }
  440. }
  441. <span class="enscript-keyword">return</span>(sock);
  442. }
  443. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* INET6_ENABLE */</span>
  444. #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_STDARG_H</span>)
  445. <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, ...)
  446. {
  447. #<span class="enscript-reference">else</span>
  448. <span class="enscript-type">int</span> <span class="enscript-function-name">SockPrintf</span>(sock,format,va_alist)
  449. <span class="enscript-type">int</span> sock;
  450. <span class="enscript-type">char</span> *format;
  451. va_dcl {
  452. #<span class="enscript-reference">endif</span>
  453. va_list ap;
  454. <span class="enscript-type">char</span> buf[8192];
  455. #<span class="enscript-reference">if</span> <span class="enscript-reference">defined</span>(<span class="enscript-variable-name">HAVE_STDARG_H</span>)
  456. va_start(ap, format) ;
  457. #<span class="enscript-reference">else</span>
  458. va_start(ap);
  459. #<span class="enscript-reference">endif</span>
  460. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_VSNPRINTF</span>
  461. vsnprintf(buf, <span class="enscript-keyword">sizeof</span>(buf), format, ap);
  462. #<span class="enscript-reference">else</span>
  463. vsprintf(buf, format, ap);
  464. #<span class="enscript-reference">endif</span>
  465. va_end(ap);
  466. <span class="enscript-keyword">return</span> SockWrite(sock, buf, strlen(buf));
  467. }
  468. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  469. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;openssl/ssl.h&quot;</span>
  470. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;openssl/err.h&quot;</span>
  471. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;openssl/pem.h&quot;</span>
  472. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;openssl/x509.h&quot;</span>
  473. <span class="enscript-type">static</span> SSL_CTX *_ctx = NULL;
  474. <span class="enscript-type">static</span> SSL *_ssl_context[FD_SETSIZE];
  475. SSL *SSLGetContext( <span class="enscript-type">int</span> );
  476. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
  477. <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)
  478. {
  479. <span class="enscript-type">int</span> n, wrlen = 0;
  480. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  481. SSL *ssl;
  482. #<span class="enscript-reference">endif</span>
  483. <span class="enscript-keyword">while</span> (len)
  484. {
  485. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  486. <span class="enscript-keyword">if</span>( NULL != ( ssl = SSLGetContext( sock ) ) )
  487. n = SSL_write(ssl, buf, len);
  488. <span class="enscript-keyword">else</span>
  489. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
  490. n = fm_write(sock, buf, len);
  491. <span class="enscript-keyword">if</span> (n &lt;= 0)
  492. <span class="enscript-keyword">return</span> -1;
  493. len -= n;
  494. wrlen += n;
  495. buf += n;
  496. }
  497. <span class="enscript-keyword">return</span> wrlen;
  498. }
  499. <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)
  500. {
  501. <span class="enscript-type">char</span> *newline, *bp = buf;
  502. <span class="enscript-type">int</span> n;
  503. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  504. SSL *ssl;
  505. #<span class="enscript-reference">endif</span>
  506. <span class="enscript-keyword">if</span> (--len &lt; 1)
  507. <span class="enscript-keyword">return</span>(-1);
  508. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
  509. <span class="enscript-keyword">if</span> (peeked != 0){
  510. (*bp) = peeked;
  511. bp++;
  512. len--;
  513. peeked = 0;
  514. }
  515. #<span class="enscript-reference">endif</span>
  516. <span class="enscript-keyword">do</span> {
  517. <span class="enscript-comment">/*
  518. * The reason for these gymnastics is that we want two things:
  519. * (1) to read \n-terminated lines,
  520. * (2) to return the true length of data read, even if the
  521. * data coming in has embedded NULS.
  522. */</span>
  523. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  524. <span class="enscript-keyword">if</span>( NULL != ( ssl = SSLGetContext( sock ) ) ) {
  525. <span class="enscript-comment">/* Hack alert! */</span>
  526. <span class="enscript-comment">/* OK... SSL_peek works a little different from MSG_PEEK
  527. Problem is that SSL_peek can return 0 if there
  528. is no data currently available. If, on the other
  529. hand, we loose the socket, we also get a zero, but
  530. the SSL_read then SEGFAULTS! To deal with this,
  531. we'll check the error code any time we get a return
  532. of zero from SSL_peek. If we have an error, we bail.
  533. If we don't, we read one character in SSL_read and
  534. loop. This should continue to work even if they
  535. later change the behavior of SSL_peek
  536. to &quot;fix&quot; this problem... :-( */</span>
  537. <span class="enscript-keyword">if</span> ((n = SSL_peek(ssl, bp, len)) &lt; 0) {
  538. (<span class="enscript-type">void</span>)SSL_get_error(ssl, n);
  539. <span class="enscript-keyword">return</span>(-1);
  540. }
  541. <span class="enscript-keyword">if</span>( 0 == n ) {
  542. <span class="enscript-comment">/* SSL_peek says no data... Does he mean no data
  543. or did the connection blow up? If we got an error
  544. then bail! */</span>
  545. <span class="enscript-keyword">if</span>( 0 != ( n = SSL_get_error(ssl, n) ) ) {
  546. <span class="enscript-keyword">return</span> -1;
  547. }
  548. <span class="enscript-comment">/* We didn't get an error so read at least one
  549. character at this point and loop */</span>
  550. n = 1;
  551. <span class="enscript-comment">/* Make sure newline start out NULL!
  552. * We don't have a string to pass through
  553. * the strchr at this point yet */</span>
  554. newline = NULL;
  555. } <span class="enscript-keyword">else</span> <span class="enscript-keyword">if</span> ((newline = memchr(bp, <span class="enscript-string">'\n'</span>, n)) != NULL)
  556. n = newline - bp + 1;
  557. <span class="enscript-comment">/* Matthias Andree: SSL_read can return 0, in that case
  558. * we must cal SSL_get_error to figure if there was
  559. * an error or just a &quot;no data&quot; condition */</span>
  560. <span class="enscript-keyword">if</span> ((n = SSL_read(ssl, bp, n)) &lt;= 0) {
  561. <span class="enscript-keyword">if</span> ((n = SSL_get_error(ssl, n))) {
  562. <span class="enscript-keyword">return</span>(-1);
  563. }
  564. }
  565. <span class="enscript-comment">/* Check for case where our single character turned out to
  566. * be a newline... (It wasn't going to get caught by
  567. * the strchr above if it came from the hack... ). */</span>
  568. <span class="enscript-keyword">if</span>( NULL == newline &amp;&amp; 1 == n &amp;&amp; <span class="enscript-string">'\n'</span> == *bp ) {
  569. <span class="enscript-comment">/* Got our newline - this will break
  570. out of the loop now */</span>
  571. newline = bp;
  572. }
  573. }
  574. <span class="enscript-keyword">else</span>
  575. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
  576. {
  577. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
  578. <span class="enscript-keyword">if</span> ((n = fm_read(sock, bp, 1)) &lt;= 0)
  579. #<span class="enscript-reference">else</span>
  580. <span class="enscript-keyword">if</span> ((n = fm_peek(sock, bp, len)) &lt;= 0)
  581. #<span class="enscript-reference">endif</span>
  582. <span class="enscript-keyword">return</span> (-1);
  583. <span class="enscript-keyword">if</span> ((newline = memchr(bp, <span class="enscript-string">'\n'</span>, n)) != NULL)
  584. n = newline - bp + 1;
  585. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">__BEOS__</span>
  586. <span class="enscript-keyword">if</span> ((n = fm_read(sock, bp, n)) == -1)
  587. <span class="enscript-keyword">return</span>(-1);
  588. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* __BEOS__ */</span>
  589. }
  590. bp += n;
  591. len -= n;
  592. } <span class="enscript-keyword">while</span>
  593. (!newline &amp;&amp; len);
  594. *bp = <span class="enscript-string">'\0'</span>;
  595. <span class="enscript-keyword">return</span> bp - buf;
  596. }
  597. <span class="enscript-type">int</span> <span class="enscript-function-name">SockPeek</span>(<span class="enscript-type">int</span> sock)
  598. <span class="enscript-comment">/* peek at the next socket character without actually reading it */</span>
  599. {
  600. <span class="enscript-type">int</span> n;
  601. <span class="enscript-type">char</span> ch;
  602. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  603. SSL *ssl;
  604. #<span class="enscript-reference">endif</span>
  605. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  606. <span class="enscript-keyword">if</span>( NULL != ( ssl = SSLGetContext( sock ) ) ) {
  607. n = SSL_peek(ssl, &amp;ch, 1);
  608. <span class="enscript-keyword">if</span> (n &lt; 0) {
  609. (<span class="enscript-type">void</span>)SSL_get_error(ssl, n);
  610. <span class="enscript-keyword">return</span> -1;
  611. }
  612. <span class="enscript-keyword">if</span>( 0 == n ) {
  613. <span class="enscript-comment">/* This code really needs to implement a &quot;hold back&quot;
  614. * to simulate a functioning SSL_peek()... sigh...
  615. * Has to be coordinated with the read code above.
  616. * Next on the list todo... */</span>
  617. <span class="enscript-comment">/* SSL_peek says 0... Does that mean no data
  618. or did the connection blow up? If we got an error
  619. then bail! */</span>
  620. <span class="enscript-keyword">if</span>( 0 != ( n = SSL_get_error(ssl, n) ) ) {
  621. <span class="enscript-keyword">return</span> -1;
  622. }
  623. <span class="enscript-comment">/* Haven't seen this case actually occur, but...
  624. if the problem in SockRead can occur, this should
  625. be possible... Just not sure what to do here.
  626. This should be a safe &quot;punt&quot; the &quot;peek&quot; but don't
  627. &quot;punt&quot; the &quot;session&quot;... */</span>
  628. <span class="enscript-keyword">return</span> 0; <span class="enscript-comment">/* Give him a '\0' character */</span>
  629. }
  630. }
  631. <span class="enscript-keyword">else</span>
  632. #<span class="enscript-reference">endif</span> <span class="enscript-comment">/* SSL_ENABLE */</span>
  633. n = fm_peek(sock, &amp;ch, 1);
  634. <span class="enscript-keyword">if</span> (n == -1)
  635. <span class="enscript-keyword">return</span> -1;
  636. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">__BEOS__</span>
  637. peeked = ch;
  638. #<span class="enscript-reference">endif</span>
  639. <span class="enscript-keyword">return</span>(ch);
  640. }
  641. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">SSL_ENABLE</span>
  642. <span class="enscript-type">static</span> <span class="enscript-type">char</span> *_ssl_server_cname = NULL;
  643. <span class="enscript-type">static</span> <span class="enscript-type">int</span> _check_fp;
  644. <span class="enscript-type">static</span> <span class="enscript-type">char</span> *_check_digest;
  645. <span class="enscript-type">static</span> <span class="enscript-type">char</span> *_server_label;
  646. <span class="enscript-type">static</span> <span class="enscript-type">int</span> _depth0ck;
  647. SSL *<span class="enscript-function-name">SSLGetContext</span>( <span class="enscript-type">int</span> sock )
  648. {
  649. <span class="enscript-comment">/* If SSLOpen has never initialized - just return NULL */</span>
  650. <span class="enscript-keyword">if</span>( NULL == _ctx )
  651. <span class="enscript-keyword">return</span> NULL;
  652. <span class="enscript-keyword">if</span>( sock &lt; 0 || sock &gt; FD_SETSIZE )
  653. <span class="enscript-keyword">return</span> NULL;
  654. <span class="enscript-keyword">return</span> _ssl_context[sock];
  655. }
  656. <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 )
  657. {
  658. <span class="enscript-type">char</span> buf[257];
  659. X509 *x509_cert;
  660. <span class="enscript-type">int</span> err, depth;
  661. <span class="enscript-type">unsigned</span> <span class="enscript-type">char</span> digest[EVP_MAX_MD_SIZE];
  662. <span class="enscript-type">char</span> text[EVP_MAX_MD_SIZE * 3 + 1], *tp, *te;
  663. EVP_MD *digest_tp;
  664. <span class="enscript-type">unsigned</span> <span class="enscript-type">int</span> dsz, i, esz;
  665. X509_NAME *subj, *issuer;
  666. x509_cert = X509_STORE_CTX_get_current_cert(ctx);
  667. err = X509_STORE_CTX_get_error(ctx);
  668. depth = X509_STORE_CTX_get_error_depth(ctx);
  669. subj = X509_get_subject_name(x509_cert);
  670. issuer = X509_get_issuer_name(x509_cert);
  671. <span class="enscript-keyword">if</span> (depth == 0) {
  672. _depth0ck = 1;
  673. <span class="enscript-keyword">if</span> (outlevel == O_VERBOSE) {
  674. <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) {
  675. report(stdout, GT_(<span class="enscript-string">&quot;Issuer Organization: %s\n&quot;</span>), buf);
  676. <span class="enscript-keyword">if</span> (i &gt;= <span class="enscript-keyword">sizeof</span>(buf) - 1)
  677. report(stdout, GT_(<span class="enscript-string">&quot;Warning: Issuer Organization Name too long (possibly truncated).\n&quot;</span>));
  678. } <span class="enscript-keyword">else</span>
  679. report(stdout, GT_(<span class="enscript-string">&quot;Unknown Organization\n&quot;</span>));
  680. <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) {
  681. report(stdout, GT_(<span class="enscript-string">&quot;Issuer CommonName: %s\n&quot;</span>), buf);
  682. <span class="enscript-keyword">if</span> (i &gt;= <span class="enscript-keyword">sizeof</span>(buf) - 1)
  683. report(stdout, GT_(<span class="enscript-string">&quot;Warning: Issuer CommonName too long (possibly truncated).\n&quot;</span>));
  684. } <span class="enscript-keyword">else</span>
  685. report(stdout, GT_(<span class="enscript-string">&quot;Unknown Issuer CommonName\n&quot;</span>));
  686. }
  687. <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) {
  688. <span class="enscript-keyword">if</span> (outlevel == O_VERBOSE)
  689. report(stdout, GT_(<span class="enscript-string">&quot;Server CommonName: %s\n&quot;</span>), buf);
  690. <span class="enscript-keyword">if</span> (i &gt;= <span class="enscript-keyword">sizeof</span>(buf) - 1) {
  691. <span class="enscript-comment">/* Possible truncation. In this case, this is a DNS name, so this
  692. * is really bad. We do not tolerate this even in the non-strict case. */</span>
  693. report(stderr, GT_(<span class="enscript-string">&quot;Bad certificate: Subject CommonName too long!\n&quot;</span>));
  694. <span class="enscript-keyword">return</span> (0);
  695. }
  696. <span class="enscript-keyword">if</span> (_ssl_server_cname != NULL) {
  697. <span class="enscript-type">char</span> *p1 = buf;
  698. <span class="enscript-type">char</span> *p2 = _ssl_server_cname;
  699. <span class="enscript-type">int</span> n;
  700. <span class="enscript-keyword">if</span> (*p1 == <span class="enscript-string">'*'</span>) {
  701. ++p1;
  702. n = strlen(p2) - strlen(p1);
  703. <span class="enscript-keyword">if</span> (n &gt;= 0)
  704. p2 += n;
  705. }
  706. <span class="enscript-keyword">if</span> (0 != strcasecmp(p1, p2)) {
  707. report(stderr,
  708. GT_(<span class="enscript-string">&quot;Server CommonName mismatch: %s != %s\n&quot;</span>),
  709. buf, _ssl_server_cname );
  710. <span class="enscript-keyword">if</span> (ok_return &amp;&amp; strict)
  711. <span class="enscript-keyword">return</span> (0);
  712. }
  713. } <span class="enscript-keyword">else</span> <span class="enscript-keyword">if</span> (ok_return &amp;&amp; strict) {
  714. report(stderr, GT_(<span class="enscript-string">&quot;Server name not set, could not verify certificate!\n&quot;</span>));
  715. <span class="enscript-keyword">return</span> (0);
  716. }
  717. } <span class="enscript-keyword">else</span> {
  718. <span class="enscript-keyword">if</span> (outlevel == O_VERBOSE)
  719. report(stdout, GT_(<span class="enscript-string">&quot;Unknown Server CommonName\n&quot;</span>));
  720. <span class="enscript-keyword">if</span> (ok_return &amp;&amp; strict) {
  721. report(stderr, GT_(<span class="enscript-string">&quot;Server name not specified in certificate!\n&quot;</span>));
  722. <span class="enscript-keyword">return</span> (0);
  723. }
  724. }
  725. <span class="enscript-comment">/* Print the finger print. Note that on errors, we might print it more than once
  726. * normally; we kluge around that by using a global variable. */</span>
  727. <span class="enscript-keyword">if</span> (_check_fp) {
  728. _check_fp = 0;
  729. digest_tp = EVP_md5();
  730. <span class="enscript-keyword">if</span> (digest_tp == NULL) {
  731. report(stderr, GT_(<span class="enscript-string">&quot;EVP_md5() failed!\n&quot;</span>));
  732. <span class="enscript-keyword">return</span> (0);
  733. }
  734. <span class="enscript-keyword">if</span> (!X509_digest(x509_cert, digest_tp, digest, &amp;dsz)) {
  735. report(stderr, GT_(<span class="enscript-string">&quot;Out of memory!\n&quot;</span>));
  736. <span class="enscript-keyword">return</span> (0);
  737. }
  738. tp = text;
  739. te = text + <span class="enscript-keyword">sizeof</span>(text);
  740. <span class="enscript-keyword">for</span> (i = 0; i &lt; dsz; i++) {
  741. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SNPRINTF</span>
  742. esz = snprintf(tp, te - tp, i &gt; 0 ? <span class="enscript-string">&quot;:%02X&quot;</span> : <span class="enscript-string">&quot;%02X&quot;</span>, digest[i]);
  743. #<span class="enscript-reference">else</span>
  744. esz = sprintf(tp, i &gt; 0 ? <span class="enscript-string">&quot;:%02X&quot;</span> : <span class="enscript-string">&quot;%02X&quot;</span>, digest[i]);
  745. #<span class="enscript-reference">endif</span>
  746. <span class="enscript-keyword">if</span> (esz &gt;= te - tp) {
  747. report(stderr, GT_(<span class="enscript-string">&quot;Digest text buffer too small!\n&quot;</span>));
  748. <span class="enscript-keyword">return</span> (0);
  749. }
  750. tp += esz;
  751. }
  752. <span class="enscript-keyword">if</span> (outlevel &gt; O_NORMAL)
  753. report(stdout, GT_(<span class="enscript-string">&quot;%s key fingerprint: %s\n&quot;</span>), _server_label, text);
  754. <span class="enscript-keyword">if</span> (_check_digest != NULL) {
  755. <span class="enscript-keyword">if</span> (strcmp(text, _check_digest) == 0) {
  756. <span class="enscript-keyword">if</span> (outlevel &gt; O_NORMAL)
  757. report(stdout, GT_(<span class="enscript-string">&quot;%s fingerprints match.\n&quot;</span>), _server_label);
  758. } <span class="enscript-keyword">else</span> {
  759. <span class="enscript-keyword">if</span> (outlevel &gt; O_SILENT)
  760. report(stderr, GT_(<span class="enscript-string">&quot;%s fingerprints do not match!\n&quot;</span>), _server_label);
  761. <span class="enscript-keyword">return</span> (0);
  762. }
  763. }
  764. }
  765. }
  766. <span class="enscript-keyword">if</span> (err != X509_V_OK &amp;&amp; (strict || outlevel == O_VERBOSE)) {
  767. report(strict ? stderr : stdout, GT_(<span class="enscript-string">&quot;Warning: server certificate verification: %s\n&quot;</span>), X509_verify_cert_error_string(err));
  768. <span class="enscript-comment">/* We gave the error code, but maybe we can add some more details for debugging */</span>
  769. <span class="enscript-keyword">switch</span> (err) {
  770. <span class="enscript-keyword">case</span> <span class="en…

Large files files are truncated, but you can click here to view the full file