-/*
- * $Source$
- * $Header$
+/* $Id$
+ *
+ * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*/
-/* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
-/* For copying and distribution information, please see the file */
-/* <mit-copyright.h>. */
-
-#ifndef lint
-static char *rcsid_get_file_c = "$Header$";
-#endif
#include <mit-copyright.h>
+#include <moira.h>
+#include "update_server.h"
+#include "update.h"
+
+#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
-#include <gdb.h>
-#include <ctype.h>
+#include <stdlib.h>
#include <string.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef HAVE_KRB4
#include <des.h>
-#include <krb.h>
-#include <moira.h>
-#include "update.h"
+#endif
+
+RCSID("$Header$");
#ifndef MIN
-#define MIN(a,b) (((a) < (b))?(a):(b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif /* MIN */
-extern CONNECTION conn;
-extern char buf[BUFSIZ];
-
-extern int code, errno, uid;
-extern char *whoami;
-
-extern int have_authorization, have_file, done;
-extern C_Block session;
+#ifdef HAVE_KRB4
static des_key_schedule sched;
static des_cblock ivec;
+extern des_cblock session;
+#endif
-static int get_block();
+static int get_block(int conn, int fd, int max_size, int encrypt);
/*
* get_file()
*
*/
-int
-get_file(pathname, file_size, checksum, mode, encrypt)
- char *pathname;
- int file_size;
- int checksum;
- int mode;
- int encrypt;
+int get_file(int conn, char *pathname, int file_size, int checksum,
+ int mode, int encrypt)
{
- int fd, n_written;
- int found_checksum;
-
- if (!have_authorization) {
- reject_call(MR_PERM);
- return(1);
+ int fd, n_written, code;
+ int found_checksum;
+ char buf[BUFSIZ];
+
+ memset(buf, '\0', sizeof(buf));
+
+ if (!have_authorization)
+ {
+ send_int(conn, MR_PERM);
+ return 1;
}
- if (done) /* re-initialize data */
- initialize();
-#ifdef POSIX
- if (setuid(uid) < 0) {
-#else
- if (setreuid(0, uid) < 0) {
-#endif
- com_err(whoami, errno, "Unable to setuid to %d\n", uid);
- exit(1);
+ if (setuid(uid) < 0)
+ {
+ com_err(whoami, errno, "Unable to setuid to %d\n", uid);
+ exit(1);
}
- /* unlink old file */
- if (!config_lookup("noclobber"))
- (void) unlink(pathname);
- /* open file descriptor */
- fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
- if (fd == -1) {
- code = errno;
- sprintf(buf, "%s: creating file %s (get_file)",
- error_message(code), pathname);
- mr_log_error(buf);
- report_error("reporting file creation error (get_file)");
- if (setuid(0) < 0) {
- com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
- exit(1);
- }
- return(1);
+
+ /* unlink old file */
+ if (!config_lookup("noclobber"))
+ unlink(pathname);
+ /* open file descriptor */
+ fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
+ if (fd == -1)
+ {
+ code = errno;
+ com_err(whoami, errno, "creating file %s (get_file)", pathname);
+ send_int(conn, code);
+ return 1;
}
- /* check to see if we've got the disk space */
- n_written = 0;
- while (n_written < file_size) {
- register int n_wrote;
- n_wrote = write(fd, buf, sizeof(buf));
- if (n_wrote == -1) {
- code = errno;
- sprintf(buf, "%s: verifying free disk space for %s (get_file)",
- error_message(code), pathname);
- mr_log_error(buf);
- /* do all we can to free the space */
- (void) unlink(pathname);
- (void) ftruncate(fd, 0);
- (void) close(fd);
- report_error("reporting test-write error (get_file)");
- if (setuid(0) < 0) {
- com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
- exit(1);
- }
- return(1);
+
+ /* check to see if we've got the disk space */
+ n_written = 0;
+ while (n_written < file_size)
+ {
+ int n_wrote;
+ n_wrote = write(fd, buf, sizeof(buf));
+ if (n_wrote == -1)
+ {
+ code = errno;
+ com_err(whoami, code, "verifying free disk space for %s (get_file)",
+ pathname);
+ send_int(conn, code);
+
+ /* do all we can to free the space */
+ unlink(pathname);
+ ftruncate(fd, 0);
+ close(fd);
+ return 1;
}
- n_written += n_wrote;
+ n_written += n_wrote;
}
- lseek(fd, 0, L_SET);
- if (send_ok())
- lose("sending okay for file transfer (get_file)");
- if (encrypt) {
-#ifdef DEBUG
- com_err(whoami, 0, "Session %02x %02x %02x %02x %02x %02x %02x %02x",
- session[0], session[1], session[2], session[3],
- session[4], session[5], session[6], session[7]);
-#endif /* DEBUG */
- des_key_sched(session, sched);
- memcpy(ivec, session, sizeof(ivec));
- }
- n_written = 0;
- while (n_written < file_size && code == 0) {
- int n_got = get_block(fd, file_size - n_written, encrypt);
- if (n_got == -1) {
- /* get_block has already printed a message */
- unlink(pathname);
- if (setuid(0) < 0) {
- com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
- exit(1);
- }
- return(1);
- }
- n_written += n_got;
- if (n_written != file_size)
- if (send_ok())
- lose("receiving data");
+
+ lseek(fd, 0, SEEK_SET);
+ send_ok(conn);
+
+ if (encrypt)
+ {
+#ifdef HAVE_KRB4
+ des_key_sched(session, sched);
+ memcpy(ivec, session, sizeof(ivec));
+#else
+ /* The session key only gets stored if auth happens in krb4 to
+ begin with. If you don't have krb4, you can't possibly be
+ coming up with a valid session key. */
+ return MR_NO_KRB4;
+#endif
}
- if (code) {
- code = connection_errno(conn);
- report_error("reading file (get_file)");
- if (setuid(0) < 0) {
- com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
- exit(1);
+
+ n_written = 0;
+ while (n_written < file_size)
+ {
+ int n_got = get_block(conn, fd, file_size - n_written, encrypt);
+
+ if (n_got == -1)
+ {
+ /* get_block has already printed a message */
+ unlink(pathname);
+ return 1;
}
- return(1);
+ n_written += n_got;
+ if (n_written != file_size)
+ send_ok(conn);
}
- fsync(fd);
- ftruncate(fd, file_size);
- fsync(fd);
- close(fd);
- if (setuid(0) < 0) {
- com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
- exit(1);
- }
- /* validate checksum */
- found_checksum = checksum_file(pathname);
- if (checksum != found_checksum) {
- code = MR_MISSINGFILE;
- com_err(whoami, code, ": expected = %d, found = %d",
- checksum, found_checksum);
- report_error("checksum error");
- return(1);
- }
- /* send ack or nack */
- have_file = 1;
- if (send_ok()) {
- code = connection_errno(conn);
- (void) unlink(pathname);
- lose("sending ok after file transfer (get_file)");
- return(1);
+
+ fsync(fd);
+ ftruncate(fd, file_size);
+ fsync(fd);
+ close(fd);
+
+ /* validate checksum */
+ found_checksum = checksum_file(pathname);
+ if (checksum != found_checksum)
+ {
+ code = MR_MISSINGFILE;
+ com_err(whoami, code, ": expected = %d, found = %d",
+ checksum, found_checksum);
+ send_int(conn, code);
+ return 1;
}
- return(0);
+
+ send_ok(conn);
+ return 0;
}
-static int
-get_block(fd, max_size, encrypt)
- int fd;
- int max_size;
- int encrypt;
+static int get_block(int conn, int fd, int max_size, int encrypt)
{
- STRING data;
- unsigned char dst[UPDATE_BUFSIZ + 8], *src;
- int n_read, n, i;
-
- code = receive_object(conn, (char *)&data, STRING_T);
- if (code) {
- code = connection_errno(conn);
- lose("receiving data file (get_file)");
- }
+ char *data;
+ size_t len;
+ int n_read, n, i, code;
- if (encrypt) {
- src = (unsigned char *)STRING_DATA(data);
- n = MAX_STRING_SIZE(data);
- des_pcbc_encrypt(src, dst, n, sched, ivec, 1);
- for (i = 0; i < 8; i++)
- ivec[i] = src[n - 8 + i] ^ dst[n - 8 + i];
- memcpy(STRING_DATA(data), dst, n);
+ recv_string(conn, &data, &len);
+
+ if (encrypt)
+ {
+#ifdef HAVE_KRB4
+ char *unenc = malloc(len);
+
+ if (!unenc)
+ {
+ send_int(conn, ENOMEM);
+ return -1;
+ }
+
+ des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
+ for (i = 0; i < 8; i++)
+ ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
+ free(data);
+ data = unenc;
+#endif
}
- n_read = MIN(MAX_STRING_SIZE(data), max_size);
- n = 0;
- while (n < n_read) {
- register int n_wrote;
- n_wrote = write(fd, STRING_DATA(data)+n,
- n_read-n);
- if (n_wrote == -1) {
- code = errno;
- sprintf(buf, "%s: writing file (get_file)", error_message(code));
- mr_log_error(buf);
- string_free(&data);
- report_error("reporting write error (get_file)");
- close(fd);
- return(-1);
+ n_read = MIN(len, max_size);
+ n = 0;
+ while (n < n_read)
+ {
+ int n_wrote;
+ n_wrote = write(fd, data + n, n_read - n);
+ if (n_wrote == -1)
+ {
+ code = errno;
+ com_err(whoami, errno, "writing file (get_file)");
+ send_int(conn, code);
+ free(data);
+ close(fd);
+ return -1;
}
- n += n_wrote;
+ n += n_wrote;
}
- string_free(&data);
- return(n);
+ free(data);
+ return n;
}