#include <stdio.h>
#include <stdarg.h>
-#define MODAUTHKERB_VERSION "5.3"
+#define MODAUTHKERB_VERSION "5.4"
#define MECH_NEGOTIATE "Negotiate"
#define SERVICE_NAME "HTTP"
+#include <ap_provider.h>
+#include <mod_auth.h>
#include <httpd.h>
#include <http_config.h>
#include <http_core.h>
char *krb_auth_realms;
int krb_save_credentials;
int krb_verify_kdc;
- char *krb_service_name;
+ const char *krb_service_name;
int krb_authoritative;
int krb_delegate_basic;
#if 0
const char *auth_line)
{
int ret;
- const char *sent_pw;
+ char *sent_pw;
const char *sent_name;
char *sent_instance;
char tkt_file[32];
return OK;
}
-
static int
authenticate_user_krb5pwd(request_rec *r,
kerb_auth_config *conf,
const char *auth_line)
{
const char *sent_pw = NULL;
- char *sent_name = NULL;
+ const char *sent_name = NULL;
const char *realms = NULL;
const char *realm = NULL;
krb5_context kcontext = NULL;
token.length = strlen(buf) + 1;
major_status = gss_import_name(&minor_status, &token,
- (have_server_princ) ? GSS_KRB5_NT_PRINCIPAL_NAME : GSS_C_NT_HOSTBASED_SERVICE,
+ (have_server_princ) ? (gss_OID) GSS_KRB5_NT_PRINCIPAL_NAME : (gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
&server_name);
memset(&token, 0, sizeof(token));
if (GSS_ERROR(major_status)) {
gss_accept_sec_context_spnego : gss_accept_sec_context;
#endif
- log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Verifying client data using %s",
+ log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Verifying client data using KRB5 GSS-API %s",
(accept_sec_token == gss_accept_sec_context)
- ? "KRB5 GSS-API"
- : "SPNEGO GSS-API");
+ ? ""
+ : "with our SPNEGO lib");
major_status = accept_sec_token(&minor_status,
&context,
&delegated_cred);
log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"Client %s us their credential",
- (ret_flags & GSS_C_DELEG_FLAG) ? "sent" : "didn't send");
+ (ret_flags & GSS_C_DELEG_FLAG) ? "delegated" : "didn't delegate");
if (output_token.length) {
char *token = NULL;
size_t len;
already_succeeded(request_rec *r, char *auth_line)
{
krb5_conn_data *conn_data;
- const char keyname[1024];
+ char keyname[1024];
snprintf(keyname, sizeof(keyname) - 1,
"mod_auth_kerb::connection::%s::%ld", r->connection->remote_ip,
r->connection->id);
- if (apr_pool_userdata_get(&conn_data, keyname, r->connection->pool) != 0)
+ if (apr_pool_userdata_get((void**)&conn_data, keyname, r->connection->pool) != 0)
return NULL;
if(conn_data) {
#endif
}
+static authn_status authn_krb_password(request_rec *r, const char *user,
+ const char *password)
+{
+kerb_auth_config *conf =
+ (kerb_auth_config *) ap_get_module_config(r->per_dir_config,
+ &auth_kerb_module);
+ krb5_conn_data *prevauth = NULL;
+ const char *auth_type = NULL;
+ char *auth_line = NULL;
+ const char *type = NULL;
+ int use_krb5 = 0, use_krb4 = 0;
+ int ret;
+ static int last_return = HTTP_UNAUTHORIZED;
+ char *negotiate_ret_value = NULL;
+ char keyname[1024];
+
+ auth_line = ap_pbase64encode (r->pool, apr_psprintf(r->pool, "%s:%s", user, password));
+
+ if ( (prevauth = already_succeeded(r, auth_line)) == NULL) {
+ ret = HTTP_UNAUTHORIZED;
+
+#ifdef KRB5
+ ret = authenticate_user_krb5pwd(r, conf, auth_line);
+#endif
+
+#ifdef KRB4
+ if (ret == HTTP_UNAUTHORIZED && use_krb4 && conf->krb_method_k4pass)
+ ret = authenticate_user_krb4pwd(r, conf, auth_line);
+#endif
+
+ if (ret == HTTP_UNAUTHORIZED)
+ set_kerb_auth_headers(r, conf, use_krb4, use_krb5, negotiate_ret_value);
+
+ } else {
+ ret = prevauth->last_return;
+ MK_USER = prevauth->user;
+ MK_AUTH_TYPE = prevauth->mech;
+ }
+
+ /*
+ * save who was auth'd, if it's not already stashed.
+ */
+ if(!prevauth) {
+ prevauth = (krb5_conn_data *) apr_pcalloc(r->connection->pool, sizeof(krb5_conn_data));
+ prevauth->user = apr_pstrdup(r->connection->pool, MK_USER);
+ prevauth->authline = apr_pstrdup(r->connection->pool, auth_line);
+ prevauth->mech = apr_pstrdup(r->connection->pool, auth_type);
+ prevauth->last_return = ret;
+ snprintf(keyname, sizeof(keyname) - 1,
+ "mod_auth_kerb::connection::%s::%ld",
+ r->connection->remote_ip, r->connection->id);
+ apr_pool_userdata_set(prevauth, keyname, NULL, r->connection->pool);
+ }
+ if (ret == OK && conf->krb5_do_auth_to_local)
+ ret = do_krb5_an_to_ln(r);
+
+ last_return = ret;
+
+ if (last_return == OK) return AUTH_GRANTED;
+ else return AUTH_DENIED;
+}
+
static int
kerb_authenticate_user(request_rec *r)
{
&auth_kerb_module);
krb5_conn_data *prevauth = NULL;
const char *auth_type = NULL;
- const char *auth_line = NULL;
+ char *auth_line = NULL;
const char *type = NULL;
int use_krb5 = 0, use_krb4 = 0;
int ret;
#endif
/* get what the user sent us in the HTTP header */
- auth_line = MK_TABLE_GET(r->headers_in, (r->proxyreq == PROXYREQ_PROXY)
+ auth_line = (char *)MK_TABLE_GET(r->headers_in, (r->proxyreq == PROXYREQ_PROXY)
? "Proxy-Authorization"
: "Authorization");
if (!auth_line) {
(use_krb5) ? "\0" : NULL);
return HTTP_UNAUTHORIZED;
}
- auth_type = ap_getword_white(r->pool, &auth_line);
+ auth_type = ap_getword_white(r->pool, (const char **)&auth_line);
/* If we are delegating Basic to other modules, DECLINE the request */
if (conf->krb_delegate_basic &&
static void
kerb_register_hooks(apr_pool_t *p)
{
+ static const authn_provider authn_krb_provider = {
+ &authn_krb_password,
+ };
+
+ ap_register_provider(p, "authn", "krb", "0", &authn_krb_provider);
ap_hook_post_config(kerb_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
}