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

« back to all changes in this revision

Viewing changes to subversion/mod_dav_svn/mod_dav_svn.c

  • 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:
72
72
 
73
73
/* A tri-state enum used for per directory on/off flags.  Note that
74
74
   it's important that CONF_FLAG_DEFAULT is 0 to make
75
 
   dav_svn_merge_dir_config do the right thing. */
 
75
   merge_dir_config in mod_dav_svn do the right thing. */
76
76
enum conf_flag {
77
77
  CONF_FLAG_DEFAULT,
78
78
  CONF_FLAG_ON,
105
105
  enum conf_flag txdelta_cache;      /* whether to enable txdelta caching */
106
106
  enum conf_flag fulltext_cache;     /* whether to enable fulltext caching */
107
107
  enum conf_flag revprop_cache;      /* whether to enable revprop caching */
 
108
  enum conf_flag block_read;         /* whether to enable block read mode */
108
109
  const char *hooks_env;             /* path to hook script env config file */
109
110
} dir_conf_t;
110
111
 
142
143
  return OK;
143
144
}
144
145
 
 
146
static svn_error_t *
 
147
malfunction_handler(svn_boolean_t can_return,
 
148
                    const char *file, int line,
 
149
                    const char *expr)
 
150
{
 
151
  if (expr)
 
152
    ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL,
 
153
                 "mod_dav_svn: file '%s', line %d, assertion \"%s\" failed",
 
154
                 file, line, expr);
 
155
  else
 
156
    ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL,
 
157
                 "mod_dav_svn: file '%s', line %d, internal malfunction",
 
158
                 file, line);
 
159
  abort();
 
160
 
 
161
  /* Should not be reached. */
 
162
  return SVN_NO_ERROR;
 
163
}
 
164
 
145
165
static int
146
166
init_dso(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
147
167
{
161
181
      return HTTP_INTERNAL_SERVER_ERROR;
162
182
    }
163
183
 
 
184
  svn_error_set_malfunction_handler(malfunction_handler);
 
185
 
164
186
  return OK;
165
187
}
166
188
 
215
237
  if (dir)
216
238
    conf->root_dir = svn_urlpath__canonicalize(dir, p);
217
239
  conf->bulk_updates = CONF_BULKUPD_DEFAULT;
218
 
  conf->v2_protocol = CONF_FLAG_ON;
 
240
  conf->v2_protocol = CONF_FLAG_DEFAULT;
219
241
  conf->hooks_env = NULL;
 
242
  conf->txdelta_cache = CONF_FLAG_DEFAULT;
220
243
 
221
244
  return conf;
222
245
}
247
270
  newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
248
271
  newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
249
272
  newconf->revprop_cache = INHERIT_VALUE(parent, child, revprop_cache);
 
273
  newconf->block_read = INHERIT_VALUE(parent, child, block_read);
250
274
  newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
251
275
  newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
252
276
 
543
567
}
544
568
 
545
569
static const char *
 
570
SVNBlockRead_cmd(cmd_parms *cmd, void *config, int arg)
 
571
{
 
572
  dir_conf_t *conf = config;
 
573
 
 
574
  if (arg)
 
575
    conf->block_read = CONF_FLAG_ON;
 
576
  else
 
577
    conf->block_read = CONF_FLAG_OFF;
 
578
 
 
579
  return NULL;
 
580
}
 
581
 
 
582
static const char *
546
583
SVNInMemoryCacheSize_cmd(cmd_parms *cmd, void *config, const char *arg1)
547
584
{
548
585
  svn_cache_config_t settings = *svn_cache_config_get();
612
649
  return NULL;
613
650
}
614
651
 
 
652
static svn_boolean_t
 
653
get_conf_flag(enum conf_flag flag, svn_boolean_t default_value)
 
654
{
 
655
  if (flag == CONF_FLAG_ON)
 
656
    return TRUE;
 
657
  else if (flag == CONF_FLAG_OFF)
 
658
    return FALSE;
 
659
  else /* CONF_FLAG_DEFAULT*/
 
660
    return default_value;
 
661
}
615
662
 
616
663
/** Accessor functions for the module's configuration state **/
617
664
 
636
683
 
637
684
 
638
685
AP_MODULE_DECLARE(dav_error *)
639
 
dav_svn_get_repos_path(request_rec *r,
640
 
                       const char *root_path,
641
 
                       const char **repos_path)
 
686
dav_svn_get_repos_path2(request_rec *r,
 
687
                        const char *root_path,
 
688
                        const char **repos_path,
 
689
                        apr_pool_t *pool)
