--- loncom/lond 2022/07/25 23:31:40 1.576 +++ loncom/lond 2023/05/22 21:10:56 1.577 @@ -2,7 +2,7 @@ # The LearningOnline Network # lond "LON Daemon" Server (port "LOND" 5663) # -# $Id: lond,v 1.576 2022/07/25 23:31:40 raeburn Exp $ +# $Id: lond,v 1.577 2023/05/22 21:10:56 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -65,7 +65,7 @@ my $DEBUG = 0; # Non zero to ena my $status=''; my $lastlog=''; -my $VERSION='$Revision: 1.576 $'; #' stupid emacs +my $VERSION='$Revision: 1.577 $'; #' stupid emacs my $remoteVERSION; my $currenthostid="default"; my $currentdomainid; @@ -306,6 +306,7 @@ my %trust = ( servertimezone => {remote => 1, enroll => 1}, setannounce => {remote => 1, domroles => 1}, sethost => {anywhere => 1}, + signlti => {remote => 1}, store => {remote => 1, enroll => 1, reqcrs => 1,}, studentphoto => {remote => 1, enroll => 1}, sub => {content => 1,}, @@ -5307,6 +5308,76 @@ sub lti_handler { ®ister_handler("lti", \<i_handler, 1, 1, 0); # +# LTI data for launch payload (received encrypted) are unencrypted and +# then signed with the appropriate key and secret, before re-encrypting +# for sending as the signed payload to the client (caller lonnet::sign_lti()). +# +# Parameters: +# $cmd - Command request keyword (signlti). +# $tail - Tail of the command. This is a colon-separated list +# consisting of the domain, coursenum (if for an External +# Tool defined in a course), crstool (true if defined in +# a course), escaped launch URL, numeric ID of external tool +# version number for encryption key (if tool's LTI secret was +# encrypted before storing), post (true if signed data are +# to be returned from Net::OAuth, as a post_body), +# a frozen hash of LTI launch parameters, and a frozen hash +# of LTI config data (i.e., method => signature method). +# $client - File descriptor open on the client. +# Returns: +# 1 - Continue processing. +# 0 - Exit. +# Side effects: +# The reply will contain the LTI payload, as & separated key=value pairs, +# where value is itself a frozen hash, if the required key and secret +# for the apecific tool ID are available. The payload data are retrived from +# a call to Lond::sign_params(), and the reply is encrypted before being +# written to $client. +# +sub sign_lti_handler { + my ($cmd, $tail, $client) = @_; + + my $userinput = "$cmd:$tail"; + + my ($cdom,$cnum,$crstool,$escurl,$idx,$keynum,$post,$paramsref,$inforef) = split(/:/,$tail); + my $url = &unescape($escurl); + my $params = &Apache::lonnet::thaw_unescape($paramsref); + my $info = &Apache::lonnet::thaw_unescape($inforef); + my $res = + &LONCAPA::Lond::sign_params($cdom,$cnum,$crstool,$url,$idx,$keynum, + $post,$perlvar{'lonVersion'},$params,$info); + my $result; + if (ref($res) eq 'HASH') { + foreach my $key (keys(%{$res})) { + $result .= &escape($key).'='.&Apache::lonnet::freeze_escape($res->{$key}).'&'; + } + $result =~ s/\&$//; + } else { + $result = $res; + } + if ($result =~ /^error:/) { + &Failure($client, \$result, $userinput); + } else { + if ($cipher) { + my $cmdlength=length($result); + $result.=" "; + my $encres=''; + for (my $encidx=0;$encidx<=$cmdlength;$encidx+=8) { + $encres.= unpack("H16", + $cipher->encrypt(substr($result, + $encidx, + 8))); + } + &Reply( $client,"enc:$cmdlength:$encres\n",$userinput); + } else { + &Failure( $client, "error:no_key\n",$userinput); + } + } + return 1; +} +®ister_handler("signlti", \&sign_lti_handler, 1, 1, 0); + +# # Puts an id to a domains id database. # # Parameters: