~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/bindings/javahl/native/ClientContext.cpp

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
#include "svn_client.h"
28
28
#include "private/svn_wc_private.h"
29
 
#include "svn_private_config.h"
30
29
 
31
30
#include "ClientContext.h"
32
31
#include "JNIUtil.h"
37
36
#include "EnumMapper.h"
38
37
#include "CommitMessage.h"
39
38
 
 
39
#include "svn_private_config.h"
40
40
 
41
41
ClientContext::ClientContext(jobject jsvnclient, SVN::Pool &pool)
42
 
    : m_prompter(NULL),
43
 
      m_cancelOperation(false)
 
42
    : OperationContext(pool)
44
43
{
45
 
    JNIEnv *env = JNIUtil::getEnv();
46
 
 
47
 
    /* Grab a global reference to the Java object embedded in the parent Java
48
 
       object. */
49
44
    static jfieldID ctxFieldID = 0;
50
 
    if (ctxFieldID == 0)
51
 
    {
52
 
        jclass clazz = env->GetObjectClass(jsvnclient);
53
 
        if (JNIUtil::isJavaExceptionThrown())
54
 
            return;
55
 
 
56
 
        ctxFieldID = env->GetFieldID(clazz, "clientContext",
57
 
                                "L"JAVA_PACKAGE"/SVNClient$ClientContext;");
58
 
        if (JNIUtil::isJavaExceptionThrown() || ctxFieldID == 0)
59
 
            return;
60
 
 
61
 
        env->DeleteLocalRef(clazz);
62
 
    }
63
 
 
64
 
    jobject jctx = env->GetObjectField(jsvnclient, ctxFieldID);
65
 
    if (JNIUtil::isJavaExceptionThrown())
66
 
        return;
67
 
 
68
 
    m_jctx = env->NewGlobalRef(jctx);
69
 
    if (JNIUtil::isJavaExceptionThrown())
70
 
        return;
71
 
 
72
 
    env->DeleteLocalRef(jctx);
 
45
    attachJavaObject(jsvnclient, JAVAHL_ARG("/SVNClient$ClientContext;"), "clientContext", &ctxFieldID);
73
46
 
74
47
    SVN_JNI_ERR(svn_client_create_context2(&m_context, NULL,
75
48
                                           pool.getPool()),
96
69
    m_context->conflict_func2 = resolve;
97
70
    m_context->conflict_baton2 = m_jctx;
98
71
 
99
 
    m_context->client_name = "javahl";
100
 
    m_pool = &pool;
 
72
    m_context->client_name = getClientName();
 
73
 
 
74
    if (m_jtunnelcb)
 
75
      {
 
76
        m_context->check_tunnel_func = checkTunnel;
 
77
        m_context->open_tunnel_func = openTunnel;
 
78
        m_context->tunnel_baton = m_jtunnelcb;
 
79
      }
101
80
}
102
81
 
103
82
ClientContext::~ClientContext()
104
83
{
105
 
    delete m_prompter;
106
 
 
107
 
    JNIEnv *env = JNIUtil::getEnv();
108
 
    env->DeleteGlobalRef(m_jctx);
109
 
}
110
 
 
 
84
}
 
85
 
 
86
void ClientContext::setTunnelCallback(jobject jtunnelcb)
 
87
{
 
88
  OperationContext::setTunnelCallback(jtunnelcb);
 
89
  if (m_jtunnelcb)
 
90
    {
 
91
      m_context->check_tunnel_func = checkTunnel;
 
92
      m_context->open_tunnel_func = openTunnel;
 
93
      m_context->tunnel_baton = m_jtunnelcb;
 
94
    }
 
95
  else
 
96
    {
 
97
      m_context->check_tunnel_func = NULL;
 
98
      m_context->open_tunnel_func = NULL;
 
99
      m_context->tunnel_baton = NULL;
 
100
    }
 
101
}
111
102
 
