-
Notifications
You must be signed in to change notification settings - Fork 360
Support SAML authentication #1241
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
Conversation
5ac02fb to
4db8b39
Compare
|
|
I've extracted only the SAML feature from your branch for easier review. The configuration options for dns and route overwrite I did not adopt. These options may go in as a separate pull request. |
|
I will wait for this to be merged first |
4db8b39 to
0e9f255
Compare
Let's see how it goes... |
412e692 to
191099c
Compare
|
How does this compare to #1217? |
At a first glance it looks like both MRs are doing about the same. |
|
Not sure if something changed since I posted this comment |
It hasn't AFAICT, but all I get from your comment is that it's an independently developed alternative, and that you have implemented some additional features. Now, @Rainer-Keller has put some effort into breaking this up into manageable pieces, so I thought that there was some reason why this alternative implementation was deemed better. Hopefully, in the near future, I'll have some time to try out one or the other implementation. I'm not convinced having two to test is better than one 😅 |
|
@exzombie Yours looks fine as well. It has the extra option to pass the auth ID from the command line. But not sure of what use that is. If would be good to get some feedback from a maintainer which of these changes has the highest chance to get in. Otherwise we'll have double effort. |
There seems to be some confusion, that MR is not mine, it is from @filippor. And are you sure there's a third one? Anyway, thanks for reviewing that MR; I haven't taken the time yet, I'm still waiting for some prerequisites to fall into place. I hope we'll be able to move the SAML story forward, and that FortiClient updates won't break EMS, but that's a different ball of hair ... |
|
Actually, this pull request looks quite clean to me. I have been hesitant to dependencies on too many external tools, and also workflows involving sudo and pipes. Although I haven't recapitulated all discussions in the previous pull requests, and honestly I didn't do a detailed code review of them, I would still vote for this one. The reason for me is, that @Rainer-Keller has dropped several unrelated changes, and thereby has made the change much more readable and understandable. There are also a couple of potentially security related fixes included in this PR, compared to the original one. |
|
@exzombie
Any details on what prerequisites that are?
There are solutions out there that seems to use a special built browser tool to extract the SAML id and forward this to openfortivpn.
Pipes have been used in the original MR from @dsl400 , but these were unrelated to SAML and I have removed them. This would be my summary of the two PRs
If we all agree it is my PR that it the preferred candidate, then I can integrate the features from #1217 here as well. |
Our internal stuff, mostly, and Fortinet dragging their feet with supporting Ubuntu 24.04. So, nothing you need to bother yourself with.
Ah, ok. Just making sure I haven't missed another attempt at what I consider a proper SAML implementation. |
|
Hello I create the pull request #1217 when I found the way to implement it using external browser. I'm not a c developer. Thanks for the code review. If it is needed I will fix the issue. I have no problems if this one will be merged. But I will wait for a word from a maintainer to complete my PR. It is working as is for my needs |
exzombie
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey! Thanks again for taking the time to push this feature forward. I'm happy with the simplicity of the approach, the "HTTP server" is really lightweight. That said, dealing with strings in C is one of the things I personally hate quite a bit, and the approach taken in the HTTP server does not convince me that the code is safe. I made some suggestions, hope you find them helpful.
src/http_server.c
Outdated
| return -1; | ||
| } | ||
|
|
||
| strncpy(id, &request[id_start], id_length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused here. id_length is determined by looking for a space. Then, you use this length with strncpy, which will not insert a null terminator at id[id_length-1]. And yet, the data in id is expected to be null terminated, because it's used with strlen in http.c. If this code works, I guess it's because id happens to be initialized to zeros. But we can't rely on that.
I suggest using memcpy and adding a null at the end explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section was taken from the original author. I've replaced it with a completely different approach.
8791318 to
a91b087
Compare
67769e6 to
400c787
Compare
|
The remaining linter warnings are indentation warnings. You can run the linters locally using |
|
Ah, ok. I now see the problem. My assumption was that the project uses tab indentation. But looks like like the linters use mixed indentation. Half tabs half spaces. |
|
Ok, now applied the patch directly with mixed indenting. |
|
Hmm. My local lint run did produce a patch that is not accepted by the one in github. |
|
You must be lacking |
There is a warning about it. I've installed it to get the patch. Version 3.6.6 comes with my distro. However, the last remaining style issue I also get locally. The messages are quite long, should I really make them a single long line? There were other style issues where long lines were not wanted. |
|
I agree multiple lines are better in this case. I'm not sure how to silence checkpatch.pl in this case. |
|
The script seems to not complain when assigning a |
|
Moving did not solve it. But turns out adding line breaks to the string makes code checker happy. |
src/http.c
Outdated
| 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"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| static const char *uri_pattern = "/remote/saml/auth_id?id=%s"; | |
| static const char uri_pattern[] = "/remote/saml/auth_id?id=%s"; |
src/http_server.c
Outdated
| // Desired string is | ||
| // https://company.com:port/remote/saml/start?redirect=1(&realm=<str>) | ||
| // with the realm being optional | ||
| static const char *uri_pattern = "https://%s:%d/remote/saml/start?redirect=1%s%s"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| static const char *uri_pattern = "https://%s:%d/remote/saml/start?redirect=1%s%s"; | |
| static const char uri_pattern[] = "https://%s:%d/remote/saml/start?redirect=1%s%s"; |
src/http_server.c
Outdated
| // after being redirected from the Fortinet Server. | ||
| static void send_status_response(int socket, const char *userMessage) | ||
| { | ||
| static const char *replyHeader = "HTTP/1.1 200 OK\r\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| static const char *replyHeader = "HTTP/1.1 200 OK\r\n" | |
| static const char replyHeader[] = "HTTP/1.1 200 OK\r\n" |
src/http_server.c
Outdated
| "Connection: close\r\n" | ||
| "\r\n"; | ||
|
|
||
| static const char *replyBody = "<!DOCTYPE html>\r\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| static const char *replyBody = "<!DOCTYPE html>\r\n" | |
| static const char replyBody[] = "<!DOCTYPE html>\r\n" |
| @@ -0,0 +1,295 @@ | |||
| #include <netinet/in.h> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a copyright statement at the top.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I would reorganise includes as follows, for consistency with the other files:
#include "config.h"
#include "http.h"
#include "log.h"
#include "tunnel.h"
#include <unistd.h>
#include <netinet/tcp.h>
#include <sys/select.h>
#include <ctype.h>
#include <string.h>That is:
- openfortivpn header files
- POSIX header files
- ISO C header files
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last thing, don't forget to include the relevant header first:
| #include "http_server.h" |
src/http_server.c
Outdated
| */ | ||
|
|
||
| #include "config.h" | ||
| #include "http.h" // for url_encode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either we document why we include headers for all of them, or for none of them. We have chosen the latter so far:
| #include "http.h" // for url_encode | |
| #include "http.h" |
|
@mrbaseman Linter issues and other details have been fixed. Would you mind having a last look at the source code? |
src/http_server.c
Outdated
| request[sizeof(request) - 1] = 0; | ||
| request[read_result] = 0; | ||
|
|
||
| static const char *request_head = "GET /?id="; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed this one:
| static const char *request_head = "GET /?id="; | |
| static const char request_head[] = "GET /?id="; |
src/http_server.c
Outdated
| } | ||
|
|
||
| // Extract the id | ||
| static const char *token_delimiter = " &\r\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this one:
| static const char *token_delimiter = " &\r\n"; | |
| static const char token_delimiter[] = " &\r\n"; |
src/tunnel.c
Outdated
| const char *eol = NULL; | ||
|
|
||
| for (int i = 0; (i < ARRAY_SIZE(HTTP_EOL)) && | ||
| for (unsigned int i = 0; (i < ARRAY_SIZE(HTTP_EOL)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
If the rationale was type correctness, size_t might be a better candidate as the type of ARRAY_SIZE() is size_t.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I'll switch to size_t then.
This change is based on work from Valentin Sasek <[email protected]>
Fix compiler warnings about comparing signed with unsigned integers.
It's fine for me. I have just run the checks once more on the latest force-pushed commits and reviewed the last changes. I'll merge it now. |
|
done. Thanks to all who have contributed, especially to @Rainer-Keller who has put a lot of effort in improving the saml code. |
|
Thanks to all, @mrbaseman when will we have a release tagged with this feature? |
|
Openfortivpn 1.23.0 has just been tagged |
This pull request is based on #1219, but has everything unrelated to SAML removed and all the review issues fixed.