|
23 | 23 | //! and revoked markers. See "FIXME" comments littered in this file. |
24 | 24 |
|
25 | 25 | use crate::util::context::{Definition, GlobalContext, Value}; |
| 26 | +use crate::util::restricted_names::is_glob_pattern; |
26 | 27 | use crate::CargoResult; |
27 | 28 | use base64::engine::general_purpose::STANDARD; |
28 | 29 | use base64::engine::general_purpose::STANDARD_NO_PAD; |
29 | 30 | use base64::Engine as _; |
30 | 31 | use git2::cert::{Cert, SshHostKeyType}; |
31 | 32 | use git2::CertificateCheckStatus; |
32 | 33 | use hmac::Mac; |
| 34 | +use regex::Regex; |
33 | 35 | use std::collections::HashSet; |
34 | 36 | use std::fmt::{Display, Write}; |
35 | 37 | use std::path::{Path, PathBuf}; |
@@ -588,7 +590,18 @@ impl KnownHost { |
588 | 590 | } |
589 | 591 | for pattern in self.patterns.split(',') { |
590 | 592 | let pattern = pattern.to_lowercase(); |
591 | | - // FIXME: support * and ? wildcards |
| 593 | + let is_glob = is_glob_pattern(&pattern); |
| 594 | + |
| 595 | + if is_glob { |
| 596 | + let regex_pattern = |
| 597 | + regex::escape(&pattern.replace("*", ",,,,").replace("?", ";;;;")) |
| 598 | + .replace(",,,,", ".*") |
| 599 | + .replace(";;;;", "."); |
| 600 | + if let Ok(regex) = Regex::new(®ex_pattern) { |
| 601 | + match_found |= regex.is_match(&host); |
| 602 | + } |
| 603 | + } |
| 604 | + |
592 | 605 | if let Some(pattern) = pattern.strip_prefix('!') { |
593 | 606 | if pattern == host { |
594 | 607 | return false; |
@@ -696,13 +709,16 @@ mod tests { |
696 | 709 | |1|QxzZoTXIWLhUsuHAXjuDMIV3FjQ=|M6NCOIkjiWdCWqkh5+Q+/uFLGjs= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHgN3O21U4LWtP5OzjTzPnUnSDmCNDvyvlaj6Hi65JC eric@host |
697 | 710 | # Negation isn't terribly useful without globs. |
698 | 711 | neg.example.com,!neg.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOXfUnaAHTlo1Qi//rNk26OcmHikmkns1Z6WW/UuuS3K eric@host |
| 712 | + # Glob patterns |
| 713 | + *.asterisk.glob.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO6/wm8Z5aVL2cDyALY6zE7KVW0s64utWTUmbAvvSKlI eric@host |
| 714 | + test?.question.glob.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKceiey2vuK/WB/kLsiGa85xw897JzvGGaHmkAZbVHf3 eric@host |
699 | 715 | "#; |
700 | 716 |
|
701 | 717 | #[test] |
702 | 718 | fn known_hosts_parse() { |
703 | 719 | let kh_path = Path::new("/home/abc/.known_hosts"); |
704 | 720 | let khs = load_hostfile_contents(kh_path, COMMON_CONTENTS); |
705 | | - assert_eq!(khs.len(), 12); |
| 721 | + assert_eq!(khs.len(), 14); |
706 | 722 | match &khs[0].location { |
707 | 723 | KnownHostLocation::File { path, lineno } => { |
708 | 724 | assert_eq!(path, kh_path); |
@@ -740,6 +756,12 @@ mod tests { |
740 | 756 | assert!(khs[10].host_matches("hashed.example.com")); |
741 | 757 | assert!(!khs[10].host_matches("example.com")); |
742 | 758 | assert!(!khs[11].host_matches("neg.example.com")); |
| 759 | + |
| 760 | + // Glob patterns |
| 761 | + assert!(khs[12].host_matches("matches.asterisk.glob.example.com")); |
| 762 | + assert!(!khs[12].host_matches("matches.not.glob.example.com")); |
| 763 | + assert!(khs[13].host_matches("test3.question.glob.example.com")); |
| 764 | + assert!(!khs[13].host_matches("test120.question.glob.example.com")); |
743 | 765 | } |
744 | 766 |
|
745 | 767 | #[test] |
|
0 commit comments