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 
17 bool
18 Ftp::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 
51 bool
52 Ftp::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 
92 const char *
93 Ftp::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 
bool ParseProtoIpPort(const char *buf, Ip::Address &addr)
Definition: Parsing.cc:52
bool isAnyAddr() const
Definition: Address.cc:190
static int port
Definition: ldap_backend.cc:70
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
Definition: forward.h:25
void append(const char *c, int sz) override
Definition: MemBuf.cc:209
unsigned short port() const
Definition: Address.cc:790
bool isIPv6() const
Definition: Address.cc:184
Definition: MemBuf.h:23
const char * UnescapeDoubleQuoted(const char *quotedPath)
parses an FTP-quoted quote-escaped path
Definition: Parsing.cc:93
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
char * content()
start of the added data
Definition: MemBuf.h:41
struct SquidConfig::@92 Ftp
void reset()
Definition: MemBuf.cc:129
class SquidConfig Config
Definition: SquidConfig.cc:12

 

Introduction

Documentation

Support

Miscellaneous