642
690
{
643
691
 
644
692
  const char *fs_path;
666
714
 
667
715
  /* Split the svn URI to get the name of the repository below
668
716
     the parent path. */
669
 
  derr = dav_svn_split_uri(r, r->uri, root_path,
670
 
                           &ignored_cleaned_uri, &ignored_had_slash,
671
 
                           &repos_name,
672
 
                           &ignored_relative, &ignored_path_in_repos);
 
717
  derr = dav_svn_split_uri2(r, r->uri, root_path,
 
718
                            &ignored_cleaned_uri, &ignored_had_slash,
 
719
                            &repos_name,
 
720
                            &ignored_relative, &ignored_path_in_repos, pool);
673
721
  if (derr)
674
722
    return derr;
675
723
 
676
724
  /* Construct the full path from the parent path base directory
677
725
     and the repository name. */
678
 
  *repos_path = svn_dirent_join(fs_parent_path, repos_name, r->pool);
 
726
  *repos_path = svn_dirent_join(fs_parent_path, repos_name, pool);
679
727
  return NULL;
680
728
}
681
729
 
 
730
AP_MODULE_DECLARE(dav_error *)
 
731
dav_svn_get_repos_path(request_rec *r,
 
732
                       const char *root_path,
 
733
                       const char **repos_path)
 
734
{
 
735
  return dav_svn_get_repos_path2(r, root_path, repos_path, r->pool);
 
736
}
682
737
 
683
738
const char *
684
739
dav_svn__get_repo_name(request_rec *r)
745
800
dav_svn__get_me_resource_uri(request_rec *r)
746
801
{
747
802
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/me",
748
 
                     (char *)NULL);
 
803
                     SVN_VA_NULL);
749
804
}
750
805
 
751
806
 
753
808
dav_svn__get_rev_stub(request_rec *r)
754
809
{
755
810
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/rev",
756
 
                     (char *)NULL);
 
811
                     SVN_VA_NULL);
757
812
}
758
813
 
759
814
 
761
816
dav_svn__get_rev_root_stub(request_rec *r)
762
817
{
763
818
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/rvr",
764
 
                     (char *)NULL);
 
819
                     SVN_VA_NULL);
765
820
}
766
821
 
767
822
 
769
824
dav_svn__get_txn_stub(request_rec *r)
770
825
{
771
826
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/txn",
772
 
                     (char *)NULL);
 
827
                     SVN_VA_NULL);
773
828
}
774
829
 
775
830
 
776
831
const char *
777
832
dav_svn__get_txn_root_stub(request_rec *r)
778
833
{
779
 
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/txr", (char *)NULL);
 
834
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/txr", SVN_VA_NULL);
780
835
}
781
836
 
782
837
 
784
839
dav_svn__get_vtxn_stub(request_rec *r)
785
840
{
786
841
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/vtxn",
787
 
                     (char *)NULL);
 
842
                     SVN_VA_NULL);
788
843
}
789
844
 
790
845
 
792
847
dav_svn__get_vtxn_root_stub(request_rec *r)
793
848
{
794
849
  return apr_pstrcat(r->pool, dav_svn__get_special_uri(r), "/vtxr",
795
 
                     (char *)NULL);
 
850
                     SVN_VA_NULL);
796
851
}
797
852
 
798
853
 
828
883
  svn_boolean_t available;
829
884
 
830
885
  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
831
 
  available = conf->v2_protocol == CONF_FLAG_ON;
 
886
  available = get_conf_flag(conf->v2_protocol, TRUE);
832
887
 
833
888
  /* If our configuration says that HTTPv2 is available, but we are
834
889
     proxying requests to a master Subversion server which lacks
911
966
  dir_conf_t *conf;
912
967
 
913
968
  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
914
 
  return conf->txdelta_cache == CONF_FLAG_ON;
 
969
 
 
970
  /* txdelta caching is enabled by default. */
 
971
  return get_conf_flag(conf->txdelta_cache, TRUE);
915
972
}
916
973
 
917
974
 
935
992
}
936
993
 
937
994
 
 
995
svn_boolean_t
 
996
dav_svn__get_block_read_flag(request_rec *r)
 
997
{
 
998
  dir_conf_t *conf;
 
999
 
 
1000
  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
 
1001
  return conf->block_read == CONF_FLAG_ON;
 
1002
}
 
1003
 
938
1004
int
939
1005
dav_svn__get_compression_level(request_rec *r)
940
1006
{
984
1050
typedef struct merge_ctx_t {
985
1051
  apr_bucket_brigade *bb;
986
1052
  apr_xml_parser *parser;
987
 
  apr_pool_t *pool;
988
1053
} merge_ctx_t;
989
1054
 
990
1055
 
1014
1079
      f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx));
1015
1080
      ctx->parser = apr_xml_parser_create(r->pool);
1016
1081
      ctx->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1017
 
      apr_pool_create(&ctx->pool, r->pool);
1018
1082
    }
1019
1083
 
1020
1084
  rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes);
1103
1167
 
1104
1168
/* Fill the filename on the request with a bogus path since we aren't serving
1105
1169
 * a file off the disk.  This means that <Directory> blocks will not match and
1106
 
 * that %f in logging formats will show as "svn:/path/to/repo/path/in/repo". */
 
