Handle relative redirect and form action
authorDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 22 Feb 2010 14:43:30 +0000 (14:43 +0000)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 22 Feb 2010 14:43:30 +0000 (14:43 +0000)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
auth.c
http.c

diff --git a/auth.c b/auth.c
index 21095f5..93e175f 100644 (file)
--- a/auth.c
+++ b/auth.c
@@ -359,7 +359,7 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response,
                        form->method = (char *)xmlGetProp(xml_node, (unsigned char *)"method");
                        form->action = (char *)xmlGetProp(xml_node, (unsigned char *)"action");
                        if (!form->method || !form->action || 
-                           strcasecmp(form->method, "POST") || form->action[0] != '/') {
+                           strcasecmp(form->method, "POST") || !form->action[0]) {
                                vpninfo->progress(vpninfo, PRG_ERR,
                                                  "Cannot handle form method='%s', action='%s'\n",
                                                  form->method, form->action);
diff --git a/http.c b/http.c
index 2084e88..28cdf64 100644 (file)
--- a/http.c
+++ b/http.c
@@ -681,10 +681,28 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
                        vpninfo->redirect_url = NULL;
                        goto retry;
                } else {
-                       vpninfo->progress(vpninfo, PRG_ERR, "Relative redirect (to '%s') not supported\n",
-                               vpninfo->redirect_url);
-                       free(form_buf);
-                       return -EINVAL;
+                       char *lastslash = strrchr(vpninfo->urlpath, '/');
+                       if (!lastslash) {
+                               free(vpninfo->urlpath);
+                               vpninfo->urlpath = vpninfo->redirect_url;
+                               vpninfo->redirect_url = NULL;
+                       } else {
+                               char *oldurl = vpninfo->urlpath;
+                               *lastslash = 0;
+                               vpninfo->urlpath = NULL;
+                               if (asprintf(&vpninfo->urlpath, "%s/%s",
+                                            oldurl, vpninfo->redirect_url) == -1) {
+                                       int err = -errno;
+                                       vpninfo->progress(vpninfo, PRG_ERR,
+                                                         "Allocating new path for relative redirect failed: %s\n",
+                                                         strerror(-err));
+                                       return err;
+                               }
+                               free(oldurl);
+                               free(vpninfo->redirect_url);
+                               vpninfo->redirect_url = NULL;
+                       }
+                       goto retry;
                }
        }