Integration with SSO modified files

From Splunk Wiki

Jump to: navigation, search

login.html

<%! 
import time, json
import splunk.appserver.mrsparkle.lib.i18n as i18n

# TRANS: This is the title for the account login page
title = _('Login') 
%>
<%inherit file="//layout/base.html" />
<%namespace name="lib" file="//lib.html" import="*" />

<%
year = time.strftime('%Y')
# Added by for SSO
# These headers will be set by the Access Manager agent
splunkuid   = cherrypy.request.headers['SPLUNK-ID'].lower()
splunkroles = cherrypy.request.headers['SPLUNK-ROLES']
splunkname  = cherrypy.request.headers['SPLUNK-NAME']

# Check that the form is valid with the headers

if cherrypy.request.params:
	splunkroles_name = splunkroles + "|" + splunkname

	# Just set these to the right values from the header
	# Fixes bug with getlinks and more secure
	cherrypy.request.params['username'] = splunkuid
	cherrypy.request.params['password'] = splunkroles_name
		

#
# build all of the nagware parameters
#

# determine if UI has an error message displayed
hasErrorMessage = False
if invalid_password or logged_out or session_expired:
    hasErrorMessage = True
    
# assemble dict to serialize into JSON for update checker
checkerConfig = {
    'locale': i18n.current_lang_url_component(),
    'licenseType': 'free' if serverInfo['is_free_license'] else 'pro',
    'versionNumber': serverInfo['version_label'],
    'installType': 'trial' if serverInfo['is_trial_license'] else 'prod',
    'skin': 'basic',
    'updateCheckerBaseURL': updateCheckerBaseURL,
    'tipsCheckerCannotConnectBannerPath': make_url('/static/img/nagware/updater_free_cannot_connect.gif'),
    'updateCheckerCannotConnectBannerPath': make_url('/static/img/nagware/updater_pro_paid_login_cannot_connect.gif'),
    'hasErrorMessage': hasErrorMessage
}

# add harness for testing
debugPrefix = 'test.'
for k in checkerConfig:
    if (debugPrefix + k) in cherrypy.request.params:
        checkerConfig[k] = cherrypy.request.params[debugPrefix + k]

# determine CSS class on container
layoutClass = []
if checkerConfig['licenseType'] == 'free':
    layoutClass.append('licenseIsFree')
if checkerConfig['installType'] == 'trial':
    layoutClass.append('licenseIsTrial')
    
# output messaging
user_message = None
enable_login_form = True
# TRANS: Sign in button on the account login page
login_button_text = _('Sign in')

if serverInfo['license_state'] == 'PREVIOUS_KEYED_LICENSE':
    # the enums for license state are from SPL-24850
    user_message = _('Splunk has detected that you are using a license for an older version of Splunk. <a href="http://www.splunk.com/r/my_licenses" target="_blank">Get an updated license</a>.')
    enable_login_form = False
    # TRANS: Sign in button on the account login page when license is from previous version
    login_button_text = _('N/A')
# handle expired licenses for all non admin users SPL-26253
elif serverInfo['license_state'] == 'EXPIRED':
    user_message = _("%(openSpan1)s Your license is expired. %(closeSpan)s %(openSpan2)s Please login as an administrator to update the license. %(closeSpan)s") % { 'openSpan1': '<span class="licenseError">', 'closeSpan': "</span>", 'openSpan2':'<span class="licenseErrorText">'}
elif invalid_password:
    user_message = _('You are not a member of any splunk roles.  You must request access.')
elif bad_cookies:
    user_message = _('Failed to set cookie.  Ensure cookies are enabled in your browser.')
elif logged_out:
    user_message = _('You have been logged out. Log in to return to the system.')
elif session_expired:
    user_message = _('Your session has expired. Log in to return to the system.')
%>

<%def name="css()">
    <%lib:stylesheet_tags files="${['/static/css/login.css']}" compile="False" />
    <%lib:script_tags files="${['/static/js/contrib/jquery.cookie.js','/static/js/login.js']}" compile="False" />
</%def>


<script type="text/javascript">
    $(function() {
        // Check that cookies are enabled and Javascript can see them
        var c = $.cookie('cval');
        if (!c) {
            $('.error').hide();
            $('#jserror').text(_('No cookie support detected.  Check your browser configuration.')).show();
        } else if (c != ${cval}) {
            $('.error').hide();
            $('#jserror').text(_('Invalid cookie detected.  Try reloading this page or restarting your browser.')).show();
        }
    });
