예제 #1
0
SASLSession::SASLSession(const string& serviceName, ref <SASLContext> ctx,
                 ref <authenticator> auth, ref <SASLMechanism> mech)
	: m_serviceName(serviceName), m_context(ctx), m_auth(auth),
	  m_mech(mech), m_gsaslContext(0), m_gsaslSession(0)
{
	if (gsasl_init(&m_gsaslContext) != GSASL_OK)
		throw std::bad_alloc();

	gsasl_client_start(m_gsaslContext, mech->getName().c_str(), &m_gsaslSession);

	gsasl_callback_set(m_gsaslContext, gsaslCallback);
	gsasl_callback_hook_set(m_gsaslContext, this);
}
예제 #2
0
int
main (int argc, char *argv[])
{
  const char *service = argc > 1 ? argv[1] : "2000";
  volatile int run = 1;
  struct addrinfo hints, *addrs;
  int sockfd;
  int rc;
  int yes = 1;
  Gsasl *ctx;
  struct cfg cfg;

  setvbuf (stdout, NULL, _IONBF, 0);

  if (argc != 7)
    {
      printf ("Usage: %s PORT CFG-PATH STATE-PATH SP-METADATA "
	      "SP-KEY SP-CERT\n", argv[0]);
      exit (EXIT_FAILURE);
    }
  cfg.cfg_path = argv[2];
  cfg.state_path = argv[3];
  cfg.sp_metadata = argv[4];
  cfg.sp_key = argv[5];
  cfg.sp_cert = argv[6];

  rc = gsasl_init (&ctx);
  if (rc < 0)
    {
      printf ("gsasl_init (%d): %s\n", rc, gsasl_strerror (rc));
      exit (EXIT_FAILURE);
    }

  printf ("%s [gsasl header %s library %s]\n",
	  argv[0], GSASL_VERSION, gsasl_check_version (NULL));

  gsasl_callback_set (ctx, callback);
  gsasl_callback_hook_set (ctx, &cfg);

  memset (&hints, 0, sizeof (hints));
  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
  hints.ai_socktype = SOCK_STREAM;

  rc = getaddrinfo (NULL, service, &hints, &addrs);
  if (rc < 0)
    {
      printf ("getaddrinfo: %s\n", gai_strerror (rc));
      exit (EXIT_FAILURE);
    }

  sockfd = socket (addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
  if (sockfd < 0)
    {
      perror ("socket");
      exit (EXIT_FAILURE);
    }

  if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes)) < 0)
    {
      perror ("setsockopt");
      exit (EXIT_FAILURE);
    }

  rc = bind (sockfd, addrs->ai_addr, addrs->ai_addrlen);
  if (rc < 0)
    {
      perror ("bind");
      exit (EXIT_FAILURE);
    }

  freeaddrinfo (addrs);

  rc = listen (sockfd, SOMAXCONN);
  if (rc < 0)
    {
      perror ("listen");
      exit (EXIT_FAILURE);
    }

  signal (SIGPIPE, SIG_IGN);

  while (run)
    {
      struct sockaddr from;
      socklen_t fromlen = sizeof (from);
      char host[NI_MAXHOST];
      int fd;
      FILE *fh;

      fd = accept (sockfd, &from, &fromlen);
      if (fd < 0)
	{
	  perror ("accept");
	  continue;
	}

      rc = getnameinfo (&from, fromlen, host, sizeof (host),
			NULL, 0, NI_NUMERICHOST);
      if (rc == 0)
	printf ("connection from %s\n", host);
      else
	printf ("getnameinfo: %s\n", gai_strerror (rc));

      fh = fdopen (fd, "w+");
      if (!fh)
	{
	  perror ("fdopen");
	  close (fd);
	  continue;
	}

      smtp (fh, ctx);

      fclose (fh);
    }

  close (sockfd);
  gsasl_done (ctx);

  return 0;
}
예제 #3
0
파일: gsasl.c 프로젝트: baohaojun/dico
static int
sasl_auth(dico_stream_t str, char *mechanism, char *initresp,
	  Gsasl_session **psess)
{
    int rc;
    Gsasl_session *sess_ctx;
    char *input;
    char *output;
    char *inbuf;
    size_t insize;
    struct sasl_data sdata = { NULL, 0 };

    if (disabled_mechanism_p(mechanism)) 
	return RC_NOMECH;
    rc = gsasl_server_start (ctx, mechanism, &sess_ctx);
    if (rc != GSASL_OK) {
	dico_log(L_ERR, 0, _("SASL gsasl_server_start: %s"),
		 gsasl_strerror(rc));
	return rc == GSASL_UNKNOWN_MECHANISM ? RC_NOMECH : RC_FAIL;
    }

    gsasl_callback_hook_set(ctx, &sdata);
    output = NULL;
    if (initresp) {
	inbuf = xstrdup(initresp);
	insize = strlen(initresp) + 1;
    } else {
	inbuf = NULL;
	insize = 0;
    }
    input = inbuf;
    while ((rc = gsasl_step64(sess_ctx, input, &output)) == GSASL_NEEDS_MORE) {
	send_challenge(str, output);
	
	free(output);
	output = NULL;
	if (get_sasl_response(str, &input, &inbuf, &insize)) 
	    return RC_FAIL;
    }

    if (rc != GSASL_OK) {
	dico_log(L_ERR, 0, _("GSASL error: %s"), gsasl_strerror(rc));
	free(output);
	free(inbuf);
	gsasl_finish(sess_ctx);
	return RC_FAIL;
    }

    /* Some SASL mechanisms output data when GSASL_OK is returned */
    if (output[0]) 
	send_challenge(str, output);

    free(output);
    free(inbuf);
    
    if (sdata.username == NULL) {
	dico_log(L_ERR, 0, _("GSASL %s: cannot get username"), mechanism);
	gsasl_finish(sess_ctx);
	return RC_FAIL;
    }

    user_name = xstrdup(sdata.username);
    if (sdata.anon) {
	if (sasl_anon_groups) {
	    user_groups = xdico_list_create();
	    dico_list_iterate (sasl_anon_groups, _append_item, user_groups);
	}
    } else
	dico_udb_get_groups(user_db, sdata.username, &user_groups);
    check_db_visibility();

    *psess = sess_ctx;
    return RC_SUCCESS;
}
예제 #4
0
파일: simple.c 프로젝트: cktan/toolchain
void
doit (void)
{
  Gsasl *ctx = NULL;
  Gsasl_session *sctx = NULL;
  char *out = NULL;
  int i, j;
  int res;

  if (!gsasl_check_version (GSASL_VERSION))
    fail ("gsasl_check_version failure");

  success ("Header version %s library version %s\n",
	   GSASL_VERSION, gsasl_check_version (NULL));

  res = gsasl_init (&ctx);
  if (res != GSASL_OK)
    {
      fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
      return;
    }

  gsasl_callback_set (ctx, cb);

  res = gsasl_client_mechlist (ctx, &out);
  if (res != GSASL_OK)
    fail ("gsasl_client_mechlist() failed (%d):\n%s\n",
	  res, gsasl_strerror (res));
  success ("client_mechlist: %s\n", out);
  gsasl_free (out);
  out = NULL;

  res = gsasl_server_mechlist (ctx, &out);
  if (res != GSASL_OK)
    fail ("gsasl_server_mechlist() failed (%d):\n%s\n",
	  res, gsasl_strerror (res));
  success ("server_mechlist: %s\n", out);
  gsasl_free (out);
  out = NULL;

  for (i = 0; i < sizeof (sasltv) / sizeof (sasltv[0]); i++)
    {
      gsasl_callback_hook_set (ctx, &i);

      if (debug)
	printf ("Entry %d %s mechanism %s:\n",
		i, sasltv[i].clientp ? "client" : "server", sasltv[i].mech);

      if (sasltv[i].clientp)
	res = gsasl_client_support_p (ctx, sasltv[i].mech);
      else
	res = gsasl_server_support_p (ctx, sasltv[i].mech);
      if (!res)
	continue;

      if (sasltv[i].clientp)
	res = gsasl_client_start (ctx, sasltv[i].mech, &sctx);
      else
	res = gsasl_server_start (ctx, sasltv[i].mech, &sctx);
      if (res != GSASL_OK)
	{
	  fail ("SASL %s start for mechanism %s failed (%d):\n%s\n",
		sasltv[i].clientp ? "client" : "server",
		sasltv[i].mech, res, gsasl_strerror (res));
	  continue;
	}

      for (j = 0; sasltv[i].step[j]; j += 2)
	{
	  gsasl_session_hook_set (sctx, &j);

	  if (debug)
	    printf ("Input : %s\n",
		    sasltv[i].step[j] ? sasltv[i].step[j] : "");

	  res = gsasl_step64 (sctx, sasltv[i].step[j], &out);

	  if (debug)
	    printf ("Output: %s\n", out ? out : "(null)");

	  if (res != GSASL_OK && res != GSASL_NEEDS_MORE)
	    {
	      fail ("gsasl_step64 failed (%d): %s", res,
		    gsasl_strerror (res));
	      break;
	    }

	  if (strlen (out) !=
	      strlen (sasltv[i].step[j + 1] ? sasltv[i].step[j + 1] : ""))
	    {
	      printf ("Expected: %s\n", sasltv[i].step[j + 1] ?
		      sasltv[i].step[j + 1] : "");
	      fail
		("SASL entry %d mechanism %s client step %d length error\n",
		 i, sasltv[i].mech, j);
	      j = -1;
	      break;
	    }

	  if (strcmp (out, sasltv[i].step[j + 1] ?
		      sasltv[i].step[j + 1] : "") != 0)
	    {
	      printf ("Expected: %s\n", sasltv[i].step[j + 1] ?
		      sasltv[i].step[j + 1] : "");
	      fail ("SASL entry %d mechanism %s client step %d data error\n",
		    i, sasltv[i].mech, j);
	      j = -1;
	      break;
	    }

	  gsasl_free (out);
	  out = NULL;

	  if (strcmp (sasltv[i].mech, "SECURID") != 0 && res == GSASL_OK)
	    break;
	}

      if (j != (size_t) - 1 && res == GSASL_OK && sasltv[i].step[j + 2])
	fail ("SASL entry %d mechanism %s step %d code ended prematurely\n",
	      i, sasltv[i].mech, j);
      else if (j != (size_t) - 1 && res == GSASL_NEEDS_MORE)
	fail ("SASL entry %d mechanism %s step %d table ended prematurely\n",
	      i, sasltv[i].mech, j);
      else if (j != (size_t) - 1 && res != GSASL_OK)
	fail ("SASL entry %d mechanism %s step %d failed (%d):\n%s\n",
	      i, sasltv[i].mech, j, res, gsasl_strerror (res));
      else
	printf ("PASS: simple %s %s %d\n", sasltv[i].mech,
		sasltv[i].clientp ? "client" : "server", i);

      {
	size_t outlen;

	res = gsasl_encode (sctx, "foo", 3, &out, &outlen);
	if (res != GSASL_OK)
	  fail ("gsasl_encode %d: %s\n", res, gsasl_strerror (res));
	if (outlen != 3 && memcmp (out, "foo", outlen) != 0)
	  fail ("gsasl_encode memcmp: %.*s\n", (int) outlen, out);
	gsasl_free (out);
	out = NULL;

	res = gsasl_decode (sctx, "foo", 3, &out, &outlen);
	if (res != GSASL_OK)
	  fail ("gsasl_decode %d: %s\n", res, gsasl_strerror (res));
	if (outlen != 3 && memcmp (out, "foo", outlen) != 0)
	  fail ("gsasl_decode memcmp: %.*s\n", (int) outlen, out);
	gsasl_free (out);
	out = NULL;
      }

      gsasl_finish (sctx);

      if (debug)
	printf ("\n");
    }

  gsasl_done (ctx);

  /* Sanity check interfaces. */
  gsasl_finish (NULL);
  gsasl_done (NULL);
}