1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! `AUTH`, and the two lines a command refused for want of it is answered with.
//!
//! The passwords themselves are not here. They belong to users and users belong
//! to the `acl` module, which is where `requirepass` lives too: setting it is a
//! way of writing one rule on the user called `default`. What is left here is
//! the command, because `AUTH` is a command like any other and the rest of the
//! ACL is not.
//!
//! # Who starts out let in
//!
//! A connection carries a flag saying whether it has authenticated, and the
//! flag is decided when the connection is accepted rather than when it sends
//! its first command. A connection accepted while no password is set is let in
//! at once, because the default user is `nopass` and there is nothing to ask
//! it for, and it stays let in if a password is set later. A connection
//! accepted while a password is set has to send `AUTH` first.
//!
//! That is a real server's rule and it is worth being clear about, because it
//! is not the rule anybody would guess. `CONFIG SET requirepass` does not lock
//! out the clients that are already connected, including the one that just set
//! it, and it does lock out every client that connects after it.
//!
//! `RESET` puts the connection back to how it was accepted, and that includes
//! this: a connection that authenticated and then sent `RESET` has to
//! authenticate again on a server with a password, and does not on a server
//! without one. It also puts the connection back on the default user, whatever
//! it had authenticated as.
use ;
use acl;
use ;
use ;
use crateOut;
/// The one line a command refused for want of a password is answered with.
///
/// The whole line and not the part after the code, because it goes two places:
/// straight into the reply, and spliced into the `EXECABORT` an `EXEC` gets, and
/// the reference puts the code in both.
pub const NOAUTH: &str = "NOAUTH Authentication required.";
/// The line `HELLO` gets instead, which says what to do about it.
///
/// A client that speaks RESP3 has to send `HELLO` before it can send `AUTH`, or
/// it would be speaking RESP2 by the time it authenticated, so the reference
/// spends a sentence here pointing at the option that solves it.
pub const HELLO_NOAUTH: &str = "NOAUTH HELLO must be called with the client already authenticated, otherwise the HELLO <proto> AUTH <user> <pass> option can be used to authenticate the client and select the RESP protocol version at the same time";
/// The name a node of the cluster authenticates as rather than a user.
///
/// Matched exactly rather than case insensitively, which is the reference's
/// `strcmp` and is worth keeping: `AUTH "INTERNAL CONNECTION" x` is a failed
/// login as a user of that name and says so, rather than a failed internal
/// login.
const INTERNAL: & = b"internal connection";
/// `AUTH password` or `AUTH username password`.
pub
/// `AUTH "internal connection" <secret>`, which is one node of a cluster
/// introducing itself to another one over an ordinary client connection.
///
/// The secret is the forty characters the bus gossips until the whole cluster
/// agrees on one, so a client cannot get past this without already knowing
/// something only the nodes know, and there is nothing to know at all on a
/// server that is not a cluster node, which is why that case is refused before
/// the password is looked at.
///
/// What it opens is the slot migration protocol, which is a state machine driven
/// from the other end and not defended against being driven out of order,
/// because the only thing that ever drives it is another node running the same
/// code. That is the whole reason for the gate.