Squid Web Cache master
Loading...
Searching...
No Matches
Parsing.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* DEBUG: section 09 File Transfer Protocol (FTP) */
10
11#include "squid.h"
12#include "ftp/Parsing.h"
13#include "ip/Address.h"
14#include "MemBuf.h"
15#include "SquidConfig.h"
16
17bool
18Ftp::ParseIpPort(const char *buf, const char *forceIp, Ip::Address &addr)
19{
20 int h1, h2, h3, h4;
21 int p1, p2;
22 const int n = sscanf(buf, "%d,%d,%d,%d,%d,%d",
23 &h1, &h2, &h3, &h4, &p1, &p2);
24
25 if (n != 6 || p1 < 0 || p2 < 0 || p1 > 255 || p2 > 255)
26 return false;
27
28 if (forceIp) {
29 addr = forceIp; // but the above code still validates the IP we got
30 } else {
31 static char ipBuf[1024];
32 snprintf(ipBuf, sizeof(ipBuf), "%d.%d.%d.%d", h1, h2, h3, h4);
33 addr = ipBuf;
34
35 if (addr.isAnyAddr())
36 return false;
37 }
38
39 const int port = ((p1 << 8) + p2);
40
41 if (port <= 0)
42 return false;
43
44 if (Config.Ftp.sanitycheck && port < 1024)
45 return false;
46
47 addr.port(port);
48 return true;
49}
50
51bool
52Ftp::ParseProtoIpPort(const char *buf, Ip::Address &addr)
53{
54
55 const char delim = *buf;
56 const char *s = buf + 1;
57 const char *e = s;
58 const int proto = strtol(s, const_cast<char**>(&e), 10);
59 if ((proto != 1 && proto != 2) || *e != delim)
60 return false;
61
62 s = e + 1;
63 e = strchr(s, delim);
64 if (!e)
65 return false;
66
67 char ip[MAX_IPSTRLEN];
68 if (static_cast<size_t>(e - s) >= sizeof(ip))
69 return false;
70 strncpy(ip, s, e - s);
71 ip[e - s] = '\0';
72 addr = ip;
73
74 if (addr.isAnyAddr())
75 return false;
76
77 if ((proto == 2) != addr.isIPv6()) // proto ID mismatches address version
78 return false;
79
80 s = e + 1; // skip port delimiter
81 const int port = strtol(s, const_cast<char**>(&e), 10);
82 if (port < 0 || *e != '|')
83 return false;
84
85 if (Config.Ftp.sanitycheck && port < 1024)
86 return false;
87
88 addr.port(port);
89 return true;
90}
91
92const char *
93Ftp::UnescapeDoubleQuoted(const char *quotedPath)
94{
95 static MemBuf path;
96 path.reset();
97 const char *s = quotedPath;
98 if (*s == '"') {
99 ++s;
100 bool parseDone = false;
101 while (!parseDone) {
102 if (const char *e = strchr(s, '"')) {
103 path.append(s, e - s);
104 s = e + 1;
105 if (*s == '"') {
106 path.append(s, 1);
107 ++s;
108 } else
109 parseDone = true;
110 } else { //parse error
111 parseDone = true;
112 path.reset();
113 }
114 }
115 }
116 return path.content();
117}
118
class SquidConfig Config
bool isAnyAddr() const
Definition Address.cc:190
bool isIPv6() const
Definition Address.cc:184
unsigned short port() const
Definition Address.cc:790
void append(const char *c, int sz) override
Definition MemBuf.cc:209
char * content()
start of the added data
Definition MemBuf.h:41
void reset()
Definition MemBuf.cc:129
struct SquidConfig::@92 Ftp
static int port
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
Definition forward.h:25
const char * UnescapeDoubleQuoted(const char *quotedPath)
parses an FTP-quoted quote-escaped path
Definition Parsing.cc:93
bool ParseProtoIpPort(const char *buf, Ip::Address &addr)
Definition Parsing.cc:52
bool ParseIpPort(const char *buf, const char *forceIp, Ip::Address &addr)
parses and validates "A1,A2,A3,A4,P1,P2" IP,port sequence
Definition Parsing.cc:18