1/*
2 * Copyright (C) 2004, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "platform/weborigin/KnownPorts.h"
29
30#include "platform/weborigin/KURL.h"
31#include "wtf/HashMap.h"
32#include "wtf/StdLibExtras.h"
33#include "wtf/text/StringHash.h"
34
35namespace blink {
36
37bool isDefaultPortForProtocol(unsigned short port, const String& protocol)
38{
39    if (protocol.isEmpty())
40        return false;
41
42    typedef HashMap<String, unsigned, CaseFoldingHash> DefaultPortsMap;
43    DEFINE_STATIC_LOCAL(DefaultPortsMap, defaultPorts, ());
44    if (defaultPorts.isEmpty()) {
45        defaultPorts.set("http", 80);
46        defaultPorts.set("https", 443);
47        defaultPorts.set("ftp", 21);
48        defaultPorts.set("ftps", 990);
49    }
50    return defaultPorts.get(protocol) == port;
51}
52
53bool portAllowed(const KURL& url)
54{
55    unsigned short port = url.port();
56
57    // Since most URLs don't have a port, return early for the "no port" case.
58    if (!port)
59        return true;
60
61    // This blocked port list matches the port blocking that Mozilla implements.
62    // See http://www.mozilla.org/projects/netlib/PortBanning.html for more information.
63    static const unsigned short blockedPortList[] = {
64        1,    // tcpmux
65        7,    // echo
66        9,    // discard
67        11,   // systat
68        13,   // daytime
69        15,   // netstat
70        17,   // qotd
71        19,   // chargen
72        20,   // FTP-data
73        21,   // FTP-control
74        22,   // SSH
75        23,   // telnet
76        25,   // SMTP
77        37,   // time
78        42,   // name
79        43,   // nicname
80        53,   // domain
81        77,   // priv-rjs
82        79,   // finger
83        87,   // ttylink
84        95,   // supdup
85        101,  // hostriame
86        102,  // iso-tsap
87        103,  // gppitnp
88        104,  // acr-nema
89        109,  // POP2
90        110,  // POP3
91        111,  // sunrpc
92        113,  // auth
93        115,  // SFTP
94        117,  // uucp-path
95        119,  // nntp
96        123,  // NTP
97        135,  // loc-srv / epmap
98        139,  // netbios
99        143,  // IMAP2
100        179,  // BGP
101        389,  // LDAP
102        465,  // SMTP+SSL
103        512,  // print / exec
104        513,  // login
105        514,  // shell
106        515,  // printer
107        526,  // tempo
108        530,  // courier
109        531,  // Chat
110        532,  // netnews
111        540,  // UUCP
112        556,  // remotefs
113        563,  // NNTP+SSL
114        587,  // ESMTP
115        601,  // syslog-conn
116        636,  // LDAP+SSL
117        993,  // IMAP+SSL
118        995,  // POP3+SSL
119        2049, // NFS
120        3659, // apple-sasl / PasswordServer [Apple addition]
121        4045, // lockd
122        6000, // X11
123        6665, // Alternate IRC [Apple addition]
124        6666, // Alternate IRC [Apple addition]
125        6667, // Standard IRC [Apple addition]
126        6668, // Alternate IRC [Apple addition]
127        6669, // Alternate IRC [Apple addition]
128        0xFFFF, // Used to block all invalid port numbers
129    };
130    const unsigned short* const blockedPortListEnd = blockedPortList + WTF_ARRAY_LENGTH(blockedPortList);
131
132#if ENABLE(ASSERT)
133    // The port list must be sorted for binary_search to work.
134    static bool checkedPortList = false;
135    if (!checkedPortList) {
136        for (const unsigned short* p = blockedPortList; p != blockedPortListEnd - 1; ++p)
137            ASSERT(*p < *(p + 1));
138        checkedPortList = true;
139    }
140#endif
141
142    // If the port is not in the blocked port list, allow it.
143    if (!std::binary_search(blockedPortList, blockedPortListEnd, port))
144        return true;
145
146    // Allow ports 21 and 22 for FTP URLs, as Mozilla does.
147    if ((port == 21 || port == 22) && url.protocolIs("ftp"))
148        return true;
149
150    // Allow any port number in a file URL, since the port number is ignored.
151    if (url.protocolIs("file"))
152        return true;
153
154    return false;
155}
156
157}
158