]> andersk Git - moira.git/blob - update/auth_002.c
2500ead6990ac31fa228189348e4d0520b722b9c
[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 #ifdef HAVE_KRB4
19 #include <krb.h>
20 #endif
21
22 RCSID("$Header$");
23
24 static char service[] = "rcmd";
25 static char master[] = "sms";
26 static char qmark[] = "???";
27 #ifdef HAVE_KRB4
28 extern 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
44 void 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(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
130 auth_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   return MR_NO_KRB4;
136 #endif
137 }
This page took 0.03893 seconds and 3 git commands to generate.