1 /*
2  *  linux/fs/ncpfs/sock.c
3  *
4  *  Copyright (C) 1992, 1993  Rick Sladkey
5  *
6  *  Modified 1995, 1996 by Volker Lendecke to be usable for ncp
7  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
8  *
9  */
10 
11 
12 #include <linux/time.h>
13 #include <linux/errno.h>
14 #include <linux/socket.h>
15 #include <linux/fcntl.h>
16 #include <linux/stat.h>
17 #include <linux/string.h>
18 #include <asm/uaccess.h>
19 #include <linux/in.h>
20 #include <linux/net.h>
21 #include <linux/mm.h>
22 #include <linux/netdevice.h>
23 #include <linux/signal.h>
24 #include <linux/slab.h>
25 #include <net/scm.h>
26 #include <net/sock.h>
27 #include <linux/ipx.h>
28 #include <linux/poll.h>
29 #include <linux/file.h>
30 
31 #include "ncp_fs.h"
32 
33 #include "ncpsign_kernel.h"
34 
_recv(struct socket * sock,void * buf,int size,unsigned flags)35 static int _recv(struct socket *sock, void *buf, int size, unsigned flags)
36 {
37 	struct msghdr msg = {NULL, };
38 	struct kvec iov = {buf, size};
39 	return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);
40 }
41 
do_send(struct socket * sock,struct kvec * vec,int count,int len,unsigned flags)42 static inline int do_send(struct socket *sock, struct kvec *vec, int count,
43 			  int len, unsigned flags)
44 {
45 	struct msghdr msg = { .msg_flags = flags };
46 	return kernel_sendmsg(sock, &msg, vec, count, len);
47 }
48 
_send(struct socket * sock,const void * buff,int len)49 static int _send(struct socket *sock, const void *buff, int len)
50 {
51 	struct kvec vec;
52 	vec.iov_base = (void *) buff;
53 	vec.iov_len = len;
54 	return do_send(sock, &vec, 1, len, 0);
55 }
56 
57 struct ncp_request_reply {
58 	struct list_head req;
59 	wait_queue_head_t wq;
60 	atomic_t refs;
61 	unsigned char* reply_buf;
62 	size_t datalen;
63 	int result;
64 	enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status;
65 	struct kvec* tx_ciov;
66 	size_t tx_totallen;
67 	size_t tx_iovlen;
68 	struct kvec tx_iov[3];
69 	u_int16_t tx_type;
70 	u_int32_t sign[6];
71 };
72 
ncp_alloc_req(void)73 static inline struct ncp_request_reply* ncp_alloc_req(void)
74 {
75 	struct ncp_request_reply *req;
76 
77 	req = kmalloc(sizeof(struct ncp_request_reply), GFP_KERNEL);
78 	if (!req)
79 		return NULL;
80 
81 	init_waitqueue_head(&req->wq);
82 	atomic_set(&req->refs, (1));
83 	req->status = RQ_IDLE;
84 
85 	return req;
86 }
87 
ncp_req_get(struct ncp_request_reply * req)88 static void ncp_req_get(struct ncp_request_reply *req)
89 {
90 	atomic_inc(&req->refs);
91 }
92 
ncp_req_put(struct ncp_request_reply * req)93 static void ncp_req_put(struct ncp_request_reply *req)
94 {
95 	if (atomic_dec_and_test(&req->refs))
96 		kfree(req);
97 }
98 
ncp_tcp_data_ready(struct sock * sk,int len)99 void ncp_tcp_data_ready(struct sock *sk, int len)
100 {
101 	struct ncp_server *server = sk->sk_user_data;
102 
103 	server->data_ready(sk, len);
104 	schedule_work(&server->rcv.tq);
105 }
106 
ncp_tcp_error_report(struct sock * sk)107 void ncp_tcp_error_report(struct sock *sk)
108 {
109 	struct ncp_server *server = sk->sk_user_data;
110 
111 	server->error_report(sk);
112 	schedule_work(&server->rcv.tq);
113 }
114 
ncp_tcp_write_space(struct sock * sk)115 void ncp_tcp_write_space(struct sock *sk)
116 {
117 	struct ncp_server *server = sk->sk_user_data;
118 
119 	/* We do not need any locking: we first set tx.creq, and then we do sendmsg,
120 	   not vice versa... */
121 	server->write_space(sk);
122 	if (server->tx.creq)
123 		schedule_work(&server->tx.tq);
124 }
125 
ncpdgram_timeout_call(unsigned long v)126 void ncpdgram_timeout_call(unsigned long v)
127 {
128 	struct ncp_server *server = (void*)v;
129 
130 	schedule_work(&server->timeout_tq);
131 }
132 
ncp_finish_request(struct ncp_server * server,struct ncp_request_reply * req,int result)133 static inline void ncp_finish_request(struct ncp_server *server, struct ncp_request_reply *req, int result)
134 {
135 	req->result = result;
136 	if (req->status != RQ_ABANDONED)
137 		memcpy(req->reply_buf, server->rxbuf, req->datalen);
138 	req->status = RQ_DONE;
139 	wake_up_all(&req->wq);
140 	ncp_req_put(req);
141 }
142 
__abort_ncp_connection(struct ncp_server * server)143 static void __abort_ncp_connection(struct ncp_server *server)
144 {
145 	struct ncp_request_reply *req;
146 
147 	ncp_invalidate_conn(server);
148 	del_timer(&server->timeout_tm);
149 	while (!list_empty(&server->tx.requests)) {
150 		req = list_entry(server->tx.requests.next, struct ncp_request_reply, req);
151 
152 		list_del_init(&req->req);
153 		ncp_finish_request(server, req, -EIO);
154 	}
155 	req = server->rcv.creq;
156 	if (req) {
157 		server->rcv.creq = NULL;
158 		ncp_finish_request(server, req, -EIO);
159 		server->rcv.ptr = NULL;
160 		server->rcv.state = 0;
161 	}
162 	req = server->tx.creq;
163 	if (req) {
164 		server->tx.creq = NULL;
165 		ncp_finish_request(server, req, -EIO);
166 	}
167 }
168 
get_conn_number(struct ncp_reply_header * rp)169 static inline int get_conn_number(struct ncp_reply_header *rp)
170 {
171 	return rp->conn_low | (rp->conn_high << 8);
172 }
173 
__ncp_abort_request(struct ncp_server * server,struct ncp_request_reply * req,int err)174 static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
175 {
176 	/* If req is done, we got signal, but we also received answer... */
177 	switch (req->status) {
178 		case RQ_IDLE:
179 		case RQ_DONE:
180 			break;
181 		case RQ_QUEUED:
182 			list_del_init(&req->req);
183 			ncp_finish_request(server, req, err);
184 			break;
185 		case RQ_INPROGRESS:
186 			req->status = RQ_ABANDONED;
187 			break;
188 		case RQ_ABANDONED:
189 			break;
190 	}
191 }
192 
ncp_abort_request(struct ncp_server * server,struct ncp_request_reply * req,int err)193 static inline void ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
194 {
195 	mutex_lock(&server->rcv.creq_mutex);
196 	__ncp_abort_request(server, req, err);
197 	mutex_unlock(&server->rcv.creq_mutex);
198 }
199 
__ncptcp_abort(struct ncp_server * server)200 static inline void __ncptcp_abort(struct ncp_server *server)
201 {
202 	__abort_ncp_connection(server);
203 }
204 
ncpdgram_send(struct socket * sock,struct ncp_request_reply * req)205 static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req)
206 {
207 	struct kvec vec[3];
208 	/* sock_sendmsg updates iov pointers for us :-( */
209 	memcpy(vec, req->tx_ciov, req->tx_iovlen * sizeof(vec[0]));
210 	return do_send(sock, vec, req->tx_iovlen,
211 		       req->tx_totallen, MSG_DONTWAIT);
212 }
213 
__ncptcp_try_send(struct ncp_server * server)214 static void __ncptcp_try_send(struct ncp_server *server)
215 {
216 	struct ncp_request_reply *rq;
217 	struct kvec *iov;
218 	struct kvec iovc[3];
219 	int result;
220 
221 	rq = server->tx.creq;
222 	if (!rq)
223 		return;
224 
225 	/* sock_sendmsg updates iov pointers for us :-( */
226 	memcpy(iovc, rq->tx_ciov, rq->tx_iovlen * sizeof(iov[0]));
227 	result = do_send(server->ncp_sock, iovc, rq->tx_iovlen,
228 			 rq->tx_totallen, MSG_NOSIGNAL | MSG_DONTWAIT);
229 
230 	if (result == -EAGAIN)
231 		return;
232 
233 	if (result < 0) {
234 		printk(KERN_ERR "ncpfs: tcp: Send failed: %d\n", result);
235 		__ncp_abort_request(server, rq, result);
236 		return;
237 	}
238 	if (result >= rq->tx_totallen) {
239 		server->rcv.creq = rq;
240 		server->tx.creq = NULL;
241 		return;
242 	}
243 	rq->tx_totallen -= result;
244 	iov = rq->tx_ciov;
245 	while (iov->iov_len <= result) {
246 		result -= iov->iov_len;
247 		iov++;
248 		rq->tx_iovlen--;
249 	}
250 	iov->iov_base += result;
251 	iov->iov_len -= result;
252 	rq->tx_ciov = iov;
253 }
254 
ncp_init_header(struct ncp_server * server,struct ncp_request_reply * req,struct ncp_request_header * h)255 static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h)
256 {
257 	req->status = RQ_INPROGRESS;
258 	h->conn_low = server->connection;
259 	h->conn_high = server->connection >> 8;
260 	h->sequence = ++server->sequence;
261 }
262 
ncpdgram_start_request(struct ncp_server * server,struct ncp_request_reply * req)263 static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req)
264 {
265 	size_t signlen;
266 	struct ncp_request_header* h;
267 
268 	req->tx_ciov = req->tx_iov + 1;
269 
270 	h = req->tx_iov[1].iov_base;
271 	ncp_init_header(server, req, h);
272 	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
273 			req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1,
274 			cpu_to_le32(req->tx_totallen), req->sign);
275 	if (signlen) {
276 		req->tx_ciov[1].iov_base = req->sign;
277 		req->tx_ciov[1].iov_len = signlen;
278 		req->tx_iovlen += 1;
279 		req->tx_totallen += signlen;
280 	}
281 	server->rcv.creq = req;
282 	server->timeout_last = server->m.time_out;
283 	server->timeout_retries = server->m.retry_count;
284 	ncpdgram_send(server->ncp_sock, req);
285 	mod_timer(&server->timeout_tm, jiffies + server->m.time_out);
286 }
287 
288 #define NCP_TCP_XMIT_MAGIC	(0x446D6454)
289 #define NCP_TCP_XMIT_VERSION	(1)
290 #define NCP_TCP_RCVD_MAGIC	(0x744E6350)
291 
ncptcp_start_request(struct ncp_server * server,struct ncp_request_reply * req)292 static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
293 {
294 	size_t signlen;
295 	struct ncp_request_header* h;
296 
297 	req->tx_ciov = req->tx_iov;
298 	h = req->tx_iov[1].iov_base;
299 	ncp_init_header(server, req, h);
300 	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
301 			req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1,
302 			cpu_to_be32(req->tx_totallen + 24), req->sign + 4) + 16;
303 
304 	req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC);
305 	req->sign[1] = htonl(req->tx_totallen + signlen);
306 	req->sign[2] = htonl(NCP_TCP_XMIT_VERSION);
307 	req->sign[3] = htonl(req->datalen + 8);
308 	req->tx_iov[0].iov_base = req->sign;
309 	req->tx_iov[0].iov_len = signlen;
310 	req->tx_iovlen += 1;
311 	req->tx_totallen += signlen;
312 
313 	server->tx.creq = req;
314 	__ncptcp_try_send(server);
315 }
316 
__ncp_start_request(struct ncp_server * server,struct ncp_request_reply * req)317 static inline void __ncp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
318 {
319 	/* we copy the data so that we do not depend on the caller
320 	   staying alive */
321 	memcpy(server->txbuf, req->tx_iov[1].iov_base, req->tx_iov[1].iov_len);
322 	req->tx_iov[1].iov_base = server->txbuf;
323 
324 	if (server->ncp_sock->type == SOCK_STREAM)
325 		ncptcp_start_request(server, req);
326 	else
327 		ncpdgram_start_request(server, req);
328 }
329 
ncp_add_request(struct ncp_server * server,struct ncp_request_reply * req)330 static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply *req)
331 {
332 	mutex_lock(&server->rcv.creq_mutex);
333 	if (!ncp_conn_valid(server)) {
334 		mutex_unlock(&server->rcv.creq_mutex);
335 		printk(KERN_ERR "ncpfs: tcp: Server died\n");
336 		return -EIO;
337 	}
338 	ncp_req_get(req);
339 	if (server->tx.creq || server->rcv.creq) {
340 		req->status = RQ_QUEUED;
341 		list_add_tail(&req->req, &server->tx.requests);
342 		mutex_unlock(&server->rcv.creq_mutex);
343 		return 0;
344 	}
345 	__ncp_start_request(server, req);
346 	mutex_unlock(&server->rcv.creq_mutex);
347 	return 0;
348 }
349 
__ncp_next_request(struct ncp_server * server)350 static void __ncp_next_request(struct ncp_server *server)
351 {
352 	struct ncp_request_reply *req;
353 
354 	server->rcv.creq = NULL;
355 	if (list_empty(&server->tx.requests)) {
356 		return;
357 	}
358 	req = list_entry(server->tx.requests.next, struct ncp_request_reply, req);
359 	list_del_init(&req->req);
360 	__ncp_start_request(server, req);
361 }
362 
info_server(struct ncp_server * server,unsigned int id,const void * data,size_t len)363 static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len)
364 {
365 	if (server->info_sock) {
366 		struct kvec iov[2];
367 		__be32 hdr[2];
368 
369 		hdr[0] = cpu_to_be32(len + 8);
370 		hdr[1] = cpu_to_be32(id);
371 
372 		iov[0].iov_base = hdr;
373 		iov[0].iov_len = 8;
374 		iov[1].iov_base = (void *) data;
375 		iov[1].iov_len = len;
376 
377 		do_send(server->info_sock, iov, 2, len + 8, MSG_NOSIGNAL);
378 	}
379 }
380 
ncpdgram_rcv_proc(struct work_struct * work)381 void ncpdgram_rcv_proc(struct work_struct *work)
382 {
383 	struct ncp_server *server =
384 		container_of(work, struct ncp_server, rcv.tq);
385 	struct socket* sock;
386 
387 	sock = server->ncp_sock;
388 
389 	while (1) {
390 		struct ncp_reply_header reply;
391 		int result;
392 
393 		result = _recv(sock, &reply, sizeof(reply), MSG_PEEK | MSG_DONTWAIT);
394 		if (result < 0) {
395 			break;
396 		}
397 		if (result >= sizeof(reply)) {
398 			struct ncp_request_reply *req;
399 
400 			if (reply.type == NCP_WATCHDOG) {
401 				unsigned char buf[10];
402 
403 				if (server->connection != get_conn_number(&reply)) {
404 					goto drop;
405 				}
406 				result = _recv(sock, buf, sizeof(buf), MSG_DONTWAIT);
407 				if (result < 0) {
408 					DPRINTK("recv failed with %d\n", result);
409 					continue;
410 				}
411 				if (result < 10) {
412 					DPRINTK("too short (%u) watchdog packet\n", result);
413 					continue;
414 				}
415 				if (buf[9] != '?') {
416 					DPRINTK("bad signature (%02X) in watchdog packet\n", buf[9]);
417 					continue;
418 				}
419 				buf[9] = 'Y';
420 				_send(sock, buf, sizeof(buf));
421 				continue;
422 			}
423 			if (reply.type != NCP_POSITIVE_ACK && reply.type != NCP_REPLY) {
424 				result = _recv(sock, server->unexpected_packet.data, sizeof(server->unexpected_packet.data), MSG_DONTWAIT);
425 				if (result < 0) {
426 					continue;
427 				}
428 				info_server(server, 0, server->unexpected_packet.data, result);
429 				continue;
430 			}
431 			mutex_lock(&server->rcv.creq_mutex);
432 			req = server->rcv.creq;
433 			if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence &&
434 					server->connection == get_conn_number(&reply)))) {
435 				if (reply.type == NCP_POSITIVE_ACK) {
436 					server->timeout_retries = server->m.retry_count;
437 					server->timeout_last = NCP_MAX_RPC_TIMEOUT;
438 					mod_timer(&server->timeout_tm, jiffies + NCP_MAX_RPC_TIMEOUT);
439 				} else if (reply.type == NCP_REPLY) {
440 					result = _recv(sock, server->rxbuf, req->datalen, MSG_DONTWAIT);
441 #ifdef CONFIG_NCPFS_PACKET_SIGNING
442 					if (result >= 0 && server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
443 						if (result < 8 + 8) {
444 							result = -EIO;
445 						} else {
446 							unsigned int hdrl;
447 
448 							result -= 8;
449 							hdrl = sock->sk->sk_family == AF_INET ? 8 : 6;
450 							if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) {
451 								printk(KERN_INFO "ncpfs: Signature violation\n");
452 								result = -EIO;
453 							}
454 						}
455 					}
456 #endif
457 					del_timer(&server->timeout_tm);
458 				     	server->rcv.creq = NULL;
459 					ncp_finish_request(server, req, result);
460 					__ncp_next_request(server);
461 					mutex_unlock(&server->rcv.creq_mutex);
462 					continue;
463 				}
464 			}
465 			mutex_unlock(&server->rcv.creq_mutex);
466 		}
467 drop:;
468 		_recv(sock, &reply, sizeof(reply), MSG_DONTWAIT);
469 	}
470 }
471 
__ncpdgram_timeout_proc(struct ncp_server * server)472 static void __ncpdgram_timeout_proc(struct ncp_server *server)
473 {
474 	/* If timer is pending, we are processing another request... */
475 	if (!timer_pending(&server->timeout_tm)) {
476 		struct ncp_request_reply* req;
477 
478 		req = server->rcv.creq;
479 		if (req) {
480 			int timeout;
481 
482 			if (server->m.flags & NCP_MOUNT_SOFT) {
483 				if (server->timeout_retries-- == 0) {
484 					__ncp_abort_request(server, req, -ETIMEDOUT);
485 					return;
486 				}
487 			}
488 			/* Ignore errors */
489 			ncpdgram_send(server->ncp_sock, req);
490 			timeout = server->timeout_last << 1;
491 			if (timeout > NCP_MAX_RPC_TIMEOUT) {
492 				timeout = NCP_MAX_RPC_TIMEOUT;
493 			}
494 			server->timeout_last = timeout;
495 			mod_timer(&server->timeout_tm, jiffies + timeout);
496 		}
497 	}
498 }
499 
ncpdgram_timeout_proc(struct work_struct * work)500 void ncpdgram_timeout_proc(struct work_struct *work)
501 {
502 	struct ncp_server *server =
503 		container_of(work, struct ncp_server, timeout_tq);
504 	mutex_lock(&server->rcv.creq_mutex);
505 	__ncpdgram_timeout_proc(server);
506 	mutex_unlock(&server->rcv.creq_mutex);
507 }
508 
do_tcp_rcv(struct ncp_server * server,void * buffer,size_t len)509 static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len)
510 {
511 	int result;
512 
513 	if (buffer) {
514 		result = _recv(server->ncp_sock, buffer, len, MSG_DONTWAIT);
515 	} else {
516 		static unsigned char dummy[1024];
517 
518 		if (len > sizeof(dummy)) {
519 			len = sizeof(dummy);
520 		}
521 		result = _recv(server->ncp_sock, dummy, len, MSG_DONTWAIT);
522 	}
523 	if (result < 0) {
524 		return result;
525 	}
526 	if (result > len) {
527 		printk(KERN_ERR "ncpfs: tcp: bug in recvmsg (%u > %Zu)\n", result, len);
528 		return -EIO;
529 	}
530 	return result;
531 }
532 
__ncptcp_rcv_proc(struct ncp_server * server)533 static int __ncptcp_rcv_proc(struct ncp_server *server)
534 {
535 	/* We have to check the result, so store the complete header */
536 	while (1) {
537 		int result;
538 		struct ncp_request_reply *req;
539 		int datalen;
540 		int type;
541 
542 		while (server->rcv.len) {
543 			result = do_tcp_rcv(server, server->rcv.ptr, server->rcv.len);
544 			if (result == -EAGAIN) {
545 				return 0;
546 			}
547 			if (result <= 0) {
548 				req = server->rcv.creq;
549 				if (req) {
550 					__ncp_abort_request(server, req, -EIO);
551 				} else {
552 					__ncptcp_abort(server);
553 				}
554 				if (result < 0) {
555 					printk(KERN_ERR "ncpfs: tcp: error in recvmsg: %d\n", result);
556 				} else {
557 					DPRINTK(KERN_ERR "ncpfs: tcp: EOF\n");
558 				}
559 				return -EIO;
560 			}
561 			if (server->rcv.ptr) {
562 				server->rcv.ptr += result;
563 			}
564 			server->rcv.len -= result;
565 		}
566 		switch (server->rcv.state) {
567 			case 0:
568 				if (server->rcv.buf.magic != htonl(NCP_TCP_RCVD_MAGIC)) {
569 					printk(KERN_ERR "ncpfs: tcp: Unexpected reply type %08X\n", ntohl(server->rcv.buf.magic));
570 					__ncptcp_abort(server);
571 					return -EIO;
572 				}
573 				datalen = ntohl(server->rcv.buf.len) & 0x0FFFFFFF;
574 				if (datalen < 10) {
575 					printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);
576 					__ncptcp_abort(server);
577 					return -EIO;
578 				}
579 #ifdef CONFIG_NCPFS_PACKET_SIGNING
580 				if (server->sign_active) {
581 					if (datalen < 18) {
582 						printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);
583 						__ncptcp_abort(server);
584 						return -EIO;
585 					}
586 					server->rcv.buf.len = datalen - 8;
587 					server->rcv.ptr = (unsigned char*)&server->rcv.buf.p1;
588 					server->rcv.len = 8;
589 					server->rcv.state = 4;
590 					break;
591 				}
592 #endif
593 				type = ntohs(server->rcv.buf.type);
594 #ifdef CONFIG_NCPFS_PACKET_SIGNING
595 cont:;
596 #endif
597 				if (type != NCP_REPLY) {
598 					if (datalen - 8 <= sizeof(server->unexpected_packet.data)) {
599 						*(__u16*)(server->unexpected_packet.data) = htons(type);
600 						server->unexpected_packet.len = datalen - 8;
601 
602 						server->rcv.state = 5;
603 						server->rcv.ptr = server->unexpected_packet.data + 2;
604 						server->rcv.len = datalen - 10;
605 						break;
606 					}
607 					DPRINTK("ncpfs: tcp: Unexpected NCP type %02X\n", type);
608 skipdata2:;
609 					server->rcv.state = 2;
610 skipdata:;
611 					server->rcv.ptr = NULL;
612 					server->rcv.len = datalen - 10;
613 					break;
614 				}
615 				req = server->rcv.creq;
616 				if (!req) {
617 					DPRINTK(KERN_ERR "ncpfs: Reply without appropriate request\n");
618 					goto skipdata2;
619 				}
620 				if (datalen > req->datalen + 8) {
621 					printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d (expected at most %Zd)\n", datalen, req->datalen + 8);
622 					server->rcv.state = 3;
623 					goto skipdata;
624 				}
625 				req->datalen = datalen - 8;
626 				((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY;
627 				server->rcv.ptr = server->rxbuf + 2;
628 				server->rcv.len = datalen - 10;
629 				server->rcv.state = 1;
630 				break;
631 #ifdef CONFIG_NCPFS_PACKET_SIGNING
632 			case 4:
633 				datalen = server->rcv.buf.len;
634 				type = ntohs(server->rcv.buf.type2);
635 				goto cont;
636 #endif
637 			case 1:
638 				req = server->rcv.creq;
639 				if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) {
640 					if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) {
641 						printk(KERN_ERR "ncpfs: tcp: Bad sequence number\n");
642 						__ncp_abort_request(server, req, -EIO);
643 						return -EIO;
644 					}
645 					if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) {
646 						printk(KERN_ERR "ncpfs: tcp: Connection number mismatch\n");
647 						__ncp_abort_request(server, req, -EIO);
648 						return -EIO;
649 					}
650 				}
651 #ifdef CONFIG_NCPFS_PACKET_SIGNING
652 				if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
653 					if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) {
654 						printk(KERN_ERR "ncpfs: tcp: Signature violation\n");
655 						__ncp_abort_request(server, req, -EIO);
656 						return -EIO;
657 					}
658 				}
659 #endif
660 				ncp_finish_request(server, req, req->datalen);
661 			nextreq:;
662 				__ncp_next_request(server);
663 			case 2:
664 			next:;
665 				server->rcv.ptr = (unsigned char*)&server->rcv.buf;
666 				server->rcv.len = 10;
667 				server->rcv.state = 0;
668 				break;
669 			case 3:
670 				ncp_finish_request(server, server->rcv.creq, -EIO);
671 				goto nextreq;
672 			case 5:
673 				info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len);
674 				goto next;
675 		}
676 	}
677 }
678 
ncp_tcp_rcv_proc(struct work_struct * work)679 void ncp_tcp_rcv_proc(struct work_struct *work)
680 {
681 	struct ncp_server *server =
682 		container_of(work, struct ncp_server, rcv.tq);
683 
684 	mutex_lock(&server->rcv.creq_mutex);
685 	__ncptcp_rcv_proc(server);
686 	mutex_unlock(&server->rcv.creq_mutex);
687 }
688 
ncp_tcp_tx_proc(struct work_struct * work)689 void ncp_tcp_tx_proc(struct work_struct *work)
690 {
691 	struct ncp_server *server =
692 		container_of(work, struct ncp_server, tx.tq);
693 
694 	mutex_lock(&server->rcv.creq_mutex);
695 	__ncptcp_try_send(server);
696 	mutex_unlock(&server->rcv.creq_mutex);
697 }
698 
do_ncp_rpc_call(struct ncp_server * server,int size,unsigned char * reply_buf,int max_reply_size)699 static int do_ncp_rpc_call(struct ncp_server *server, int size,
700 		unsigned char* reply_buf, int max_reply_size)
701 {
702 	int result;
703 	struct ncp_request_reply *req;
704 
705 	req = ncp_alloc_req();
706 	if (!req)
707 		return -ENOMEM;
708 
709 	req->reply_buf = reply_buf;
710 	req->datalen = max_reply_size;
711 	req->tx_iov[1].iov_base = server->packet;
712 	req->tx_iov[1].iov_len = size;
713 	req->tx_iovlen = 1;
714 	req->tx_totallen = size;
715 	req->tx_type = *(u_int16_t*)server->packet;
716 
717 	result = ncp_add_request(server, req);
718 	if (result < 0)
719 		goto out;
720 
721 	if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) {
722 		ncp_abort_request(server, req, -EINTR);
723 		result = -EINTR;
724 		goto out;
725 	}
726 
727 	result = req->result;
728 
729 out:
730 	ncp_req_put(req);
731 
732 	return result;
733 }
734 
735 /*
736  * We need the server to be locked here, so check!
737  */
738 
ncp_do_request(struct ncp_server * server,int size,void * reply,int max_reply_size)739 static int ncp_do_request(struct ncp_server *server, int size,
740 		void* reply, int max_reply_size)
741 {
742 	int result;
743 
744 	if (server->lock == 0) {
745 		printk(KERN_ERR "ncpfs: Server not locked!\n");
746 		return -EIO;
747 	}
748 	if (!ncp_conn_valid(server)) {
749 		return -EIO;
750 	}
751 	{
752 		sigset_t old_set;
753 		unsigned long mask, flags;
754 
755 		spin_lock_irqsave(&current->sighand->siglock, flags);
756 		old_set = current->blocked;
757 		if (current->flags & PF_EXITING)
758 			mask = 0;
759 		else
760 			mask = sigmask(SIGKILL);
761 		if (server->m.flags & NCP_MOUNT_INTR) {
762 			/* FIXME: This doesn't seem right at all.  So, like,
763 			   we can't handle SIGINT and get whatever to stop?
764 			   What if we've blocked it ourselves?  What about
765 			   alarms?  Why, in fact, are we mucking with the
766 			   sigmask at all? -- r~ */
767 			if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL)
768 				mask |= sigmask(SIGINT);
769 			if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
770 				mask |= sigmask(SIGQUIT);
771 		}
772 		siginitsetinv(&current->blocked, mask);
773 		recalc_sigpending();
774 		spin_unlock_irqrestore(&current->sighand->siglock, flags);
775 
776 		result = do_ncp_rpc_call(server, size, reply, max_reply_size);
777 
778 		spin_lock_irqsave(&current->sighand->siglock, flags);
779 		current->blocked = old_set;
780 		recalc_sigpending();
781 		spin_unlock_irqrestore(&current->sighand->siglock, flags);
782 	}
783 
784 	DDPRINTK("do_ncp_rpc_call returned %d\n", result);
785 
786 	return result;
787 }
788 
789 /* ncp_do_request assures that at least a complete reply header is
790  * received. It assumes that server->current_size contains the ncp
791  * request size
792  */
ncp_request2(struct ncp_server * server,int function,void * rpl,int size)793 int ncp_request2(struct ncp_server *server, int function,
794 		void* rpl, int size)
795 {
796 	struct ncp_request_header *h;
797 	struct ncp_reply_header* reply = rpl;
798 	int result;
799 
800 	h = (struct ncp_request_header *) (server->packet);
801 	if (server->has_subfunction != 0) {
802 		*(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2);
803 	}
804 	h->type = NCP_REQUEST;
805 	/*
806 	 * The server shouldn't know or care what task is making a
807 	 * request, so we always use the same task number.
808 	 */
809 	h->task = 2; /* (current->pid) & 0xff; */
810 	h->function = function;
811 
812 	result = ncp_do_request(server, server->current_size, reply, size);
813 	if (result < 0) {
814 		DPRINTK("ncp_request_error: %d\n", result);
815 		goto out;
816 	}
817 	server->completion = reply->completion_code;
818 	server->conn_status = reply->connection_state;
819 	server->reply_size = result;
820 	server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
821 
822 	result = reply->completion_code;
823 
824 	if (result != 0)
825 		PPRINTK("ncp_request: completion code=%x\n", result);
826 out:
827 	return result;
828 }
829 
ncp_connect(struct ncp_server * server)830 int ncp_connect(struct ncp_server *server)
831 {
832 	struct ncp_request_header *h;
833 	int result;
834 
835 	server->connection = 0xFFFF;
836 	server->sequence = 255;
837 
838 	h = (struct ncp_request_header *) (server->packet);
839 	h->type = NCP_ALLOC_SLOT_REQUEST;
840 	h->task		= 2; /* see above */
841 	h->function	= 0;
842 
843 	result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
844 	if (result < 0)
845 		goto out;
846 	server->connection = h->conn_low + (h->conn_high * 256);
847 	result = 0;
848 out:
849 	return result;
850 }
851 
ncp_disconnect(struct ncp_server * server)852 int ncp_disconnect(struct ncp_server *server)
853 {
854 	struct ncp_request_header *h;
855 
856 	h = (struct ncp_request_header *) (server->packet);
857 	h->type = NCP_DEALLOC_SLOT_REQUEST;
858 	h->task		= 2; /* see above */
859 	h->function	= 0;
860 
861 	return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
862 }
863 
ncp_lock_server(struct ncp_server * server)864 void ncp_lock_server(struct ncp_server *server)
865 {
866 	mutex_lock(&server->mutex);
867 	if (server->lock)
868 		printk(KERN_WARNING "ncp_lock_server: was locked!\n");
869 	server->lock = 1;
870 }
871 
ncp_unlock_server(struct ncp_server * server)872 void ncp_unlock_server(struct ncp_server *server)
873 {
874 	if (!server->lock) {
875 		printk(KERN_WARNING "ncp_unlock_server: was not locked!\n");
876 		return;
877 	}
878 	server->lock = 0;
879 	mutex_unlock(&server->mutex);
880 }
881