]> andersk Git - moira.git/blobdiff - update/get_file.c
Build without krb4 if it's unavailable.
[moira.git] / update / get_file.c
index 540a2a47a96bd6a29bc040be6b5af49f5a3caab2..337947ac112b3d095184b980f7d720387379f52e 100644 (file)
@@ -1,39 +1,39 @@
-/*
- *     $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 lint
 
 #include <mit-copyright.h>
-#include <stdio.h>
-#include <gdb.h>
-#include <ctype.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <des.h>
-#include <krb.h>
 #include <moira.h>
+#include "update_server.h"
 #include "update.h"
 
-#ifndef MIN
-#define MIN(a,b)    (((a) < (b))?(a):(b))
-#endif /* MIN */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
-extern CONNECTION conn;
-char buf[BUFSIZ];
+#ifdef HAVE_KRB4
+#include <des.h>
+#endif
 
-extern int code, errno, uid;
+RCSID("$Header$");
 
-extern int have_authorization, have_file, done;
-extern C_Block session;
+#ifndef MIN
+#define MIN(a, b)    (((a) < (b)) ? (a) : (b))
+#endif /* MIN */
 
-int get_block();
+#ifdef HAVE_KRB4
+static des_key_schedule sched;
+static des_cblock ivec;
+extern des_cblock session;
+#endif
+
+static int get_block(int conn, int fd, int max_size, int encrypt);
 
 /*
  * get_file()
@@ -67,169 +67,157 @@ int get_block();
  *
  */
 
-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();
-    if (setreuid(0, uid) < 0) {
-       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)");
-    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);
-    }
-    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);
+      n_written += n_got;
+      if (n_written != file_size)
+       send_ok(conn);
     }
-    /* 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;
-    int n_read, n;
+  char *data;
+  size_t len;
+  int n_read, n, i, code;
 
-    code = receive_object(conn, (char *)&data, STRING_T);
-    if (code) {
-       code = connection_errno(conn);
-       lose("receiving data file (get_file)");
-    }
-    n_read = MIN(MAX_STRING_SIZE(data), max_size);
-    if (encrypt) {
-       des_key_schedule sched;
-       des_cblock ivec;
-       STRING newdata;
-
-       des_key_sched(session, sched);
-       bzero(ivec, sizeof(ivec));
-       STRING_DATA(newdata) = (char *) malloc(n_read+9);
-       des_pcbc_encrypt(STRING_DATA(data), STRING_DATA(newdata),
-                        n_read, sched, &ivec, 1);
-       string_free(&data);
-       data.ptr = newdata.ptr;
+  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 = 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;
 }
This page took 0.216343 seconds and 4 git commands to generate.