home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / PortAliases.ycp < prev    next >
Text File  |  2006-11-29  |  8KB  |  266 lines

  1. /**
  2.  * File:    modules/PortAliases.ycp
  3.  * Package:    Ports Aliases.
  4.  * Summary:    Definition of Port Aliases.
  5.  * Authors:    Lukas Ocilka <locilka@suse.cz>
  6.  *
  7.  * $Id: PortAliases.ycp 33164 2006-09-27 08:42:24Z jsrain $
  8.  *
  9.  * Global Definition of Port Aliases for services taken from /etc/services.
  10.  * /etc/services are defined by IANA http://www.iana.org/assignments/port-numbers.
  11.  * This module provides full listing of port aliases (supporting also multiple
  12.  * aliases like "http", "www" and "www-http" for port 80). 
  13.  * Results are cached, so repeated requests are answered faster.
  14.  */
  15.  
  16. {
  17.     module "PortAliases";
  18.     textdomain "base";
  19.  
  20.     import "SCR";
  21.  
  22.     /* an internal service aliases map for port-numbers pointing to port-names,
  23.     aliases are separated by space */
  24.     define map <integer, string> SERVICE_PORT_TO_NAME = $[
  25.     22    :    "ssh",
  26.     25    :    "smtp",
  27.     53    :    "domain",
  28.     67    :    "bootps",
  29.     68    :    "bootpc",
  30.     69    :    "tftp",
  31.     80    :    "http www www-http",
  32.     110    :    "pop3",
  33.     111    :    "sunrpc",
  34.     123    :    "ntp",
  35.     137    :    "netbios-ns",
  36.     138    :    "netbios-dgm",
  37.     139    :    "netbios-ssn",
  38.     143    :    "imap",
  39.     389    :    "ldap",
  40.     443    :    "https",
  41.     445    :    "microsoft-ds",
  42.     500    :    "isakmp",
  43.     631    :    "ipp",
  44.     636    :    "ldaps",
  45.     873    :    "rsync",
  46.     993    :    "imaps",
  47.     995    :    "pop3s",
  48.     3128    :    "ndl-aas",
  49.     4500    :    "ipsec-nat-t",
  50.     8080    :    "http-alt",
  51.     ];
  52.  
  53.     /* an internal service aliases map for port-names pointing to port-numbers */
  54.     define map <string, integer> SERVICE_NAME_TO_PORT = $[
  55.     "ssh"        :    22,
  56.     "smtp"        :    25,
  57.     "domain"    :    53,
  58.     "bootps"    :    67,
  59.     "bootpc"    :    68,
  60.     "tftp"        :    69,
  61.     "http"        :    80,
  62.     "www"        :    80,
  63.     "www-http"    :    80,
  64.     "pop3"        :    110,
  65.     "sunrpc"    :    111,
  66.     "ntp"        :    123,
  67.     "netbios-ns"    :    137,
  68.     "netbios-dgm"    :    138,
  69.     "netbios-ssn"    :    139,
  70.     "imap"        :    143,
  71.     "ldap"        :    389,
  72.     "https"        :    443,
  73.     "microsoft-ds"    :    445,
  74.     "isakmp"    :    500,
  75.     "ipp"        :    631,
  76.     "ldaps"        :    636,
  77.     "rsync"        :    873,
  78.     "imaps"        :    993,
  79.     "pop3s"        :    995,
  80.     "ndl-aas"    :    3128,
  81.     "ipsec-nat-t"    :    4500,
  82.     "http-alt"    :    8080,
  83.     ];
  84.  
  85.     /* This variable contains characters allowed in port-names, backslashed for regexpmatch() */
  86.     string allowed_service_regexp = "^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\*\/\+\._-]*$";
  87.  
  88.     /**
  89.      * Function returns if the port name is allowed port name (or number).
  90.      *
  91.      * @return    boolean if allowed
  92.      */
  93.     global define boolean IsAllowedPortName(string port_name) {
  94.     // port is number
  95.     if (regexpmatch(port_name, "^[0123456789]+$")) {
  96.         integer port_number = tointeger(port_name);
  97.         // checking range
  98.         return (port_number>=0 && port_number<=65535);
  99.     // port is name
  100.     } else {
  101.         return (regexpmatch(port_name, allowed_service_regexp));
  102.     }
  103.     }
  104.  
  105.     /**
  106.      * Function returns string describing allowed port name or number.
  107.      *
  108.      * @return    string with description
  109.      */
  110.     global define string AllowedPortNameOrNumber () {
  111.     // TRANSLATORS: popup informing message, allowed characters for port-names
  112.     return _("A port name may consist of the characters 'a-z', 'A-Z', '0-9', and '*+._-'.
  113. A port number may be a number from 0 to 65535.
  114. No spaces are allowed.
  115. ");
  116.     }
  117.  
  118.     /* Internal function for preparing string for grep command */
  119.     string QuoteString (string port_name) {
  120.     port_name = mergestring (splitstring(port_name, "\""), "\\\"");
  121.     port_name = mergestring (splitstring(port_name, "*"), "\\*");
  122.     port_name = mergestring (splitstring(port_name, "."), "\\.");
  123.     return port_name;
  124.     }
  125.  
  126.     /* Internal function for loading unknown ports into memory and returning them as list[string] */
  127.     string LoadAndReturnPortToName (integer port_number) {
  128.     string command = "grep \"^[^#].*[ \\t]" + port_number + "\/\" /etc/services | sed \"s/\\([^ \\t]*\\)[ \\t]*.*/\\1/\"";
  129.     map found = (map) SCR::Execute(.target.bash_output, command);
  130.     list <string> aliases = [];
  131.  
  132.     if (found["exit"]:0 == 0) {
  133.         foreach (string alias, splitstring(found["stdout"]:"", "\n"), {
  134.         if (alias == "") return;
  135.         aliases = add(aliases, alias);
  136.         });
  137.     } else {
  138.         y2error("Services Command: %1 -> %2", command, found["stderr"]:"");
  139.         return nil;
  140.     }
  141.  
  142.     // store results for later requests
  143.     SERVICE_PORT_TO_NAME[port_number] = mergestring(toset(aliases), " ");
  144.  
  145.     return SERVICE_PORT_TO_NAME[port_number]:"";
  146.     }
  147.  
  148.     /* Internal function for loading unknown ports into memory and returning them as integer */
  149.     integer LoadAndReturnNameToPort (string port_name) {
  150.     if (! IsAllowedPortName(port_name)) {
  151.         y2error("Disallwed port-name '%1'", port_name);
  152.         return nil;
  153.     }
  154.  
  155.     string command = "grep --perl-regexp \"^" + QuoteString(port_name) + "[ \\t]\" /etc/services | sed \"s/[^ \\t]*[ \\t]*\\([^\/ \\t]*\\).*/\\1/\"";
  156.     map found = (map) SCR::Execute(.target.bash_output, command);
  157.     integer alias_found = nil;
  158.  
  159.     if (found["exit"]:0 == 0) {
  160.         foreach (string alias, splitstring(found["stdout"]:"", "\n"), {
  161.         if (alias == "") return;
  162.         alias_found = tointeger(alias);
  163.         });
  164.     } else {
  165.         y2error("Services Command: %1 -> %2", command, found["stderr"]:"");
  166.         return nil;
  167.     }
  168.  
  169.     // store results for later requests
  170.     SERVICE_NAME_TO_PORT[port_name] = alias_found;
  171.  
  172.     return alias_found;
  173.     }
  174.  
  175.     list <string> cache_not_allowed_ports = [];
  176.  
  177.     /**
  178.      * Function returns list of aliases (port-names and port-numbers) for
  179.      * requested port-number or port-name. Also the requested name or port is returned.
  180.      *
  181.      * @param    string port-number or port-name
  182.      * @return    list [string] of aliases
  183.      */
  184.     global define list <string> GetListOfServiceAliases (string port) {
  185.     list <string> service_aliases = [ port ];
  186.     integer port_number = nil;
  187.  
  188.     // service is a port number
  189.     if (regexpmatch(port, "^[0123456789]+$")) {
  190.         port_number = tointeger(port);
  191.  
  192.         service_aliases = (list<string>) union (
  193.         service_aliases,
  194.         splitstring (
  195.             SERVICE_PORT_TO_NAME[port_number]:LoadAndReturnPortToName(port_number),
  196.             " "
  197.         )
  198.         );
  199.     // service is a port name, any space isn't allowed
  200.     } else if (IsAllowedPortName(port)) {
  201.         integer found_alias_port = SERVICE_NAME_TO_PORT[port]:LoadAndReturnNameToPort(port);
  202.         if (found_alias_port != nil) {
  203.         service_aliases = add (service_aliases,tostring(found_alias_port));
  204.  
  205.         // search for another port-name aliases when port-number found
  206.         service_aliases = (list<string>) union (
  207.             service_aliases,
  208.             splitstring (
  209.             SERVICE_PORT_TO_NAME[found_alias_port]:LoadAndReturnPortToName(found_alias_port),
  210.             " "
  211.             )
  212.         );
  213.         }
  214.     } else {
  215.         if (!contains(cache_not_allowed_ports, port)) {
  216.         cache_not_allowed_ports = add (cache_not_allowed_ports, port);
  217.         y2error("Port name '%1' is not allowed", port);
  218.         } else {
  219.         y2debug("Port name '%1' is not allowed", port);
  220.         }
  221.         return [ port ];
  222.     }
  223.  
  224.     return toset(service_aliases);
  225.     }
  226.  
  227.     /**
  228.      * Function returns if the requested port-name is known port.
  229.      * Known port have an IANA alias.
  230.      *
  231.      * @param    string port-name
  232.      * @return    boolean if is known
  233.      */
  234.     global define boolean IsKnownPortName (string port_name) {
  235.     // function returns the requested port and aliases if exists
  236.     if (size(GetListOfServiceAliases(port_name))>1) {
  237.         return true;
  238.     }
  239.     return false;
  240.     }
  241.  
  242.     /**
  243.      * Function returns a port number for the port name alias
  244.      *
  245.      * @param port_name_or_number
  246.      * @param port_number or nil when not found
  247.      */
  248.     global define integer GetPortNumber (string port_name) {
  249.     if (!regexpmatch(port_name, "^[0123456789]+$")) {
  250.         any port_number = SERVICE_NAME_TO_PORT[port_name]:LoadAndReturnNameToPort(port_name);
  251.  
  252.         // not a known port
  253.         if (port_number == nil) {
  254.         return nil;
  255.         } else {
  256.         return tointeger (port_number);
  257.         }
  258.     } else {
  259.         return tointeger(port_name);
  260.     }
  261.     }
  262.                                             
  263.  
  264. /* EOF */
  265. }
  266.