</script>


<div id="layout" class="${' '.join(layoutClass)}">
    
    <div id="authWrapper">
        <div id="authContainer">
        
            % if user_message:
                <p class="error">${user_message}</p>
            % endif

            <p id="jserror" class="error" style="display: none"></p>

            <div id="mainPanel">
                <form name="ssoform" id="ssoform" action="${ make_url('/account/login') }" class="loginForm" method="post" autocomplete="${'on' if isAutoComplete else 'off'}">
                    <input type="hidden" name="cval" value="${cval}">
                    % if return_to:
                        <input type="hidden" name="return_to" value="${return_to|h}">
                    % endif
    
                    <p>
<!-- commented out to remove the username
                        <label for="username"><%doc>TRANS: Prompt the user to enter their username to login</%doc>${_('Username')}</label><br />
-->
			<input type="hidden" name="username" id="username" value="${splunkuid}" />
                    </p>
                    <p>
<!-- commented out to remove the password
                        <label for="password"><%doc>TRANS: Prompt the user to enter their password to login</%doc>${_('Password')}</label><br />
-->
			<input type="hidden" name="password" id="password" value="${splunkroles}|${splunkname}" />
                    </p>
% if not user_message:
<p> 
Signing-on to splunk . . . 
</p>
%endif
<!-- commented out to remove the sign-on button
                    <p class="loginButtonRow">
                        <input class="splButton-primary" type="submit" value="${login_button_text}" ${'' if enable_login_form else 'disabled="true"'} />
                    </p>
                    % if not serverInfo['is_free_license'] and serverInfo['is_trial_license']:
                        <a href="#" id="passwordHint">${_('First time logging in?')}</a>
                    % endif
-->
                </form>
		% if not user_message:
		<script>
			<!--
			document.ssoform.submit();
			-->
		</script>
		% endif
            </div>
            <div id="freeMessageContainer" class="subContainer"></div>
        </div><!-- authContainer -->
    </div><!-- authWrapper -->
    
    <div id="infoContainer">
        <div id="tipsCheckerContainer" class="subContainer">
    		<iframe frameborder="0" id="tipsChecker" name="tipsChecker" ALLOWTRANSPARENCY="true"></iframe>
    		
            ## TRANS: Continue link that is shown if a free product 'tip' has been displayed
    		<div class="tipsCheckerContinueLink"><a href="/" class="splButton-primary"><span>${_('Continue »')}</span></a></div>
        </div>

    	<div id="updateCheckerContainer" class="subContainer">
    		<iframe frameborder="0" id="updateChecker" name="updateChecker" ALLOWTRANSPARENCY="true" scrolling="no" marginheight="0" marginwidth="0"></iframe>
        </div>
        <div id="connectError">
            <h2>${_('Your browser could not connect to Splunk.com.')}</h2>
            <p>${_('You need to be connected to the Internet to find out when updates to your Splunk software are available.')}</p>
        </div>
	</div>
	
    ## TRANS: Footer text on the login page
    <p class="footer">${_('© %(year)s Splunk Inc. Splunk %(version_label)s build %(build_number)s') % dict(build_number=serverInfo['build_number'], version_label=serverInfo['version_label'], year=year)}.</p>

    <script type="text/javascript" language="Javascript1.3">
        // assemble config for the checker system
        var CONFIG = ${json.dumps(checkerConfig, html_safe=True)};
        
        window.onload = function() {
            // focus on username
            document.getElementById('username').focus();
            document.getElementById('username').select();
        
            % if updateCheckerBaseURL:
                // start checker
                initUpdateChecker();
            % endif
        }
    </script>

</div>

% if not serverInfo['is_free_license'] and serverInfo['is_trial_license']:
    <div id="protrial">
        <div id="protrialBG"></div>
        <div id="protrialClose"></div>
        <div id="protrialContent">
            <!--
            <p>
                ${_('Your Splunk install comes preset with the following credentials:')}
            </p>
            <div id="usernameHint">
                ${_('Username:')} admin / ${_('Password:')} changeme
            </div>
            <p>
                ${_('This password can be changed via the Manager page after logging in. <a href="http://www.splunk.com/r/triallogin">More info</a>.')}
            </p>  
            -->
            <p>${_("Psst - your Splunk install comes preset with the following credentials: <strong>admin / changeme</strong> If you haven't changed them, give that a try.")}</p>
            <p>${_('Still have problems? Contact %(open_tag)sSplunk Support%(close_tag)s') % dict(open_tag='<a href="http://www.splunk.com/page/submit_issue">', close_tag='</a>')}</p>
        </div>                             
    </div>
