]> andersk Git - moira.git/blob - update/auth_002.c
18cc73eafd7592ea781d4f59778a58d19833fc88
[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 #include <string.h>
17
18 #include <krb.h>
19
20 RCSID("$Header$");
21
22 static char service[] = "rcmd";
23 static char master[] = "sms";
24 static char qmark[] = "???";
25 extern 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
40 void 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
125 auth_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 }
This page took 0.034078 seconds and 3 git commands to generate.