3 * The Regents of the University of Michigan
6 * Permission is granted to use, copy, create derivative works
7 * and redistribute this software and such derivative works
8 * for any purpose, so long as the name of The University of
9 * Michigan is not used in any advertising or publicity
10 * pertaining to the use of distribution of this software
11 * without specific, written prior authorization. If the
12 * above copyright notice or any other identification of the
13 * University of Michigan is included in any copy of any
14 * portion of this software, then the disclaimer below must
17 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
24 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
33 #endif /* HAVE_CONFIG_H */
42 #include <gssapi/gssapi.h>
48 #include "svcgssd_krb5.h"
49 #include "../mount/version.h"
53 char *supported_enctypes_filename = "/proc/fs/nfsd/supported_krb5_enctypes";
54 int parsed_num_enctypes = 0;
55 krb5_enctype *parsed_enctypes = NULL;
56 char *cached_enctypes = NULL;
58 /*==========================*/
59 /*=== Internal routines ===*/
60 /*==========================*/
63 * Parse the supported encryption type information
66 parse_enctypes(char *enctypes)
72 /* Don't parse the same string over and over... */
73 if (cached_enctypes && strcmp(cached_enctypes, enctypes) == 0)
76 /* Free any existing cached_enctypes */
77 free(cached_enctypes);
79 if (parsed_enctypes != NULL) {
80 free(parsed_enctypes);
81 parsed_enctypes = NULL;
82 parsed_num_enctypes = 0;
85 /* count the number of commas */
86 for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
87 comma = strchr(curr, ',');
94 /* If no more commas and we're not at the end, there's one more value */
98 /* Empty string, return an error */
102 /* Skip pass any non digits */
103 while (*enctypes && isdigit(*enctypes) == 0)
105 if (*enctypes == '\0')
108 /* Allocate space for enctypes array */
109 if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
113 /* Now parse each value into the array */
114 for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
115 parsed_enctypes[i++] = atoi(curr);
116 comma = strchr(curr, ',');
121 parsed_num_enctypes = n;
122 if ((cached_enctypes = malloc(strlen(enctypes)+1)))
123 strcpy(cached_enctypes, enctypes);
129 get_kernel_supported_enctypes(void)
133 char buffer[MYBUFLEN + 1];
135 memset(buffer, '\0', sizeof(buffer));
137 s_e = fopen(supported_enctypes_filename, "r");
139 goto out_clean_parsed;
141 ret = fread(buffer, 1, MYBUFLEN, s_e);
144 goto out_clean_parsed;
147 if (parse_enctypes(buffer)) {
148 goto out_clean_parsed;
154 if (parsed_enctypes != NULL) {
155 free(parsed_enctypes);
156 parsed_num_enctypes = 0;
161 /*==========================*/
162 /*=== External routines ===*/
163 /*==========================*/
166 * Get encryption types supported by the kernel, and then
167 * call gss_krb5_set_allowable_enctypes() to limit the
168 * encryption types negotiated.
172 * -1 => there was an error
176 svcgssd_limit_krb5_enctypes(void)
178 #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
179 u_int maj_stat, min_stat;
180 krb5_enctype old_kernel_enctypes[] = {
183 ENCTYPE_DES_CBC_MD4 };
184 krb5_enctype new_kernel_enctypes[] = {
185 ENCTYPE_AES256_CTS_HMAC_SHA1_96,
186 ENCTYPE_AES128_CTS_HMAC_SHA1_96,
187 ENCTYPE_DES3_CBC_SHA1,
188 ENCTYPE_ARCFOUR_HMAC,
191 ENCTYPE_DES_CBC_MD4 };
192 krb5_enctype *default_enctypes, *enctypes;
193 int default_num_enctypes, num_enctypes;
196 if (linux_version_code() < MAKE_VERSION(2, 6, 35)) {
197 default_enctypes = old_kernel_enctypes;
198 default_num_enctypes =
199 sizeof(old_kernel_enctypes) / sizeof(old_kernel_enctypes[0]);
201 default_enctypes = new_kernel_enctypes;
202 default_num_enctypes =
203 sizeof(new_kernel_enctypes) / sizeof(new_kernel_enctypes[0]);
206 get_kernel_supported_enctypes();
208 if (parsed_enctypes != NULL) {
209 enctypes = parsed_enctypes;
210 num_enctypes = parsed_num_enctypes;
211 printerr(2, "%s: Calling gss_set_allowable_enctypes with %d "
212 "enctypes from the kernel\n", __func__, num_enctypes);
214 enctypes = default_enctypes;
215 num_enctypes = default_num_enctypes;
216 printerr(2, "%s: Calling gss_set_allowable_enctypes with %d "
217 "enctypes from defaults\n", __func__, num_enctypes);
220 maj_stat = gss_set_allowable_enctypes(&min_stat, gssd_creds,
221 &krb5oid, num_enctypes, enctypes);
222 if (maj_stat != GSS_S_COMPLETE) {
223 printerr(1, "WARNING: gss_set_allowable_enctypes failed\n");
224 pgsserr("svcgssd_limit_krb5_enctypes: gss_set_allowable_enctypes",
225 maj_stat, min_stat, &krb5oid);