itsi-server 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +950 -239
  3. data/README.md +2 -0
  4. data/exe/itsi +5 -5
  5. data/ext/itsi_acme/Cargo.toml +86 -0
  6. data/ext/itsi_acme/examples/high_level.rs +63 -0
  7. data/ext/itsi_acme/examples/high_level_warp.rs +52 -0
  8. data/ext/itsi_acme/examples/low_level.rs +87 -0
  9. data/ext/itsi_acme/examples/low_level_axum.rs +66 -0
  10. data/ext/itsi_acme/src/acceptor.rs +81 -0
  11. data/ext/itsi_acme/src/acme.rs +354 -0
  12. data/ext/itsi_acme/src/axum.rs +86 -0
  13. data/ext/itsi_acme/src/cache.rs +39 -0
  14. data/ext/itsi_acme/src/caches/boxed.rs +80 -0
  15. data/ext/itsi_acme/src/caches/composite.rs +69 -0
  16. data/ext/itsi_acme/src/caches/dir.rs +106 -0
  17. data/ext/itsi_acme/src/caches/mod.rs +11 -0
  18. data/ext/itsi_acme/src/caches/no.rs +78 -0
  19. data/ext/itsi_acme/src/caches/test.rs +136 -0
  20. data/ext/itsi_acme/src/config.rs +172 -0
  21. data/ext/itsi_acme/src/https_helper.rs +69 -0
  22. data/ext/itsi_acme/src/incoming.rs +142 -0
  23. data/ext/itsi_acme/src/jose.rs +161 -0
  24. data/ext/itsi_acme/src/lib.rs +142 -0
  25. data/ext/itsi_acme/src/resolver.rs +59 -0
  26. data/ext/itsi_acme/src/state.rs +424 -0
  27. data/ext/itsi_server/Cargo.toml +3 -3
  28. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +2 -2
  29. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +150 -19
  30. data/ext/itsi_server/src/ruby_types/itsi_server.rs +1 -0
  31. data/ext/itsi_server/src/server/binds/listener.rs +34 -29
  32. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +2 -2
  33. data/ext/itsi_server/src/server/binds/tls.rs +1 -1
  34. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +33 -28
  35. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +56 -3
  36. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +179 -0
  37. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +25 -2
  38. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +3 -3
  39. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +2 -1
  40. data/ext/itsi_server/src/server/middleware_stack/mod.rs +32 -34
  41. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +10 -4
  42. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +30 -7
  43. data/ext/itsi_server/src/server/thread_worker.rs +2 -2
  44. data/ext/itsi_server/src/services/static_file_server.rs +30 -28
  45. data/ext/itsi_tracing/src/lib.rs +39 -8
  46. data/lib/itsi/server/config/config_helpers.rb +93 -0
  47. data/lib/itsi/server/config/dsl.rb +81 -33
  48. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  49. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  50. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  51. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  52. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  53. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  54. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  55. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  56. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  57. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  58. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  59. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  60. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  61. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  62. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  63. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  64. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  65. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  66. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  67. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  68. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  69. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  70. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  71. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  72. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  73. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  74. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  75. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  76. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  77. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  78. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  79. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  80. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  81. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  82. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  83. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  84. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  85. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  86. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  87. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  88. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  89. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  90. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  91. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  92. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  93. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  94. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  95. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  96. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  97. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  98. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  99. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  100. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  101. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  102. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  103. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  104. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  105. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  106. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  107. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  108. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  109. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  110. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  111. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  112. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  113. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  114. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  115. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  116. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  117. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  118. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  119. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  120. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  121. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  122. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  123. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  124. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  125. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  126. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  127. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  128. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  129. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  130. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  131. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  132. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  133. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  134. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  135. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  136. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  137. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  138. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  139. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  140. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  141. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  142. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  143. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  144. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  145. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  146. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  147. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  148. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  149. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  150. data/lib/itsi/server/config/known_paths.rb +17 -0
  151. data/lib/itsi/server/config/middleware/_index.md +54 -0
  152. data/lib/itsi/server/config/middleware/log_requests.md +63 -0
  153. data/lib/itsi/server/config/middleware/log_requests.rb +33 -0
  154. data/lib/itsi/server/config/middleware.rb +9 -0
  155. data/lib/itsi/server/config/option.rb +9 -0
  156. data/lib/itsi/server/config/options/_index.md +36 -0
  157. data/lib/itsi/server/config/options/fiber_scheduler.md +35 -0
  158. data/lib/itsi/server/config/options/fiber_scheduler.rb +18 -0
  159. data/lib/itsi/server/config/options/threads.md +39 -0
  160. data/lib/itsi/server/config/options/threads.rb +17 -0
  161. data/lib/itsi/server/config/options/workers.md +43 -0
  162. data/lib/itsi/server/config/options/workers.rb +17 -0
  163. data/lib/itsi/server/config/typed_struct.rb +203 -0
  164. data/lib/itsi/server/config.rb +124 -30
  165. data/lib/itsi/server/signal_trap.rb +5 -1
  166. data/lib/itsi/server/typed_handlers/source_parser.rb +1 -1
  167. data/lib/itsi/server/version.rb +1 -1
  168. data/lib/itsi/server.rb +27 -6
  169. data/lib/ruby_lsp/itsi/addon.rb +64 -48
  170. metadata +141 -5
  171. data/CHANGELOG.md +0 -10
  172. data/CODE_OF_CONDUCT.md +0 -139
  173. data/LICENSE.txt +0 -21
  174. data/_index.md +0 -6
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  ---
2
2
  type: docs
