예제 #1
0
파일: id.c 프로젝트: svn2github/subversion
svn_string_t *
svn_fs_fs__id_unparse(const svn_fs_id_t *fs_id,
                      apr_pool_t *pool)
{
  char string[6 * SVN_INT64_BUFFER_SIZE + 10];
  const fs_fs__id_t *id = (const fs_fs__id_t *)fs_id;

  char *p = unparse_id_part(string, &id->private_id.node_id);
  p = unparse_id_part(p, &id->private_id.copy_id);

  if (svn_fs_fs__id_txn_used(&id->private_id.txn_id))
    {
      *(p++) = 't';
      p += svn__i64toa(p, id->private_id.txn_id.revision);
      *(p++) = '-';
      p += svn__ui64tobase36(p, id->private_id.txn_id.number);
    }
  else
    {
      *(p++) = 'r';
      p += svn__i64toa(p, id->private_id.rev_item.revision);
      *(p++) = '/';
      p += svn__i64toa(p, id->private_id.rev_item.number);
    }

  return svn_string_ncreate(string, p - string, pool);
}
예제 #2
0
파일: skel.c 프로젝트: 2asoft/freebsd
svn_error_t *
svn_skel__parse_iprops(apr_array_header_t **iprops,
                       const svn_skel_t *skel,
                       apr_pool_t *result_pool)
{
  svn_skel_t *elt;

  /* Validate the skel. */
  if (! is_valid_iproplist_skel(skel))
    return skel_err("iprops");

  /* Create the returned structure */
  *iprops = apr_array_make(result_pool, 1,
                           sizeof(svn_prop_inherited_item_t *));

  for (elt = skel->children; elt; elt = elt->next->next)
    {
      svn_prop_inherited_item_t *new_iprop = apr_palloc(result_pool,
                                                        sizeof(*new_iprop));
      svn_string_t *repos_parent = svn_string_ncreate(elt->data, elt->len,
                                                      result_pool);
      SVN_ERR(svn_skel__parse_proplist(&(new_iprop->prop_hash), elt->next,
                                       result_pool));
      new_iprop->path_or_url = repos_parent->data;
      APR_ARRAY_PUSH(*iprops, svn_prop_inherited_item_t *) = new_iprop;
    }
  return SVN_NO_ERROR;
}
예제 #3
0
파일: skel.c 프로젝트: 2asoft/freebsd
svn_error_t *
svn_skel__parse_prop(svn_string_t **propval,
                     const svn_skel_t *skel,
                     const char *propname,
                     apr_pool_t *pool /* result_pool */)
{
  svn_skel_t *elt;

  *propval = NULL;

  /* Validate the skel. */
  if (! is_valid_proplist_skel(skel))
    return skel_err("proplist");

  /* Look for PROPNAME in SKEL. */
  for (elt = skel->children; elt; elt = elt->next->next)
    {
      if (elt->len == strlen(propname)
          && strncmp(propname, elt->data, elt->len) == 0)
        {
          *propval = svn_string_ncreate(elt->next->data, elt->next->len,
                                        pool);
          break;
        }
      else
        {
          continue;
        }
    }
  return SVN_NO_ERROR;
}
예제 #4
0
파일: skel.c 프로젝트: 2asoft/freebsd
svn_error_t *
svn_skel__parse_proplist(apr_hash_t **proplist_p,
                         const svn_skel_t *skel,
                         apr_pool_t *pool /* result_pool */)
{
  apr_hash_t *proplist = NULL;
  svn_skel_t *elt;

  /* Validate the skel. */
  if (! is_valid_proplist_skel(skel))
    return skel_err("proplist");

  /* Create the returned structure */
  proplist = apr_hash_make(pool);
  for (elt = skel->children; elt; elt = elt->next->next)
    {
      svn_string_t *value = svn_string_ncreate(elt->next->data,
                                               elt->next->len, pool);
      apr_hash_set(proplist,
                   apr_pstrmemdup(pool, elt->data, elt->len),
                   elt->len,
                   value);
    }

  /* Return the structure. */
  *proplist_p = proplist;
  return SVN_NO_ERROR;
}
예제 #5
0
/* Return a copy, allocated in POOL, of the next line of text from *STR
 * up to and including a CR and/or an LF. Change *STR to point to the
 * remainder of the string after the returned part. If there are no
 * characters to be returned, return NULL; never return an empty string.
 */
