Esempio n. 1
0
int
_gnutls_srp_pwd_read_entry (gnutls_session_t state, char *username,
                            SRP_PWD_ENTRY ** _entry)
{
  gnutls_srp_server_credentials_t cred;
  FILE *fd;
  char line[2 * 1024];
  unsigned i, len;
  int ret;
  int idx, last_idx;
  SRP_PWD_ENTRY *entry;

  *_entry = gnutls_calloc (1, sizeof (SRP_PWD_ENTRY));
  if (*_entry == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }
  entry = *_entry;

  cred = (gnutls_srp_server_credentials_t)
    _gnutls_get_cred (state->key, GNUTLS_CRD_SRP, NULL);
  if (cred == NULL)
    {
      gnutls_assert ();
      _gnutls_srp_entry_free (entry);
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  /* if the callback which sends the parameters is
   * set, use it.
   */
  if (cred->pwd_callback != NULL)
    {
      ret = cred->pwd_callback (state, username, &entry->salt,
                                &entry->v, &entry->g, &entry->n);

      if (ret == 1)
        {                       /* the user does not exist */
          if (entry->g.size != 0 && entry->n.size != 0)
            {
              ret = _randomize_pwd_entry (entry);
              if (ret < 0)
                {
                  gnutls_assert ();
                  _gnutls_srp_entry_free (entry);
                  return ret;
                }
              return 0;
            }
          else
            {
              gnutls_assert ();
              ret = -1;         /* error in the callback */
            }
        }

      if (ret < 0)
        {
          gnutls_assert ();
          _gnutls_srp_entry_free (entry);
          return GNUTLS_E_SRP_PWD_ERROR;
        }

      return 0;
    }

  /* The callback was not set. Proceed.
   */

  if (cred->password_file == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_SRP_PWD_ERROR;
    }

  /* Open the selected password file.
   */
  fd = fopen (cred->password_file, "r");
  if (fd == NULL)
    {
      gnutls_assert ();
      _gnutls_srp_entry_free (entry);
      return GNUTLS_E_SRP_PWD_ERROR;
    }

  last_idx = 1;                 /* a default value */

  len = strlen (username);
  while (fgets (line, sizeof (line), fd) != NULL)
    {
      /* move to first ':' */
      i = 0;
      while ((line[i] != ':') && (line[i] != '\0') && (i < sizeof (line)))
        {
          i++;
        }

      if (strncmp (username, line, MAX (i, len)) == 0)
        {
          if ((idx = pwd_put_values (entry, line)) >= 0)
            {
              /* Keep the last index in memory, so we can retrieve fake parameters (g,n)
               * when the user does not exist.
               */
              /* XXX: last_idx will not be read as both if block branches return. */
              last_idx = idx;
              if (pwd_read_conf (cred->password_conf_file, entry, idx) == 0)
                {
                  return 0;
                }
              else
                {
                  gnutls_assert ();
                  _gnutls_srp_entry_free (entry);
                  return GNUTLS_E_SRP_PWD_ERROR;
                }
            }
          else
            {
              gnutls_assert ();
              _gnutls_srp_entry_free (entry);
              return GNUTLS_E_SRP_PWD_ERROR;
            }
        }
    }

  /* user was not found. Fake him. Actually read the g,n values from
   * the last index found and randomize the entry.
   */
  if (pwd_read_conf (cred->password_conf_file, entry, last_idx) == 0)
    {
      ret = _randomize_pwd_entry (entry);
      if (ret < 0)
        {
          gnutls_assert ();
          _gnutls_srp_entry_free (entry);
          return ret;
        }

      return 0;
    }

  gnutls_assert ();
  _gnutls_srp_entry_free (entry);
  return GNUTLS_E_SRP_PWD_ERROR;

}
Esempio n. 2
0
int
_gnutls_srp_pwd_read_entry(gnutls_session_t state, char *username,
			   SRP_PWD_ENTRY ** _entry)
{
	gnutls_srp_server_credentials_t cred;
	FILE *fd = NULL;
	char *line = NULL;
	size_t line_size = 0;
	unsigned i, len;
	int ret;
	int idx;
	SRP_PWD_ENTRY *entry = NULL;

	*_entry = gnutls_calloc(1, sizeof(SRP_PWD_ENTRY));
	if (*_entry == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}
	entry = *_entry;

	cred = (gnutls_srp_server_credentials_t)
	    _gnutls_get_cred(state, GNUTLS_CRD_SRP);
	if (cred == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_INSUFFICIENT_CREDENTIALS;
		goto cleanup;
	}

	/* if the callback which sends the parameters is
	 * set, use it.
	 */
	if (cred->pwd_callback != NULL) {
		ret = cred->pwd_callback(state, username, &entry->salt,
					 &entry->v, &entry->g, &entry->n);

		if (ret == 1) {	/* the user does not exist */
			if (entry->g.size != 0 && entry->n.size != 0) {
				ret = _randomize_pwd_entry(entry, cred, username);
				if (ret < 0) {
					gnutls_assert();
					goto cleanup;
				}
				return 0;
			} else {
				gnutls_assert();
				ret = -1;	/* error in the callback */
			}
		}

		if (ret < 0) {
			gnutls_assert();
			ret = GNUTLS_E_SRP_PWD_ERROR;
			goto cleanup;
		}

		return 0;
	}

	/* The callback was not set. Proceed.
	 */

	if (cred->password_file == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_SRP_PWD_ERROR;
		goto cleanup;
	}

	/* Open the selected password file.
	 */
	fd = fopen(cred->password_file, "r");
	if (fd == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_SRP_PWD_ERROR;
		goto cleanup;
	}

	len = strlen(username);
	while (getline(&line, &line_size, fd) > 0) {
		/* move to first ':' */
		i = 0;
		while ((i < line_size) && (line[i] != '\0')
		       && (line[i] != ':')) {
			i++;
		}

		if (strncmp(username, line, MAX(i, len)) == 0) {
			if ((idx = parse_tpasswd_values(entry, line)) >= 0) {
				/* Keep the last index in memory, so we can retrieve fake parameters (g,n)
				 * when the user does not exist.
				 */
				if (pwd_read_conf
				    (cred->password_conf_file, entry,
				     idx) == 0) {
					ret = 0;
					goto found;
				} else {
					gnutls_assert();
					ret = GNUTLS_E_SRP_PWD_ERROR;
					goto cleanup;
				}
			} else {
				gnutls_assert();
				ret = GNUTLS_E_SRP_PWD_ERROR;
				goto cleanup;
			}
		}
	}

	/* user was not found. Fake him. Actually read the g,n values from
	 * the last index found and randomize the entry.
	 */
	if (pwd_read_conf(cred->password_conf_file, entry, 1) == 0) {
		ret = _randomize_pwd_entry(entry, cred, username);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		ret = 0;
		goto found;
	}

	ret = GNUTLS_E_SRP_PWD_ERROR;

cleanup:
	gnutls_assert();
	_gnutls_srp_entry_free(entry);

found:
	zeroize_key(line, line_size);
	free(line);
	if (fd)
		fclose(fd);
	return ret;
}