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"
27 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
31 static des_key_schedule sched;
32 static des_cblock ivec;
33 extern des_cblock session;
36 static int get_block(int conn, int fd, int max_size, int encrypt);
47 * linear checksum of bytes
50 * (initial protocol already done)
51 * <<< (int)code (can we accept the file?)
57 * >>> (STRING)data (last data block)
58 * <<< (int)code (from read, write, checksum verify)
62 * 0 for success, 1 for failure
65 * perform initial preparations and receive file as
66 * a single string, storing it into <pathname>
70 int get_file(int conn, char *pathname, int file_size, int checksum,
71 int mode, int encrypt)
73 int fd, n_written, code;
77 memset(buf, '\0', sizeof(buf));
79 if (!have_authorization)
81 send_int(conn, MR_PERM);
86 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
91 if (!config_lookup("noclobber"))
93 /* open file descriptor */
94 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
98 com_err(whoami, errno, "creating file %s (get_file)", pathname);
103 /* check to see if we've got the disk space */
105 while (n_written < file_size)
108 n_wrote = write(fd, buf, sizeof(buf));
112 com_err(whoami, code, "verifying free disk space for %s (get_file)",
114 send_int(conn, code);
116 /* do all we can to free the space */
122 n_written += n_wrote;
125 lseek(fd, 0, SEEK_SET);
131 des_key_sched(session, sched);
132 memcpy(ivec, session, sizeof(ivec));
134 /* The session key only gets stored if auth happens in krb4 to
135 begin with. If you don't have krb4, you can't possibly be
136 coming up with a valid session key. */
142 while (n_written < file_size)
144 int n_got = get_block(conn, fd, file_size - n_written, encrypt);
148 /* get_block has already printed a message */
153 if (n_written != file_size)
158 ftruncate(fd, file_size);
162 /* validate checksum */
163 found_checksum = checksum_file(pathname);
164 if (checksum != found_checksum)
166 code = MR_MISSINGFILE;
167 com_err(whoami, code, ": expected = %d, found = %d",
168 checksum, found_checksum);
169 send_int(conn, code);
177 static int get_block(int conn, int fd, int max_size, int encrypt)
181 int n_read, n, i, code;
183 recv_string(conn, &data, &len);
188 char *unenc = malloc(len);
192 send_int(conn, ENOMEM);
196 des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
197 for (i = 0; i < 8; i++)
198 ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
204 n_read = MIN(len, max_size);
209 n_wrote = write(fd, data + n, n_read - n);
213 com_err(whoami, errno, "writing file (get_file)");
214 send_int(conn, code);