<t hangText='26'>This authentication was rejected due to too
many failed authentication attempts for this user. The
authentication should be retried later.</t>
+
+ <t hangText='27'>This authentication failed due to a remctl
+ timeout. The authentication should be tried again.</t>
</list>
</t>
</section>
with more information about possible factors and authentication
methods. Remove the attributes for <configuredFactor> tags,
since that approach was less flexible.</t>
+
+ <t hangText='3.7.0 (2014-09-18, jonrober)'>
+ <vspace blankLines='0'/>Add error code 27, representing a
+ remctl timeout during multifactor login.</t>
</list>
</t>
</section>
WA_PEC_AUTH_REJECTED = 24, /* Auth to this site rejected */
WA_PEC_AUTH_REPLAY = 25, /* Auth was a replay */
WA_PEC_AUTH_LOCKOUT = 26, /* Too many failed attempts */
+ WA_PEC_LOGIN_TIMEOUT = 27, /* Timeout during login */
/* Internal status codes. */
WA_ERR_INTERNAL = 1000, /* Internal error */
WA_ERR_NO_ROOM, /* Supplied buffer too small */
WA_ERR_RAND_FAILURE, /* Unable to get random data */
WA_ERR_REMOTE_FAILURE, /* A remote service call failed */
+ WA_ERR_REMOTE_TIMEOUT, /* A remote service call timed out */
WA_ERR_TOKEN_EXPIRED, /* Token has expired */
WA_ERR_TOKEN_REJECTED, /* Token used in invalid context */
WA_ERR_TOKEN_STALE, /* Token is stale */
case WA_PEC_AUTH_REPLAY:
return "authentication appears to be a replay";
case WA_PEC_AUTH_LOCKOUT: return "too many failed attempts";
+ case WA_PEC_LOGIN_TIMEOUT: return "timeout during login";
/* Internal errors. */
case WA_ERR_INTERNAL: return "internal error";
case WA_ERR_NO_ROOM: return "supplied buffer too small";
case WA_ERR_RAND_FAILURE: return "unable to get random data";
case WA_ERR_REMOTE_FAILURE: return "remote call failed";
+ case WA_ERR_REMOTE_TIMEOUT: return "remote call timed out";
case WA_ERR_TOKEN_EXPIRED: return "token has expired";
case WA_ERR_TOKEN_REJECTED: return "token used in invalid context";
case WA_ERR_TOKEN_STALE: return "token is stale";
/* Set up and execute the command. */
if (!remctl_open(r, c->host, c->port, c->identity)) {
- s = WA_ERR_REMOTE_FAILURE;
+ if (strstr(remctl_error(r), "timed out") != NULL)
+ s = WA_ERR_REMOTE_TIMEOUT;
+ else
+ s = WA_ERR_REMOTE_FAILURE;
wai_error_set(ctx, s, "%s", remctl_error(r));
goto fail;
}
if (!remctl_command(r, command)) {
- s = WA_ERR_REMOTE_FAILURE;
+ if (strstr(remctl_error(r), "timed out") != NULL)
+ s = WA_ERR_REMOTE_TIMEOUT;
+ else
+ s = WA_ERR_REMOTE_FAILURE;
wai_error_set(ctx, s, "%s", remctl_error(r));
goto fail;
}
do {
out = remctl_output(r);
if (out == NULL) {
- s = WA_ERR_REMOTE_FAILURE;
+ if (strstr(remctl_error(r), "timed out") != NULL)
+ s = WA_ERR_REMOTE_TIMEOUT;
+ else
+ s = WA_ERR_REMOTE_FAILURE;
wai_error_set(ctx, s, "%s", remctl_error(r));
goto fail;
}
wai_buffer_append(buffer, out->data, out->length);
break;
case REMCTL_OUT_ERROR:
- s = WA_ERR_REMOTE_FAILURE;
+ if (strstr(remctl_error(r), "timed out") != NULL)
+ s = WA_ERR_REMOTE_TIMEOUT;
+ else
+ s = WA_ERR_REMOTE_FAILURE;
wai_buffer_set(errors, out->data, out->length);
wai_error_set(ctx, s, "%s", errors->data);
goto fail;
out->status);
if (wai_buffer_find_string(errors, "\n", 0, &offset))
errors->data[offset] = '\0';
- s = WA_ERR_REMOTE_FAILURE;
+ if (strstr(remctl_error(r), "timed out") != NULL)
+ s = WA_ERR_REMOTE_TIMEOUT;
+ else
+ s = WA_ERR_REMOTE_FAILURE;
wai_error_set(ctx, s, "%s", errors->data);
goto fail;
}
else
s = wai_user_info_xml(ctx, user, ip, random_mf, url, factors, info);
+ /* Map a timeout to a general failure for userinfo. */
+ if (s == WA_ERR_REMOTE_TIMEOUT)
+ s = WA_ERR_REMOTE_FAILURE;
+
/*
* If the call succeeded and random_multifactor was set, say that the
* random multifactor check passed. If the call failed but we were told
result);
else
s = wai_user_validate_xml(ctx, user, ip, code, type, state, result);
+
+ /* Map a timeout to a protocol error for validation. */
+ if (s == WA_ERR_REMOTE_TIMEOUT)
+ s = WA_PEC_LOGIN_TIMEOUT;
+
return s;
}
IV_CONST(WA_PEC_AUTH_REJECTED);
IV_CONST(WA_PEC_AUTH_REPLAY);
IV_CONST(WA_PEC_AUTH_LOCKOUT);
+ IV_CONST(WA_PEC_LOGIN_TIMEOUT);
/* Key types. */
IV_CONST(WA_KEY_AES);
&WA_PEC_AUTH_REJECTED => WK_ERR_AUTH_REJECTED,
&WA_PEC_AUTH_REPLAY => WK_ERR_AUTH_REPLAY,
&WA_PEC_AUTH_LOCKOUT => WK_ERR_AUTH_LOCKOUT,
+ &WA_PEC_LOGIN_TIMEOUT => WK_ERR_LOGIN_TIMEOUT,
);
# Get a keyring from the configured WebLogin keyring path. This used to
WK_ERR_LOA_UNAVAILABLE
WK_ERR_AUTH_REJECTED
WK_ERR_AUTH_REPLAY
- WK_ERR_AUTH_LOCKOUT);
+ WK_ERR_AUTH_LOCKOUT
+ WK_ERR_LOGIN_TIMEOUT);
}
# This hash maps the error codes to names, used when stringifying.
sub WK_ERR_AUTH_REJECTED () { 13 }
sub WK_ERR_AUTH_REPLAY () { 14 }
sub WK_ERR_AUTH_LOCKOUT () { 15 }
+sub WK_ERR_LOGIN_TIMEOUT () { 16 }
# Create a new WebKDC::WebKDCException object and initialize the status,
# message, protocol error, and data.
This account has been locked out due to too many unsuccessful login
attempts. The login should be retried later.
+=item WK_ERR_LOGIN_TIMEOUT
+
+There was a timeout while attempting to log in. The login should be
+retried, though multiple errors could mean a problem outside of WebAuth.
+
=back
=head1 CLASS METHODS
print STDERR "multifactor rejected: $error ($status): $message\n"
if $self->param ('logging');
$self->register_auth_fail ($req->user);
-
- # We will get this if there is a webkdc timeout for an out-of-band
- # authentication. Matching on this isn't optimal because it could be
- # other things, but for right now build from here. Do not log an
- # auth fail for this.
- } elsif ($status == WK_ERR_UNRECOVERABLE_ERROR) {
+ } elsif ($status == WK_ERR_LOGIN_TIMEOUT) {
print STDERR "multifactor timeout: $error ($status)\n"
if $self->param ('logging');
+ $self->template_params ({err_multifactor_timeout => 1});
} else {
# Hopefully this is close enough that we can just use the default