You can customise error text/documents with Apache (http://httpd.apache.org/docs/current/custom-error.html) but that wouldn't help you here.
The error messages are embedded in to the client source (subversion/libsvn_ra_serf/util.c
):
svn_ra_serf__error_on_status(serf_status_line sline,
const char *path,
const char *location)
{
switch(sline.code)
{
case 301:
case 302:
case 307:
return svn_error_createf(SVN_ERR_RA_DAV_RELOCATED, NULL,
(sline.code == 301)
? _("Repository moved permanently to '%s';"
" please relocate")
: _("Repository moved temporarily to '%s';"
" please relocate"), location);
case 403:
return svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN, NULL,
_("Access to '%s' forbidden"), path);
Without looking, I suspect the other clients (SmartSVN, Tortoise) use the same or very similar HTTP client libraries, so you'd have the same problem: there's no facility for routing custom error messages from the server through to the client when the client is denied by password failure or authz.
However, if this is something you really need, then you might be able to special case the necessary path in the pre-commit
hook, since when a hook script exists with a non-zero status, the contents of stdout
are fed back to the user and you can have it say whatever you like.
The problem there is that the request would have had to be authenticated first, so a solution like this would likely break on your permission model unless it was for a very specific, single case. (You could always customise the client, but I suspect that's further than you'd be willing to go for this)