source: trunk/third/moira/update/auth_002.c @ 23178

Revision 23178, 2.8 KB checked in by broder, 16 years ago (diff)
Take a new snapshot from CVS for Moira, and add a debathena-moira-update-server package
Line 
1/* $Id$
2 *
3 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
5 * <mit-copyright.h>.
6 */
7
8#include <mit-copyright.h>
9#include <moira.h>
10#include "update_server.h"
11
12#include <sys/utsname.h>
13
14#include <errno.h>
15#include <stdio.h>
16#include <string.h>
17
18#include <krb.h>
19
20RCSID("$Header$");
21
22static char service[] = "rcmd";
23static char master[] = "sms";
24static char qmark[] = "???";
25extern des_cblock session;
26
27/*
28 * authentication request auth_002:
29 *
30 * >>> (STRING) "auth_002"
31 * <<< (int) 0
32 * >>> (STRING) ticket
33 * <<< (int) code
34 * <<< (STRING) nonce
35 * >>> (STRING) encrypted nonce
36 * <<< (int) code
37 *
38 */
39
40void auth_002(int conn, char *str)
41{
42  char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ];
43  AUTH_DAT ad;
44  char *p, *first, *data;
45  size_t size;
46  KTEXT_ST ticket_st;
47  des_key_schedule sched;
48  des_cblock nonce, nonce2;
49  long code;
50
51  send_ok(conn);
52 
53  recv_string(conn, &data, &size);
54  if (size > sizeof(ticket_st.dat))
55    {
56      code = KE_RD_AP_UNDEC;
57      com_err(whoami, code, ": authenticator too large");
58      send_int(conn, code);
59      return;
60    }
61  memcpy(ticket_st.dat, data, size);
62  free(data);
63  ticket_st.mbz = 0;
64  ticket_st.length = size;
65  code = krb_rd_req(&ticket_st, service, krb_get_phost(hostname), 0,
66                    &ad, KEYFILE);
67  if (code)
68    {
69      code += ERROR_TABLE_BASE_krb;
70      strcpy(ad.pname, qmark);
71      strcpy(ad.pinst, qmark);
72      strcpy(ad.prealm, qmark);
73      goto auth_failed;
74    }
75
76  /* If there is an auth record in the config file matching the
77   * authenticator we received, then accept it.  If there's no
78   * auth record, assume [master]@[local realm].
79   */
80  if ((first = p = config_lookup("auth")))
81    {
82      do
83        {
84          kname_parse(aname, ainst, arealm, p);
85          if (strcmp(aname, ad.pname) ||
86              strcmp(ainst, ad.pinst) ||
87              strcmp(arealm, ad.prealm))
88            p = config_lookup("auth");
89          else
90            p = first;
91        }
92      while (p != first);
93    }
94  else
95    {
96      strcpy(aname, master);
97      strcpy(ainst, "");
98      if (krb_get_lrealm(arealm, 1))
99        strcpy(arealm, KRB_REALM);
100    }
101  code = EPERM;
102  if (strcmp(aname, ad.pname) ||
103      strcmp(ainst, ad.pinst) ||
104      strcmp(arealm, ad.prealm))
105    goto auth_failed;
106
107  send_ok(conn);
108
109  /* replay protection */
110  des_random_key(&nonce);
111  send_string(conn, (char *)nonce, sizeof(nonce));
112  recv_string(conn, &data, &size);
113  des_key_sched(ad.session, sched);
114  des_ecb_encrypt(data, nonce2, sched, 0);
115  free(data);
116  if (memcmp(nonce, nonce2, sizeof(nonce)))
117    goto auth_failed;
118  send_ok(conn);
119
120  have_authorization = 1;
121  /* Stash away session key */
122  memcpy(session, ad.session, sizeof(session));
123  return;
124
125auth_failed:
126  com_err(whoami, code, "auth for %s.%s@%s failed",
127          ad.pname, ad.pinst, ad.prealm);
128  send_int(conn, code);
129}
Note: See TracBrowser for help on using the repository browser.