3 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
8 #include <mit-copyright.h>
10 #include "update_server.h"
24 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
27 static des_key_schedule sched;
28 static des_cblock ivec;
29 extern des_cblock session;
31 static int get_block(int conn, int fd, int max_size, int encrypt);
42 * linear checksum of bytes
45 * (initial protocol already done)
46 * <<< (int)code (can we accept the file?)
52 * >>> (STRING)data (last data block)
53 * <<< (int)code (from read, write, checksum verify)
57 * 0 for success, 1 for failure
60 * perform initial preparations and receive file as
61 * a single string, storing it into <pathname>
65 int get_file(int conn, char *pathname, int file_size, int checksum,
66 int mode, int encrypt)
68 int fd, n_written, code;
72 if (!have_authorization)
74 send_int(conn, MR_PERM);
79 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
84 if (!config_lookup("noclobber"))
86 /* open file descriptor */
87 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
91 com_err(whoami, errno, "creating file %s (get_file)", pathname);
95 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
101 /* check to see if we've got the disk space */
103 while (n_written < file_size)
106 n_wrote = write(fd, buf, sizeof(buf));
110 com_err(whoami, code, "verifying free disk space for %s (get_file)",
112 send_int(conn, code);
114 /* do all we can to free the space */
121 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
126 n_written += n_wrote;
129 lseek(fd, 0, SEEK_SET);
134 des_key_sched(session, sched);
135 memcpy(ivec, session, sizeof(ivec));
139 while (n_written < file_size)
141 int n_got = get_block(conn, fd, file_size - n_written, encrypt);
145 /* get_block has already printed a message */
149 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
155 if (n_written != file_size)
160 ftruncate(fd, file_size);
166 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
170 /* validate checksum */
171 found_checksum = checksum_file(pathname);
172 if (checksum != found_checksum)
174 code = MR_MISSINGFILE;
175 com_err(whoami, code, ": expected = %d, found = %d",
176 checksum, found_checksum);
177 send_int(conn, code);
185 static int get_block(int conn, int fd, int max_size, int encrypt)
189 int n_read, n, i, code;
191 recv_string(conn, &data, &len);
195 char *unenc = malloc(len);
199 send_int(conn, ENOMEM);
203 des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
204 for (i = 0; i < 8; i++)
205 ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
210 n_read = MIN(len, max_size);
215 n_wrote = write(fd, data + n, n_read - n);
219 com_err(whoami, errno, "writing file (get_file)");
220 send_int(conn, code);