static const char *
next_line(const char **str, apr_pool_t *pool)
{
  const char *start = *str;
  const char *p = *str;

  /* n.b. Throughout this fn, we never read any character after a '\0'. */
  /* Skip over all non-EOL characters, if any. */
  while (*p != '\r' && *p != '\n' && *p != '\0')
    p++;
  /* Skip over \r\n or \n\r or \r or \n, if any. */
  if (*p == '\r' || *p == '\n')
    {
      char c = *p++;

      if ((c == '\r' && *p == '\n') || (c == '\n' && *p == '\r'))
        p++;
    }

  /* Now p points after at most one '\n' and/or '\r'. */
  *str = p;

  if (p == start)
    return NULL;

  return svn_string_ncreate(start, p - start, pool)->data;
}
예제 #6
0
static void
x509parse_get_hostnames(svn_x509_certinfo_t *ci, x509_cert *crt,
                        apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
  ci->hostnames = NULL;

  if (crt->dnsnames->nelts > 0)
    {
      int i;

      ci->hostnames = apr_array_make(result_pool, crt->dnsnames->nelts,
                                     sizeof(const char*));

      /* Subject Alt Names take priority */
      for (i = 0; i < crt->dnsnames->nelts; i++)
        {
          x509_buf *dnsname = APR_ARRAY_IDX(crt->dnsnames, i, x509_buf *);
          const svn_string_t *temp = svn_string_ncreate((const char *)dnsname->p,
                                                        dnsname->len,
                                                        scratch_pool);

          APR_ARRAY_PUSH(ci->hostnames, const char*)
            = fuzzy_escape(temp, result_pool);
        }
    }
예제 #7
0
apr_hash_t *PropertyTable::hash(const SVN::Pool &pool, bool nullIfEmpty)
{
  if (m_revprops.size() == 0 && nullIfEmpty)
    return NULL;

  apr_hash_t *revprop_table = apr_hash_make(pool.getPool());

  std::map<std::string, std::string>::const_iterator it;
  for (it = m_revprops.begin(); it != m_revprops.end(); ++it)
    {
      const char *propname = apr_pstrdup(pool.getPool(), it->first.c_str());
      if (!svn_prop_name_is_valid(propname))
        {
          const char *msg = apr_psprintf(pool.getPool(),
                                         "Invalid property name: '%s'",
                                         propname);
          JNIUtil::throwNativeException(JAVA_PACKAGE "/ClientException", msg,
                                        NULL, SVN_ERR_CLIENT_PROPERTY_NAME);
          return NULL;
        }

      svn_string_t *propval = svn_string_ncreate(it->second.c_str(),
                                                 it->second.size(),
                                                 pool.getPool());

      apr_hash_set(revprop_table, propname, APR_HASH_KEY_STRING, propval);
    }

  return revprop_table;
}
예제 #8
0
Py::Object pysvn_client::cmd_revpropset( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true,  name_prop_name },
    { true,  name_prop_value },
    { true,  name_url },
    { false, name_revision },
    { false, name_force },
    { false, NULL }
    };
    FunctionArguments args( "revpropset", args_desc, a_args, a_kws );
    args.check();

    std::string propname( args.getUtf8String( name_prop_name ) );
    std::string propval( args.getUtf8String( name_prop_value ) );
    std::string path( args.getUtf8String( name_url ) );
    svn_opt_revision_t revision = args.getRevision( name_revision, svn_opt_revision_head );

    bool force = args.getBoolean( name_force, false );

    SvnPool pool( m_context );

    svn_revnum_t revnum = 0;
    try
    {
        std::string norm_path( svnNormalisedIfPath( path, pool ) );

        checkThreadPermission();

        PythonAllowThreads permission( m_context );

        const svn_string_t *svn_propval = svn_string_ncreate( propval.c_str(), propval.size(), pool );
        svn_error_t *error = svn_client_revprop_set
            (
            propname.c_str(),
            svn_propval,
            norm_path.c_str(),
            &revision,
            &revnum,
            force,
            m_context,
            pool
            );
        permission.allowThisThread();
        if( error != NULL )
            throw SvnException( error );
    }
    catch( SvnException &e )
    {
        // use callback error over ClientException
        m_context.checkForError( m_module.client_error );

        throw_client_error( e );
    }

    return Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, revnum ) );
}
예제 #9
0
/* Set the value of KEY (whose size is KEY_LEN, or APR_HASH_KEY_STRING
   if unknown) to an svn_string_t-ized version of VALUE (whose size is
   VALUE_LEN, or APR_HASH_KEY_STRING if unknown) in HASH.  The value
   will be allocated in POOL; KEY will not be duped.  If either KEY or VALUE
   is NULL, this function will do nothing. */
