Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309825
b: refs/heads/master
c: c52226d
h: refs/heads/master
i:
  309823: 457727d
v: v3
  • Loading branch information
J. Bruce Fields committed Jun 1, 2012
1 parent a3ec381 commit dc3475e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e7a0444aef4a1649bc155fd5c6d6ab3f8bdc88ab
refs/heads/master: c52226daf553b21891f39777d78a54ea4e7e8654
61 changes: 45 additions & 16 deletions trunk/net/sunrpc/auth_gss/gss_krb5_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,21 +381,53 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
}

/*
* We cannot currently handle tokens with rotated data. We need a
* generalized routine to rotate the data in place. It is anticipated
* that we won't encounter rotated data in the general case.
* We can shift data by up to LOCAL_BUF_LEN bytes in a pass. If we need
* to do more than that, we shift repeatedly. Kevin Coffman reports
* seeing 28 bytes as the value used by Microsoft clients and servers
* with AES, so this constant is chosen to allow handling 28 in one pass
* without using too much stack space.
*
* If that proves to a problem perhaps we could use a more clever
* algorithm.
*/
static u32
rotate_left(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, u16 rrc)
#define LOCAL_BUF_LEN 32u

static void rotate_buf_a_little(struct xdr_buf *buf, unsigned int shift)
{
unsigned int realrrc = rrc % (buf->len - offset - GSS_KRB5_TOK_HDR_LEN);
char head[LOCAL_BUF_LEN];
char tmp[LOCAL_BUF_LEN];
unsigned int this_len, i;

BUG_ON(shift > LOCAL_BUF_LEN);

if (realrrc == 0)
return 0;
read_bytes_from_xdr_buf(buf, 0, head, shift);
for (i = 0; i + shift < buf->len; i += LOCAL_BUF_LEN) {
this_len = min(LOCAL_BUF_LEN, buf->len - (i + shift));
read_bytes_from_xdr_buf(buf, i+shift, tmp, this_len);
write_bytes_to_xdr_buf(buf, i, tmp, this_len);
}
write_bytes_to_xdr_buf(buf, buf->len - shift, head, shift);
}

dprintk("%s: cannot process token with rotated data: "
"rrc %u, realrrc %u\n", __func__, rrc, realrrc);
return 1;
static void _rotate_left(struct xdr_buf *buf, unsigned int shift)
{
int shifted = 0;
int this_shift;

shift %= buf->len;
while (shifted < shift) {
this_shift = min(shift - shifted, LOCAL_BUF_LEN);
rotate_buf_a_little(buf, this_shift);
shifted += this_shift;
}
}

static void rotate_left(u32 base, struct xdr_buf *buf, unsigned int shift)
{
struct xdr_buf subbuf;

xdr_buf_subsegment(buf, &subbuf, base, buf->len - base);
_rotate_left(&subbuf, shift);
}

static u32
Expand Down Expand Up @@ -495,11 +527,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)

seqnum = be64_to_cpup((__be64 *)(ptr + 8));

if (rrc != 0) {
err = rotate_left(kctx, offset, buf, rrc);
if (err)
return GSS_S_FAILURE;
}
if (rrc != 0)
rotate_left(offset + 16, buf, rrc);

err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf,
&headskip, &tailskip);
Expand Down

0 comments on commit dc3475e

Please sign in to comment.