Parsing.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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  char ip[MAX_IPSTRLEN];
65  if (static_cast<size_t>(e - s) >= sizeof(ip))
66  return false;
67  strncpy(ip, s, e - s);
68  ip[e - s] = '\0';
69  addr = ip;
70 
71  if (addr.isAnyAddr())
72  return false;
73 
74  if ((proto == 2) != addr.isIPv6()) // proto ID mismatches address version
75  return false;
76 
77  s = e + 1; // skip port delimiter
78  const int port = strtol(s, const_cast<char**>(&e), 10);
79  if (port < 0 || *e != '|')
80  return false;
81 
82  if (Config.Ftp.sanitycheck && port < 1024)
83  return false;
84 
85  addr.port(port);
86  return true;
87 }
88 
89 const char *
90 Ftp::UnescapeDoubleQuoted(const char *quotedPath)
91 {
92  static MemBuf path;
93  path.reset();
94  const char *s = quotedPath;
95  if (*s == '"') {
96  ++s;
97  bool parseDone = false;
98  while (!parseDone) {
99  if (const char *e = strchr(s, '"')) {
100  path.append(s, e - s);
101  s = e + 1;
102  if (*s == '"') {
103  path.append(s, 1);
104  ++s;
105  } else
106  parseDone = true;
107  } else { //parse error
108  parseDone = true;
109  path.reset();
110  }
111  }
112  }
113  return path.content();
114 }
115 
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:798
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:90
struct SquidConfig::@99 Ftp
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
void reset()
Definition: MemBuf.cc:129
class SquidConfig Config
Definition: SquidConfig.cc:12

 

Introduction

Documentation

Support

Miscellaneous