/*
 * wocky-scram-sha1-test.c - Test for wocky scram-sha1
 * Copyright (C) 2010 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <stdio.h>
#include <wocky/wocky-sasl-scram.h>

#include "wocky-test-helper.h"

typedef struct {
  guint32 seed;
  gchar *server;
  gchar *user;
  gchar *password;
  gchar *client_initial_response;
  gchar *server_initial_response;
  gchar *client_final_response;
  gchar *server_final_response;
} testcase;

static void
test_scram_sha1 (testcase *test)
{
  WockyAuthHandler *scram;
  GString *out, *in;
  GError *error = NULL;

  g_random_set_seed (test->seed);

  scram = WOCKY_AUTH_HANDLER (wocky_sasl_scram_new (
    test->server, test->user, test->password));

  g_assert (wocky_auth_handler_get_initial_response (scram,
      &out,
      &error));
  g_assert_no_error (error);

  g_assert_cmpstr (test->client_initial_response, ==, out->str);
  g_string_free (out, TRUE);

  /* Initial challenge, response */
  in = g_string_new (test->server_initial_response);

  (wocky_auth_handler_handle_auth_data (scram, in, &out, &error));
  g_assert_no_error (error);

  g_assert_cmpstr (test->client_final_response, ==, out->str);
  g_string_free (in, TRUE);
  g_string_free (out, TRUE);


  in = g_string_new (test->server_final_response);
  out = NULL;

  g_assert (wocky_auth_handler_handle_auth_data (scram, in, &out, &error));
  g_assert_no_error (error);

  g_assert (out == NULL);
  g_string_free (in, TRUE);

  g_assert (wocky_auth_handler_handle_success (scram, &error));
  g_assert_no_error (error);

  g_object_unref (scram);
}

/* Some static tests as generated by trail of our current implementation, which
 * has been tested against real servers. These testcases are mostly here
 * because to prevent regressions and differences of output on different
 * platforms */
static testcase tests[] = {
  { 42, "example.com", "harry", "blaat",
    /* client first */
    "n,,n=harry,r=ZtzhX7M96stcA2LzDpX1Lmr0Y7tH1JnHvK5BmRQsy5g=",
    /* server first */
    "r=ZtzhX7M96stcA2LzDpX1Lmr0Y7tH1JnHvK5BmRQsy5g=deadfish,"
    "s=snakes==,i=128",
    /* client final */
    "c=biws,r=ZtzhX7M96stcA2LzDpX1Lmr0Y7tH1JnHvK5BmRQsy5g=deadfish,"
    "p=0933cKmf/GHBIh+GYTROuRT78zM=",
    /* server final */
    "v=zW58Ag+pg9C8lGkof3wb7/jvQQQ="
  },
  { 0xcafe, "eagle.co.uk", "watson", "dna",
    /* client first */
    "n,,n=watson,r=xHkPPK3a6sJZYzbEJVq965vi70Mt9ZaFPI3PdSj8SEU=",
    /* server first */
    "r=xHkPPK3a6sJZYzbEJVq965vi70Mt9ZaFPI3PdSj8SEU=doublehelix,"
    "s=francis=,i=4096",
    /* client final */
    "c=biws,"
    "r=xHkPPK3a6sJZYzbEJVq965vi70Mt9ZaFPI3PdSj8SEU=doublehelix,"
    "p=V4VHXC1JL++UDZWRg82mcP16Hdc=",
    /* server final */
    "v=LYJrt3+nDh0XOEjKZC6DRccsnG0="
  },

  { 0, }
};

int
main (int argc,
    char **argv)
{
  int i;

  test_init (argc, argv);

  for (i = 0; tests[i].seed != 0; i++)
    {
      gchar *name = g_strdup_printf ("/scram-sha1/test-%d", i);
      g_test_add_data_func (name, tests + i,
        (void (*)(const void *)) test_scram_sha1);
      g_free (name);
    }

  return g_test_run ();
}
