Exemplo n.º 1
0
/** move the stream to the auth state */
void _sx_sasl_open(sx_t s, Gsasl_session *sd) {
    char *method, *authzid;
    const char *realm = NULL;
    struct sx_sasl_creds_st creds = {NULL, NULL, NULL, NULL};
    _sx_sasl_t ctx = gsasl_session_hook_get(sd);
    const char *mechname = gsasl_mechanism_name (sd);

    /* get the method */
    method = (char *) malloc(sizeof(char) * (strlen(mechname) + 6));
    sprintf(method, "SASL/%s", mechname);

    /* and the authorization identifier */
    creds.authzid = gsasl_property_fast(sd, GSASL_AUTHZID);
    creds.authnid = gsasl_property_fast(sd, GSASL_AUTHID);
    creds.realm   = gsasl_property_fast(sd, GSASL_REALM);

    if(0 && ctx && ctx->cb) { /* not supported yet */
        if((ctx->cb)(sx_sasl_cb_CHECK_AUTHZID, &creds, NULL, s, ctx->cbarg)!=sx_sasl_ret_OK) {
            _sx_debug(ZONE, "stream authzid: %s verification failed, not advancing to auth state", creds.authzid);
            free(method);
            return;
        }
    } else if (NULL != gsasl_property_fast(sd, GSASL_GSSAPI_DISPLAY_NAME)) {
        creds.authzid = strdup(gsasl_property_fast(sd, GSASL_GSSAPI_DISPLAY_NAME));
        authzid = NULL;
    } else {
        /* override unchecked arbitrary authzid */
        if(creds.realm && creds.realm[0] != '\0') {
            realm = creds.realm;
        } else {
            realm = s->req_to;
        }
        authzid = (char *) malloc(sizeof(char) * (strlen(creds.authnid) + strlen(realm) + 2));
        sprintf(authzid, "%s@%s", creds.authnid, realm);
        creds.authzid = authzid;
    }

    /* proceed stream to authenticated state */
    sx_auth(s, method, creds.authzid);

    free(method);
    if(authzid) free(authzid);
}
Exemplo n.º 2
0
static int
callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
{
  int rc = GSASL_NO_CALLBACK;
  struct cfg *cfg = gsasl_callback_hook_get (ctx);

  switch (prop)
    {
    case GSASL_SAML20_REDIRECT_URL:
      {
	FILE *fh;
	char *reqid, *redirect_url, *tmp;
	size_t n = 0;
	const char *idp =
	  gsasl_property_get (sctx, GSASL_SAML20_IDP_IDENTIFIER);

	/* User did not provide a SAML IdP identifier. */
	if (!idp)
	  return GSASL_AUTHENTICATION_ERROR;

	/* Sanitize input. */
	if (strcmp (idp, ".") == 0 || strcmp (idp, "..") == 0)
	  return GSASL_AUTHENTICATION_ERROR;
	for (n = 0; idp[n]; n++)
	  if (!((idp[n] >= 'a' && idp[n] <= 'z')
		|| (idp[n] >= 'A' && idp[n] <= 'Z')
		|| (idp[n] >= '0' && idp[n] <= '9') || idp[n] == '.'))
	    {
	      printf ("Cannot handle identifier (%ld): %s\n",
		      (unsigned long) n, idp);
	      return GSASL_AUTHENTICATION_ERROR;
	    }

	/* Run helper to generate SAML AuthnRequest.   Read out request ID. */
	rc = asprintf (&tmp, "gsasl-saml20-request %s %s %s %s "
		       "%s/%s/idp-metadata.xml",
		       cfg->state_path, cfg->sp_metadata,
		       cfg->sp_key, cfg->sp_cert, cfg->cfg_path, idp);
	if (rc <= 0)
	  return GSASL_AUTHENTICATION_ERROR;
	fh = popen (tmp, "r");
	free (tmp);
	if (!fh)
	  {
	    perror ("popen");
	    return GSASL_AUTHENTICATION_ERROR;
	  }
	reqid = NULL;
	n = 0;
	if (getline (&reqid, &n, fh) <= 0)
	  {
	    perror ("getline");
	    return GSASL_AUTHENTICATION_ERROR;
	  }
	if (reqid[strlen (reqid) - 1] == '\n')
	  reqid[strlen (reqid) - 1] = '\0';
	if (reqid[strlen (reqid) - 1] == '\r')
	  reqid[strlen (reqid) - 1] = '\0';
	rc = pclose (fh);
	if (rc != 0)
	  {
	    perror ("pclose");
	    return GSASL_AUTHENTICATION_ERROR;
	  }

	/* Read URL to redirect to.  Written by gsasl-saml20-request. */
	rc = asprintf (&tmp, "%s/%s/redirect_url", cfg->state_path, reqid);
	if (rc <= 0)
	  return GSASL_AUTHENTICATION_ERROR;
	fh = fopen (tmp, "r");
	free (tmp);
	if (!fh)
	  {
	    perror ("fopen");
	    return GSASL_AUTHENTICATION_ERROR;
	  }
	redirect_url = NULL;
	n = 0;
	if (getline (&redirect_url, &n, fh) <= 0)
	  {
	    perror ("getline");
	    return GSASL_AUTHENTICATION_ERROR;
	  }
	rc = fclose (fh);
	if (rc != 0)
	  {
	    perror ("fclose");
	    return GSASL_AUTHENTICATION_ERROR;
	  }

	/* We are done */
	gsasl_session_hook_set (sctx, reqid);
	gsasl_property_set (sctx, prop, redirect_url);

	printf ("read id: %s\n", reqid);
	printf ("url: %s\n", redirect_url);

	free (redirect_url);

	return GSASL_OK;
      }
      break;

    case GSASL_VALIDATE_SAML20:
      {
	time_t start = time (NULL);
	char *id = (char *) gsasl_session_hook_get (sctx);
	char *tmp, *line;
	size_t n;
	FILE *fh;

	if (!id)
	  return GSASL_AUTHENTICATION_ERROR;

	do
	  {
	    sleep (1);

	    rc = asprintf (&tmp, "%s/%s/success", cfg->state_path, id);
	    if (rc <= 0)
	      return GSASL_AUTHENTICATION_ERROR;
	    fh = fopen (tmp, "r");
	    free (tmp);
	    if (!fh)
	      {
		rc = asprintf (&tmp, "%s/%s/fail", cfg->state_path, id);
		if (rc <= 0)
		  return GSASL_AUTHENTICATION_ERROR;
		fh = fopen (tmp, "r");
		free (tmp);
		if (!fh)
		  {
		    puts ("waiting");
		    continue;
		  }
		rc = fclose (fh);
		if (rc != 0)
		  {
		    perror ("fclose");
		    return GSASL_AUTHENTICATION_ERROR;
		  }

		return GSASL_AUTHENTICATION_ERROR;
	      }

	    rc = fclose (fh);
	    if (rc != 0)
	      {
		perror ("fclose");
		return GSASL_AUTHENTICATION_ERROR;
	      }

	    rc = asprintf (&tmp, "%s/%s/subject", cfg->state_path, id);
	    if (rc <= 0)
	      return GSASL_AUTHENTICATION_ERROR;
	    fh = fopen (tmp, "r");
	    free (tmp);
	    if (!fh)
	      {
		perror ("fopen");
		return GSASL_AUTHENTICATION_ERROR;
	      }

	    line = NULL;
	    n = 0;
	    if (getline (&line, &n, fh) <= 0)
	      {
		perror ("getline");
		return GSASL_AUTHENTICATION_ERROR;
	      }

	    printf ("subject: %s\n", line);
	    gsasl_property_set (sctx, GSASL_AUTHID, line);
	    free (line);

	    rc = fclose (fh);
	    if (rc != 0)
	      {
		perror ("fclose");
		return GSASL_AUTHENTICATION_ERROR;
	      }

	    free (id);

	    return GSASL_OK;
	  }
	while (time (NULL) - start < 30);

	printf ("timeout\n");

	return GSASL_AUTHENTICATION_ERROR;
      }
      break;

    case GSASL_PASSWORD:
      gsasl_property_set (sctx, prop, "sesam");
      rc = GSASL_OK;
      break;

    default:
      /* You may want to log (at debug verbosity level) that an
         unknown property was requested here, possibly after filtering
         known rejected property requests. */
      break;
    }

  return rc;
}
Exemplo n.º 3
0
static int
cb (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
{
  int rc = GSASL_NO_CALLBACK;
  int i = 0, j = 0;

  if (gsasl_callback_hook_get (ctx))
    i = *(int *) gsasl_callback_hook_get (ctx);
  if (gsasl_session_hook_get (sctx))
    j = *(int *) gsasl_session_hook_get (sctx);

  if (j < 0 || j > 5)
    fail ("j out of bounds: %d\n", j);

  switch (prop)
    {
    case GSASL_AUTHID:
      gsasl_property_set (sctx, prop, sasltv[i].authid);
      rc = GSASL_OK;
      break;

    case GSASL_AUTHZID:
      gsasl_property_set (sctx, prop, sasltv[i].authzid);
      rc = GSASL_OK;
      break;

    case GSASL_PASSWORD:
      gsasl_property_set (sctx, prop, sasltv[i].password);
      rc = GSASL_OK;
      break;

    case GSASL_ANONYMOUS_TOKEN:
      gsasl_property_set (sctx, prop, sasltv[i].anonymous);
      rc = GSASL_OK;
      break;

    case GSASL_SERVICE:
      rc = GSASL_OK;
      break;

    case GSASL_PASSCODE:
      gsasl_property_set (sctx, prop, sasltv[i].passcode);
      rc = GSASL_OK;
      break;

    case GSASL_SUGGESTED_PIN:
    case GSASL_PIN:
      {
	const char *suggestion =
	  gsasl_property_fast (sctx, GSASL_SUGGESTED_PIN);
	if (suggestion && sasltv[i].suggestpin
	    && strcmp (suggestion, sasltv[i].suggestpin) != 0)
	  return GSASL_AUTHENTICATION_ERROR;

	if ((suggestion == NULL && sasltv[i].suggestpin != NULL) ||
	    (suggestion != NULL && sasltv[i].suggestpin == NULL))
	  return GSASL_AUTHENTICATION_ERROR;

	gsasl_property_set (sctx, prop, sasltv[i].pin);
	rc = GSASL_OK;
      }

    case GSASL_REALM:
      break;

    case GSASL_VALIDATE_EXTERNAL:
      rc = GSASL_OK;
      break;

    case GSASL_VALIDATE_ANONYMOUS:
      if (strcmp (sasltv[i].anonymous,
		  gsasl_property_fast (sctx, GSASL_ANONYMOUS_TOKEN)) == 0)
	rc = GSASL_OK;
      else
	rc = GSASL_AUTHENTICATION_ERROR;
      break;

    case GSASL_VALIDATE_SECURID:
      {
	const char *passcode = gsasl_property_fast (sctx, GSASL_PASSCODE);
	const char *pin = gsasl_property_fast (sctx, GSASL_PIN);

	if (strcmp (passcode, sasltv[i].passcode) != 0)
	  return GSASL_AUTHENTICATION_ERROR;

	if (sasltv[i].securidrc == GSASL_SECURID_SERVER_NEED_NEW_PIN)
	  {
	    rc = sasltv[i].securidrc;
	    sasltv[i].securidrc = GSASL_OK;

	    if (sasltv[i].suggestpin)
	      {
		gsasl_property_set (sctx, GSASL_SUGGESTED_PIN,
				    sasltv[i].suggestpin);
	      }
	  }
	else if (sasltv[i].securidrc ==
		 GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE)
	  {
	    rc = sasltv[i].securidrc;
	    sasltv[i].securidrc = GSASL_OK;
	  }
	else
	  {
	    rc = sasltv[i].securidrc;

	    if (pin && sasltv[i].pin && strcmp (pin, sasltv[i].pin) != 0)
	      return GSASL_AUTHENTICATION_ERROR;

	    if ((pin == NULL && sasltv[i].pin != NULL) ||
		(pin != NULL && sasltv[i].pin == NULL))
	      return GSASL_AUTHENTICATION_ERROR;
	  }
      }
      break;

    default:
      printf ("Unknown property %d\n", prop);
      break;
    }

  return rc;
}