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"
25 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
28 static des_key_schedule sched;
29 static des_cblock ivec;
30 extern des_cblock session;
32 static int get_block(int conn, int fd, int max_size, int encrypt);
43 * linear checksum of bytes
46 * (initial protocol already done)
47 * <<< (int)code (can we accept the file?)
53 * >>> (STRING)data (last data block)
54 * <<< (int)code (from read, write, checksum verify)
58 * 0 for success, 1 for failure
61 * perform initial preparations and receive file as
62 * a single string, storing it into <pathname>
66 int get_file(int conn, char *pathname, int file_size, int checksum,
67 int mode, int encrypt)
69 int fd, n_written, code;
73 if (!have_authorization)
75 send_int(conn, MR_PERM);
80 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
85 if (!config_lookup("noclobber"))
87 /* open file descriptor */
88 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
92 com_err(whoami, errno, "creating file %s (get_file)", pathname);
96 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
102 /* check to see if we've got the disk space */
104 while (n_written < file_size)
107 n_wrote = write(fd, buf, sizeof(buf));
111 com_err(whoami, code, "verifying free disk space for %s (get_file)",
113 send_int(conn, code);
115 /* do all we can to free the space */
122 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
127 n_written += n_wrote;
130 lseek(fd, 0, SEEK_SET);
135 des_key_sched(session, sched);
136 memcpy(ivec, session, sizeof(ivec));
140 while (n_written < file_size)
142 int n_got = get_block(conn, fd, file_size - n_written, encrypt);
146 /* get_block has already printed a message */
150 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
156 if (n_written != file_size)
161 ftruncate(fd, file_size);
167 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
171 /* validate checksum */
172 found_checksum = checksum_file(pathname);
173 if (checksum != found_checksum)
175 code = MR_MISSINGFILE;
176 com_err(whoami, code, ": expected = %d, found = %d",
177 checksum, found_checksum);
178 send_int(conn, code);
186 static int get_block(int conn, int fd, int max_size, int encrypt)
190 int n_read, n, i, code;
192 recv_string(conn, &data, &len);
196 char *unenc = malloc(len);
200 send_int(conn, ENOMEM);
204 des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
205 for (i = 0; i < 8; i++)
206 ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
211 n_read = MIN(len, max_size);
216 n_wrote = write(fd, data + n, n_read - n);
220 com_err(whoami, errno, "writing file (get_file)");
221 send_int(conn, code);