1 /* utftpd_send.c: server side sending code */
2 
3 /*
4  * Copyright (C) 1999 Uwe Ohse
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 #include "config.h"
22 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <signal.h>
27 
28 #include <sys/socket.h>
29 #include <sys/stat.h>
30 #include <netinet/in.h>
31 #include "no_tftp.h"
32 
33 #include <syslog.h>
34 #include <errno.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include "timselsysdep.h"
38 #include "str2num.h"
39 #include "uostr.h"
40 #include "uoio.h"
41 #include "utftpd.h"
42 
43 #define ERR_LOG1(x) do { const char *er=strerror(safe_errno); syslog(LOG_ERR,x,er); } while(1)
44 #define ERR_LOG2(x,y) do { const char *er=strerror(safe_errno); syslog(LOG_ERR,x,y,er); } while(1)
45 #define ERR_LOG3(x,y,z) do { const char *er=strerror(safe_errno); syslog(LOG_ERR,x,y,z,er); } while(1)
46 #define ES(x) do {int safe_errno=errno; { x } errno=safe_errno; } while(0)
47 
48 static int got_sig;
49 static void
50 sig_handler(int signo)
51 {
52 	got_sig=signo;
53 }
54 
55 
56 int
57 utftpd_send(struct utftpd_ctrl *flags)
58 {
59 	uoio_t io;
60 	int blockno;
61 	int lastchar=0; /* in case of netascii */
62 	const char *errortext;
63 	struct sigaction sa,sa_old;
64 	int got_timeouts=0;
65 	struct stat st;
66 	int sorcerers_problem;
67 
68 	if (0!=fstat(flags->filefd,&st)) {
69 		int e=errno;
70 		const char *cs=strerror(errno);
71 		syslog(LOG_ERR,"fstat(%s): %s",flags->filename, cs);
72 		if (e==ENOENT) utftpd_nak(flags->remotefd,ENOTFOUND,cs,flags);
73 		if (e==EACCES) utftpd_nak(flags->remotefd,EACCESS,cs,flags);
74 		else utftpd_nak(flags->remotefd,EUNDEF,cs,flags);
75 		errno=e;
76 		return 1;
77 	} else if (!(S_ISREG(st.st_mode))) {
78 		/* if sending a version controlled file we will read from a pipe */
79 		if (flags->vc==&utftpd_novc) {
80 			syslog(LOG_ERR,"%s: is not a regular file",flags->filename);
81 			utftpd_nak(flags->remotefd,EUNDEF,"not a regular file",flags);
82 			return 1;
83 		}
84 	}
85 	/* if we are root be even more restrictive */
86 	if (getuid()==0) {
87 		if (!(st.st_mode & S_IROTH)) {
88 			int e=errno;
89 			syslog(LOG_ERR,"%s: not readable for everybody",flags->filename);
90 			utftpd_nak(flags->remotefd,EACCESS,"access denied",flags);
91 			errno=e;
92 			return 1;
93 		}
94 	}
95 	sa.sa_handler = sig_handler;
96 	sa.sa_flags = 0;
97 	sigemptyset (&sa.sa_mask);
98 	sigaction (SIGALRM, &sa, &sa_old);
99 
100 	uoio_assign_r(&io,flags->filefd,read,0);
101 
102 	blockno=1;
103 	while (1) {
104 		ssize_t len;
105 		int got_eof=0;
106 		int tryno;
107 		/* get data, if needed */
108 		if (flags->first_packet_length) {
109 			/* we have to send an OACK before ... */
110 			blockno=0; /* and expect an ACK for packet 0 */
111 			len=flags->first_packet_length;
112 			flags->first_packet_length=0;
113 		} else {
114 			if (flags->netascii) {
115 				char c;
116 				/* LF -> CR LF, CR -> CR nul .... what a stupid thing :-) */
117 				for (len=0;len<(ssize_t) flags->segsize;len++) {
118 					ssize_t l;
119 					if (lastchar=='\r') { c=0; lastchar = 0; }
120 					else if (lastchar =='\n') { c='\n'; lastchar = 0; }
121 					else {
122 						l=uoio_getchar(&io,&c);
123 						if (l==-1) {
124 							errortext=strerror(errno);
125 							ES( syslog(LOG_ERR,"read(%s): %s",flags->filename,errortext););
126 							goto do_error_nak;
127 						}
128 						if (l==0) {got_eof=1; break;}
129 						lastchar=c;
130 						if (c=='\n') c='\r';
131 					}
132 					flags->sendbuf.buf[TFTP_OFFSET+len]=c;
133 				}
134 			} else {
135 				len=uoio_getmem(&io,flags->sendbuf.buf+TFTP_OFFSET,flags->segsize);
136 				if (len==-1) {
137 					errortext=strerror(errno);
138 					ES(syslog(LOG_ERR,"read(%s): %s",flags->filename,errortext););
139 					goto do_error_nak;
140 				}
141 				if (len==0) got_eof=1;
142 			}
143 			flags->sendbuf.hdr->th_opcode = htons((u_short)DATA);
144 			flags->sendbuf.hdr->th_block = htons((u_short)blockno);
145 			flags->bytes+=len;
146 		}
147 		if (got_eof) {
148 			if (flags->pid) {
149 				int fail;
150 				fail=wait_check_and_log(flags->pid);
151 				if (fail) {
152 					errortext="child terminated abnormally";
153 					goto do_error_nak;
154 				}
155 				flags->pid=0; /* do not wait again */
156 			}
157 		}
158 		tryno=5;
159 		sorcerers_problem=0;
160 		while (1) {
161 			struct tftphdr *rhdr;
162 			ssize_t got;
163 			/* send to the peer */
164 			if (!sorcerers_problem) {
165 				if (send(flags->remotefd, flags->sendbuf.buf, len+TFTP_OFFSET, 0) != len+TFTP_OFFSET) {
166 					errortext=strerror(errno);
167 					ES(syslog(LOG_ERR,"send(): %s",errortext););
168 					goto do_error;
169 				}
170 			}
171 			sorcerers_problem=0;
172 
173 			alarm(flags->timeout * (got_timeouts+1));
174 			got = recv(flags->remotefd, flags->recvbuf.buf, flags->segsize+TFTP_OFFSET, 0);
175 			if (got < 0) {
176 				if (errno==EINTR && got_timeouts++<5) continue;
177 				ES(syslog(LOG_ERR, "recv: %s",strerror(errno)););
178 				goto do_error;
179 			}
180 			got_timeouts=0;
181 
182 			rhdr=(struct tftphdr *)flags->recvbuf.hdr;
183 			rhdr->th_opcode = ntohs((u_short)rhdr->th_opcode);
184 			rhdr->th_block = ntohs((u_short)rhdr->th_block);
185 			if (rhdr->th_opcode == ERROR) {
186 				ES(syslog(LOG_ERR, "got ERROR"););
187 				goto do_error;
188 			}
189 			if (rhdr->th_opcode!=ACK)  {
190 				errortext="unknown TFTP opcode";
191 				ES(syslog(LOG_ERR, "got unknown opcode %d",rhdr->th_opcode););
192 				goto do_error_nak;
193 			}
194 			sorcerers_problem=1;
195 
196 			if (rhdr->th_block == blockno)  /* ACK for our block */
197 				break;
198 			if (rhdr->th_block == blockno-1 && blockno)
199 				sorcerers_problem=1;
200 
201 			/* ACK for something else. Throw away everything the kernel may have buffered */
202 			while (1) {
203 				struct timeval tv;
204 				fd_set set;
205 				FD_ZERO(&set);
206 				FD_SET(flags->remotefd,&set);
207 				tv.tv_sec=0;
208 				tv.tv_usec=0;
209 				if (select(flags->remotefd+1,&set,0,0,&tv)<1)
210 					break;
211 				if (TFTP_OFFSET == recv(flags->remotefd, flags->recvbuf.buf,
212 					flags->segsize +TFTP_OFFSET, 0)) {
213 					rhdr=(struct tftphdr *)flags->recvbuf.hdr;
214 					rhdr->th_opcode = ntohs((u_short)rhdr->th_opcode);
215 					rhdr->th_block = ntohs((u_short)rhdr->th_block);
216 					if (rhdr->th_opcode==ACK && rhdr->th_block==blockno)
217 						break;
218 				}
219 			}
220 			if (rhdr->th_block == blockno)  /* ACK for our block */
221 				break;
222 			/* we will now simply resend the block */
223 		} /* while !ACK for our block */
224 		/* the first packet which is not "full" is the last packet.
225 		 * Except, of course, if the get an OACK, which is block number 0
226 		 */
227 		if (len!=(ssize_t) flags->segsize && blockno!=0)
228 			break;
229 		blockno++;
230 	}
231 	uoio_destroy(&io);
232 	if (flags->pid) {
233 		int fail;
234 		fail=wait_check_and_log(flags->pid);
235 		if (fail) {
236 			errortext="child terminated abnormally";
237 			goto do_error_nak;
238 		}
239 	}
240 	alarm(0);
241 	sigaction(SIGALRM,&sa_old,0);
242 	syslog(LOG_INFO,"did send %s",flags->filename);
243 	return 0;
244   do_error_nak:
245   	ES(
246 		uoio_destroy(&io);
247 		utftpd_nak(flags->remotefd,EUNDEF,errortext,flags);
248 	);
249 	alarm(0);
250 	sigaction(SIGALRM,&sa_old,0);
251 	return -1;
252   do_error:
253   	ES( uoio_destroy(&io););
254 	alarm(0);
255 	sigaction(SIGALRM,&sa_old,0);
256 	return -1;
257 }
258 
259