nginxtra 1.0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (363) hide show
  1. data/VERSION +1 -0
  2. data/bin/nginxtra +5 -0
  3. data/lib/nginxtra.rb +12 -0
  4. data/lib/nginxtra/action.rb +36 -0
  5. data/lib/nginxtra/actions/compile.rb +60 -0
  6. data/lib/nginxtra/actions/install.rb +99 -0
  7. data/lib/nginxtra/actions/reload.rb +14 -0
  8. data/lib/nginxtra/actions/restart.rb +15 -0
  9. data/lib/nginxtra/actions/start.rb +53 -0
  10. data/lib/nginxtra/actions/status.rb +31 -0
  11. data/lib/nginxtra/actions/stop.rb +14 -0
  12. data/lib/nginxtra/cli.rb +77 -0
  13. data/lib/nginxtra/config.rb +339 -0
  14. data/lib/nginxtra/error.rb +13 -0
  15. data/lib/nginxtra/status.rb +57 -0
  16. data/src/nginx/CHANGES +5630 -0
  17. data/src/nginx/CHANGES.ru +5716 -0
  18. data/src/nginx/LICENSE +25 -0
  19. data/src/nginx/README +3 -0
  20. data/src/nginx/auto/cc/acc +15 -0
  21. data/src/nginx/auto/cc/bcc +72 -0
  22. data/src/nginx/auto/cc/ccc +46 -0
  23. data/src/nginx/auto/cc/conf +189 -0
  24. data/src/nginx/auto/cc/gcc +183 -0
  25. data/src/nginx/auto/cc/icc +121 -0
  26. data/src/nginx/auto/cc/msvc +138 -0
  27. data/src/nginx/auto/cc/name +101 -0
  28. data/src/nginx/auto/cc/owc +104 -0
  29. data/src/nginx/auto/cc/sunc +158 -0
  30. data/src/nginx/auto/define +12 -0
  31. data/src/nginx/auto/endianess +45 -0
  32. data/src/nginx/auto/feature +123 -0
  33. data/src/nginx/auto/have +12 -0
  34. data/src/nginx/auto/have_headers +12 -0
  35. data/src/nginx/auto/headers +13 -0
  36. data/src/nginx/auto/include +61 -0
  37. data/src/nginx/auto/init +51 -0
  38. data/src/nginx/auto/install +184 -0
  39. data/src/nginx/auto/lib/conf +83 -0
  40. data/src/nginx/auto/lib/geoip/conf +79 -0
  41. data/src/nginx/auto/lib/google-perftools/conf +45 -0
  42. data/src/nginx/auto/lib/libatomic/conf +43 -0
  43. data/src/nginx/auto/lib/libatomic/make +14 -0
  44. data/src/nginx/auto/lib/libgd/conf +83 -0
  45. data/src/nginx/auto/lib/libxslt/conf +156 -0
  46. data/src/nginx/auto/lib/make +32 -0
  47. data/src/nginx/auto/lib/md5/conf +103 -0
  48. data/src/nginx/auto/lib/md5/make +96 -0
  49. data/src/nginx/auto/lib/md5/makefile.bcc +22 -0
  50. data/src/nginx/auto/lib/md5/makefile.msvc +22 -0
  51. data/src/nginx/auto/lib/md5/makefile.owc +11 -0
  52. data/src/nginx/auto/lib/openssl/conf +74 -0
  53. data/src/nginx/auto/lib/openssl/make +67 -0
  54. data/src/nginx/auto/lib/openssl/makefile.bcc +18 -0
  55. data/src/nginx/auto/lib/openssl/makefile.msvc +14 -0
  56. data/src/nginx/auto/lib/pcre/conf +180 -0
  57. data/src/nginx/auto/lib/pcre/make +64 -0
  58. data/src/nginx/auto/lib/pcre/makefile.bcc +26 -0
  59. data/src/nginx/auto/lib/pcre/makefile.msvc +22 -0
  60. data/src/nginx/auto/lib/pcre/makefile.owc +24 -0
  61. data/src/nginx/auto/lib/perl/conf +60 -0
  62. data/src/nginx/auto/lib/perl/make +36 -0
  63. data/src/nginx/auto/lib/sha1/conf +79 -0
  64. data/src/nginx/auto/lib/sha1/make +96 -0
  65. data/src/nginx/auto/lib/sha1/makefile.bcc +22 -0
  66. data/src/nginx/auto/lib/sha1/makefile.msvc +22 -0
  67. data/src/nginx/auto/lib/sha1/makefile.owc +11 -0
  68. data/src/nginx/auto/lib/test +40 -0
  69. data/src/nginx/auto/lib/zlib/conf +76 -0
  70. data/src/nginx/auto/lib/zlib/make +114 -0
  71. data/src/nginx/auto/lib/zlib/makefile.bcc +15 -0
  72. data/src/nginx/auto/lib/zlib/makefile.msvc +14 -0
  73. data/src/nginx/auto/lib/zlib/makefile.owc +14 -0
  74. data/src/nginx/auto/lib/zlib/patch.zlib.h +10 -0
  75. data/src/nginx/auto/make +417 -0
  76. data/src/nginx/auto/modules +479 -0
  77. data/src/nginx/auto/nohave +12 -0
  78. data/src/nginx/auto/options +490 -0
  79. data/src/nginx/auto/os/conf +105 -0
  80. data/src/nginx/auto/os/darwin +116 -0
  81. data/src/nginx/auto/os/freebsd +136 -0
  82. data/src/nginx/auto/os/linux +152 -0
  83. data/src/nginx/auto/os/solaris +60 -0
  84. data/src/nginx/auto/os/win32 +29 -0
  85. data/src/nginx/auto/sources +518 -0
  86. data/src/nginx/auto/stubs +8 -0
  87. data/src/nginx/auto/summary +114 -0
  88. data/src/nginx/auto/types/sizeof +83 -0
  89. data/src/nginx/auto/types/typedef +77 -0
  90. data/src/nginx/auto/types/uintptr_t +42 -0
  91. data/src/nginx/auto/types/value +12 -0
  92. data/src/nginx/auto/unix +719 -0
  93. data/src/nginx/conf/fastcgi.conf +24 -0
  94. data/src/nginx/conf/fastcgi_params +23 -0
  95. data/src/nginx/conf/koi-utf +109 -0
  96. data/src/nginx/conf/koi-win +103 -0
  97. data/src/nginx/conf/mime.types +80 -0
  98. data/src/nginx/conf/nginx.conf +118 -0
  99. data/src/nginx/conf/scgi_params +15 -0
  100. data/src/nginx/conf/uwsgi_params +15 -0
  101. data/src/nginx/conf/win-utf +126 -0
  102. data/src/nginx/configure +108 -0
  103. data/src/nginx/contrib/README +15 -0
  104. data/src/nginx/contrib/geo2nginx.pl +58 -0
  105. data/src/nginx/contrib/unicode2nginx/koi-utf +131 -0
  106. data/src/nginx/contrib/unicode2nginx/unicode-to-nginx.pl +45 -0
  107. data/src/nginx/contrib/unicode2nginx/win-utf +130 -0
  108. data/src/nginx/html/50x.html +18 -0
  109. data/src/nginx/html/index.html +8 -0
  110. data/src/nginx/man/nginx.8 +202 -0
  111. data/src/nginx/src/core/nginx.c +1333 -0
  112. data/src/nginx/src/core/nginx.h +20 -0
  113. data/src/nginx/src/core/ngx_array.c +147 -0
  114. data/src/nginx/src/core/ngx_array.h +53 -0
  115. data/src/nginx/src/core/ngx_buf.c +218 -0
  116. data/src/nginx/src/core/ngx_buf.h +162 -0
  117. data/src/nginx/src/core/ngx_conf_file.c +1506 -0
  118. data/src/nginx/src/core/ngx_conf_file.h +348 -0
  119. data/src/nginx/src/core/ngx_config.h +134 -0
  120. data/src/nginx/src/core/ngx_connection.c +1074 -0
  121. data/src/nginx/src/core/ngx_connection.h +195 -0
  122. data/src/nginx/src/core/ngx_core.h +95 -0
  123. data/src/nginx/src/core/ngx_cpuinfo.c +139 -0
  124. data/src/nginx/src/core/ngx_crc.h +39 -0
  125. data/src/nginx/src/core/ngx_crc32.c +129 -0
  126. data/src/nginx/src/core/ngx_crc32.h +79 -0
  127. data/src/nginx/src/core/ngx_crypt.c +238 -0
  128. data/src/nginx/src/core/ngx_crypt.h +20 -0
  129. data/src/nginx/src/core/ngx_cycle.c +1379 -0
  130. data/src/nginx/src/core/ngx_cycle.h +142 -0
  131. data/src/nginx/src/core/ngx_file.c +993 -0
  132. data/src/nginx/src/core/ngx_file.h +151 -0
  133. data/src/nginx/src/core/ngx_hash.c +976 -0
  134. data/src/nginx/src/core/ngx_hash.h +122 -0
  135. data/src/nginx/src/core/ngx_inet.c +1008 -0
  136. data/src/nginx/src/core/ngx_inet.h +120 -0
  137. data/src/nginx/src/core/ngx_list.c +71 -0
  138. data/src/nginx/src/core/ngx_list.h +83 -0
  139. data/src/nginx/src/core/ngx_log.c +459 -0
  140. data/src/nginx/src/core/ngx_log.h +250 -0
  141. data/src/nginx/src/core/ngx_md5.c +289 -0
  142. data/src/nginx/src/core/ngx_md5.h +60 -0
  143. data/src/nginx/src/core/ngx_murmurhash.c +50 -0
  144. data/src/nginx/src/core/ngx_murmurhash.h +19 -0
  145. data/src/nginx/src/core/ngx_open_file_cache.c +882 -0
  146. data/src/nginx/src/core/ngx_open_file_cache.h +119 -0
  147. data/src/nginx/src/core/ngx_output_chain.c +673 -0
  148. data/src/nginx/src/core/ngx_palloc.c +433 -0
  149. data/src/nginx/src/core/ngx_palloc.h +95 -0
  150. data/src/nginx/src/core/ngx_parse.c +249 -0
  151. data/src/nginx/src/core/ngx_parse.h +24 -0
  152. data/src/nginx/src/core/ngx_queue.c +80 -0
  153. data/src/nginx/src/core/ngx_queue.h +112 -0
  154. data/src/nginx/src/core/ngx_radix_tree.c +291 -0
  155. data/src/nginx/src/core/ngx_radix_tree.h +46 -0
  156. data/src/nginx/src/core/ngx_rbtree.c +383 -0
  157. data/src/nginx/src/core/ngx_rbtree.h +84 -0
  158. data/src/nginx/src/core/ngx_regex.c +206 -0
  159. data/src/nginx/src/core/ngx_regex.h +56 -0
  160. data/src/nginx/src/core/ngx_resolver.c +2201 -0
  161. data/src/nginx/src/core/ngx_resolver.h +149 -0
  162. data/src/nginx/src/core/ngx_sha1.h +31 -0
  163. data/src/nginx/src/core/ngx_shmtx.c +284 -0
  164. data/src/nginx/src/core/ngx_shmtx.h +38 -0
  165. data/src/nginx/src/core/ngx_slab.c +701 -0
  166. data/src/nginx/src/core/ngx_slab.h +54 -0
  167. data/src/nginx/src/core/ngx_spinlock.c +53 -0
  168. data/src/nginx/src/core/ngx_string.c +1837 -0
  169. data/src/nginx/src/core/ngx_string.h +231 -0
  170. data/src/nginx/src/core/ngx_times.c +407 -0
  171. data/src/nginx/src/core/ngx_times.h +51 -0
  172. data/src/nginx/src/event/modules/ngx_aio_module.c +171 -0
  173. data/src/nginx/src/event/modules/ngx_devpoll_module.c +569 -0
  174. data/src/nginx/src/event/modules/ngx_epoll_module.c +833 -0
  175. data/src/nginx/src/event/modules/ngx_eventport_module.c +602 -0
  176. data/src/nginx/src/event/modules/ngx_kqueue_module.c +785 -0
  177. data/src/nginx/src/event/modules/ngx_poll_module.c +443 -0
  178. data/src/nginx/src/event/modules/ngx_rtsig_module.c +735 -0
  179. data/src/nginx/src/event/modules/ngx_select_module.c +435 -0
  180. data/src/nginx/src/event/modules/ngx_win32_select_module.c +400 -0
  181. data/src/nginx/src/event/ngx_event.c +1275 -0
  182. data/src/nginx/src/event/ngx_event.h +573 -0
  183. data/src/nginx/src/event/ngx_event_accept.c +428 -0
  184. data/src/nginx/src/event/ngx_event_busy_lock.c +286 -0
  185. data/src/nginx/src/event/ngx_event_busy_lock.h +65 -0
  186. data/src/nginx/src/event/ngx_event_connect.c +258 -0
  187. data/src/nginx/src/event/ngx_event_connect.h +76 -0
  188. data/src/nginx/src/event/ngx_event_mutex.c +70 -0
  189. data/src/nginx/src/event/ngx_event_openssl.c +2382 -0
  190. data/src/nginx/src/event/ngx_event_openssl.h +162 -0
  191. data/src/nginx/src/event/ngx_event_pipe.c +996 -0
  192. data/src/nginx/src/event/ngx_event_pipe.h +95 -0
  193. data/src/nginx/src/event/ngx_event_posted.c +173 -0
  194. data/src/nginx/src/event/ngx_event_posted.h +75 -0
  195. data/src/nginx/src/event/ngx_event_timer.c +159 -0
  196. data/src/nginx/src/event/ngx_event_timer.h +102 -0
  197. data/src/nginx/src/http/modules/ngx_http_access_module.c +384 -0
  198. data/src/nginx/src/http/modules/ngx_http_addition_filter_module.c +250 -0
  199. data/src/nginx/src/http/modules/ngx_http_auth_basic_module.c +478 -0
  200. data/src/nginx/src/http/modules/ngx_http_autoindex_module.c +701 -0
  201. data/src/nginx/src/http/modules/ngx_http_browser_module.c +713 -0
  202. data/src/nginx/src/http/modules/ngx_http_charset_filter_module.c +1681 -0
  203. data/src/nginx/src/http/modules/ngx_http_chunked_filter_module.c +242 -0
  204. data/src/nginx/src/http/modules/ngx_http_dav_module.c +1141 -0
  205. data/src/nginx/src/http/modules/ngx_http_degradation_module.c +243 -0
  206. data/src/nginx/src/http/modules/ngx_http_empty_gif_module.c +140 -0
  207. data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +2916 -0
  208. data/src/nginx/src/http/modules/ngx_http_flv_module.c +254 -0
  209. data/src/nginx/src/http/modules/ngx_http_geo_module.c +1441 -0
  210. data/src/nginx/src/http/modules/ngx_http_geoip_module.c +671 -0
  211. data/src/nginx/src/http/modules/ngx_http_gzip_filter_module.c +1206 -0
  212. data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +299 -0
  213. data/src/nginx/src/http/modules/ngx_http_headers_filter_module.c +616 -0
  214. data/src/nginx/src/http/modules/ngx_http_image_filter_module.c +1489 -0
  215. data/src/nginx/src/http/modules/ngx_http_index_module.c +516 -0
  216. data/src/nginx/src/http/modules/ngx_http_limit_req_module.c +809 -0
  217. data/src/nginx/src/http/modules/ngx_http_limit_zone_module.c +553 -0
  218. data/src/nginx/src/http/modules/ngx_http_log_module.c +1357 -0
  219. data/src/nginx/src/http/modules/ngx_http_map_module.c +575 -0
  220. data/src/nginx/src/http/modules/ngx_http_memcached_module.c +624 -0
  221. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +3000 -0
  222. data/src/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +143 -0
  223. data/src/nginx/src/http/modules/ngx_http_proxy_module.c +2831 -0
  224. data/src/nginx/src/http/modules/ngx_http_random_index_module.c +317 -0
  225. data/src/nginx/src/http/modules/ngx_http_range_filter_module.c +855 -0
  226. data/src/nginx/src/http/modules/ngx_http_realip_module.c +476 -0
  227. data/src/nginx/src/http/modules/ngx_http_referer_module.c +613 -0
  228. data/src/nginx/src/http/modules/ngx_http_rewrite_module.c +1019 -0
  229. data/src/nginx/src/http/modules/ngx_http_scgi_module.c +1714 -0
  230. data/src/nginx/src/http/modules/ngx_http_secure_link_module.c +355 -0
  231. data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +242 -0
  232. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.c +2913 -0
  233. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.h +114 -0
  234. data/src/nginx/src/http/modules/ngx_http_ssl_module.c +652 -0
  235. data/src/nginx/src/http/modules/ngx_http_ssl_module.h +52 -0
  236. data/src/nginx/src/http/modules/ngx_http_static_module.c +278 -0
  237. data/src/nginx/src/http/modules/ngx_http_stub_status_module.c +144 -0
  238. data/src/nginx/src/http/modules/ngx_http_sub_filter_module.c +716 -0
  239. data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +237 -0
  240. data/src/nginx/src/http/modules/ngx_http_userid_filter_module.c +846 -0
  241. data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +1774 -0
  242. data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +984 -0
  243. data/src/nginx/src/http/modules/perl/Makefile.PL +42 -0
  244. data/src/nginx/src/http/modules/perl/nginx.pm +137 -0
  245. data/src/nginx/src/http/modules/perl/nginx.xs +986 -0
  246. data/src/nginx/src/http/modules/perl/ngx_http_perl_module.c +1076 -0
  247. data/src/nginx/src/http/modules/perl/ngx_http_perl_module.h +67 -0
  248. data/src/nginx/src/http/modules/perl/typemap +3 -0
  249. data/src/nginx/src/http/ngx_http.c +2073 -0
  250. data/src/nginx/src/http/ngx_http.h +160 -0
  251. data/src/nginx/src/http/ngx_http_busy_lock.c +307 -0
  252. data/src/nginx/src/http/ngx_http_busy_lock.h +54 -0
  253. data/src/nginx/src/http/ngx_http_cache.h +148 -0
  254. data/src/nginx/src/http/ngx_http_config.h +75 -0
  255. data/src/nginx/src/http/ngx_http_copy_filter_module.c +300 -0
  256. data/src/nginx/src/http/ngx_http_core_module.c +4736 -0
  257. data/src/nginx/src/http/ngx_http_core_module.h +541 -0
  258. data/src/nginx/src/http/ngx_http_file_cache.c +1715 -0
  259. data/src/nginx/src/http/ngx_http_header_filter_module.c +623 -0
  260. data/src/nginx/src/http/ngx_http_parse.c +1734 -0
  261. data/src/nginx/src/http/ngx_http_parse_time.c +276 -0
  262. data/src/nginx/src/http/ngx_http_postpone_filter_module.c +178 -0
  263. data/src/nginx/src/http/ngx_http_request.c +3181 -0
  264. data/src/nginx/src/http/ngx_http_request.h +573 -0
  265. data/src/nginx/src/http/ngx_http_request_body.c +644 -0
  266. data/src/nginx/src/http/ngx_http_script.c +1752 -0
  267. data/src/nginx/src/http/ngx_http_script.h +257 -0
  268. data/src/nginx/src/http/ngx_http_special_response.c +789 -0
  269. data/src/nginx/src/http/ngx_http_upstream.c +4555 -0
  270. data/src/nginx/src/http/ngx_http_upstream.h +350 -0
  271. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +791 -0
  272. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +85 -0
  273. data/src/nginx/src/http/ngx_http_variables.c +2053 -0
  274. data/src/nginx/src/http/ngx_http_variables.h +115 -0
  275. data/src/nginx/src/http/ngx_http_write_filter_module.c +315 -0
  276. data/src/nginx/src/mail/ngx_mail.c +542 -0
  277. data/src/nginx/src/mail/ngx_mail.h +407 -0
  278. data/src/nginx/src/mail/ngx_mail_auth_http_module.c +1452 -0
  279. data/src/nginx/src/mail/ngx_mail_core_module.c +553 -0
  280. data/src/nginx/src/mail/ngx_mail_handler.c +773 -0
  281. data/src/nginx/src/mail/ngx_mail_imap_handler.c +457 -0
  282. data/src/nginx/src/mail/ngx_mail_imap_module.c +253 -0
  283. data/src/nginx/src/mail/ngx_mail_imap_module.h +39 -0
  284. data/src/nginx/src/mail/ngx_mail_parse.c +885 -0
  285. data/src/nginx/src/mail/ngx_mail_pop3_handler.c +500 -0
  286. data/src/nginx/src/mail/ngx_mail_pop3_module.c +264 -0
  287. data/src/nginx/src/mail/ngx_mail_pop3_module.h +38 -0
  288. data/src/nginx/src/mail/ngx_mail_proxy_module.c +1089 -0
  289. data/src/nginx/src/mail/ngx_mail_smtp_handler.c +872 -0
  290. data/src/nginx/src/mail/ngx_mail_smtp_module.c +308 -0
  291. data/src/nginx/src/mail/ngx_mail_smtp_module.h +45 -0
  292. data/src/nginx/src/mail/ngx_mail_ssl_module.c +491 -0
  293. data/src/nginx/src/mail/ngx_mail_ssl_module.h +52 -0
  294. data/src/nginx/src/misc/ngx_cpp_test_module.cpp +27 -0
  295. data/src/nginx/src/misc/ngx_google_perftools_module.c +126 -0
  296. data/src/nginx/src/os/unix/ngx_aio_read.c +109 -0
  297. data/src/nginx/src/os/unix/ngx_aio_read_chain.c +78 -0
  298. data/src/nginx/src/os/unix/ngx_aio_write.c +109 -0
  299. data/src/nginx/src/os/unix/ngx_aio_write_chain.c +100 -0
  300. data/src/nginx/src/os/unix/ngx_alloc.c +90 -0
  301. data/src/nginx/src/os/unix/ngx_alloc.h +45 -0
  302. data/src/nginx/src/os/unix/ngx_atomic.h +311 -0
  303. data/src/nginx/src/os/unix/ngx_channel.c +258 -0
  304. data/src/nginx/src/os/unix/ngx_channel.h +34 -0
  305. data/src/nginx/src/os/unix/ngx_daemon.c +69 -0
  306. data/src/nginx/src/os/unix/ngx_darwin.h +20 -0
  307. data/src/nginx/src/os/unix/ngx_darwin_config.h +96 -0
  308. data/src/nginx/src/os/unix/ngx_darwin_init.c +166 -0
  309. data/src/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +366 -0
  310. data/src/nginx/src/os/unix/ngx_errno.c +87 -0
  311. data/src/nginx/src/os/unix/ngx_errno.h +68 -0
  312. data/src/nginx/src/os/unix/ngx_file_aio_read.c +208 -0
  313. data/src/nginx/src/os/unix/ngx_files.c +566 -0
  314. data/src/nginx/src/os/unix/ngx_files.h +343 -0
  315. data/src/nginx/src/os/unix/ngx_freebsd.h +24 -0
  316. data/src/nginx/src/os/unix/ngx_freebsd_config.h +119 -0
  317. data/src/nginx/src/os/unix/ngx_freebsd_init.c +259 -0
  318. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +756 -0
  319. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +122 -0
  320. data/src/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +436 -0
  321. data/src/nginx/src/os/unix/ngx_gcc_atomic_amd64.h +82 -0
  322. data/src/nginx/src/os/unix/ngx_gcc_atomic_ppc.h +155 -0
  323. data/src/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h +82 -0
  324. data/src/nginx/src/os/unix/ngx_gcc_atomic_x86.h +127 -0
  325. data/src/nginx/src/os/unix/ngx_linux.h +18 -0
  326. data/src/nginx/src/os/unix/ngx_linux_aio_read.c +137 -0
  327. data/src/nginx/src/os/unix/ngx_linux_config.h +117 -0
  328. data/src/nginx/src/os/unix/ngx_linux_init.c +91 -0
  329. data/src/nginx/src/os/unix/ngx_linux_sendfile_chain.c +378 -0
  330. data/src/nginx/src/os/unix/ngx_os.h +84 -0
  331. data/src/nginx/src/os/unix/ngx_posix_config.h +153 -0
  332. data/src/nginx/src/os/unix/ngx_posix_init.c +124 -0
  333. data/src/nginx/src/os/unix/ngx_process.c +590 -0
  334. data/src/nginx/src/os/unix/ngx_process.h +87 -0
  335. data/src/nginx/src/os/unix/ngx_process_cycle.c +1390 -0
  336. data/src/nginx/src/os/unix/ngx_process_cycle.h +61 -0
  337. data/src/nginx/src/os/unix/ngx_pthread_thread.c +278 -0
  338. data/src/nginx/src/os/unix/ngx_readv_chain.c +258 -0
  339. data/src/nginx/src/os/unix/ngx_recv.c +180 -0
  340. data/src/nginx/src/os/unix/ngx_send.c +73 -0
  341. data/src/nginx/src/os/unix/ngx_setproctitle.c +135 -0
  342. data/src/nginx/src/os/unix/ngx_setproctitle.h +52 -0
  343. data/src/nginx/src/os/unix/ngx_shmem.c +126 -0
  344. data/src/nginx/src/os/unix/ngx_shmem.h +29 -0
  345. data/src/nginx/src/os/unix/ngx_socket.c +116 -0
  346. data/src/nginx/src/os/unix/ngx_socket.h +64 -0
  347. data/src/nginx/src/os/unix/ngx_solaris.h +16 -0
  348. data/src/nginx/src/os/unix/ngx_solaris_config.h +107 -0
  349. data/src/nginx/src/os/unix/ngx_solaris_init.c +75 -0
  350. data/src/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +251 -0
  351. data/src/nginx/src/os/unix/ngx_sunpro_amd64.il +43 -0
  352. data/src/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h +61 -0
  353. data/src/nginx/src/os/unix/ngx_sunpro_sparc64.il +36 -0
  354. data/src/nginx/src/os/unix/ngx_sunpro_x86.il +44 -0
  355. data/src/nginx/src/os/unix/ngx_thread.h +128 -0
  356. data/src/nginx/src/os/unix/ngx_time.c +104 -0
  357. data/src/nginx/src/os/unix/ngx_time.h +66 -0
  358. data/src/nginx/src/os/unix/ngx_udp_recv.c +115 -0
  359. data/src/nginx/src/os/unix/ngx_user.c +109 -0
  360. data/src/nginx/src/os/unix/ngx_user.h +24 -0
  361. data/src/nginx/src/os/unix/ngx_writev_chain.c +181 -0
  362. data/src/nginx/src/os/unix/rfork_thread.S +73 -0
  363. metadata +419 -0
