gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 193/256: tests: add initial gssapi test using stub


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 193/256: tests: add initial gssapi test using stub implementation
Date: Fri, 06 Oct 2017 19:44:44 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 56d949d31ad182a22bd3bad25b1a902b635d549d
Author: Isaac Boukris <address@hidden>
AuthorDate: Tue Jul 18 21:46:21 2017 +0300

    tests: add initial gssapi test using stub implementation
    
    The stub implementation is pre-loaded using LD_PRELOAD
    and emulates common gssapi uses (only builds if curl is
    initially built with gssapi support).
    
    The initial tests are currently disabled for debug builds
    as LD_PRELOAD is not used then.
    
    Ref: https://github.com/curl/curl/pull/1687
---
 configure.ac                |   7 +
 tests/FILEFORMAT            |   3 +
 tests/data/Makefile.inc     |   3 +-
 tests/data/test2056         |  87 ++++++++++
 tests/data/test2057         | 108 ++++++++++++
 tests/libtest/Makefile.am   |  15 ++
 tests/libtest/stub_gssapi.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 tests/libtest/stub_gssapi.h | 183 ++++++++++++++++++++
 tests/runtests.pl           |   9 +
 tests/server/sws.c          |  15 +-
 10 files changed, 825 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 234da1052..4d5018d91 100755
--- a/configure.ac
+++ b/configure.ac
@@ -1335,6 +1335,13 @@ else
   CPPFLAGS="$save_CPPFLAGS"
 fi
 
+build_libstubgss=no
+if test x"$want_gss" = "xyes"; then
+  build_libstubgss=yes
+fi
+
+AM_CONDITIONAL(BUILD_STUB_GSS, test "x$build_libstubgss" = "xyes")
+
 dnl -------------------------------------------------------------
 dnl parse --with-default-ssl-backend so it can be validated below
 dnl -------------------------------------------------------------
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
index 75e561ae8..fbeee2a7e 100644
--- a/tests/FILEFORMAT
+++ b/tests/FILEFORMAT
@@ -74,6 +74,8 @@ B) The request was HTTP and included digest details, which 
adds 1000 to NUM
 C) If a HTTP request is NTLM type-1, it adds 1001 to num
 D) If a HTTP request is NTLM type-3, it adds 1002 to num
 E) If a HTTP request is Basic and num is already >=1000, it adds 1 to num
+F) If a HTTP request is Negotiate, num gets incremented by one for each
+request with Negotiate authorization header on the same test case.
 
 Dynamically changing num in this way allows the test harness to be used to
 test authentication negotiation where several different requests must be sent
@@ -243,6 +245,7 @@ threaded-resolver
 unittest
 unix-sockets
 WinSSL
