Skip to content

Commit 0cfaed7

Browse files
committed
fix: Make TLS work for testing
1 parent e1ecce6 commit 0cfaed7

File tree

5 files changed

+60
-104
lines changed

5 files changed

+60
-104
lines changed

Cargo.lock

Lines changed: 1 addition & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ async-native-tls = { version = "0.5.0", default-features = false, features = [
6666
async-imap = { version = "0.9.1", default-features = false, features = [
6767
"runtime-tokio",
6868
], optional = true }
69-
irc = { version = "1.0.0", optional = true }
70-
futures = { version = "0.3.0", optional = true }
7169
mini-telnet = { version = "0.1.8", optional = true }
7270
ldap3 = { version = "0.11.3", optional = true }
7371
kerberos_crypto = { version = "0.3.6", optional = true }
@@ -138,7 +136,7 @@ ftp = ["dep:async_ftp"]
138136
smtp = ["dep:async-smtp"]
139137
pop3 = ["dep:async-pop"]
140138
imap = ["dep:async-imap"]
141-
irc = ["dep:irc", "dep:futures"]
139+
irc = []
142140
telnet = ["dep:mini-telnet"]
143141
ldap = ["dep:ldap3"]
144142
kerberos = [

src/plugins/irc/mod.rs

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use futures::StreamExt;
2-
1+
use rand::Rng;
32
use std::time::Duration;
3+
use tokio::io::{AsyncReadExt, AsyncWriteExt};
44

55
use async_trait::async_trait;
66

@@ -26,6 +26,20 @@ impl IRC {
2626
pub fn new() -> Self {
2727
IRC { tls: false }
2828
}
29+
30+
fn generate_random_username() -> String {
31+
let mut rng = rand::thread_rng();
32+
let length = rng.gen_range(5..=9);
33+
(0..length)
34+
.map(|_| {
35+
if rng.gen_bool(0.5) {
36+
rng.gen_range(b'a'..=b'z') as char
37+
} else {
38+
rng.gen_range(b'A'..=b'Z') as char
39+
}
40+
})
41+
.collect()
42+
}
2943
}
3044

3145
#[async_trait]
@@ -44,43 +58,39 @@ impl Plugin for IRC {
4458
creds: &Credentials,
4559
timeout: Duration,
4660
) -> Result<Option<Vec<Loot>>, Error> {
47-
let (address, port) =
48-
utils::parse_target(&creds.target, if self.tls { 6697 } else { 6667 })?;
61+
let address =
62+
utils::parse_target_address(&creds.target, if self.tls { 6697 } else { 6667 })?;
4963

50-
let mut config = irc::client::data::Config::default();
51-
config.nickname = Some(creds.username.to_owned());
52-
// Prevents erroring when getting a ERR_NICKNAMEINUSE response from the server because of concurrency
53-
config.alt_nicks = vec![
54-
"legba1".to_owned(),
55-
"legba2".to_owned(),
56-
"legba3".to_owned(),
57-
];
58-
config.server = Some(address.to_owned());
59-
config.port = Some(port);
60-
config.password = Some(creds.password.to_owned());
61-
config.use_tls = Some(self.tls);
64+
let mut stream = crate::utils::net::async_tcp_stream(&address, timeout, self.tls).await?;
6265

63-
let mut client = tokio::time::timeout(timeout, irc::client::Client::from_config(config))
66+
let username = IRC::generate_random_username();
67+
stream
68+
.write_all(
69+
format!(
70+
"NICK {}\r\nUSER {} 0 * :{}\r\nPASS {}\r\n",
71+
username, username, username, creds.password
72+
)
73+
.as_bytes(),
74+
)
6475
.await
65-
.map_err(|e| e.to_string())?
6676
.map_err(|e| e.to_string())?;
67-
if client.identify().is_ok() {
68-
let mut stream = client.stream().map_err(|e| e.to_string())?;
69-
while let Some(message) = stream.next().await.transpose().map_err(|e| e.to_string())? {
70-
if matches!(
71-
message.command,
72-
irc::proto::Command::Response(irc::proto::Response::RPL_WELCOME, ..)
73-
) {
74-
return Ok(Some(vec![Loot::new(
75-
"irc",
76-
&address,
77-
[("password".to_owned(), creds.password.to_owned())],
78-
)]));
79-
}
77+
78+
let mut buffer = vec![0; 1024];
79+
let mut accumulated_data = Vec::new();
80+
loop {
81+
let bytes_read = stream.read(&mut buffer).await.map_err(|e| e.to_string())?;
82+
if bytes_read == 0 {
83+
return Ok(None);
84+
}
85+
accumulated_data.extend_from_slice(&buffer[..bytes_read]);
86+
let response = String::from_utf8_lossy(&accumulated_data);
87+
if response.contains(" 001 ") && response.contains("Welcome") {
88+
return Ok(Some(vec![Loot::new(
89+
"irc",
90+
&address,
91+
[("password".to_owned(), creds.password.to_owned())],
92+
)]));
8093
}
81-
Ok(None)
82-
} else {
83-
Ok(None)
8494
}
8595
}
8696
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<connect allow="*" password="test12345">
2+
3+
<bind address="*" port="6667" type="clients">
4+
<bind address="*" port="6697" type="clients" ssl="ssl">
5+
6+
<module name="ssl_gnutls">
7+
<sslprofile name="ssl"
8+
provider="gnutls"
9+
certfile="/inspircd/conf/cert.pem"
10+
keyfile="/inspircd/conf/key.pem"
11+
dhfile="/inspircd/conf/dhparams.pem"
12+
priority="NORMAL:-MD5">

test-servers/irc.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
docker run -p 6667:6667 \
2-
-e "INSP_CONNECT_PASSWORD=test12345" \
2+
-p 6697:6697 \
3+
-v ./inspircd.config:/inspircd/conf/ \
34
inspircd/inspircd-docker

0 commit comments

Comments
 (0)