Skip to content

Commit

Permalink
use correct refresh grant (#738)
Browse files Browse the repository at this point in the history
* use correct refresh grant

* make sure browser gets HTTP response
  • Loading branch information
ekoby authored Oct 2, 2024
1 parent 29c1d3f commit 511af4d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 12 deletions.
2 changes: 2 additions & 0 deletions inc_internal/oidc.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ struct oidc_client_s {

void *config;
void *tokens;
const char *refresh_grant;

uv_timer_t *timer;
char *jwt_token_auth;

Expand Down
72 changes: 60 additions & 12 deletions library/oidc.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#define default_cb_url cb_url("localhost",auth_cb_port,auth_url_path)
#define default_scope "openid offline_access"

#define TOKEN_EXCHANGE_GRANT "urn:ietf:params:oauth:grant-type:token-exchange"

typedef struct oidc_req oidc_req;

typedef void (*oidc_cb)(oidc_req *, int status, json_object *resp);
Expand Down Expand Up @@ -197,8 +199,21 @@ static void internal_config_cb(oidc_req *req, int status, json_object *resp) {
assert(json_object_get_type(resp) == json_type_object);
json_object_put(clt->config);
clt->config = resp;
clt->refresh_grant = "refresh_token";
// config has full URLs, so we can drop the prefix now
tlsuv_http_set_path_prefix(&clt->http, "");

struct json_object *grants = json_object_object_get(resp, "grant_types_supported");
if (grants != NULL && json_object_is_type(grants, json_type_array)) {
for (int i = 0; i < json_object_array_length(grants); i++) {
struct json_object *g = json_object_array_get_idx(grants, i);
const char *name = json_object_get_string(g);
if (strcmp(name, TOKEN_EXCHANGE_GRANT) == 0) {
clt->refresh_grant = name;
break;
}
}
}
}

if (clt->config_cb) {
Expand Down Expand Up @@ -373,6 +388,8 @@ struct ext_link_req {
};

static int set_blocking(uv_os_sock_t sock) {
int yes = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
#ifdef _WIN32
unsigned long mode = 0;
if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
Expand Down Expand Up @@ -460,22 +477,45 @@ static void ext_accept(uv_work_t *wr) {

char resp_body[] = "<script type=\"text/javascript\">window.close()</script>"
"<body onload=\"window.close()\">You may close this window</body>";
#define RESP_FMT "HTTP/1.1 200 OK\r\n"\
"Content-Type: text/html\r\n"\
"Content-Length: %zd\r\n"\
"\r\n%s"
#define RESP_FMT "HTTP/1.0 200 OK\r\n"\
"Connection: close\r\n"\
"Content-Type: text/html\r\n"\
"Content-Length: %zd\r\n"\
"\r\n%s"
string_buf_fmt(&resp_buf, RESP_FMT, strlen(resp_body), resp_body);
size_t resp_len;
char *resp = string_buf_to_string(&resp_buf, &resp_len);
const char *rp = resp;

while (resp_len > 0) {
ssize_t wc =
#if _WIN32
send(clt, rp, resp_len, 0);
#else
write(clt, rp, resp_len);
#endif
if (wc < 0) {
int err =
#if _WIN32
send(clt, resp, resp_len, 0);
WSAGetLastError();
#else
write(clt, resp, resp_len);
errno;
#endif
ZITI_LOG(WARN, "failed to write HTTP resp: %d/%s", err, strerror(err));
break;
}
resp_len -= wc;
rp += wc;
}

free(resp);
string_buf_free(&resp_buf);

#if _WIN32
shutdown(clt, SD_SEND);
#else
shutdown(clt, SHUT_WR);
#endif
close_socket(clt);
}

Expand Down Expand Up @@ -716,12 +756,20 @@ static void refresh_time_cb(uv_timer_t *t) {
tlsuv_http_req_header(req, "Authorization",
get_basic_auth_header(clt->signer_cfg->client_id));
const char *refresher = json_object_get_string(tok);
tlsuv_http_req_form(req, 4, (tlsuv_http_pair[]) {
{"grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"},
{"requested_token_type", "urn:ietf:params:oauth:token-type:refresh_token"},
{"subject_token_type", "urn:ietf:params:oauth:token-type:refresh_token"},
{"subject_token", refresher},
});
if (clt->refresh_grant && strcmp(clt->refresh_grant, TOKEN_EXCHANGE_GRANT) == 0) {
tlsuv_http_req_form(req, 4, (tlsuv_http_pair[]) {
{"grant_type", TOKEN_EXCHANGE_GRANT},
{"requested_token_type", "urn:ietf:params:oauth:token-type:refresh_token"},
{"subject_token_type", "urn:ietf:params:oauth:token-type:refresh_token"},
{"subject_token", refresher},
});
} else {
tlsuv_http_req_form(req, 3, (tlsuv_http_pair[]) {
{"client_id", clt->signer_cfg->client_id},
{"grant_type", "refresh_token"},
{"refresh_token", refresher},
});
}
}

static const char *get_endpoint_path(oidc_client_t *clt, const char *key) {
Expand Down

0 comments on commit 511af4d

Please sign in to comment.