+ld_preload
 
 as well as each protocol that curl supports.  A protocol only needs to be
 specified if it is different from the server (useful when the server
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 942d2fe7c..c26699ab0 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -182,4 +182,5 @@ test2016 test2017 test2018 test2019 test2020 test2021 
test2022 test2023 \
 test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
 test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \
 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \
-test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055
+test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
+test2056 test2057
diff --git a/tests/data/test2056 b/tests/data/test2056
new file mode 100644
index 000000000..f00e21204
--- /dev/null
+++ b/tests/data/test2056
@@ -0,0 +1,87 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP Negotiate auth (stub krb5)
+</keywords>
+</info>
+# Server-side
+<reply>
+<!-- First request, expect 401 Negotiate -->
+<data>
+HTTP/1.1 401 Authorization Required
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate
+Content-Length: 13
+
+Not yet sir!
+</data>
+<!-- Second request, expect success in one shot -->
+<data1>
+HTTP/1.1 200 Things are fine in server land
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate RA==
+Content-Length: 15
+
+Nice auth sir!
+</data1>
+<datacheck>
+HTTP/1.1 401 Authorization Required
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate
+Content-Length: 13
+
+HTTP/1.1 200 Things are fine in server land
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate RA==
+Content-Length: 15
+
+Nice auth sir!
+</datacheck>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+HTTP Negotiate authentication (stub krb5)
+</name>
+<features>
+GSS-API
+ld_preload
+!debug
+</features>
+<setenv>
+LD_PRELOAD=%PWD/libtest/.libs/libstubgss.so
+CURL_STUB_GSS_CREDS="KRB5_Alice"
+</setenv>
+<command>
+-u: --negotiate http://%HOSTIP:%HTTPPORT/2056
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /2056 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+GET /2056 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Authorization: Negotiate 
IktSQjVfQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjE6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test2057 b/tests/data/test2057
new file mode 100644
index 000000000..562505168
--- /dev/null
+++ b/tests/data/test2057
@@ -0,0 +1,108 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP Negotiate auth (stub ntlm)
+</keywords>
+</info>
+# Server-side
+<reply>
+<!-- First request, expect 401 Negotiate -->
+<data>
+HTTP/1.1 401 Authorization Required
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate
+Content-Length: 13
+
+Not yet sir!
+</data>
+<!-- Second request, expect 401 (ntlm challenge) -->
+<data1>
+HTTP/1.1 401 Authorization Required
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate Qw==
+Content-Length: 19
+
+Still not yet sir!
+</data1>
+<!-- Third request, expect success  -->
+<data2>
+HTTP/1.1 200 Things are fine in server land
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate RA==
+Content-Length: 15
+
+Nice auth sir!
+</data2>
+<datacheck>
+HTTP/1.1 401 Authorization Required
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate
+Content-Length: 13
+
+HTTP/1.1 401 Authorization Required
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate Qw==
+Content-Length: 19
+
+HTTP/1.1 200 Things are fine in server land
+Server: Microsoft-IIS/7.0
+Content-Type: text/html; charset=iso-8859-1
+WWW-Authenticate: Negotiate RA==
+Content-Length: 15
+
+Nice auth sir!
+</datacheck>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+HTTP Negotiate authentication (stub ntlm)
+</name>
+<features>
+GSS-API
+ld_preload
+!debug
+</features>
+<setenv>
+LD_PRELOAD=%PWD/libtest/.libs/libstubgss.so
+CURL_STUB_GSS_CREDS="NTLM_Alice"
+</setenv>
+<command>
+-u: --negotiate http://%HOSTIP:%HTTPPORT/2057
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /2057 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+GET /2057 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Authorization: Negotiate 
Ik5UTE1fQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjI6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
+Accept: */*
+
+GET /2057 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Authorization: Negotiate 
Ik5UTE1fQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjM6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am
index 9128a453d..a4e85ef0c 100644
--- a/tests/libtest/Makefile.am
+++ b/tests/libtest/Makefile.am
@@ -109,6 +109,21 @@ libhostname_la_SOURCES = sethostname.c sethostname.h
 libhostname_la_LIBADD =
 libhostname_la_DEPENDENCIES =
 
+# Build a stub gssapi implementation for testing
+if BUILD_STUB_GSS
+noinst_LTLIBRARIES += libstubgss.la
+
+libstubgss_la_CPPFLAGS = $(AM_CPPFLAGS)
+libstubgss_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -rpath /nowhere
+libstubgss_la_CFLAGS = $(AM_CFLAGS) -g -Wno-unused-parameter
+
+libstubgss_la_SOURCES = stub_gssapi.c stub_gssapi.h
+
+libstubgss_la_LIBADD =
+libstubgss_la_DEPENDENCIES =
+endif
+
+
 lib1521.c: $(top_srcdir)/tests/libtest/mk-lib1521.pl 
$(top_srcdir)/include/curl/curl.h
        @PERL@ $(top_srcdir)/tests/libtest/mk-lib1521.pl < 
$(top_srcdir)/include/curl/curl.h > lib1521.c
 
diff --git a/tests/libtest/stub_gssapi.c b/tests/libtest/stub_gssapi.c
new file mode 100644
index 000000000..168becf88
--- /dev/null
+++ b/tests/libtest/stub_gssapi.c
@@ -0,0 +1,397 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2017, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Only provides the bare minimum to link with libcurl */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stub_gssapi.h"
+
+#define MAX_CREDS_LENGTH 250
+#define APPROX_TOKEN_LEN 250
+
+enum min_err_code {
+    GSS_OK = 0,
+    GSS_NO_MEMORY,
+    GSS_INVALID_ARGS,
+    GSS_INVALID_CREDS,
+    GSS_INVALID_CTX,
+    GSS_SERVER_ERR,
+    GSS_NO_MECH,
+    GSS_LAST
+};
+
+const char *min_err_table[] = {
+    "stub-gss: no error",
+    "stub-gss: no memory",
+    "stub-gss: invalid arguments",
+    "stub-gss: invalid credentials",
+    "stub-gss: invalid context",
+    "stub-gss: server returned error",
+    "stub-gss: cannot find a mechanism",
+    NULL
+};
+
+struct gss_ctx_id_t_desc_struct {
+  enum { NONE, KRB5, NTLM1, NTLM3 } sent;
+  int have_krb5;
+  int have_ntlm;
+  OM_uint32 flags;
+  char creds[MAX_CREDS_LENGTH];
+};
+
+OM_uint32 gss_init_sec_context(OM_uint32 *min,
+            gss_const_cred_id_t initiator_cred_handle,
+            gss_ctx_id_t *context_handle,
+            gss_const_name_t target_name,
+            const gss_OID mech_type,
+            OM_uint32 req_flags,
+            OM_uint32 time_req,
+            const gss_channel_bindings_t input_chan_bindings,
+            const gss_buffer_t input_token,
+            gss_OID *actual_mech_type,
+            gss_buffer_t output_token,
+            OM_uint32 *ret_flags,
+            OM_uint32 *time_rec)
+{
+  /* The token will be encoded in base64 */
+  int length = APPROX_TOKEN_LEN * 3 / 4;
+  int used = 0;
+  char *token = NULL;
+  const char *creds = NULL;
+  gss_ctx_id_t ctx = NULL;
+
+  if(!min)
+    return GSS_S_FAILURE;
+
+  *min = 0;
+
+  if(!context_handle || !target_name || !output_token) {
+    *min = GSS_INVALID_ARGS;
+    return GSS_S_FAILURE;
+  }
+
+  creds = getenv("CURL_STUB_GSS_CREDS");
+  if(!creds || strlen(creds) >= MAX_CREDS_LENGTH) {
+    *min = GSS_INVALID_CREDS;
+    return GSS_S_FAILURE;
+  }
+
+  ctx = *context_handle;
+  if(ctx && strcmp(ctx->creds, creds)) {
+    *min = GSS_INVALID_CREDS;
+    return GSS_S_FAILURE;
+  }
+
+  output_token->length = 0;
+  output_token->value = NULL;
+
+  if(input_token && input_token->length) {
+    if(!ctx) {
+      *min = GSS_INVALID_CTX;
+      return GSS_S_FAILURE;
+    }
+
+    /* Server response, either D (RA==) or C (Qw==) */
+    if(((char *) input_token->value)[0] == 'D') {
+      /* Done */
+      switch(ctx->sent) {
+      case KRB5:
+      case NTLM3:
+        if(ret_flags)
+          *ret_flags = ctx->flags;
+        if(time_rec)
+          *time_rec = GSS_C_INDEFINITE;
+        return GSS_S_COMPLETE;
+      default:
+        *min = GSS_SERVER_ERR;
+        return GSS_S_FAILURE;
+      }
+    }
+
+    if(((char *) input_token->value)[0] != 'C') {
+      /* We only support Done or Continue */
+      *min = GSS_SERVER_ERR;
+      return GSS_S_FAILURE;
+    }
+
+    /* Continue */
+    switch(ctx->sent) {
+    case KRB5:
+      /* We sent KRB5 and it failed, let's try NTLM */
+      if(ctx->have_ntlm) {
+        ctx->sent = NTLM1;
+        break;
+      }
+      else {
+        *min = GSS_SERVER_ERR;
+        return GSS_S_FAILURE;
+      }
+    case NTLM1:
+      ctx->sent = NTLM3;
+      break;
+    default:
+      *min = GSS_SERVER_ERR;
+      return GSS_S_FAILURE;
+    }
+  }
+  else {
+    if(ctx) {
+      *min = GSS_INVALID_CTX;
+      return GSS_S_FAILURE;
+    }
+
+    ctx = (gss_ctx_id_t) calloc(sizeof(*ctx), 1);
+    if(!ctx) {
+      *min = GSS_NO_MEMORY;
+      return GSS_S_FAILURE;
+    }
+
+    if(strstr(creds, "KRB5"))
+      ctx->have_krb5 = 1;
+
+    if(strstr(creds, "NTLM"))
+      ctx->have_ntlm = 1;
+
+    if(ctx->have_krb5)
+      ctx->sent = KRB5;
+    else if(ctx->have_ntlm)
+      ctx->sent = NTLM1;
+    else {
+      free(ctx);
+      *min = GSS_NO_MECH;
+      return GSS_S_FAILURE;
+    }
+
+    strcpy(ctx->creds, creds);
+    ctx->flags = req_flags;
+  }
+
+  token = malloc(length);
+  if(!token) {
+    free(ctx);
+    *min = GSS_NO_MEMORY;
+    return GSS_S_FAILURE;
+  }
+
+  /* Token format: creds:target:type:padding */
+  used = snprintf(token, length, "%s:%s:%d:", creds,
+                  (char *) target_name, ctx->sent);
+
+  if(used >= length) {
+    free(token);
+    free(ctx);
+    *min = GSS_NO_MEMORY;
+    return GSS_S_FAILURE;
+  }
+
+  /* Overwrite null terminator */
+  memset(token + used, 'A', length - used);
+
+  *context_handle = ctx;
+
+  output_token->value = token;
+  output_token->length = length;
+
+  return GSS_S_CONTINUE_NEEDED;
+}
+
+OM_uint32 gss_delete_sec_context(OM_uint32 *min,
+                                 gss_ctx_id_t *context_handle,
+                                 gss_buffer_t output_token)
+{
+  if(!min)
+    return GSS_S_FAILURE;
+
+  if(!context_handle) {
+    *min = GSS_INVALID_CTX;
+    return GSS_S_FAILURE;
+  }
+
+  free(*context_handle);
+  *context_handle = NULL;
+  *min = 0;
+
+  return GSS_S_COMPLETE;
+}
+
+OM_uint32 gss_release_buffer(OM_uint32 *min,
+                             gss_buffer_t buffer)
+{
+  if(min)
+    *min = 0;
+
+  if(buffer && buffer->length) {
+    free(buffer->value);
+    buffer->length = 0;
+  }
+
+  return GSS_S_COMPLETE;
+}
+
+OM_uint32 gss_import_name(OM_uint32 *min,
+                          const gss_buffer_t input_name_buffer,
+                          const gss_OID input_name_type,
+                          gss_name_t *output_name)
+{
+  char *name = NULL;
+
+  if(!min)
+    return GSS_S_FAILURE;
+
+  if(!input_name_buffer || !output_name) {
+    *min = GSS_INVALID_ARGS;
+    return GSS_S_FAILURE;
+  }
+
+  name = strndup(input_name_buffer->value, input_name_buffer->length);
+  if(!name) {
+    *min = GSS_NO_MEMORY;
+    return GSS_S_FAILURE;
+  }
+
+  *output_name = (gss_name_t) name;
+  *min = 0;
+
+  return GSS_S_COMPLETE;
+}
+
+OM_uint32 gss_release_name(OM_uint32 *min,
+                           gss_name_t *input_name)
+{
+  if(min)
+    *min = 0;
+
+  if(input_name)
+    free(*input_name);
+
+  return GSS_S_COMPLETE;
+}
+
+OM_uint32 gss_display_status(OM_uint32 *min,
+                             OM_uint32 status_value,
+                             int status_type,
+                             const gss_OID mech_type,
+                             OM_uint32 *message_context,
+                             gss_buffer_t status_string)
+{
+  const char maj_str[] = "Stub GSS error";
+  if(min)
+    *min = 0;
+
+  if(message_context)
+    *message_context = 0;
+
+  if(status_string) {
+    status_string->value = NULL;
+    status_string->length = 0;
+
+    if(status_value >= GSS_LAST)
+      return GSS_S_FAILURE;
+
+    switch(status_type) {
+      case GSS_C_GSS_CODE:
+        status_string->value = strdup(maj_str);
+        break;
+      case GSS_C_MECH_CODE:
+        status_string->value = strdup(min_err_table[status_value]);
+        break;
+      default:
+        return GSS_S_FAILURE;
+    }
+
+    if(status_string->value)
+      status_string->length = strlen(status_string->value);
+    else
+       return GSS_S_FAILURE;
+  }
+
+  return GSS_S_COMPLETE;
+}
+
+/* Stubs returning error */
+
+OM_uint32 gss_display_name(OM_uint32 *min,
+                           gss_const_name_t input_name,
+                           gss_buffer_t output_name_buffer,
+                           gss_OID *output_name_type)
+{
+  return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_inquire_context(OM_uint32 *min,
+                              gss_const_ctx_id_t context_handle,
+                              gss_name_t *src_name,
+                              gss_name_t *targ_name,
+                              OM_uint32 *lifetime_rec,
+                              gss_OID *mech_type,
+                              OM_uint32 *ctx_flags,
+                              int *locally_initiated,
+                              int *open_context)
+{
+  return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_wrap(OM_uint32 *min,
+                   gss_const_ctx_id_t context_handle,
+                   int conf_req_flag,
+                   gss_qop_t qop_req,
+                   const gss_buffer_t input_message_buffer,
+                   int *conf_state,
+                   gss_buffer_t output_message_buffer)
+{
+  return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_unwrap(OM_uint32 *min,
+                     gss_const_ctx_id_t context_handle,
+                     const gss_buffer_t input_message_buffer,
+                     gss_buffer_t output_message_buffer,
+                     int *conf_state,
+                     gss_qop_t *qop_state)
+{
+  return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_seal(OM_uint32 *min,
+                   gss_ctx_id_t context_handle,
+                   int conf_req_flag,
+                   int qop_req,
+                   gss_buffer_t input_message_buffer,
+                   int *conf_state,
+                   gss_buffer_t output_message_buffer)
+{
+  return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_unseal(OM_uint32 *min,
+                     gss_ctx_id_t context_handle,
+                     gss_buffer_t input_message_buffer,
+                     gss_buffer_t output_message_buffer,
+                     int *conf_state,
+                     int *qop_state)
+{
+  return GSS_S_FAILURE;
+}
+
diff --git a/tests/libtest/stub_gssapi.h b/tests/libtest/stub_gssapi.h
new file mode 100644
index 000000000..9a302f0f5
--- /dev/null
+++ b/tests/libtest/stub_gssapi.h
@@ -0,0 +1,183 @@
+#ifndef HEADER_CURL_GSSAPI_STUBS_H
+#define HEADER_CURL_GSSAPI_STUBS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2017, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Roughly based on Heimdal's gssapi.h */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define GSS_ERROR(status) (status & 0x80000000)
+
+#define GSS_S_COMPLETE 0
+#define GSS_S_FAILURE (0x80000000)
+#define GSS_S_CONTINUE_NEEDED (1ul)
+
+#define GSS_C_QOP_DEFAULT 0
+#define GSS_C_NO_OID ((gss_OID) 0)
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+
+#define GSS_C_NULL_OID GSS_C_NO_OID
+
+#define GSS_C_EMPTY_BUFFER {0, NULL}
+
+#define GSS_C_AF_INET 2
+
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE 0xfffffffful
+
+#define GSS_C_NT_HOSTBASED_SERVICE NULL
+
+typedef uint32_t OM_uint32;
+
+typedef OM_uint32 gss_qop_t;
+
+typedef struct gss_buffer_desc_struct {
+  size_t length;
+  void *value;
+} gss_buffer_desc, *gss_buffer_t;
+
+struct gss_cred_id_t_desc_struct;
+typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t;
+typedef const struct gss_cred_id_t_desc_struct *gss_const_cred_id_t;
+
+struct gss_ctx_id_t_desc_struct;
+typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t;
+typedef const struct gss_ctx_id_t_desc_struct *gss_const_ctx_id_t;
+
+struct gss_name_t_desc_struct;
+typedef struct gss_name_t_desc_struct *gss_name_t;
+typedef const struct gss_name_t_desc_struct *gss_const_name_t;
+
+typedef struct gss_OID_desc_struct {
+  OM_uint32 length;
+  void      *elements;
+} gss_OID_desc, *gss_OID;
+
+typedef struct gss_channel_bindings_struct {
+  OM_uint32 initiator_addrtype;
+  gss_buffer_desc initiator_address;
+  OM_uint32 acceptor_addrtype;
+  gss_buffer_desc acceptor_address;
+  gss_buffer_desc application_data;
+} *gss_channel_bindings_t;
+
+OM_uint32 gss_release_buffer(OM_uint32 * /*minor_status*/,
+                             gss_buffer_t /*buffer*/);
+
+OM_uint32 gss_init_sec_context(OM_uint32 * /*minor_status*/,
+            gss_const_cred_id_t /*initiator_cred_handle*/,
+            gss_ctx_id_t * /*context_handle*/,
+            gss_const_name_t /*target_name*/,
+            const gss_OID /*mech_type*/,
+            OM_uint32 /*req_flags*/,
+            OM_uint32 /*time_req*/,
+            const gss_channel_bindings_t /*input_chan_bindings*/,
+            const gss_buffer_t /*input_token*/,
+            gss_OID * /*actual_mech_type*/,
+            gss_buffer_t /*output_token*/,
+            OM_uint32 * /*ret_flags*/,
+            OM_uint32 * /*time_rec*/);
+
+OM_uint32 gss_delete_sec_context(OM_uint32 * /*minor_status*/,
+                                 gss_ctx_id_t * /*context_handle*/,
+                                 gss_buffer_t /*output_token*/);
+
+OM_uint32 gss_inquire_context(OM_uint32 * /*minor_status*/,
+                              gss_const_ctx_id_t /*context_handle*/,
+                              gss_name_t * /*src_name*/,
+                              gss_name_t * /*targ_name*/,
+                              OM_uint32 * /*lifetime_rec*/,
+                              gss_OID * /*mech_type*/,
+                              OM_uint32 * /*ctx_flags*/,
+                              int * /*locally_initiated*/,
+                              int * /*open_context*/);
+
+OM_uint32 gss_wrap(OM_uint32 * /*minor_status*/,
+                   gss_const_ctx_id_t /*context_handle*/,
+                   int /*conf_req_flag*/,
+                   gss_qop_t /*qop_req*/,
+                   const gss_buffer_t /*input_message_buffer*/,
+                   int * /*conf_state*/,
+                   gss_buffer_t /*output_message_buffer*/);
+
+OM_uint32 gss_unwrap(OM_uint32 * /*minor_status*/,
+                     gss_const_ctx_id_t /*context_handle*/,
+                     const gss_buffer_t /*input_message_buffer*/,
+                     gss_buffer_t /*output_message_buffer*/,
+                     int * /*conf_state*/,
+                     gss_qop_t * /*qop_state*/);
+
+OM_uint32 gss_seal(OM_uint32 * /*minor_status*/,
+                   gss_ctx_id_t /*context_handle*/,
+                   int /*conf_req_flag*/,
+                   int /*qop_req*/,
+                   gss_buffer_t /*input_message_buffer*/,
+                   int * /*conf_state*/,
+                   gss_buffer_t /*output_message_buffer*/);
+
+OM_uint32 gss_unseal(OM_uint32 * /*minor_status*/,
+                     gss_ctx_id_t /*context_handle*/,
+                     gss_buffer_t /*input_message_buffer*/,
+                     gss_buffer_t /*output_message_buffer*/,
+                     int * /*conf_state*/,
+                     int * /*qop_state*/);
+
+OM_uint32 gss_import_name(OM_uint32 * /*minor_status*/,
+                          const gss_buffer_t /*input_name_buffer*/,
+                          const gss_OID /*input_name_type*/,
+                          gss_name_t * /*output_name*/);
+
+OM_uint32 gss_release_name(OM_uint32 * /*minor_status*/,
+                           gss_name_t * /*input_name*/);
+
+OM_uint32 gss_display_name(OM_uint32 * /*minor_status*/,
+                           gss_const_name_t /*input_name*/,
+                           gss_buffer_t /*output_name_buffer*/,
+                           gss_OID * /*output_name_type*/);
+
+OM_uint32 gss_display_status(OM_uint32 * /*minor_status*/,
+                             OM_uint32 /*status_value*/,
+                             int /*status_type*/,
+                             const gss_OID /*mech_type*/,
+                             OM_uint32 * /*message_context*/,
+                             gss_buffer_t /*status_string*/);
+
+#endif /* HEADER_CURL_GSSAPI_STUBS_H */
+
diff --git a/tests/runtests.pl b/tests/runtests.pl
index e3cf2bff8..44fd0ae93 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -232,6 +232,7 @@ my $has_crypto;     # set if libcurl is built with 
cryptographic support
 my $has_cares;      # set if built with c-ares
 my $has_threadedres;# set if built with threaded resolver
 my $has_psl;        # set if libcurl is built with PSL support
+my $has_ldpreload;  # set if curl is built for systems supporting LD_PRELOAD
 
 # this version is decided by the particular nghttp2 library that is being used
 my $h2cver = "h2c";
@@ -2731,6 +2732,9 @@ sub checksystem {
             $curl =~ s/^(.*)(libcurl.*)/$1/g;
 
             $libcurl = $2;
+            if($curl =~ /linux|bsd|solaris|darwin/) {
+                $has_ldpreload = 1;
+            }
             if($curl =~ /win32|mingw(32|64)/) {
                 # This is a Windows MinGW build or native build, we need to use
                 # Win32-style path.
@@ -3315,6 +3319,11 @@ sub singletest {
                     next;
                 }
             }
+            elsif($1 eq "ld_preload") {
+                if($has_ldpreload && !$debug_build) {
+                    next;
+                }
+            }
             elsif($1 eq "unittest") {
                 if($debug_build) {
                     next;
diff --git a/tests/server/sws.c b/tests/server/sws.c
index 993fefcf7..821497068 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -763,7 +763,20 @@ static int ProcessRequest(struct httprequest *req)
       logmsg("Authorization header found, as required");
   }
 
-  if(!req->digest && strstr(req->reqbuf, "Authorization: Digest")) {
+  if(strstr(req->reqbuf, "Authorization: Negotiate")) {
+    /* Negotiate iterations */
+    static long prev_testno = -1;
+    static long prev_partno = -1;
+    logmsg("Negotiate: prev_testno: %d, prev_partno: %d",
+            prev_testno, prev_partno);
+    if(req->testno != prev_testno) {
+      prev_testno = req->testno;
+      prev_partno = req->partno;
+    }
+    prev_partno += 1;
+    req->partno = prev_partno;
+  }
+  else if(!req->digest && strstr(req->reqbuf, "Authorization: Digest")) {
     /* If the client is passing this Digest-header, we set the part number
        to 1000. Not only to spice up the complexity of this, but to make
        Digest stuff to work in the test suite. */

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]