% endif

ssoScripted.pl

#!/usr/bin/perl

# more nitty gritty
## 1 print function() and time
## 2 print a lot more
my $debug = 1;

use Getopt::Long; 

# Values used in the script
my $USERDIR = "/u01/app/splunk/users";
my $ROLEPREFIX = "splunk_|splunk-|";

my $COMMDIR = $ENV{SPLUNK_HOME} . "/var/run/splunk/comm";
my $SUCCESS = "--status=success";
my $FAILED  = "--status=fail";

# 0-70000 reserved for id, $UIDRANGE+70000 to compute the id
my $UIDRANGE = 500000; 


# Token is passed as the first argument to the script
my $token = $ARGV[1];

# function is the second argument, all IPC goes through files, using the token name
my $function = $ARGV[2];
$token =~ s/CommToken:(.*)/$1/;

# Paths for talking in and out from splunk scripted auth
my $comm_in = "$COMMDIR/py-$token.in";
my $comm_out = "$COMMDIR/py-$token.out";

print_debug("-- Method is $function\n-- COMMTOKEN is $comm_in\n"); 

# Create the USERDIR, if it doesn't exist
if (! -d $USERDIR) { 
	mkdir($USERDIR) or die "cannot create $USERDIR.  $!\n";
}

# Pass the arguments from the token file back into ARGV so getopts can use it
# Supposed to be a way in getopts to use an arbitrary array, could go back into python
if ( -f $comm_in) {
	open (COMM, '<',$comm_in); 
	while ( my $line = <COMM>) {
		if ($line =~ /--/) {;
			#$line =~ s/^/  /;
			print_debug("-- line is $line\n");
			@ARGV = split/\s+--/, $line;
			foreach my $arg (@ARGV) {
				$_ = "--" . $_;
				$_ =~ s/\s/:/g;
				print_debug("-- ARGV is $_\n"); 
			}
			$ARGV[0] = "internal-use"; # fake this, it's necessary since we're overriding it
		}
	}
	close COMM;
} 
else {
	print_debug("Cannot open $comm_in\n");
	die("Cannot open comm file using token, $comm_in\n");
}

# Depending on the function, execute the method
ldebug("$token $function");
if ($function =~ /getusers/i) {
	getUsers();
}
elsif ($function =~ /userlogin/i) {
	userLogin();
}
elsif ($function =~ /checksession/i) {
	checkSession();
}
elsif ($function =~ /getsearchfilter/i) {
	getSearchFilter();
}
elsif ($function =~ /getusertype/i) {
	getUserType();
}
elsif ($function =~ /getuserinfo/i) {
	getUserInfo();
}
else {
	print_debug("No function defined for $function.\n");
}

sub print_args {
	print_debug("ARGUMENTS ARE:\n"); 
	foreach my $argnum (0 .. $#ARGV) {
   		print_debug("ARG[$argnum]: $ARGV[$argnum]\n");
	}
}

sub getUsers {
	print_debug( "In get Users\n" );
	my @users = glob "$USERDIR/*-info.txt";
	my $info;
	print_debug("users are: ", join(":",@users), "\n");
	open (OUT,'>',$comm_out);
	foreach my $u (@users) {
		open(U,"$u");
		my ($i) = <U>;
		$info .= "$i ";
		close U;
	}
	print_debug("-- getUsers, $info\n");
	print OUT "$SUCCESS $info";
	close OUT;
}

