aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth_gss/auth_gss.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/auth_gss/auth_gss.c')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c204
1 files changed, 110 insertions, 94 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index b333b1bdad45..206788e8b787 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1671,59 +1671,62 @@ gss_refresh_null(struct rpc_task *task)
1671 return 0; 1671 return 0;
1672} 1672}
1673 1673
1674static __be32 * 1674static int
1675gss_validate(struct rpc_task *task, __be32 *p) 1675gss_validate(struct rpc_task *task, struct xdr_stream *xdr)
1676{ 1676{
1677 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 1677 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1678 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1678 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1679 __be32 *seq = NULL; 1679 __be32 *p, *seq = NULL;
1680 struct kvec iov; 1680 struct kvec iov;
1681 struct xdr_buf verf_buf; 1681 struct xdr_buf verf_buf;
1682 struct xdr_netobj mic; 1682 struct xdr_netobj mic;
1683 u32 flav,len; 1683 u32 len, maj_stat;
1684 u32 maj_stat; 1684 int status;
1685 __be32 *ret = ERR_PTR(-EIO);
1686 1685
1687 dprintk("RPC: %5u %s\n", task->tk_pid, __func__); 1686 p = xdr_inline_decode(xdr, 2 * sizeof(*p));
1687 if (!p)
1688 goto validate_failed;
1689 if (*p++ != rpc_auth_gss)
1690 goto validate_failed;
1691 len = be32_to_cpup(p);
1692 if (len > RPC_MAX_AUTH_SIZE)
1693 goto validate_failed;
1694 p = xdr_inline_decode(xdr, len);
1695 if (!p)
1696 goto validate_failed;
1688 1697
1689 flav = ntohl(*p++);
1690 if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
1691 goto out_bad;
1692 if (flav != RPC_AUTH_GSS)
1693 goto out_bad;
1694 seq = kmalloc(4, GFP_NOFS); 1698 seq = kmalloc(4, GFP_NOFS);
1695 if (!seq) 1699 if (!seq)
1696 goto out_bad; 1700 goto validate_failed;
1697 *seq = htonl(task->tk_rqstp->rq_seqno); 1701 *seq = cpu_to_be32(task->tk_rqstp->rq_seqno);
1698 iov.iov_base = seq; 1702 iov.iov_base = seq;
1699 iov.iov_len = 4; 1703 iov.iov_len = 4;
1700 xdr_buf_from_iov(&iov, &verf_buf); 1704 xdr_buf_from_iov(&iov, &verf_buf);
1701 mic.data = (u8 *)p; 1705 mic.data = (u8 *)p;
1702 mic.len = len; 1706 mic.len = len;
1703
1704 ret = ERR_PTR(-EACCES);
1705 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 1707 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1706 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1708 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1707 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1709 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1708 if (maj_stat) { 1710 if (maj_stat)
1709 dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n", 1711 goto bad_mic;
1710 task->tk_pid, __func__, maj_stat); 1712
1711 goto out_bad;
1712 }
1713 /* We leave it to unwrap to calculate au_rslack. For now we just 1713 /* We leave it to unwrap to calculate au_rslack. For now we just
1714 * calculate the length of the verifier: */ 1714 * calculate the length of the verifier: */
1715 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2; 1715 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1716 status = 0;
1717out:
1716 gss_put_ctx(ctx); 1718 gss_put_ctx(ctx);
1717 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1718 task->tk_pid, __func__);
1719 kfree(seq);
1720 return p + XDR_QUADLEN(len);
1721out_bad:
1722 gss_put_ctx(ctx);
1723 dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
1724 PTR_ERR(ret));
1725 kfree(seq); 1719 kfree(seq);
1726 return ret; 1720 return status;
1721
1722validate_failed:
1723 status = -EIO;
1724 goto out;
1725bad_mic:
1726 dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
1727 task->tk_pid, __func__, maj_stat);
1728 status = -EACCES;
1729 goto out;
1727} 1730}
1728 1731
1729static int gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1732static int gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
@@ -1921,79 +1924,98 @@ out:
1921 return status; 1924 return status;
1922} 1925}
1923 1926
1924static inline int 1927static int
1928gss_unwrap_resp_auth(struct rpc_cred *cred)
1929{
1930 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize;
1931 return 0;
1932}
1933
1934static int
1925gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1935gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1926 struct rpc_rqst *rqstp, __be32 **p) 1936 struct rpc_rqst *rqstp, struct xdr_stream *xdr)
1927{ 1937{
1928 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; 1938 struct xdr_buf integ_buf, *rcv_buf = &rqstp->rq_rcv_buf;
1929 struct xdr_buf integ_buf; 1939 u32 data_offset, mic_offset, integ_len, maj_stat;
1930 struct xdr_netobj mic; 1940 struct xdr_netobj mic;
1931 u32 data_offset, mic_offset; 1941 __be32 *p;
1932 u32 integ_len;
1933 u32 maj_stat;
1934 int status = -EIO;
1935 1942
1936 integ_len = ntohl(*(*p)++); 1943 p = xdr_inline_decode(xdr, 2 * sizeof(*p));
1944 if (unlikely(!p))
1945 goto unwrap_failed;
1946 integ_len = be32_to_cpup(p++);
1937 if (integ_len & 3) 1947 if (integ_len & 3)
1938 return status; 1948 goto unwrap_failed;
1939 data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base; 1949 data_offset = (u8 *)(p) - (u8 *)rcv_buf->head[0].iov_base;
1940 mic_offset = integ_len + data_offset; 1950 mic_offset = integ_len + data_offset;
1941 if (mic_offset > rcv_buf->len) 1951 if (mic_offset > rcv_buf->len)
1942 return status; 1952 goto unwrap_failed;
1943 if (ntohl(*(*p)++) != rqstp->rq_seqno) 1953 if (be32_to_cpup(p) != rqstp->rq_seqno)
1944 return status; 1954 goto unwrap_failed;
1945
1946 if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1947 mic_offset - data_offset))
1948 return status;
1949 1955
1956 if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset, integ_len))
1957 goto unwrap_failed;
1950 if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset)) 1958 if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1951 return status; 1959 goto unwrap_failed;
1952
1953 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic); 1960 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1954 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1961 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1955 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1962 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1956 if (maj_stat != GSS_S_COMPLETE) 1963 if (maj_stat != GSS_S_COMPLETE)
1957 return status; 1964 goto bad_mic;
1965
1966 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + 2 +
1967 1 + XDR_QUADLEN(mic.len);
1958 return 0; 1968 return 0;
1969unwrap_failed:
1970 return -EIO;
1971bad_mic:
1972 dprintk("RPC: %s: gss_verify_mic returned error 0x%08x\n",
1973 __func__, maj_stat);
1974 return -EIO;
1959} 1975}
1960 1976
1961static inline int 1977static int
1962gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1978gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1963 struct rpc_rqst *rqstp, __be32 **p) 1979 struct rpc_rqst *rqstp, struct xdr_stream *xdr)
1964{ 1980{
1965 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; 1981 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1966 u32 offset; 1982 struct kvec *head = rqstp->rq_rcv_buf.head;
1967 u32 opaque_len; 1983 unsigned int savedlen = rcv_buf->len;
1968 u32 maj_stat; 1984 u32 offset, opaque_len, maj_stat;
1969 int status = -EIO; 1985 __be32 *p;
1970 1986
1971 opaque_len = ntohl(*(*p)++); 1987 p = xdr_inline_decode(xdr, 2 * sizeof(*p));
1972 offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base; 1988 if (unlikely(!p))
1989 goto unwrap_failed;
1990 opaque_len = be32_to_cpup(p++);
1991 offset = (u8 *)(p) - (u8 *)head->iov_base;
1973 if (offset + opaque_len > rcv_buf->len) 1992 if (offset + opaque_len > rcv_buf->len)
1974 return status; 1993 goto unwrap_failed;
1975 /* remove padding: */
1976 rcv_buf->len = offset + opaque_len; 1994 rcv_buf->len = offset + opaque_len;
1977 1995
1978 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf); 1996 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
1979 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1997 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1980 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1998 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1981 if (maj_stat != GSS_S_COMPLETE) 1999 if (maj_stat != GSS_S_COMPLETE)
1982 return status; 2000 goto bad_unwrap;
1983 if (ntohl(*(*p)++) != rqstp->rq_seqno) 2001 /* gss_unwrap decrypted the sequence number */
1984 return status; 2002 if (be32_to_cpup(p++) != rqstp->rq_seqno)
1985 2003 goto unwrap_failed;
1986 return 0;
1987}
1988 2004
1989static int 2005 /* gss_unwrap redacts the opaque blob from the head iovec.
1990gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, 2006 * rcv_buf has changed, thus the stream needs to be reset.
1991 __be32 *p, void *obj) 2007 */
1992{ 2008 xdr_init_decode(xdr, rcv_buf, p, rqstp);
1993 struct xdr_stream xdr;
1994 2009
1995 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p, rqstp); 2010 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + 2 +
1996 return decode(rqstp, &xdr, obj); 2011 XDR_QUADLEN(savedlen - rcv_buf->len);
2012 return 0;
2013unwrap_failed:
2014 return -EIO;
2015bad_unwrap:
2016 dprintk("RPC: %s: gss_unwrap returned error 0x%08x\n",
2017 __func__, maj_stat);
2018 return -EIO;
1997} 2019}
1998 2020
1999static bool 2021static bool
@@ -2037,39 +2059,33 @@ out:
2037} 2059}
2038 2060
2039static int 2061static int
2040gss_unwrap_resp(struct rpc_task *task, 2062gss_unwrap_resp(struct rpc_task *task, struct xdr_stream *xdr)
2041 kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj)
2042{ 2063{
2043 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 2064 struct rpc_rqst *rqstp = task->tk_rqstp;
2065 struct rpc_cred *cred = rqstp->rq_cred;
2044 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 2066 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
2045 gc_base); 2067 gc_base);
2046 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 2068 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
2047 __be32 *savedp = p; 2069 int status = -EIO;
2048 struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
2049 int savedlen = head->iov_len;
2050 int status = -EIO;
2051 2070
2052 if (ctx->gc_proc != RPC_GSS_PROC_DATA) 2071 if (ctx->gc_proc != RPC_GSS_PROC_DATA)
2053 goto out_decode; 2072 goto out_decode;
2054 switch (gss_cred->gc_service) { 2073 switch (gss_cred->gc_service) {
2055 case RPC_GSS_SVC_NONE: 2074 case RPC_GSS_SVC_NONE:
2075 status = gss_unwrap_resp_auth(cred);
2056 break; 2076 break;
2057 case RPC_GSS_SVC_INTEGRITY: 2077 case RPC_GSS_SVC_INTEGRITY:
2058 status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p); 2078 status = gss_unwrap_resp_integ(cred, ctx, rqstp, xdr);
2059 if (status)
2060 goto out;
2061 break; 2079 break;
2062 case RPC_GSS_SVC_PRIVACY: 2080 case RPC_GSS_SVC_PRIVACY:
2063 status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p); 2081 status = gss_unwrap_resp_priv(cred, ctx, rqstp, xdr);
2064 if (status)
2065 goto out;
2066 break; 2082 break;
2067 } 2083 }
2068 /* take into account extra slack for integrity and privacy cases: */ 2084 if (status)
2069 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) 2085 goto out;
2070 + (savedlen - head->iov_len); 2086
2071out_decode: 2087out_decode:
2072 status = gss_unwrap_req_decode(decode, rqstp, p, obj); 2088 status = rpcauth_unwrap_resp_decode(task, xdr);
2073out: 2089out:
2074 gss_put_ctx(ctx); 2090 gss_put_ctx(ctx);
2075 dprintk("RPC: %5u %s returning %d\n", 2091 dprintk("RPC: %5u %s returning %d\n",