112
103
/* Helper function to make sure that we don't keep dangling pointers in ctx.
113
104
   Note that this function might be called multiple times if getContext()
140
131
ClientContext::getContext(CommitMessage *message, SVN::Pool &in_pool)
141
132
{
142
133
    apr_pool_t *pool = in_pool.getPool();
143
 
    svn_auth_baton_t *ab;
144
134
    svn_client_ctx_t *ctx = m_context;
145
135
 
146
136
    /* Make a temporary copy of ctx to restore at pool cleanup to avoid
157
147
    apr_pool_cleanup_register(in_pool.getPool(), bt, clear_ctx_ptrs,
158
148
                              clear_ctx_ptrs);
159
149
 
160
 
 
161
150
    if (!ctx->config)
162
151
      {
163
 
        const char *configDir = m_configDir.c_str();
164
 
        if (m_configDir.empty())
165
 
            configDir = NULL;
166
 
        SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir,
167
 
                                          m_pool->getPool()),
168
 
                    NULL);
 
152
        apr_hash_t * configData = getConfigData();
169
153
 
 
154
        ctx->config = configData;
170
155
        bt->backup->config = ctx->config;
171
156
      }
172
 
    svn_config_t *config =
173
 
        reinterpret_cast<svn_config_t *>(apr_hash_get(ctx->config,
174
 
                                                      SVN_CONFIG_CATEGORY_CONFIG,
175
 
                                                      APR_HASH_KEY_STRING));
176
 
 
177
 
 
178
 
    /* The whole list of registered providers */
179
 
    apr_array_header_t *providers;
180
 
 
181
 
    /* Populate the registered providers with the platform-specific providers */
182
 
    SVN_JNI_ERR(svn_auth_get_platform_specific_client_providers(&providers,
183
 
                                                                config,
184
 
                                                                pool),
185
 
                NULL);
186
 
 
187
 
    /* Use the prompter (if available) to prompt for password and cert
188
 
     * caching. */
189
 
    svn_auth_plaintext_prompt_func_t plaintext_prompt_func = NULL;
190
 
    void *plaintext_prompt_baton = NULL;
191
 
    svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func;
192
 
    void *plaintext_passphrase_prompt_baton = NULL;
193
 
 
194
 
    if (m_prompter != NULL)
195
 
    {
196
 
        plaintext_prompt_func = Prompter::plaintext_prompt;
197
 
        plaintext_prompt_baton = m_prompter;
198
 
        plaintext_passphrase_prompt_func = Prompter::plaintext_passphrase_prompt;
199
 
        plaintext_passphrase_prompt_baton = m_prompter;
200
 
    }
201
 
 
202
 
    /* The main disk-caching auth providers, for both
203
 
     * 'username/password' creds and 'username' creds.  */
204
 
    svn_auth_provider_object_t *provider;
205
 
 
206
 
    svn_auth_get_simple_provider2(&provider, plaintext_prompt_func,
207
 
                                  plaintext_prompt_baton, pool);
208
 
    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
209
 
 
210
 
    svn_auth_get_username_provider(&provider, pool);
211
 
    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
212
 
 
213
 
    /* The server-cert, client-cert, and client-cert-password providers. */
214
 
    SVN_JNI_ERR(svn_auth_get_platform_specific_provider(&provider,
215
 
                                                        "windows",
216
 
                                                        "ssl_server_trust",
217
 
                                                        pool),
218
 
                NULL);
219
 
 
220
 
    if (provider)
221
 
        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
222
 
 
223
 
    svn_auth_get_ssl_server_trust_file_provider(&provider, pool);
224
 
    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
225
 
    svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
226
 
    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
227
 
    svn_auth_get_ssl_client_cert_pw_file_provider2(&provider,
228
 
                        plaintext_passphrase_prompt_func,
229
 
                        plaintext_passphrase_prompt_baton, pool);
230
 
    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
231
 
 
232
 
    if (m_prompter != NULL)