static void
hash_store(apr_hash_t *hash,
           const char *key,
           apr_ssize_t key_len,
           const char *value,
           apr_ssize_t value_len,
           apr_pool_t *pool)
{
  if (! (key && value))
    return;
  if (value_len == APR_HASH_KEY_STRING)
    value_len = strlen(value);
  apr_hash_set(hash, key, key_len,
               svn_string_ncreate(value, value_len, pool));
}
예제 #10
0
/* Set *MC_KEY to a memcache key for the given key KEY for CACHE, allocated
   in POOL. */
static svn_error_t *
build_key(const char **mc_key,
          memcache_t *cache,
          const void *raw_key,
          apr_pool_t *pool)
{
  const char *encoded_suffix;
  const char *long_key;
  apr_size_t long_key_len;

  if (cache->klen == APR_HASH_KEY_STRING)
    encoded_suffix = svn_path_uri_encode(raw_key, pool);
  else
    {
      const svn_string_t *raw = svn_string_ncreate(raw_key, cache->klen, pool);
      const svn_string_t *encoded = svn_base64_encode_string2(raw, FALSE,
                                                              pool);
      encoded_suffix = encoded->data;
    }

  long_key = apr_pstrcat(pool, "SVN:", cache->prefix, ":", encoded_suffix,
                         (char *)NULL);
  long_key_len = strlen(long_key);

  /* We don't want to have a key that's too big.  If it was going to
     be too big, we MD5 the entire string, then replace the last bit
     with the checksum.  Note that APR_MD5_DIGESTSIZE is for the pure
     binary digest; we have to double that when we convert to hex.

     Every key we use will either be at most
     MEMCACHED_KEY_UNHASHED_LEN bytes long, or be exactly
     MAX_MEMCACHED_KEY_LEN bytes long. */
  if (long_key_len > MEMCACHED_KEY_UNHASHED_LEN)
    {
      svn_checksum_t *checksum;
      SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, long_key, long_key_len,
                           pool));

      long_key = apr_pstrcat(pool,
                             apr_pstrmemdup(pool, long_key,
                                            MEMCACHED_KEY_UNHASHED_LEN),
                             svn_checksum_to_cstring_display(checksum, pool),
                             (char *)NULL);
    }

  *mc_key = long_key;
  return SVN_NO_ERROR;
}
예제 #11
0
svn_error_t *svn_fs_bdb__set_node_origin(svn_fs_t *fs,
                                         const char *node_id,
                                         const svn_fs_id_t *origin_id,
                                         trail_t *trail,
                                         apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  /* Create a key from our NODE_ID. */
  svn_fs_base__str_to_dbt(&key, node_id);

  /* Check to see if we already have a mapping for NODE_ID.  If so,
     and the value is the same one we were about to write.  That's
     cool -- just do nothing.  If, however, the value is *different*,
     that's a red flag!  */
  svn_fs_base__trail_debug(trail, "node-origins", "get");
  db_err = bfd->node_origins->get(bfd->node_origins, trail->db_txn,
                                  &key, svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);
  if (db_err != DB_NOTFOUND)
    {
      const svn_string_t *origin_id_str = svn_fs_base__id_unparse(origin_id, pool);
      const svn_string_t *old_origin_id_str =
        svn_string_ncreate(value.data, value.size, pool);

      if (! svn_string_compare(origin_id_str, old_origin_id_str))
        return svn_error_createf
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Node origin for '%s' exists in filesystem '%s' with a different "
             "value (%s) than what we were about to store (%s)"),
           node_id, fs->path, old_origin_id_str->data, origin_id_str->data);
      else
        return SVN_NO_ERROR;
    }

  /* Create a value from our ORIGIN_ID, and add this record to the table. */
  svn_fs_base__id_to_dbt(&value, origin_id, pool);
  svn_fs_base__trail_debug(trail, "node-origins", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing node-origins record"),
                   bfd->node_origins->put(bfd->node_origins, trail->db_txn,
                                          &key, &value, 0)));
  return SVN_NO_ERROR;
}
예제 #12
0
const svn_string_t * SVNAuthData::encrypt_data(const svn_string_t *orig, apr_pool_t *pool)
{
    DATA_BLOB blobin;
    DATA_BLOB blobout;
    const svn_string_t * crypted = NULL;

    blobin.cbData = (DWORD)orig->len;
    blobin.pbData = (BYTE *)orig->data;
    if (CryptProtectData(&blobin, description, NULL, NULL, NULL,
        CRYPTPROTECT_UI_FORBIDDEN, &blobout))
    {
        const svn_string_t * crypt = svn_string_ncreate((const char *)blobout.pbData,
                                     blobout.cbData, pool);
        if (crypt)
            crypted = svn_base64_encode_string2(crypt, false, pool);
        LocalFree(blobout.pbData);
    }
    return crypted;
}
예제 #13
0
/* Return a copy of ORIG, encrypted using the Windows CryptoAPI and
   allocated from POOL. */
