many improvements on the process and published of the encrypted format; if a public key isn't provided as metadata, the key is passed in plain text using a .txt file, otherwise a .enc file is used to store the encrypted key; fixed identation; removing all files except the published ones; handling also the files stored on /var/bigbluebutton/{meetingId} - they are now included into the zip file and will be restored on the recording server
This commit is contained in:
parent
420f5c976b
commit
d26f25f7fb
22
record-and-playback/mconf/scripts/mconf.nginx
Normal file
22
record-and-playback/mconf/scripts/mconf.nginx
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
location /mconf {
|
||||
root /var/bigbluebutton/published;
|
||||
index index.html index.htm;
|
||||
}
|
@ -1,3 +1 @@
|
||||
publish_dir: /var/bigbluebutton/published/mconf
|
||||
playback_host: 143.54.10.141
|
||||
get_recordings_url: http://143.54.10.141/bigbluebutton/api/getRecordings?checksum=890f03ce56424120dc467f3bbf310a54fd05b541
|
||||
|
@ -38,16 +38,22 @@ BigBlueButton.logger = logger
|
||||
props = YAML::load(File.open('../../core/scripts/bigbluebutton.yml'))
|
||||
|
||||
recording_dir = props['recording_dir']
|
||||
raw_archive_dir = "#{recording_dir}/raw/#{meeting_id}"
|
||||
target_dir = "#{recording_dir}/process/mconf/#{meeting_id}"
|
||||
raw_presentation_src = props['raw_presentation_src']
|
||||
|
||||
if not FileTest.directory?(target_dir)
|
||||
FileUtils.mkdir_p target_dir
|
||||
# Create a copy of the raw archives
|
||||
FileUtils.cp_r(raw_archive_dir, target_dir)
|
||||
FileUtils.rm_r(Dir.glob("#{raw_archive_dir}/*"))
|
||||
process_done = File.new("#{recording_dir}/status/processed/#{meeting_id}-mconf.done", "w")
|
||||
process_done.write("Processed #{meeting_id}")
|
||||
process_done.close
|
||||
meeting_raw_dir = "#{recording_dir}/raw/#{meeting_id}"
|
||||
meeting_raw_presentation_dir = "#{raw_presentation_src}/#{meeting_id}"
|
||||
meeting_process_dir = "#{recording_dir}/process/mconf/#{meeting_id}"
|
||||
|
||||
if not FileTest.directory?(meeting_process_dir)
|
||||
FileUtils.mkdir_p "#{meeting_process_dir}/presentation_raw"
|
||||
# Create a copy of the raw archives
|
||||
BigBlueButton.logger.info("Copying the recording raw files from #{meeting_raw_dir} to #{meeting_process_dir}")
|
||||
FileUtils.cp_r Dir.glob("#{meeting_raw_dir}/*"), meeting_process_dir
|
||||
BigBlueButton.logger.info("Copying the recording presentation from #{meeting_raw_presentation_dir}/#{meeting_id} to #{meeting_process_dir}/presentation_raw")
|
||||
FileUtils.cp_r Dir.glob("#{meeting_raw_presentation_dir}/#{meeting_id}/*"), "#{meeting_process_dir}/presentation_raw"
|
||||
|
||||
process_done = File.new("#{recording_dir}/status/processed/#{meeting_id}-mconf.done", "w")
|
||||
process_done.write("Processed #{meeting_id}")
|
||||
process_done.close
|
||||
end
|
||||
|
||||
|
@ -25,10 +25,11 @@ require 'cgi'
|
||||
require 'digest/md5'
|
||||
|
||||
bbb_props = YAML::load(File.open('../../core/scripts/bigbluebutton.yml'))
|
||||
simple_props = YAML::load(File.open('mconf.yml'))
|
||||
recording_dir = bbb_props['recording_dir']
|
||||
playback_host = simple_props['playback_host']
|
||||
publish_dir = simple_props['publish_dir']
|
||||
playback_host = bbb_props['playback_host']
|
||||
published_dir = bbb_props['published_dir']
|
||||
raw_presentation_src = bbb_props['raw_presentation_src']
|
||||
|
||||
done_files = Dir.glob("#{recording_dir}/status/processed/*.done")
|
||||
done_files.each do |df|
|
||||
match = /(.*)-(.*).done/.match df.sub(/.+\//, "")
|
||||
@ -36,94 +37,102 @@ done_files.each do |df|
|
||||
if (match[2] == "mconf")
|
||||
BigBlueButton.logger = Logger.new("/var/log/bigbluebutton/mconf/publish-#{meeting_id}.log", 'daily' )
|
||||
|
||||
process_dir = "#{recording_dir}/process/mconf/#{meeting_id}"
|
||||
target_dir = "#{recording_dir}/publish/mconf/#{meeting_id}"
|
||||
if not FileTest.directory?(target_dir)
|
||||
FileUtils.mkdir_p target_dir
|
||||
meeting_process_dir = "#{recording_dir}/process/mconf/#{meeting_id}"
|
||||
meeting_publish_dir = "#{recording_dir}/publish/mconf/#{meeting_id}"
|
||||
meeting_published_dir = "#{recording_dir}/published/mconf/#{meeting_id}"
|
||||
meeting_raw_dir = "#{recording_dir}/raw/#{meeting_id}"
|
||||
meeting_raw_presentation_dir = "#{raw_presentation_src}/#{meeting_id}"
|
||||
|
||||
Dir.chdir(target_dir) do
|
||||
BigBlueButton::MconfProcessor.zip_directory(process_dir, "#{meeting_id}.zip")
|
||||
|
||||
if not FileTest.directory?(meeting_publish_dir)
|
||||
FileUtils.mkdir_p meeting_publish_dir
|
||||
|
||||
metadata = BigBlueButton::Events.get_meeting_metadata("#{process_dir}/#{meeting_id}/events.xml")
|
||||
|
||||
if not (metadata[:keypublic])
|
||||
BigBlueButton.logger.info("Verifying events: #{metadata[:keypublic.to_s]}")
|
||||
public_key_decoded = CGI::unescape("#{metadata[:keypublic.to_s]}")
|
||||
|
||||
length = 16
|
||||
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
|
||||
password = ''
|
||||
length.times { password << chars[rand(chars.size)] }
|
||||
|
||||
passfile = File.new("#{meeting_id}.txt", "w")
|
||||
passfile.write "#{password}"
|
||||
passfile.close
|
||||
Dir.chdir(meeting_publish_dir) do
|
||||
BigBlueButton::MconfProcessor.zip_directory(meeting_process_dir, "#{meeting_id}.zip")
|
||||
|
||||
keypublic = File.new("key-public.pem","w")
|
||||
keypublic.write "#{public_key_decoded}"
|
||||
keypublic.close
|
||||
metadata = BigBlueButton::Events.get_meeting_metadata("#{meeting_process_dir}/events.xml")
|
||||
|
||||
#Encrypt files
|
||||
command = "openssl enc -aes-256-cbc -pass file:#{meeting_id}.txt < #{meeting_id}.zip > #{meeting_id}.dat"
|
||||
BigBlueButton.logger.info(command)
|
||||
Open3.popen3(command) do | stdin, stdout, stderr|
|
||||
BigBlueButton.logger.info("commandresult=")#{$?.exitstatus}")
|
||||
end
|
||||
command = "openssl rsautl -encrypt -pubin -inkey key-public.pem < #{meeting_id}.txt > #{meeting_id}.enc"
|
||||
BigBlueButton.logger.info(command)
|
||||
Open3.popen3(command) do | stdin, stdout, stderr|
|
||||
BigBlueButton.logger.info("commandresult=") #{$?.exitstatus}")
|
||||
end
|
||||
length = 16
|
||||
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
|
||||
password = ''
|
||||
length.times { password << chars[rand(chars.size)] }
|
||||
|
||||
#Generate md5 checksum
|
||||
md5sum = Digest::MD5.file("#{meeting_id}.dat")
|
||||
passfile = File.new("#{meeting_id}.txt", "w")
|
||||
passfile.write "#{password}"
|
||||
passfile.close
|
||||
|
||||
BigBlueButton.logger.info("Removing files")
|
||||
PUBLICKEY = "key-public.pem"
|
||||
PASSFILE = "#{meeting_id}.txt"
|
||||
ZIPFILE = "#{meeting_id}.zip"
|
||||
|
||||
[PUBLICKEY, PASSFILE, ZIPFILE].each { |file| FileUtils.rm_f(file)}
|
||||
|
||||
BigBlueButton.logger.info("Creating metadata.xml")
|
||||
# Create metadata.xml
|
||||
b = Builder::XmlMarkup.new(:indent => 2)
|
||||
metaxml = b.recording {
|
||||
b.id(meeting_id)
|
||||
b.state("available")
|
||||
b.published(false)
|
||||
# Date Format for recordings: Thu Mar 04 14:05:56 UTC 2010
|
||||
b.start_time(BigBlueButton::Events.first_event_timestamp("#{process_dir}/#{meeting_id}/events.xml"))
|
||||
b.end_time(BigBlueButton::Events.last_event_timestamp("#{process_dir}/#{meeting_id}/events.xml"))
|
||||
b.download {
|
||||
b.format("encrypted")
|
||||
b.link("http://#{playback_host}/mconf/#{meeting_id}/#{meeting_id}.dat")
|
||||
b.md5(md5sum)
|
||||
b.key("http://#{playback_host}/mconf/#{meeting_id}/#{meeting_id}.enc")
|
||||
}
|
||||
b.meta {
|
||||
BigBlueButton::Events.get_meeting_metadata("#{process_dir}/#{meeting_id}/events.xml").each { |k,v| b.method_missing(k,v) }
|
||||
}
|
||||
}
|
||||
# encrypt files
|
||||
command = "openssl enc -aes-256-cbc -pass file:#{meeting_id}.txt < #{meeting_id}.zip > #{meeting_id}.dat"
|
||||
BigBlueButton.execute(command)
|
||||
|
||||
metadata_xml = File.new("metadata.xml","w")
|
||||
metadata_xml.write(metaxml)
|
||||
metadata_xml.close
|
||||
|
||||
BigBlueButton.logger.info("Removing processed files.")
|
||||
FileUtils.rm_r(Dir.glob("#{process_dir}/*"))
|
||||
|
||||
BigBlueButton.logger.info("Publishing mconf")
|
||||
# Now publish this recording
|
||||
if not FileTest.directory?(publish_dir)
|
||||
FileUtils.mkdir_p publish_dir
|
||||
end
|
||||
FileUtils.cp_r(target_dir, publish_dir)
|
||||
end
|
||||
key_filename = ""
|
||||
if metadata.has_key?('public_key')
|
||||
key_filename = "#{meeting_id}.enc"
|
||||
BigBlueButton.logger.info("Unescaping public key")
|
||||
public_key_decoded = CGI::unescape("#{metadata[:public_key.to_s]}")
|
||||
public_key = File.new("public_key.pem","w")
|
||||
public_key.write "#{public_key_decoded}"
|
||||
public_key.close
|
||||
|
||||
end
|
||||
end
|
||||
command = "openssl rsautl -encrypt -pubin -inkey public-key.pem < #{meeting_id}.txt > #{meeting_id}.enc"
|
||||
BigBlueButton.execute(command)
|
||||
FileUtils.rm_f "#{meeting_id}.txt"
|
||||
else
|
||||
key_filename = "#{meeting_id}.txt"
|
||||
BigBlueButton.logger.warn "No public key was found in the meeting's metadata"
|
||||
end
|
||||
|
||||
# generate md5 checksum
|
||||
md5sum = Digest::MD5.file("#{meeting_id}.dat")
|
||||
|
||||
BigBlueButton.logger.info("Creating metadata.xml")
|
||||
|
||||
# TODO: create a flag to indicate if the file .enc is encrypted or not
|
||||
# due to the presence the public key in the meeting's metadata
|
||||
|
||||
# Create metadata.xml
|
||||
b = Builder::XmlMarkup.new(:indent => 2)
|
||||
metaxml = b.recording {
|
||||
b.id(meeting_id)
|
||||
b.state("available")
|
||||
b.published(true)
|
||||
# Date Format for recordings: Thu Mar 04 14:05:56 UTC 2010
|
||||
b.start_time(BigBlueButton::Events.first_event_timestamp("#{meeting_process_dir}/events.xml"))
|
||||
b.end_time(BigBlueButton::Events.last_event_timestamp("#{meeting_process_dir}/events.xml"))
|
||||
b.download {
|
||||
b.format("encrypted")
|
||||
b.link("http://#{playback_host}/mconf/#{meeting_id}/#{meeting_id}.dat")
|
||||
b.md5(md5sum)
|
||||
b.key("http://#{playback_host}/mconf/#{meeting_id}/#{key_filename}")
|
||||
}
|
||||
b.meta {
|
||||
BigBlueButton::Events.get_meeting_metadata("#{meeting_process_dir}/events.xml").each { |k,v| b.method_missing(k,v) }
|
||||
}
|
||||
}
|
||||
|
||||
metadata_xml = File.new("metadata.xml","w")
|
||||
metadata_xml.write(metaxml)
|
||||
metadata_xml.close
|
||||
|
||||
BigBlueButton.logger.info("Publishing mconf")
|
||||
|
||||
# Now publish this recording
|
||||
if not FileTest.directory?("#{published_dir}/mconf")
|
||||
FileUtils.mkdir_p "#{published_dir}/mconf"
|
||||
end
|
||||
BigBlueButton.logger.info("Publishing files")
|
||||
FileUtils.cp_r(meeting_publish_dir, "#{published_dir}/mconf")
|
||||
|
||||
BigBlueButton.logger.info("Removing processed files: #{meeting_process_dir}")
|
||||
FileUtils.remove_entry_secure meeting_process_dir, :force => true, :verbose => true
|
||||
|
||||
BigBlueButton.logger.info("Removing published files: #{meeting_publish_dir}")
|
||||
FileUtils.remove_entry_secure meeting_publish_dir, :force => true, :verbose => true
|
||||
|
||||
BigBlueButton.logger.info("Removing the recording raw files: #{meeting_raw_dir}")
|
||||
FileUtils.remove_entry_secure meeting_raw_dir, :force => true, :verbose => true
|
||||
BigBlueButton.logger.info("Removing the recording presentation: #{meeting_raw_presentation_dir}")
|
||||
FileUtils.remove_entry_secure meeting_raw_presentation_dir, :force => true, :verbose => true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user