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 10, 2024
1 parent 994fabe commit 429a9fd
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 203 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
7 changes: 6 additions & 1 deletion doc/openfortivpn.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ A valid cookie (SVPNCOOKIE) to use in place of username and password.
Read the cookie (SVPNCOOKIE) from standard input.
.TP
\fB\-\-saml\-login[=\fI<port>\fR]
Create http server and accept requests for SAML login
Create a temporary web server to receive a local SAML redirect operation.
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
`http://127.0.0.1:8020/?id=<session-id>'. The actual URL to use for the login,
including the optional ream, is printed to the terminal when the web server it started.
.TP
\fB\-\-pinentry=\fI<name>\fR
The pinentry program to use. Allows supplying the password in a secure manner.
Expand Down
14 changes: 10 additions & 4 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 Expand Up @@ -538,7 +544,7 @@ void merge_config(struct vpn_config *dst, struct vpn_config *src)
free(dst->cookie);
dst->cookie = src->cookie;
}
if(src->saml_port != 0){
if(src->saml_port != 0) {
dst->saml_port = src->saml_port;
}
if (src->pinentry) {
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 429a9fd

Please sign in to comment.