eventmachine-mkroman 1.3.0.dev.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +179 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +110 -0
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +520 -0
  8. data/docs/old/ChangeLog +211 -0
  9. data/docs/old/DEFERRABLES +246 -0
  10. data/docs/old/EPOLL +141 -0
  11. data/docs/old/INSTALL +13 -0
  12. data/docs/old/KEYBOARD +42 -0
  13. data/docs/old/LEGAL +25 -0
  14. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  15. data/docs/old/PURE_RUBY +75 -0
  16. data/docs/old/RELEASE_NOTES +94 -0
  17. data/docs/old/SMTP +4 -0
  18. data/docs/old/SPAWNED_PROCESSES +148 -0
  19. data/docs/old/TODO +8 -0
  20. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  21. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  22. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  23. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  24. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  25. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  26. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  27. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  28. data/examples/old/ex_channel.rb +43 -0
  29. data/examples/old/ex_queue.rb +2 -0
  30. data/examples/old/ex_tick_loop_array.rb +15 -0
  31. data/examples/old/ex_tick_loop_counter.rb +32 -0
  32. data/examples/old/helper.rb +2 -0
  33. data/ext/binder.cpp +124 -0
  34. data/ext/binder.h +52 -0
  35. data/ext/cmain.cpp +1046 -0
  36. data/ext/ed.cpp +2243 -0
  37. data/ext/ed.h +463 -0
  38. data/ext/em.cpp +2378 -0
  39. data/ext/em.h +266 -0
  40. data/ext/eventmachine.h +152 -0
  41. data/ext/extconf.rb +291 -0
  42. data/ext/fastfilereader/extconf.rb +120 -0
  43. data/ext/fastfilereader/mapper.cpp +214 -0
  44. data/ext/fastfilereader/mapper.h +59 -0
  45. data/ext/fastfilereader/rubymain.cpp +126 -0
  46. data/ext/kb.cpp +79 -0
  47. data/ext/page.cpp +107 -0
  48. data/ext/page.h +51 -0
  49. data/ext/pipe.cpp +354 -0
  50. data/ext/project.h +174 -0
  51. data/ext/rubymain.cpp +1643 -0
  52. data/ext/ssl.cpp +701 -0
  53. data/ext/ssl.h +103 -0
  54. data/ext/wait_for_single_fd.h +36 -0
  55. data/java/.classpath +8 -0
  56. data/java/.project +17 -0
  57. data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
  58. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  59. data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
  60. data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
  61. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
  62. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
  63. data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
  64. data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
  65. data/lib/em/buftok.rb +59 -0
  66. data/lib/em/callback.rb +58 -0
  67. data/lib/em/channel.rb +69 -0
  68. data/lib/em/completion.rb +307 -0
  69. data/lib/em/connection.rb +802 -0
  70. data/lib/em/deferrable/pool.rb +2 -0
  71. data/lib/em/deferrable.rb +210 -0
  72. data/lib/em/file_watch.rb +73 -0
  73. data/lib/em/future.rb +61 -0
  74. data/lib/em/io_streamer.rb +68 -0
  75. data/lib/em/iterator.rb +252 -0
  76. data/lib/em/messages.rb +66 -0
  77. data/lib/em/pool.rb +151 -0
  78. data/lib/em/process_watch.rb +45 -0
  79. data/lib/em/processes.rb +123 -0
  80. data/lib/em/protocols/header_and_content.rb +138 -0
  81. data/lib/em/protocols/httpclient.rb +303 -0
  82. data/lib/em/protocols/httpclient2.rb +602 -0
  83. data/lib/em/protocols/line_and_text.rb +125 -0
  84. data/lib/em/protocols/line_protocol.rb +33 -0
  85. data/lib/em/protocols/linetext2.rb +179 -0
  86. data/lib/em/protocols/memcache.rb +331 -0
  87. data/lib/em/protocols/object_protocol.rb +46 -0
  88. data/lib/em/protocols/postgres3.rb +246 -0
  89. data/lib/em/protocols/saslauth.rb +175 -0
  90. data/lib/em/protocols/smtpclient.rb +394 -0
  91. data/lib/em/protocols/smtpserver.rb +666 -0
  92. data/lib/em/protocols/socks4.rb +66 -0
  93. data/lib/em/protocols/stomp.rb +205 -0
  94. data/lib/em/protocols/tcptest.rb +54 -0
  95. data/lib/em/protocols.rb +37 -0
  96. data/lib/em/pure_ruby.rb +1300 -0
  97. data/lib/em/queue.rb +80 -0
  98. data/lib/em/resolver.rb +232 -0
  99. data/lib/em/spawnable.rb +84 -0
  100. data/lib/em/streamer.rb +118 -0
  101. data/lib/em/threaded_resource.rb +90 -0
  102. data/lib/em/tick_loop.rb +85 -0
  103. data/lib/em/timers.rb +61 -0
  104. data/lib/em/version.rb +3 -0
  105. data/lib/eventmachine.rb +1602 -0
  106. data/lib/jeventmachine.rb +319 -0
  107. data/rakelib/package.rake +120 -0
  108. data/rakelib/test.rake +6 -0
  109. data/rakelib/test_pure.rake +11 -0
  110. data/tests/client.crt +31 -0
  111. data/tests/client.key +51 -0
  112. data/tests/dhparam.pem +13 -0
  113. data/tests/em_ssl_handlers.rb +165 -0
  114. data/tests/em_test_helper.rb +198 -0
  115. data/tests/encoded_client.key +54 -0
  116. data/tests/jruby/test_jeventmachine.rb +38 -0
  117. data/tests/test_attach.rb +199 -0
  118. data/tests/test_basic.rb +321 -0
  119. data/tests/test_channel.rb +75 -0
  120. data/tests/test_completion.rb +178 -0
  121. data/tests/test_connection_count.rb +83 -0
  122. data/tests/test_connection_write.rb +35 -0
  123. data/tests/test_defer.rb +35 -0
  124. data/tests/test_deferrable.rb +35 -0
  125. data/tests/test_epoll.rb +141 -0
  126. data/tests/test_error_handler.rb +38 -0
  127. data/tests/test_exc.rb +37 -0
  128. data/tests/test_file_watch.rb +86 -0
  129. data/tests/test_fork.rb +75 -0
  130. data/tests/test_futures.rb +170 -0
  131. data/tests/test_handler_check.rb +35 -0
  132. data/tests/test_hc.rb +155 -0
  133. data/tests/test_httpclient.rb +238 -0
  134. data/tests/test_httpclient2.rb +132 -0
  135. data/tests/test_idle_connection.rb +31 -0
  136. data/tests/test_inactivity_timeout.rb +102 -0
  137. data/tests/test_io_streamer.rb +48 -0
  138. data/tests/test_ipv4.rb +96 -0
  139. data/tests/test_ipv6.rb +107 -0
  140. data/tests/test_iterator.rb +122 -0
  141. data/tests/test_kb.rb +28 -0
  142. data/tests/test_keepalive.rb +113 -0
  143. data/tests/test_line_protocol.rb +33 -0
  144. data/tests/test_ltp.rb +155 -0
  145. data/tests/test_ltp2.rb +332 -0
  146. data/tests/test_many_fds.rb +21 -0
  147. data/tests/test_next_tick.rb +104 -0
  148. data/tests/test_object_protocol.rb +36 -0
  149. data/tests/test_pause.rb +109 -0
  150. data/tests/test_pending_connect_timeout.rb +52 -0
  151. data/tests/test_pool.rb +196 -0
  152. data/tests/test_process_watch.rb +50 -0
  153. data/tests/test_processes.rb +147 -0
  154. data/tests/test_proxy_connection.rb +180 -0
  155. data/tests/test_pure.rb +156 -0
  156. data/tests/test_queue.rb +64 -0
  157. data/tests/test_resolver.rb +129 -0
  158. data/tests/test_running.rb +14 -0
  159. data/tests/test_sasl.rb +46 -0
  160. data/tests/test_send_file.rb +217 -0
  161. data/tests/test_servers.rb +32 -0
  162. data/tests/test_shutdown_hooks.rb +23 -0
  163. data/tests/test_smtpclient.rb +75 -0
  164. data/tests/test_smtpserver.rb +90 -0
  165. data/tests/test_sock_opt.rb +53 -0
  166. data/tests/test_spawn.rb +290 -0
  167. data/tests/test_ssl_args.rb +70 -0
  168. data/tests/test_ssl_dhparam.rb +57 -0
  169. data/tests/test_ssl_ecdh_curve.rb +57 -0
  170. data/tests/test_ssl_extensions.rb +24 -0
  171. data/tests/test_ssl_inline_cert.rb +222 -0
  172. data/tests/test_ssl_methods.rb +31 -0
  173. data/tests/test_ssl_protocols.rb +190 -0
  174. data/tests/test_ssl_verify.rb +108 -0
  175. data/tests/test_stomp.rb +38 -0
  176. data/tests/test_system.rb +46 -0
  177. data/tests/test_threaded_resource.rb +68 -0
  178. data/tests/test_tick_loop.rb +58 -0
  179. data/tests/test_timers.rb +150 -0
  180. data/tests/test_ud.rb +8 -0
  181. data/tests/test_unbind_reason.rb +40 -0
  182. metadata +389 -0
