]> andersk Git - moira.git/blame - update/get_file.c
make encrypted transfers work
[moira.git] / update / get_file.c
CommitLineData
de56407f 1/*
2 * $Source$
3 * $Header$
4 */
546bc43b 5/* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
6/* For copying and distribution information, please see the file */
7/* <mit-copyright.h>. */
de56407f 8
9#ifndef lint
10static char *rcsid_get_file_c = "$Header$";
11#endif lint
12
546bc43b 13#include <mit-copyright.h>
de56407f 14#include <stdio.h>
ea579254 15#include <gdb.h>
de56407f 16#include <ctype.h>
17#include <sys/param.h>
18#include <sys/file.h>
32df7737 19#include <des.h>
20#include <krb.h>
2ad0a777 21#include <moira.h>
de56407f 22#include "update.h"
de56407f 23
7b18e95b 24#ifndef MIN
25#define MIN(a,b) (((a) < (b))?(a):(b))
26#endif /* MIN */
27
de56407f 28extern CONNECTION conn;
29char buf[BUFSIZ];
30
35fd45e2 31extern int code, errno, uid;
de56407f 32
33extern int have_authorization, have_file, done;
32df7737 34extern C_Block session;
d599d457 35static des_key_schedule sched;
36static des_cblock ivec;
de56407f 37
38int get_block();
39
40/*
41 * get_file()
42 *
43 * arguments:
44 * char *pathname
45 * file to receive
46 * int file_size
47 * number of bytes
48 * int checksum
49 * linear checksum of bytes
50 *
51 * syntax:
52 * (initial protocol already done)
53 * <<< (int)code (can we accept the file?)
54 * >>> (STRING)data
55 * <<< (int)code
56 * >>> (STRING)data
57 * <<< (int)code
58 * ...
59 * >>> (STRING)data (last data block)
60 * <<< (int)code (from read, write, checksum verify)
61 *
62 * returns:
63 * int
64 * 0 for success, 1 for failure
65 *
66 * function:
67 * perform initial preparations and receive file as
68 * a single string, storing it into <pathname>
69 *
70 */
71
72int
32df7737 73get_file(pathname, file_size, checksum, mode, encrypt)
de56407f 74 char *pathname;
75 int file_size;
76 int checksum;
35fd45e2 77 int mode;
32df7737 78 int encrypt;
de56407f 79{
80 int fd, n_written;
81 int found_checksum;
82
83 if (!have_authorization) {
2ad0a777 84 reject_call(MR_PERM);
de56407f 85 return(1);
86 }
87 if (done) /* re-initialize data */
88 initialize();
35fd45e2 89 if (setreuid(0, uid) < 0) {
90 com_err(whoami, errno, "Unable to setuid to %d\n", uid);
91 exit(1);
92 }
de56407f 93 /* unlink old file */
35fd45e2 94 if (!config_lookup("noclobber"))
95 (void) unlink(pathname);
de56407f 96 /* open file descriptor */
35fd45e2 97 fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode);
de56407f 98 if (fd == -1) {
99 code = errno;
100 sprintf(buf, "%s: creating file %s (get_file)",
101 error_message(code), pathname);
2ad0a777 102 mr_log_error(buf);
de56407f 103 report_error("reporting file creation error (get_file)");
35fd45e2 104 if (setuid(0) < 0) {
105 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
106 exit(1);
107 }
de56407f 108 return(1);
109 }
110 /* check to see if we've got the disk space */
111 n_written = 0;
112 while (n_written < file_size) {
113 register int n_wrote;
114 n_wrote = write(fd, buf, sizeof(buf));
115 if (n_wrote == -1) {
116 code = errno;
117 sprintf(buf, "%s: verifying free disk space for %s (get_file)",
118 error_message(code), pathname);
2ad0a777 119 mr_log_error(buf);
de56407f 120 /* do all we can to free the space */
121 (void) unlink(pathname);
122 (void) ftruncate(fd, 0);
123 (void) close(fd);
124 report_error("reporting test-write error (get_file)");
35fd45e2 125 if (setuid(0) < 0) {
126 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
127 exit(1);
128 }
de56407f 129 return(1);
130 }
131 n_written += n_wrote;
132 }
133 lseek(fd, 0, L_SET);
134 if (send_ok())
135 lose("sending okay for file transfer (get_file)");
d599d457 136 if (encrypt) {
137#ifdef DEBUG
138 com_err(whoami, 0, "Session %02x %02x %02x %02x %02x %02x %02x %02x",
139 session[0], session[1], session[2], session[3],
140 session[4], session[5], session[6], session[7]);
141#endif /* DEBUG */
142 des_key_sched(session, sched);
143 bcopy(session, ivec, sizeof(ivec));
144 }
de56407f 145 n_written = 0;
146 while (n_written < file_size && code == 0) {
32df7737 147 int n_got = get_block(fd, file_size - n_written, encrypt);
de56407f 148 if (n_got == -1) {
149 /* get_block has already printed a message */
150 unlink(pathname);
35fd45e2 151 if (setuid(0) < 0) {
152 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
153 exit(1);
154 }
de56407f 155 return(1);
156 }
157 n_written += n_got;
158 if (n_written != file_size)
159 if (send_ok())
160 lose("receiving data");
161 }
162 if (code) {
163 code = connection_errno(conn);
164 report_error("reading file (get_file)");
35fd45e2 165 if (setuid(0) < 0) {
166 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
167 exit(1);
168 }
de56407f 169 return(1);
170 }
171 fsync(fd);
172 ftruncate(fd, file_size);
173 fsync(fd);
174 close(fd);
35fd45e2 175 if (setuid(0) < 0) {
176 com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
177 exit(1);
178 }
de56407f 179 /* validate checksum */
ea579254 180 found_checksum = checksum_file(pathname);
de56407f 181 if (checksum != found_checksum) {
2ad0a777 182 code = MR_MISSINGFILE;
de56407f 183 com_err(whoami, code, ": expected = %d, found = %d",
184 checksum, found_checksum);
185 report_error("checksum error");
186 return(1);
187 }
de56407f 188 /* send ack or nack */
189 have_file = 1;
190 if (send_ok()) {
191 code = connection_errno(conn);
192 (void) unlink(pathname);
193 lose("sending ok after file transfer (get_file)");
194 return(1);
195 }
196 return(0);
197}
198
199static int
32df7737 200get_block(fd, max_size, encrypt)
de56407f 201 int fd;
202 int max_size;
32df7737 203 int encrypt;
de56407f 204{
205 STRING data;
d599d457 206 unsigned char dst[UPDATE_BUFSIZ + 8], *src;
207 int n_read, n, i;
de56407f 208
209 code = receive_object(conn, (char *)&data, STRING_T);
210 if (code) {
211 code = connection_errno(conn);
212 lose("receiving data file (get_file)");
213 }
32df7737 214
d599d457 215 if (encrypt) {
216 src = (unsigned char *)STRING_DATA(data);
217 n = MAX_STRING_SIZE(data);
218 des_pcbc_encrypt(src, dst, n, sched, ivec, 1);
219 for (i = 0; i < 8; i++)
220 ivec[i] = src[n - 8 + i] ^ dst[n - 8 + i];
221 bcopy(dst, STRING_DATA(data), n);
32df7737 222 }
223
d599d457 224 n_read = MIN(MAX_STRING_SIZE(data), max_size);
de56407f 225 n = 0;
226 while (n < n_read) {
227 register int n_wrote;
228 n_wrote = write(fd, STRING_DATA(data)+n,
229 n_read-n);
230 if (n_wrote == -1) {
231 code = errno;
232 sprintf(buf, "%s: writing file (get_file)", error_message(code));
2ad0a777 233 mr_log_error(buf);
de56407f 234 string_free(&data);
235 report_error("reporting write error (get_file)");
236 close(fd);
237 return(-1);
238 }
239 n += n_wrote;
240 }
241 string_free(&data);
242 return(n);
243}
This page took 0.95451 seconds and 5 git commands to generate.