const svn_string_t *
encrypt_data(const svn_string_t *orig,
             apr_pool_t *pool)
{
  DATA_BLOB blobin;
  DATA_BLOB blobout;
  const svn_string_t *crypted = NULL;

  blobin.cbData = orig->len;
  blobin.pbData = (BYTE *)orig->data;
  if (CryptProtectData(&blobin, description, NULL, NULL, NULL,
                       CRYPTPROTECT_UI_FORBIDDEN, &blobout))
    {
      crypted = svn_string_ncreate((const char *)blobout.pbData,
                                   blobout.cbData, pool);
      LocalFree(blobout.pbData);
    }
  return crypted;
}
예제 #14
0
const svn_string_t * SVNAuthData::decrypt_data(const svn_string_t *crypted, apr_pool_t *pool)
{
    crypted = svn_base64_decode_string(crypted, pool);

    DATA_BLOB blobin;
    DATA_BLOB blobout;
    LPWSTR descr;
    const svn_string_t * orig = NULL;

    blobin.cbData = (DWORD)crypted->len;
    blobin.pbData = (BYTE *)crypted->data;
    if (CryptUnprotectData(&blobin, &descr, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobout))
    {
        if (0 == lstrcmpW(descr, description))
            orig = svn_string_ncreate((const char *)blobout.pbData, blobout.cbData, pool);
        LocalFree(blobout.pbData);
        LocalFree(descr);
    }
    return orig;
}
예제 #15
0
svn_string_t *
svn_string_dup(const svn_string_t *original_string, apr_pool_t *pool)
{
  return (svn_string_ncreate(original_string->data,
                             original_string->len, pool));
}
예제 #16
0
svn_string_t *
svn_string_create_from_buf(const svn_stringbuf_t *strbuf, apr_pool_t *pool)
{
  return svn_string_ncreate(strbuf->data, strbuf->len, pool);
}
예제 #17
0
svn_string_t *
svn_string_create(const char *cstring, apr_pool_t *pool)
{
  return svn_string_ncreate(cstring, strlen(cstring), pool);
}
예제 #18
0
static svn_error_t *try_auth(svn_ra_svn_conn_t *conn,
                             sasl_conn_t *sasl_ctx,
                             apr_pool_t *pool,
                             server_baton_t *b,
                             svn_boolean_t *success)
{
  const char *out, *mech;
  const svn_string_t *arg = NULL, *in;
  unsigned int outlen;
  int result;
  svn_boolean_t use_base64;

  *success = FALSE;

  /* Read the client's chosen mech and the initial token. */
  SVN_ERR(svn_ra_svn_read_tuple(conn, pool, "w(?s)", &mech, &in));

  if (strcmp(mech, "EXTERNAL") == 0 && !in)
    in = svn_string_create(b->tunnel_user, pool);
  else if (in)
    in = svn_base64_decode_string(in, pool);

  /* For CRAM-MD5, we don't base64-encode stuff. */
  use_base64 = (strcmp(mech, "CRAM-MD5") != 0);

  result = sasl_server_start(sasl_ctx, mech,
                             in ? in->data : NULL,
                             in ? in->len : 0, &out, &outlen);

  if (result != SASL_OK && result != SASL_CONTINUE)
    return fail_auth(conn, pool, sasl_ctx);

  while (result == SASL_CONTINUE)
    {
      svn_ra_svn_item_t *item;

      arg = svn_string_ncreate(out, outlen, pool);
      /* Encode what we send to the client. */
      if (use_base64)
        arg = svn_base64_encode_string2(arg, TRUE, pool);

      SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(s)", "step", arg));

      /* Read and decode the client response. */
      SVN_ERR(svn_ra_svn_read_item(conn, pool, &item));
      if (item->kind != SVN_RA_SVN_STRING)
        return SVN_NO_ERROR;

      in = item->u.string;
      if (use_base64)
        in = svn_base64_decode_string(in, pool);
      result = sasl_server_step(sasl_ctx, in->data, in->len, &out, &outlen);
    }

  if (result != SASL_OK)
    return fail_auth(conn, pool, sasl_ctx);

  /* Send our last response, if necessary. */
  if (outlen)
    arg = svn_base64_encode_string2(svn_string_ncreate(out, outlen, pool), TRUE,
                                    pool);
  else
    arg = NULL;

  *success = TRUE;
  SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(?s)", "success", arg));

  return SVN_NO_ERROR;
}
예제 #19
0
/* Implements svn_hash_read2 and svn_hash_read_incremental. */
static svn_error_t *
hash_read(apr_hash_t *hash, svn_stream_t *stream, const char *terminator,
          svn_boolean_t incremental, apr_pool_t *pool)
{
  svn_stringbuf_t *buf;
  svn_boolean_t eof;
  apr_size_t len, keylen, vallen;
  char c, *end, *keybuf, *valbuf;
  apr_pool_t *iterpool = svn_pool_create(pool);

  while (1)
    {
      svn_pool_clear(iterpool);

      /* Read a key length line.  Might be END, though. */
      SVN_ERR(svn_stream_readline(stream, &buf, "\n", &eof, iterpool));

      /* Check for the end of the hash. */
      if ((!terminator && eof && buf->len == 0)
          || (terminator && (strcmp(buf->data, terminator) == 0)))
        break;

      /* Check for unexpected end of stream */
      if (eof)
        return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                _("Serialized hash missing terminator"));

      if ((buf->len >= 3) && (buf->data[0] == 'K') && (buf->data[1] == ' '))
        {
          /* Get the length of the key */
          keylen = (size_t) strtoul(buf->data + 2, &end, 10);
          if (keylen == (size_t) ULONG_MAX || *end != '\0')
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                    _("Serialized hash malformed"));

          /* Now read that much into a buffer. */
          keybuf = apr_palloc(pool, keylen + 1);
          SVN_ERR(svn_stream_read(stream, keybuf, &keylen));
          keybuf[keylen] = '\0';

          /* Suck up extra newline after key data */
          len = 1;
          SVN_ERR(svn_stream_read(stream, &c, &len));
          if (c != '\n')
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                    _("Serialized hash malformed"));

          /* Read a val length line */
          SVN_ERR(svn_stream_readline(stream, &buf, "\n", &eof, iterpool));

          if ((buf->data[0] == 'V') && (buf->data[1] == ' '))
            {
              vallen = (size_t) strtoul(buf->data + 2, &end, 10);
              if (vallen == (size_t) ULONG_MAX || *end != '\0')
                return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                        _("Serialized hash malformed"));

              valbuf = apr_palloc(iterpool, vallen + 1);
              SVN_ERR(svn_stream_read(stream, valbuf, &vallen));
              valbuf[vallen] = '\0';

              /* Suck up extra newline after val data */
              len = 1;
              SVN_ERR(svn_stream_read(stream, &c, &len));
              if (c != '\n')
                return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                        _("Serialized hash malformed"));

              /* Add a new hash entry. */
              apr_hash_set(hash, keybuf, keylen,
                           svn_string_ncreate(valbuf, vallen, pool));
            }
          else
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                    _("Serialized hash malformed"));
        }
      else if (incremental && (buf->len >= 3)
               && (buf->data[0] == 'D') && (buf->data[1] == ' '))
        {
          /* Get the length of the key */
          keylen = (size_t) strtoul(buf->data + 2, &end, 10);
          if (keylen == (size_t) ULONG_MAX || *end != '\0')
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                    _("Serialized hash malformed"));

          /* Now read that much into a buffer. */
          keybuf = apr_palloc(iterpool, keylen + 1);
          SVN_ERR(svn_stream_read(stream, keybuf, &keylen));
          keybuf[keylen] = '\0';

          /* Suck up extra newline after key data */
          len = 1;
          SVN_ERR(svn_stream_read(stream, &c, &len));
          if (c != '\n')
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                    _("Serialized hash malformed"));

          /* Remove this hash entry. */
          apr_hash_set(hash, keybuf, keylen, NULL);
        }
      else
        {
          return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                  _("Serialized hash malformed"));
        }
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}
예제 #20
0
static svn_error_t *try_auth(svn_ra_svn_conn_t *conn,
                             sasl_conn_t *sasl_ctx,
                             apr_pool_t *pool,
                             server_baton_t *b,
                             svn_boolean_t *success)
{
  const char *out, *mech;
  const svn_string_t *arg = NULL, *in;
  unsigned int outlen;
  int result;
  svn_boolean_t use_base64;

  *success = FALSE;

  /* Read the client's chosen mech and the initial token. */
  SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "w(?s)", &mech, &in));

  if (strcmp(mech, "EXTERNAL") == 0 && !in)
    in = svn_string_create(b->client_info->tunnel_user, pool);
  else if (in)
    in = svn_base64_decode_string(in, pool);

  /* For CRAM-MD5, we don't base64-encode stuff. */
  use_base64 = (strcmp(mech, "CRAM-MD5") != 0);

  /* sasl uses unsigned int for the length of strings, we use apr_size_t
   * which may not be the same size.  Deal with potential integer overflow */
  if (in && in->len > UINT_MAX)
    return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                             _("Initial token is too long"));

  result = svn_sasl__server_start(sasl_ctx, mech,
                                  in ? in->data : NULL,
                                  in ? (unsigned int) in->len : 0,
                                  &out, &outlen);

  if (result != SASL_OK && result != SASL_CONTINUE)
    return fail_auth(conn, pool, sasl_ctx);

  while (result == SASL_CONTINUE)
    {
      svn_ra_svn__item_t *item;

      arg = svn_string_ncreate(out, outlen, pool);
      /* Encode what we send to the client. */
      if (use_base64)
        arg = svn_base64_encode_string2(arg, TRUE, pool);

      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(s)", "step", arg));

      /* Read and decode the client response. */
      SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
      if (item->kind != SVN_RA_SVN_STRING)
        return SVN_NO_ERROR;

      in = &item->u.string;
      if (use_base64)
        in = svn_base64_decode_string(in, pool);

      if (in->len > UINT_MAX)
        return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                 _("Step response is too long"));

      result = svn_sasl__server_step(sasl_ctx, in->data,
                                     (unsigned int) in->len,
                                     &out, &outlen);
    }

  if (result != SASL_OK)
    return fail_auth(conn, pool, sasl_ctx);

  /* Send our last response, if necessary. */
  if (outlen)
    arg = svn_base64_encode_string2(svn_string_ncreate(out, outlen, pool), TRUE,
                                    pool);
  else
    arg = NULL;

  *success = TRUE;
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(?s)", "success", arg));

  return SVN_NO_ERROR;
}
예제 #21
0
Py::Object pysvn_client::cmd_propset( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
        { true,  name_prop_name },
        { true,  name_prop_value },
        { true,  name_url_or_path },
        { false, name_revision },
        { false, name_recurse },
#if defined( PYSVN_HAS_CLIENT_PROPSET2 )
        { false, name_skip_checks },
#endif
#if defined( PYSVN_HAS_CLIENT_PROPSET3 )
        { false, name_depth },
        { false, name_base_revision_for_url },
        { false, name_changelists },
        { false, name_revprops },
#endif
        { false, NULL }
    };
    FunctionArguments args( "propset", args_desc, a_args, a_kws );
    args.check();

    std::string propname( args.getUtf8String( name_prop_name ) );
    std::string propval( args.getUtf8String( name_prop_value ) );
    std::string path( args.getUtf8String( name_url_or_path ) );

    svn_opt_revision_t revision;
    if( is_svn_url( path ) )
        revision = args.getRevision( name_revision, svn_opt_revision_head );
    else
        revision = args.getRevision( name_revision, svn_opt_revision_working );

    SvnPool pool( m_context );