233
 
    {
234
 
        /* Two basic prompt providers: username/password, and just username.*/
235
 
        provider = m_prompter->getProviderSimple(in_pool);
236
 
 
237
 
        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
238
 
 
239
 
        provider = m_prompter->getProviderUsername(in_pool);
240
 
        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
241
 
 
242
 
        /* Three ssl prompt providers, for server-certs, client-certs,
243
 
         * and client-cert-passphrases.  */
244
 
        provider = m_prompter->getProviderServerSSLTrust(in_pool);
245
 
        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
246
 
 
247
 
        provider = m_prompter->getProviderClientSSL(in_pool);
248
 
        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
249
 
 
250
 
        provider = m_prompter->getProviderClientSSLPassword(in_pool);
251
 
        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
252
 
    }
253
 
 
254
 
    /* Build an authentication baton to give to libsvn_client. */
255
 
    svn_auth_open(&ab, providers, pool);
256
 
 
257
 
    /* Place any default --username or --password credentials into the
258
 
     * auth_baton's run-time parameter hash.  ### Same with --no-auth-cache? */
259
 
    if (!m_userName.empty())
260
 
        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME,
261
 
                               apr_pstrdup(in_pool.getPool(),
262
 
                                           m_userName.c_str()));
263
 
    if (!m_passWord.empty())
264
 
        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD,
265
 
                               apr_pstrdup(in_pool.getPool(),
266
 
                                           m_passWord.c_str()));
267
 
    /* Store where to retrieve authentication data? */
268
 
    if (!m_configDir.empty())
269
 
        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR,
270
 
                               apr_pstrdup(in_pool.getPool(),
271
 
                                           m_configDir.c_str()));
272
 
 
273
 
    ctx->auth_baton = ab;
 
157
 
 
158
    ctx->auth_baton = getAuthBaton(in_pool);
274
159
    ctx->log_msg_baton3 = message;
275
 
    m_cancelOperation = false;
 
160
    resetCancelRequest();
276
161
 
277
162
    SVN_JNI_ERR(svn_wc_context_create(&ctx->wc_ctx, NULL,
278
163
                                      in_pool.getPool(), in_pool.getPool()),
282
167
}
283
168
 
284
169
void
285
 
ClientContext::username(const char *pi_username)
286
 
{
287
 
    m_userName = (pi_username == NULL ? "" : pi_username);
288
 
}
289
 
 
290
 
void
291
 
ClientContext::password(const char *pi_password)
292
 
{
293
 
    m_passWord = (pi_password == NULL ? "" : pi_password);
294
 
}
295
 
 
296
 
void
297
 
ClientContext::setPrompt(Prompter *prompter)
298
 
{
299
 
    delete m_prompter;
300
 
    m_prompter = prompter;
301
 
}
302
 
 
303
 
void
304
 
ClientContext::setConfigDirectory(const char *configDir)
305
 
{
306
 
    // A change to the config directory may necessitate creation of
307
 
    // the config templates.
308
 
    SVN::Pool requestPool;
309
 
    SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.getPool()), );
310
 
 
311
 
    m_configDir = (configDir == NULL ? "" : configDir);
312
 
    m_context->config = NULL;
313
 
}
314
 
 
315
 
const char *
316
 
ClientContext::getConfigDirectory() const
317
 
{
318
 
    return m_configDir.c_str();
319
 
}
320
 
 
321
 
void
322
 
ClientContext::cancelOperation()
323
 
{
324
 
    m_cancelOperation = true;
325
 
}
326
 
 
327
 
svn_error_t *
328
 
ClientContext::checkCancel(void *cancelBaton)
329
 
{
330
 
    ClientContext *that = static_cast<ClientContext *>(cancelBaton);
331
 
    if (that->m_cancelOperation)
332
 
        return svn_error_create(SVN_ERR_CANCELLED, NULL,
333
 
                                _("Operation cancelled"));
334
 
    else
335
 
        return SVN_NO_ERROR;
336
 
}
337
 
 
338
 
void
339
170
ClientContext::notify(void *baton,
340
171
                      const svn_wc_notify_t *notify,
341
172
                      apr_pool_t *pool)
351
182
        return;
352
183
 
353
184
      mid = env->GetMethodID(clazz, "onNotify",
354
 
                             "(L"JAVA_PACKAGE"/ClientNotifyInformation;)V");
 
