1 /*
2  * h_port.c
3  * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4  * All rights reserved.
5  *
6  * $Id: h_port.c,v 1.11 2015/03/14 06:11:25 marc Exp marc $
7  *
8  */
9 
10 #include "headers.h"
11 
12 static const char rcsid[] __attribute__ ((used)) = "$Id: h_port.c,v 1.11 2015/03/14 06:11:25 marc Exp marc $";
13 
14 #define MODE_PORT 0
15 #define MODE_LPRT 1
16 #define MODE_EPRT 2
17 
18 static char *modelist[] = { "PORT", "LPRT", "EPRT" };
19 
do_port(int mode,struct context * ctx,char * arg)20 static void do_port(int mode, struct context *ctx, char *arg)
21 {
22     int af_d;
23 
24     DebugIn(DEBUG_COMMAND);
25 
26     if (ctx->dfn > -1)
27 	cleanup_data(ctx, ctx->dfn);
28 
29     if (ctx->epsv_all) {
30 	reply(ctx, MSG_500_EPSV_only);
31 	DebugOut(DEBUG_COMMAND);
32 	return;
33     }
34 
35     switch (mode) {
36     case MODE_LPRT:
37 	af_d = foobar_eval(&ctx->sa_d_remote, arg);
38 	break;
39     case MODE_EPRT:
40 	af_d = rfc2428_eval(&ctx->sa_d_remote, arg);
41 	break;
42     default:
43 	af_d = rfc959_eval(&ctx->sa_d_remote, arg);
44     }
45 
46     if (af_d == -2) {
47 	char buf[160];
48 	switch (mode) {
49 	case MODE_LPRT:
50 	    replyf(ctx, MSG_521_Supported_AF, print_foobar_families(buf, sizeof(buf)));
51 	    break;
52 	case MODE_EPRT:
53 	    replyf(ctx, MSG_522_Supported_AF, print_rfc2428_families(buf, sizeof(buf)));
54 	}
55 	DebugOut(DEBUG_COMMAND);
56 	return;
57     }
58 
59     if (af_d < 0)
60 	reply(ctx, MSG_501_Syntax_error);
61     /* rfc2577 suggests to deny connections to reserved ports: */
62     else if (su_get_port(&ctx->sa_d_remote) < IPPORT_RESERVED) {
63 	ctx->sa_d_remote = ctx->sa_c_remote;
64 	reply(ctx, MSG_504_Command_not_implemented);
65     } else if (!ctx->address_mismatch && !su_equal_addr(&ctx->sa_d_remote, &ctx->sa_c_remote))
66 	replyf(ctx, MSG_501_port_denied, modelist[mode]);
67     else
68 	replyf(ctx, MSG_200_port_successful, modelist[mode]);
69 
70     DebugOut(DEBUG_COMMAND);
71 }
72 
h_port(struct context * ctx,char * arg)73 void h_port(struct context *ctx, char *arg)
74 {
75     do_port(MODE_PORT, ctx, arg);
76 }
77 
h_lprt(struct context * ctx,char * arg)78 void h_lprt(struct context *ctx, char *arg)
79 {
80     do_port(MODE_LPRT, ctx, arg);
81 }
82 
h_eprt(struct context * ctx,char * arg)83 void h_eprt(struct context *ctx, char *arg)
84 {
85     do_port(MODE_EPRT, ctx, arg);
86 }
87