[krb5/f20] Pull in changes to OTP that postdate the backport

Nalin Dahyabhai nalin at fedoraproject.org
Tue Dec 17 22:01:18 UTC 2013


commit 9f751be356f337298c8d55d246f8aa35cafa6346
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date:   Tue Dec 17 16:59:50 2013 -0500

    Pull in changes to OTP that postdate the backport
    
    - backport additional changes to libkrad to make it function more like
      the version in upstream 1.12, and a few things in the OTP plugin as well
      (most visibly, that the secret that's shared with the RADIUS server is read
      from a file rather than used directly) (#1040056)

 krb5-1.11.3-otp2.patch   |  699 ++++++++++++++++++++++++++++++++++++++++++++++
 krb5.spec                |   10 +-
 persistent_keyring.patch |   16 +-
 3 files changed, 710 insertions(+), 15 deletions(-)
---
diff --git a/krb5-1.11.3-otp2.patch b/krb5-1.11.3-otp2.patch
new file mode 100644
index 0000000..da8d79a
--- /dev/null
+++ b/krb5-1.11.3-otp2.patch
@@ -0,0 +1,699 @@
+A couple of other changes that were made for OTP support when it was merged,
+extracted and applied after the OTP backport:
+* Read the secret that we share with the RADIUS server from the file named by
+  the "secret" configuration setting.
+* Log an error if we can't parse the OTP configuration string for a given
+  principal entry.
+* Pass back the error code if attempting to read the OTP configuration string
+  for an entry produces one.
+* When setting the remote address on the socket we're using to talk to the
+  RADIUS server, wait for the non-blocking connect() to complete by waiting
+  for it to become writable instead of readable.
+--- krb5-1.11.3/src/include/k5-int.h
++++ krb5-1.11.3/src/include/k5-int.h
+@@ -2612,6 +2612,17 @@ k5memdup(const void *in, size_t len, krb
+     return ptr;
+ }
+ 
++/* Like k5memdup, but add a final null byte. */
++static inline void *
++k5memdup0(const void *in, size_t len, krb5_error_code *code)
++{
++    void *ptr = k5alloc(len + 1, code);
++
++    if (ptr != NULL)
++        memcpy(ptr, in, len);
++    return ptr;
++}
++
+ krb5_error_code KRB5_CALLCONV
+ krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
+                               krb5_ccache ccache,
+--- krb5-1.11.3/src/plugins/preauth/otp/otp_state.c
++++ krb5-1.11.3/src/plugins/preauth/otp/otp_state.c
+@@ -43,6 +43,7 @@
+ #define DEFAULT_SOCKET_FMT KDC_DIR "/%s.socket"
+ #define DEFAULT_TIMEOUT 5
+ #define DEFAULT_RETRIES 3
++#define MAX_SECRET_LEN 1024
+ 
+ typedef struct token_type_st {
+     char *name;
+@@ -76,6 +77,52 @@ struct otp_state_st {
+ 
+ static void request_send(request *req);
+ 
++static krb5_error_code
++read_secret_file(const char *secret_file, char **secret)
++{
++    char buf[MAX_SECRET_LEN];
++    krb5_error_code retval;
++    char *filename;
++    FILE *file;
++    int i, j;
++
++    *secret = NULL;
++
++    retval = k5_path_join(KDC_DIR, secret_file, &filename);
++    if (retval != 0) {
++        com_err("otp", retval, "Unable to resolve secret file '%s'", filename);
++        return retval;
++    }
++
++    file = fopen(filename, "r");
++    if (file == NULL) {
++        retval = errno;
++        com_err("otp", retval, "Unable to open secret file '%s'", filename);
++        return retval;
++    }
++
++    if (fgets(buf, sizeof(buf), file) == NULL)
++        retval = EIO;
++    fclose(file);
++    if (retval != 0) {
++        com_err("otp", retval, "Unable to read secret file '%s'", filename);
++        return retval;
++    }
++
++    /* Strip whitespace. */
++    for (i = 0; buf[i] != '\0'; i++) {
++        if (!isspace(buf[i]))
++            break;
++    }
++    for (j = strlen(buf) - i; j > 0; j--) {
++        if (!isspace(buf[j - 1]))
++            break;
++    }
++
++    *secret = k5memdup0(&buf[i], j - i, &retval);
++    return retval;
++}
++
+ /* Free the contents of a single token type. */
+ static void
+ token_type_free(token_type *type)
+@@ -125,8 +172,7 @@ static krb5_error_code
+ token_type_decode(profile_t profile, const char *name, token_type *out)
+ {
+     krb5_error_code retval;
+-    char *server = NULL, *name_copy = NULL, *secret = NULL;
+-    const char *default_secret;
++    char *server = NULL, *name_copy = NULL, *secret = NULL, *pstr = NULL;
+     int strip_realm, timeout, retries;
+ 
+     memset(out, 0, sizeof(*out));
+@@ -152,16 +198,27 @@ token_type_decode(profile_t profile, con
+     }
+ 
+     /* Get the secret (optional for Unix-domain sockets). */
+-    default_secret = (*server == '/') ? "" : NULL;
+-    retval = profile_get_string(profile, "otp", name, "secret", default_secret,
+-                                &secret);
++    retval = profile_get_string(profile, "otp", name, "secret", NULL, &pstr);
+     if (retval != 0)
+         goto cleanup;
+-    if (secret == NULL) {
+-        com_err("otp", EINVAL, "Secret not specified in token type '%s'",
+-		name);
+-        retval = EINVAL;
+-        goto cleanup;
++    if (pstr != NULL) {
++        retval = read_secret_file(pstr, &secret);
++        profile_release_string(pstr);
++        if (retval != 0)
++            goto cleanup;
++    } else {
++        if (server[0] != '/') {
++            com_err("otp", EINVAL, "Secret missing (token type '%s')", name);
++            retval = EINVAL;
++            goto cleanup;
++        }
++
++        /* Use the default empty secret for UNIX domain stream sockets. */
++        secret = strdup("");
++        if (secret == NULL) {
++            retval = ENOMEM;
++            goto cleanup;
++        }
+     }
+ 
+     /* Get the timeout (profile value in seconds, result in milliseconds). */
+@@ -521,6 +578,7 @@ otp_state_verify(otp_state *state, verto
+ {
+     krb5_error_code retval;
+     request *rqst = NULL;
++    char *name;
+ 
+     if (state->radius == NULL) {
+         retval = krad_client_new(state->ctx, ctx, &state->radius);
+@@ -548,8 +606,14 @@ otp_state_verify(otp_state *state, verto
+ 
+     retval = tokens_decode(state->ctx, princ, state->types, config,
+                            &rqst->tokens);
+-    if (retval != 0)
++    if (retval != 0) {
++        if (krb5_unparse_name(state->ctx, princ, &name) == 0) {
++            com_err("otp", retval,
++                    "Can't decode otp config string for principal '%s'", name);
++            krb5_free_unparsed_name(state->ctx, name);
++        }
+         goto error;
++    }
+ 
+     request_send(rqst);
+     return;
+--- krb5-1.11.3/src/plugins/preauth/otp/main.c
++++ krb5-1.11.3/src/plugins/preauth/otp/main.c
+@@ -204,7 +204,9 @@ otp_edata(krb5_context context, krb5_kdc
+ 
+     /* Determine if otp is enabled for the user. */
+     retval = cb->get_string(context, rock, "otp", &config);
+-    if (retval != 0 || config == NULL)
++    if (retval == 0 && config == NULL)
++        retval = ENOENT;
++    if (retval != 0)
+         goto out;
+     cb->free_string(context, rock, config);
+ 
+@@ -305,7 +307,7 @@ otp_verify(krb5_context context, krb5_da
+ 
+     /* Get the principal's OTP configuration string. */
+     retval = cb->get_string(context, rock, "otp", &config);
+-    if (config == NULL)
++    if (retval == 0 && config == NULL)
+         retval = KRB5_PREAUTH_FAILED;
+     if (retval != 0) {
+         free(rs);
+--- krb5-1.11.3/src/lib/krad/remote.c
++++ krb5-1.11.3/src/lib/krad/remote.c
+@@ -36,9 +36,10 @@
+ 
+ #include <sys/un.h>
+ 
+-#define FLAGS_READ (VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_CLOSE_FD | \
+-                    VERTO_EV_FLAG_IO_ERROR | VERTO_EV_FLAG_IO_READ)
+-#define FLAGS_WRITE (FLAGS_READ | VERTO_EV_FLAG_IO_WRITE)
++#define FLAGS_NONE  VERTO_EV_FLAG_NONE
++#define FLAGS_READ  VERTO_EV_FLAG_IO_READ
++#define FLAGS_WRITE VERTO_EV_FLAG_IO_WRITE
++#define FLAGS_BASE  VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_ERROR
+ 
+ TAILQ_HEAD(request_head, request_st);
+ 
+@@ -58,6 +59,7 @@
+ struct krad_remote_st {
+     krb5_context kctx;
+     verto_ctx *vctx;
++    int fd;
+     verto_ev *io;
+     char *secret;
+     struct addrinfo *info;
+@@ -69,6 +71,9 @@
+ static void
+ on_io(verto_ctx *ctx, verto_ev *ev);
+ 
++static void
++on_timeout(verto_ctx *ctx, verto_ev *ev);
++
+ /* Iterate over the set of outstanding packets. */
+ static const krad_packet *
+ iterator(request **out)
+@@ -121,91 +126,131 @@
+     }
+ }
+ 
+-/* Handle when packets receive no response within their alloted time. */
+-static void
+-on_timeout(verto_ctx *ctx, verto_ev *ev)
++/* Start the timeout timer for the request. */
++static krb5_error_code
++request_start_timer(request *r, verto_ctx *vctx)
+ {
+-    request *req = verto_get_private(ev);
++    verto_del(r->timer);
+ 
+-    req->timer = NULL;          /* Void the timer event. */
++    r->timer = verto_add_timeout(vctx, VERTO_EV_FLAG_NONE, on_timeout,
++                                 r->timeout);
++    if (r->timer != NULL)
++        verto_set_private(r->timer, r, NULL);
+ 
+-    /* If we have more retries to perform, resend the packet. */
+-    if (req->retries-- > 1) {
+-        req->sent = 0;
+-        verto_set_flags(req->rr->io, FLAGS_WRITE);
+-        return;
+-    }
++    return (r->timer == NULL) ? ENOMEM : 0;
++}
+ 
+-    request_finish(req, ETIMEDOUT, NULL);
++/* Disconnect from the remote host. */
++static void
++remote_disconnect(krad_remote *rr)
++{
++    close(rr->fd);
++    verto_del(rr->io);
++    rr->fd = -1;
++    rr->io = NULL;
+ }
+ 
+-/* Connect to the remote host. */
++/* Add the specified flags to the remote. This automatically manages the
++ * lifecyle of the underlying event. Also connects if disconnected. */
+ static krb5_error_code
+-remote_connect(krad_remote *rr)
++remote_add_flags(krad_remote *remote, verto_ev_flag flags)
+ {
+-    int i, sock = -1;
+-    verto_ev *ev;
++    verto_ev_flag curflags = VERTO_EV_FLAG_NONE;
++    int i;
+ 
+-    sock = socket(rr->info->ai_family, rr->info->ai_socktype,
+-                  rr->info->ai_protocol);
+-    if (sock < 0)
+-        return errno;
++    flags &= (FLAGS_READ | FLAGS_WRITE);
++    if (remote == NULL || flags == FLAGS_NONE)
++        return EINVAL;
++
++    /* If there is no connection, connect. */
++    if (remote->fd < 0) {
++        verto_del(remote->io);
++        remote->io = NULL;
++
++        remote->fd = socket(remote->info->ai_family, remote->info->ai_socktype,
++                            remote->info->ai_protocol);
++        if (remote->fd < 0)
++            return errno;
+ 
+-    i = connect(sock, rr->info->ai_addr, rr->info->ai_addrlen);
+-    if (i < 0) {
+-        i = errno;
+-        close(sock);
+-        return i;
++        i = connect(remote->fd, remote->info->ai_addr,
++                    remote->info->ai_addrlen);
++        if (i < 0) {
++            i = errno;
++            remote_disconnect(remote);
++            return i;
++        }
+     }
+ 
+-    ev = verto_add_io(rr->vctx, FLAGS_READ, on_io, sock);
+-    if (ev == NULL) {
+-        close(sock);
+-        return ENOMEM;
++    if (remote->io == NULL) {
++        remote->io = verto_add_io(remote->vctx, FLAGS_BASE | flags,
++                                  on_io, remote->fd);
++        if (remote->io == NULL)
++            return ENOMEM;
++        verto_set_private(remote->io, remote, NULL);
+     }
+ 
+-    rr->io = ev;
+-    verto_set_private(rr->io, rr, NULL);
++    curflags = verto_get_flags(remote->io);
++    if ((curflags & flags) != flags)
++        verto_set_flags(remote->io, FLAGS_BASE | curflags | flags);
++
+     return 0;
+ }
+ 
+-/* Disconnect and reconnect to the remote host. */
+-static krb5_error_code
+-remote_reconnect(krad_remote *rr, int errnum)
++/* Remove the specified flags to the remote. This automatically manages the
++ * lifecyle of the underlying event. */
++static void
++remote_del_flags(krad_remote *remote, verto_ev_flag flags)
++{
++    if (remote == NULL || remote->io == NULL)
++        return;
++
++    flags = verto_get_flags(remote->io) & (FLAGS_READ | FLAGS_WRITE) & ~flags;
++    if (flags == FLAGS_NONE) {
++        verto_del(remote->io);
++        remote->io = NULL;
++        return;
++    }
++
++    verto_set_flags(remote->io, FLAGS_BASE | flags);
++}
++
++/* Close the connection and start the timers of all outstanding requests. */
++static void
++remote_shutdown(krad_remote *rr)
+ {
+     krb5_error_code retval;
+-    const krb5_data *tmp;
+     request *r;
+ 
+-    verto_del(rr->io);
+-    rr->io = NULL;
+-    retval = remote_connect(rr);
+-    if (retval != 0)
+-        return retval;
++    remote_disconnect(rr);
+ 
++    /* Start timers for all unsent packets. */
+     TAILQ_FOREACH(r, &rr->list, list) {
+-        tmp = krad_packet_encode(r->request);
+-
+-        if (r->sent == tmp->length) {
+-            /* Error out sent requests. */
+-            request_finish(r, errnum, NULL);
+-        } else {
+-            /* Reset partially sent requests. */
+-            r->sent = 0;
++        if (r->timer == NULL) {
++            retval = request_start_timer(r, rr->vctx);
++            if (retval != 0)
++                request_finish(r, retval, NULL);
+         }
+     }
+-
+-    return 0;
+ }
+ 
+-/* Close the connection and call the callbacks of all oustanding requests. */
++/* Handle when packets receive no response within their alloted time. */
+ static void
+-remote_shutdown(krad_remote *rr, int errnum)
++on_timeout(verto_ctx *ctx, verto_ev *ev)
+ {
+-    verto_del(rr->io);
+-    rr->io = NULL;
+-    while (!TAILQ_EMPTY(&rr->list))
+-        request_finish(TAILQ_FIRST(&rr->list), errnum, NULL);
++    request *req = verto_get_private(ev);
++    krb5_error_code retval = ETIMEDOUT;
++
++    req->timer = NULL;          /* Void the timer event. */
++
++    /* If we have more retries to perform, resend the packet. */
++    if (req->retries-- > 1) {
++        req->sent = 0;
++        retval = remote_add_flags(req->rr, FLAGS_WRITE);
++        if (retval == 0)
++            return;
++    }
++
++    request_finish(req, retval, NULL);
+ }
+ 
+ /* Write data to the socket. */
+@@ -213,8 +258,8 @@
+ on_io_write(krad_remote *rr)
+ {
+     const krb5_data *tmp;
++    ssize_t written;
+     request *r;
+-    int i;
+ 
+     TAILQ_FOREACH(r, &rr->list, list) {
+         tmp = krad_packet_encode(r->request);
+@@ -224,45 +269,38 @@
+             continue;
+ 
+         /* Send the packet. */
+-        i = sendto(verto_get_fd(rr->io), tmp->data + r->sent,
+-                   tmp->length - r->sent, 0, NULL, 0);
+-        if (i < 0) {
++        written = sendto(verto_get_fd(rr->io), tmp->data + r->sent,
++                         tmp->length - r->sent, 0, NULL, 0);
++        if (written < 0) {
+             /* Should we try again? */
+             if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS ||
+                 errno == EINTR)
+                 return;
+ 
+-            /* In this case, we need to re-connect. */
+-            i = remote_reconnect(rr, errno);
+-            if (i == 0)
+-                return;
+-
+-            /* Do a full reset. */
+-            remote_shutdown(rr, i);
++            /* This error can't be worked around. */
++            remote_shutdown(rr);
+             return;
+         }
+ 
+-        /* SOCK_STREAM permits partial writes. */
+-        if (rr->info->ai_socktype == SOCK_STREAM)
+-            r->sent += i;
+-        else if (i == (int)tmp->length)
+-            r->sent = i;
+-
+         /* If the packet was completely sent, set a timeout. */
++        r->sent += written;
+         if (r->sent == tmp->length) {
+-            verto_del(r->timer);
+-            r->timer = verto_add_timeout(rr->vctx, VERTO_EV_FLAG_NONE,
+-                                         on_timeout, r->timeout);
+-            if (r->timer == NULL)
++            if (request_start_timer(r, rr->vctx) != 0) {
+                 request_finish(r, ENOMEM, NULL);
+-            else
+-                verto_set_private(r->timer, r, NULL);
++                return;
++            }
++
++            if (remote_add_flags(rr, FLAGS_READ) != 0) {
++                remote_shutdown(rr);
++                return;
++            }
+         }
+ 
+         return;
+     }
+ 
+-    verto_set_flags(rr->io, FLAGS_READ);
++    remote_del_flags(rr, FLAGS_WRITE);
++    return;
+ }
+ 
+ /* Read data from the socket. */
+@@ -280,9 +318,9 @@
+     if (rr->info->ai_socktype == SOCK_STREAM) {
+         pktlen = krad_packet_bytes_needed(&rr->buffer);
+         if (pktlen < 0) {
+-            retval = remote_reconnect(rr, EBADMSG);
+-            if (retval != 0)
+-                remote_shutdown(rr, retval);
++            /* If we received a malformed packet on a stream socket,
++             * assume the socket to be unrecoverable. */
++            remote_shutdown(rr);
+             return;
+         }
+     }
+@@ -295,26 +333,11 @@
+         if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
+             return;
+ 
+-        if (errno == ECONNREFUSED || errno == ECONNRESET ||
+-            errno == ENOTCONN) {
+-            /*
+-             * When doing UDP against a local socket, the kernel will notify
+-             * when the daemon closes. But not against remote sockets. We want
+-             * to treat them both the same. Returning here will cause an
+-             * eventual timeout.
+-             */
+-            if (rr->info->ai_socktype != SOCK_STREAM)
+-                return;
+-        }
+-
+-        /* In this case, we need to re-connect. */
+-        i = remote_reconnect(rr, errno);
+-        if (i == 0)
+-           return;
+-
+-        /* Do a full reset. */
+-        remote_shutdown(rr, i);
++        /* The socket is unrecoverable. */
++        remote_shutdown(rr);
+         return;
++    } else if (i == 0) {
++        remote_del_flags(rr, FLAGS_READ);
+     }
+ 
+     /* If we have a partial read or just the header, try again. */
+@@ -374,6 +397,7 @@
+     tmp->vctx = vctx;
+     tmp->buffer = make_data(tmp->buffer_, 0);
+     TAILQ_INIT(&tmp->list);
++    tmp->fd = -1;
+ 
+     tmp->secret = strdup(secret);
+     if (tmp->secret == NULL)
+@@ -389,10 +413,6 @@
+     tmp->info->ai_next = NULL;
+     tmp->info->ai_canonname = NULL;
+ 
+-    retval = remote_connect(tmp);
+-    if (retval != 0)
+-        goto error;
+-
+     *rr = tmp;
+     return 0;
+ 
+@@ -414,7 +434,7 @@
+     if (rr->info != NULL)
+         free(rr->info->ai_addr);
+     free(rr->info);
+-    verto_del(rr->io);
++    remote_disconnect(rr);
+     free(rr);
+ }
+ 
+@@ -440,21 +460,14 @@
+         }
+     }
+ 
+-    if (rr->io == NULL) {
+-        retval = remote_connect(rr);
+-        if (retval != 0)
+-            goto error;
+-    }
+-
+-    if (rr->info->ai_socktype == SOCK_STREAM)
+-        retries = 0;
+     timeout = timeout / (retries + 1);
+     retval = request_new(rr, tmp, timeout, retries, cb, data, &r);
+     if (retval != 0)
+         goto error;
+ 
+-    if ((verto_get_flags(rr->io) & VERTO_EV_FLAG_IO_WRITE) == 0)
+-        verto_set_flags(rr->io, FLAGS_WRITE);
++    retval = remote_add_flags(rr, FLAGS_WRITE);
++    if (retval != 0)
++        goto error;
+ 
+     TAILQ_INSERT_TAIL(&rr->list, r, list);
+     if (pkt != NULL)
+--- krb5-1.11.3/src/lib/krad/t_attr.c
++++ krb5-1.11.3/src/lib/krad/t_attr.c
+@@ -29,7 +29,7 @@
+ 
+ #include "t_test.h"
+ 
+-const static char encoded[] = {
++const static unsigned char encoded[] = {
+     0xba, 0xfc, 0xed, 0x50, 0xe1, 0xeb, 0xa6, 0xc3,
+     0xc1, 0x75, 0x20, 0xe9, 0x10, 0xce, 0xc2, 0xcb
+ };
+--- krb5-1.11.3/src/lib/krad/t_attrset.c
++++ krb5-1.11.3/src/lib/krad/t_attrset.c
+@@ -34,7 +34,7 @@
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ 
+-const static char encpass[] = {
++const static unsigned char encpass[] = {
+     0x58, 0x8d, 0xff, 0xda, 0x37, 0xf9, 0xe4, 0xca,
+     0x19, 0xae, 0x49, 0xb7, 0x16, 0x6d, 0x58, 0x27
+ };
+--- krb5-1.11.3/src/lib/krad/t_daemon.h
++++ krb5-1.11.3/src/lib/krad/t_daemon.h
+@@ -51,8 +51,8 @@
+ static krb5_boolean
+ daemon_start(int argc, const char **argv)
+ {
+-    sigset_t set;
+-    int sig;
++    int fds[2];
++    char buf[1];
+ 
+     if (argc != 3 || argv == NULL)
+         return FALSE;
+@@ -60,30 +60,23 @@
+     if (daemon_pid != 0)
+         return TRUE;
+ 
+-    if (sigemptyset(&set) != 0)
+-        return FALSE;
+-
+-    if (sigaddset(&set, SIGUSR1) != 0)
+-        return FALSE;
+-
+-    if (sigaddset(&set, SIGCHLD) != 0)
+-        return FALSE;
+-
+-    if (sigprocmask(SIG_BLOCK, &set, NULL) != 0)
++    if (pipe(fds) != 0)
+         return FALSE;
+ 
++    /* Start the child process with the write end of the pipe as stdout. */
+     daemon_pid = fork();
+     if (daemon_pid == 0) {
+-        close(STDOUT_FILENO);
+-        open("/dev/null", O_WRONLY);
++        dup2(fds[1], STDOUT_FILENO);
++        close(fds[0]);
++        close(fds[1]);
+         exit(execlp(argv[1], argv[1], argv[2], NULL));
+     }
++    close(fds[1]);
+ 
+-    if (sigwait(&set, &sig) != 0 || sig == SIGCHLD) {
+-        daemon_stop();
+-        daemon_pid = 0;
++    /* The child will write a sentinel character when it is listening. */
++    if (read(fds[0], buf, 1) != 1 || *buf != '~')
+         return FALSE;
+-    }
++    close(fds[0]);
+ 
+     atexit(daemon_stop);
+     return TRUE;
+--- krb5-1.11.3/src/lib/krad/t_daemon.py
++++ krb5-1.11.3/src/lib/krad/t_daemon.py
+@@ -33,7 +33,7 @@
+ try:
+     from pyrad import dictionary, packet, server
+ except ImportError:
+-    sys.stdout.write("pyrad not found!\n")
++    sys.stderr.write("pyrad not found!\n")
+     sys.exit(0)
+ 
+ # We could use a dictionary file, but since we need
+@@ -49,28 +49,25 @@
+         server.Server._HandleAuthPacket(self, pkt)
+ 
+         passwd = []
+-  
+-        print "Request: "
++
+         for key in pkt.keys():
+             if key == "User-Password":
+                 passwd = map(pkt.PwDecrypt, pkt[key])
+-                print "\t%s\t%s" % (key, passwd)
+-            else:
+-                print "\t%s\t%s" % (key, pkt[key])
+-  
++
+         reply = self.CreateReplyPacket(pkt)
+         if passwd == ['accept']:
+             reply.code = packet.AccessAccept
+-            print "Response: %s" % "Access-Accept"
+         else:
+             reply.code = packet.AccessReject
+-            print "Response: %s" % "Access-Reject"
+-        print
+         self.SendReplyPacket(pkt.fd, reply)
+ 
+ srv = TestServer(addresses=["localhost"],
+                  hosts={"127.0.0.1":
+                         server.RemoteHost("127.0.0.1", "foo", "localhost")},
+                  dict=dictionary.Dictionary(StringIO.StringIO(DICTIONARY)))
+-os.kill(os.getppid(), signal.SIGUSR1)
++
++# Write a sentinel character to let the parent process know we're listening.
++sys.stdout.write("~")
++sys.stdout.flush()
++
+ srv.Run()
diff --git a/krb5.spec b/krb5.spec
index 41c70d3..eee950d 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -41,7 +41,7 @@
 Summary: The Kerberos network authentication system
 Name: krb5
 Version: 1.11.3
-Release: 33%{?dist}
+Release: 34%{?dist}
 # Maybe we should explode from the now-available-to-everybody tarball instead?
 # http://web.mit.edu/kerberos/dist/krb5/1.11/krb5-1.11.3-signed.tar
 Source0: krb5-%{version}.tar.gz
@@ -117,6 +117,7 @@ Patch143: krb5-master-keyring-expiration.patch
 # Patches for otp plugin backport
 Patch201: krb5-1.11.2-keycheck.patch
 Patch202: krb5-1.11.2-otp.patch
+Patch203: krb5-1.11.3-otp2.patch
 
 # Patches for kernel-persistent-keyring support (backport)
 Patch301: persistent_keyring.patch
@@ -368,6 +369,7 @@ ln -s NOTICE LICENSE
 
 %patch201 -p1 -b .keycheck
 %patch202 -p1 -b .otp
+%patch203 -p1 -b .otp2
 
 # Take the execute bit off of documentation.
 chmod -x doc/krb5-protocol/*.txt
@@ -1016,6 +1018,12 @@ exit 0
 %{_sbindir}/uuserver
 
 %changelog
+* Tue Dec 17 2013 Nalin Dahyabhai <nalin at redhat.com> - 1.11.3-34
+- backport additional changes to libkrad to make it function more like
+  the version in upstream 1.12, and a few things in the OTP plugin as well
+  (most visibly, that the secret that's shared with the RADIUS server is read
+  from a file rather than used directly) (#1040056)
+
 * Mon Nov 18 2013 Nalin Dahyabhai <nalin at redhat.com> - 1.11.3-33
 - backport fix to not spin on a short read when reading the length of a
   response over TCP (RT#7508, #1029674)
diff --git a/persistent_keyring.patch b/persistent_keyring.patch
index 863774c..2e625b8 100644
--- a/persistent_keyring.patch
+++ b/persistent_keyring.patch
@@ -1,5 +1,4 @@
-Pared down from the git commits, with a local copy of k5memdup0() added in
-to cc_keyring, and a wrapper 'run' in to k5test.py.
+Pared down from the git commits, with a wrapper 'run' added to k5test.py.
 
 diff --git a/src/aclocal.m4 b/src/aclocal.m4
 index 2c17e46..7be77c2 100644
@@ -238,7 +237,7 @@ index fd1bcec..795ccd6 100644
  } krb5_krcc_bc;
  
  /* Global mutex */
-@@ -258,6 +311,29 @@ static krb5_error_code KRB5_CALLCONV krb5_krcc_lock
+@@ -258,6 +311,18 @@ static krb5_error_code KRB5_CALLCONV krb5_krcc_lock
  static krb5_error_code KRB5_CALLCONV krb5_krcc_unlock
  (krb5_context context, krb5_ccache id);
  
@@ -254,17 +253,6 @@ index fd1bcec..795ccd6 100644
 +static krb5_error_code KRB5_CALLCONV krb5_krcc_switch_to
 +(krb5_context context, krb5_ccache cache);
 +
-+/* Like k5memdup, but add a final null byte. */
-+static inline void *
-+k5memdup0(const void *in, size_t len, krb5_error_code *code)
-+{
-+    void *ptr = k5alloc(len + 1, code);
-+
-+    if (ptr != NULL && len > 0)
-+        memcpy(ptr, in, len);
-+    return ptr;
-+}
-+
  /*
   * Internal utility functions
   */


More information about the scm-commits mailing list