Skip to content

Commit 413da8c

Browse files
committed
Merge #252: Reproduce Bitcoin Core's handling of cookie files
b16f7ef Reproduce Bitcoin Core's handling of cookie files (Casey Rodarmor) Pull request description: I was running into an confusing issue where a cookie file that worked with `bitcoin-cli` wasn't working with rust-bitcoincore-rpc. It turned out that the cookie file contained a newline, which Bitcoin Core ignored but `rust-bitcoincore-rpc` included as part of the password. This PR reproduces the behavior of Bitcoin Core, so that all cookie files that with Bitcoin Core should work with `rust-bitcoincore-rpc`. The commit message: Bitcoin Core uses a single call to std::getline to read the contents of cookie files, making it ignore newlines in the file, as well as ignore any lines after the first. This reproduces that behavior, so that all cookie files that work with Bitcoin Core should work with this library. ACKs for top commit: RCasatta: utACK b16f7ef Tree-SHA512: d3d2a0d6d526bbeb905e4dec5ebd2c03a2ca20bd8a06f7336aacc149d6c44c41dee908e702951d21806a33c84c227f37bdce524677b432963b0266950faf467c
2 parents b4f4576 + b16f7ef commit 413da8c

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

client/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ jsonrpc = "0.14.0"
2828
serde = "1"
2929
serde_json = "1"
3030
bitcoin-private = "0.1.0"
31+
32+
[dev-dependencies]
33+
tempfile = "3.3.0"

client/src/client.rs

+37-9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use std::collections::HashMap;
1212
use std::fs::File;
13+
use std::io::{BufRead, BufReader};
1314
use std::iter::FromIterator;
1415
use std::path::PathBuf;
1516
use std::{fmt, result};
@@ -201,19 +202,16 @@ pub enum Auth {
201202
impl Auth {
202203
/// Convert into the arguments that jsonrpc::Client needs.
203204
pub fn get_user_pass(self) -> Result<(Option<String>, Option<String>)> {
204-
use std::io::Read;
205205
match self {
206206
Auth::None => Ok((None, None)),
207207
Auth::UserPass(u, p) => Ok((Some(u), Some(p))),
208208
Auth::CookieFile(path) => {
209-
let mut file = File::open(path)?;
210-
let mut contents = String::new();
211-
file.read_to_string(&mut contents)?;
212-
let mut split = contents.splitn(2, ":");
213-
Ok((
214-
Some(split.next().ok_or(Error::InvalidCookieFile)?.into()),
215-
Some(split.next().ok_or(Error::InvalidCookieFile)?.into()),
216-
))
209+
let line = BufReader::new(File::open(path)?)
210+
.lines()
211+
.next()
212+
.ok_or(Error::InvalidCookieFile)??;
213+
let colon = line.find(':').ok_or(Error::InvalidCookieFile)?;
214+
Ok((Some(line[..colon].into()), Some(line[colon + 1..].into())))
217215
}
218216
}
219217
}
@@ -1429,4 +1427,34 @@ mod tests {
14291427
fn test_handle_defaults() {
14301428
test_handle_defaults_inner().unwrap();
14311429
}
1430+
1431+
#[test]
1432+
fn auth_cookie_file_ignores_newline() {
1433+
let tempdir = tempfile::tempdir().unwrap();
1434+
let path = tempdir.path().join("cookie");
1435+
std::fs::write(&path, "foo:bar\n").unwrap();
1436+
assert_eq!(
1437+
Auth::CookieFile(path).get_user_pass().unwrap(),
1438+
(Some("foo".into()), Some("bar".into())),
1439+
);
1440+
}
1441+
1442+
#[test]
1443+
fn auth_cookie_file_ignores_additional_lines() {
1444+
let tempdir = tempfile::tempdir().unwrap();
1445+
let path = tempdir.path().join("cookie");
1446+
std::fs::write(&path, "foo:bar\nbaz").unwrap();
1447+
assert_eq!(
1448+
Auth::CookieFile(path).get_user_pass().unwrap(),
1449+
(Some("foo".into()), Some("bar".into())),
1450+
);
1451+
}
1452+
1453+
#[test]
1454+
fn auth_cookie_file_fails_if_colon_isnt_present() {
1455+
let tempdir = tempfile::tempdir().unwrap();
1456+
let path = tempdir.path().join("cookie");
1457+
std::fs::write(&path, "foobar").unwrap();
1458+
assert!(matches!(Auth::CookieFile(path).get_user_pass(), Err(Error::InvalidCookieFile)));
1459+
}
14321460
}

contrib/test.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ fi
1515

1616
# Test pinned versions (these are from rust-bitcoin pinning for 1.48).
1717
if cargo --version | grep ${MSRV}; then
18+
cargo update -p tempfile --precise 3.3.0
1819
cargo update -p log --precise 0.4.18
1920
cargo update -p serde_json --precise 1.0.99
2021
cargo update -p serde --precise 1.0.156
@@ -36,4 +37,3 @@ else
3637
cargo test --verbose
3738
cargo build --verbose --examples
3839
fi
39-

0 commit comments

Comments
 (0)