PageRenderTime 62ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/opensource.apple.com/source/fetchmail/fetchmail-4.1/fetchmail/socket.c

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

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