]> andersk Git - moira.git/blob - update/auth_002.c
punt mrgdb
[moira.git] / update / auth_002.c
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
17 #include <krb.h>
18
19 RCSID("$Header$");
20
21 static char service[] = "rcmd";
22 static char master[] = "sms";
23 static char qmark[] = "???";
24 extern des_cblock session;
25
26 /*
27  * authentication request auth_002:
28  *
29  * >>> (STRING) "auth_002"
30  * <<< (int) 0
31  * >>> (STRING) ticket
32  * <<< (int) code
33  * <<< (STRING) nonce
34  * >>> (STRING) encrypted nonce
35  * <<< (int) code
36  *
37  */
38
39 void auth_002(int conn, char *str)
40 {
41   char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ];
42   AUTH_DAT ad;
43   char *p, *first, *data;
44   size_t size;
45   KTEXT_ST ticket_st;
46   des_key_schedule sched;
47   des_cblock nonce, nonce2;
48   long code;
49
50   send_ok(conn);
51   
52   recv_string(conn, &data, &size);
53   if (size > sizeof(ticket_st.dat))
54     {
55       code = KE_RD_AP_UNDEC;
56       com_err(whoami, code, ": authenticator too large");
57       send_int(conn, code);
58       return;
59     }
60   memcpy(ticket_st.dat, data, size);
61   free(data);
62   ticket_st.mbz = 0;
63   ticket_st.length = size;
64   code = krb_rd_req(&ticket_st, service, krb_get_phost(hostname), 0,
65                     &ad, KEYFILE);
66   if (code)
67     {
68       code += ERROR_TABLE_BASE_krb;
69       strcpy(ad.pname, qmark);
70       strcpy(ad.pinst, qmark);
71       strcpy(ad.prealm, qmark);
72       goto auth_failed;
73     }
74
75   /* If there is an auth record in the config file matching the
76    * authenticator we received, then accept it.  If there's no
77    * auth record, assume [master]@[local realm].
78    */
79   if ((first = p = config_lookup("auth")))
80     {
81       do
82         {
83           kname_parse(aname, ainst, arealm, p);
84           if (strcmp(aname, ad.pname) ||
85               strcmp(ainst, ad.pinst) ||
86               strcmp(arealm, ad.prealm))
87             p = config_lookup("auth");
88           else
89             p = first;
90         }
91       while (p != first);
92     }
93   else
94     {
95       strcpy(aname, master);
96       strcpy(ainst, "");
97       if (krb_get_lrealm(arealm, 1))
98         strcpy(arealm, KRB_REALM);
99     }
100   code = EPERM;
101   if (strcmp(aname, ad.pname) ||
102       strcmp(ainst, ad.pinst) ||
103       strcmp(arealm, ad.prealm))
104     goto auth_failed;
105
106   send_ok(conn);
107
108   /* replay protection */
109   des_random_key(&nonce);
110   send_string(conn, (char *)nonce, sizeof(nonce));
111   recv_string(conn, &data, &size);
112   des_key_sched(ad.session, sched);
113   des_ecb_encrypt(data, nonce2, sched, 0);
114   free(data);
115   if (memcmp(nonce, nonce2, sizeof(nonce)))
116     goto auth_failed;
117   send_ok(conn);
118
119   have_authorization = 1;
120   /* Stash away session key */
121   memcpy(session, ad.session, sizeof(session));
122   return;
123
124 auth_failed:
125   com_err(whoami, code, "auth for %s.%s@%s failed",
126           ad.pname, ad.pinst, ad.prealm);
127   send_int(conn, code);
128 }
This page took 0.312347 seconds and 5 git commands to generate.