Skip to content

Commit

Permalink
Improve SAML authentication
Browse files Browse the repository at this point in the history
In the initial implementation there were still some issues that needed
to be fixed.
One main improvement is that the http server thread does not run the
tunnel thread. Instead the http server is first shut down and then
the tunnel is started as usual.
  • Loading branch information
Rainer-Keller committed Oct 9, 2024
1 parent 994fabe commit 8d7d836
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 201 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ solution requires a graphic session.
When started using `--saml-login` the program creates a web server that
accepts SAML login requests. To login using SAML you just have to open
`<your-vpn-domain>/remote/saml/start?redirect=1` and follow the login steps.
At the end of the login process the page will be redirected to
At the end of the login process the page will be redirected to
`http://127.0.0.1:8020/?id=<session-id>`

Contributing
Expand Down
12 changes: 9 additions & 3 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const struct vpn_config invalid_cfg = {
.password = {'\0'},
.password_set = 0,
.cookie = NULL,
.saml_port = 0,
.saml_session_id = {'\0'},
.otp = {'\0'},
.otp_prompt = NULL,
.otp_delay = -1,
Expand Down Expand Up @@ -418,9 +420,13 @@ int load_config(struct vpn_config *cfg, const char *filename)
if (strncmp(cfg->user_cert, "pkcs11:", 7) == 0)
cfg->use_engine = 1;
} else if (strcmp(key, "saml-login") == 0) {
free(cfg->saml_port);
cfg->saml_port = atol(val);
continue;
long port = strtol(val, NULL, 0);

if (port < 1 || port > 65535) {
log_error("Bad SAML listen port: \"%s\".\n", val);
goto err_free;
}
cfg->saml_port = (uint16_t)port;
} else if (strcmp(key, "user-key") == 0) {
free(cfg->user_key);
cfg->user_key = strdup(val);
Expand Down
5 changes: 3 additions & 2 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct x509_digest {
* We believe we are on the safe side using this value.
*/
#define MAX_DOMAIN_LENGTH 256
#define MAX_SAML_SESSION_ID_LENGTH 1024

struct vpn_config {
char gateway_host[GATEWAY_HOST_SIZE + 1];
Expand All @@ -91,8 +92,8 @@ struct vpn_config {
int password_set;
char otp[OTP_SIZE + 1];
char *cookie;
int saml_port;
char saml_session_id[1024];
int saml_port;
char saml_session_id[MAX_SAML_SESSION_ID_LENGTH];
char *otp_prompt;
unsigned int otp_delay;
int no_ftm_push;
Expand Down
46 changes: 9 additions & 37 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,42 +621,6 @@ static int try_otp_auth(struct tunnel *tunnel, const char *buffer,
}


/*
* Authenticates to gateway by sending username and password.
*
* @return 1 in case of success
* < 0 in case of error
*/
int saml_login(struct tunnel *tunnel)
{
log_debug("SAML login\n");

int ret;
ssl_connect(tunnel);

char uri[1024];
snprintf(uri, sizeof(uri), "/remote/saml/auth_id?id=%s", tunnel->config->saml_session_id);
char *response;
uint32_t response_size = 0;
ret = http_request(tunnel, "GET", uri, "", &response, &response_size);
if(ret != 1 || response_size <= 15) return ret;
if (memcmp(response, "HTTP/1.1 200 OK", 15) != 0){
log_error("SAML login failed: %s\n", response);
return ret;
}
auth_get_cookie(tunnel, response, response_size);
if (ret == ERR_HTTP_NO_COOKIE){
log_error("SAML login failed: no cookie\n");
return ret;
}

// free(response);



return ret;
}

/*
* Authenticates to gateway by sending username and password.
*
Expand Down Expand Up @@ -703,7 +667,15 @@ int auth_log_in(struct tunnel *tunnel)

tunnel->cookie[0] = '\0';

if (username[0] == '\0' && tunnel->config->password[0] == '\0') {
if (strlen(tunnel->config->saml_session_id) > 0) {
// SAML login
static const char *uri_pattern = "/remote/saml/auth_id?id=%s";
int required_size = snprintf(NULL, 0, uri_pattern, tunnel->config->saml_session_id) + 1;
char *uri = alloca(required_size);
snprintf(uri, required_size, uri_pattern, tunnel->config->saml_session_id);
log_debug("Using SAML authentication URL %s\n", uri);
ret = http_request(tunnel, "GET", uri, "", &res, &response_size);
} else if (username[0] == '\0' && tunnel->config->password[0] == '\0') {
ret = http_request(tunnel, "GET", "/remote/login",
data, &res, &response_size);
} else {
Expand Down
2 changes: 0 additions & 2 deletions src/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#define OPENFORTIVPN_HTTP_H

#include "tunnel.h"
#include "config.h"

#include <stdint.h>

Expand Down Expand Up @@ -56,7 +55,6 @@ static inline const char *err_http_str(int code)
int http_send(struct tunnel *tunnel, const char *request, ...);
int http_receive(struct tunnel *tunnel, char **response, uint32_t *response_size);

int saml_login(struct tunnel *tunnel);
int auth_log_in(struct tunnel *tunnel);
int auth_log_out(struct tunnel *tunnel);
int auth_request_vpn_allocation(struct tunnel *tunnel);
Expand Down
Loading

0 comments on commit 8d7d836

Please sign in to comment.