]> andersk Git - moira.git/blame - update/client.c
Implement AUTH_002, which isn't vulnerable to replay attacks. Remove
[moira.git] / update / client.c
CommitLineData
de56407f 1/*
2 * $Source$
3 * $Header$
4 */
5
6#ifndef lint
7static char *rcsid_client2_c = "$Header$";
8#endif lint
9
10/*
11 * MODULE IDENTIFICATION:
12 * $Header$
546bc43b 13 * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
14 * For copying and distribution information, please see the file
15 * <mit-copyright.h>.
de56407f 16 * DESCRIPTION:
17 * This code handles the actual distribution of data files
2ad0a777 18 * to servers in the MOIRA server-update program.
de56407f 19 * AUTHOR:
20 * Ken Raeburn (spook@athena.MIT.EDU),
21 * MIT Project Athena/MIT Information Systems.
22 * DEFINED VALUES:
23 * conn
2ad0a777 24 * mr_update_server
de56407f 25 */
26
546bc43b 27#include <mit-copyright.h>
de56407f 28#include <stdio.h>
7da203a3 29#include <stdlib.h>
7b48c9f9 30#include <string.h>
7bd50861 31#include <gdb.h>
de56407f 32#include <sys/param.h>
7bd50861 33#include <sys/wait.h>
f5b9994a 34#include <sys/socket.h>
7bd50861 35#include <update.h>
de56407f 36#include <errno.h>
7bd50861 37#include <dcm.h>
2ad0a777 38#include <moira.h>
39#include <moira_site.h>
de56407f 40#include <krb.h>
41
bc6cbc65 42extern int errno, dbg;
be86b0c2 43extern C_Block session;
de56407f 44
de56407f 45static char buf[BUFSIZ];
7bd50861 46static int code;
de56407f 47
48CONNECTION conn;
de56407f 49
de56407f 50
51/*
52 * FUNCTION:
53 * initialize()
54 * DESCRIPTION:
55 * Insures that various libraries have a chance to get
56 * initialized.
57 * INPUT:
58 * OUTPUT:
59 * RETURN VALUE:
60 * void
61 * SIDE EFFECTS:
756e2c48 62 * Initializes GDB library.
de56407f 63 * PROBLEMS:
64 *
65 */
7bd50861 66static void
de56407f 67initialize()
68{
69 static int initialized = 0;
7bd50861 70
de56407f 71 if (!initialized) {
72 gdb_init();
de56407f 73 initialized++;
74 }
75}
76
7bd50861 77
de56407f 78/*
79 * FUNCTION:
2ad0a777 80 * mr_update_server(service, machine, target_path)
de56407f 81 * DESCRIPTION:
7bd50861 82 * Attempts to perform an update to the named machine
a6be2cf4 83 * of the named service. The file DCM_DIR/service.out
7bd50861 84 * will be sent, then the file SMS_DIR/bin/service.sh,
85 * the the shell script will be executed.
de56407f 86 * INPUT:
7bd50861 87 * service
de56407f 88 * Name of service to be updated; used to find
2ad0a777 89 * the source data file in the MR data directory.
7bd50861 90 * machine
91 * target_path
de56407f 92 * Location to install the file.
de56407f 93 * RETURN VALUE:
94 * int:
95 * Error code, or zero if no error was detected
96 * in the data supplied to this routine.
97 * SIDE EFFECTS:
98 * May write information to logs.
99 * PROBLEMS:
100 *
101 */
102
103int
2ad0a777 104mr_update_server(service, machine, target_path, instructions)
7bd50861 105char *service;
106char *machine;
107char *target_path;
108char *instructions;
de56407f 109{
7bd50861 110#define ASSERT(condition,stat,amsg) \
111 if (!(condition)) { com_err(whoami, stat, amsg); return(stat); }
112#define ASSERT2(condition,stat,amsg,arg1) \
113 if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); }
de56407f 114#define NONNULL(str) \
7bd50861 115 (((str) != (char *)NULL) && (strlen(str) != 0))
de56407f 116
7bd50861 117 char *service_address, *service_updated, *pathname;
f5b9994a 118 int on;
de56407f 119
de56407f 120 /* some sanity checking of arguments while we build data */
2ad0a777 121 ASSERT(NONNULL(machine), MR_INTERNAL, " null host name");
122 ASSERT(NONNULL(service), MR_INTERNAL, " null service name");
123 ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), MR_ARG_TOO_LONG,
7bd50861 124 " machine and service names");
125 sprintf(buf, "%s:%s", machine, service);
126 service_updated = strsave(buf);
2ad0a777 127 ASSERT(NONNULL(service_updated), MR_NO_MEM, " for service name");
128 ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), MR_ARG_TOO_LONG,
7bd50861 129 " machine and update service name");
130 sprintf(buf, "%s:%s", machine, SERVICE_NAME);
131 service_address = strsave(buf);
2ad0a777 132 ASSERT(NONNULL(service_address), MR_NO_MEM, " for service address");
133 ASSERT(NONNULL(target_path), MR_INTERNAL, " null target pathname");
134 ASSERT((strlen(target_path) < MAXPATHLEN), MR_ARG_TOO_LONG,
7bd50861 135 " target pathname");
2ad0a777 136 ASSERT2(target_path[0] == '/', MR_NOT_UNIQUE,
7bd50861 137 " non-absolute pathname supplied \"%s\"", target_path);
a6be2cf4 138 sprintf(buf, "%s/%s.out", DCM_DIR, service);
7bd50861 139 pathname = strsave(buf);
2ad0a777 140 ASSERT(NONNULL(pathname), MR_NO_MEM, " for pathname");
141 ASSERT(NONNULL(instructions), MR_NO_MEM, " for instructions");
142 ASSERT((strlen(instructions) < MAXPATHLEN), MR_ARG_TOO_LONG,
7bd50861 143 " instruction pathname");
de56407f 144
145 initialize();
7bd50861 146 com_err(whoami, 0, "starting update for %s", service_updated);
de56407f 147
148 /* open connection */
333d2c82 149 gdb_Options |= GDB_OPT_KEEPALIVE;
5dabdff4 150 conn = start_server_connection(service_address, "");
7bd50861 151 if (!conn || (connection_status(conn) == CON_STOPPED)) {
152 com_err(whoami, connection_errno(conn),
153 " can't connect to update %s", service_address);
2ad0a777 154 return(MR_CANT_CONNECT);
de56407f 155 }
de56407f 156
157 /* send authenticators */
7bd50861 158 code = send_auth(machine);
de56407f 159 if (code) {
7bd50861 160 com_err(whoami, code, " authorization attempt to %s failed",
161 service_updated);
de56407f 162 goto update_failed;
163 }
164
be86b0c2 165 code = send_file(pathname, target_path, 1);
de56407f 166 if (code)
7bd50861 167 goto update_failed;
168
de56407f 169 /* send instructions for installation */
2ad0a777 170 strcpy(buf, "/tmp/moira-update.XXXXXX");
de56407f 171 mktemp(buf);
de940d6f 172 code = send_file(instructions, buf, 0);
de56407f 173 if (code)
7bd50861 174 goto update_failed;
175
de56407f 176 /* perform installation */
177 code = execute(buf);
178 if (code) {
7bd50861 179 com_err(whoami, code, " installation of %s failed, code = %d",
180 service_updated, code);
181 goto update_failed;
de56407f 182 }
183
de56407f 184 /* finished updates */
2ad0a777 185 code = MR_SUCCESS;
7bd50861 186
187 update_failed:
de56407f 188 send_quit();
de56407f 189 conn = sever_connection(conn);
190 return(code);
7bd50861 191
de56407f 192#undef NONNULL
193#undef ASSERT
194}
195
7bd50861 196send_auth(host_name)
197char *host_name;
de56407f 198{
199 KTEXT_ST ticket_st;
200 KTEXT ticket = &ticket_st;
201 STRING data;
202 register int code;
203 int response;
be86b0c2 204 int auth_version = 2;
de56407f 205
2ad0a777 206 code = get_mr_update_ticket(host_name, ticket);
de56407f 207 if (code) {
208 return(code);
209 }
be86b0c2 210 STRING_DATA(data) = "AUTH_002";
de56407f 211 MAX_STRING_SIZE(data) = 9;
212 code = send_object(conn, (char *)&data, STRING_T);
213 if (code) {
214 return(connection_errno(conn));
215 }
216 code = receive_object(conn, (char *)&response, INTEGER_T);
217 if (code) {
218 return(connection_errno(conn));
219 }
220 if (response) {
be86b0c2 221 STRING_DATA(data) = "AUTH_001";
222 MAX_STRING_SIZE(data) = 9;
223 code = send_object(conn, (char *)&data, STRING_T);
224 if (code) {
225 return(connection_errno(conn));
226 }
227 code = receive_object(conn, (char *)&response, INTEGER_T);
228 if (code) {
229 return(connection_errno(conn));
230 }
231 if (response) {
232 return(response);
233 }
234 auth_version = 1;
de56407f 235 }
236 STRING_DATA(data) = (char *)ticket->dat;
237 MAX_STRING_SIZE(data) = ticket->length;
238 code = send_object(conn, (char *)&data, STRING_T);
239 if (code) {
240 return(connection_errno(conn));
241 }
242 code = receive_object(conn, (char *)&response, INTEGER_T);
243 if (code) {
244 return(connection_errno(conn));
245 }
246 if (response) {
247 return(response);
248 }
be86b0c2 249
250 if (auth_version == 2) {
251 des_key_schedule sched;
252 C_Block enonce;
253
254 code = receive_object(conn, (char *)&data, STRING_T);
255 if (code) {
256 return(connection_errno(conn));
257 }
258 des_key_sched(&session, &sched);
259 des_ecb_encrypt(STRING_DATA(data), enonce, sched, 1);
260 STRING_DATA(data) = enonce;
261 code = send_object(conn, (char *)&data, STRING_T);
262 if (code) {
263 return(connection_errno(conn));
264 }
265 code = receive_object(conn, (char *)&response, INTEGER_T);
266 if (code) {
267 return(connection_errno(conn));
268 }
269 if (response) {
270 return(response);
271 }
272 }
273
2ad0a777 274 return(MR_SUCCESS);
de56407f 275}
276
de56407f 277execute(path)
278 char *path;
279{
1e447eb1 280 int response;
de56407f 281 STRING data;
282 register int code;
283
284 string_alloc(&data, BUFSIZ);
285 sprintf(STRING_DATA(data), "EXEC_002 %s", path);
286 code = send_object(conn, (char *)&data, STRING_T);
287 if (code)
288 return(connection_errno(conn));
289 code = receive_object(conn, (char *)&response, INTEGER_T);
290 if (code)
291 return(connection_errno(conn));
1e447eb1 292 if (response)
293 return(response);
2ad0a777 294 return(MR_SUCCESS);
de56407f 295}
296
297send_quit()
298{
299 STRING str;
300 if (!conn)
301 return;
302 string_alloc(&str, 5);
303 (void) strcpy(STRING_DATA(str), "quit");
304 (void) send_object(conn, (char *)&str, STRING_T);
305 string_free(&str);
306}
This page took 0.151936 seconds and 5 git commands to generate.