The target and redirect_to query args are being double-escaped in shibboleth_session_initiator_url(), as mentioned in another topic. Since around WordPress 2.2 add_query_arg() runs urlencode_deep(). The plugin says it requires >= 2.8, so it seems urlencode() could be removed from shibboleth_session_initiator_url().
function shibboleth_session_initiator_url($redirect = null) {
// first build the target URL. This is the WordPress URL the user will be returned to after Shibboleth
// is done, and will handle actually logging the user into WordPress using the data provdied by Shibboleth
if ( function_exists('switch_to_blog') ) switch_to_blog($GLOBALS['current_site']->blog_id);
$target = site_url('wp-login.php');
if ( function_exists('restore_current_blog') ) restore_current_blog();
$target = add_query_arg('action', 'shibboleth', $target);
if ( !empty($redirect) ) {
$target = add_query_arg('redirect_to', $redirect, $target);
}
// now build the Shibboleth session initiator URL
$initiator_url = shibboleth_get_option('shibboleth_login_url');
$initiator_url = add_query_arg('target', $target, $initiator_url);
$initiator_url = apply_filters('shibboleth_session_initiator_url', $initiator_url);
return $initiator_url;
}