|
5 | 5 |
|
6 | 6 | use std::collections::HashMap;
|
7 | 7 | use std::convert::Infallible;
|
| 8 | +use std::fs; |
| 9 | +use std::io::{Read, Write}; |
8 | 10 | use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
9 |
| -use std::path::PathBuf; |
| 11 | +use std::path::{Path, PathBuf}; |
10 | 12 | use std::sync::{Arc, Mutex};
|
11 | 13 | use std::time::{Duration, Instant};
|
12 | 14 |
|
@@ -76,15 +78,14 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
|
76 | 78 | legal::require_consent(&ctx.paths, args.accept_server_license_terms)?;
|
77 | 79 |
|
78 | 80 | let platform: crate::update_service::Platform = PreReqChecker::new().verify().await?;
|
79 |
| - |
80 | 81 | if !args.without_connection_token {
|
81 | 82 | // Ensure there's a defined connection token, since if multiple server versions
|
82 | 83 | // are excuted, they will need to have a single shared token.
|
83 |
| - args.connection_token = Some( |
84 |
| - args.connection_token |
85 |
| - .clone() |
86 |
| - .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()), |
87 |
| - ); |
| 84 | + let token_path = ctx.paths.root().join("serve-web-token"); |
| 85 | + let token = mint_connection_token(&token_path, args.connection_token.clone()) |
| 86 | + .map_err(CodeError::CouldNotCreateConnectionTokenFile)?; |
| 87 | + args.connection_token = Some(token); |
| 88 | + args.connection_token_file = Some(token_path.to_string_lossy().to_string()); |
88 | 89 | }
|
89 | 90 |
|
90 | 91 | let cm = ConnectionManager::new(&ctx, platform, args.clone());
|
@@ -704,8 +705,10 @@ impl ConnectionManager {
|
704 | 705 | if args.args.without_connection_token {
|
705 | 706 | cmd.arg("--without-connection-token");
|
706 | 707 | }
|
707 |
| - if let Some(ct) = &args.args.connection_token { |
708 |
| - cmd.arg("--connection-token"); |
| 708 | + // Note: intentional that we don't pass --connection-token here, we always |
| 709 | + // convert it into the file variant. |
| 710 | + if let Some(ct) = &args.args.connection_token_file { |
| 711 | + cmd.arg("--connection-token-file"); |
709 | 712 | cmd.arg(ct);
|
710 | 713 | }
|
711 | 714 |
|
@@ -779,3 +782,30 @@ struct StartArgs {
|
779 | 782 | release: Release,
|
780 | 783 | opener: BarrierOpener<Result<StartData, String>>,
|
781 | 784 | }
|
| 785 | + |
| 786 | +fn mint_connection_token(path: &Path, prefer_token: Option<String>) -> std::io::Result<String> { |
| 787 | + #[cfg(not(windows))] |
| 788 | + use std::os::unix::fs::OpenOptionsExt; |
| 789 | + |
| 790 | + let mut f = fs::OpenOptions::new(); |
| 791 | + f.create(true); |
| 792 | + f.write(true); |
| 793 | + f.read(true); |
| 794 | + #[cfg(not(windows))] |
| 795 | + f.mode(0o600); |
| 796 | + let mut f = f.open(path)?; |
| 797 | + |
| 798 | + if prefer_token.is_none() { |
| 799 | + let mut t = String::new(); |
| 800 | + f.read_to_string(&mut t)?; |
| 801 | + let t = t.trim(); |
| 802 | + if !t.is_empty() { |
| 803 | + return Ok(t.to_string()); |
| 804 | + } |
| 805 | + } |
| 806 | + |
| 807 | + f.set_len(0)?; |
| 808 | + let prefer_token = prefer_token.unwrap_or_else(|| uuid::Uuid::new_v4().to_string()); |
| 809 | + f.write_all(prefer_token.as_bytes())?; |
| 810 | + Ok(prefer_token) |
| 811 | +} |
0 commit comments