diff --git a/lib/krb5/auth_context.c b/lib/krb5/auth_context.c index 33f4ed283..b1b67906e 100644 --- a/lib/krb5/auth_context.c +++ b/lib/krb5/auth_context.c @@ -33,6 +33,16 @@ #include "krb5_locl.h" +/** + * Allocate and initialize an autentication context. + * + * @param context A kerberos context. + * @param auth_context The authentication context to be initialized. + * + * Use krb5_auth_con_free() to release the memory when done using the context. + * + * @return An krb5 error code, see krb5_get_error_message(). + */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context) @@ -64,6 +74,15 @@ krb5_auth_con_init(krb5_context context, return 0; } +/** + * Deallocate an authentication context previously initialized with + * krb5_auth_con_init(). + * + * @param context A kerberos context. + * @param auth_context The authentication context to be deallocated. + * + * @return An krb5 error code, see krb5_get_error_message(). + */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context) @@ -154,6 +173,12 @@ krb5_auth_con_setaddrs(krb5_context context, return 0; } +/** + * Update the authentication context \a auth_context with the local + * and remote addresses from socket \a fd, according to \a flags. + * + * @return An krb5 error code, see krb5_get_error_message(). + */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_auth_con_genaddrs(krb5_context context, krb5_auth_context auth_context, diff --git a/lib/krb5/doxygen.c b/lib/krb5/doxygen.c index fec9a6719..d3ee52fe9 100644 --- a/lib/krb5/doxygen.c +++ b/lib/krb5/doxygen.c @@ -308,8 +308,8 @@ * * In this case, mutual authentication will be tried. That means that the server * will authenticate to the client. Using mutual authentication - * is good since it enables the user to verify that they are talking to the - * right server (a server that knows the key). + * is required to avoid man-in-the-middle attacks, since it enables the user to + * verify that they are talking to the right server (a server that knows the key). * * If you are using a non-blocking socket you will need to do all work of * krb5_sendauth() yourself. Basically you need to send over the diff --git a/lib/krb5/net_read.c b/lib/krb5/net_read.c index f6d781c27..70b18007e 100644 --- a/lib/krb5/net_read.c +++ b/lib/krb5/net_read.c @@ -33,6 +33,15 @@ #include "krb5_locl.h" +/** + * Read \a len bytes from socket \a p_fd into buffer \a buf. + * Block until \a len bytes are read or until an error. + * + * @return If successful, the number of bytes read: \a len. + * On end-of-file, 0. + * On error, less than 0 (if single-threaded, the error can be found + * in the errno global variable). + */ KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL krb5_net_read (krb5_context context, void *p_fd, diff --git a/lib/krb5/rd_req.c b/lib/krb5/rd_req.c index c870a0e75..78d750fb6 100644 --- a/lib/krb5/rd_req.c +++ b/lib/krb5/rd_req.c @@ -680,10 +680,22 @@ krb5_rd_req_out_ctx_free(krb5_context context, krb5_rd_req_out_ctx ctx) free(ctx); } -/* +/** + * Process an AP_REQ message. * + * @param context Kerberos 5 context. + * @param auth_context authentication context of the peer. + * @param inbuf the AP_REQ message, obtained for example with krb5_read_message(). + * @param server server principal. + * @param keytab server keytab. + * @param ap_req_options set to the AP_REQ options. See the AP_OPTS_* defines. + * @param ticket on success, set to the authenticated client credentials. + * Must be deallocated with krb5_free_ticket(). If not + * interested, pass a NULL value. + * + * @return 0 to indicate success. Otherwise a Kerberos error code is + * returned, see krb5_get_error_message(). */ - KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, @@ -822,12 +834,12 @@ out: * default values for the authentication context will used. * @param inbuf the (AP-REQ) authentication buffer * - * @param server the server with authenticate as, if NULL the function + * @param server the server to authenticate to. If NULL the function * will try to find any available credential in the keytab * that will verify the reply. The function will prefer the - * server the server client specified in the AP-REQ, but if + * server specified in the AP-REQ, but if * there is no mach, it will try all keytab entries for a - * match. This have serious performance issues for larger keytabs. + * match. This has serious performance issues for large keytabs. * * @param inctx control the behavior of the function, if NULL, the * default behavior is used. @@ -870,7 +882,7 @@ krb5_rd_req_ctx(krb5_context context, if(ret) goto out; - /* Save that principal that was in the request */ + /* Save the principal that was in the request */ ret = _krb5_principalname2krb5_principal(context, &o->server, ap_req.ticket.sname, diff --git a/lib/krb5/recvauth.c b/lib/krb5/recvauth.c index 78e98a10f..a6f1d51c9 100644 --- a/lib/krb5/recvauth.c +++ b/lib/krb5/recvauth.c @@ -43,6 +43,24 @@ match_exact(const void *data, const char *appl_version) return strcmp(data, appl_version) == 0; } +/** + * Perform the server side of the sendauth protocol. + * + * @param context Kerberos 5 context. + * @param auth_context authentication context of the peer. + * @param p_fd socket associated to the connection. + * @param appl_version server-specific string. + * @param server server principal. + * @param flags if KRB5_RECVAUTH_IGNORE_VERSION is set, skip the sendauth version + * part of the protocol. + * @param keytab server keytab. + * @param ticket on success, set to the authenticated client credentials. + * Must be deallocated with krb5_free_ticket(). If not + * interested, pass a NULL value. + * + * @return 0 to indicate success. Otherwise a Kerberos error code is + * returned, see krb5_get_error_message(). + */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_recvauth(krb5_context context, krb5_auth_context *auth_context, @@ -59,6 +77,11 @@ krb5_recvauth(krb5_context context, keytab, ticket); } +/** + * Perform the server side of the sendauth protocol like krb5_recvauth(), but support + * a user-specified callback, \a match_appl_version, to perform the match of the application + * version \a match_data. + */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_recvauth_match_version(krb5_context context, krb5_auth_context *auth_context, @@ -97,6 +120,9 @@ krb5_recvauth_match_version(krb5_context context, if (ret) return ret; + /* + * Expect SENDAUTH protocol version. + */ if(!(flags & KRB5_RECVAUTH_IGNORE_VERSION)) { n = krb5_net_read (context, p_fd, &len, 4); if (n < 0) { @@ -120,6 +146,9 @@ krb5_recvauth_match_version(krb5_context context, } } + /* + * Expect application protocol version. + */ n = krb5_net_read (context, p_fd, &len, 4); if (n < 0) { ret = errno; @@ -144,13 +173,16 @@ krb5_recvauth_match_version(krb5_context context, repl = 2; krb5_net_write (context, p_fd, &repl, 1); krb5_set_error_message(context, KRB5_SENDAUTH_BADAPPLVERS, - N_("wrong sendauth version (%s)", ""), + N_("wrong sendauth application version (%s)", ""), her_appl_version); free (her_appl_version); return KRB5_SENDAUTH_BADAPPLVERS; } free (her_appl_version); + /* + * Send OK. + */ repl = 0; if (krb5_net_write (context, p_fd, &repl, 1) != 1) { ret = errno; @@ -158,6 +190,14 @@ krb5_recvauth_match_version(krb5_context context, return ret; } + /* + * Until here, the fields in the message were in cleartext and unauthenticated. + * From now on, Kerberos kicks in. + */ + + /* + * Expect AP_REQ. + */ krb5_data_zero (&data); ret = krb5_read_message (context, p_fd, &data); if (ret) @@ -191,6 +231,9 @@ krb5_recvauth_match_version(krb5_context context, return ret; } + /* + * Send OK. + */ len = 0; if (krb5_net_write (context, p_fd, &len, 4) != 4) { ret = errno; @@ -200,6 +243,9 @@ krb5_recvauth_match_version(krb5_context context, return ret; } + /* + * If client requires mutual authentication, send AP_REP. + */ if (ap_options & AP_OPTS_MUTUAL_REQUIRED) { ret = krb5_mk_rep (context, *auth_context, &data); if (ret) {