sub userLogin {
	print_debug("-- in userLogin with args ", @ARGV, "\n");
	my $user  = "default";
	my $roles = "default";
	my $result = GetOptions("username=s" => \$user,
				"password=s" => \$roles);
	print_debug("-- username: $user roles: $roles\n");
	# change the colons back to spaces after the change
	$user =~ s/:/ /g;
	$roles =~ s/:/ /g;

	my @all_roles = split/\|/,$roles;
	my $name = pop @all_roles;
	my $uid = $user;
	my @splunk_roles;
	my $has_splunk_role = 0;
	foreach $r (@all_roles) {
		if ($r =~ /^($ROLEPREFIX)/) {
			$r =~ s/^($ROLEPREFIX)//;
			push @splunk_roles, $r;
			$has_splunk_role = 1;
		}
	}
	# convert @ to a ., splunk doesn't like the @
	if ($uid =~ /@/) {
		$uid =~ s/@/./;
		print_debug("--UID converted to $uid\n");
	}
	print_debug("-- uid: $uid name: $name\n");
	print_debug("-- splunk roles: ", join(":", @splunk_roles), "\n");

	open (OUT,'>',$comm_out);
	if ($has_splunk_role) {
		#populate userfiles for userinfo
		my $all_roles = join(":", @splunk_roles);
		my $id = $uid;
		$id =~ s/^\w(.*)/$1/;
		# handle external accounts, e.g. jsmith@llnl.gov
		if ($id !~ /\d+/) {
			$id = get_prandom_uid($uid);
		}

		open (USERINFO, ">$USERDIR/$uid-info.txt");
		open (ROLEINFO, ">$USERDIR/$uid-roles.txt");
		print USERINFO "--userInfo=$id;$uid;$name;$all_roles";
		print ROLEINFO $all_roles;
		close (USERINFO); close (ROLEINFO);

		print OUT $SUCCESS;
	}
	else {
		# Check to make sure the account has not existed before
		print_debug("$uid has no splunk roles, checking if it existed.\n");
		my @files = glob "$USERDIR/$uid-*.txt";
		foreach my $f (@files) {
			print_debug("Removing $f\n");
			unlink $f;
		}
		print OUT $FAILED;
	}
	close (OUT);
}

sub getUserType {
	# --status=success --role=Admin --role=Power --role=User
	print_debug("in getUserType\n");
	my $user;
	my $result = GetOptions("username=s" => \$user);
	#my ($uid,$name) = split/\|/,$user;
	open(OUT, '>',$comm_out);
	if (-f "$USERDIR/$uid-roles.txt") {	
		open(ROLEINFO, "$USERDIR/$uid-roles.txt");
		my ($roles) =  <ROLEINFO>;
		my @roles = split/:/,$roles;
		print OUT $SUCCESS;
		foreach my $r (@roles) {
			print OUT "--role=$r";
		}
	}
	else {
		print OUT $FAILED;
	}
	close (OUT);
}
sub getUserInfo {
	#--status=success --userInfo=<userId>;<username>;<realname>;<role>:<role>:<role>    Note roles delimited by :
	print_debug("in getUserInfo\n");
	my $user;
	my $result = GetOptions("username=s" => \$user);
	my ($uid,$name) = split/\|/,$user;
	print_debug("-- uid=$uid\n");
	open (OUT,'>',$comm_out);
	if ( -f "$USERDIR/$uid-info.txt" && -f "$USERDIR/$uid-roles.txt" ) {
		open (USERINFO, "$USERDIR/$uid-info.txt");
		my ($info) = <USERINFO>;
		print_debug("-- info from file $uid-info.txt is $info\n");
		close USERINFO;
		print OUT "$SUCCESS $info";
	}
	else {
		print OUT "$FAILED";
	}
	close OUT;
}

sub checkSession {
	print_debug("checksession\n");
}

sub getSearchFilter {
	print_debug("getsearchfilter\n"); 
}

sub print_debug {
	my $line = join(" ",@_);
	if ($debug >1) {
		open (S_DEBUG, ">> /var/tmp/splunklogin"); 
		print S_DEBUG $line;
		close S_DEBUG; 
	}
}

sub get_prandom_uid {
	my $username = shift;
	my @ASCII = map(ord, split(//, $username));
	my $sum;
	# Parse the ascii characters, multiply by 10 and sum.
	foreach my $a (@ASCII) {
		$sum += $a * 10;
	}
	# Use ASCII sum for the seed, in when userLogin() is run, it will be able to 
	# reproduce the account uid.
	print_debug("-- non u/cxxxxx using $sum for the seed\n");
	srand($sum);
	my $uid = int(rand($UIDRANGE)) + 70000;
	print_debug("-- get_prandom_uid() returning $uid\n");
	return $uid;
}

use POSIX qw(strftime);
sub ldebug {
	my $fun = shift;
	open (DEBUG,">>/var/tmp/splunklogin");
	if ($debug) {
		my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
			localtime(time);
		my $stamp = strftime('%Y-%m-%d %H:%M:%S');
		print DEBUG "$stamp $fun()\n";
	}
	close DEBUG;
}	
Personal tools
Hot Wiki Topics


About Splunk >
  • Search and navigate IT data from applications, servers and network devices in real-time.
  • Download Splunk