Skip to content

Commit 70a9881

Browse files
committed
Implement pass field for connecting password-protected servers
(fixes #60)
1 parent ef32f05 commit 70a9881

File tree

6 files changed

+45
-6
lines changed

6 files changed

+45
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
- `TOPIC` messages are now handled (#58).
1414
- `RPL_AWAY` is now handled (#55). Away message is shown in user tab.
1515
- `/ignore` command added to ignore `join/quit` messages in channels.
16+
- New server config field `pass` added for connecting to password-protected
17+
servers (e.g. znc).
1618

1719
# 2017/11/12: 0.3.0
1820

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ servers:
6565
port: 6697
6666
# optional field, defaults to false:
6767
tls: true
68+
# optional field for server password:
69+
# pass: 'server_pass'
6870
hostname: yourhost
6971
realname: yourname
7072
nicks: [tiny_user]

src/cmd.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ fn connect<'a, 'b>(args: &str, poll: &'b Poll, tiny: &'a mut Tiny<'b>, src: MsgS
215215
0 =>
216216
reconnect(tiny, src),
217217
1 =>
218-
connect_(words[0], poll, tiny),
218+
connect_(words[0], None, poll, tiny),
219+
2 =>
220+
connect_(words[0], Some(words[1]), poll, tiny),
219221
_ =>
220222
// wat
221223
tiny.tui.add_client_err_msg(
@@ -255,7 +257,7 @@ fn reconnect(tiny: &mut Tiny, src: MsgSource) {
255257
}
256258
}
257259

258-
fn connect_<'a, 'b>(serv_addr: &str, poll: &'b Poll, tiny: &'a mut Tiny<'b>) {
260+
fn connect_<'a, 'b>(serv_addr: &str, pass: Option<&str>, poll: &'b Poll, tiny: &'a mut Tiny<'b>) {
259261
fn split_port(s: &str) -> Option<(&str, &str)> {
260262
s.find(':').map(|split| (&s[0..split], &s[split + 1..]))
261263
}
@@ -322,6 +324,7 @@ fn connect_<'a, 'b>(serv_addr: &str, poll: &'b Poll, tiny: &'a mut Tiny<'b>) {
322324
tls: tiny.defaults.tls,
323325
hostname: tiny.defaults.hostname.clone(),
324326
realname: tiny.defaults.realname.clone(),
327+
pass: pass.map(str::to_owned),
325328
nicks: tiny.defaults.nicks.clone(),
326329
auto_cmds: tiny.defaults.auto_cmds.clone(),
327330
join: tiny.defaults.join.clone(),

src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ pub struct Server {
2121
#[serde(default)]
2222
pub tls: bool,
2323

24+
/// Server password (optional)
25+
#[serde(default)]
26+
pub pass: Option<String>,
27+
2428
/// Hostname to be used in connection registration
2529
pub hostname: String,
2630

src/conn.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use mio::Poll;
22
use mio::Token;
3+
use std::io::Write;
34
use std::result;
45
use std::str;
56

@@ -17,6 +18,10 @@ pub struct Conn<'poll> {
1718
tls: bool,
1819
hostname: String,
1920
realname: String,
21+
22+
/// Server password
23+
pass: Option<String>,
24+
2025
nicks: Vec<String>,
2126

2227
/// Always in range of `nicks`
@@ -128,20 +133,34 @@ pub enum ConnEv {
128133
NickChange(String),
129134
}
130135

136+
fn introduce<W: Write>(stream: &mut W, pass: Option<&str>, hostname: &str, realname: &str, nick: &str) {
137+
if let Some(pass) = pass {
138+
wire::pass(stream, pass).unwrap();
139+
}
140+
wire::nick(stream, nick).unwrap();
141+
wire::user(stream, hostname, realname).unwrap();
142+
}
143+
131144
impl<'poll> Conn<'poll> {
132145
pub fn new(server: config::Server, poll: &'poll Poll) -> Result<Conn<'poll>> {
133146
let mut stream =
134147
Stream::new(poll, &server.addr, server.port, server.tls).map_err(StreamErr::from)?;
135148

136-
wire::user(&mut stream, &server.hostname, &server.realname).unwrap();
137-
wire::nick(&mut stream, &server.nicks[0]).unwrap();
149+
introduce(
150+
&mut stream,
151+
server.pass.as_ref().map(String::as_str),
152+
&server.hostname,
153+
&server.realname,
154+
&server.nicks[0],
155+
);
138156

139157
Ok(Conn {
140158
serv_addr: server.addr,
141159
serv_port: server.port,
142160
tls: server.tls,
143161
hostname: server.hostname,
144162
realname: server.realname,
163+
pass: server.pass,
145164
nicks: server.nicks,
146165
current_nick_idx: 0,
147166
auto_join: server.join,
@@ -173,8 +192,13 @@ impl<'poll> Conn<'poll> {
173192
Err(err) =>
174193
Err(StreamErr::from(err)),
175194
Ok(mut stream) => {
176-
wire::user(&mut stream, &self.hostname, &self.realname).unwrap();
177-
wire::nick(&mut stream, &self.nicks[self.current_nick_idx]).unwrap();
195+
introduce(
196+
&mut stream,
197+
self.pass.as_ref().map(String::as_str),
198+
&self.hostname,
199+
&self.realname,
200+
self.get_nick()
201+
);
178202
self.status = ConnStatus::PingPong {
179203
ticks_passed: 0,
180204
stream: stream,

src/wire.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ use std;
66

77
use logger::LogFile;
88

9+
pub fn pass<W: Write>(sink: &mut W, pass: &str) -> std::io::Result<()> {
10+
write!(sink, "PASS {}\r\n", pass)
11+
}
12+
913
pub fn user<W: Write>(sink: &mut W, hostname: &str, realname: &str) -> std::io::Result<()> {
1014
write!(sink, "USER {} 8 * :{}\r\n", hostname, realname)
1115
}

0 commit comments

Comments
 (0)