diff options
Diffstat (limited to 'net/sunrpc/auth_gss')
-rw-r--r-- | net/sunrpc/auth_gss/Makefile | 5 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_mech.c | 247 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_seal.c | 186 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_token.c | 267 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_unseal.c | 127 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 51 |
6 files changed, 24 insertions, 859 deletions
diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile index 74a231735f67..7350d86a32ee 100644 --- a/net/sunrpc/auth_gss/Makefile +++ b/net/sunrpc/auth_gss/Makefile | |||
@@ -11,8 +11,3 @@ obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o | |||
11 | 11 | ||
12 | rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ | 12 | rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ |
13 | gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o | 13 | gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o |
14 | |||
15 | obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o | ||
16 | |||
17 | rpcsec_gss_spkm3-objs := gss_spkm3_mech.o gss_spkm3_seal.o gss_spkm3_unseal.o \ | ||
18 | gss_spkm3_token.o | ||
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c deleted file mode 100644 index adade3d313f2..000000000000 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ /dev/null | |||
@@ -1,247 +0,0 @@ | |||
1 | /* | ||
2 | * linux/net/sunrpc/gss_spkm3_mech.c | ||
3 | * | ||
4 | * Copyright (c) 2003 The Regents of the University of Michigan. | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Andy Adamson <andros@umich.edu> | ||
8 | * J. Bruce Fields <bfields@umich.edu> | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * 3. Neither the name of the University nor the names of its | ||
20 | * contributors may be used to endorse or promote products derived | ||
21 | * from this software without specific prior written permission. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
24 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
25 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
30 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
31 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
32 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | * | ||
35 | */ | ||
36 | |||
37 | #include <linux/err.h> | ||
38 | #include <linux/module.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/types.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/sunrpc/auth.h> | ||
43 | #include <linux/in.h> | ||
44 | #include <linux/sunrpc/svcauth_gss.h> | ||
45 | #include <linux/sunrpc/gss_spkm3.h> | ||
46 | #include <linux/sunrpc/xdr.h> | ||
47 | #include <linux/crypto.h> | ||
48 | |||
49 | #ifdef RPC_DEBUG | ||
50 | # define RPCDBG_FACILITY RPCDBG_AUTH | ||
51 | #endif | ||
52 | |||
53 | static const void * | ||
54 | simple_get_bytes(const void *p, const void *end, void *res, int len) | ||
55 | { | ||
56 | const void *q = (const void *)((const char *)p + len); | ||
57 | if (unlikely(q > end || q < p)) | ||
58 | return ERR_PTR(-EFAULT); | ||
59 | memcpy(res, p, len); | ||
60 | return q; | ||
61 | } | ||
62 | |||
63 | static const void * | ||
64 | simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) | ||
65 | { | ||
66 | const void *q; | ||
67 | unsigned int len; | ||
68 | p = simple_get_bytes(p, end, &len, sizeof(len)); | ||
69 | if (IS_ERR(p)) | ||
70 | return p; | ||
71 | res->len = len; | ||
72 | if (len == 0) { | ||
73 | res->data = NULL; | ||
74 | return p; | ||
75 | } | ||
76 | q = (const void *)((const char *)p + len); | ||
77 | if (unlikely(q > end || q < p)) | ||
78 | return ERR_PTR(-EFAULT); | ||
79 | res->data = kmemdup(p, len, GFP_NOFS); | ||
80 | if (unlikely(res->data == NULL)) | ||
81 | return ERR_PTR(-ENOMEM); | ||
82 | return q; | ||
83 | } | ||
84 | |||
85 | static int | ||
86 | gss_import_sec_context_spkm3(const void *p, size_t len, | ||
87 | struct gss_ctx *ctx_id, | ||
88 | gfp_t gfp_mask) | ||
89 | { | ||
90 | const void *end = (const void *)((const char *)p + len); | ||
91 | struct spkm3_ctx *ctx; | ||
92 | int version; | ||
93 | |||
94 | if (!(ctx = kzalloc(sizeof(*ctx), gfp_mask))) | ||
95 | goto out_err; | ||
96 | |||
97 | p = simple_get_bytes(p, end, &version, sizeof(version)); | ||
98 | if (IS_ERR(p)) | ||
99 | goto out_err_free_ctx; | ||
100 | if (version != 1) { | ||
101 | dprintk("RPC: unknown spkm3 token format: " | ||
102 | "obsolete nfs-utils?\n"); | ||
103 | p = ERR_PTR(-EINVAL); | ||
104 | goto out_err_free_ctx; | ||
105 | } | ||
106 | |||
107 | p = simple_get_netobj(p, end, &ctx->ctx_id); | ||
108 | if (IS_ERR(p)) | ||
109 | goto out_err_free_ctx; | ||
110 | |||
111 | p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); | ||
112 | if (IS_ERR(p)) | ||
113 | goto out_err_free_ctx_id; | ||
114 | |||
115 | p = simple_get_netobj(p, end, &ctx->mech_used); | ||
116 | if (IS_ERR(p)) | ||
117 | goto out_err_free_ctx_id; | ||
118 | |||
119 | p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags)); | ||
120 | if (IS_ERR(p)) | ||
121 | goto out_err_free_mech; | ||
122 | |||
123 | p = simple_get_netobj(p, end, &ctx->conf_alg); | ||
124 | if (IS_ERR(p)) | ||
125 | goto out_err_free_mech; | ||
126 | |||
127 | p = simple_get_netobj(p, end, &ctx->derived_conf_key); | ||
128 | if (IS_ERR(p)) | ||
129 | goto out_err_free_conf_alg; | ||
130 | |||
131 | p = simple_get_netobj(p, end, &ctx->intg_alg); | ||
132 | if (IS_ERR(p)) | ||
133 | goto out_err_free_conf_key; | ||
134 | |||
135 | p = simple_get_netobj(p, end, &ctx->derived_integ_key); | ||
136 | if (IS_ERR(p)) | ||
137 | goto out_err_free_intg_alg; | ||
138 | |||
139 | if (p != end) { | ||
140 | p = ERR_PTR(-EFAULT); | ||
141 | goto out_err_free_intg_key; | ||
142 | } | ||
143 | |||
144 | ctx_id->internal_ctx_id = ctx; | ||
145 | |||
146 | dprintk("RPC: Successfully imported new spkm context.\n"); | ||
147 | return 0; | ||
148 | |||
149 | out_err_free_intg_key: | ||
150 | kfree(ctx->derived_integ_key.data); | ||
151 | out_err_free_intg_alg: | ||
152 | kfree(ctx->intg_alg.data); | ||
153 | out_err_free_conf_key: | ||
154 | kfree(ctx->derived_conf_key.data); | ||
155 | out_err_free_conf_alg: | ||
156 | kfree(ctx->conf_alg.data); | ||
157 | out_err_free_mech: | ||
158 | kfree(ctx->mech_used.data); | ||
159 | out_err_free_ctx_id: | ||
160 | kfree(ctx->ctx_id.data); | ||
161 | out_err_free_ctx: | ||
162 | kfree(ctx); | ||
163 | out_err: | ||
164 | return PTR_ERR(p); | ||
165 | } | ||
166 | |||
167 | static void | ||
168 | gss_delete_sec_context_spkm3(void *internal_ctx) | ||
169 | { | ||
170 | struct spkm3_ctx *sctx = internal_ctx; | ||
171 | |||
172 | kfree(sctx->derived_integ_key.data); | ||
173 | kfree(sctx->intg_alg.data); | ||
174 | kfree(sctx->derived_conf_key.data); | ||
175 | kfree(sctx->conf_alg.data); | ||
176 | kfree(sctx->mech_used.data); | ||
177 | kfree(sctx->ctx_id.data); | ||
178 | kfree(sctx); | ||
179 | } | ||
180 | |||
181 | static u32 | ||
182 | gss_verify_mic_spkm3(struct gss_ctx *ctx, | ||
183 | struct xdr_buf *signbuf, | ||
184 | struct xdr_netobj *checksum) | ||
185 | { | ||
186 | u32 maj_stat = 0; | ||
187 | struct spkm3_ctx *sctx = ctx->internal_ctx_id; | ||
188 | |||
189 | maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK); | ||
190 | |||
191 | dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat); | ||
192 | return maj_stat; | ||
193 | } | ||
194 | |||
195 | static u32 | ||
196 | gss_get_mic_spkm3(struct gss_ctx *ctx, | ||
197 | struct xdr_buf *message_buffer, | ||
198 | struct xdr_netobj *message_token) | ||
199 | { | ||
200 | u32 err = 0; | ||
201 | struct spkm3_ctx *sctx = ctx->internal_ctx_id; | ||
202 | |||
203 | err = spkm3_make_token(sctx, message_buffer, | ||
204 | message_token, SPKM_MIC_TOK); | ||
205 | dprintk("RPC: gss_get_mic_spkm3 returning %d\n", err); | ||
206 | return err; | ||
207 | } | ||
208 | |||
209 | static const struct gss_api_ops gss_spkm3_ops = { | ||
210 | .gss_import_sec_context = gss_import_sec_context_spkm3, | ||
211 | .gss_get_mic = gss_get_mic_spkm3, | ||
212 | .gss_verify_mic = gss_verify_mic_spkm3, | ||
213 | .gss_delete_sec_context = gss_delete_sec_context_spkm3, | ||
214 | }; | ||
215 | |||
216 | static struct pf_desc gss_spkm3_pfs[] = { | ||
217 | {RPC_AUTH_GSS_SPKM, RPC_GSS_SVC_NONE, "spkm3"}, | ||
218 | {RPC_AUTH_GSS_SPKMI, RPC_GSS_SVC_INTEGRITY, "spkm3i"}, | ||
219 | }; | ||
220 | |||
221 | static struct gss_api_mech gss_spkm3_mech = { | ||
222 | .gm_name = "spkm3", | ||
223 | .gm_owner = THIS_MODULE, | ||
224 | .gm_oid = {7, "\053\006\001\005\005\001\003"}, | ||
225 | .gm_ops = &gss_spkm3_ops, | ||
226 | .gm_pf_num = ARRAY_SIZE(gss_spkm3_pfs), | ||
227 | .gm_pfs = gss_spkm3_pfs, | ||
228 | }; | ||
229 | |||
230 | static int __init init_spkm3_module(void) | ||
231 | { | ||
232 | int status; | ||
233 | |||
234 | status = gss_mech_register(&gss_spkm3_mech); | ||
235 | if (status) | ||
236 | printk("Failed to register spkm3 gss mechanism!\n"); | ||
237 | return status; | ||
238 | } | ||
239 | |||
240 | static void __exit cleanup_spkm3_module(void) | ||
241 | { | ||
242 | gss_mech_unregister(&gss_spkm3_mech); | ||
243 | } | ||
244 | |||
245 | MODULE_LICENSE("GPL"); | ||
246 | module_init(init_spkm3_module); | ||
247 | module_exit(cleanup_spkm3_module); | ||
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c deleted file mode 100644 index 5a3a65a0e2b4..000000000000 --- a/net/sunrpc/auth_gss/gss_spkm3_seal.c +++ /dev/null | |||
@@ -1,186 +0,0 @@ | |||
1 | /* | ||
2 | * linux/net/sunrpc/gss_spkm3_seal.c | ||
3 | * | ||
4 | * Copyright (c) 2003 The Regents of the University of Michigan. | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Andy Adamson <andros@umich.edu> | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of the University nor the names of its | ||
19 | * contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
25 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | * | ||
34 | */ | ||
35 | |||
36 | #include <linux/types.h> | ||
37 | #include <linux/jiffies.h> | ||
38 | #include <linux/sunrpc/gss_spkm3.h> | ||
39 | #include <linux/random.h> | ||
40 | #include <linux/crypto.h> | ||
41 | #include <linux/pagemap.h> | ||
42 | #include <linux/scatterlist.h> | ||
43 | #include <linux/sunrpc/xdr.h> | ||
44 | |||
45 | #ifdef RPC_DEBUG | ||
46 | # define RPCDBG_FACILITY RPCDBG_AUTH | ||
47 | #endif | ||
48 | |||
49 | const struct xdr_netobj hmac_md5_oid = { 8, "\x2B\x06\x01\x05\x05\x08\x01\x01"}; | ||
50 | const struct xdr_netobj cast5_cbc_oid = {9, "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A"}; | ||
51 | |||
52 | /* | ||
53 | * spkm3_make_token() | ||
54 | * | ||
55 | * Only SPKM_MIC_TOK with md5 intg-alg is supported | ||
56 | */ | ||
57 | |||
58 | u32 | ||
59 | spkm3_make_token(struct spkm3_ctx *ctx, | ||
60 | struct xdr_buf * text, struct xdr_netobj * token, | ||
61 | int toktype) | ||
62 | { | ||
63 | s32 checksum_type; | ||
64 | char tokhdrbuf[25]; | ||
65 | char cksumdata[16]; | ||
66 | struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; | ||
67 | struct xdr_netobj mic_hdr = {.len = 0, .data = tokhdrbuf}; | ||
68 | int tokenlen = 0; | ||
69 | unsigned char *ptr; | ||
70 | s32 now; | ||
71 | int ctxelen = 0, ctxzbit = 0; | ||
72 | int md5elen = 0, md5zbit = 0; | ||
73 | |||
74 | now = jiffies; | ||
75 | |||
76 | if (ctx->ctx_id.len != 16) { | ||
77 | dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n", | ||
78 | ctx->ctx_id.len); | ||
79 | goto out_err; | ||
80 | } | ||
81 | |||
82 | if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) { | ||
83 | dprintk("RPC: gss_spkm3_seal: unsupported I-ALG " | ||
84 | "algorithm. only support hmac-md5 I-ALG.\n"); | ||
85 | goto out_err; | ||
86 | } else | ||
87 | checksum_type = CKSUMTYPE_HMAC_MD5; | ||
88 | |||
89 | if (!g_OID_equal(&ctx->conf_alg, &cast5_cbc_oid)) { | ||
90 | dprintk("RPC: gss_spkm3_seal: unsupported C-ALG " | ||
91 | "algorithm\n"); | ||
92 | goto out_err; | ||
93 | } | ||
94 | |||
95 | if (toktype == SPKM_MIC_TOK) { | ||
96 | /* Calculate checksum over the mic-header */ | ||
97 | asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit); | ||
98 | spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data, | ||
99 | ctxelen, ctxzbit); | ||
100 | if (make_spkm3_checksum(checksum_type, &ctx->derived_integ_key, | ||
101 | (char *)mic_hdr.data, mic_hdr.len, | ||
102 | text, 0, &md5cksum)) | ||
103 | goto out_err; | ||
104 | |||
105 | asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit); | ||
106 | tokenlen = 10 + ctxelen + 1 + md5elen + 1; | ||
107 | |||
108 | /* Create token header using generic routines */ | ||
109 | token->len = g_token_size(&ctx->mech_used, tokenlen + 2); | ||
110 | |||
111 | ptr = token->data; | ||
112 | g_make_token_header(&ctx->mech_used, tokenlen + 2, &ptr); | ||
113 | |||
114 | spkm3_make_mic_token(&ptr, tokenlen, &mic_hdr, &md5cksum, md5elen, md5zbit); | ||
115 | } else if (toktype == SPKM_WRAP_TOK) { /* Not Supported */ | ||
116 | dprintk("RPC: gss_spkm3_seal: SPKM_WRAP_TOK " | ||
117 | "not supported\n"); | ||
118 | goto out_err; | ||
119 | } | ||
120 | |||
121 | /* XXX need to implement sequence numbers, and ctx->expired */ | ||
122 | |||
123 | return GSS_S_COMPLETE; | ||
124 | out_err: | ||
125 | token->data = NULL; | ||
126 | token->len = 0; | ||
127 | return GSS_S_FAILURE; | ||
128 | } | ||
129 | |||
130 | static int | ||
131 | spkm3_checksummer(struct scatterlist *sg, void *data) | ||
132 | { | ||
133 | struct hash_desc *desc = data; | ||
134 | |||
135 | return crypto_hash_update(desc, sg, sg->length); | ||
136 | } | ||
137 | |||
138 | /* checksum the plaintext data and hdrlen bytes of the token header */ | ||
139 | s32 | ||
140 | make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header, | ||
141 | unsigned int hdrlen, struct xdr_buf *body, | ||
142 | unsigned int body_offset, struct xdr_netobj *cksum) | ||
143 | { | ||
144 | char *cksumname; | ||
145 | struct hash_desc desc; /* XXX add to ctx? */ | ||
146 | struct scatterlist sg[1]; | ||
147 | int err; | ||
148 | |||
149 | switch (cksumtype) { | ||
150 | case CKSUMTYPE_HMAC_MD5: | ||
151 | cksumname = "hmac(md5)"; | ||
152 | break; | ||
153 | default: | ||
154 | dprintk("RPC: spkm3_make_checksum:" | ||
155 | " unsupported checksum %d", cksumtype); | ||
156 | return GSS_S_FAILURE; | ||
157 | } | ||
158 | |||
159 | if (key->data == NULL || key->len <= 0) return GSS_S_FAILURE; | ||
160 | |||
161 | desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC); | ||
162 | if (IS_ERR(desc.tfm)) | ||
163 | return GSS_S_FAILURE; | ||
164 | cksum->len = crypto_hash_digestsize(desc.tfm); | ||
165 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
166 | |||
167 | err = crypto_hash_setkey(desc.tfm, key->data, key->len); | ||
168 | if (err) | ||
169 | goto out; | ||
170 | |||
171 | err = crypto_hash_init(&desc); | ||
172 | if (err) | ||
173 | goto out; | ||
174 | |||
175 | sg_init_one(sg, header, hdrlen); | ||
176 | crypto_hash_update(&desc, sg, sg->length); | ||
177 | |||
178 | xdr_process_buf(body, body_offset, body->len - body_offset, | ||
179 | spkm3_checksummer, &desc); | ||
180 | crypto_hash_final(&desc, cksum->data); | ||
181 | |||
182 | out: | ||
183 | crypto_free_hash(desc.tfm); | ||
184 | |||
185 | return err ? GSS_S_FAILURE : 0; | ||
186 | } | ||
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c deleted file mode 100644 index a99825d7caa0..000000000000 --- a/net/sunrpc/auth_gss/gss_spkm3_token.c +++ /dev/null | |||
@@ -1,267 +0,0 @@ | |||
1 | /* | ||
2 | * linux/net/sunrpc/gss_spkm3_token.c | ||
3 | * | ||
4 | * Copyright (c) 2003 The Regents of the University of Michigan. | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Andy Adamson <andros@umich.edu> | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of the University nor the names of its | ||
19 | * contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
25 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | * | ||
34 | */ | ||
35 | |||
36 | #include <linux/types.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/jiffies.h> | ||
39 | #include <linux/sunrpc/gss_spkm3.h> | ||
40 | #include <linux/random.h> | ||
41 | #include <linux/crypto.h> | ||
42 | |||
43 | #ifdef RPC_DEBUG | ||
44 | # define RPCDBG_FACILITY RPCDBG_AUTH | ||
45 | #endif | ||
46 | |||
47 | /* | ||
48 | * asn1_bitstring_len() | ||
49 | * | ||
50 | * calculate the asn1 bitstring length of the xdr_netobject | ||
51 | */ | ||
52 | void | ||
53 | asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits) | ||
54 | { | ||
55 | int i, zbit = 0,elen = in->len; | ||
56 | char *ptr; | ||
57 | |||
58 | ptr = &in->data[in->len -1]; | ||
59 | |||
60 | /* count trailing 0's */ | ||
61 | for(i = in->len; i > 0; i--) { | ||
62 | if (*ptr == 0) { | ||
63 | ptr--; | ||
64 | elen--; | ||
65 | } else | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | /* count number of 0 bits in final octet */ | ||
70 | ptr = &in->data[elen - 1]; | ||
71 | for(i = 0; i < 8; i++) { | ||
72 | short mask = 0x01; | ||
73 | |||
74 | if (!((mask << i) & *ptr)) | ||
75 | zbit++; | ||
76 | else | ||
77 | break; | ||
78 | } | ||
79 | *enclen = elen; | ||
80 | *zerobits = zbit; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * decode_asn1_bitstring() | ||
85 | * | ||
86 | * decode a bitstring into a buffer of the expected length. | ||
87 | * enclen = bit string length | ||
88 | * explen = expected length (define in rfc) | ||
89 | */ | ||
90 | int | ||
91 | decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen) | ||
92 | { | ||
93 | if (!(out->data = kzalloc(explen,GFP_NOFS))) | ||
94 | return 0; | ||
95 | out->len = explen; | ||
96 | memcpy(out->data, in, enclen); | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * SPKMInnerContextToken choice SPKM_MIC asn1 token layout | ||
102 | * | ||
103 | * contextid is always 16 bytes plain data. max asn1 bitstring len = 17. | ||
104 | * | ||
105 | * tokenlen = pos[0] to end of token (max pos[45] with MD5 cksum) | ||
106 | * | ||
107 | * pos value | ||
108 | * ---------- | ||
109 | * [0] a4 SPKM-MIC tag | ||
110 | * [1] ?? innertoken length (max 44) | ||
111 | * | ||
112 | * | ||
113 | * tok_hdr piece of checksum data starts here | ||
114 | * | ||
115 | * the maximum mic-header len = 9 + 17 = 26 | ||
116 | * mic-header | ||
117 | * ---------- | ||
118 | * [2] 30 SEQUENCE tag | ||
119 | * [3] ?? mic-header length: (max 23) = TokenID + ContextID | ||
120 | * | ||
121 | * TokenID - all fields constant and can be hardcoded | ||
122 | * ------- | ||
123 | * [4] 02 Type 2 | ||
124 | * [5] 02 Length 2 | ||
125 | * [6][7] 01 01 TokenID (SPKM_MIC_TOK) | ||
126 | * | ||
127 | * ContextID - encoded length not constant, calculated | ||
128 | * --------- | ||
129 | * [8] 03 Type 3 | ||
130 | * [9] ?? encoded length | ||
131 | * [10] ?? ctxzbit | ||
132 | * [11] contextid | ||
133 | * | ||
134 | * mic_header piece of checksum data ends here. | ||
135 | * | ||
136 | * int-cksum - encoded length not constant, calculated | ||
137 | * --------- | ||
138 | * [??] 03 Type 3 | ||
139 | * [??] ?? encoded length | ||
140 | * [??] ?? md5zbit | ||
141 | * [??] int-cksum (NID_md5 = 16) | ||
142 | * | ||
143 | * maximum SPKM-MIC innercontext token length = | ||
144 | * 10 + encoded contextid_size(17 max) + 2 + encoded | ||
145 | * cksum_size (17 maxfor NID_md5) = 46 | ||
146 | */ | ||
147 | |||
148 | /* | ||
149 | * spkm3_mic_header() | ||
150 | * | ||
151 | * Prepare the SPKM_MIC_TOK mic-header for check-sum calculation | ||
152 | * elen: 16 byte context id asn1 bitstring encoded length | ||
153 | */ | ||
154 | void | ||
155 | spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, unsigned char *ctxdata, int elen, int zbit) | ||
156 | { | ||
157 | char *hptr = *hdrbuf; | ||
158 | char *top = *hdrbuf; | ||
159 | |||
160 | *(u8 *)hptr++ = 0x30; | ||
161 | *(u8 *)hptr++ = elen + 7; /* on the wire header length */ | ||
162 | |||
163 | /* tokenid */ | ||
164 | *(u8 *)hptr++ = 0x02; | ||
165 | *(u8 *)hptr++ = 0x02; | ||
166 | *(u8 *)hptr++ = 0x01; | ||
167 | *(u8 *)hptr++ = 0x01; | ||
168 | |||
169 | /* coniextid */ | ||
170 | *(u8 *)hptr++ = 0x03; | ||
171 | *(u8 *)hptr++ = elen + 1; /* add 1 to include zbit */ | ||
172 | *(u8 *)hptr++ = zbit; | ||
173 | memcpy(hptr, ctxdata, elen); | ||
174 | hptr += elen; | ||
175 | *hdrlen = hptr - top; | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * spkm3_mic_innercontext_token() | ||
180 | * | ||
181 | * *tokp points to the beginning of the SPKM_MIC token described | ||
182 | * in rfc 2025, section 3.2.1: | ||
183 | * | ||
184 | * toklen is the inner token length | ||
185 | */ | ||
186 | void | ||
187 | spkm3_make_mic_token(unsigned char **tokp, int toklen, struct xdr_netobj *mic_hdr, struct xdr_netobj *md5cksum, int md5elen, int md5zbit) | ||
188 | { | ||
189 | unsigned char *ict = *tokp; | ||
190 | |||
191 | *(u8 *)ict++ = 0xa4; | ||
192 | *(u8 *)ict++ = toklen; | ||
193 | memcpy(ict, mic_hdr->data, mic_hdr->len); | ||
194 | ict += mic_hdr->len; | ||
195 | |||
196 | *(u8 *)ict++ = 0x03; | ||
197 | *(u8 *)ict++ = md5elen + 1; /* add 1 to include zbit */ | ||
198 | *(u8 *)ict++ = md5zbit; | ||
199 | memcpy(ict, md5cksum->data, md5elen); | ||
200 | } | ||
201 | |||
202 | u32 | ||
203 | spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, unsigned char **cksum) | ||
204 | { | ||
205 | struct xdr_netobj spkm3_ctx_id = {.len =0, .data = NULL}; | ||
206 | unsigned char *ptr = *tokp; | ||
207 | int ctxelen; | ||
208 | u32 ret = GSS_S_DEFECTIVE_TOKEN; | ||
209 | |||
210 | /* spkm3 innercontext token preamble */ | ||
211 | if ((ptr[0] != 0xa4) || (ptr[2] != 0x30)) { | ||
212 | dprintk("RPC: BAD SPKM ictoken preamble\n"); | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | *mic_hdrlen = ptr[3]; | ||
217 | |||
218 | /* token type */ | ||
219 | if ((ptr[4] != 0x02) || (ptr[5] != 0x02)) { | ||
220 | dprintk("RPC: BAD asn1 SPKM3 token type\n"); | ||
221 | goto out; | ||
222 | } | ||
223 | |||
224 | /* only support SPKM_MIC_TOK */ | ||
225 | if((ptr[6] != 0x01) || (ptr[7] != 0x01)) { | ||
226 | dprintk("RPC: ERROR unsupported SPKM3 token\n"); | ||
227 | goto out; | ||
228 | } | ||
229 | |||
230 | /* contextid */ | ||
231 | if (ptr[8] != 0x03) { | ||
232 | dprintk("RPC: BAD SPKM3 asn1 context-id type\n"); | ||
233 | goto out; | ||
234 | } | ||
235 | |||
236 | ctxelen = ptr[9]; | ||
237 | if (ctxelen > 17) { /* length includes asn1 zbit octet */ | ||
238 | dprintk("RPC: BAD SPKM3 contextid len %d\n", ctxelen); | ||
239 | goto out; | ||
240 | } | ||
241 | |||
242 | /* ignore ptr[10] */ | ||
243 | |||
244 | if(!decode_asn1_bitstring(&spkm3_ctx_id, &ptr[11], ctxelen - 1, 16)) | ||
245 | goto out; | ||
246 | |||
247 | /* | ||
248 | * in the current implementation: the optional int-alg is not present | ||
249 | * so the default int-alg (md5) is used the optional snd-seq field is | ||
250 | * also not present | ||
251 | */ | ||
252 | |||
253 | if (*mic_hdrlen != 6 + ctxelen) { | ||
254 | dprintk("RPC: BAD SPKM_ MIC_TOK header len %d: we only " | ||
255 | "support default int-alg (should be absent) " | ||
256 | "and do not support snd-seq\n", *mic_hdrlen); | ||
257 | goto out; | ||
258 | } | ||
259 | /* checksum */ | ||
260 | *cksum = (&ptr[10] + ctxelen); /* ctxelen includes ptr[10] */ | ||
261 | |||
262 | ret = GSS_S_COMPLETE; | ||
263 | out: | ||
264 | kfree(spkm3_ctx_id.data); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c deleted file mode 100644 index cc21ee860bb6..000000000000 --- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | /* | ||
2 | * linux/net/sunrpc/gss_spkm3_unseal.c | ||
3 | * | ||
4 | * Copyright (c) 2003 The Regents of the University of Michigan. | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Andy Adamson <andros@umich.edu> | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of the University nor the names of its | ||
19 | * contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
25 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | * | ||
34 | */ | ||
35 | |||
36 | #include <linux/types.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/jiffies.h> | ||
39 | #include <linux/sunrpc/gss_spkm3.h> | ||
40 | #include <linux/crypto.h> | ||
41 | |||
42 | #ifdef RPC_DEBUG | ||
43 | # define RPCDBG_FACILITY RPCDBG_AUTH | ||
44 | #endif | ||
45 | |||
46 | /* | ||
47 | * spkm3_read_token() | ||
48 | * | ||
49 | * only SPKM_MIC_TOK with md5 intg-alg is supported | ||
50 | */ | ||
51 | u32 | ||
52 | spkm3_read_token(struct spkm3_ctx *ctx, | ||
53 | struct xdr_netobj *read_token, /* checksum */ | ||
54 | struct xdr_buf *message_buffer, /* signbuf */ | ||
55 | int toktype) | ||
56 | { | ||
57 | s32 checksum_type; | ||
58 | s32 code; | ||
59 | struct xdr_netobj wire_cksum = {.len =0, .data = NULL}; | ||
60 | char cksumdata[16]; | ||
61 | struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; | ||
62 | unsigned char *ptr = (unsigned char *)read_token->data; | ||
63 | unsigned char *cksum; | ||
64 | int bodysize, md5elen; | ||
65 | int mic_hdrlen; | ||
66 | u32 ret = GSS_S_DEFECTIVE_TOKEN; | ||
67 | |||
68 | if (g_verify_token_header((struct xdr_netobj *) &ctx->mech_used, | ||
69 | &bodysize, &ptr, read_token->len)) | ||
70 | goto out; | ||
71 | |||
72 | /* decode the token */ | ||
73 | |||
74 | if (toktype != SPKM_MIC_TOK) { | ||
75 | dprintk("RPC: BAD SPKM3 token type: %d\n", toktype); | ||
76 | goto out; | ||
77 | } | ||
78 | |||
79 | if ((ret = spkm3_verify_mic_token(&ptr, &mic_hdrlen, &cksum))) | ||
80 | goto out; | ||
81 | |||
82 | if (*cksum++ != 0x03) { | ||
83 | dprintk("RPC: spkm3_read_token BAD checksum type\n"); | ||
84 | goto out; | ||
85 | } | ||
86 | md5elen = *cksum++; | ||
87 | cksum++; /* move past the zbit */ | ||
88 | |||
89 | if (!decode_asn1_bitstring(&wire_cksum, cksum, md5elen - 1, 16)) | ||
90 | goto out; | ||
91 | |||
92 | /* HARD CODED FOR MD5 */ | ||
93 | |||
94 | /* compute the checksum of the message. | ||
95 | * ptr + 2 = start of header piece of checksum | ||
96 | * mic_hdrlen + 2 = length of header piece of checksum | ||
97 | */ | ||
98 | ret = GSS_S_DEFECTIVE_TOKEN; | ||
99 | if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) { | ||
100 | dprintk("RPC: gss_spkm3_seal: unsupported I-ALG " | ||
101 | "algorithm\n"); | ||
102 | goto out; | ||
103 | } | ||
104 | |||
105 | checksum_type = CKSUMTYPE_HMAC_MD5; | ||
106 | |||
107 | code = make_spkm3_checksum(checksum_type, | ||
108 | &ctx->derived_integ_key, ptr + 2, mic_hdrlen + 2, | ||
109 | message_buffer, 0, &md5cksum); | ||
110 | |||
111 | if (code) | ||
112 | goto out; | ||
113 | |||
114 | ret = GSS_S_BAD_SIG; | ||
115 | code = memcmp(md5cksum.data, wire_cksum.data, wire_cksum.len); | ||
116 | if (code) { | ||
117 | dprintk("RPC: bad MIC checksum\n"); | ||
118 | goto out; | ||
119 | } | ||
120 | |||
121 | |||
122 | /* XXX: need to add expiration and sequencing */ | ||
123 | ret = GSS_S_COMPLETE; | ||
124 | out: | ||
125 | kfree(wire_cksum.data); | ||
126 | return ret; | ||
127 | } | ||
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index cc385b3a59c2..dec2a6fc7c12 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -964,7 +964,7 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) | |||
964 | if (rqstp->rq_gssclient == NULL) | 964 | if (rqstp->rq_gssclient == NULL) |
965 | return SVC_DENIED; | 965 | return SVC_DENIED; |
966 | stat = svcauth_unix_set_client(rqstp); | 966 | stat = svcauth_unix_set_client(rqstp); |
967 | if (stat == SVC_DROP) | 967 | if (stat == SVC_DROP || stat == SVC_CLOSE) |
968 | return stat; | 968 | return stat; |
969 | return SVC_OK; | 969 | return SVC_OK; |
970 | } | 970 | } |
@@ -1018,7 +1018,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1018 | return SVC_DENIED; | 1018 | return SVC_DENIED; |
1019 | memset(&rsikey, 0, sizeof(rsikey)); | 1019 | memset(&rsikey, 0, sizeof(rsikey)); |
1020 | if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx)) | 1020 | if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx)) |
1021 | return SVC_DROP; | 1021 | return SVC_CLOSE; |
1022 | *authp = rpc_autherr_badverf; | 1022 | *authp = rpc_autherr_badverf; |
1023 | if (svc_safe_getnetobj(argv, &tmpobj)) { | 1023 | if (svc_safe_getnetobj(argv, &tmpobj)) { |
1024 | kfree(rsikey.in_handle.data); | 1024 | kfree(rsikey.in_handle.data); |
@@ -1026,38 +1026,35 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1026 | } | 1026 | } |
1027 | if (dup_netobj(&rsikey.in_token, &tmpobj)) { | 1027 | if (dup_netobj(&rsikey.in_token, &tmpobj)) { |
1028 | kfree(rsikey.in_handle.data); | 1028 | kfree(rsikey.in_handle.data); |
1029 | return SVC_DROP; | 1029 | return SVC_CLOSE; |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | /* Perform upcall, or find upcall result: */ | 1032 | /* Perform upcall, or find upcall result: */ |
1033 | rsip = rsi_lookup(&rsikey); | 1033 | rsip = rsi_lookup(&rsikey); |
1034 | rsi_free(&rsikey); | 1034 | rsi_free(&rsikey); |
1035 | if (!rsip) | 1035 | if (!rsip) |
1036 | return SVC_DROP; | 1036 | return SVC_CLOSE; |
1037 | switch (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) { | 1037 | if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) |
1038 | case -EAGAIN: | ||
1039 | case -ETIMEDOUT: | ||
1040 | case -ENOENT: | ||
1041 | /* No upcall result: */ | 1038 | /* No upcall result: */ |
1042 | return SVC_DROP; | 1039 | return SVC_CLOSE; |
1043 | case 0: | 1040 | |
1044 | ret = SVC_DROP; | 1041 | ret = SVC_CLOSE; |
1045 | /* Got an answer to the upcall; use it: */ | 1042 | /* Got an answer to the upcall; use it: */ |
1046 | if (gss_write_init_verf(rqstp, rsip)) | 1043 | if (gss_write_init_verf(rqstp, rsip)) |
1047 | goto out; | 1044 | goto out; |
1048 | if (resv->iov_len + 4 > PAGE_SIZE) | 1045 | if (resv->iov_len + 4 > PAGE_SIZE) |
1049 | goto out; | 1046 | goto out; |
1050 | svc_putnl(resv, RPC_SUCCESS); | 1047 | svc_putnl(resv, RPC_SUCCESS); |
1051 | if (svc_safe_putnetobj(resv, &rsip->out_handle)) | 1048 | if (svc_safe_putnetobj(resv, &rsip->out_handle)) |
1052 | goto out; | 1049 | goto out; |
1053 | if (resv->iov_len + 3 * 4 > PAGE_SIZE) | 1050 | if (resv->iov_len + 3 * 4 > PAGE_SIZE) |
1054 | goto out; | 1051 | goto out; |
1055 | svc_putnl(resv, rsip->major_status); | 1052 | svc_putnl(resv, rsip->major_status); |
1056 | svc_putnl(resv, rsip->minor_status); | 1053 | svc_putnl(resv, rsip->minor_status); |
1057 | svc_putnl(resv, GSS_SEQ_WIN); | 1054 | svc_putnl(resv, GSS_SEQ_WIN); |
1058 | if (svc_safe_putnetobj(resv, &rsip->out_token)) | 1055 | if (svc_safe_putnetobj(resv, &rsip->out_token)) |
1059 | goto out; | 1056 | goto out; |
1060 | } | 1057 | |
1061 | ret = SVC_COMPLETE; | 1058 | ret = SVC_COMPLETE; |
1062 | out: | 1059 | out: |
1063 | cache_put(&rsip->h, &rsi_cache); | 1060 | cache_put(&rsip->h, &rsi_cache); |