<commit_before><?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# All rights reserved.
#
require("defs.php3");
require("node_defs.php");

$reqargs = RequiredPageArguments("ip", PAGEARG_STRING);
$optargs = OptionalPageArguments("privkey", PAGEARG_STRING,
				 "check", PAGEARG_BOOLEAN,
				 "os", PAGEARG_STRING,
				 "os_version", PAGEARG_STRING,
				 "distro", PAGEARG_STRING,
				 "distro_version", PAGEARG_STRING,
				 "arch", PAGEARG_STRING,
				 "env", PAGEARG_STRING);

#
# The point of this page is to figure out what osconfig scripts
# the node ought to execute, and return them in a tarball.  We attempt to 
# cache the tarballs as much as possible and only rebuild when necessary.
#
# NOTE!  This page is only accessible over SSL, but it is only "secure" for 
# widearea nodes (which provide a privkey).  Local connections are not secure
# at all -- eventually this could move to tmcc.  And when you get down to it,
# the widearea privkeys are not well protected.  Consequently, NO PRIVATE DATA
# should go into these scripts.  There should not be a need for that, anyway.
# This is meant to be an operator mechanism, not a user mechanism, and it is 
# not meant for private data, just client-side config stuff.
#

#
# Constraints that we satisfy.  Note that different constraint types are ANDed;
# if there are multiple values to a constraint type, those are ORed.  Had to
# do something...
#
$constraints = array("node_id","class","type",
                     "os","os_version","distro","distro_version","arch");

#
# Available states in which we support an osconfig
#
$stages = array("premfs","postload");
$FILEROOT = "$TBDIR/etc/osconfig";

#
# A few helper functions.
#
function SPITERROR($msg) {
    header("Content-Type: text/plain");
    $fmsg = "TBERROR: $msg\n";
    header("Content-Length: " . strlen($fmsg) . "\n");
    echo "$fmsg";
    exit(1);
}

function SPITMSG($msg) {
    header("Content-Type: text/plain");
    $fmsg = "TBMSG: $msg\n";
    header("Content-Length: " . strlen($fmsg) . "\n");
    echo "$fmsg";
    exit(1);
}

function SPITNOTHING() {
    header("Content-Type: text/plain");
    header("Content-Length: 0");
    exit(0);
}

function IsControlNetIP($myIP) {
    global $CONTROL_NETWORK,$CONTROL_NETMASK;

    if (ip2long($CONTROL_NETWORK) == (ip2long($CONTROL_NETMASK) 
				      && ip2long($myIP)))
	return 1;

    return 0;
}

function match_constraint($constraint,$value,$data) {
    if (!isset($data[$constraint]))
	return FALSE;

    if (!strncmp($value,"/",1)) {
        # a pcre regex
	if (preg_match($value,$data[$constraint]))
	    return TRUE;
    }
    else if ($value == $data[$constraint]) {
	return TRUE;
    }

    return FALSE;
}

#
# do stuff!
#

# if we do not have a stage, assume one
if (!isset($env) || !in_array($env,$stages)) {
    $env = "postload";
}

# if check is not set, don't just check
if (!isset($check)) {
    $check = 0;
}

# Must use https
if (!isset($_SERVER["SSL_PROTOCOL"])) {
    SPITERROR("insecure");
}

# make sure args are sane
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ip) ||
    (isset($privkey) && !preg_match('/^[\w]+$/', $privkey))) {
    SPITERROR("invalid args");
}

# XXX for now, we assert if REMOTE_ADDR is not the same as $ip
# obviously, this needs to be changed for remote nodes with proxies...
if ($_SERVER["REMOTE_ADDR"] != $ip) {
    SPITERROR("no proxies allowed");
}

# need node_id below
#
# Make sure this is a valid request before we return anything.
#
# Note, we don't use Node::LookupByIP in the widearea case since there might
# be multiple node_ids using this control IP -- we explicitly look for the
# one in the widearea_nodeinfo table.
$node_id = "";
if (isset($privkey)) {
    $qres = DBQueryFatal("select node_id from widearea_nodeinfo" .
			 " where IP='" . addslashes($ip) . "' and" . 
			 "   privkey='" . addslashes($privkey) . "'");
    if (!$qres || mysql_num_rows($qres) < 1) {
	SPITERROR("noauth");
    }
    else if (mysql_num_rows($qres) > 1) {
	SPITERROR("ambiguous id");
    }

    $row = mysql_fetch_array($qres);
    $node_id = $row["node_id"];
    $node = Node::Lookup($node_id);
}
else {
    if (!IsControlNetIP($ip)) {
	SPITERROR("notlocal");
    }
    $node = Node::Lookup($ip);
    $node_id = $node->node_id();
}
if (!$node) {
    SPITERROR("no such node");
}

#
# Load up and match constraints.
#
$qres = DBQueryFatal("select target_file_idx,constraint_name,constraint_value" .
		     "  from osconfig_targets" .
		     " where target_apply='" . addslashes($env) . "'" . 
		     " order by constraint_idx");
if (!mysql_num_rows($qres))
    SPITNOTHING();

$match_targets = array();
$conproc = array();