1170
 * %f in logging formats will show as "dav_svn:/path/to/repo/path/in/repo".
 
1171
 */
1107
1172
static int dav_svn__translate_name(request_rec *r)
1108
1173
{
1109
 
  const char *fs_path, *repos_basename, *repos_path, *slash;
 
1174
  const char *fs_path, *repos_basename, *repos_path;
1110
1175
  const char *ignore_cleaned_uri, *ignore_relative_path;
1111
1176
  int ignore_had_slash;
1112
1177
  dir_conf_t *conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
1148
1213
      fs_path = conf->fs_path;
1149
1214
    }
1150
1215
 
1151
 
  /* Avoid a trailing slash on the bogus path when repos_path is just "/" and
1152
 
   * ensure that there is always a slash between fs_path and repos_path as
1153
 
   * long as the repos_path is not an empty path. */
1154
 
  slash = "";
1155
 
  if (repos_path)
1156
 
    {
1157
 
      if ('/' == repos_path[0] && '\0' == repos_path[1])
1158
 
        repos_path = NULL;
1159
 
      else if ('/' != repos_path[0] && '\0' != repos_path[0])
1160
 
        slash = "/";
1161
 
    }
 
1216
  /* Avoid a trailing slash on the bogus path when repos_path is just "/" */
 
1217
  if (repos_path && '/' == repos_path[0] && '\0' == repos_path[1])
 
1218
    repos_path = NULL;
1162
1219
 
1163
 
  /* Combine 'svn:', fs_path and repos_path to produce the bogus path we're
 
1220
  /* Combine 'dav_svn:', fs_path and repos_path to produce the bogus path we're
1164
1221
   * placing in r->filename.  We can't use our standard join helpers such
1165
1222
   * as svn_dirent_join.  fs_path is a dirent and repos_path is a fspath
1166
1223
   * (that can be trivially converted to a relpath by skipping the leading
1168
1225
   * repository is 'trunk/c:hi' this results in a non canonical dirent on
1169
1226
   * Windows. Instead we just cat them together. */
1170
1227
  r->filename = apr_pstrcat(r->pool,
1171
 
                            "svn:", fs_path, slash, repos_path, NULL);
 
1228
                            "dav_svn:", fs_path, repos_path, SVN_VA_NULL);
1172
1229
 
1173
1230
  /* Leave a note to ourselves so that we know not to decline in the
1174
1231
   * map_to_storage hook. */
1268
1325
               ACCESS_CONF|RSRC_CONF,
1269
1326
               "speeds up data access to older revisions by caching "
1270
1327
               "delta information if sufficient in-memory cache is "
1271
 
               "available (default is Off)."),
 
1328
               "available (default is On)."),
1272
1329
 
1273
1330
  /* per directory/location */
1274
1331
  AP_INIT_FLAG("SVNCacheFullTexts", SVNCacheFullTexts_cmd, NULL,
1285
1342
               "in the documentation"
1286
1343
               "(default is Off)."),
1287
1344
 
 
1345
  /* per directory/location */
 
1346
  AP_INIT_FLAG("SVNBlockRead", SVNBlockRead_cmd, NULL,
 
1347
               ACCESS_CONF|RSRC_CONF,
 
1348
               "speeds up operations of FSFS 1.9+ repositories if large"
 
1349
               "caches (see SVNInMemoryCacheSize) have been configured."
 
1350
               "(default is Off)."),
 
1351
 
1288
1352
  /* per server */
1289
1353
  AP_INIT_TAKE1("SVNInMemoryCacheSize", SVNInMemoryCacheSize_cmd, NULL,
1290
1354
                RSRC_CONF,
1291
1355
                "specifies the maximum size in kB per process of Subversion's "
1292
 
                "in-memory object cache (default value is 16384; 0 deactivates "
1293
 
                "the cache)."),
 
1356
                "in-memory object cache (default value is 16384; 0 switches "
 
1357
                "to dynamically sized caches)."),
1294
1358
  /* per server */
1295
1359
  AP_INIT_TAKE1("SVNCompressionLevel", SVNCompressionLevel_cmd, NULL,
1296
1360
                RSRC_CONF,
1345
1409
  /* general request handler for methods which mod_dav DECLINEs. */
1346
1410
  ap_hook_handler(dav_svn__handler, NULL, NULL, APR_HOOK_LAST);
1347
1411
 
 
1412
  /* Handler to GET Subversion's FSFS cache stats, a bit like mod_status. */
 
1413
  ap_hook_handler(dav_svn__status, NULL, NULL, APR_HOOK_MIDDLE);
 
1414
 
1348
1415
  /* live property handling */
1349
1416
  dav_hook_gather_propsets(dav_svn__gather_propsets, NULL, NULL,
1350
1417
                           APR_HOOK_MIDDLE);