#if defined( PYSVN_HAS_CLIENT_PROPSET3 )
    apr_array_header_t *changelists = NULL;

    if( args.hasArg( name_changelists ) )
    {
        changelists = arrayOfStringsFromListOfStrings( args.getArg( name_changelists ), pool );
    }

    svn_revnum_t base_revision_for_url = args.getInteger( name_base_revision_for_url, 0 );
    svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_files, svn_depth_empty );

    apr_hash_t *revprops = NULL;
    if( args.hasArg( name_revprops ) )
    {
        Py::Object py_revprop = args.getArg( name_revprops );
        if( !py_revprop.isNone() )
        {
            revprops = hashOfStringsFromDistOfStrings( py_revprop, pool );
        }
    }
#else
    bool recurse = args.getBoolean( name_recurse, false );
#endif
#if defined( PYSVN_HAS_CLIENT_PROPSET2 )
    bool skip_checks = args.getBoolean( name_skip_checks, false );
#endif

#if defined( PYSVN_HAS_CLIENT_PROPSET3 )
    pysvn_commit_info_t *commit_info = NULL;
#endif

    try
    {
        std::string norm_path( svnNormalisedIfPath( path, pool ) );

        checkThreadPermission();

        PythonAllowThreads permission( m_context );

        const svn_string_t *svn_propval = svn_string_ncreate( propval.c_str(), propval.size(), pool );

#if defined( PYSVN_HAS_CLIENT_PROPSET3 )
        svn_error_t *error = svn_client_propset3
                             (
                                 &commit_info,
                                 propname.c_str(),
                                 svn_propval,
                                 norm_path.c_str(),
                                 depth,
                                 skip_checks,
                                 base_revision_for_url,
                                 changelists,
                                 revprops,
                                 m_context.ctx(),
                                 pool
                             );
#elif defined( PYSVN_HAS_CLIENT_PROPSET2 )
        svn_error_t *error = svn_client_propset2
                             (
                                 propname.c_str(),
                                 svn_propval,
                                 norm_path.c_str(),
                                 recurse,
                                 skip_checks,
                                 m_context.ctx(),
                                 pool
                             );
#else
        svn_error_t *error = svn_client_propset
                             (
                                 propname.c_str(),
                                 svn_propval,
                                 norm_path.c_str(),
                                 recurse,
                                 pool
                             );
#endif
        permission.allowThisThread();
        if( error != NULL )
            throw SvnException( error );
    }
    catch( SvnException &e )
    {
        // use callback error over ClientException
        m_context.checkForError( m_module.client_error );

        throw_client_error( e );
    }