$data = array("node_id" => $node_id,"class" => $node->TypeClass(),<commit_msg>Ugh, stupidity.<commit_after><?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# All rights reserved.
#
require("defs.php3");
require("node_defs.php");

$reqargs = RequiredPageArguments("ip", PAGEARG_STRING);
$optargs = OptionalPageArguments("privkey", PAGEARG_STRING,
				 "check", PAGEARG_BOOLEAN,
				 "os", PAGEARG_STRING,
				 "os_version", PAGEARG_STRING,
				 "distro", PAGEARG_STRING,
				 "distro_version", PAGEARG_STRING,
				 "arch", PAGEARG_STRING,
				 "env", PAGEARG_STRING);

#
# The point of this page is to figure out what osconfig scripts
# the node ought to execute, and return them in a tarball.  We attempt to 
# cache the tarballs as much as possible and only rebuild when necessary.
#
# NOTE!  This page is only accessible over SSL, but it is only "secure" for 
# widearea nodes (which provide a privkey).  Local connections are not secure
# at all -- eventually this could move to tmcc.  And when you get down to it,
# the widearea privkeys are not well protected.  Consequently, NO PRIVATE DATA
# should go into these scripts.  There should not be a need for that, anyway.
# This is meant to be an operator mechanism, not a user mechanism, and it is 
# not meant for private data, just client-side config stuff.
#

#
# Constraints that we satisfy.  Note that different constraint types are ANDed;
# if there are multiple values to a constraint type, those are ORed.  Had to
# do something...
#
$constraints = array("node_id","class","type",
                     "os","os_version","distro","distro_version","arch");

#
# Available states in which we support an osconfig
#
$stages = array("premfs","postload");
$FILEROOT = "$TBDIR/etc/osconfig";

#
# A few helper functions.
#
function SPITERROR($msg) {
    header("Content-Type: text/plain");
    $fmsg = "TBERROR: $msg\n";
    header("Content-Length: " . strlen($fmsg) . "\n");
    echo "$fmsg";
    exit(1);
}

function SPITMSG($msg) {
    header("Content-Type: text/plain");
    $fmsg = "TBMSG: $msg\n";
    header("Content-Length: " . strlen($fmsg) . "\n");
    echo "$fmsg";
    exit(1);
}

function SPITNOTHING() {
    header("Content-Type: text/plain");
    header("Content-Length: 0");
    exit(0);
}

function IsControlNetIP($myIP) {
    global $CONTROL_NETWORK,$CONTROL_NETMASK;

    if (ip2long($CONTROL_NETWORK) == (ip2long($CONTROL_NETMASK) 
				      && ip2long($myIP)))
	return 1;

    return 0;
}

function match_constraint($constraint,$value,$data) {
    if (!isset($data[$constraint]))
	return FALSE;

    if (!strncmp($value,"/",1)) {
        # a pcre regex
	if (preg_match($value,$data[$constraint]))
	    return TRUE;
    }
    else if ($value == $data[$constraint]) {
	return TRUE;
    }

    return FALSE;
}

#
# do stuff!
#

# if we do not have a stage, assume one
if (!isset($env) || !in_array($env,$stages)) {
    $env = "postload";
}

# if check is not set, don't just check
if (!isset($check)) {
    $check = 0;
}

# Must use https
if (!isset($_SERVER["SSL_PROTOCOL"])) {
    SPITERROR("insecure");
}

# make sure args are sane
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ip) ||
    (isset($privkey) && !preg_match('/^[\w]+$/', $privkey))) {
    SPITERROR("invalid args");
}

# XXX for now, we assert if REMOTE_ADDR is not the same as $ip
# obviously, this needs to be changed for remote nodes with proxies...
if ($_SERVER["REMOTE_ADDR"] != $ip) {
    SPITERROR("no proxies allowed");
}

# need node_id below
#
# Make sure this is a valid request before we return anything.
#
# Note, we don't use Node::LookupByIP in the widearea case since there might
# be multiple node_ids using this control IP -- we explicitly look for the
# one in the widearea_nodeinfo table.
$node_id = "";
if (isset($privkey)) {
    $qres = DBQueryFatal("select node_id from widearea_nodeinfo" .
			 " where IP='" . addslashes($ip) . "' and" . 
			 "   privkey='" . addslashes($privkey) . "'");
    if (!$qres || mysql_num_rows($qres) < 1) {
	SPITERROR("noauth");
    }
    else if (mysql_num_rows($qres) > 1) {
	SPITERROR("ambiguous id");
    }

    $row = mysql_fetch_array($qres);
    $node_id = $row["node_id"];
    $node = Node::Lookup($node_id);
}
else {
    if (!IsControlNetIP($ip)) {
	SPITERROR("notlocal");
    }
    $node = Node::Lookup($ip);
    if ($node) {
	$node_id = $node->node_id();
    }
}
if (!$node) {
    SPITERROR("no such node");
}

#
# Load up and match constraints.
#
$qres = DBQueryFatal("select target_file_idx,constraint_name,constraint_value" .
		     "  from osconfig_targets" .
		     " where target_apply='" . addslashes($env) . "'" . 
		     " order by constraint_idx");
if (!mysql_num_rows($qres))
    SPITNOTHING();

$match_targets = array();
$conproc = array();

$data = array("node_id" => $node_id,"class" => $node->TypeClass(),
{'fraction_non_alphanumeric': 0.15566924201294632, 'fraction_numerical': 0.006264355815410315, 'mean_word_length': 3.686399217221135, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2720516', 'n_tokens_mistral': 3379, 'n_tokens_neox': 3220, 'n_words': 940}