@@ -0,0 +1,2382 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #include <ngx_config.h>
9
+ #include <ngx_core.h>
10
+ #include <ngx_event.h>
11
+
12
+
13
+ typedef struct {
14
+ ngx_uint_t engine; /* unsigned engine:1; */
15
+ } ngx_openssl_conf_t;
16
+
17
+
18
+ static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
19
+ static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
20
+ int ret);
21
+ static void ngx_ssl_handshake_handler(ngx_event_t *ev);
22
+ static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
23
+ static void ngx_ssl_write_handler(ngx_event_t *wev);
24
+ static void ngx_ssl_read_handler(ngx_event_t *rev);
25
+ static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
26
+ static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
27
+ ngx_err_t err, char *text);
28
+ static void ngx_ssl_clear_error(ngx_log_t *log);
29
+
30
+ ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
31
+ static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
32
+ ngx_ssl_session_t *sess);
33
+ static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
34
+ u_char *id, int len, int *copy);
35
+ static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
36
+ static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
37
+ ngx_slab_pool_t *shpool, ngx_uint_t n);
38
+ static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
39
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
40
+
41
+ static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
42
+ static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
43
+ static void ngx_openssl_exit(ngx_cycle_t *cycle);
44
+
45
+
46
+ static ngx_command_t ngx_openssl_commands[] = {
47
+
48
+ { ngx_string("ssl_engine"),
49
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
50
+ ngx_openssl_engine,
51
+ 0,
52
+ 0,
53
+ NULL },
54
+
55
+ ngx_null_command
56
+ };
57
+
58
+
59
+ static ngx_core_module_t ngx_openssl_module_ctx = {
60
+ ngx_string("openssl"),
61
+ ngx_openssl_create_conf,
62
+ NULL
63
+ };
64
+
65
+
66
+ ngx_module_t ngx_openssl_module = {
67
+ NGX_MODULE_V1,
68
+ &ngx_openssl_module_ctx, /* module context */
69
+ ngx_openssl_commands, /* module directives */
70
+ NGX_CORE_MODULE, /* module type */
71
+ NULL, /* init master */
72
+ NULL, /* init module */
73
+ NULL, /* init process */
74
+ NULL, /* init thread */
75
+ NULL, /* exit thread */
76
+ NULL, /* exit process */
77
+ ngx_openssl_exit, /* exit master */
78
+ NGX_MODULE_V1_PADDING
79
+ };
80
+
81
+
82
+ int ngx_ssl_connection_index;
83
+ int ngx_ssl_server_conf_index;
84
+ int ngx_ssl_session_cache_index;
85
+
86
+
87
+ ngx_int_t
88
+ ngx_ssl_init(ngx_log_t *log)
89
+ {
90
+ OPENSSL_config(NULL);
91
+
92
+ SSL_library_init();
93
+ SSL_load_error_strings();
94
+
95
+ OpenSSL_add_all_algorithms();
96
+
97
+ ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
98
+
99
+ if (ngx_ssl_connection_index == -1) {
100
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed");
101
+ return NGX_ERROR;
102
+ }
103
+
104
+ ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
105
+ NULL);
106
+ if (ngx_ssl_server_conf_index == -1) {
107
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
108
+ "SSL_CTX_get_ex_new_index() failed");
109
+ return NGX_ERROR;
110
+ }
111
+
112
+ ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
113
+ NULL);
114
+ if (ngx_ssl_session_cache_index == -1) {
115
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
116
+ "SSL_CTX_get_ex_new_index() failed");
117
+ return NGX_ERROR;
118
+ }
119
+
120
+ return NGX_OK;
121
+ }
122
+
123
+
124
+ ngx_int_t
125
+ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
126
+ {
127
+ ssl->ctx = SSL_CTX_new(SSLv23_method());
128
+
129
+ if (ssl->ctx == NULL) {
130
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed");
131
+ return NGX_ERROR;
132
+ }
133
+
134
+ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) {
135
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
136
+ "SSL_CTX_set_ex_data() failed");
137
+ return NGX_ERROR;
138
+ }
139
+
140
+ /* client side options */
141
+
142
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
143
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
144
+
145
+ /* server side options */
146
+
147
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
148
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
149
+
150
+ /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */
151
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING);
152
+
153
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
154
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
155
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
156
+
157
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
158
+
159
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
160
+
161
+ if (!(protocols & NGX_SSL_SSLv2)) {
162
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2);
163
+ }
164
+ if (!(protocols & NGX_SSL_SSLv3)) {
165
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv3);
166
+ }
167
+ if (!(protocols & NGX_SSL_TLSv1)) {
168
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1);
169
+ }
170
+ #ifdef SSL_OP_NO_TLSv1_1
171
+ if (!(protocols & NGX_SSL_TLSv1_1)) {
172
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_1);
173
+ }
174
+ #endif
175
+ #ifdef SSL_OP_NO_TLSv1_2
176
+ if (!(protocols & NGX_SSL_TLSv1_2)) {
177
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
178
+ }
179
+ #endif
180
+
181
+ #ifdef SSL_OP_NO_COMPRESSION
182
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
183
+ #endif
184
+
185
+ #ifdef SSL_MODE_RELEASE_BUFFERS
186
+ SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
187
+ #endif
188
+
189
+ SSL_CTX_set_read_ahead(ssl->ctx, 1);
190
+
191
+ SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
192
+
193
+ return NGX_OK;
194
+ }
195
+
196
+
197
+ ngx_int_t
198
+ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
199
+ ngx_str_t *key)
200
+ {
201
+ if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
202
+ return NGX_ERROR;
203
+ }
204
+
205
+ if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert->data)
206
+ == 0)
207
+ {
208
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
209
+ "SSL_CTX_use_certificate_chain_file(\"%s\") failed",
210
+ cert->data);
211
+ return NGX_ERROR;
212
+ }
213
+
214
+ if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
215
+ return NGX_ERROR;
216
+ }
217
+
218
+ if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key->data,
219
+ SSL_FILETYPE_PEM)
220
+ == 0)
221
+ {
222
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
223
+ "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data);
224
+ return NGX_ERROR;
225
+ }
226
+
227
+ return NGX_OK;
228
+ }
229
+
230
+
231
+ ngx_int_t
232
+ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
233
+ ngx_int_t depth)
234
+ {
235
+ STACK_OF(X509_NAME) *list;
236
+
237
+ SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_http_ssl_verify_callback);
238
+
239
+ SSL_CTX_set_verify_depth(ssl->ctx, depth);
240
+
241
+ if (cert->len == 0) {
242
+ return NGX_OK;
243
+ }
244
+
245
+ if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
246
+ return NGX_ERROR;
247
+ }
248
+
249
+ if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
250
+ == 0)
251
+ {
252
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
253
+ "SSL_CTX_load_verify_locations(\"%s\") failed",
254
+ cert->data);
255
+ return NGX_ERROR;
256
+ }
257
+
258
+ list = SSL_load_client_CA_file((char *) cert->data);
259
+
260
+ if (list == NULL) {
261
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
262
+ "SSL_load_client_CA_file(\"%s\") failed", cert->data);
263
+ return NGX_ERROR;
264
+ }
265
+
266
+ /*
267
+ * before 0.9.7h and 0.9.8 SSL_load_client_CA_file()
268
+ * always leaved an error in the error queue
269
+ */
270
+
271
+ ERR_clear_error();
272
+
273
+ SSL_CTX_set_client_CA_list(ssl->ctx, list);
274
+
275
+ return NGX_OK;
276
+ }
277
+
278
+
279
+ ngx_int_t
280
+ ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
281
+ {
282
+ X509_STORE *store;
283
+ X509_LOOKUP *lookup;
284
+
285
+ if (crl->len == 0) {
286
+ return NGX_OK;
287
+ }
288
+
289
+ if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
290
+ return NGX_ERROR;
291
+ }
292
+
293
+ store = SSL_CTX_get_cert_store(ssl->ctx);
294
+
295
+ if (store == NULL) {
296
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
297
+ "SSL_CTX_get_cert_store() failed");
298
+ return NGX_ERROR;
299
+ }
300
+
301
+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
302
+
303
+ if (lookup == NULL) {
304
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
305
+ "X509_STORE_add_lookup() failed");
306
+ return NGX_ERROR;
307
+ }
308
+
309
+ if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
310
+ == 0)
311
+ {
312
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
313
+ "X509_LOOKUP_load_file(\"%s\") failed", crl->data);
314
+ return NGX_ERROR;
315
+ }
316
+
317
+ X509_STORE_set_flags(store,
318
+ X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
319
+
320
+ return NGX_OK;
321
+ }
322
+
323
+
324
+ static int
325
+ ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
326
+ {
327
+ #if (NGX_DEBUG)
328
+ char *subject, *issuer;
329
+ int err, depth;
330
+ X509 *cert;
331
+ X509_NAME *sname, *iname;
332
+ ngx_connection_t *c;
333
+ ngx_ssl_conn_t *ssl_conn;
334
+
335
+ ssl_conn = X509_STORE_CTX_get_ex_data(x509_store,
336
+ SSL_get_ex_data_X509_STORE_CTX_idx());
337
+
338
+ c = ngx_ssl_get_connection(ssl_conn);
339
+
340
+ cert = X509_STORE_CTX_get_current_cert(x509_store);
341
+ err = X509_STORE_CTX_get_error(x509_store);
342
+ depth = X509_STORE_CTX_get_error_depth(x509_store);
343
+
344
+ sname = X509_get_subject_name(cert);
345
+ subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";
346
+
347
+ iname = X509_get_issuer_name(cert);
348
+ issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
349
+
350
+ ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
351
+ "verify:%d, error:%d, depth:%d, "
352
+ "subject:\"%s\",issuer: \"%s\"",
353
+ ok, err, depth, subject, issuer);
354
+
355
+ if (sname) {
356
+ OPENSSL_free(subject);
357
+ }
358
+
359
+ if (iname) {
360
+ OPENSSL_free(issuer);
361
+ }
362
+ #endif
363
+
364
+ return 1;
365
+ }
366
+
367
+
368
+ static void
369
+ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
370
+ {
371
+ ngx_connection_t *c;
372
+
373
+ if (where & SSL_CB_HANDSHAKE_START) {
374
+ c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
375
+
376
+ if (c->ssl->handshaked) {
377
+ c->ssl->renegotiation = 1;
378
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation");
379
+ }
380
+ }
381
+ }
382
+
383
+
384
+ RSA *
385
+ ngx_ssl_rsa512_key_callback(SSL *ssl, int is_export, int key_length)
386
+ {
387
+ static RSA *key;
388
+
389
+ if (key_length == 512) {
390
+ if (key == NULL) {
391
+ key = RSA_generate_key(512, RSA_F4, NULL, NULL);
392
+ }
393
+ }
394
+
395
+ return key;
396
+ }
397
+
398
+
399
+ ngx_int_t
400
+ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
401
+ {
402
+ DH *dh;
403
+ BIO *bio;
404
+
405
+ /*
406
+ * -----BEGIN DH PARAMETERS-----
407
+ * MIGHAoGBALu8LcrYRnSQfEP89YDpz9vZWKP1aLQtSwju1OsPs1BMbAMCducQgAxc
408
+ * y7qokiYUxb7spWWl/fHSh6K8BJvmd4Bg6RqSp1fjBI9osHb302zI8pul34HcLKcl
409
+ * 7OZicMyaUDXYzs7vnqAnSmOrHlj6/UmI0PZdFGdX2gcd8EXP4WubAgEC
410
+ * -----END DH PARAMETERS-----
411
+ */
412
+
413
+ static unsigned char dh1024_p[] = {
414
+ 0xBB, 0xBC, 0x2D, 0xCA, 0xD8, 0x46, 0x74, 0x90, 0x7C, 0x43, 0xFC, 0xF5,
415
+ 0x80, 0xE9, 0xCF, 0xDB, 0xD9, 0x58, 0xA3, 0xF5, 0x68, 0xB4, 0x2D, 0x4B,
416
+ 0x08, 0xEE, 0xD4, 0xEB, 0x0F, 0xB3, 0x50, 0x4C, 0x6C, 0x03, 0x02, 0x76,
417
+ 0xE7, 0x10, 0x80, 0x0C, 0x5C, 0xCB, 0xBA, 0xA8, 0x92, 0x26, 0x14, 0xC5,
418
+ 0xBE, 0xEC, 0xA5, 0x65, 0xA5, 0xFD, 0xF1, 0xD2, 0x87, 0xA2, 0xBC, 0x04,
419
+ 0x9B, 0xE6, 0x77, 0x80, 0x60, 0xE9, 0x1A, 0x92, 0xA7, 0x57, 0xE3, 0x04,
420
+ 0x8F, 0x68, 0xB0, 0x76, 0xF7, 0xD3, 0x6C, 0xC8, 0xF2, 0x9B, 0xA5, 0xDF,
421
+ 0x81, 0xDC, 0x2C, 0xA7, 0x25, 0xEC, 0xE6, 0x62, 0x70, 0xCC, 0x9A, 0x50,
422
+ 0x35, 0xD8, 0xCE, 0xCE, 0xEF, 0x9E, 0xA0, 0x27, 0x4A, 0x63, 0xAB, 0x1E,
423
+ 0x58, 0xFA, 0xFD, 0x49, 0x88, 0xD0, 0xF6, 0x5D, 0x14, 0x67, 0x57, 0xDA,
424
+ 0x07, 0x1D, 0xF0, 0x45, 0xCF, 0xE1, 0x6B, 0x9B
425
+ };
426
+
427
+ static unsigned char dh1024_g[] = { 0x02 };
428
+
429
+
430
+ if (file->len == 0) {
431
+
432
+ dh = DH_new();
433
+ if (dh == NULL) {
434
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "DH_new() failed");
435
+ return NGX_ERROR;
436
+ }
437
+
438
+ dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
439
+ dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
440
+
441
+ if (dh->p == NULL || dh->g == NULL) {
442
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "BN_bin2bn() failed");
443
+ DH_free(dh);
444
+ return NGX_ERROR;
445
+ }
446
+
447
+ SSL_CTX_set_tmp_dh(ssl->ctx, dh);
448
+
449
+ DH_free(dh);
450
+
451
+ return NGX_OK;
452
+ }
453
+
454
+ if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
455
+ return NGX_ERROR;
456
+ }
457
+
458
+ bio = BIO_new_file((char *) file->data, "r");
459
+ if (bio == NULL) {
460
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
461
+ "BIO_new_file(\"%s\") failed", file->data);
462
+ return NGX_ERROR;
463
+ }
464
+
465
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
466
+ if (dh == NULL) {
467
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
468
+ "PEM_read_bio_DHparams(\"%s\") failed", file->data);
469
+ BIO_free(bio);
470
+ return NGX_ERROR;
471
+ }
472
+
473
+ SSL_CTX_set_tmp_dh(ssl->ctx, dh);
474
+
475
+ DH_free(dh);
476
+ BIO_free(bio);
477
+
478
+ return NGX_OK;
479
+ }
480
+
481
+ ngx_int_t
482
+ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
483
+ {
484
+ #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
485
+ #ifndef OPENSSL_NO_ECDH
486
+ int nid;
487
+ EC_KEY *ecdh;
488
+
489
+ /*
490
+ * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
491
+ * from RFC 4492 section 5.1.1, or explicitely described curves over
492
+ * binary fields. OpenSSL only supports the "named curves", which provide
493
+ * maximum interoperability.
494
+ */
495
+
496
+ nid = OBJ_sn2nid((const char *) name->data);
497
+ if (nid == 0) {
498
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
499
+ "Unknown curve name \"%s\"", name->data);
500
+ return NGX_ERROR;
501
+ }
502
+
503
+ ecdh = EC_KEY_new_by_curve_name(nid);
504
+ if (ecdh == NULL) {
505
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
506
+ "Unable to create curve \"%s\"", name->data);
507
+ return NGX_ERROR;
508
+ }
509
+
510
+ SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
511
+
512
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
513
+
514
+ EC_KEY_free(ecdh);
515
+ #endif
516
+ #endif
517
+
518
+ return NGX_OK;
519
+ }
520
+
521
+ ngx_int_t
522
+ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
523
+ {
524
+ ngx_ssl_connection_t *sc;
525
+
526
+ sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t));
527
+ if (sc == NULL) {
528
+ return NGX_ERROR;
529
+ }
530
+
531
+ sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
532
+
533
+ sc->connection = SSL_new(ssl->ctx);
534
+
535
+ if (sc->connection == NULL) {
536
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed");
537
+ return NGX_ERROR;
538
+ }
539
+
540
+ if (SSL_set_fd(sc->connection, c->fd) == 0) {
541
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");
542
+ return NGX_ERROR;
543
+ }
544
+
545
+ if (flags & NGX_SSL_CLIENT) {
546
+ SSL_set_connect_state(sc->connection);
547
+
548
+ } else {
549
+ SSL_set_accept_state(sc->connection);
550
+ }
551
+
552
+ if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) {
553
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
554
+ return NGX_ERROR;
555
+ }
556
+
557
+ c->ssl = sc;
558
+
559
+ return NGX_OK;
560
+ }
561
+
562
+
563
+ ngx_int_t
564
+ ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
565
+ {
566
+ if (session) {
567
+ if (SSL_set_session(c->ssl->connection, session) == 0) {
568
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed");
569
+ return NGX_ERROR;
570
+ }
571
+ }
572
+
573
+ return NGX_OK;
574
+ }
575
+
576
+
577
+ ngx_int_t
578
+ ngx_ssl_handshake(ngx_connection_t *c)
579
+ {
580
+ int n, sslerr;
581
+ ngx_err_t err;
582
+
583
+ ngx_ssl_clear_error(c->log);
584
+
585
+ n = SSL_do_handshake(c->ssl->connection);
586
+
587
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
588
+
589
+ if (n == 1) {
590
+
591
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
592
+ return NGX_ERROR;
593
+ }
594
+
595
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
596
+ return NGX_ERROR;
597
+ }
598
+
599
+ #if (NGX_DEBUG)
600
+ {
601
+ char buf[129], *s, *d;
602
+ #if OPENSSL_VERSION_NUMBER >= 0x10000000L
603
+ const
604
+ #endif
605
+ SSL_CIPHER *cipher;
606
+
607
+ cipher = SSL_get_current_cipher(c->ssl->connection);
608
+
609
+ if (cipher) {
610
+ SSL_CIPHER_description(cipher, &buf[1], 128);
611
+
612
+ for (s = &buf[1], d = buf; *s; s++) {
613
+ if (*s == ' ' && *d == ' ') {
614
+ continue;
615
+ }
616
+
617
+ if (*s == LF || *s == CR) {
618
+ continue;
619
+ }
620
+
621
+ *++d = *s;
622
+ }
623
+
624
+ if (*d != ' ') {
625
+ d++;
626
+ }
627
+
628
+ *d = '\0';
629
+
630
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
631
+ "SSL: %s, cipher: \"%s\"",
632
+ SSL_get_version(c->ssl->connection), &buf[1]);
633
+
634
+ if (SSL_session_reused(c->ssl->connection)) {
635
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
636
+ "SSL reused session");
637
+ }
638
+
639
+ } else {
640
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
641
+ "SSL no shared ciphers");
642
+ }
643
+ }
644
+ #endif
645
+
646
+ c->ssl->handshaked = 1;
647
+
648
+ c->recv = ngx_ssl_recv;
649
+ c->send = ngx_ssl_write;
650
+ c->recv_chain = ngx_ssl_recv_chain;
651
+ c->send_chain = ngx_ssl_send_chain;
652
+
653
+ /* initial handshake done, disable renegotiation (CVE-2009-3555) */
654
+ if (c->ssl->connection->s3) {
655
+ c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
656
+ }
657
+
658
+ return NGX_OK;
659
+ }
660
+
661
+ sslerr = SSL_get_error(c->ssl->connection, n);
662
+
663
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
664
+
665
+ if (sslerr == SSL_ERROR_WANT_READ) {
666
+ c->read->ready = 0;
667
+ c->read->handler = ngx_ssl_handshake_handler;
668
+ c->write->handler = ngx_ssl_handshake_handler;
669
+
670
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
671
+ return NGX_ERROR;
672
+ }
673
+
674
+ return NGX_AGAIN;
675
+ }
676
+
677
+ if (sslerr == SSL_ERROR_WANT_WRITE) {
678
+ c->write->ready = 0;
679
+ c->read->handler = ngx_ssl_handshake_handler;
680
+ c->write->handler = ngx_ssl_handshake_handler;
681
+
682
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
683
+ return NGX_ERROR;
684
+ }
685
+
686
+ return NGX_AGAIN;
687
+ }
688
+
689
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
690
+
691
+ c->ssl->no_wait_shutdown = 1;
692
+ c->ssl->no_send_shutdown = 1;
693
+ c->read->eof = 1;
694
+
695
+ if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
696
+ ngx_log_error(NGX_LOG_INFO, c->log, err,
697
+ "peer closed connection in SSL handshake");
698
+
699
+ return NGX_ERROR;
700
+ }
701
+
702
+ c->read->error = 1;
703
+
704
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");
705
+
706
+ return NGX_ERROR;
707
+ }
708
+
709
+
710
+ static void
711
+ ngx_ssl_handshake_handler(ngx_event_t *ev)
712
+ {
713
+ ngx_connection_t *c;
714
+
715
+ c = ev->data;
716
+
717
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
718
+ "SSL handshake handler: %d", ev->write);
719
+
720
+ if (ev->timedout) {
721
+ c->ssl->handler(c);
722
+ return;
723
+ }
724
+
725
+ if (ngx_ssl_handshake(c) == NGX_AGAIN) {
726
+ return;
727
+ }
728
+
729
+ c->ssl->handler(c);
730
+ }
731
+
732
+
733
+ ssize_t
734
+ ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl)
735
+ {
736
+ u_char *last;
737
+ ssize_t n, bytes;
738
+ ngx_buf_t *b;
739
+
740
+ bytes = 0;
741
+
742
+ b = cl->buf;
743
+ last = b->last;
744
+
745
+ for ( ;; ) {
746
+
747
+ n = ngx_ssl_recv(c, last, b->end - last);
748
+
749
+ if (n > 0) {
750
+ last += n;
751
+ bytes += n;
752
+
753
+ if (last == b->end) {
754
+ cl = cl->next;
755
+
756
+ if (cl == NULL) {
757
+ return bytes;
758
+ }
759
+
760
+ b = cl->buf;
761
+ last = b->last;
762
+ }
763
+
764
+ continue;
765
+ }
766
+
767
+ if (bytes) {
768
+
769
+ if (n == 0 || n == NGX_ERROR) {
770
+ c->read->ready = 1;
771
+ }
772
+
773
+ return bytes;
774
+ }
775
+
776
+ return n;
777
+ }
778
+ }
779
+
780
+
781
+ ssize_t
782
+ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
783
+ {
784
+ int n, bytes;
785
+
786
+ if (c->ssl->last == NGX_ERROR) {
787
+ c->read->error = 1;
788
+ return NGX_ERROR;
789
+ }
790
+
791
+ if (c->ssl->last == NGX_DONE) {
792
+ c->read->ready = 0;
793
+ c->read->eof = 1;
794
+ return 0;
795
+ }
796
+
797
+ bytes = 0;
798
+
799
+ ngx_ssl_clear_error(c->log);
800
+
801
+ /*
802
+ * SSL_read() may return data in parts, so try to read
803
+ * until SSL_read() would return no data
804
+ */
805
+
806
+ for ( ;; ) {
807
+
808
+ n = SSL_read(c->ssl->connection, buf, size);
809
+
810
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);
811
+
812
+ if (n > 0) {
813
+ bytes += n;
814
+ }
815
+
816
+ c->ssl->last = ngx_ssl_handle_recv(c, n);
817
+
818
+ if (c->ssl->last == NGX_OK) {
819
+
820
+ size -= n;
821
+
822
+ if (size == 0) {
823
+ return bytes;
824
+ }
825
+
826
+ buf += n;
827
+
828
+ continue;
829
+ }
830
+
831
+ if (bytes) {
832
+ return bytes;
833
+ }
834
+
835
+ switch (c->ssl->last) {
836
+
837
+ case NGX_DONE:
838
+ c->read->ready = 0;
839
+ c->read->eof = 1;
840
+ return 0;
841
+
842
+ case NGX_ERROR:
843
+ c->read->error = 1;
844
+
845
+ /* fall through */
846
+
847
+ case NGX_AGAIN:
848
+ return c->ssl->last;
849
+ }
850
+ }
851
+ }
852
+
853
+
854
+ static ngx_int_t
855
+ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
856
+ {
857
+ int sslerr;
858
+ ngx_err_t err;
859
+
860
+ if (c->ssl->renegotiation) {
861
+ /*
862
+ * disable renegotiation (CVE-2009-3555):
863
+ * OpenSSL (at least up to 0.9.8l) does not handle disabled
864
+ * renegotiation gracefully, so drop connection here
865
+ */
866
+
867
+ ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled");
868
+
869
+ while (ERR_peek_error()) {
870
+ ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0,
871
+ "ignoring stale global SSL error");
872
+ }
873
+
874
+ ERR_clear_error();
875
+
876
+ c->ssl->no_wait_shutdown = 1;
877
+ c->ssl->no_send_shutdown = 1;
878
+
879
+ return NGX_ERROR;
880
+ }
881
+
882
+ if (n > 0) {
883
+
884
+ if (c->ssl->saved_write_handler) {
885
+
886
+ c->write->handler = c->ssl->saved_write_handler;
887
+ c->ssl->saved_write_handler = NULL;
888
+ c->write->ready = 1;
889
+
890
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
891
+ return NGX_ERROR;
892
+ }
893
+
894
+ ngx_post_event(c->write, &ngx_posted_events);
895
+ }
896
+
897
+ return NGX_OK;
898
+ }
899
+
900
+ sslerr = SSL_get_error(c->ssl->connection, n);
901
+
902
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
903
+
904
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
905
+
906
+ if (sslerr == SSL_ERROR_WANT_READ) {
907
+ c->read->ready = 0;
908
+ return NGX_AGAIN;
909
+ }
910
+
911
+ if (sslerr == SSL_ERROR_WANT_WRITE) {
912
+
913
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
914
+ "peer started SSL renegotiation");
915
+
916
+ c->write->ready = 0;
917
+
918
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
919
+ return NGX_ERROR;
920
+ }
921
+
922
+ /*
923
+ * we do not set the timer because there is already the read event timer
924
+ */
925
+
926
+ if (c->ssl->saved_write_handler == NULL) {
927
+ c->ssl->saved_write_handler = c->write->handler;
928
+ c->write->handler = ngx_ssl_write_handler;
929
+ }
930
+
931
+ return NGX_AGAIN;
932
+ }
933
+
934
+ c->ssl->no_wait_shutdown = 1;
935
+ c->ssl->no_send_shutdown = 1;
936
+
937
+ if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
938
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
939
+ "peer shutdown SSL cleanly");
940
+ return NGX_DONE;
941
+ }
942
+
943
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed");
944
+
945
+ return NGX_ERROR;
946
+ }
947
+
948
+
949
+ static void
950
+ ngx_ssl_write_handler(ngx_event_t *wev)
951
+ {
952
+ ngx_connection_t *c;
953
+
954
+ c = wev->data;
955
+
956
+ c->read->handler(c->read);
957
+ }
958
+
959
+
960
+ /*
961
+ * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
962
+ * before the SSL_write() call to decrease a SSL overhead.
963
+ *
964
+ * Besides for protocols such as HTTP it is possible to always buffer
965
+ * the output to decrease a SSL overhead some more.
966
+ */
967
+
968
+ ngx_chain_t *
969
+ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
970
+ {
971
+ int n;
972
+ ngx_uint_t flush;
973
+ ssize_t send, size;
974
+ ngx_buf_t *buf;
975
+
976
+ if (!c->ssl->buffer) {
977
+
978
+ while (in) {
979
+ if (ngx_buf_special(in->buf)) {
980
+ in = in->next;
981
+ continue;
982
+ }
983
+
984
+ n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos);
985
+
986
+ if (n == NGX_ERROR) {
987
+ return NGX_CHAIN_ERROR;
988
+ }
989
+
990
+ if (n == NGX_AGAIN) {
991
+ c->buffered |= NGX_SSL_BUFFERED;
992
+ return in;
993
+ }
994
+
995
+ in->buf->pos += n;
996
+
997
+ if (in->buf->pos == in->buf->last) {
998
+ in = in->next;
999
+ }
1000
+ }
1001
+
1002
+ return in;
1003
+ }
1004
+
1005
+
1006
+ /* the maximum limit size is the maximum int32_t value - the page size */
1007
+
1008
+ if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) {
1009
+ limit = NGX_MAX_INT32_VALUE - ngx_pagesize;
1010
+ }
1011
+
1012
+ buf = c->ssl->buf;
1013
+
1014
+ if (buf == NULL) {
1015
+ buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE);
1016
+ if (buf == NULL) {
1017
+ return NGX_CHAIN_ERROR;
1018
+ }
1019
+
1020
+ c->ssl->buf = buf;
1021
+ }
1022
+
1023
+ if (buf->start == NULL) {
1024
+ buf->start = ngx_palloc(c->pool, NGX_SSL_BUFSIZE);
1025
+ if (buf->start == NULL) {
1026
+ return NGX_CHAIN_ERROR;
1027
+ }
1028
+
1029
+ buf->pos = buf->start;
1030
+ buf->last = buf->start;
1031
+ buf->end = buf->start + NGX_SSL_BUFSIZE;
1032
+ }
1033
+
1034
+ send = 0;
1035
+ flush = (in == NULL) ? 1 : 0;
1036
+
1037
+ for ( ;; ) {
1038
+
1039
+ while (in && buf->last < buf->end && send < limit) {
1040
+ if (in->buf->last_buf || in->buf->flush) {
1041
+ flush = 1;
1042
+ }
1043
+
1044
+ if (ngx_buf_special(in->buf)) {
1045
+ in = in->next;
1046
+ continue;
1047
+ }
1048
+
1049
+ size = in->buf->last - in->buf->pos;
1050
+
1051
+ if (size > buf->end - buf->last) {
1052
+ size = buf->end - buf->last;
1053
+ }
1054
+
1055
+ if (send + size > limit) {
1056
+ size = (ssize_t) (limit - send);
1057
+ flush = 1;
1058
+ }
1059
+
1060
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1061
+ "SSL buf copy: %d", size);
1062
+
1063
+ ngx_memcpy(buf->last, in->buf->pos, size);
1064
+
1065
+ buf->last += size;
1066
+ in->buf->pos += size;
1067
+ send += size;
1068
+
1069
+ if (in->buf->pos == in->buf->last) {
1070
+ in = in->next;
1071
+ }
1072
+ }
1073
+
1074
+ size = buf->last - buf->pos;
1075
+
1076
+ if (!flush && buf->last < buf->end && c->ssl->buffer) {
1077
+ break;
1078
+ }
1079
+
1080
+ n = ngx_ssl_write(c, buf->pos, size);
1081
+
1082
+ if (n == NGX_ERROR) {
1083
+ return NGX_CHAIN_ERROR;
1084
+ }
1085
+
1086
+ if (n == NGX_AGAIN) {
1087
+ c->buffered |= NGX_SSL_BUFFERED;
1088
+ return in;
1089
+ }
1090
+
1091
+ buf->pos += n;
1092
+ c->sent += n;
1093
+
1094
+ if (n < size) {
1095
+ break;
1096
+ }
1097
+
1098
+ if (buf->pos == buf->last) {
1099
+ buf->pos = buf->start;
1100
+ buf->last = buf->start;
1101
+ }
1102
+
1103
+ if (in == NULL || send == limit) {
1104
+ break;
1105
+ }
1106
+ }
1107
+
1108
+ if (buf->pos < buf->last) {
1109
+ c->buffered |= NGX_SSL_BUFFERED;
1110
+
1111
+ } else {
1112
+ c->buffered &= ~NGX_SSL_BUFFERED;
1113
+ }
1114
+
1115
+ return in;
1116
+ }
1117
+
1118
+
1119
+ ssize_t
1120
+ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
1121
+ {
1122
+ int n, sslerr;
1123
+ ngx_err_t err;
1124
+
1125
+ ngx_ssl_clear_error(c->log);
1126
+
1127
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
1128
+
1129
+ n = SSL_write(c->ssl->connection, data, size);
1130
+
1131
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
1132
+
1133
+ if (n > 0) {
1134
+
1135
+ if (c->ssl->saved_read_handler) {
1136
+
1137
+ c->read->handler = c->ssl->saved_read_handler;
1138
+ c->ssl->saved_read_handler = NULL;
1139
+ c->read->ready = 1;
1140
+
1141
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
1142
+ return NGX_ERROR;
1143
+ }
1144
+
1145
+ ngx_post_event(c->read, &ngx_posted_events);
1146
+ }
1147
+
1148
+ return n;
1149
+ }
1150
+
1151
+ sslerr = SSL_get_error(c->ssl->connection, n);
1152
+
1153
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
1154
+
1155
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
1156
+
1157
+ if (sslerr == SSL_ERROR_WANT_WRITE) {
1158
+ c->write->ready = 0;
1159
+ return NGX_AGAIN;
1160
+ }
1161
+
1162
+ if (sslerr == SSL_ERROR_WANT_READ) {
1163
+
1164
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1165
+ "peer started SSL renegotiation");
1166
+
1167
+ c->read->ready = 0;
1168
+
1169
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
1170
+ return NGX_ERROR;
1171
+ }
1172
+
1173
+ /*
1174
+ * we do not set the timer because there is already
1175
+ * the write event timer
1176
+ */
1177
+
1178
+ if (c->ssl->saved_read_handler == NULL) {
1179
+ c->ssl->saved_read_handler = c->read->handler;
1180
+ c->read->handler = ngx_ssl_read_handler;
1181
+ }
1182
+
1183
+ return NGX_AGAIN;
1184
+ }
1185
+
1186
+ c->ssl->no_wait_shutdown = 1;
1187
+ c->ssl->no_send_shutdown = 1;
1188
+ c->write->error = 1;
1189
+
1190
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed");
1191
+
1192
+ return NGX_ERROR;
1193
+ }
1194
+
1195
+
1196
+ static void
1197
+ ngx_ssl_read_handler(ngx_event_t *rev)
1198
+ {
1199
+ ngx_connection_t *c;
1200
+
1201
+ c = rev->data;
1202
+
1203
+ c->write->handler(c->write);
1204
+ }
1205
+
1206
+
1207
+ void
1208
+ ngx_ssl_free_buffer(ngx_connection_t *c)
1209
+ {
1210
+ if (c->ssl->buf && c->ssl->buf->start) {
1211
+ if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
1212
+ c->ssl->buf->start = NULL;
1213
+ }
1214
+ }
1215
+ }
1216
+
1217
+
1218
+ ngx_int_t
1219
+ ngx_ssl_shutdown(ngx_connection_t *c)
1220
+ {
1221
+ int n, sslerr, mode;
1222
+ ngx_err_t err;
1223
+
1224
+ if (c->timedout) {
1225
+ mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
1226
+ SSL_set_quiet_shutdown(c->ssl->connection, 1);
1227
+
1228
+ } else {
1229
+ mode = SSL_get_shutdown(c->ssl->connection);
1230
+
1231
+ if (c->ssl->no_wait_shutdown) {
1232
+ mode |= SSL_RECEIVED_SHUTDOWN;
1233
+ }
1234
+
1235
+ if (c->ssl->no_send_shutdown) {
1236
+ mode |= SSL_SENT_SHUTDOWN;
1237
+ }
1238
+
1239
+ if (c->ssl->no_wait_shutdown && c->ssl->no_send_shutdown) {
1240
+ SSL_set_quiet_shutdown(c->ssl->connection, 1);
1241
+ }
1242
+ }
1243
+
1244
+ SSL_set_shutdown(c->ssl->connection, mode);
1245
+
1246
+ ngx_ssl_clear_error(c->log);
1247
+
1248
+ n = SSL_shutdown(c->ssl->connection);
1249
+
1250
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
1251
+
1252
+ sslerr = 0;
1253
+
1254
+ /* SSL_shutdown() never returns -1, on error it returns 0 */
1255
+
1256
+ if (n != 1 && ERR_peek_error()) {
1257
+ sslerr = SSL_get_error(c->ssl->connection, n);
1258
+
1259
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1260
+ "SSL_get_error: %d", sslerr);
1261
+ }
1262
+
1263
+ if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
1264
+ SSL_free(c->ssl->connection);
1265
+ c->ssl = NULL;
1266
+
1267
+ return NGX_OK;
1268
+ }
1269
+
1270
+ if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
1271
+ c->read->handler = ngx_ssl_shutdown_handler;
1272
+ c->write->handler = ngx_ssl_shutdown_handler;
1273
+
1274
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
1275
+ return NGX_ERROR;
1276
+ }
1277
+
1278
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
1279
+ return NGX_ERROR;
1280
+ }
1281
+
1282
+ if (sslerr == SSL_ERROR_WANT_READ) {
1283
+ ngx_add_timer(c->read, 30000);
1284
+ }
1285
+
1286
+ return NGX_AGAIN;
1287
+ }
1288
+
1289
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
1290
+
1291
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
1292
+
1293
+ SSL_free(c->ssl->connection);
1294
+ c->ssl = NULL;
1295
+
1296
+ return NGX_ERROR;
1297
+ }
1298
+
1299
+
1300
+ static void
1301
+ ngx_ssl_shutdown_handler(ngx_event_t *ev)
1302
+ {
1303
+ ngx_connection_t *c;
1304
+ ngx_connection_handler_pt handler;
1305
+
1306
+ c = ev->data;
1307
+ handler = c->ssl->handler;
1308
+
1309
+ if (ev->timedout) {
1310
+ c->timedout = 1;
1311
+ }
1312
+
1313
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "SSL shutdown handler");
1314
+
1315
+ if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
1316
+ return;
1317
+ }
1318
+
1319
+ handler(c);
1320
+ }
1321
+
1322
+
1323
+ static void
1324
+ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
1325
+ char *text)
1326
+ {
1327
+ int n;
1328
+ ngx_uint_t level;
1329
+
1330
+ level = NGX_LOG_CRIT;
1331
+
1332
+ if (sslerr == SSL_ERROR_SYSCALL) {
1333
+
1334
+ if (err == NGX_ECONNRESET
1335
+ || err == NGX_EPIPE
1336
+ || err == NGX_ENOTCONN
1337
+ || err == NGX_ETIMEDOUT
1338
+ || err == NGX_ECONNREFUSED
1339
+ || err == NGX_ENETDOWN
1340
+ || err == NGX_ENETUNREACH
1341
+ || err == NGX_EHOSTDOWN
1342
+ || err == NGX_EHOSTUNREACH)
1343
+ {
1344
+ switch (c->log_error) {
1345
+
1346
+ case NGX_ERROR_IGNORE_ECONNRESET:
1347
+ case NGX_ERROR_INFO:
1348
+ level = NGX_LOG_INFO;
1349
+ break;
1350
+
1351
+ case NGX_ERROR_ERR:
1352
+ level = NGX_LOG_ERR;
1353
+ break;
1354
+
1355
+ default:
1356
+ break;
1357
+ }
1358
+ }
1359
+
1360
+ } else if (sslerr == SSL_ERROR_SSL) {
1361
+
1362
+ n = ERR_GET_REASON(ERR_peek_error());
1363
+
1364
+ /* handshake failures */
1365
+ if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */
1366
+ || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */
1367
+ || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */
1368
+ || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */
1369
+ || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */
1370
+ || n == SSL_R_LENGTH_MISMATCH /* 159 */
1371
+ || n == SSL_R_NO_CIPHERS_PASSED /* 182 */
1372
+ || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */
1373
+ || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */
1374
+ || n == SSL_R_NO_SHARED_CIPHER /* 193 */
1375
+ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */
1376
+ #ifdef SSL_R_PARSE_TLSEXT
1377
+ || n == SSL_R_PARSE_TLSEXT /* 227 */
1378
+ #endif
1379
+ || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */
1380
+ || n == SSL_R_UNEXPECTED_RECORD /* 245 */
1381
+ || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */
1382
+ || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
1383
+ || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
1384
+ || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
1385
+ #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
1386
+ || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG /* 335 */
1387
+ || n == SSL_R_RENEGOTIATION_ENCODING_ERR /* 336 */
1388
+ || n == SSL_R_RENEGOTIATION_MISMATCH /* 337 */
1389
+ #endif
1390
+ #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
1391
+ || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED /* 338 */
1392
+ #endif
1393
+ #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
1394
+ || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */
1395
+ #endif
1396
+ || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
1397
+ || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */
1398
+ || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */
1399
+ || n == SSL_R_TLSV1_ALERT_DECRYPTION_FAILED /* 1021 */
1400
+ || n == SSL_R_TLSV1_ALERT_RECORD_OVERFLOW /* 1022 */
1401
+ || n == SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE /* 1030 */
1402
+ || n == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE /* 1040 */
1403
+ || n == SSL_R_SSLV3_ALERT_NO_CERTIFICATE /* 1041 */
1404
+ || n == SSL_R_SSLV3_ALERT_BAD_CERTIFICATE /* 1042 */
1405
+ || n == SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE /* 1043 */
1406
+ || n == SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED /* 1044 */
1407
+ || n == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED /* 1045 */
1408
+ || n == SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN /* 1046 */
1409
+ || n == SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER /* 1047 */
1410
+ || n == SSL_R_TLSV1_ALERT_UNKNOWN_CA /* 1048 */
1411
+ || n == SSL_R_TLSV1_ALERT_ACCESS_DENIED /* 1049 */
1412
+ || n == SSL_R_TLSV1_ALERT_DECODE_ERROR /* 1050 */
1413
+ || n == SSL_R_TLSV1_ALERT_DECRYPT_ERROR /* 1051 */
1414
+ || n == SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION /* 1060 */
1415
+ || n == SSL_R_TLSV1_ALERT_PROTOCOL_VERSION /* 1070 */
1416
+ || n == SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY /* 1071 */
1417
+ || n == SSL_R_TLSV1_ALERT_INTERNAL_ERROR /* 1080 */
1418
+ || n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */
1419
+ || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION) /* 1100 */
1420
+ {
1421
+ switch (c->log_error) {
1422
+
1423
+ case NGX_ERROR_IGNORE_ECONNRESET:
1424
+ case NGX_ERROR_INFO:
1425
+ level = NGX_LOG_INFO;
1426
+ break;
1427
+
1428
+ case NGX_ERROR_ERR:
1429
+ level = NGX_LOG_ERR;
1430
+ break;
1431
+
1432
+ default:
1433
+ break;
1434
+ }
1435
+ }
1436
+ }
1437
+
1438
+ ngx_ssl_error(level, c->log, err, text);
1439
+ }
1440
+
1441
+
1442
+ static void
1443
+ ngx_ssl_clear_error(ngx_log_t *log)
1444
+ {
1445
+ while (ERR_peek_error()) {
1446
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
1447
+ }
1448
+
1449
+ ERR_clear_error();
1450
+ }
1451
+
1452
+
1453
+ void ngx_cdecl
1454
+ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
1455
+ {
1456
+ u_long n;
1457
+ va_list args;
1458
+ u_char *p, *last;
1459
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
1460
+
1461
+ last = errstr + NGX_MAX_CONF_ERRSTR;
1462
+
1463
+ va_start(args, fmt);
1464
+ p = ngx_vslprintf(errstr, last - 1, fmt, args);
1465
+ va_end(args);
1466
+
1467
+ p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);
1468
+
1469
+ for ( ;; ) {
1470
+
1471
+ n = ERR_get_error();
1472
+
1473
+ if (n == 0) {
1474
+ break;
1475
+ }
1476
+
1477
+ if (p >= last) {
1478
+ continue;
1479
+ }
1480
+
1481
+ *p++ = ' ';
1482
+
1483
+ ERR_error_string_n(n, (char *) p, last - p);
1484
+
1485
+ while (p < last && *p) {
1486
+ p++;
1487
+ }
1488
+ }
1489
+
1490
+ ngx_log_error(level, log, err, "%s)", errstr);
1491
+ }
1492
+
1493
+
1494
+ ngx_int_t
1495
+ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
1496
+ ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout)
1497
+ {
1498
+ long cache_mode;
1499
+
1500
+ if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
1501
+ SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
1502
+ return NGX_OK;
1503
+ }
1504
+
1505
+ SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
1506
+
1507
+ if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
1508
+
1509
+ /*
1510
+ * If the server explicitly says that it does not support
1511
+ * session reuse (see SSL_SESS_CACHE_OFF above), then
1512
+ * Outlook Express fails to upload a sent email to
1513
+ * the Sent Items folder on the IMAP server via a separate IMAP
1514
+ * connection in the background. Therefore we have a special
1515
+ * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
1516
+ * where the server pretends that it supports session reuse,
1517
+ * but it does not actually store any session.
1518
+ */
1519
+
1520
+ SSL_CTX_set_session_cache_mode(ssl->ctx,
1521
+ SSL_SESS_CACHE_SERVER
1522
+ |SSL_SESS_CACHE_NO_AUTO_CLEAR
1523
+ |SSL_SESS_CACHE_NO_INTERNAL_STORE);
1524
+
1525
+ SSL_CTX_sess_set_cache_size(ssl->ctx, 1);
1526
+
1527
+ return NGX_OK;
1528
+ }
1529
+
1530
+ cache_mode = SSL_SESS_CACHE_SERVER;
1531
+
1532
+ if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
1533
+ cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
1534
+ }
1535
+
1536
+ SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode);
1537
+
1538
+ if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {
1539
+
1540
+ if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
1541
+ SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
1542
+ }
1543
+ }
1544
+
1545
+ SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
1546
+
1547
+ if (shm_zone) {
1548
+ SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
1549
+ SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
1550
+ SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);
1551
+
1552
+ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone)
1553
+ == 0)
1554
+ {
1555
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1556
+ "SSL_CTX_set_ex_data() failed");
1557
+ return NGX_ERROR;
1558
+ }
1559
+ }
1560
+
1561
+ return NGX_OK;
1562
+ }
1563
+
1564
+
1565
+ ngx_int_t
1566
+ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
1567
+ {
1568
+ size_t len;
1569
+ ngx_slab_pool_t *shpool;
1570
+ ngx_ssl_session_cache_t *cache;
1571
+
1572
+ if (data) {
1573
+ shm_zone->data = data;
1574
+ return NGX_OK;
1575
+ }
1576
+
1577
+ if (shm_zone->shm.exists) {
1578
+ shm_zone->data = data;
1579
+ return NGX_OK;
1580
+ }
1581
+
1582
+ shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
1583
+
1584
+ cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
1585
+ if (cache == NULL) {
1586
+ return NGX_ERROR;
1587
+ }
1588
+
1589
+ shpool->data = cache;
1590
+ shm_zone->data = cache;
1591
+
1592
+ ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
1593
+ ngx_ssl_session_rbtree_insert_value);
1594
+
1595
+ ngx_queue_init(&cache->expire_queue);
1596
+
1597
+ len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len;
1598
+
1599
+ shpool->log_ctx = ngx_slab_alloc(shpool, len);
1600
+ if (shpool->log_ctx == NULL) {
1601
+ return NGX_ERROR;
1602
+ }
1603
+
1604
+ ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z",
1605
+ &shm_zone->shm.name);
1606
+
1607
+ return NGX_OK;
1608
+ }
1609
+
1610
+
1611
+ /*
1612
+ * The length of the session id is 16 bytes for SSLv2 sessions and
1613
+ * between 1 and 32 bytes for SSLv3/TLSv1, typically 32 bytes.
1614
+ * It seems that the typical length of the external ASN1 representation
1615
+ * of a session is 118 or 119 bytes for SSLv3/TSLv1.
1616
+ *
1617
+ * Thus on 32-bit platforms we allocate separately an rbtree node,
1618
+ * a session id, and an ASN1 representation, they take accordingly
1619
+ * 64, 32, and 128 bytes.
1620
+ *
1621
+ * On 64-bit platforms we allocate separately an rbtree node + session_id,
1622
+ * and an ASN1 representation, they take accordingly 128 and 128 bytes.
1623
+ *
1624
+ * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
1625
+ * so they are outside the code locked by shared pool mutex
1626
+ */
1627
+
1628
+ static int
1629
+ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
1630
+ {
1631
+ int len;
1632
+ u_char *p, *id, *cached_sess;
1633
+ uint32_t hash;
1634
+ SSL_CTX *ssl_ctx;
1635
+ ngx_shm_zone_t *shm_zone;
1636
+ ngx_connection_t *c;
1637
+ ngx_slab_pool_t *shpool;
1638
+ ngx_ssl_sess_id_t *sess_id;
1639
+ ngx_ssl_session_cache_t *cache;
1640
+ u_char buf[NGX_SSL_MAX_SESSION_SIZE];
1641
+
1642
+ len = i2d_SSL_SESSION(sess, NULL);
1643
+
1644
+ /* do not cache too big session */
1645
+
1646
+ if (len > (int) NGX_SSL_MAX_SESSION_SIZE) {
1647
+ return 0;
1648
+ }
1649
+
1650
+ p = buf;
1651
+ i2d_SSL_SESSION(sess, &p);
1652
+
1653
+ c = ngx_ssl_get_connection(ssl_conn);
1654
+
1655
+ ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
1656
+ shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);
1657
+
1658
+ cache = shm_zone->data;
1659
+ shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
1660
+
1661
+ ngx_shmtx_lock(&shpool->mutex);
1662
+
1663
+ /* drop one or two expired sessions */
1664
+ ngx_ssl_expire_sessions(cache, shpool, 1);
1665
+
1666
+ cached_sess = ngx_slab_alloc_locked(shpool, len);
1667
+
1668
+ if (cached_sess == NULL) {
1669
+
1670
+ /* drop the oldest non-expired session and try once more */
1671
+
1672
+ ngx_ssl_expire_sessions(cache, shpool, 0);
1673
+
1674
+ cached_sess = ngx_slab_alloc_locked(shpool, len);
1675
+
1676
+ if (cached_sess == NULL) {
1677
+ sess_id = NULL;
1678
+ goto failed;
1679
+ }
1680
+ }
1681
+
1682
+ sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
1683
+ if (sess_id == NULL) {
1684
+ goto failed;
1685
+ }
1686
+
1687
+ #if (NGX_PTR_SIZE == 8)
1688
+
1689
+ id = sess_id->sess_id;
1690
+
1691
+ #else
1692
+
1693
+ id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
1694
+ if (id == NULL) {
1695
+ goto failed;
1696
+ }
1697
+
1698
+ #endif
1699
+
1700
+ ngx_memcpy(cached_sess, buf, len);
1701
+
1702
+ ngx_memcpy(id, sess->session_id, sess->session_id_length);
1703
+
1704
+ hash = ngx_crc32_short(sess->session_id, sess->session_id_length);
1705
+
1706
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
1707
+ "ssl new session: %08XD:%d:%d",
1708
+ hash, sess->session_id_length, len);
1709
+
1710
+ sess_id->node.key = hash;
1711
+ sess_id->node.data = (u_char) sess->session_id_length;
1712
+ sess_id->id = id;
1713
+ sess_id->len = len;
1714
+ sess_id->session = cached_sess;
1715
+
1716
+ sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx);
1717
+
1718
+ ngx_queue_insert_head(&cache->expire_queue, &sess_id->queue);
1719
+
1720
+ ngx_rbtree_insert(&cache->session_rbtree, &sess_id->node);
1721
+
1722
+ ngx_shmtx_unlock(&shpool->mutex);
1723
+
1724
+ return 0;
1725
+
1726
+ failed:
1727
+
1728
+ if (cached_sess) {
1729
+ ngx_slab_free_locked(shpool, cached_sess);
1730
+ }
1731
+
1732
+ if (sess_id) {
1733
+ ngx_slab_free_locked(shpool, sess_id);
1734
+ }
1735
+
1736
+ ngx_shmtx_unlock(&shpool->mutex);
1737
+
1738
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
1739
+ "could not add new SSL session to the session cache");
1740
+
1741
+ return 0;
1742
+ }
1743
+
1744
+
1745
+ static ngx_ssl_session_t *
1746
+ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
1747
+ int *copy)
1748
+ {
1749
+ #if OPENSSL_VERSION_NUMBER >= 0x0090707fL
1750
+ const
1751
+ #endif
1752
+ u_char *p;
1753
+ uint32_t hash;
1754
+ ngx_int_t rc;
1755
+ ngx_shm_zone_t *shm_zone;
1756
+ ngx_slab_pool_t *shpool;
1757
+ ngx_rbtree_node_t *node, *sentinel;
1758
+ ngx_ssl_session_t *sess;
1759
+ ngx_ssl_sess_id_t *sess_id;
1760
+ ngx_ssl_session_cache_t *cache;
1761
+ u_char buf[NGX_SSL_MAX_SESSION_SIZE];
1762
+ #if (NGX_DEBUG)
1763
+ ngx_connection_t *c;
1764
+ #endif
1765
+
1766
+ hash = ngx_crc32_short(id, (size_t) len);
1767
+ *copy = 0;
1768
+
1769
+ #if (NGX_DEBUG)
1770
+ c = ngx_ssl_get_connection(ssl_conn);
1771
+
1772
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1773
+ "ssl get session: %08XD:%d", hash, len);
1774
+ #endif
1775
+
1776
+ shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
1777
+ ngx_ssl_session_cache_index);
1778
+
1779
+ cache = shm_zone->data;
1780
+
1781
+ sess = NULL;
1782
+
1783
+ shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
1784
+
1785
+ ngx_shmtx_lock(&shpool->mutex);
1786
+
1787
+ node = cache->session_rbtree.root;
1788
+ sentinel = cache->session_rbtree.sentinel;
1789
+
1790
+ while (node != sentinel) {
1791
+
1792
+ if (hash < node->key) {
1793
+ node = node->left;
1794
+ continue;
1795
+ }
1796
+
1797
+ if (hash > node->key) {
1798
+ node = node->right;
1799
+ continue;
1800
+ }
1801
+
1802
+ /* hash == node->key */
1803
+
1804
+ sess_id = (ngx_ssl_sess_id_t *) node;
1805
+
1806
+ rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
1807
+
1808
+ if (rc == 0) {
1809
+
1810
+ if (sess_id->expire > ngx_time()) {
1811
+ ngx_memcpy(buf, sess_id->session, sess_id->len);
1812
+
1813
+ ngx_shmtx_unlock(&shpool->mutex);
1814
+
1815
+ p = buf;
1816
+ sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1817
+
1818
+ return sess;
1819
+ }
1820
+
1821
+ ngx_queue_remove(&sess_id->queue);
1822
+
1823
+ ngx_rbtree_delete(&cache->session_rbtree, node);
1824
+
1825
+ ngx_slab_free_locked(shpool, sess_id->session);
1826
+ #if (NGX_PTR_SIZE == 4)
1827
+ ngx_slab_free_locked(shpool, sess_id->id);
1828
+ #endif
1829
+ ngx_slab_free_locked(shpool, sess_id);
1830
+
1831
+ sess = NULL;
1832
+
1833
+ goto done;
1834
+ }
1835
+
1836
+ node = (rc < 0) ? node->left : node->right;
1837
+ }
1838
+
1839
+ done:
1840
+
1841
+ ngx_shmtx_unlock(&shpool->mutex);
1842
+
1843
+ return sess;
1844
+ }
1845
+
1846
+
1847
+ void
1848
+ ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
1849
+ {
1850
+ SSL_CTX_remove_session(ssl, sess);
1851
+
1852
+ ngx_ssl_remove_session(ssl, sess);
1853
+ }
1854
+
1855
+
1856
+ static void
1857
+ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
1858
+ {
1859
+ size_t len;
1860
+ u_char *id;
1861
+ uint32_t hash;
1862
+ ngx_int_t rc;
1863
+ ngx_shm_zone_t *shm_zone;
1864
+ ngx_slab_pool_t *shpool;
1865
+ ngx_rbtree_node_t *node, *sentinel;
1866
+ ngx_ssl_sess_id_t *sess_id;
1867
+ ngx_ssl_session_cache_t *cache;
1868
+
1869
+ shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);
1870
+
1871
+ if (shm_zone == NULL) {
1872
+ return;
1873
+ }
1874
+
1875
+ cache = shm_zone->data;
1876
+
1877
+ id = sess->session_id;
1878
+ len = (size_t) sess->session_id_length;
1879
+
1880
+ hash = ngx_crc32_short(id, len);
1881
+
1882
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
1883
+ "ssl remove session: %08XD:%uz", hash, len);
1884
+
1885
+ shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
1886
+
1887
+ ngx_shmtx_lock(&shpool->mutex);
1888
+
1889
+ node = cache->session_rbtree.root;
1890
+ sentinel = cache->session_rbtree.sentinel;
1891
+
1892
+ while (node != sentinel) {
1893
+
1894
+ if (hash < node->key) {
1895
+ node = node->left;
1896
+ continue;
1897
+ }
1898
+
1899
+ if (hash > node->key) {
1900
+ node = node->right;
1901
+ continue;
1902
+ }
1903
+
1904
+ /* hash == node->key */
1905
+
1906
+ sess_id = (ngx_ssl_sess_id_t *) node;
1907
+
1908
+ rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
1909
+
1910
+ if (rc == 0) {
1911
+
1912
+ ngx_queue_remove(&sess_id->queue);
1913
+
1914
+ ngx_rbtree_delete(&cache->session_rbtree, node);
1915
+
1916
+ ngx_slab_free_locked(shpool, sess_id->session);
1917
+ #if (NGX_PTR_SIZE == 4)
1918
+ ngx_slab_free_locked(shpool, sess_id->id);
1919
+ #endif
1920
+ ngx_slab_free_locked(shpool, sess_id);
1921
+
1922
+ goto done;
1923
+ }
1924
+
1925
+ node = (rc < 0) ? node->left : node->right;
1926
+ }
1927
+
1928
+ done:
1929
+
1930
+ ngx_shmtx_unlock(&shpool->mutex);
1931
+ }
1932
+
1933
+
1934
+ static void
1935
+ ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
1936
+ ngx_slab_pool_t *shpool, ngx_uint_t n)
1937
+ {
1938
+ time_t now;
1939
+ ngx_queue_t *q;
1940
+ ngx_ssl_sess_id_t *sess_id;
1941
+
1942
+ now = ngx_time();
1943
+
1944
+ while (n < 3) {
1945
+
1946
+ if (ngx_queue_empty(&cache->expire_queue)) {
1947
+ return;
1948
+ }
1949
+
1950
+ q = ngx_queue_last(&cache->expire_queue);
1951
+
1952
+ sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);
1953
+
1954
+ if (n++ != 0 && sess_id->expire > now) {
1955
+ return;
1956
+ }
1957
+
1958
+ ngx_queue_remove(q);
1959
+
1960
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
1961
+ "expire session: %08Xi", sess_id->node.key);
1962
+
1963
+ ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);
1964
+
1965
+ ngx_slab_free_locked(shpool, sess_id->session);
1966
+ #if (NGX_PTR_SIZE == 4)
1967
+ ngx_slab_free_locked(shpool, sess_id->id);
1968
+ #endif
1969
+ ngx_slab_free_locked(shpool, sess_id);
1970
+ }
1971
+ }
1972
+
1973
+
1974
+ static void
1975
+ ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
1976
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
1977
+ {
1978
+ ngx_rbtree_node_t **p;
1979
+ ngx_ssl_sess_id_t *sess_id, *sess_id_temp;
1980
+
1981
+ for ( ;; ) {
1982
+
1983
+ if (node->key < temp->key) {
1984
+
1985
+ p = &temp->left;
1986
+
1987
+ } else if (node->key > temp->key) {
1988
+
1989
+ p = &temp->right;
1990
+
1991
+ } else { /* node->key == temp->key */
1992
+
1993
+ sess_id = (ngx_ssl_sess_id_t *) node;
1994
+ sess_id_temp = (ngx_ssl_sess_id_t *) temp;
1995
+
1996
+ p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
1997
+ (size_t) node->data, (size_t) temp->data)
1998
+ < 0) ? &temp->left : &temp->right;
1999
+ }
2000
+
2001
+ if (*p == sentinel) {
2002
+ break;
2003
+ }
2004
+
2005
+ temp = *p;
2006
+ }
2007
+
2008
+ *p = node;
2009
+ node->parent = temp;
2010
+ node->left = sentinel;
2011
+ node->right = sentinel;
2012
+ ngx_rbt_red(node);
2013
+ }
2014
+
2015
+
2016
+ void
2017
+ ngx_ssl_cleanup_ctx(void *data)
2018
+ {
2019
+ ngx_ssl_t *ssl = data;
2020
+
2021
+ SSL_CTX_free(ssl->ctx);
2022
+ }
2023
+
2024
+
2025
+ ngx_int_t
2026
+ ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2027
+ {
2028
+ s->data = (u_char *) SSL_get_version(c->ssl->connection);
2029
+ return NGX_OK;
2030
+ }
2031
+
2032
+
2033
+ ngx_int_t
2034
+ ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2035
+ {
2036
+ s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);
2037
+ return NGX_OK;
2038
+ }
2039
+
2040
+
2041
+ ngx_int_t
2042
+ ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2043
+ {
2044
+ int len;
2045
+ u_char *p, *buf;
2046
+ SSL_SESSION *sess;
2047
+
2048
+ sess = SSL_get0_session(c->ssl->connection);
2049
+
2050
+ len = i2d_SSL_SESSION(sess, NULL);
2051
+
2052
+ buf = ngx_alloc(len, c->log);
2053
+ if (buf == NULL) {
2054
+ return NGX_ERROR;
2055
+ }
2056
+
2057
+ s->len = 2 * len;
2058
+ s->data = ngx_pnalloc(pool, 2 * len);
2059
+ if (s->data == NULL) {
2060
+ ngx_free(buf);
2061
+ return NGX_ERROR;
2062
+ }
2063
+
2064
+ p = buf;
2065
+ i2d_SSL_SESSION(sess, &p);
2066
+
2067
+ ngx_hex_dump(s->data, buf, len);
2068
+
2069
+ ngx_free(buf);
2070
+
2071
+ return NGX_OK;
2072
+ }
2073
+
2074
+
2075
+ ngx_int_t
2076
+ ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2077
+ {
2078
+ size_t len;
2079
+ BIO *bio;
2080
+ X509 *cert;
2081
+
2082
+ s->len = 0;
2083
+
2084
+ cert = SSL_get_peer_certificate(c->ssl->connection);
2085
+ if (cert == NULL) {
2086
+ return NGX_OK;
2087
+ }
2088
+
2089
+ bio = BIO_new(BIO_s_mem());
2090
+ if (bio == NULL) {
2091
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
2092
+ X509_free(cert);
2093
+ return NGX_ERROR;
2094
+ }
2095
+
2096
+ if (PEM_write_bio_X509(bio, cert) == 0) {
2097
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
2098
+ goto failed;
2099
+ }
2100
+
2101
+ len = BIO_pending(bio);
2102
+ s->len = len;
2103
+
2104
+ s->data = ngx_pnalloc(pool, len);
2105
+ if (s->data == NULL) {
2106
+ goto failed;
2107
+ }
2108
+
2109
+ BIO_read(bio, s->data, len);
2110
+
2111
+ BIO_free(bio);
2112
+ X509_free(cert);
2113
+
2114
+ return NGX_OK;
2115
+
2116
+ failed:
2117
+
2118
+ BIO_free(bio);
2119
+ X509_free(cert);
2120
+
2121
+ return NGX_ERROR;
2122
+ }
2123
+
2124
+
2125
+ ngx_int_t
2126
+ ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2127
+ {
2128
+ u_char *p;
2129
+ size_t len;
2130
+ ngx_uint_t i;
2131
+ ngx_str_t cert;
2132
+
2133
+ if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
2134
+ return NGX_ERROR;
2135
+ }
2136
+
2137
+ if (cert.len == 0) {
2138
+ s->len = 0;
2139
+ return NGX_OK;
2140
+ }
2141
+
2142
+ len = cert.len - 1;
2143
+
2144
+ for (i = 0; i < cert.len - 1; i++) {
2145
+ if (cert.data[i] == LF) {
2146
+ len++;
2147
+ }
2148
+ }
2149
+
2150
+ s->len = len;
2151
+ s->data = ngx_pnalloc(pool, len);
2152
+ if (s->data == NULL) {
2153
+ return NGX_ERROR;
2154
+ }
2155
+
2156
+ p = s->data;
2157
+
2158
+ for (i = 0; i < cert.len - 1; i++) {
2159
+ *p++ = cert.data[i];
2160
+ if (cert.data[i] == LF) {
2161
+ *p++ = '\t';
2162
+ }
2163
+ }
2164
+
2165
+ return NGX_OK;
2166
+ }
2167
+
2168
+
2169
+ ngx_int_t
2170
+ ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2171
+ {
2172
+ char *p;
2173
+ size_t len;
2174
+ X509 *cert;
2175
+ X509_NAME *name;
2176
+
2177
+ s->len = 0;
2178
+
2179
+ cert = SSL_get_peer_certificate(c->ssl->connection);
2180
+ if (cert == NULL) {
2181
+ return NGX_OK;
2182
+ }
2183
+
2184
+ name = X509_get_subject_name(cert);
2185
+ if (name == NULL) {
2186
+ X509_free(cert);
2187
+ return NGX_ERROR;
2188
+ }
2189
+
2190
+ p = X509_NAME_oneline(name, NULL, 0);
2191
+
2192
+ for (len = 0; p[len]; len++) { /* void */ }
2193
+
2194
+ s->len = len;
2195
+ s->data = ngx_pnalloc(pool, len);
2196
+ if (s->data == NULL) {
2197
+ OPENSSL_free(p);
2198
+ X509_free(cert);
2199
+ return NGX_ERROR;
2200
+ }
2201
+
2202
+ ngx_memcpy(s->data, p, len);
2203
+
2204
+ OPENSSL_free(p);
2205
+ X509_free(cert);
2206
+
2207
+ return NGX_OK;
2208
+ }
2209
+
2210
+
2211
+ ngx_int_t
2212
+ ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2213
+ {
2214
+ char *p;
2215
+ size_t len;
2216
+ X509 *cert;
2217
+ X509_NAME *name;
2218
+
2219
+ s->len = 0;
2220
+
2221
+ cert = SSL_get_peer_certificate(c->ssl->connection);
2222
+ if (cert == NULL) {
2223
+ return NGX_OK;
2224
+ }
2225
+
2226
+ name = X509_get_issuer_name(cert);
2227
+ if (name == NULL) {
2228
+ X509_free(cert);
2229
+ return NGX_ERROR;
2230
+ }
2231
+
2232
+ p = X509_NAME_oneline(name, NULL, 0);
2233
+
2234
+ for (len = 0; p[len]; len++) { /* void */ }
2235
+
2236
+ s->len = len;
2237
+ s->data = ngx_pnalloc(pool, len);
2238
+ if (s->data == NULL) {
2239
+ OPENSSL_free(p);
2240
+ X509_free(cert);
2241
+ return NGX_ERROR;
2242
+ }
2243
+
2244
+ ngx_memcpy(s->data, p, len);
2245
+
2246
+ OPENSSL_free(p);
2247
+ X509_free(cert);
2248
+
2249
+ return NGX_OK;
2250
+ }
2251
+
2252
+
2253
+ ngx_int_t
2254
+ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2255
+ {
2256
+ size_t len;
2257
+ X509 *cert;
2258
+ BIO *bio;
2259
+
2260
+ s->len = 0;
2261
+
2262
+ cert = SSL_get_peer_certificate(c->ssl->connection);
2263
+ if (cert == NULL) {
2264
+ return NGX_OK;
2265
+ }
2266
+
2267
+ bio = BIO_new(BIO_s_mem());
2268
+ if (bio == NULL) {
2269
+ X509_free(cert);
2270
+ return NGX_ERROR;
2271
+ }
2272
+
2273
+ i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
2274
+ len = BIO_pending(bio);
2275
+
2276
+ s->len = len;
2277
+ s->data = ngx_pnalloc(pool, len);
2278
+ if (s->data == NULL) {
2279
+ BIO_free(bio);
2280
+ X509_free(cert);
2281
+ return NGX_ERROR;
2282
+ }
2283
+
2284
+ BIO_read(bio, s->data, len);
2285
+ BIO_free(bio);
2286
+ X509_free(cert);
2287
+
2288
+ return NGX_OK;
2289
+ }
2290
+
2291
+
2292
+ ngx_int_t
2293
+ ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2294
+ {
2295
+ X509 *cert;
2296
+
2297
+ if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
2298
+ ngx_str_set(s, "FAILED");
2299
+ return NGX_OK;
2300
+ }
2301
+
2302
+ cert = SSL_get_peer_certificate(c->ssl->connection);
2303
+
2304
+ if (cert) {
2305
+ ngx_str_set(s, "SUCCESS");
2306
+
2307
+ } else {
2308
+ ngx_str_set(s, "NONE");
2309
+ }
2310
+
2311
+ X509_free(cert);
2312
+
2313
+ return NGX_OK;
2314
+ }
2315
+
2316
+
2317
+ static void *
2318
+ ngx_openssl_create_conf(ngx_cycle_t *cycle)
2319
+ {
2320
+ ngx_openssl_conf_t *oscf;
2321
+
2322
+ oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
2323
+ if (oscf == NULL) {
2324
+ return NULL;
2325
+ }
2326
+
2327
+ /*
2328
+ * set by ngx_pcalloc():
2329
+ *
2330
+ * oscf->engine = 0;
2331
+ */
2332
+
2333
+ return oscf;
2334
+ }
2335
+
2336
+
2337
+ static char *
2338
+ ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2339
+ {
2340
+ ngx_openssl_conf_t *oscf = conf;
2341
+
2342
+ ENGINE *engine;
2343
+ ngx_str_t *value;
2344
+
2345
+ if (oscf->engine) {
2346
+ return "is duplicate";
2347
+ }
2348
+
2349
+ oscf->engine = 1;
2350
+
2351
+ value = cf->args->elts;
2352
+
2353
+ engine = ENGINE_by_id((const char *) value[1].data);
2354
+
2355
+ if (engine == NULL) {
2356
+ ngx_ssl_error(NGX_LOG_WARN, cf->log, 0,
2357
+ "ENGINE_by_id(\"%V\") failed", &value[1]);
2358
+ return NGX_CONF_ERROR;
2359
+ }
2360
+
2361
+ if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
2362
+ ngx_ssl_error(NGX_LOG_WARN, cf->log, 0,
2363
+ "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",
2364
+ &value[1]);
2365
+
2366
+ ENGINE_free(engine);
2367
+
2368
+ return NGX_CONF_ERROR;
2369
+ }
2370
+
2371
+ ENGINE_free(engine);
2372
+
2373
+ return NGX_CONF_OK;
2374
+ }
2375
+
2376
+
2377
+ static void
2378
+ ngx_openssl_exit(ngx_cycle_t *cycle)
2379
+ {
2380
+ EVP_cleanup();
2381
+ ENGINE_cleanup();
2382
+ }