summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2020-03-12 13:25:01 +0100
committerantirez <antirez@gmail.com>2020-03-12 13:25:01 +0100
commit2091d73ef5026b7a8a93b65d2d90e59d9437413c (patch)
treef7b98e1d70452b8e4705f00657672c5a91ec46fe
parent513931dfea68ae866b91b197ca7fc0e9d845bb0a (diff)
parentbd28dbee0ed53db74b21d702c23c3254cebdbc7f (diff)
downloadredis-2091d73ef5026b7a8a93b65d2d90e59d9437413c.tar.gz
Merge branch 'unstable' of github.com:/antirez/redis into unstable
-rw-r--r--deps/linenoise/README.markdown25
-rw-r--r--deps/linenoise/example.c5
-rw-r--r--deps/linenoise/linenoise.c31
-rw-r--r--deps/linenoise/linenoise.h2
-rw-r--r--redis.conf6
-rw-r--r--src/redis-cli.c20
-rw-r--r--src/replication.c4
-rw-r--r--tests/integration/psync2.tcl21
8 files changed, 106 insertions, 8 deletions
diff --git a/deps/linenoise/README.markdown b/deps/linenoise/README.markdown
index e01642cf8..1afea2ae6 100644
--- a/deps/linenoise/README.markdown
+++ b/deps/linenoise/README.markdown
@@ -21,7 +21,7 @@ So what usually happens is either:
The result is a pollution of binaries without line editing support.
-So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporing line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to Linenoise if not.
+So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporting line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to Linenoise if not.
## Terminals, in 2010.
@@ -126,6 +126,24 @@ Linenoise has direct support for persisting the history into an history
file. The functions `linenoiseHistorySave` and `linenoiseHistoryLoad` do
just that. Both functions return -1 on error and 0 on success.
+## Mask mode
+
+Sometimes it is useful to allow the user to type passwords or other
+secrets that should not be displayed. For such situations linenoise supports
+a "mask mode" that will just replace the characters the user is typing
+with `*` characters, like in the following example:
+
+ $ ./linenoise_example
+ hello> get mykey
+ echo: 'get mykey'
+ hello> /mask
+ hello> *********
+
+You can enable and disable mask mode using the following two functions:
+
+ void linenoiseMaskModeEnable(void);
+ void linenoiseMaskModeDisable(void);
+
## Completion
Linenoise supports completion, which is the ability to complete the user
@@ -222,3 +240,8 @@ Sometimes you may want to clear the screen as a result of something the
user typed. You can do this by calling the following function:
void linenoiseClearScreen(void);
+
+## Related projects
+
+* [Linenoise NG](https://github.com/arangodb/linenoise-ng) is a fork of Linenoise that aims to add more advanced features like UTF-8 support, Windows support and other features. Uses C++ instead of C as development language.
+* [Linenoise-swift](https://github.com/andybest/linenoise-swift) is a reimplementation of Linenoise written in Swift.
diff --git a/deps/linenoise/example.c b/deps/linenoise/example.c
index 3a544d3c6..74358c323 100644
--- a/deps/linenoise/example.c
+++ b/deps/linenoise/example.c
@@ -55,6 +55,7 @@ int main(int argc, char **argv) {
*
* The typed string is returned as a malloc() allocated string by
* linenoise, so the user needs to free() it. */
+
while((line = linenoise("hello> ")) != NULL) {
/* Do something with the string. */
if (line[0] != '\0' && line[0] != '/') {
@@ -65,6 +66,10 @@ int main(int argc, char **argv) {
/* The "/historylen" command will change the history len. */
int len = atoi(line+11);
linenoiseHistorySetMaxLen(len);
+ } else if (!strncmp(line, "/mask", 5)) {
+ linenoiseMaskModeEnable();
+ } else if (!strncmp(line, "/unmask", 7)) {
+ linenoiseMaskModeDisable();
} else if (line[0] == '/') {
printf("Unreconized command: %s\n", line);
}
diff --git a/deps/linenoise/linenoise.c b/deps/linenoise/linenoise.c
index fce14a7c5..01c3b9350 100644
--- a/deps/linenoise/linenoise.c
+++ b/deps/linenoise/linenoise.c
@@ -125,6 +125,7 @@ static linenoiseHintsCallback *hintsCallback = NULL;
static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
static struct termios orig_termios; /* In order to restore at exit.*/
+static int maskmode = 0; /* Show "***" instead of input. For passwords. */
static int rawmode = 0; /* For atexit() function to check if restore is needed*/
static int mlmode = 0; /* Multi line mode. Default is single line. */
static int atexit_registered = 0; /* Register atexit just 1 time. */
@@ -197,6 +198,19 @@ FILE *lndebug_fp = NULL;
/* ======================= Low level terminal handling ====================== */
+/* Enable "mask mode". When it is enabled, instead of the input that
+ * the user is typing, the terminal will just display a corresponding
+ * number of asterisks, like "****". This is useful for passwords and other
+ * secrets that should not be displayed. */
+void linenoiseMaskModeEnable(void) {
+ maskmode = 1;
+}
+
+/* Disable mask mode. */
+void linenoiseMaskModeDisable(void) {
+ maskmode = 0;
+}
+
/* Set if to use or not the multi line mode. */
void linenoiseSetMultiLine(int ml) {
mlmode = ml;
@@ -485,6 +499,8 @@ void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
if (bold == 1 && color == -1) color = 37;
if (color != -1 || bold != 0)
snprintf(seq,64,"\033[%d;%d;49m",bold,color);
+ else
+ seq[0] = '\0';
abAppend(ab,seq,strlen(seq));
abAppend(ab,hint,hintlen);
if (color != -1 || bold != 0)
@@ -523,7 +539,11 @@ static void refreshSingleLine(struct linenoiseState *l) {
abAppend(&ab,seq,strlen(seq));
/* Write the prompt and the current buffer content */
abAppend(&ab,l->prompt,strlen(l->prompt));
- abAppend(&ab,buf,len);
+ if (maskmode == 1) {
+ while (len--) abAppend(&ab,"*",1);
+ } else {
+ abAppend(&ab,buf,len);
+ }
/* Show hits if any. */
refreshShowHints(&ab,l,plen);
/* Erase to right */
@@ -577,7 +597,11 @@ static void refreshMultiLine(struct linenoiseState *l) {
/* Write the prompt and the current buffer content */
abAppend(&ab,l->prompt,strlen(l->prompt));
- abAppend(&ab,l->buf,l->len);
+ if (maskmode == 1) {
+ for (uint i = 0; i < l->len; i++) abAppend(&ab,"*",1);
+ } else {
+ abAppend(&ab,l->buf,l->len);
+ }
/* Show hits if any. */
refreshShowHints(&ab,l,plen);
@@ -645,7 +669,8 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) {
if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) {
/* Avoid a full update of the line in the
* trivial case. */
- if (write(l->ofd,&c,1) == -1) return -1;
+ char d = (maskmode==1) ? '*' : c;
+ if (write(l->ofd,&d,1) == -1) return -1;
} else {
refreshLine(l);
}
diff --git a/deps/linenoise/linenoise.h b/deps/linenoise/linenoise.h
index ed20232c5..6dfee73bc 100644
--- a/deps/linenoise/linenoise.h
+++ b/deps/linenoise/linenoise.h
@@ -65,6 +65,8 @@ int linenoiseHistoryLoad(const char *filename);
void linenoiseClearScreen(void);
void linenoiseSetMultiLine(int ml);
void linenoisePrintKeyCodes(void);
+void linenoiseMaskModeEnable(void);
+void linenoiseMaskModeDisable(void);
#ifdef __cplusplus
}
diff --git a/redis.conf b/redis.conf
index 8609a9f57..c9d256bef 100644
--- a/redis.conf
+++ b/redis.conf
@@ -142,7 +142,8 @@ tcp-keepalive 300
# server to connected clients, masters or cluster peers. These files should be
# PEM formatted.
#
-# tls-cert-file redis.crt tls-key-file redis.key
+# tls-cert-file redis.crt
+# tls-key-file redis.key
# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
#
@@ -175,8 +176,7 @@ tcp-keepalive 300
# tls-cluster yes
# Explicitly specify TLS versions to support. Allowed values are case insensitive
-# and include "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" (OpenSSL >= 1.1.1) or
-# "default" which is currently >= TLSv1.1.
+# and include "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" (OpenSSL >= 1.1.1)
#
# tls-protocols TLSv1.2
diff --git a/src/redis-cli.c b/src/redis-cli.c
index 54898f42e..b44db9a1e 100644
--- a/src/redis-cli.c
+++ b/src/redis-cli.c
@@ -229,6 +229,7 @@ static struct config {
int hotkeys;
int stdinarg; /* get last arg from stdin. (-x option) */
char *auth;
+ int askpass;
char *user;
int output; /* output mode, see OUTPUT_* defines */
sds mb_delim;
@@ -1450,6 +1451,8 @@ static int parseOptions(int argc, char **argv) {
config.dbnum = atoi(argv[++i]);
} else if (!strcmp(argv[i], "--no-auth-warning")) {
config.no_auth_warning = 1;
+ } else if (!strcmp(argv[i], "--askpass")) {
+ config.askpass = 1;
} else if ((!strcmp(argv[i],"-a") || !strcmp(argv[i],"--pass"))
&& !lastarg)
{
@@ -1690,6 +1693,9 @@ static void usage(void) {
" (if both are used, this argument takes predecence).\n"
" --user <username> Used to send ACL style 'AUTH username pass'. Needs -a.\n"
" --pass <password> Alias of -a for consistency with the new --user option.\n"
+" --askpass Force user to input password with mask from STDIN.\n"
+" If this argument is used, '-a' and " REDIS_CLI_AUTH_ENV "\n"
+" environment variable will be ignored.\n"
" -u <uri> Server URI.\n"
" -r <repeat> Execute specified command N times.\n"
" -i <interval> When -r is used, waits <interval> seconds per command.\n"
@@ -7858,6 +7864,13 @@ static void intrinsicLatencyMode(void) {
}
}
+static sds askPassword() {
+ linenoiseMaskModeEnable();
+ sds auth = linenoise("Please input password: ");
+ linenoiseMaskModeDisable();
+ return auth;
+}
+
/*------------------------------------------------------------------------------
* Program main()
*--------------------------------------------------------------------------- */
@@ -7894,6 +7907,7 @@ int main(int argc, char **argv) {
config.hotkeys = 0;
config.stdinarg = 0;
config.auth = NULL;
+ config.askpass = 0;
config.user = NULL;
config.eval = NULL;
config.eval_ldb = 0;
@@ -7935,6 +7949,10 @@ int main(int argc, char **argv) {
parseEnv();
+ if (config.askpass) {
+ config.auth = askPassword();
+ }
+
#ifdef USE_OPENSSL
if (config.tls) {
ERR_load_crypto_strings();
@@ -8044,4 +8062,4 @@ int main(int argc, char **argv) {
} else {
return noninteractive(argc,convertToSds(argc,argv));
}
-}
+} \ No newline at end of file
diff --git a/src/replication.c b/src/replication.c
index 429e1d8a8..31e14d7fe 100644
--- a/src/replication.c
+++ b/src/replication.c
@@ -2284,6 +2284,10 @@ void syncWithMaster(connection *conn) {
if (psync_result == PSYNC_CONTINUE) {
serverLog(LL_NOTICE, "MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.");
+ if (server.supervised_mode == SUPERVISED_SYSTEMD) {
+ redisCommunicateSystemd("STATUS=MASTER <-> REPLICA sync: Partial Resynchronization accepted. Ready to accept connections.\n");
+ redisCommunicateSystemd("READY=1\n");
+ }
return;
}
diff --git a/tests/integration/psync2.tcl b/tests/integration/psync2.tcl
index d1212b640..333736ffa 100644
--- a/tests/integration/psync2.tcl
+++ b/tests/integration/psync2.tcl
@@ -114,6 +114,27 @@ start_server {} {
}
}
+ # wait for all the slaves to be in sync with the master
+ set master_ofs [status $R($master_id) master_repl_offset]
+ wait_for_condition 500 100 {
+ $master_ofs == [status $R(0) master_repl_offset] &&
+ $master_ofs == [status $R(1) master_repl_offset] &&
+ $master_ofs == [status $R(2) master_repl_offset] &&
+ $master_ofs == [status $R(3) master_repl_offset] &&
+ $master_ofs == [status $R(4) master_repl_offset]
+ } else {
+ if {$debug_msg} {
+ for {set j 0} {$j < 5} {incr j} {
+ puts "$j: sync_full: [status $R($j) sync_full]"
+ puts "$j: id1 : [status $R($j) master_replid]:[status $R($j) master_repl_offset]"
+ puts "$j: id2 : [status $R($j) master_replid2]:[status $R($j) second_repl_offset]"
+ puts "$j: backlog : firstbyte=[status $R($j) repl_backlog_first_byte_offset] len=[status $R($j) repl_backlog_histlen]"
+ puts "---"
+ }
+ }
+ fail "Slaves are not in sync with the master after too long time."
+ }
+
# Put down the old master so that it cannot generate more
# replication stream, this way in the next master switch, the time at
# which we move slaves away is not important, each will have full