Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support REDIS AUTH command #576

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

axelfauvel
Copy link

Hello,

According to this issue : #46

We have implemented AUTH command in Dynomite

Enjoy :)

@blogumi
Copy link

blogumi commented Jul 5, 2018

I support the push to get this integrated. Has this been pulled into dev branch?

@LukeCarrier
Copy link

I've rebased @axelfauvel's work on top of the style changes:

https://github.com/LukeCarrier/dynomite/tree/redis-auth

@smukil smukil self-requested a review October 12, 2018 22:18
@gsambasiva
Copy link

@axelfauvel @smukil Is there any chance to rethink about this issue.

@axelfauvel
Copy link
Author

@axelfauvel @smukil Is there any chance to rethink about this issue.

Hi @gsambasiva, i would love to see this implemented but i haven't received feedbacks :(

@timvaillancourt
Copy link

Bumping this. Would love to use this project but AUTH is a blocker

@smukil
Copy link
Contributor

smukil commented Jul 8, 2019

Reviewing this now. Will get back shortly with comments.

Copy link
Contributor

@smukil smukil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting this patch. I've done a first pass. After these changes are addressed, I'll have another pass then approve.

@@ -355,9 +355,117 @@ req_recv_next(struct context *ctx, struct conn *conn, bool alloc)
return req;
}

static struct mbuf *
get_mbuf(struct msg *msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call this get_or_create_mbuf(struct msg*) and move it to dyn_message.h/c.

}
}
auth_reply(ctx, conn, req, "-ERR invalid password\r\n");
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove this else condition and just do:

...
...
    auth_reply(ctx, conn, req, "-ERR invalid password\r\n");
  }
  auth_reply(ctx, conn, req, "-NOAUTH Authentication required\r\n");
  return true;
}
...
...

}

static void
auth_reply(struct context *ctx, struct conn *conn, struct msg *smsg, const char *usr_msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move auth_reply() and get_password() to a new file called src/proto/dyn_redis_auth.c ?

And have a top level function called authenticate_conn(struct conn*), which can be called from the Handle "AUTH requirepass\r\n" case.

msg->done = 1;

conn_event_add_out(conn);
TAILQ_INSERT_TAIL(&conn->omsg_q, smsg, c_tqe);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a race. You'd need to insert it to the omsg_q before doing an event notification.

Also, prefer to use the conn_enqueue_outq() helper which would eventually call req_client_enqueue_omsgq().

@@ -296,17 +296,53 @@ server_close(struct context *ctx, struct conn *conn)
server_failure(ctx, datastore);
}

static void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move redis_auth() to src/dyn_redis_auth.c. We shouldn't be mixing redis specifc code in generic files. (There are other instances of this in existing code that need to be cleaned up as well, but when introducing new code, let's try to keep it as clean as possible).

conn_pool_connected(conn->conn_pool, conn);

log_notice("%s connected ", print_obj(conn));
redis_auth(ctx, conn);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of calling redis_auth() directly here, we'd need to add some indirection to keep it datastore agnostic.
You'd need to add a function like datastore_auth() and call into redis_auth() if Dynomite is configured for Redis.

It's fairly simple to do, and you can follow this example of how I added a datastore agnostic rewrite_query() function:
68aad15

grep for g_rewrite_query and see all the places it's used to understand how to do this.

@@ -832,7 +869,19 @@ server_rsp_forward(struct context *ctx, struct conn *s_conn, struct msg *rsp)

c_conn = req->owner;
log_info("%s %s RECEIVED %s", print_obj(c_conn), print_obj(req), print_obj(rsp));


if (c_conn->type == CONN_SERVER) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this block of code necessary?


static void
auth_reply(struct context *ctx, struct conn *conn, struct msg *smsg, const char *usr_msg)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the top of the new file src/proto/dyn_redis_auth.c, could you add some comments about how Dynomite performs this authentication.

Eg: On Dynomite startup, the server authenticates with the datastore by itself. And on each client connection, it authenticates on the first AUTH command from the client. (add detail as you see fit)

@smukil
Copy link
Contributor

smukil commented Jul 8, 2019

@axelfauvel I've submitted a review above.

@axelfauvel
Copy link
Author

@smukil : unfortunately the person who made the code for this PR is gone and we don't have resources that can handle it anymore.

Nethertheless, I agree on letting you fix the code and merging it

@nCore
Copy link

nCore commented Oct 10, 2019

@axelfauvel @smukil I can take this and try to merge it properly to current version of dynomite. Any objections?

@axelfauvel
Copy link
Author