data/ext/ssl.cpp ADDED
@@ -0,0 +1,701 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: ssl.cpp
6
+ Date: 30Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+ #ifdef WITH_SSL
22
+
23
+ #include "project.h"
24
+
25
+
26
+ bool SslContext_t::bLibraryInitialized = false;
27
+
28
+
29
+
30
+ static void InitializeDefaultCredentials();
31
+ static EVP_PKEY *DefaultPrivateKey = NULL;
32
+ static X509 *DefaultCertificate = NULL;
33
+
34
+ static char PrivateMaterials[] = {
35
+ "-----BEGIN RSA PRIVATE KEY-----\n"
36
+ "MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDQmOnboooYGgbU\n"
37
+ "rNr+O7xQRrEn/pFdVfWTmW/vCbWWL7BYerxs9Uh7E1PmQpIovdw1DClFx4vMkdvb\n"
38
+ "RHzkILY4+mgN05FLdwncxF8X+za4p7nhvJWu2TIinRmkmHRIiXncMU4yqreKnjAX\n"
39
+ "9kacWxPMglvnge7CUsywWmaN7qyFT+ywcuN/EGoCiFU7Dzen/HqTgPGeq4gOJ9wl\n"
40
+ "ImFuaAiA7696K7UwBI/QEN76QmYOG/iXdZNnp1DDY9h2pA2fmJTmKUzzkk8XXz+Z\n"
41
+ "Q4/NHOdzLvl7znRrlI2Y6m4LEr1cCdn7mWNESo5dkif8LVX1j/RDOP6Dtv+oYscG\n"
42
+ "TPSSR+Wlcw/0K4tAOILtDs1IVAGhcfZbTXM3EQS66Zx84yrlqkno6JKaGEKvtF9h\n"
43
+ "qEYT7lxHP/kIsyxZvXAhJQ8A1ajTDcqetyzphQiaKqeWTEmobibD8JtqshggTVv5\n"
44
+ "DtvdU62AfrDfOXub51/+WtdhjCe30aIrLpAaXOTktqYW1tv5Vj986Aj2JPBu7cQZ\n"
45
+ "Zxq1KG6KwfeB4EQTxJ5Nt+qJlPC8QPGoep1XejCSgShW6/NjK76C+dXvYFy1Poj+\n"
46
+ "4iddW385y1MB+7AwjXEpEQHv5XZ+lkXSk8qtQkgGgQjies6tHKdNv1cfmXMrk0zv\n"
47
+ "c+YOQZxCqIUyI0nqyiCA8+2FNYW7PwIDAQABAoICAQCXgxoJsAvB6dWgUFVYaCcl\n"
48
+ "39L5i8wmETOom8BTzaeZiNX7zlpigd69lpJQI3ZqJU13Mngf+Qqv8hnRL/PO93uj\n"
49
+ "8y31LQDR4YrGUdQIZS2f/iPjtMi8EYJ65cUkap+7uC9NInr8Dkf2ZWPlY7pyAy1k\n"
50
+ "VCNRCm1TtDR8u4zV9tBUnHL8ztYzCscVQ9U0ap8wYxDdZsEZUNon/gfG6Sv/t4zF\n"
51
+ "qlK42FpooEedB0QOXoAmK2brDDmfBkaBRVqLAinrDDbK3qDIIjNUdJiLSCmBAEeU\n"
52
+ "wD/yD0k8gtA+i7iWTmxAF9+/AfC6P7UcffaREpTnIkJ3OUSUgy07L1QEXY0fWx2P\n"
53
+ "OFy/ZwUJBvmVCL6dJkDZyBHjDwiu9V09sbdQ9dU+eM8XeaYq1DxWtfuVYnCvId1b\n"
54
+ "i6kEZTSAW2IVMazcbZA7GYH+yrYt7Gmhyy/9fR1Kovf6bouJFOhK0oBNNBGf3rZj\n"
55
+ "VfZyVJ6U1gGx7DGKGeWHIUswtXEBjpfAZ436k6ruKKyDfneeb82uCf4jp/vFVNN3\n"
56
+ "CxiAsCoicULdtKj4U4EmxN9HInGPpLBT32hfHLUnpNzFmoAN6dVRjA++4kzq9Q3Q\n"
57
+ "qFgoV7pXP/A2nyZv+QD5GJ218a7B/QThmWsAEEaaNYyNzKmowDckv6cGwTiBv3zD\n"
58
+ "7wAQ2n5Vh4bStbiTqRbroQKCAQEA+PRzSPIwlhU0iDhTqTec+RxyYOuQMEizwJHr\n"
59
+ "+kgJlvmhUVQ3ALQKzcTRrkz6VAgO/MvoF2gUj6bVLcEo/jqHrc7IC83L4+B7xBFh\n"
60
+ "M7dELCvIiETIPivwVSW5vgLY51O2aiJdsZRr7L0jyjQP1uMoc304JegXAC7SxwqH\n"
61
+ "+gmsmGMlUfB2I4NYRR12+so7paGqGYgjHaki6e1oNKaWk/8W8FJWh7Vqa9RTEkFD\n"
62
+ "oog0JM6yT1ykm2fRdsPaar2lcYbfXAdPuEMpTE+3pQ+au62ZS7vdFGx1FL5ffZyS\n"
63
+ "UvmxywJZBvW8Al++PbGuX39AJ948WM/riTt1M2N+AOOsJ32f+QKCAQEA1oAX64id\n"
64
+ "eMoXjUjekektTp1hcDRTipF7npjnxI1DUhDJTWgeAUlLzC+RDUpJl64vVF8yEGM2\n"
65
+ "N9R1TVQ+B9QglC0OQzpp0h6nCeTcfn12SzzlqsyKzx/07Sucg2VRIdUzpad9gKCR\n"
66
+ "Qza5v96rGl0yN7kDrjN9WK511wzLgYdKFkqsvC/bW62HFKkDbfEKqy8qTNy3Haus\n"
67
+ "dgfc9uMeqLzuC73bHqVxkRvOdIbRhQw1KGggpnw3Jrs94qydMJu3MYZPfsTbeDvC\n"
68
+ "44O83dsrVjOKFXGVTOtZRluHKeeArdtmfUmZaENUXwyaSiGU89Y7AOo+vOFHXMjm\n"
69
+ "r/V6fKnVbo/y9wKCAQEAx3NIvWNTK5p3iL7fv81PVIDG3gE7doN4h0og7VYzYKJD\n"
70
+ "7J10p3qWwT3y4xrG3vXJ1BwkqEP5XRFC7zI2fl8z/jqRKGvK8pkRbwahgkZMNrsp\n"
71
+ "IItChhS7qevcgG9ViRcXKLa5q6CGSpdJiiDlo7o/2S60AiKL8tiQg2hbgiWoAjpE\n"
72
+ "Vv44F8GNwWmWvduxp8P6PBRGVegAkbti5fOk5ZLTtNuyeW0NgrALka952UgXxnlW\n"
73
+ "f6BwPBUTynukjCm911M/tUIiSzR7bKjdLz9uLvgovXUX7Nnrfx/57u+2hwWGvGb4\n"
74
+ "HkxXQOulxVWJpvaS1p4EaP7C7CIXhoEqHNpKPSU3OQKCAQEArJs9JGK13Ro6o42M\n"
75
+ "1LtfoxBP9VuWEj6JzJDciDTohGRPqMNsyboyjWeFgL1TxQP8wBcukTNU0M5dalGs\n"
76
+ "7N3NLY+oF38s4lGaNwL8T6kkBN1HLw8TcCMWE7fxZWalR+VpfxbtjhEnc3/ZL0W+\n"
77
+ "SCPQojh2drqmVjNlThzUsjGs8405vOGB0h8sQPrUcKbz39a/YkSF8hFQYVZogB85\n"
78
+ "b61AnSA08E9PuOY4V1qZxUeSiyZnh7ETLE6mOP6QKypS2z5qP+end/QXGr/Kvnh8\n"
79
+ "QgyNRD43V0NXfp9uf9DzonOX4J/WG6l6flYE3jxxwVmV92GIBLP/mfFseRG/dAuy\n"
80
+ "XRrm9wKCAQAFRj1X8h3ePt7sCUUZXN2XBsEPx7W+hVzl+STu4oDmPMcCL8tL6Ndd\n"
81
+ "eUZChT+fZbgSk+rw7OYnNGi5+ES3qRQwXdIJKP8Niu0cHCFPaikWn5rC3Yu8ngsg\n"
82
+ "XsrVCNsvfDZkfRtd73s8LFp0+pmTe1AlWVxcDnBZOsoezppDxikHgoRdNbPjGGrO\n"
83
+ "T/J8XCPS5aT5TOr1tywKgruqLuZ7v7W6zLDBeImqKGDbH7D5+8vMYUu6d1hoXETp\n"
84
+ "DuBmagv/t80FQda1p6b7V0ICvp7GuqGhMjgBFDDszs3cdDZa8sZvheMPOog56EYd\n"
85
+ "Rnvuj8XvBcSE6pVTMgkCw06w2fpef7T7\n"
86
+ "-----END RSA PRIVATE KEY-----\n"
87
+ "-----BEGIN CERTIFICATE-----\n"
88
+ "MIIFZTCCA02gAwIBAgIUMAJUww8HOXGFlyZvieX9rzd+1x4wDQYJKoZIhvcNAQEL\n"
89
+ "BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE\n"
90
+ "CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMDA4MDQxMDQxMzRaFw0zODA1MjIx\n"
91
+ "MDQxMzRaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa\n"
92
+ "BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4IC\n"
93
+ "DwAwggIKAoICAQDQmOnboooYGgbUrNr+O7xQRrEn/pFdVfWTmW/vCbWWL7BYerxs\n"
94
+ "9Uh7E1PmQpIovdw1DClFx4vMkdvbRHzkILY4+mgN05FLdwncxF8X+za4p7nhvJWu\n"
95
+ "2TIinRmkmHRIiXncMU4yqreKnjAX9kacWxPMglvnge7CUsywWmaN7qyFT+ywcuN/\n"
96
+ "EGoCiFU7Dzen/HqTgPGeq4gOJ9wlImFuaAiA7696K7UwBI/QEN76QmYOG/iXdZNn\n"
97
+ "p1DDY9h2pA2fmJTmKUzzkk8XXz+ZQ4/NHOdzLvl7znRrlI2Y6m4LEr1cCdn7mWNE\n"
98
+ "So5dkif8LVX1j/RDOP6Dtv+oYscGTPSSR+Wlcw/0K4tAOILtDs1IVAGhcfZbTXM3\n"
99
+ "EQS66Zx84yrlqkno6JKaGEKvtF9hqEYT7lxHP/kIsyxZvXAhJQ8A1ajTDcqetyzp\n"
100
+ "hQiaKqeWTEmobibD8JtqshggTVv5DtvdU62AfrDfOXub51/+WtdhjCe30aIrLpAa\n"
101
+ "XOTktqYW1tv5Vj986Aj2JPBu7cQZZxq1KG6KwfeB4EQTxJ5Nt+qJlPC8QPGoep1X\n"
102
+ "ejCSgShW6/NjK76C+dXvYFy1Poj+4iddW385y1MB+7AwjXEpEQHv5XZ+lkXSk8qt\n"
103
+ "QkgGgQjies6tHKdNv1cfmXMrk0zvc+YOQZxCqIUyI0nqyiCA8+2FNYW7PwIDAQAB\n"
104
+ "o1MwUTAdBgNVHQ4EFgQUWE9IXPXnQXqYKQYcDSjAxNSwejowHwYDVR0jBBgwFoAU\n"
105
+ "WE9IXPXnQXqYKQYcDSjAxNSwejowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B\n"
106
+ "AQsFAAOCAgEAu94JzOvp/NQ+/OPaJw6cilSu5E+S1mcLJiPWmkv41Gwnl86rDfS1\n"
107
+ "eVmR58jJhKKypeahNgCMq1dvlIrlIrQEF6hi2JBMjYDPNCWPcWzCqVbOSXfNRKWg\n"
108
+ "78nzAuSj0Kp3WEsw95ACmGbJODEW3Ga+AzRIPe4vw35sv06eZsUJJ3QD4mTjOEV9\n"
109
+ "UQvVozP5FUCY2VLBjjWT6dDykDiYKTc/xaE2SUgRgykY4nJxihEN6QMLghlEuPyY\n"
110
+ "mOKKXXMQDyZalGc9V/VtUY3qNnrbIhcBQeZgKXGRPEqnbTw0H7Q+fSc7xj5bFAmr\n"
111
+ "ufjQSWCqqbPNPvgt9NytOUrCzNeKk2x/BUDyI0kHUBj17HtBNo9o4ongcSM2Qs/Z\n"
112
+ "kfi/lr/UpqpelIlreC8IJsAY5cgjeChebAwEhf8uGh41grJwmowjVSDqFb0rINTO\n"
113
+ "imUEABpFQ/zBGdF1ZG/y07N7mvgEE0UwcH8Si1wSIxWlXw36dED1yoUROKgTXG4k\n"
114
+ "ChJmWyPwZoxjBtR86UwIyVgC2Z8pya8h7uvp2wKtlSNUqpXmCvsl+X/zib2YRwI/\n"
115
+ "QvxbM4J50AGyIiqXzuULCg2ap9t7Zpc9/+hg0t5BEbym+RbcNLy+lh4ZjrEwH3Xe\n"
116
+ "LNIU1lM0Xyg0SY6o1hfH3eiRukedhlametaIGwYG6n5gzYgh7T4W+uI=\n"
117
+ "-----END CERTIFICATE-----\n"};
118
+
119
+ /* These private materials were made with:
120
+ * openssl req -new -x509 -keyout cakey.pem -out cacert.pem -nodes -days 6500 -pkeyopt rsa_keygen_bits:4096
121
+ * TODO: We need a full-blown capability to work with user-supplied
122
+ * keypairs and properly-signed certificates.
123
+ */
124
+
125
+
126
+ /*****************
127
+ builtin_passwd_cb
128
+ *****************/
129
+
130
+ extern "C" int builtin_passwd_cb (char *buf UNUSED, int bufsize UNUSED, int rwflag UNUSED, void *userdata UNUSED)
131
+ {
132
+ strcpy (buf, "kittycat");
133
+ return 8;
134
+ }
135
+
136
+ /****************************
137
+ InitializeDefaultCredentials
138
+ ****************************/
139
+
140
+ static void InitializeDefaultCredentials()
141
+ {
142
+ BIO *bio = BIO_new_mem_buf (PrivateMaterials, -1);
143
+ assert (bio);
144
+
145
+ if (DefaultPrivateKey) {
146
+ // we may come here in a restart.
147
+ EVP_PKEY_free (DefaultPrivateKey);
148
+ DefaultPrivateKey = NULL;
149
+ }
150
+ PEM_read_bio_PrivateKey (bio, &DefaultPrivateKey, builtin_passwd_cb, 0);
151
+ if (DefaultCertificate) {
152
+ // we may come here in a restart.
153
+ X509_free (DefaultCertificate);
154
+ DefaultCertificate = NULL;
155
+ }
156
+ PEM_read_bio_X509 (bio, &DefaultCertificate, NULL, 0);
157
+
158
+ BIO_free (bio);
159
+ }
160
+
161
+
162
+
163
+ /**************************
164
+ SslContext_t::SslContext_t
165
+ **************************/
166
+
167
+ SslContext_t::SslContext_t (bool is_server, const std::string &privkeyfile, const std::string &privkey, const std::string &privkeypass, const std::string &certchainfile, const std::string &cert, const std::string &cipherlist, const std::string &ecdh_curve, const std::string &dhparam, int ssl_version) :
168
+ bIsServer (is_server),
169
+ pCtx (NULL),
170
+ PrivateKey (NULL),
171
+ Certificate (NULL)
172
+ {
173
+ /* TODO: Also, in this implementation, server-side connections use statically defined X-509 defaults.
174
+ * One thing I'm really not clear on is whether or not you have to explicitly free X509 and EVP_PKEY
175
+ * objects when we call our destructor, or whether just calling SSL_CTX_free is enough.
176
+ */
177
+
178
+ if (!bLibraryInitialized) {
179
+ bLibraryInitialized = true;
180
+ SSL_library_init();
181
+ OpenSSL_add_ssl_algorithms();
182
+ OpenSSL_add_all_algorithms();
183
+ SSL_load_error_strings();
184
+ ERR_load_crypto_strings();
185
+
186
+ InitializeDefaultCredentials();
187
+ }
188
+ #ifdef HAVE_TLS_SERVER_METHOD
189
+ pCtx = SSL_CTX_new (bIsServer ? TLS_server_method() : TLS_client_method());
190
+ #else
191
+ pCtx = SSL_CTX_new (bIsServer ? SSLv23_server_method() : SSLv23_client_method());
192
+ #endif
193
+ if (!pCtx)
194
+ throw std::runtime_error ("no SSL context");
195
+
196
+ SSL_CTX_set_options (pCtx, SSL_OP_ALL);
197
+
198
+ #ifdef SSL_CTRL_CLEAR_OPTIONS
199
+ SSL_CTX_clear_options (pCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
200
+ # ifdef SSL_OP_NO_TLSv1_1
201
+ SSL_CTX_clear_options (pCtx, SSL_OP_NO_TLSv1_1);
202
+ # endif
203
+ # ifdef SSL_OP_NO_TLSv1_2
204
+ SSL_CTX_clear_options (pCtx, SSL_OP_NO_TLSv1_2);
205
+ # endif
206
+ #endif
207
+
208
+ if (!(ssl_version & EM_PROTO_SSLv2))
209
+ SSL_CTX_set_options (pCtx, SSL_OP_NO_SSLv2);
210
+
211
+ if (!(ssl_version & EM_PROTO_SSLv3))
212
+ SSL_CTX_set_options (pCtx, SSL_OP_NO_SSLv3);
213
+
214
+ if (!(ssl_version & EM_PROTO_TLSv1))
215
+ SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1);
216
+
217
+ #ifdef SSL_OP_NO_TLSv1_1
218
+ if (!(ssl_version & EM_PROTO_TLSv1_1))
219
+ SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1_1);
220
+ #endif
221
+
222
+ #ifdef SSL_OP_NO_TLSv1_2
223
+ if (!(ssl_version & EM_PROTO_TLSv1_2))
224
+ SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1_2);
225
+ #endif
226
+
227
+ #ifdef SSL_OP_NO_TLSv1_3
228
+ if (!(ssl_version & EM_PROTO_TLSv1_3))
229
+ SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1_3);
230
+ #endif
231
+
232
+ #ifdef SSL_MODE_RELEASE_BUFFERS
233
+ SSL_CTX_set_mode (pCtx, SSL_MODE_RELEASE_BUFFERS);
234
+ #endif
235
+
236
+ int e;
237
+ // As indicated in man(3) ssl_ctx_use_privatekey_file
238
+ // To change a certificate, private key pair the new certificate needs to be set with
239
+ // SSL_use_certificate() or SSL_CTX_use_certificate() before setting the private key with SSL_CTX_use_PrivateKey() or SSL_use_PrivateKey().
240
+ if (certchainfile.length() > 0) {
241
+ e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
242
+ if (e <= 0) ERR_print_errors_fp(stderr);
243
+ assert (e > 0);
244
+ }
245
+ if (cert.length() > 0) {
246
+ BIO *bio = BIO_new_mem_buf (cert.c_str(), -1);
247
+ assert(bio);
248
+ BIO_set_mem_eof_return(bio, 0);
249
+ X509 * clientCertificate = PEM_read_bio_X509 (bio, NULL, NULL, 0);
250
+ e = SSL_CTX_use_certificate (pCtx, clientCertificate);
251
+ X509_free(clientCertificate);
252
+ BIO_free (bio);
253
+ if (e <= 0) ERR_print_errors_fp(stderr);
254
+ assert (e > 0);
255
+ }
256
+ if (privkeyfile.length() > 0) {
257
+ if (privkeypass.length() > 0) {
258
+ SSL_CTX_set_default_passwd_cb_userdata(pCtx, const_cast<char*>(privkeypass.c_str()));
259
+ }
260
+ e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
261
+ if (e <= 0) ERR_print_errors_fp(stderr);
262
+ assert (e > 0);
263
+ }
264
+ if (privkey.length() > 0) {
265
+ BIO *bio = BIO_new_mem_buf (privkey.c_str(), -1);
266
+ assert(bio);
267
+ BIO_set_mem_eof_return(bio, 0);
268
+ EVP_PKEY * clientPrivateKey = PEM_read_bio_PrivateKey (bio, NULL, NULL, const_cast<char*>(privkeypass.c_str()));
269
+ e = SSL_CTX_use_PrivateKey (pCtx, clientPrivateKey);
270
+ EVP_PKEY_free(clientPrivateKey);
271
+ BIO_free (bio);
272
+ if (e <= 0) {
273
+ BIO *bio_err = BIO_new(BIO_s_mem());
274
+ std::string error_msg;
275
+ if (bio_err != NULL) {
276
+ ERR_print_errors(bio_err);
277
+ char* buf;
278
+ long size = BIO_get_mem_data(bio_err, &buf);
279
+ error_msg.assign(buf,size);
280
+ BIO_free(bio_err);
281
+ }
282
+ throw std::runtime_error (error_msg);
283
+ }
284
+ assert (e > 0);
285
+ }
286
+
287
+ if (bIsServer) {
288
+ if (certchainfile.length() == 0 && cert.length() == 0) {
289
+ // ensure default private material is configured for ssl
290
+ e = SSL_CTX_use_certificate (pCtx, DefaultCertificate);
291
+ if (e <= 0) ERR_print_errors_fp(stderr);
292
+ assert (e > 0);
293
+ }
294
+ if (privkeyfile.length() == 0 && privkey.length() == 0) {
295
+ // ensure default private material is configured for ssl
296
+ e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey);
297
+ if (e <= 0) ERR_print_errors_fp(stderr);
298
+ assert (e > 0);
299
+ }
300
+ if (dhparam.length() > 0) {
301
+ DH *dh;
302
+ BIO *bio;
303
+
304
+ bio = BIO_new_file(dhparam.c_str(), "r");
305
+ if (bio == NULL) {
306
+ char buf [500];
307
+ snprintf (buf, sizeof(buf)-1, "dhparam: BIO_new_file(%s) failed", dhparam.c_str());
308
+ throw std::runtime_error (buf);
309
+ }
310
+
311
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
312
+
313
+ if (dh == NULL) {
314
+ BIO_free(bio);
315
+ char buf [500];
316
+ snprintf (buf, sizeof(buf)-1, "dhparam: PEM_read_bio_DHparams(%s) failed", dhparam.c_str());
317
+ throw std::runtime_error (buf);
318
+ }
319
+
320
+ SSL_CTX_set_tmp_dh(pCtx, dh);
321
+
322
+ DH_free(dh);
323
+ BIO_free(bio);
324
+ }
325
+
326
+ if (ecdh_curve.length() > 0) {
327
+ #if OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_ECDH)
328
+ int nid;
329
+ EC_KEY *ecdh;
330
+
331
+ nid = OBJ_sn2nid((const char *) ecdh_curve.c_str());
332
+ if (nid == 0) {
333
+ char buf [200];
334
+ snprintf (buf, sizeof(buf)-1, "ecdh_curve: Unknown curve name: %s", ecdh_curve.c_str());
335
+ throw std::runtime_error (buf);
336
+ }
337
+
338
+ ecdh = EC_KEY_new_by_curve_name(nid);
339
+ if (ecdh == NULL) {
340
+ char buf [200];
341
+ snprintf (buf, sizeof(buf)-1, "ecdh_curve: Unable to create: %s", ecdh_curve.c_str());
342
+ throw std::runtime_error (buf);
343
+ }
344
+
345
+ SSL_CTX_set_options(pCtx, SSL_OP_SINGLE_ECDH_USE);
346
+
347
+ SSL_CTX_set_tmp_ecdh(pCtx, ecdh);
348
+
349
+ EC_KEY_free(ecdh);
350
+ #else
351
+ throw std::runtime_error ("No openssl ECDH support");
352
+ #endif
353
+ }
354
+ }
355
+
356
+ if (cipherlist.length() > 0)
357
+ SSL_CTX_set_cipher_list (pCtx, cipherlist.c_str());
358
+ else
359
+ SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH");
360
+
361
+ if (bIsServer) {
362
+ SSL_CTX_sess_set_cache_size (pCtx, 128);
363
+ SSL_CTX_set_session_id_context (pCtx, (unsigned char*)"eventmachine", 12);
364
+ }
365
+ }
366
+
367
+
368
+
369
+ /***************************
370
+ SslContext_t::~SslContext_t
371
+ ***************************/
372
+
373
+ SslContext_t::~SslContext_t()
374
+ {
375
+ if (pCtx)
376
+ SSL_CTX_free (pCtx);
377
+ if (PrivateKey)
378
+ EVP_PKEY_free (PrivateKey);
379
+ if (Certificate)
380
+ X509_free (Certificate);
381
+ }
382
+
383
+
384
+
385
+ /******************
386
+ SslBox_t::SslBox_t
387
+ ******************/
388
+
389
+ SslBox_t::SslBox_t (bool is_server, const std::string &privkeyfile, const std::string &privkey, const std::string &privkeypass, const std::string &certchainfile, const std::string &cert, bool verify_peer, bool fail_if_no_peer_cert, const std::string &snihostname, const std::string &cipherlist, const std::string &ecdh_curve, const std::string &dhparam, int ssl_version, const uintptr_t binding):
390
+ bIsServer (is_server),
391
+ bHandshakeCompleted (false),
392
+ bVerifyPeer (verify_peer),
393
+ bFailIfNoPeerCert (fail_if_no_peer_cert),
394
+ pSSL (NULL),
395
+ pbioRead (NULL),
396
+ pbioWrite (NULL)
397
+ {
398
+ /* TODO someday: make it possible to re-use SSL contexts so we don't have to create
399
+ * a new one every time we come here.
400
+ */
401
+
402
+ Context = new SslContext_t (bIsServer, privkeyfile, privkey, privkeypass, certchainfile, cert, cipherlist, ecdh_curve, dhparam, ssl_version);
403
+ assert (Context);
404
+
405
+ pbioRead = BIO_new (BIO_s_mem());
406
+ assert (pbioRead);
407
+
408
+ pbioWrite = BIO_new (BIO_s_mem());
409
+ assert (pbioWrite);
410
+
411
+ pSSL = SSL_new (Context->pCtx);
412
+ assert (pSSL);
413
+
414
+ if (snihostname.length() > 0) {
415
+ SSL_set_tlsext_host_name (pSSL, snihostname.c_str());
416
+ }
417
+
418
+ SSL_set_bio (pSSL, pbioRead, pbioWrite);
419
+
420
+ // Store a pointer to the binding signature in the SSL object so we can retrieve it later
421
+ SSL_set_ex_data(pSSL, 0, (void*) binding);
422
+
423
+ if (bVerifyPeer) {
424
+ int mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
425
+ if (bFailIfNoPeerCert)
426
+ mode = mode | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
427
+ SSL_set_verify(pSSL, mode, ssl_verify_wrapper);
428
+ }
429
+
430
+ if (!bIsServer) {
431
+ int e = SSL_connect (pSSL);
432
+ if (e != 1)
433
+ ERR_print_errors_fp(stderr);
434
+ }
435
+ }
436
+
437
+
438
+
439
+ /*******************
440
+ SslBox_t::~SslBox_t
441
+ *******************/
442
+
443
+ SslBox_t::~SslBox_t()
444
+ {
445
+ // Freeing pSSL will also free the associated BIOs, so DON'T free them separately.
446
+ if (pSSL) {
447
+ if (SSL_get_shutdown (pSSL) & SSL_RECEIVED_SHUTDOWN)
448
+ SSL_shutdown (pSSL);
449
+ else
450
+ SSL_clear (pSSL);
451
+ SSL_free (pSSL);
452
+ }
453
+
454
+ delete Context;
455
+ }
456
+
457
+
458
+
459
+ /***********************
460
+ SslBox_t::PutCiphertext
461
+ ***********************/
462
+
463
+ bool SslBox_t::PutCiphertext (const char *buf, int bufsize)
464
+ {
465
+ assert (buf && (bufsize > 0));
466
+
467
+ assert (pbioRead);
468
+ int n = BIO_write (pbioRead, buf, bufsize);
469
+
470
+ return (n == bufsize) ? true : false;
471
+ }
472
+
473
+
474
+ /**********************
475
+ SslBox_t::GetPlaintext
476
+ **********************/
477
+
478
+ int SslBox_t::GetPlaintext (char *buf, int bufsize)
479
+ {
480
+ if (!SSL_is_init_finished (pSSL)) {
481
+ int e = bIsServer ? SSL_accept (pSSL) : SSL_connect (pSSL);
482
+ if (e != 1) {
483
+ int er = SSL_get_error (pSSL, e);
484
+ if (er != SSL_ERROR_WANT_READ) {
485
+ ERR_print_errors_fp(stderr);
486
+ // Return -1 for a nonfatal error, -2 for an error that should force the connection down.
487
+ return (er == SSL_ERROR_SSL) ? (-2) : (-1);
488
+ }
489
+ else
490
+ return 0;
491
+ }
492
+ bHandshakeCompleted = true;
493
+ // If handshake finished, FALL THROUGH and return the available plaintext.
494
+ }
495
+
496
+ if (!SSL_is_init_finished (pSSL)) {
497
+ // We can get here if a browser abandons a handshake.
498
+ // The user can see a warning dialog and abort the connection.
499
+ //cerr << "<SSL_incomp>";
500
+ return 0;
501
+ }
502
+
503
+ //cerr << "CIPH: " << SSL_get_cipher (pSSL) << endl;
504
+
505
+ int n = SSL_read (pSSL, buf, bufsize);
506
+ if (n >= 0) {
507
+ return n;
508
+ }
509
+ else {
510
+ if (SSL_get_error (pSSL, n) == SSL_ERROR_WANT_READ) {
511
+ return 0;
512
+ }
513
+ else {
514
+ return -1;
515
+ }
516
+ }
517
+
518
+ return 0;
519
+ }
520
+
521
+
522
+
523
+ /**************************
524
+ SslBox_t::CanGetCiphertext
525
+ **************************/
526
+
527
+ bool SslBox_t::CanGetCiphertext()
528
+ {
529
+ assert (pbioWrite);
530
+ return BIO_pending (pbioWrite) ? true : false;
531
+ }
532
+
533
+
534
+
535
+ /***********************
536
+ SslBox_t::GetCiphertext
537
+ ***********************/
538
+
539
+ int SslBox_t::GetCiphertext (char *buf, int bufsize)
540
+ {
541
+ assert (pbioWrite);
542
+ assert (buf && (bufsize > 0));
543
+
544
+ return BIO_read (pbioWrite, buf, bufsize);
545
+ }
546
+
547
+
548
+
549
+ /**********************
550
+ SslBox_t::PutPlaintext
551
+ **********************/
552
+
553
+ int SslBox_t::PutPlaintext (const char *buf, int bufsize)
554
+ {
555
+ // The caller will interpret the return value as the number of bytes written.
556
+ // WARNING WARNING WARNING, are there any situations in which a 0 or -1 return
557
+ // from SSL_write means we should immediately retry? The socket-machine loop
558
+ // will probably wait for a time-out cycle (perhaps a second) before re-trying.
559
+ // THIS WOULD CAUSE A PERCEPTIBLE DELAY!
560
+
561
+ /* We internally queue any outbound plaintext that can't be dispatched
562
+ * because we're in the middle of a handshake or something.
563
+ * When we get called, try to send any queued data first, and then
564
+ * send the caller's data (or queue it). We may get called with no outbound
565
+ * data, which means we try to send the outbound queue and that's all.
566
+ *
567
+ * Return >0 if we wrote any data, 0 if we didn't, and <0 for a fatal error.
568
+ * Note that if we return 0, the connection is still considered live
569
+ * and we are signalling that we have accepted the outbound data (if any).
570
+ */
571
+
572
+ OutboundQ.Push (buf, bufsize);
573
+
574
+ if (!SSL_is_init_finished (pSSL))
575
+ return 0;
576
+
577
+ bool fatal = false;
578
+ bool did_work = false;
579
+ int pending = BIO_pending(pbioWrite);
580
+
581
+ while (OutboundQ.HasPages() && pending < SSLBOX_WRITE_BUFFER_SIZE) {
582
+ const char *page;
583
+ int length;
584
+ OutboundQ.Front (&page, &length);
585
+ assert (page && (length > 0));
586
+ int n = SSL_write (pSSL, page, length);
587
+ pending = BIO_pending(pbioWrite);
588
+
589
+ if (n > 0) {
590
+ did_work = true;
591
+ OutboundQ.PopFront();
592
+ }
593
+ else {
594
+ int er = SSL_get_error (pSSL, n);
595
+ if ((er != SSL_ERROR_WANT_READ) && (er != SSL_ERROR_WANT_WRITE))
596
+ fatal = true;
597
+ break;
598
+ }
599
+ }
600
+
601
+
602
+ if (did_work)
603
+ return 1;
604
+ else if (fatal)
605
+ return -1;
606
+ else
607
+ return 0;
608
+ }
609
+
610
+ /**********************
611
+ SslBox_t::GetPeerCert
612
+ **********************/
613
+
614
+ X509 *SslBox_t::GetPeerCert()
615
+ {
616
+ X509 *cert = NULL;
617
+
618
+ if (pSSL)
619
+ cert = SSL_get_peer_certificate(pSSL);
620
+
621
+ return cert;
622
+ }
623
+
624
+ /**********************
625
+ SslBox_t::GetCipherBits
626
+ **********************/
627
+
628
+ int SslBox_t::GetCipherBits()
629
+ {
630
+ int bits = -1;
631
+ if (pSSL)
632
+ SSL_get_cipher_bits(pSSL, &bits);
633
+ return bits;
634
+ }
635
+
636
+ /**********************
637
+ SslBox_t::GetCipherName
638
+ **********************/
639
+
640
+ const char *SslBox_t::GetCipherName()
641
+ {
642
+ if (pSSL)
643
+ return SSL_get_cipher_name(pSSL);
644
+ return NULL;
645
+ }
646
+
647
+ /**********************
648
+ SslBox_t::GetCipherProtocol
649
+ **********************/
650
+
651
+ const char *SslBox_t::GetCipherProtocol()
652
+ {
653
+ if (pSSL)
654
+ return SSL_get_cipher_version(pSSL);
655
+ return NULL;
656
+ }
657
+
658
+ /**********************
659
+ SslBox_t::GetSNIHostname
660
+ **********************/
661
+
662
+ const char *SslBox_t::GetSNIHostname()
663
+ {
664
+ #ifdef TLSEXT_NAMETYPE_host_name
665
+ if (pSSL)
666
+ return SSL_get_servername (pSSL, TLSEXT_NAMETYPE_host_name);
667
+ #endif
668
+ return NULL;
669
+ }
670
+
671
+ /******************
672
+ ssl_verify_wrapper
673
+ *******************/
674
+
675
+ extern "C" int ssl_verify_wrapper(int preverify_ok UNUSED, X509_STORE_CTX *ctx)
676
+ {
677
+ uintptr_t binding;
678
+ X509 *cert;
679
+ SSL *ssl;
680
+ BUF_MEM *buf;
681
+ BIO *out;
682
+ int result;
683
+
684
+ cert = X509_STORE_CTX_get_current_cert(ctx);
685
+ ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
686
+ binding = (uintptr_t) SSL_get_ex_data(ssl, 0);
687
+
688
+ out = BIO_new(BIO_s_mem());
689
+ PEM_write_bio_X509(out, cert);
690
+ BIO_write(out, "\0", 1);
691
+ BIO_get_mem_ptr(out, &buf);
692
+
693
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject(binding));
694
+ result = (cd->VerifySslPeer(buf->data) == true ? 1 : 0);
695
+ BIO_free(out);
696
+
697
+ return result;
698
+ }
699
+
700
+ #endif // WITH_SSL
701
+