3
+ sidebar:
4
+ exclude: true
3
5
  ---
4
6
 
5
7
  # ItsiServer
data/exe/itsi CHANGED
@@ -7,9 +7,10 @@ require "optparse"
7
7
 
8
8
  COMMANDS = {
9
9
  "init" => "Initialize a new Itsi.rb server configuration file",
10
+ "test" => "Test config file validity",
10
11
  "status" => "Show the status of the server",
11
- "start" => "Start the Isti server",
12
- "serve" => "Start the Isti server",
12
+ "start" => "Start the Itsi server",
13
+ "serve" => "Start the Itsi server",
13
14
  "stop" => "Stop the server",
14
15
  "reload" => "Reload the server",
15
16
  "restart" => "Restart the server",
@@ -37,7 +38,7 @@ parser = OptionParser.new do |opts|
37
38
  end
38
39
 
39
40
  opts.on("-d", "--daemonize", "Run the process as a daemon") do
40
- Process.daemon(true)
41
+ options[:daemonize] = true
41
42
  end
42
43
 
43
44
  opts.on("-t", "--threads THREADS", Integer, "Number of threads (default: 1)") do |t|
@@ -57,7 +58,7 @@ parser = OptionParser.new do |opts|
57
58
  options[:worker_memory_limit] = ml
58
59
  end
59
60
 
60
- opts.on("-f", "--fiber_scheduler [CLASS_NAME]", [String],
61
+ opts.on("-f", "--fiber_scheduler [CLASS_NAME]", String,
61
62
  "Scheduler class to use (default: nil). Provide blank or true to use Itsi::Scheduler, or a classname to use an alternative scheduler") do |scheduler_class|
62
63
  if scheduler_class.nil? || scheduler_class == "true"
63
64
  options[:scheduler_class] = "Itsi::Scheduler"
@@ -154,7 +155,6 @@ if ENV['COMP_LINE'] || ARGV.include?('--completion')
154
155
  end
155
156
 
156
157
  parser.parse!
157
-
158
158
  case (command = ARGV.shift)
159
159
  when *COMMANDS.keys
160
160
  required_arity = Itsi::Server.method(command).parameters&.select{|c| c.first == :req }&.length&.succ || 2
@@ -0,0 +1,86 @@
1
+ [package]
2
+ name = "itsi_acme"
3
+ version = "0.1.0"
4
+ authors = [
5
+ "wouterkem <wc@pico.net.nz>",
6
+ "dignifiedquire <me@dignifiedquire.com>",
7
+ "Florian Uekermann <florian@uekermann.me>",
8
+ ]
9
+ edition = "2018"
10
+ description = "Automatic TLS certificate management using rustls, specifically for itsi"
11
+ license = "Apache-2.0 OR MIT"
12
+ repository = "https://github.com/n0-computer/tokio-rustls-acme"
13
+ documentation = "https://docs.rs/tokio-rustls-acme"
14
+ keywords = ["acme", "rustls", "tls", "letsencrypt"]
15
+ categories = ["asynchronous", "cryptography", "network-programming"]
16
+
17
+ [dependencies]
18
+ futures = "0.3.21"
19
+ rcgen = "0.13"
20
+ serde_json = "1.0.81"
21
+ serde = { version = "1.0.137", features = ["derive"] }
22
+ ring = { version = "0.17.0", features = ["std"] }
23
+ base64 = "0.22"
24
+ log = "0.4.17"
25
+ webpki-roots = "0.26"
26
+ pem = "3.0"
27
+ thiserror = "2.0"
28
+ x509-parser = "0.16"
29
+ chrono = { version = "0.4.24", default-features = false, features = ["clock"] }
30
+ async-trait = "0.1.53"
31
+ rustls = { version = "0.23", default-features = false, features = ["ring"] }
32
+ time = "0.3.36" # force the transitive dependency to a more recent minimal version. The build fails with 0.3.20
33
+
34
+ tokio = { version = "1.20.1", default-features = false }
35
+ tokio-rustls = { version = "0.26", default-features = false, features = [
36
+ "tls12",
37
+ ] }
38
+ reqwest = { version = "0.12", default-features = false, features = [
39
+ "rustls-tls",
40
+ ] }
41
+
42
+ # Axum
43
+ axum-server = { version = "0.7", features = ["tokio-rustls"], optional = true }
44
+
45
+ [dependencies.proc-macro2]
46
+ # This is a transitive dependency, we specify it to make sure we have
47
+ # a recent-enough version so that -Z minimal-versions crate resolution
48
+ # works.
49
+ version = "1.0.78"
50
+
51
+ [dependencies.num-bigint]
52
+ # This is a transitive dependency, we specify it to make sure we have
53
+ # a recent-enough version so that -Z minimal-versions crate resolution
54
+ # works.
55
+ version = "0.4.4"
56
+
57
+ [dev-dependencies]
58
+ simple_logger = "5.0"
59
+ structopt = "0.3.26"
60
+ clap = { version = "4", features = ["derive"] }
61
+ axum = "0.7"
62
+ tokio = { version = "1.19.2", features = ["full"] }
63
+ tokio-stream = { version = "0.1.9", features = ["net"] }
64
+ tokio-util = { version = "0.7.3", features = ["compat"] }
65
+ warp = "0.3"
66
+
67
+ [package.metadata.docs.rs]
68
+ all-features = true
69
+ rustdoc-args = ["--cfg", "doc_auto_cfg"]
70
+
71
+ [features]
72
+ default = []
73
+ axum = ["dep:axum-server"]
74
+
75
+ [[example]]
76
+ name = "low_level_axum"
77
+ required-features = ["axum"]
78
+
79
+ [[example]]
80
+ name = "high_level_warp"
81
+
82
+ [[example]]
83
+ name = "high_level"
84
+
85
+ [[example]]
86
+ name = "low_level"
@@ -0,0 +1,63 @@
1
+ use clap::Parser;
2
+ use itsi_acme::caches::DirCache;
3
+ use itsi_acme::AcmeConfig;
4
+ use std::net::Ipv6Addr;
5
+ use std::path::PathBuf;
6
+ use tokio::io::AsyncWriteExt;
7
+ use tokio_stream::wrappers::TcpListenerStream;
8
+ use tokio_stream::StreamExt;
9
+
10
+ #[derive(Parser, Debug)]
11
+ struct Args {
12
+ /// Domains
13
+ #[clap(short, required = true)]
14
+ domains: Vec<String>,
15
+
16
+ /// Contact info
17
+ #[clap(short)]
18
+ email: Vec<String>,
19
+
20
+ /// Cache directory
21
+ #[clap(short)]
22
+ cache: Option<PathBuf>,
23
+
24
+ /// Use Let's Encrypt production environment
25
+ /// (see https://letsencrypt.org/docs/staging-environment/)
26
+ #[clap(long)]
27
+ prod: bool,
28
+
29
+ #[clap(short, long, default_value = "443")]
30
+ port: u16,
31
+ }
32
+
33
+ #[tokio::main]
34
+ async fn main() {
35
+ simple_logger::init_with_level(log::Level::Info).unwrap();
36
+ let args = Args::parse();
37
+
38
+ let tcp_listener = tokio::net::TcpListener::bind((Ipv6Addr::UNSPECIFIED, args.port))
39
+ .await
40
+ .unwrap();
41
+ let tcp_incoming = TcpListenerStream::new(tcp_listener);
42
+
43
+ let mut tls_incoming = AcmeConfig::new(args.domains)
44
+ .contact(args.email.iter().map(|e| format!("mailto:{}", e)))
45
+ .cache_option(args.cache.clone().map(DirCache::new))
46
+ .directory_lets_encrypt(args.prod)
47
+ .incoming(tcp_incoming, Vec::new());
48
+
49
+ while let Some(tls) = tls_incoming.next().await {
50
+ let mut tls = tls.unwrap();
51
+ tokio::spawn(async move {
52
+ tls.write_all(HELLO).await.unwrap();
53
+ tls.shutdown().await.unwrap();
54
+ });
55
+ }
56
+ unreachable!()
57
+ }
58
+
59
+ const HELLO: &[u8] = br#"HTTP/1.1 200 OK
60
+ Content-Length: 10
61
+ Content-Type: text/plain; charset=utf-8
62
+
63
+ Hello Tls!"#;
@@ -0,0 +1,52 @@
1
+ use clap::Parser;
2
+ use itsi_acme::caches::DirCache;
3
+ use itsi_acme::AcmeConfig;
4
+ use std::net::Ipv6Addr;
5
+ use std::path::PathBuf;
6
+ use tokio_stream::wrappers::TcpListenerStream;
7
+ use warp::Filter;
8
+
9
+ #[derive(Parser, Debug)]
10
+ struct Args {
11
+ /// Domains
12
+ #[clap(short, required = true)]
13
+ domains: Vec<String>,
14
+
15
+ /// Contact info
16
+ #[clap(short)]
17
+ email: Vec<String>,
18
+
19
+ /// Cache directory
20
+ #[clap(short)]
21
+ cache: Option<PathBuf>,
22
+
23
+ /// Use Let's Encrypt production environment
24
+ /// (see https://letsencrypt.org/docs/staging-environment/)
25
+ #[clap(long)]
26
+ prod: bool,
27
+
28
+ #[clap(short, long, default_value = "443")]
29
+ port: u16,
30
+ }
31
+
32
+ #[tokio::main]
33
+ async fn main() {
34
+ simple_logger::init_with_level(log::Level::Info).unwrap();
35
+ let args = Args::parse();
36
+
37
+ let tcp_listener = tokio::net::TcpListener::bind((Ipv6Addr::UNSPECIFIED, args.port))
38
+ .await
39
+ .unwrap();
40
+ let tcp_incoming = TcpListenerStream::new(tcp_listener);
41
+
42
+ let tls_incoming = AcmeConfig::new(args.domains)
43
+ .contact(args.email.iter().map(|e| format!("mailto:{}", e)))
44
+ .cache_option(args.cache.clone().map(DirCache::new))
45
+ .directory_lets_encrypt(args.prod)
46
+ .incoming(tcp_incoming, Vec::new());
47
+
48
+ let route = warp::any().map(|| "Hello Tls!");
49
+ warp::serve(route).run_incoming(tls_incoming).await;
50
+
51
+ unreachable!()
52
+ }
@@ -0,0 +1,87 @@
1
+ use clap::Parser;
2
+ use itsi_acme::caches::DirCache;
3
+ use itsi_acme::{AcmeAcceptor, AcmeConfig};
4
+ use rustls::ServerConfig;
5
+ use std::net::Ipv6Addr;
6
+ use std::path::PathBuf;
7
+ use std::sync::Arc;
8
+ use tokio::io::AsyncWriteExt;
9
+ use tokio_stream::StreamExt;
10
+
11
+ #[derive(Parser, Debug)]
12
+ struct Args {
13
+ /// Domains
14
+ #[clap(short, required = true)]
15
+ domains: Vec<String>,
16
+
17
+ /// Contact info
18
+ #[clap(short)]
19
+ email: Vec<String>,
20
+
21
+ /// Cache directory
22
+ #[clap(short)]
23
+ cache: Option<PathBuf>,
24
+
25
+ /// Use Let's Encrypt production environment
26
+ /// (see https://letsencrypt.org/docs/staging-environment/)
27
+ #[clap(long)]
28
+ prod: bool,
29
+
30
+ #[clap(short, long, default_value = "443")]
31
+ port: u16,
32
+ }
33
+
34
+ #[tokio::main]
35
+ async fn main() {
36
+ simple_logger::init_with_level(log::Level::Info).unwrap();
37
+ let args = Args::parse();
38
+
39
+ let mut state = AcmeConfig::new(args.domains)
40
+ .contact(args.email.iter().map(|e| format!("mailto:{}", e)))
41
+ .cache_option(args.cache.clone().map(DirCache::new))
42
+ .directory_lets_encrypt(args.prod)
43
+ .state();
44
+ let rustls_config = ServerConfig::builder()
45
+ .with_no_client_auth()
46
+ .with_cert_resolver(state.resolver());
47
+ let acceptor = state.acceptor();
48
+
49
+ tokio::spawn(async move {
50
+ loop {
51
+ match state.next().await.unwrap() {
52
+ Ok(ok) => log::info!("event: {:?}", ok),
53
+ Err(err) => log::error!("error: {:?}", err),
54
+ }
55
+ }
56
+ });
57
+
58
+ serve(acceptor, Arc::new(rustls_config), args.port).await;
59
+ }
60
+
61
+ async fn serve(acceptor: AcmeAcceptor, rustls_config: Arc<ServerConfig>, port: u16) {
62
+ let listener = tokio::net::TcpListener::bind((Ipv6Addr::UNSPECIFIED, port))
63
+ .await
64
+ .unwrap();
65
+ loop {
66
+ let tcp = listener.accept().await.unwrap().0;
67
+ let rustls_config = rustls_config.clone();
68
+ let accept_future = acceptor.accept(tcp);
69
+
70
+ tokio::spawn(async move {
71
+ match accept_future.await.unwrap() {
72
+ None => log::info!("received TLS-ALPN-01 validation request"),
73
+ Some(start_handshake) => {
74
+ let mut tls = start_handshake.into_stream(rustls_config).await.unwrap();
75
+ tls.write_all(HELLO).await.unwrap();
76
+ tls.shutdown().await.unwrap();
77
+ }
78
+ }
79
+ });
80
+ }
81
+ }
82
+
83
+ const HELLO: &[u8] = br#"HTTP/1.1 200 OK
84
+ Content-Length: 10
85
+ Content-Type: text/plain; charset=utf-8
86
+
87
+ Hello Tls!"#;
@@ -0,0 +1,66 @@
1
+ use axum::{routing::get, Router};
2
+ use clap::Parser;
3
+ use itsi_acme::caches::DirCache;
4
+ use itsi_acme::AcmeConfig;
5
+ use rustls::ServerConfig;
6
+ use std::net::{Ipv6Addr, SocketAddr};
7
+ use std::path::PathBuf;
8
+ use std::sync::Arc;
9
+ use tokio_stream::StreamExt;
10
+
11
+ #[derive(Parser, Debug)]
12
+ struct Args {
13
+ /// Domains
14
+ #[clap(short, required = true)]
15
+ domains: Vec<String>,
16
+
17
+ /// Contact info
18
+ #[clap(short)]
19
+ email: Vec<String>,
20
+
21
+ /// Cache directory
22
+ #[clap(short)]
23
+ cache: Option<PathBuf>,
24
+
25
+ /// Use Let's Encrypt production environment
26
+ /// (see https://letsencrypt.org/docs/staging-environment/)
27
+ #[clap(long)]
28
+ prod: bool,
29
+
30
+ #[clap(short, long, default_value = "443")]
31
+ port: u16,
32
+ }
33
+
34
+ #[tokio::main]
35
+ async fn main() {
36
+ simple_logger::init_with_level(log::Level::Info).unwrap();
37
+ let args = Args::parse();
38
+
39
+ let mut state = AcmeConfig::new(args.domains)
40
+ .contact(args.email.iter().map(|e| format!("mailto:{}", e)))
41
+ .cache_option(args.cache.clone().map(DirCache::new))
42
+ .directory_lets_encrypt(args.prod)
43
+ .state();
44
+ let rustls_config = ServerConfig::builder()
45
+ .with_no_client_auth()
46
+ .with_cert_resolver(state.resolver());
47
+ let acceptor = state.axum_acceptor(Arc::new(rustls_config));
48
+
49
+ tokio::spawn(async move {
50
+ loop {
51
+ match state.next().await.unwrap() {
52
+ Ok(ok) => log::info!("event: {:?}", ok),
53
+ Err(err) => log::error!("error: {:?}", err),
54
+ }
55
+ }
56
+ });
57
+
58
+ let app = Router::new().route("/", get(|| async { "Hello Tls!" }));
59
+
60
+ let addr = SocketAddr::from((Ipv6Addr::UNSPECIFIED, args.port));
61
+ axum_server::bind(addr)
62
+ .acceptor(acceptor)
63
+ .serve(app.into_make_service())
64
+ .await
65
+ .unwrap();
66
+ }
@@ -0,0 +1,81 @@
1
+ use crate::acme::ACME_TLS_ALPN_NAME;
2
+ use crate::ResolvesServerCertAcme;
3
+ use rustls::server::Acceptor;
4
+ use rustls::ServerConfig;
5
+ use std::future::Future;
6
+ use std::io;
7
+ use std::pin::Pin;
8
+ use std::sync::Arc;
9
+ use std::task::{Context, Poll};
10
+ use tokio::io::{AsyncRead, AsyncWrite};
11
+ use tokio_rustls::{Accept, LazyConfigAcceptor, StartHandshake};
12
+
13
+ #[derive(Clone)]
14
+ pub struct AcmeAcceptor {
15
+ config: Arc<ServerConfig>,
16
+ }
17
+
18
+ impl AcmeAcceptor {
19
+ pub(crate) fn new(resolver: Arc<ResolvesServerCertAcme>) -> Self {
20
+ let mut config = ServerConfig::builder()
21
+ .with_no_client_auth()
22
+ .with_cert_resolver(resolver);
23
+ config.alpn_protocols.push(ACME_TLS_ALPN_NAME.to_vec());
24
+ Self {
25
+ config: Arc::new(config),
26
+ }
27
+ }
28
+ pub fn accept<IO: AsyncRead + AsyncWrite + Unpin>(&self, io: IO) -> AcmeAccept<IO> {
29
+ AcmeAccept::new(io, self.config.clone())
30
+ }
31
+ }
32
+
33
+ pub struct AcmeAccept<IO: AsyncRead + AsyncWrite + Unpin> {
34
+ acceptor: LazyConfigAcceptor<IO>,
35
+ config: Arc<ServerConfig>,
36
+ validation_accept: Option<Accept<IO>>,
37
+ }
38
+
39
+ impl<IO: AsyncRead + AsyncWrite + Unpin> AcmeAccept<IO> {
40
+ pub(crate) fn new(io: IO, config: Arc<ServerConfig>) -> Self {
41
+ Self {
42
+ acceptor: LazyConfigAcceptor::new(Acceptor::default(), io),
43
+ config,
44
+ validation_accept: None,
45
+ }
46
+ }
47
+ }
48
+
49
+ impl<IO: AsyncRead + AsyncWrite + Unpin> Future for AcmeAccept<IO> {
50
+ type Output = io::Result<Option<StartHandshake<IO>>>;
51
+
52
+ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
53
+ loop {
54
+ if let Some(validation_accept) = &mut self.validation_accept {
55
+ return match Pin::new(validation_accept).poll(cx) {
56
+ Poll::Ready(Ok(_)) => Poll::Ready(Ok(None)),
57
+ Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
58
+ Poll::Pending => Poll::Pending,
59
+ };
60
+ }
61
+
62
+ return match Pin::new(&mut self.acceptor).poll(cx) {
63
+ Poll::Ready(Ok(handshake)) => {
64
+ let is_validation = handshake
65
+ .client_hello()
66
+ .alpn()
67
+ .into_iter()
68
+ .flatten()
69
+ .eq([ACME_TLS_ALPN_NAME]);
70
+ if is_validation {
71
+ self.validation_accept = Some(handshake.into_stream(self.config.clone()));
72
+ continue;
73
+ }
74
+ Poll::Ready(Ok(Some(handshake)))
75
+ }
76
+ Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
77
+ Poll::Pending => Poll::Pending,
78
+ };
79
+ }
80
+ }
81
+ }