@nCore : Au contraire ! Go ahead :)

reimannf added a commit to reimannf/dynomite that referenced this pull request Dec 13, 2019
This commit is based on
orange-cloudfoundry@7aa41a4
from @axelfauvel in Netflix#576 and tries to
close Netflix#46.

Unfortunatelly the initial commit was already so old and the dynomite code base already evolved,
that it was easier to not jump directly on this. Especically as there were some refactorings
requested.

Redis Datastore Authentification
If Dynomite is configured to require a password via config option `requirepass` the following
behaviour will be applied:

1. On Dynomite startup, the server authenticates with the backend itself
   by calling the datastore agnostic function g_datastore_auth.
2. The corresponding Redis response will be handeled in g_is_authenticated.
   Dynomite will exit if authentification to the datatstore was not successful.
3. Each newly created client connection will require authentification.
4. Clients can authentificate itself by issue the AUTH command against dynomite.
5. Dynomite will check the password and simulate an AUTH response.
6. If AUTH was successful, the auth_required flag on the connection is reset and
   the client can process further commands through this connection.
@reimannf reimannf mentioned this pull request Dec 13, 2019
@yedongxin
Copy link

hello,any news about this merging ?

@yedongxin
Copy link

@nCore:互惠生!前进 :)

hello,any news about this merging ?

mcouillard pushed a commit to mcouillard/dynomite that referenced this pull request Jul 4, 2022
This commit is based on
orange-cloudfoundry@7aa41a4
from @axelfauvel in Netflix#576 and tries to
close Netflix#46.

Unfortunatelly the initial commit was already so old and the dynomite code base already evolved,
that it was easier to not jump directly on this. Especically as there were some refactorings
requested.

Redis Datastore Authentification
If Dynomite is configured to require a password via config option `requirepass` the following
behaviour will be applied:

1. On Dynomite startup, the server authenticates with the backend itself
   by calling the datastore agnostic function g_datastore_auth.
2. The corresponding Redis response will be handeled in g_is_authenticated.
   Dynomite will exit if authentification to the datatstore was not successful.
3. Each newly created client connection will require authentification.
4. Clients can authentificate itself by issue the AUTH command against dynomite.
5. Dynomite will check the password and simulate an AUTH response.
6. If AUTH was successful, the auth_required flag on the connection is reset and
   the client can process further commands through this connection.
WenningQiu pushed a commit to CSGOpenSource/dynomite that referenced this pull request Oct 31, 2022
…t/682daa32a80396f9522c390d9ffff277df3bd953.patch by W. Qiu)

This commit is based on
orange-cloudfoundry@7aa41a4
from @axelfauvel in Netflix#576 and tries to
close Netflix#46.

Unfortunatelly the initial commit was already so old and the dynomite code base already evolved,
that it was easier to not jump directly on this. Especically as there were some refactorings
requested.

Redis Datastore Authentification
If Dynomite is configured to require a password via config option `requirepass` the following
behaviour will be applied:

1. On Dynomite startup, the server authenticates with the backend itself
   by calling the datastore agnostic function g_datastore_auth.
2. The corresponding Redis response will be handeled in g_is_authenticated.
   Dynomite will exit if authentification to the datatstore was not successful.
3. Each newly created client connection will require authentification.
4. Clients can authentificate itself by issue the AUTH command against dynomite.
5. Dynomite will check the password and simulate an AUTH response.
6. If AUTH was successful, the auth_required flag on the connection is reset and
   the client can process further commands through this connection.
mcouillard pushed a commit to vtinfo/dynomite that referenced this pull request Nov 18, 2022
This commit is based on
orange-cloudfoundry@7aa41a4
from @axelfauvel in Netflix#576 and tries to
close Netflix#46.

Unfortunatelly the initial commit was already so old and the dynomite code base already evolved,
that it was easier to not jump directly on this. Especically as there were some refactorings
requested.

Redis Datastore Authentification
If Dynomite is configured to require a password via config option `requirepass` the following
behaviour will be applied:

1. On Dynomite startup, the server authenticates with the backend itself
   by calling the datastore agnostic function g_datastore_auth.
2. The corresponding Redis response will be handeled in g_is_authenticated.
   Dynomite will exit if authentification to the datatstore was not successful.
3. Each newly created client connection will require authentification.
4. Clients can authentificate itself by issue the AUTH command against dynomite.
5. Dynomite will check the password and simulate an AUTH response.
6. If AUTH was successful, the auth_required flag on the connection is reset and
   the client can process further commands through this connection.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants