commit - ef4e2f01b0bff14f003a72321ce0165a0df72fa1
commit + 365cf0f34d08316d433e730a8663283029f729b3
blob - 57b17a1dd26385f232f8f989e4fa041babfeafe3
blob + fd7f8c11aa319b18aa9f13289797a9809af40003
--- gotd/auth.c
+++ gotd/auth.c
*/
#include <sys/types.h>
+#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/uio.h>
struct imsgbuf *ibuf = &iev->ibuf;
struct gotd_imsg_auth iauth;
size_t datalen;
+ uid_t euid;
+ gid_t egid;
log_debug("authentication request received");
return got_error(GOT_ERR_PRIVSEP_LEN);
memcpy(&iauth, imsg->data, datalen);
+
+ if (imsg->fd == -1)
+ return got_error(GOT_ERR_PRIVSEP_NO_FD);
+
+ if (getpeereid(imsg->fd, &euid, &egid) == -1)
+ return got_error_from_errno("getpeerid");
+ if (iauth.euid != euid)
+ return got_error(GOT_ERR_UID);
+ if (iauth.egid != egid)
+ return got_error(GOT_ERR_GID);
+
+ log_debug("authenticating uid %d gid %d", euid, egid);
+
err = auth_check(&gotd_auth.repo->rules, gotd_auth.repo->name,
iauth.euid, iauth.egid, iauth.required_auth);
if (err) {
blob - 4e693a39b4414ee735aa6d7f2649143c79ce3a88
blob + 05f659daea632d0e305556351e4d6a5e97519fa0
--- gotd/gotd.c
+++ gotd/gotd.c
size_t datalen;
int s = -1;
struct gotd_client *client = NULL;
- uid_t euid;
- gid_t egid;
*client_id = 0;
goto done;
}
- if (getpeereid(s, &euid, &egid) == -1) {
- err = got_error_from_errno("getpeerid");
- goto done;
- }
-
client = calloc(1, sizeof(*client));
if (client == NULL) {
err = got_error_from_errno("calloc");
client->fd = s;
s = -1;
client->delta_cache_fd = -1;
- client->euid = euid;
- client->egid = egid;
+ /* The auth process will verify UID/GID for us. */
+ client->euid = iconnect.euid;
+ client->egid = iconnect.egid;
client->nref_updates = -1;
imsg_init(&client->iev.ibuf, client->fd);
struct gotd_repo *repo, char *argv0, const char *confpath,
int daemonize, int verbosity)
{
+ const struct got_error *err = NULL;
struct gotd_child_proc *proc;
struct gotd_imsg_auth iauth;
+ int fd;
memset(&iauth, 0, sizeof(iauth));
+
+ fd = dup(client->fd);
+ if (fd == -1)
+ return got_error_from_errno("dup");
proc = calloc(1, sizeof(*proc));
- if (proc == NULL)
- return got_error_from_errno("calloc");
+ if (proc == NULL) {
+ err = got_error_from_errno("calloc");
+ close(fd);
+ return err;
+ }
proc->type = PROC_AUTH;
if (strlcpy(proc->repo_name, repo->name,
iauth.required_auth = required_auth;
iauth.client_id = client->id;
if (gotd_imsg_compose_event(&proc->iev, GOTD_IMSG_AUTHENTICATE,
- PROC_GOTD, -1, &iauth, sizeof(iauth)) == -1)
+ PROC_GOTD, fd, &iauth, sizeof(iauth)) == -1) {
log_warn("imsg compose AUTHENTICATE");
+ close(fd);
+ /* Let the auth_timeout handler tidy up. */
+ }
client->auth = proc;
client->required_auth = required_auth;
case PROC_GOTD:
#ifndef PROFILE
if (pledge("stdio rpath wpath cpath proc exec "
- "sendfd recvfd fattr flock unix unveil", NULL) == -1)
+ "sendfd recvfd fattr flock unveil", NULL) == -1)
err(1, "pledge");
#endif
break;
break;
case PROC_AUTH:
#ifndef PROFILE
- if (pledge("stdio getpw", NULL) == -1)
+ if (pledge("stdio getpw recvfd unix", NULL) == -1)
err(1, "pledge");
#endif
auth_main(title, &gotd.repos, repo_path);
blob - c1090adb4ecfd2e2c122cf9a6074590b01e560dd
blob + fe0c0107c18a0d38f7565091ea1d3badb537969e
--- gotd/gotd.h
+++ gotd/gotd.h
/* Structure for GOTD_IMSG_CONNECT. */
struct gotd_imsg_connect {
uint32_t client_id;
+ uid_t euid;
+ gid_t egid;
};
/* Structure for GOTD_IMSG_AUTHENTICATE. */
blob - 96427e857a4b693de2dec2665df312e682a43f73
blob + e20369a78e149e0e24de1d635e24b7a6161e4d16
--- gotd/listen.c
+++ gotd/listen.c
int s = -1;
struct gotd_listen_client *client = NULL;
struct gotd_imsg_connect iconn;
+ uid_t euid;
+ gid_t egid;
backoff.tv_sec = 1;
backoff.tv_usec = 0;
}
if (listen_client_cnt >= GOTD_MAXCLIENTS)
+ goto err;
+
+ if (getpeereid(s, &euid, &egid) == -1) {
+ log_warn("getpeerid");
goto err;
+ }
client = calloc(1, sizeof(*client));
if (client == NULL) {
client->fd = s;
s = -1;
add_client(client);
- log_debug("%s: new client connected on fd %d", __func__, client->fd);
+ log_debug("%s: new client connected on fd %d uid %d gid %d", __func__,
+ client->fd, euid, egid);
memset(&iconn, 0, sizeof(iconn));
iconn.client_id = client->id;
+ iconn.euid = euid;
+ iconn.egid = egid;
s = dup(client->fd);
if (s == -1) {
log_warn("%s: dup", __func__);
blob - bbfa823cda9c46a471aefb0a9263d11583de85b4
blob + c951c76bc67d396a591c05f06bd362c98aa7f678
--- include/got_error.h
+++ include/got_error.h
#define GOT_ERR_REF_PROTECTED 164
#define GOT_ERR_REF_BUSY 165
#define GOT_ERR_COMMIT_BAD_AUTHOR 166
+#define GOT_ERR_UID 167
+#define GOT_ERR_GID 168
struct got_error {
int code;
blob - 3b3a634ed0c2f2b1d0dd925891e217c07e57cf5c
blob + 7e698531e6e75bd34bc4b2f0c280aded67f43de0
--- lib/error.c
+++ lib/error.c
{ GOT_ERR_REF_BUSY, "reference cannot be updated; please try again" },
{ GOT_ERR_COMMIT_BAD_AUTHOR, "commit author formatting would "
"make Git unhappy" },
+ { GOT_ERR_UID, "bad user ID" },
+ { GOT_ERR_GID, "bad group ID" },
};
static struct got_custom_error {