185
                             "(" JAVAHL_ARG("/ClientNotifyInformation;") ")V");
355
186
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
356
187
        return;
357
188
 
369
200
  env->DeleteLocalRef(jInfo);
370
201
}
371
202
 
372
 
void
373
 
ClientContext::progress(apr_off_t progressVal, apr_off_t total,
374
 
                        void *baton, apr_pool_t *pool)
375
 
{
376
 
  jobject jctx = (jobject) baton;
377
 
  JNIEnv *env = JNIUtil::getEnv();
378
 
 
379
 
  // Create a local frame for our references
380
 
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
381
 
  if (JNIUtil::isJavaExceptionThrown())
382
 
    return;
383
 
 
384
 
  static jmethodID mid = 0;
385
 
  if (mid == 0)
386
 
    {
387
 
      jclass clazz = env->GetObjectClass(jctx);
388
 
      if (JNIUtil::isJavaExceptionThrown())
389
 
        POP_AND_RETURN_NOTHING();
390
 
 
391
 
      mid = env->GetMethodID(clazz, "onProgress",
392
 
                             "(L"JAVA_PACKAGE"/ProgressEvent;)V");
393
 
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
394
 
        POP_AND_RETURN_NOTHING();
395
 
    }
396
 
 
397
 
  static jmethodID midCT = 0;
398
 
  jclass clazz = env->FindClass(JAVA_PACKAGE"/ProgressEvent");
399
 
  if (JNIUtil::isJavaExceptionThrown())
400
 
    POP_AND_RETURN_NOTHING();
401
 
 
402
 
  if (midCT == 0)
403
 
    {
404
 
      midCT = env->GetMethodID(clazz, "<init>", "(JJ)V");
405
 
      if (JNIUtil::isJavaExceptionThrown() || midCT == 0)
406
 
        POP_AND_RETURN_NOTHING();
407
 
    }
408
 
 
409
 
  // Call the Java method.
410
 
  jobject jevent = env->NewObject(clazz, midCT,
411
 
                                  (jlong) progressVal, (jlong) total);
412
 
  if (JNIUtil::isJavaExceptionThrown())
413
 
    POP_AND_RETURN_NOTHING();
414
 
 
415
 
  env->CallVoidMethod(jctx, mid, jevent);
416
 
 
417
 
  POP_AND_RETURN_NOTHING();
418
 
}
419
 
 
420
203
svn_error_t *
421
204
ClientContext::resolve(svn_wc_conflict_result_t **result,
422
205
                       const svn_wc_conflict_description2_t *desc,
440
223
        POP_AND_RETURN(SVN_NO_ERROR);
441
224
 
442
225
      mid = env->GetMethodID(clazz, "resolve",
443
 
                             "(L"JAVA_PACKAGE"/ConflictDescriptor;)"
444
 
                             "L"JAVA_PACKAGE"/ConflictResult;");
 
226
                             "(" JAVAHL_ARG("/ConflictDescriptor;") ")"
 
227
                             JAVAHL_ARG("/ConflictResult;"));
445
228
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
446
229
        POP_AND_RETURN(SVN_NO_ERROR);
447
230
    }
493
276
  jclass clazz = NULL;
494
277
  if (getChoice == 0 || getMergedPath == 0)
495
278
    {
496
 
      clazz = env->FindClass(JAVA_PACKAGE "/ConflictResult");
 
279
      clazz = env->FindClass(JAVAHL_CLASS("/ConflictResult"));
497
280
      if (JNIUtil::isJavaExceptionThrown())
498
281
        POP_AND_RETURN_NULL;
499
282
    }
501
284
  if (getChoice == 0)
502
285
    {
503
286
      getChoice = env->GetMethodID(clazz, "getChoice",
504
 
                                   "()L"JAVA_PACKAGE"/ConflictResult$Choice;");
 
287
                                   "()" JAVAHL_ARG("/ConflictResult$Choice;"));
505
288
      if (JNIUtil::isJavaExceptionThrown() || getChoice == 0)
506
289
        POP_AND_RETURN_NULL;
507
290
    }