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

Revision 24319, 3.1 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: auth_002.c 3956 2010-01-05 20:56:56Z zacheiss $
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#ifdef HAVE_KRB4
19#include <krb.h>
20#endif
21
22RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/update/auth_002.c $ $Id: auth_002.c 3956 2010-01-05 20:56:56Z zacheiss $");
23
24static char service[] = "rcmd";
25static char master[] = "sms";
26static char qmark[] = "???";
27#ifdef HAVE_KRB4
28extern des_cblock session;
29#endif
30
31/*
32 * authentication request auth_002:
33 *
34 * >>> (STRING) "auth_002"
35 * <<< (int) 0
36 * >>> (STRING) ticket
37 * <<< (int) code
38 * <<< (STRING) nonce
39 * >>> (STRING) encrypted nonce
40 * <<< (int) code
41 *
42 */
43
44void auth_002(int conn, char *str)
45{
46#ifdef HAVE_KRB4
47  char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ];
48  AUTH_DAT ad;
49  char *p, *first, *data;
50  size_t size;
51  KTEXT_ST ticket_st;
52  des_key_schedule sched;
53  des_cblock nonce, nonce2;
54  long code;
55
56  send_ok(conn);
57 
58  recv_string(conn, &data, &size);
59  if (size > sizeof(ticket_st.dat))
60    {
61      code = KE_RD_AP_UNDEC;
62      com_err(whoami, code, ": authenticator too large");
63      send_int(conn, code);
64      return;
65    }
66  memcpy(ticket_st.dat, data, size);
67  free(data);
68  ticket_st.mbz = 0;
69  ticket_st.length = size;
70  code = krb_rd_req(&ticket_st, service, krb_get_phost(hostname), 0,
71                    &ad, KEYFILE);
72  if (code)
73    {
74      code += ERROR_TABLE_BASE_krb;
75      strcpy(ad.pname, qmark);
76      strcpy(ad.pinst, qmark);
77      strcpy(ad.prealm, qmark);
78      goto auth_failed;
79    }
80
81  /* If there is an auth record in the config file matching the
82   * authenticator we received, then accept it.  If there's no
83   * auth record, assume [master]@[local realm].
84   */
85  if ((first = p = config_lookup("auth")))
86    {
87      do
88        {
89          kname_parse(aname, ainst, arealm, p);
90          if (strcmp(aname, ad.pname) ||
91              strcmp(ainst, ad.pinst) ||
92              strcmp(arealm, ad.prealm))
93            p = config_lookup("auth");
94          else
95            p = first;
96        }
97      while (p != first);
98    }
99  else
100    {
101      strcpy(aname, master);
102      strcpy(ainst, "");
103      if (krb_get_lrealm(arealm, 1))
104        strcpy(arealm, KRB_REALM);
105    }
106  code = EPERM;
107  if (strcmp(aname, ad.pname) ||
108      strcmp(ainst, ad.pinst) ||
109      strcmp(arealm, ad.prealm))
110    goto auth_failed;
111
112  send_ok(conn);
113
114  /* replay protection */
115  des_random_key(&nonce);
116  send_string(conn, (char *)nonce, sizeof(nonce));
117  recv_string(conn, &data, &size);
118  des_key_sched(ad.session, sched);
119  des_ecb_encrypt((des_cblock *)data, &nonce2, sched, 0);
120  free(data);
121  if (memcmp(nonce, nonce2, sizeof(nonce)))
122    goto auth_failed;
123  send_ok(conn);
124
125  have_authorization = 1;
126  /* Stash away session key */
127  memcpy(session, ad.session, sizeof(session));
128  return;
129
130auth_failed:
131  com_err(whoami, code, "auth for %s.%s@%s failed",
132          ad.pname, ad.pinst, ad.prealm);
133  send_int(conn, code);
134#else
135  send_int(conn, MR_NO_KRB4);
136#endif
137}
Note: See TracBrowser for help on using the repository browser.