#if defined( PYSVN_HAS_CLIENT_PROPSET3 )
    return toObject( commit_info );
#else
    return Py::None();
#endif
}
예제 #22
0
/* Make a best effort to convert a X.509 name to a UTF-8 encoded
 * string and return it.  If we can't properly convert just do a
 * fuzzy conversion so we have something to display. */
static const char *
x509name_to_utf8_string(const x509_name *name, apr_pool_t *result_pool)
{
  const svn_string_t *src_string;
  const svn_string_t *utf8_string;
  svn_error_t *err;

  src_string = svn_string_ncreate((const char *)name->val.p,
                                  name->val.len,
                                  result_pool);
  switch (name->val.tag)
    {
    case ASN1_UTF8_STRING:
      if (svn_utf__is_valid(src_string->data, src_string->len))
        return nul_escape(src_string, result_pool);
      else
        /* not a valid UTF-8 string, who knows what it is,
         * so run it through the fuzzy_escape code.  */
        return fuzzy_escape(src_string, result_pool);
      break;

      /* Both BMP and UNIVERSAL should always be in Big Endian (aka
       * network byte order).  But rumor has it that there are certs
       * out there with other endianess and even Byte Order Marks.
       * If we actually run into these, we might need to do something
       * about it. */

    case ASN1_BMP_STRING:
      if (0 != src_string->len % sizeof(apr_uint16_t))
          return fuzzy_escape(src_string, result_pool);
      err = svn_utf__utf16_to_utf8(&utf8_string,
                                   (const void*)(src_string->data),
                                   src_string->len / sizeof(apr_uint16_t),
                                   TRUE, result_pool, result_pool);
      break;

    case ASN1_UNIVERSAL_STRING:
      if (0 != src_string->len % sizeof(apr_int32_t))
          return fuzzy_escape(src_string, result_pool);
      err = svn_utf__utf32_to_utf8(&utf8_string,
                                   (const void*)(src_string->data),
                                   src_string->len / sizeof(apr_int32_t),
                                   TRUE, result_pool, result_pool);
      break;

      /* Despite what all the IETF, ISO, ITU bits say everything out
       * on the Internet that I can find treats this as ISO-8859-1.
       * Even the name is misleading, it's not actually T.61.  All the
       * gory details can be found in the Character Sets section of:
       * https://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
       */
    case ASN1_T61_STRING:
      err = latin1_to_utf8(&utf8_string, src_string, result_pool);
      break;

      /* This leaves two types out there in the wild.  PrintableString,
       * which is just a subset of ASCII and IA5 which is ASCII (though
       * 0x24 '$' and 0x23 '#' may be defined with differnet symbols
       * depending on the location, in practice it seems everyone just
       * treats it as ASCII).  Since these are just ASCII run through
       * the fuzzy_escape code to deal with anything that isn't actually
       * ASCII.  There shouldn't be any other types here but if we find
       * a cert with some other encoding, the best we can do is the
       * fuzzy_escape().  Note: Technically IA5 isn't valid in this
       * context, however in the real world it may pop up. */
    default:
      return fuzzy_escape(src_string, result_pool);
    }

  if (err)
    {
      svn_error_clear(err);
      return fuzzy_escape(src_string, result_pool);
    }

  return nul_escape(utf8_string, result_pool);
}