1 /* principal.c --- Get and set default principal.
2 * Copyright (C) 2002, 2003, 2004, 2006 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 * shishi_principal_default_guess:
27 * Guesses the principal name for the user, looking at environment
28 * variables SHISHI_USER and USER, or if that fails, returns the
31 * Return value: Returns guessed default principal for user as a
32 * string that has to be deallocated with free() by the caller.
35 shishi_principal_default_guess (void)
39 envuser
= getenv ("SHISHI_USER");
41 envuser
= getenv ("USER");
45 return xstrdup (envuser
);
50 * shishi_principal_default:
51 * @handle: Shishi library handle create by shishi_init().
53 * The default principal name is the name in the environment variable
54 * USER, but can be overridden by specifying the environment variable
57 * Return value: Returns the default principal name used in the
58 * library. (Not a copy of it, so don't modify or deallocate it.)
61 shishi_principal_default (Shishi
* handle
)
63 if (!handle
->default_principal
)
66 p
= shishi_principal_default_guess ();
67 shishi_principal_default_set (handle
, p
);
71 return handle
->default_principal
;
75 * shishi_principal_default_set:
76 * @handle: Shishi library handle create by shishi_init().
77 * @principal: string with new default principal name, or NULL to
80 * Set the default realm used in the library. The string is copied
81 * into the library, so you can dispose of the variable immediately
82 * after calling this function.
85 shishi_principal_default_set (Shishi
* handle
, const char *principal
)
87 if (handle
->default_principal
)
88 free (handle
->default_principal
);
90 handle
->default_principal
= xstrdup (principal
);
92 handle
->default_principal
= NULL
;
97 * @handle: Shishi library handle create by shishi_init().
98 * @name: Input principal name string, e.g. imap/mail.gnu.org@GNU.ORG.
99 * @principal: newly allocated output string with principal name.
100 * @realm: newly allocated output string with realm name.
102 * Split up principal name (e.g., "simon@JOSEFSSON.ORG") into two
103 * newly allocated strings, the principal ("simon") and realm
104 * ("JOSEFSSON.ORG"). If there is no realm part in NAME, REALM is set
107 * Return value: Returns SHISHI_INVALID_PRINCIPAL_NAME if NAME is NULL
108 * or ends with the escape character "\", or SHISHI_OK iff
112 shishi_parse_name (Shishi
* handle
, const char *name
,
113 char **principal
, char **realm
)
115 const char *p
= name
;
120 return SHISHI_INVALID_PRINCIPAL_NAME
;
122 while (*p
&& (*p
!= '@' || escaped
))
125 else if (*p
++ == '\\')
129 return SHISHI_INVALID_PRINCIPAL_NAME
;
133 *principal
= xstrndup (name
, p
- name
+ 1);
134 (*principal
)[p
- name
] = '\0';
144 else if (*q
++ == '\\')
148 return SHISHI_INVALID_PRINCIPAL_NAME
;
151 *realm
= xstrdup (p
);
160 * shishi_principal_name:
161 * @handle: Shishi library handle create by shishi_init().
162 * @namenode: ASN.1 structure with principal in @namefield.
163 * @namefield: name of field in @namenode containing principal name.
164 * @out: pointer to newly allocated zero terminated string containing
165 * principal name. May be %NULL (to only populate @outlen).
166 * @outlen: pointer to length of @out on output, excluding terminating
167 * zero. May be %NULL (to only populate @out).
169 * Represent principal name in ASN.1 structure as zero-terminated
170 * string. The string is allocate by this function, and it is the
171 * responsibility of the caller to deallocate it. Note that the
172 * output length @outlen does not include the terminating zero.
174 * Return value: Returns SHISHI_OK iff successful.
177 shishi_principal_name (Shishi
* handle
,
178 Shishi_asn1 namenode
,
179 const char *namefield
, char **out
, size_t * outlen
)
187 asprintf (&format
, "%s.name-string", namefield
);
188 res
= shishi_asn1_number_of_elements (handle
, namenode
, format
, &n
);
190 if (res
!= SHISHI_OK
)
193 for (i
= 1; i
<= n
; i
++)
199 asprintf (&format
, "%s.name-string.?%d", namefield
, i
);
200 res
= shishi_asn1_read (handle
, namenode
, format
, &tmp
, &tmplen
);
202 if (res
!= SHISHI_OK
)
206 for (j
= 0; j
< tmplen
; j
++)
207 if (tmp
[j
] == '@' || tmp
[j
] == '/' || tmp
[j
] == '\\')
212 name
= xrealloc (name
, namelen
+ safetmplen
);
214 for (j
= 0; j
< tmplen
; j
++)
216 if (tmp
[j
] == '@' || tmp
[j
] == '/' || tmp
[j
] == '\\')
217 name
[namelen
++] = '\\';
218 name
[namelen
++] = tmp
[j
];
222 name
[namelen
++] = '/';
227 name
= xrealloc (name
, namelen
+ 1);
228 name
[namelen
] = '\0';
241 * shishi_principal_name_realm:
242 * @handle: Shishi library handle create by shishi_init().
243 * @namenode: ASN.1 structure with principal name in @namefield.
244 * @namefield: name of field in @namenode containing principal name.
245 * @realmnode: ASN.1 structure with principal realm in @realmfield.
246 * @realmfield: name of field in @realmnode containing principal realm.
247 * @out: pointer to newly allocated zero terminated string containing
248 * principal name. May be %NULL (to only populate @outlen).
249 * @outlen: pointer to length of @out on output, excluding terminating
250 * zero. May be %NULL (to only populate @out).
252 * Represent principal name and realm in ASN.1 structure as
253 * zero-terminated string. The string is allocate by this function,
254 * and it is the responsibility of the caller to deallocate it. Note
255 * that the output length @outlen does not include the terminating
258 * Return value: Returns SHISHI_OK iff successful.
261 shishi_principal_name_realm (Shishi
* handle
,
262 Shishi_asn1 namenode
,
263 const char *namefield
,
264 Shishi_asn1 realmnode
,
265 const char *realmfield
,
266 char **out
, size_t * outlen
)
272 rc
= shishi_principal_name (handle
, namenode
, namefield
, &tmp
, &tmplen
);
276 if (realmnode
== NULL
&& realmfield
)
278 size_t realmfieldlen
= strlen (realmfield
);
280 tmp
= xrealloc (tmp
, tmplen
+ 1 + realmfieldlen
+ 1);
283 memcpy (tmp
+ tmplen
+ 1, realmfield
, realmfieldlen
);
285 tmplen
+= 1 + realmfieldlen
;
289 else if (realmnode
!= NULL
)
294 rc
= shishi_asn1_read (handle
, realmnode
, realmfield
,
302 tmp
= xrealloc (tmp
, tmplen
+ 1 + realmlen
+ 1);
305 memcpy (tmp
+ tmplen
+ 1, realm
, realmlen
);
307 tmplen
+= 1 + realmlen
;
322 * shishi_principal_name_set:
323 * @handle: shishi handle as allocated by shishi_init().
324 * @namenode: ASN.1 structure with principal in @namefield.
325 * @namefield: name of field in namenode containing principal name.
326 * @name_type: type of principial, see Shishi_name_type, usually
328 * @name: zero-terminated input array with principal name.
330 * Set the given principal name field to given name.
332 * Return value: Returns SHISHI_OK iff successful.
335 shishi_principal_name_set (Shishi
* handle
,
336 Shishi_asn1 namenode
,
337 const char *namefield
,
338 Shishi_name_type name_type
, const char *name
[])
344 asprintf (&asn1name
, "%s.name-type", namefield
);
345 res
= shishi_asn1_write_int32 (handle
, namenode
, asn1name
, name_type
);
347 if (res
!= SHISHI_OK
)
350 asprintf (&asn1name
, "%s.name-string", namefield
);
351 res
= shishi_asn1_write (handle
, namenode
, asn1name
, NULL
, 0);
353 if (res
!= SHISHI_OK
)
359 asprintf (&asn1name
, "%s.name-string", namefield
);
360 res
= shishi_asn1_write (handle
, namenode
, asn1name
, "NEW", 1);
362 if (res
!= SHISHI_OK
)
365 asprintf (&asn1name
, "%s.name-string.?%d", namefield
, i
);
366 res
= shishi_asn1_write (handle
, namenode
, asn1name
, name
[i
- 1], 0);
368 if (res
!= SHISHI_OK
)
378 * shishi_principal_set:
379 * @handle: shishi handle as allocated by shishi_init().
380 * @namenode: ASN.1 structure with principal in @namefield.
381 * @namefield: name of field in namenode containing principal name.
382 * @name: zero-terminated string with principal name on RFC 1964 form.
384 * Set principal name field in ASN.1 structure to given name.
386 * Return value: Returns SHISHI_OK iff successful.
389 shishi_principal_set (Shishi
* handle
,
390 Shishi_asn1 namenode
,
391 const char *namefield
, const char *name
)
394 const char **namebuf
;
399 tmpname
= xstrdup (name
);
400 namebuf
= xmalloc (sizeof (*namebuf
));
403 (namebuf
[i
] = strtok_r (i
== 0 ? tmpname
: NULL
, "/", &tokptr
)); i
++)
405 namebuf
= xrealloc (namebuf
, (i
+ 2) * sizeof (*namebuf
));
408 res
= shishi_principal_name_set (handle
, namenode
, namefield
,
409 SHISHI_NT_UNKNOWN
, namebuf
);
412 if (res
!= SHISHI_OK
)
414 shishi_error_printf (handle
, _("Could not set principal name: %s\n"),
415 shishi_strerror (res
));
423 * shishi_derive_default_salt:
424 * @handle: shishi handle as allocated by shishi_init().
425 * @name: principal name of user.
426 * @salt: output variable with newly allocated salt string.
428 * Derive the default salt from a principal. The default salt is the
429 * concatenation of the decoded realm and principal.
431 * Return value: Return SHISHI_OK if successful.
434 shishi_derive_default_salt (Shishi
* handle
,
442 rc
= shishi_parse_name (handle
, name
, &principal
, &realm
);
446 if (!principal
|| !realm
)
452 return SHISHI_INVALID_PRINCIPAL_NAME
;
455 *salt
= xasprintf ("%s%s", realm
, principal
);
464 * shishi_server_for_local_service:
465 * @handle: shishi handle as allocated by shishi_init().
466 * @service: zero terminated string with name of service, e.g., "host".
468 * Construct a service principal (e.g., "imap/yxa.extuno.com") based
469 * on supplied service name (i.e., "imap") and the system hostname as
470 * returned by hostname() (i.e., "yxa.extundo.com"). The string must
471 * be deallocated by the caller.
473 * Return value: Return newly allocated service name string.
476 shishi_server_for_local_service (Shishi
* handle
, const char *service
)
481 hostname
= xgethostname ();
483 asprintf (&server
, "%s/%s", service
, hostname
);