/***************************************************************************
 *
 * Copyright (c) 2000, 2001 BalaBit IT Ltd, Budapest, Hungary
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: authorization.c,v 1.5.2.2 2001/09/19 19:22:16 bazsi Exp $
 *
 ***************************************************************************/

#include <zorp/authorization.h>
#include <zorp/log.h>

gint
z_authorization_choose_method(gchar **avail_methods, gchar **supported_methods)
{
  gint i = 0;
  
  z_enter();
  while (avail_methods[i])
    {
      int j;
      
      for (j = 0; supported_methods[j]; j++)
        {
          if (strcmp(avail_methods[i], supported_methods[j]) == 0)
            {
              z_leave();
              return j;
            }
        }
      i++;
    }
  z_leave();
  return -1;
}

gchar **
z_authorization_get_methods(ZAuthorization *self, gchar *session_id, gchar *entity)
{
  ZPolicyObj *res;
  gboolean called;
  
  z_enter();
  res = z_policy_call(self, "getMethods", z_policy_var_build("(ss)", session_id, entity), &called);
  if (res &&
      z_policy_seq_check(res))
    {
      gchar **a = NULL;
      gint length = z_policy_seq_length(res);
      int i;
      
      if (length != 0)
        {
          a = g_malloc0(sizeof(gchar **) * (length + 1));
          
          for (i = 0; i < z_policy_seq_length(res); i++)
            {
              ZPolicyObj *str = z_policy_seq_getitem(res, i);
              
              if (z_policy_str_check(str))
                {
                  a[i] = g_strdup(z_policy_str_as_string(str));
                }
              else
                {
                  /* not string */
                  g_strfreev(a);
                  a = NULL;
                }
            }
        }
      z_policy_var_unref(res);
      z_leave();
      return a;
    }
  z_policy_var_unref(res);
  z_leave();
  return NULL;
}

gboolean
z_authorization_get_challenge(ZAuthorization *self, gchar *buf, gint bufsize, gchar *session_id, gchar *entity, gchar *method)
{
  ZPolicyObj *res;
  gboolean called;
  
  z_enter();
  res = z_policy_call(self, "getChallenge", z_policy_var_build("(sss)", session_id, entity, method), &called);
  if (res && (z_policy_str_check(res) || res == z_policy_none))
    {
      if (res == z_policy_none)
        buf[0] = 0;
      else
        {
          strncpy(buf, z_policy_str_as_string(res), bufsize - 1);
          buf[bufsize - 1] = 0;
        }
      z_leave();
      return TRUE;
    }
  z_policy_var_unref(res);
  z_leave();

  return FALSE;
}

gboolean
z_authorization_check_credentials(ZAuthorization *self, 
				  gchar *session_id,
                                  gchar *entity, 
                                  gchar *method, 
                                  gchar *challenge, 
                                  gchar *credentials)
{
  gboolean called;
  ZPolicyObj *res;
  gint success;
  
  z_enter();
  res = z_policy_call(self, "checkCredentials", z_policy_var_build("(sssss)", session_id, entity, method, challenge, credentials), &called);
  if (!res)
    {
      z_leave();
      return FALSE;
    }
  if (!z_policy_var_parse(res, "i", &success))
    {
      /* error parsing function result */
      z_policy_var_unref(res);
      z_leave();
      return FALSE;
    }
  z_policy_var_unref(res);
  z_leave();
  return success;
}
