]> andersk Git - moira.git/blob - update/auth_002.c
Code style cleanup. (No functional changes)
[moira.git] / update / auth_002.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5 /*  (c) Copyright 1988 by the Massachusetts Institute of Technology. */
6 /*  For copying and distribution information, please see the file */
7 /*  <mit-copyright.h>. */
8
9 #ifndef lint
10 static char *rcsid_auth_002_c = "$Header$";
11 #endif
12
13 #include <mit-copyright.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <gdb.h>
17 #include <krb.h>
18 #include <krb_et.h>
19 #include <netinet/in.h>
20 #include <errno.h>
21 #ifdef POSIX
22 #include <sys/utsname.h>
23 #endif
24
25 extern char buf[BUFSIZ];
26 extern int have_authorization;
27 extern struct sockaddr_in *client_address();
28 extern CONNECTION conn;
29 extern int code;
30 extern char *PrincipalHostname();
31 static char service[] = "rcmd";
32 static char master[] = "sms";
33 static char qmark[] = "???";
34 extern C_Block session;
35
36 /*
37  * authentication request auth_002:
38  *
39  * >>> (STRING) "auth_002"
40  * <<< (int) 0
41  * >>> (STRING) ticket
42  * <<< (int) code
43  * <<< (STRING) nonce
44  * >>> (STRING) encrypted nonce
45  * <<< (int) code
46  *
47  */
48
49 int auth_002(char *str)
50 {
51   STRING data;
52   char realm[REALM_SZ];
53   char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ];
54   AUTH_DAT ad;
55   char *p, *first, *config_lookup();
56   KTEXT_ST ticket_st;
57   struct utsname name;
58   des_key_schedule sched;
59   C_Block nonce, nonce2;
60
61   if (send_ok())
62     lose("sending okay for authorization (auth_002)");
63   code = receive_object(conn, (char *)&data, STRING_T);
64   if (code)
65     {
66       code = connection_errno(conn);
67       lose("awaiting Kerberos authenticators");
68     }
69   uname(&name);
70   ticket_st.mbz = 0;
71   ticket_st.length = MAX_STRING_SIZE(data);
72   memcpy(ticket_st.dat, STRING_DATA(data), MAX_STRING_SIZE(data));
73   code = krb_rd_req(&ticket_st, service, krb_get_phost(name.nodename), 0,
74                     &ad, KEYFILE);
75   if (code)
76     {
77       code += ERROR_TABLE_BASE_krb;
78       strcpy(ad.pname, qmark);
79       strcpy(ad.pinst, qmark);
80       strcpy(ad.prealm, qmark);
81       goto auth_failed;
82     }
83
84   /* If there is an auth record in the config file matching the
85    * authenticator we received, then accept it.  If there's no
86    * auth record, assume [master]@[local realm].
87    */
88   if (first = p = config_lookup("auth"))
89     {
90       do
91         {
92           kname_parse(aname, ainst, arealm, p);
93           if (strcmp(aname, ad.pname) ||
94               strcmp(ainst, ad.pinst) ||
95               strcmp(arealm, ad.prealm))
96             p = config_lookup("auth");
97           else
98             p = first;
99         }
100       while (p != first);
101     }
102   else
103     {
104       strcpy(aname, master);
105       strcpy(ainst, "");
106       if (krb_get_lrealm(arealm, 1))
107         strcpy(arealm, KRB_REALM);
108     }
109   code = EPERM;
110   if (strcmp(aname, ad.pname) ||
111       strcmp(ainst, ad.pinst) ||
112       strcmp(arealm, ad.prealm))
113     goto auth_failed;
114
115   if (send_ok())
116     lose("sending preliminary approval of authorization");
117
118   /* replay protection */
119   des_random_key(&nonce);
120   STRING_DATA(data) = (char *)nonce;
121   MAX_STRING_SIZE(data) = 8;
122   if (send_object(conn, (char *)&data, STRING_T))
123     lose("sending nonce");
124   code = receive_object(conn, (char *)&data, STRING_T);
125   if (code)
126     {
127       code = connection_errno(conn);
128       goto auth_failed;
129     }
130   des_key_sched(ad.session, sched);
131   des_ecb_encrypt(STRING_DATA(data), nonce2, sched, 0);
132   if (memcmp(nonce, nonce2, sizeof(nonce)))
133     goto auth_failed;
134
135   if (send_ok())
136     lose("sending approval of authorization");
137   have_authorization = 1;
138   /* Stash away session key */
139   memcpy(session, ad.session, sizeof(session));
140   return 0;
141 auth_failed:
142   sprintf(buf, "auth for %s.%s@%s failed: %s",
143           ad.pname, ad.pinst, ad.prealm, error_message(code));
144   {
145     register int rc;
146     rc = send_object(conn, (char *)&code, INTEGER_T);
147     code = rc;
148   }
149   if (code)
150     lose("sending rejection of authenticator");
151   return EPERM;
152 }
This page took 0.048142 seconds and 5 git commands to generate.