-
-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy patho-saft.tcl
executable file
·4956 lines (4698 loc) · 214 KB
/
o-saft.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/sh
#| restarts using wish \
exec wish "$0" ${1+"$@"}
#!#############################################################################
#!# Copyright (c) 2025, Achim Hoffmann
#!#----------------------------------------------------------------------------
#!# If this tool is valuable for you and we meet some day, you can spend me an
#!# O-Saft. I'll accept good wine or beer too :-). Meanwhile -- 'til we meet --
#!# your're encouraged to make a donation to any needy child you see. Thanks!
#!#----------------------------------------------------------------------------
#!# This software is provided "as is", without warranty of any kind, express or
#!# implied, including but not limited to the warranties of merchantability,
#!# fitness for a particular purpose. In no event shall the copyright holders
#!# or authors be liable for any claim, damages or other liability.
#!# This software is distributed in the hope that it will be useful.
#!#
#!# This software is licensed under GPLv2.
#!#
#!# GPL - The GNU General Public License, version 2
#!# as specified in: http://www.gnu.org/licenses/gpl-2.0
#!# or a copy of it https://github.com/OWASP/O-Saft/blob/master/LICENSE.md
#!# Permits anyone the right to use and modify the software without limitations
#!# as long as proper credits are given and the original and modified source
#!# code are included. Requires that the final product, software derivate from
#!# the original source or any software utilizing a GPL component, such as
#!# this, is also licensed under the same GPL license.
#!#############################################################################
#? NAME
#? $0 - simple GUI for o-saft.pl
#?
#? SYNOPSIS
#? $0 [OPTIONS] [host:port] [host:port] ...
#? $0 [OPTIONS] --load=result-from-o-saft.pl-file
#? $0 [OPTIONS] [+commands] [host:port] [host:port] ...
#?
#? DESCRIPTION
#? This is a simple GUI for O-Saft - OWASP SSL advanced forensic tool.
#? The GUI supports all commands (Cmd menu or Commands TAB) and options
#? (Opt menu or Options TAB) available in o-saft.pl. For each command
#? o-saft.pl will be executed as specified. Results are printed in a new
#? TAB of the GUI. A filter to markup some important texts is applied to
#? the results in the GUI. This filter can be modified and extended (see
#? Config menu or Filter TAB).
#? All results and settings (commands and options) can be saved to files.
#?
#? It can be used to read saved results from other calls of o-saft.pl.
#?
#? Any argument starting with + are considered a command for o-saft.pl
#? and o-saft.pl will be started with all other options, commands and
#? targets and show the results in the GUI.
#?
#? Result TAB
#? The results of o-saft.pl are shown in a new TAB. The format (layout)
#? of the result can be simple "text" or "table". This can be configured
#? in the Config menu or Options TAB.
#?
#? The difference between the formats are:
#? "table"
#? The table consist of 4 columns: Nr, Label, Value and Comment. It can
#? be sorted according each. All Filters are applied to matching lines.
#? The Filter will hide the lines completely.
#? Saving the results will only save the visible lines. These lines are
#? saved in the order of the last sorting.
#? Some informational lines and all header lines (see --header option)
#? from o-saft.pl are not shown and will not be saved.
#? "text"
#? In this format, the results are shown in the same format as returned
#? by o-saft.pl. Lines cannot be sorted. The Filter is applied to each
#? matching line. The Filter will just remove the text, but not hide
#? the lines.
#? Saving the result will save the complete text.
#?
#? Help
#? All functionality is documented with balloon help on each checkbutton,
#? input field, button or table header line.
#?
#? Examples for Filter
#? Match complete line containing Certificate:
#? r=1 e=0 #=0 RegEx=Certificate
#? Match word Target:
#? r=0 e=1 #=6 RegEx=Target
#? Match label text and emphase:
#? r=1 e=0 #=1 RegEx=^[A-Za-z][^:]*\s* Font=osaftHead
#?
#? Configuration
#? Some parts of the GUI, for example widget fonts or widget label texts,
#? can be customised in .o-saft.tcl , which will be searched for in the
#? user's HOME directory and in the local directory.
#? A sample .o-saft.tcl can be generated with --rc option. Please see
#? there for details.
#?
#? Buttons
#? By default, an image will be used for most buttons. Images look more
#? modern than the standard Tcl/Tk buttons. Tcl/Tk does not support round
#? edges, images as background, or different look for activated buttons.
#? The images are read from a separate file: o-saft-img.tcl . If the file
#? is missing, no images will be used, but the simple text.
#? For each button an image can be specified in o-saft-img.tcl , example:
#? set IMG(my-file) [image create photo -file path/to/your-file ]
#? set cfg_images(+info) {my-file}; # where +info is your command
#?
#? Help / Search
#? The [?] button or "? Help" menu entry opens a new window containing
#? the complete documentation of O-Saft, the result of: o-saft.pl +help .
#? The documentation contains clickable links (in blue) to other sections
#? in the text. Patterns may be specified to be searched for in the text.
#? All texts matching the pattern are highligted.
#? Search can be done forward and backward to the current positions, see
#? the [<] and [>] buttons at bottom of the window. Going to the next
#? or previous search result will then highlight the complete paragraph
#? containing the matched text.
#?
#? When more than 5 matches are found, an additional window will display
#? all matches as an overview. Click on a highligted match in this window
#? will show the paragraph containing the match in the help window.
#? When multiple "overview" windows are open, each handles its matches.
#?
#? The search pattern can be used in following modes:
#? exact - use pattern as literal text
#? regex - use pattern as regular expression (proper syntax required)
#? smart - convert pattern to RegEx: each character may be optional
#? fuzzy - convert pattern to RegEx: each position may be optional
#? Example:
#? exact: (adh|dha) - search for literal text (adh|dha)
#? regex: (adh|dha) - search for word adh or word dha
#? regex: her.*list - search for text her followed by list
#? regex: (and - fails, because of syntax error
#? smart: and - search for and or a?nd or an?d or and?
#? fuzzy: and - search for and or .?nd or a.?d or an.?
#?
#? Note: RegEx are applied to lines only, pattern cannot span more than a
#? single line.
#? The pattern must have at least 4 characters, except for mode "exact".
#?
#? The GUI contains various [?] buttons. Clicking such a button will show
#? the corresponding section in the help window (context sensitive).
#?
#? Key bindings
#? Following key bindings are defined:
#? <ButtonPress> start browser with selected link
#? <Control-ButtonPress-1> copy text to clipboard
#? <Shift-Control-ButtonPress-1> copy text to clipboard
#? <Control-v> copy text from clipboard
#? <Control-c> copy selected text to clipboard
#? q (quit) terminate Window or program (not in main window)
# ?
# ? Key bindings currently (2023) not used because they can't be disabled
# ? in entry or text widgets then:
# ? ! show window with About text
# ? ? show window with Help text
# ? c show window ciphers
# ? d show window tool settings (with --debug only)
# ? h show window with Help text
# ? q (quit) terminate Window or program
#?
#? OPTIONS
#? Options for information and help:
#? --h print this text
# ? --h prints also the section HACKER's INFO
#? --help=opts print options (for compatibility with o-saft.pl)
#? --version print version number
#? +VERSION print version number (for compatibility with o-saft.pl)
#?
#? Options for configuration and startup behaviour:
#? --rc print template for .o-saft.tcl
#? --rc=FILE read configuration from FILE instead of .o-saft.tcl
#? --no-rc do not read .o-saft.tcl and o-saft-img.tcl
#? --no-docs use configuration texts returned from o-saft.pl instead of
#? reading prepared static files
#? --gen-docs generate static files for configuration texts
#? --pod use podviewer to show help text
#? --tkpod use tkpod to show help text
#? --stdin read data from STDIN and show in result TAB
#? --load=FILE read data from FILE and show in result TAB
#?
#? Options for use with docker:
#? --docker use o-saft-docker instead of o-saft.pl
#? --docker-id=ID
#? use Docker image ID (registry:tag); default: owasp/o-saft
#? --docker-tag=ID use Docker image ID with tag; default: (empty)
#?
#? Options for GUI behaviour:
#? --gui dummy for compatibility with other tools
#? --gui-tip use own tooltip
#? --gui-button=text use simple texts as labels for buttons
#? --gui-button=image use images for buttons (see o-saft-img.tcl)
#? (not recommended on Mac OS X, because Aqua has nice buttons)
#? --gui-layout=classic tool layout for view on desktop
#? --gui-layout=tablet tool layout for tablet, smartphone; default
#? --gui-result=text print result of o-saft.pl as simple plain text
#? --gui-result=table print result of o-saft.pl formated in a table
#?
#? Options for debugging:
#? --v print verbose messages (startup and calling external tools)
#? --d print more verbose messages (for debugging)
#? --d=D print debug messages according level
#? D=1 - print verbose messages (main)
#? D=2 - print proc calls (those not triggerd by events)
#? D=4 - print debugging in proc
#? D=8 - print verbose debugging for "help" window
#? values can be combined, like --d=6 to print procs and data,
#? all --d=* imply --v
#? --trace use Tcl's trace to trace proc calls
#? --trace-CLI print command-line (for compatibility with other tools)
#?
#? Options for testing:
#? +quit exit without GUI (for compatibility with o-saft.pl)
#? --test=FILE read FILE and print on STDOUT; used for testing only
#? --test-docs just print used external o-saft.pl.--help=* files
#? --test-tcl just print debug information; similar to: --d +quit
#? --test-osaft just print text used for help window (help button)
#?
#? Option aliases for compatibility with other programs or legacy:
#? # Alias Option
#? #----------+--------------------
#? --image --gui-button=image
#? --text --gui-button=text
#? --tip --gui-tip
#? --id=ID --docker-id=ID
#? --tag=TAG --docker-tag=TAG
#?
#? Options passed through to o-saft.pl:
#? +* any option starting with +
#? --* any other option starting with --
# TODO: --post=PRG --post= parameter passed to o-saft
#?
#? DOCKER
#? This script can be used from within any Docker image. The host is then
#? responsible for providing the proper protocols for the GUI (i.e. X11).
#? In this case, anything is executed inside the Docker image, just the
#? graphical output is passed to the host. This mode is started with:
#? o-saft-docker --gui
#? which does the necessary magic with Docker for protocol and DISPLAY.
#?
#? When used with the --docker option, this script runs on the host and
#? connects to an O-Saft Docker image to execute o-saft.pl there with
#? all the selected commands and options.
#? In this mode, o-saft-docker will be used instead of o-saft.pl, which
#? must be available on the host.
#? Note that o-saft-docker relies on O-Saft's Docker image osawp/o-saft
#? which has its own (Docker) entrypoint. This means that o-saft-docker
#? is responsible to provide the same functionality as o-saft.pl does.
#? Adaptions, if necessary, should be done in o-saft-docker.
#?
#? Summary
#? o-saft.tcl --docker - run on host using o-saft.pl in Docker
#? o-saft-docker --gui - run in Docker with display to host
#?
#? KNOWN PROBLEMS
#? Using option -v causes a Tcl error, like:
#? application-specific initialization failed: "-v" option requires an\
#? additional argument
#? This is a Tcl problem and cannot be fixed herein.
#?
#? The markup defined in the filters (see Filter TAB) may not yet produce
#? perfect layouts for the results and the help texts, to be improved in
#? many ways.
#? Note that the markup is independent of the results and does not change
#? them, just "highlight" texts of the results.
#?
#? All --cfg-* settings from .o-saft.pl are not handled properly in the
#? GUI herein, in particular when texts are changed with this option.
#?
#? Some --legacy=* options are not handled properly. In particular the
#? result looks corrupted in table view when the option --legacy=compact
#? or --legacy=full is used; , use the text view for that.
#?
#? The busy cursor does not work on Win32 and Win64 systems.
#?
#? Selected coloured text will not be highlighted. Anyway it is selected.
#?
#? Some Tk widgets seem to have limits. This may result in errors like:
#? X Error of failed request: BadAlloc (insufficient resources for operation)
#? There exist configurations as workaround to avoid such errors, see:
#? cfg(max53)
#?
#? To pipe data in on STDIN, the option --stdin must be used, otherwise
#? it will not be read.
#?
#? STDIN and _LOAD as filenames can not be used to load data.
#?
#? Not really a problem, but worth to mention:
#? It's not possible to map cipher suites to the proper SSL/TLS protocol
#? in the results TAB in table view. Therefore the cipher suite names are
#? prepended by the protocol.
#? Due technical reasons, the protocol and the cipher suite name will be
#? separated by the non-breaking space character U+2007.
#? Take care when processing saved results, [Save] and [STDOUT] button.
#?
#? ARGUMENTS
#? All arguments, except the options described above, are treated as a
#? hostname to be checked.
#?
#? ADDITIONAL SYNOPSIS
#? On some systems (i.e. Android) it could be difficult to pass arguments
#? and/or options to this script. To simulate passing options, following
#? alias names are provided:
#? o-saft--test-docs.tcl
#? o-saft--test-tcl.tcl
#? o-saft--test-osaft.tcl
#? o-saft--trace.tcl
#? o-saft--d.tcl
#? osaft--test-docs.tcl
#? osaft--test-tcl.tcl
#? osaft--test-osaft.tcl
#? osaft--trace.tcl
#? osaft--d.tcl
#?
#? SEE ALSO
#? o-saft
#? o-saft.pl
#? o-saft-docker
#?
#. LAYOUT
#. Following layouts (selected with --gui-layout= option) are available:
#.
#. --gui-layout=tablet
#. +---------------------------------------------------------------+
#. (M) | ☰ Cmd Opt Config |
#. |---------------------------------------------------------------|
#. (H) | Host:Port [________________________________________] [+] [-] |
#. | |
#. | +----------++----------+ |
#. (R) | | (n) +cmd || (m) +cmd | |
#. | + +------------------------------------------------+ |
#. | | | |
#. | | | |
#. | +-----------------------------------------------------------+ |
#. |---------------------------------------------------------------|
#. |---------------------------------------------------------------|
#. (S) | | | |
#. +---------------------------------------------------------------+
#.
#. --gui-layout=classic
#. +---------------------------------------------------------------+
#. (H) | Host:Port [________________________________________] [+] [-] |
#. | [!] [?] |
#. (C) | [Start] [+info] [+check] [+cipher] [+quick] [+vulns] [Load] |
#. (O) | [ ] --header [ ] --enabled [ ] --no-dns [ ] -no-http ... |
#. |---------------------------------------------------------------|
#. | +----------++---------++--------++----------++----------+ |
#. (T) | | Commands || Options || Filter || (n) +cmd || (m) +cmd | |
#. | + +------------------------------------------------+ |
#. | | | |
#. | | | |
#. | +-----------------------------------------------------------+ |
#. |---------------------------------------------------------------|
#. (S) | | | |
#. +---------------------------------------------------------------+
#.
#. Description
#. (H) - Frame containing hostnames to be checked
#. (M) - Frame containing menus for all commands, commands, options
#. ☰ - menubutton for all commands and options
#. Cmd - menubutton for quick commands (most often used)
#. Opt - menubutton for quick options (most often used)
#. Cfg - menubutton for configuration settings
#. (C) - Buttons for most commonly used commands
#. (O) - CheckButtons for most commonly used options
#. (R) - Frame containing panes for results
#. (T) - Frame containing panes for commands, options, filter, results
#. (S) - Frame containing Status messages
#. [+] - Add line with Host:Port
#. [-] - Remove line with Host:Port
#. [!] - Help about $0
#. [?] - Help about o-saft.pl
#.
#. Filter TAB Description
#. +---------------------------------------------------------------+
#. (f) | Key r e # RegEx Foreground Background Font u |
#. | +---------+--+--+--+------+----------+----------+--------+--- |
#. (F) | |== CMT * o 0 ^==* gray osaftHead x |
#. | +---------+--+--+--+------+----------+----------+--------+--- |
#. | ... |
#. +---------------------------------------------------------------+
#.
#. (f) - Headline for filter description
#. key - unique key for this filter
#. r - RegEx used as regular expression
#. e - RegEx used as exact match
#. # - Nr. of characters to be matched by RegEx
#. Foreground - colour for matched text
#. Background - colour for background of matched text
#. Font - use this font for matched text
#. u - matched text will be underlined
#. (F) - Filter settings
#. example of a filter
#.
#. For the main workflow use the --trace option, for example:
#. $0 --trace +quit
#. $0 --trace --gui-layout=classic
#.
#. LIMITATIONS
#. All help texts reference to the default hardcoded texts, even if they
#. are changed in .o-saft.tcl .
#.
#. HACKER's INFO
#. TODO (8/2016):
#. - need to check if ugly hacks for Aqua (Mac OS X 10.6 with Tk 8.5.7)
#. are still necessary on modern Macs, in particular:
#. * tk_getSaveFile -confirmoverwrite
#. * package require Img
#.
#. This is no academically perfect code, but quick&dirty scripted:
#. - makes use of global variables instead of passing parameters etc..
#. - mixes layout and functions and application logic
#. - some widget names are hardcoded
#.
#. Data used to build GUI
#. Generation of all objects (widgets in Tk slang) is done based on data
#. provided by o-saft.pl itself, in praticular some --help=* options,
#. see CONFIGURATION o-saft.pl below. Output of all --help=* must be
#. one item per line, like:
#. This is a label, grouping next lines
#. +command1 Command nr 1
#. +command2 Command nr 2
#. Options for commands
#. --opt1 this options does something
#. This tools relies on the format of these lines. If the format changes,
#. commands and options may be missing in the generated GUI.
#. Following options of o-saft.pl are used:
#. --help --help=opt --help=commands
#. A detailed example of the format can be found in proc create_win().
#. The functions create_win() and create_buttons() mainly use the RegEx
#. prg(rec*) defined in the CONFIGURATION (see below) to match output
#. from o-saft.pl . The code in these functions may be used to parse data
#. from other tools too.
#.
#. When building the complete documention (help window), additional text
#. documentation (beside that provided by +help) will be added before the
#. ATTRIBUTION section. Hence ATTRIBUTION must exist as section header
#. in output of "o-saft.pl +help".
#.
#. The tool will only work if o-saft.pl is available and executes without
#. errors. All commands and options of o-saft.pl will be available from
#. herein, except:
#. - all "--help*" options (as they make no sense here)
#. - "+cgi" and "+exec" command (they are for internal use only)
#.
#. Some Naming Conventions
#. - procedures:
#. create_* - create widget or window
#. osaft_* - run external o-saft.pl (and process output)
#. search_* - searching texts in help (widget in help window)
#. - variables (GUI):
#. HELP- - prefix used for all Tcl-text tags in help
#. f_* - prefix used for all filter list variables
#. txt - a text widget
#. w or obj - any widget
#. parent - parent widget (may be toplevel)
#. exe() - global variable containing commands and options for
#. o-saft.pl from command-line
#. cfg() - global variable containing most configurations
#. cfg_colors()- global variable containing colours for widgets
#. cfg_texts() - global variable containing texts for widgets
#. cfg_tipps() - global variable containing texts for tooltips
#. search() - global variable containing texts used for searching
#. myX() - global variable for windows and window manager
#. - variables (O-Saft execution):
#. hosts() - global variable with list of hosts to be checked
#. results() - global variable containing results of executions
#. - comments
#. lines starting with #.
#. - these lines are intended for internal documentation
#. lines starting with #?
#. - these lines are intended for public documentation
#. lines starting with #? (inside proc definition)
#. - lines are used for internal developer documentation
#. lines starting with #|
#. - lines are used for internal developer documentation
#. lines with ;#
#. - Tcl requires a ; after the statement before any
#. comment; the ; is usually right before the #
#.
#. Coding (general)
#. Sequence of function definitions done to avoid forward declarations.
#. See Debugging Options below also.
#.
#. Coding (GUI)
#. Images (i.e. for buttons) are defined in o-saft-img.tcl, which must be
#. installed in same path as o-saft.tcl itself. The definitions are in
#. a separate file to keep the code more clean herein. If the file is not
#. found, a warning will be printed and Tcl/Tk buttons will be used.
#.
#. All buttons for the GUI are defined in a tabular array, where the key
#. is used as part of the object name. For details please see comments at
#. # define all buttons used in GUI
#. Note that the button texts defined there are displayed when using our
#. own "Copy Text" (see above) with <Control-ButtonPress-1>, even if the
#. button is displayed as image.
#.
#. Starting 11/2021 the default tool layout was changed from "classic" to
#. "tablet". This only affects building the GUI itself. The difference in
#. building the GUI is mainly controlled by the variable cfg(gui-layout).
#. This effects the procs: create_host() create_buttons() and gui_main().
#.
#. STDIN
#. Tcl's file handle (channel) for STDIN is named stdin, which is open by
#. default. Data piped to $0 can be read from this file handle.
#. But it is difficult to detect if data is available from stdin, if not,
#. Tcl's get() function simply hangs. To avoid this, the option --stdin
#. must be used if data should be read from STDIN, example:
#. cat some-file | $0 --stdin
#. o-saft.pl +check localhost | $0 --stdin
#. Reading from STDIN can simply be tested like
#. echo "label: no any comment" | $0 --stdin
#.
#. Note that STDIN is used as filename to indicate that Tcl's stdin file
#. handle should be used (which needs to be treated special).
#.
#. Tracing (GUI)
#. Tcl's trace functionality is used to trace most procs defined herein
#. and all created buttons. See trace_commands() and trace_buttons() for
#. details. Tracing does not yet work for buttons created in sub-windows.
#. Tracing is invoked with the --trace option.
#.
#. Copy Texts
#. All texts visible in the GUI, wether a label, a button, an entry or a
#. text itself, can be copied to the system's clipboard. This can be done
#. using the system's standard copy&paste methods, or with:
#. <Control-ButtonPress-1>
#. For debugging <Shift-Control-ButtonPress-1> will prefix the text by
#. the pathname and the class of the object containing the text.
#. Keep in mind that it also copies the huge text in the help window.
#. With <Control-ButtonPress-1> or <Shift-Control-ButtonPress-1> the
#. text will be copied to the (ICCCM) buffer CLIPBOARD. This ensures that
#. it will not interfere with the usual copy&paste buffer PRIMARY.
#. <ButtonPress-1> is the "select button", usually the left mouse button.
#. On X.org systems, the CLIPBOARD can be pasted using the context menu
#. (which is most likely the <left click>).
#. This behaviour is disabled with the --test-tcl option.
#.
#. Tracing (program flow)
#. --d=X - see description above
#.
#. Tracing and Debugging
#. All output for --trace and/or --dbx is printed on STDERR.
#. Trace messages are prefixed with: #[$0]:
#. Debug messages are prefixed with: #dbx# [$0]:
#.
#. --test=FILE
#. --test=FILE --gui-result=text
#. --test=FILE --gui-result=table
#. loads FILE into the GUI's tablelist widget and then calls the save
#. function, which prints the content of tablelist on STDOUT.
#. This is used in Makefile* for testing functionality, does not make
#. any sense otherwise.
#. The --gui-result=* option enforces to display and store the file
#. content in Tk's tablelist or text widget. The displayed output may
#. be slightly different, as the tablelist doesn't always contain all
#. data of the file.
#.
#. Tracing and Debugging with Alias Names
#. If arguments (options) can not be passed to the script (for example on
#. Android), alias names of the script can be used to simulate using the
#. options:
#. # alias name # behaves as called like
#. #-----------------------#-------------------------------
#. o-saft--test-docs.tcl $0 --test-docs
#. o-saft--test-tcl.tcl $0 --test-tcl
#. o-saft--test-osaft.tcl $0 --test-osaft
#. o-saft--d.tcl $0 --d
#. o-saft--trace.tcl $0 --trace
#.
#. Notes About Tcl/Tk
#. We try to avoid platform-specific code. The only exceptions since 2015
#. are the perl executable and the start method of the external browser.
#. Another exception (8/2016) is "package require Img" which is necessary
#. on some Mac OS X.
#. All external programs are started using Tcl's {*} syntax.
#.
#. If there is any text visible, we want to copy&paste it. Therefore most
#. texts are placed in Tk's text widget instead of a label widget, 'cause
#. text widgets allow selecting their content by default, while labels do
#. not. These text widgets are set to state "read-only" instaed of Tcl's
#. disabled state, see gui_set_readonly() for details.
#.
#? VERSION
#? @(#) 3.32 Spring Edition 2025
#?
#? AUTHOR
#? 04. April 2015 Achim Hoffmann
#?
#? Project Home: https://owasp.org/www-project-o-saft/
#? Help Online: https://www.owasp.org/index.php/O-Saft/Documentation
#? https://wiki.owasp.org/index.php/O-Saft/Documentation
#? Repository: https://github.com/OWASP/O-Saft
#?
# -----------------------------------------------------------------------------
set cfg(testtcl) 0
set cfg(needtk) 1 ;# load Tk if needed only; dirty hack for --h
#package require Tcl 8.5 ;# for documentation only
#package require Tk 8.5 ;# modern Tcl/Tk doesn't need it anymore
if { [regexp -- {--h(elp)?} $argv]} {
set cfg(needtk) 0
}
if {![regexp -- {--test-?tcl} $argv]} {
# keep some systems quiet
if {0<$cfg(needtk)} {
package require Tk
}
set cfg(testtcl) 1
}
#_____________________________________________________________________________
#___________________________________________________________ early bindings __|
# Bindings for simply copying text of any widget.
# To avoid conflicts with other common bindings, we use Ctrl + click to copy
# the text. Unfortunately this does not allow to select texts individually,
# but only as a whole.
# Bindings need to be done very early, so that they are active when Tcl/Tk's
# wish uses dialogs (i.e. tk_messagebox). The called function copy2clipboard
# might be defined later in the code, but it must be done before any usage.
# Hence it's defined right below.
if {0<$cfg(testtcl) && 0<$cfg(needtk)} {
# do not bind in debug-only mode to avoid errors, see "Key Bindings"
foreach klasse [list Button Combobox Entry Label Text Message Spinbox \
TButton TCombobox TEntry TLabel TText Frame Menu \
LabelFrame PanedWindow Scale Scrollbar \
Checkbutton Menubutton Radiobutton Dialog] {
bind $klasse <Control-ButtonPress-1> { copy2clipboard %W 0 }
bind $klasse <Shift-Control-ButtonPress-1> { copy2clipboard %W 1 }
}
}
proc copy2clipboard {w shift} {
#? copy visible text of object to clipboard
global cfg
set klasse [winfo class $w]
set txt {}
if {1==$shift} { set txt "$w $klasse: " }
# TODO: Menu, Spinbox not complete; some classes are missing
switch $klasse {
Frame { append dum "nothing to see in frames" }
Button -
Combobox -
Dialog -
Label -
Spinbox -
TButton -
TCombobox -
TLabel -
Menubutton -
Checkbutton -
Radiobutton { append txt [lindex [$w config -text] 4] }
Entry -
TEntry { append txt [string trim [$w get]] }
Text -
TText { append txt [string trim [$w get 1.0 end]] }
default { puts "** unknown class $klasse" }
}
if {1==$shift} {
set cmd ""
catch {lindex [$w config -command] 4} cmd ;# show error or command
append txt "\n -command $cmd"
}
pinfo "copy2clipboard($w, $shift): {\n $txt\n#}"
clipboard clear
clipboard append -type STRING -format STRING -- $txt
}; # copy2clipboard
#_____________________________________________________________________________
#____________________________________________________________ configuration __|
# this section mainly contains variable initialisations, it also defines some
# functions for easy access to configurations
# following arrays contain the index DESC multiple times, which means that it
# will be overwritten; doesn't harm, because it's used for documentation only
# in the code herein
proc docker_config {mode} {
#? initilise configuration for use with Docker image
# may be called with $mode=opt for --docker option or with $mode=prg to
# check if program name matches *-docker
# must be early definition, because called right after program start
global cfg prg env argv0
switch $mode {
prg { if {[regexp {\-docker$} $argv0]} { set mode 1 } }
opt { set mode 1 }
}
if {1==$mode} {
set cfg(docker) 1
set prg(SAFT) "o-saft-docker"
}
# independent of mode, can always be set
if {1==[info exists env(o_saft_docker_tag)] } { set prg(docker-tag) $env(o_saft_docker_tag) }
if {1==[info exists env(o_saft_docker_name)]} { set prg(docker-id) $env(o_saft_docker_name) }
return
}; # docker_config
proc docker_args {} {
#? if in "docker mode" pass image ID to Docker;
# note that docker specific options must be before o-saft.pl commands or options
global prg
set do {}
if {[regexp {\-docker$} $prg(SAFT)]} {
lappend do "-id=$prg(docker-id)"
#lappend do "-tag=$prg(docker-tag)"
# FIXME: need to distinguish if --id= or --tag= was specified
}
return $do
}; # docker_args
if {![info exists argv0]} { set argv0 "o-saft.tcl" } ;# if it is a tclet
# NOTE that cfg() also contains all +commands and -options passed to o-saft.pl
# they are extracted in osaft_exec(); so the array indexes must not start with
# + or -
set cfg(SID) "@(#) o-saft.tcl 3.32 25/01/10 16:36:52"
set cfg(mySID) "$cfg(SID) Spring Edition 2025"
# contribution to SCCS's "what" to avoid additional characters
set cfg(VERSION) {3.32}
set cfg(TITLE) {O-Saft}
set cfg(RC) {.o-saft.tcl}
set cfg(RCmin) 1.13 ;# expected minimal version of cfg(RC)
set cfg(ICH) [file tail $argv0]
set cfg(DIR) [file dirname $argv0] ;# directory of cfg(ICH)
set cfg(ME) [info script] ;# set very early, may be missing later
# O-Saft means built-in
set cfg(O-Saft) {o-saft.pl} ;# common name of O-Saft executable
# own directories, may be redifined in RC-file, constant also used for filenames
set cfg(lib-dir) $cfg(DIR)/lib ;# own modules and documentation
set cfg(usr-dir) $cfg(DIR)/usr ;# user defined files
set cfg(doc-dir) $cfg(DIR)/doc ;# generated documentation
set cfg(docs-dir) $cfg(doc-dir) ;# alias
set cfg(IMG) lib/o-saft-img.tcl ;# where to find image data
# path completed at runtime
set cfg(POD) {o-saft.pod} ;# complete help text in POD format
set cfg(HELP) "" ;# O-Saft's complete help text; see osaft_help()
set cfg(files) {} ;# files to be loaded at startup --load
set cfg(.CFG) {} ;# contains data from prg(INIT)
;# set below and processed in osaft_init
set cfg(quit) 0 ;# quit without GUI
set cfg(stdout) 0 ;# 1: call osaft_save TTY
set cfg(docker) 0 ;# 1: for --docker option or o-saft-docker
#et cfg(HELP-key) "" ;# contains linenumber of result table
#-----------------------------------------------------------------------------{
# Definitions outside RC-ANF - RC-END scope, because they're not intended to
# be changed in .o-saft.tcl .
#et exe() ... # will contain commands and options from command-line
# define some RegEx to match output from o-saft.pl or data in .o-saft.pl
# mainly used in create_win() and create_buttons()
set prg(DESC) {-- CONFIGURATION regex to match output from o-saft.pl -------}
set prg(rexCMD-int) {^\+(cgi|exec)} ;# internal use only
set prg(rexOPT-cfg) {^([^=]*)=(.*)} ;# match --cfg-CONF=KEY=VAL
set prg(rexOPT-help) {^--(h$|help)} ;# match --h or --help
set prg(rexOUT-head) {^(==|\*\*)} ;# match header lines starting with ==
set prg(rexOUT-int) {^--(cgi|call)} ;# use other tools for that
set prg(rexOUT-cmd) {^(Commands|Options)} ;# match header lines for --help=cmd
set prg(rexOUT-hide) {^Options\s*for\s*(help|compatibility) } ;# match groups not shown here
set prg(rexOUT-show) {^Commands to show } ;# commands without explizit HELP section
set prg(rexOUT-text) {[+](ciphers|info|test|version)}
;# commands which must use _layout=text
#set _me [regsub -all {^[./]*} $prg(SAFT) {}] ;# remove ./ but prg(SAFT) later
# causes problems in regsub on Mac OS X if $prg(SAFT) starts with ./
set prg(rexCOMMANDS) "\(o-saft\(.pl|.tcl|-docker\)?|checkAllCiphers.pl|\(/usr/local/\)?openssl|docker|mkdir|ldd|ln|perlapp|perl2exe|pp\)"
# most common tools used in help text...
set prg(POST) {} ;# --post= parameter, if passed on command-line
set prg(option) 0 ;# set to 1 to avoid internal "option add ..." commands
#-----------------------------------------------------------------------------}
# RC-ANF {
#-----------------------------------------------------------------------------{
# This is the only section where we know about o-saft.pl , all settings for
# o-saft.pl go here.
set prg(DESC) {-- CONFIGURATION o-saft.pl ----------------------------------}
set prg(INIT) {.o-saft.pl} ;# name of O-Saft's startup file
set prg(SAFT) {o-saft.pl} ;# name of O-Saft executable
# Will be set to o-saft-docker when --docker is given
# prg(SAFT) must be found with the system's PATH environment variable,
# otherwise a full path must be used here.
#-----------------------------------------------------------------------------}
set prg(DESC) {-- CONFIGURATION external programs --------------------------}
set prg(PERL) {} ;# full path to perl; empty on *nix
set prg(BROWSER) "" ;# external browser program, set below
# o-saft.tcl tries to find the browser automatically, a list of well known
# browser names is used for that. Another browser can be set here, must be
# a full path or found with PATH environment variable.
set prg(TKPOD) {O-Saft} ;# name of external viewer executable
# o-saft.tcl uses built-in functionality to show its documentation. This
# documentation is available in POD format also: o-saft.pod.
# If this variable is set to the name of an external program, this program
# will be used to show the documentation. It is recommended to use a full
# path to the program.
# Possible values, beside others, are:
# O-Saft - reserved for o-saft.tcl's built-in vierwer
# tkpod - Tcl/Tk-based viewer
# podviewer - GTK-based viewer
# Advantage of external viewers:
# tkpod + much better search capabilities
# Disadvantage of external viewers:
# tkpod - context-sensitive help used by o-saft.tcl not possible
# podviewer - context-sensitive help used by o-saft.tcl not possible
# * - all viewers must be started in background and will not
# be closed with o-saft.tcl itself
set prg(docker-id) {owasp/o-saft} ;# Docker image ID, if needed
set prg(docker-tag) {latest} ;# Docker image tag, if needed
set prg(DESC) {-- CONFIGURATION default buttons and checkboxes -------------}
set prg(Ocmd) {{+check} {+cipher} {+info} {+quick} {+vulns} {+protocols} }
# List of quick access commands, for which a button will be created in the
# GUI. This must be commands of o-saft.pl, which start with + character.
# +quit and +version will be added for --v or --d only.
set prg(Oopt) {{--header} {--enabled} {--no-dns} {--no-http} {--no-sni} {--no-sslv2} {--no-sslv3} }
# List of quick access options, a checkbox will be created in the GUI.
# This must be options of o-saft.pl, which start with -- character.
set myX(DESC) {-- CONFIGURATION window manager geometry --------------------}
# set minimal window sizes to be usable in a 1024x768 screen
# windows will be larger if the screen supports it (we rely on "wm maxsize")
set myX(geoo) "660x720" ;# geometry of Help window
set myX(geoO) "$myX(geoo)-0+0" ;# geometry and position of Help window
set myX(geo-) "400x80" ;# geometry and position of no match window
set myX(geoS) "700x720" ;# geometry and position of O-Saft window
set myX(geoA) "660x610" ;# geometry and position of About window
set myX(geoC) "" ;# geometry and position of Config window (computed dynamically)
set myX(geoD) "700x700" ;# geometry and position of Cipher window
set myX(geoF) "700x750" ;# geometry and position of Filter window
set myX(geoT) "" ;# geometry and position of Tool Cfg window (computed dynamically)
set myX(minx) 700 ;# O-Saft window min. width
set myX(miny) 850 ;# O-Saft window min. height
set myX(lenl) 15 ;# fixed width of labels in Options window
set myX(rpad) 15 ;# right padding in the lower right corner
set myX(padx) 5 ;# padding to right border
set myX(maxS) 3 ;# height of status line
set cfg(DESC) {-- CONFIGURATION GUI style and layout -----------------------}
set cfg(gui-button) {image} ;# button style: image or text
# used with --gui-layout=classic only
set cfg(gui-layout) {tablet} ;# tablet: tool layout for tablet, smartphone
# classic: tool layout for view on desktop
set cfg(gui-result) {table} ;# layout o-saft.pl's results: text or table
# see also comment in gui_init()
set cfg(tfont) {flat9x6} ;# font used in tablelist::tablelist
set cfg(max53) 4050 ;# max. size of text to be stored in table columns
# Some combinations of Tcl/Tk and X-Servers are limited in the size of text,
# which can be stored in Tk's table columns. When such a widget is rendered,
# the script crashes with following error message:
# X Error of failed request: BadAlloc (insufficient resources for operation)
# Major opcode of failed request: 53 (X_CreatePixmap)
# Serial number of failed request: 2223
# Current serial number in output stream: 2255
# To avoid the crash, large texts (greater than this value) can be stripped.
# The default value of ~4000 is based on experience.
set cfg(docs-src) {file} ;# file: read configuration of commands and
# options from static files in ./doc/
# dynamic: read configuration using o-saft.pl
set cfg(nbsp) \u2007 ;# character used for non-breaking spaces
set cfg(DESC) {-- CONFIGURATION misc settings ------------------------------}
set cfg(no-match) {_NO_} ;# text pattern used to avoid matching some text
# RC-END }
set cfg(docs-help) {--help=alias --help=checks --help=data --help=glossar --help=regex --help=rfc --help}
# file extensions for files from ./doc/ used in osaft_read_data() and osaft_help()
# missing: --help=text --help=ourstr --help=compliance
# missing because too much data: --help=range
set cfg(docs-help-all) "--help=commands --help=opts $cfg(docs-help) --help=ciphers-text"
# this list should be same as $cfg{'files'},
# see also man_docs_write() in in o-saft.pl
set cfg(docs-files) {} ;# contains the read files from ./doc/
set cfg(guiwidgets) {} ;# contains the widgets of the GUI
set cfg(guimenus) {} ;# contains the widgets of the GUI's menus
# debugging only for --gui-layout=tablet
docker_config prg ;# may initialise some docker-specific settings
catch {
set fid [open $prg(INIT) r] ;# read .o-saft.pl
set cfg(.CFG) [read $fid]
close $fid
}
#| configure GUI
set cfg(gui-tip) [catch { package require tooltip} tip_msg]; # 0 on success, 1 otherwise!
set IMG(help) ::tk::icons::question
#et IMG(...) ;# other images are defined in cfg(IMG)
#et myX(minx) myX(miny) myX(geoS) # see gui_init() below
# myX(buffer) ... NOT YET USED
set myX(buffer) PRIMARY ;# buffer to be used for copy&paste GUI texts
# any ICCCM like: PRIMARY, SECONDARY, CLIPBOARD
# or: CUT_BUFFER0 .. CUT_BUFFER7
# Hint for X, in particular xterm: .Xresources:
# XTerm*VT100.Translations: #override \
# ... \
# <Btn2Up>: insert-selection(PRIMARY,CLIPBOARD) \
# ... \
set my_bg #d9d9d9 ;# default background color (lightgray)
# this colour is used for buttons too
# default background of Tk widget (if available)
catch { set my_bg "[lindex [.i config -bg] 4]" }
# define all buttons used in GUI
# Following table defines the label text, background colour, image and tip
# text for each button. Each key is an object name and defines one button.
#
# This allows to generate the buttons without these attributes (-text, -bg,
# -image, etc.), which simplifies the code. These attributes are set later
# using guitheme_set(), which then also takes care if there should be a
# simple theme (just text and background) or a more sexy one using images.
# Note: the key (object name) in following table must be the last part of
# the object (widget) name of the button, example: .f.about .
# Note: should be used after calling gui_init
#----------+---------------+-------+-------+-------------------------------
# object button text colour image help text (aka tooltip)
# name -text -bg -image guitip_set()
#----------+-----------+-------+-----------+-------------------------------
array set cfg_buttons "
about {{!} $my_bg {!} {About $cfg(ICH) $cfg(VERSION)}}
help {{?} $my_bg help {Open window with complete help}}
help_me {{?} $my_bg {?} {Open window with help for these settings}}
closeme {{Quit} orange quit {Close program}}
closewin {{Close} orange close {Close window}}
closetab {{Close Tab} orange closetab {Close this TAB}}
loadresult {{Load} lightgreen load {Load results from file}}
saveresult {{Save} lightgreen save {Save results to file}}
saveconfig {{Save} lightgreen save {Save configuration to file }}
ttyresult {{STDOUT} lightgreen stdout {Print results on systems STDOUT}}
reset {{Reset} $my_bg reset {Reset configuration to defaults}}
filter {{Filter} $my_bg filter {Show configuration for filtering results}}
tkcolor {{Color Chooser} $my_bg tkcolor {Open window to choose a color}}
tkfont {{Font Chooser} $my_bg tkfont {Open window to choose a font}}
host_add {{+} $my_bg {+} {Add new line for a host}}
host_del {{-} $my_bg {-} {Remove this line for a host }}
help_home {{^} $my_bg help_home {Go to top of page (start next search from there)}}
help_prev {{<} $my_bg help_prev {Search baskward for text}}
help_next {{>} $my_bg help_next {Search forward for text}}
help_help {{?} $my_bg {?} {Show help about search functionality}}
helpreset {{Reset} $my_bg reset {Reset/clear list of search texts}}
helpsearch {{??} $my_bg helpsearch {Text to be searched}}
cmdstart {{Start} yellow cmdstart {Execute $prg(SAFT) with commands selected in 'Commands' tab}}
cmdcheck {{+check} #ffd800 +check {Execute $prg(SAFT) +check }}
cmdcipher {{+cipher} #ffd000 +cipher {Execute $prg(SAFT) +cipher }}
cmdinfo {{+info} #ffc800 +info {Execute $prg(SAFT) +info }}
cmdquit {{+quit} #ffc800 +quit {Execute $prg(SAFT) +quit (debugging only)}}
cmdquick {{+quick} #ffc000 +quick {Execute $prg(SAFT) +quick }}
cmdprotocols {{+protocols} #ffb800 +protocols {Execute $prg(SAFT) +protocols }}
cmdvulns {{+vulns} #ffb000 +vulns {Execute $prg(SAFT) +vulns }}
cmdversion {{+version} #fffa00 +version {Execute $prg(SAFT) +version }}
docker_status {{docker status} #00faff docker_status {Execute $prg(SAFT) status }}
img_txt {{image/text} $my_bg {img_txt} {toggle buttons: text or image}}
DESC_menu {-- for following rows, colour is the forground colour of the objekt --}
menu_menu {{☰} orange {} {Main menu}}
menu_cmd {{Cmd} white {} {Quick commands menu}}
menu_opt {{Opt} white {} {Quick options menu}}
menu_cfg {{Config} white {} {GUI configurations menu}}
menu_cmds {{ + All Commands} {} {} {Commands submenu}}
menu_opts {{ - All Options} {} {} {Options submenu}}
menu_load {{ Load Results} {} {} {Load results from file}}
menu_filt {{ Config Filter} {} {} {Show configuration for filtering results}}
menu_conf {{ Config GUI} {} {} {Show configuration for GUI settings}}
menu_prog {{ Config Tool} {} {} {Show configuration for tool itself}}
menu_mode {{Change Layout} {} {} {Toogle layout between classic and tablet}}
menu_help {{ ? Help} {} help {Open window with complete help}}
menu_list {{ Cipher Suites} {} {&} {Open window with list of cipher suites}}
menu_uber {{❗ About} {} {!} {About $cfg(ICH) $cfg(VERSION)}}
menu_exit {{⏻ Quit} orange quit {Close program}}
menu_rsave {{Save} {} save {Save results to file}}
menu_reset {{Reset} {} reset {Reset configuration to defaults}}
"; #----------+-----------+-------+-----------+-------------------------------
# name -text -bg -image guitip_set()
#----------+-----------+-------+-----------+-------------------------------
# Note: all buttons as described above, can be configured also by the user
# using cfg(RC). Configurable are: text (-text), background colour (-bg)
# and the tooltip. Because configuring the above table is a bit cumbersome
# for most users, we provide simple lists with key=value pairs. These lists
# are: cfg_colors, cfg_texts and cfg_tipps. The settings here are defaults,
# and may be redefined in cfg(RC) using cfg_color, cfg_label and cfg_tipp.
# These lists (arrays in Tcl terms) contain not just the button values, but
# also values for other objects. So the lists are initialised here for all
# other values, and then the values from cfg_buttons are added.
#
# array in cfg(RC) array herein (see also update_cfg() )
# cfg_color cfg_colors
# cfg_label cfg_texts
# cfg_tipp cfg_tipps
# functions to get above texts
proc _get_btn_txt {key} { global cfg_buttons; return [lindex $cfg_buttons($key) 0] }