Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 88

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 215

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 216

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 217

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 218

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 219

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 220
PK!k7 simple.gonu[GOOF----LE-8-2.0]4h/ ] gguile  gdefine-module*   grnrs gio gsimple  gfilenameS frnrs/io/simple.scm gpureS gversionS   gset-current-module   gresolve-r6rs-interface   gonly gports  gcall-with-port g close-port gopen-file-input-port gopen-file-output-port g eof-object g eof-object? g file-options g buffer-mode gnative-transcoder !gget-char "glookahead-char #g get-datum $gput-char %g put-datum &g input-port? 'g output-port? ( !"#$%&' )gcall-with-deferred-observers *) +) ,gmodule-use-interfaces! -, ., /gcurrent-module 0/ 1/ 2g@@ 3gcurrent-input-port 4gcurrent-output-port 5gcurrent-error-port 6gdefine* 7gwith-input-from-port 8gwith-output-to-port 92345678  :gbase ;: gmodule-export! ?> @> Agmodule-re-export! BA CA Dgi/o-error-port Egi/o-port-error? Fgmake-i/o-port-error Gg &i/o-port Hgi/o-file-does-not-exist-error? Ig"make-i/o-file-does-not-exist-error Jg&i/o-file-does-not-exist Kgi/o-file-already-exists-error? Lg"make-i/o-file-already-exists-error Mg&i/o-file-already-exists Ngi/o-file-is-read-only-error? Og make-i/o-file-is-read-only-error Pg&i/o-file-is-read-only Qgi/o-file-protection-error? Rgmake-i/o-file-protection-error Sg&i/o-file-protection Tgi/o-error-filename Ugi/o-filename-error? Vgmake-i/o-filename-error Wg &i/o-filename Xgi/o-error-position Ygi/o-invalid-position-error? Zgmake-i/o-invalid-position-error [g&i/o-invalid-position \gi/o-write-error? ]gmake-i/o-write-error ^g &i/o-write _gi/o-read-error? `gmake-i/o-read-error ag &i/o-read bg i/o-error? cgmake-i/o-error dg&i/o eDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd543'&( fgmodule-replace! gf hf igwrite jgdisplay kgnewline lg write-char mgread ng peek-char og read-char pgclose-output-port qgclose-input-port rgopen-output-file sgopen-input-file tgwith-output-to-file ugwith-input-from-file vgcall-with-output-file wgcall-with-input-file xijklmnopqrstuvw yj zj {genums |{ }genum-set-constructor ~|} |} gmake-enumeration | | g no-create gno-fail g no-truncate  gblockC5h 7]4     54>"G4(54+.1hD]45L6<gfilenamefrnrs/io/simple.scm     CO>"G4954+.1hD]45L6<gfilenamefrnrs/io/simple.scm     CO>"G4;54+.1hD]45L6<gfilenamefrnrs/io/simple.scm     CO>"G4=54+.1hD]45L6<gfilenamefrnrs/io/simple.scm     CO>"G4+@1hD]456<gfilenamefrnrs/io/simple.scm    C>"G4+C1ehD]456<gfilenamefrnrs/io/simple.scm    C>"G4+h1xhD]456<gfilenamefrnrs/io/simple.scm    C>"GzjRh]456gfilename  gproc  gfilenamefrnrs/io/simple.scm w    gnamegcall-with-input-fileCwRh]456gfilename  gproc  gfilenamefrnrs/io/simple.scm z    gnamegcall-with-output-fileCvRw7h,]L6$gport    Ch]O6gfilename  gthunk  gfilenamefrnrs/io/simple.scm }    gnamegwith-input-from-fileCuRv8h,]L6$gport    Ch]O6gfilename  gthunk  gfilenamefrnrs/io/simple.scm    gnamegwith-output-to-fileCtR h y]444555456qgfilename  gfilenamefrnrs/io/simple.scm    gnamegopen-input-fileCsR h z]444555456rgfilename  gfilenamefrnrs/io/simple.scm    gnamegopen-output-fileCrRiqRipR3!h p-.,3#456hgport gfilenamefrnrs/io/simple.scm   gnameg read-charCoR3"h p-.,3#456hgport gfilenamefrnrs/io/simple.scm   gnameg peek-charCnR3#h k-.,3#456cgport gfilenamefrnrs/io/simple.scm   gnamegreadCmR4$h(-.,3#456zgchar !gport !gfilenamefrnrs/io/simple.scm  ! gnameg write-charClR4$h(n-.,3#45 6fgport !gfilenamefrnrs/io/simple.scm  ! gnamegnewlineCkR4%h(-.,3#456wgobject !gport !gfilenamefrnrs/io/simple.scm  ! gnamegwriteCiRC/gm  +giface 2 giface 9giface @ giface  Igfilenamefrnrs/io/simple.scm    u  j w  # z  # }  #          K    U      C6PK!;ports.gonu[GOOF----LE-8-2.0]4h4] gguile  gdefine-module*   grnrs gio gports  gfilenameS frnrs/io/ports.scm gpureS gversionS   gset-current-module   gresolve-r6rs-interface   gice-9 g binary-ports  gcall-with-deferred-observers   gmodule-use-interfaces!   gcurrent-module   !gonly "gbase #" $gassertion-violation %!#$ &genums '& (grecords )g syntactic *() +g exceptions ,+ -g conditions .- /gfiles 0/ 1gsrfi 2gsrfi-8 312 4grdelim 54 6gexcept 7graise 8gdisplay 9678 :gprefix ;!8 gmodule-export! ?> @> Agi/o-encoding-error-char Bgmake-i/o-encoding-error Cgi/o-encoding-error? Dg&i/o-encoding-error Egmake-i/o-decoding-error Fgi/o-decoding-error? Gg&i/o-decoding-error Hgstandard-error-port Igstandard-output-port Jgstandard-input-port Kg put-string Lg put-datum Mgput-char Nglookahead-char Og get-string-n Pgget-string-all Qgget-line Rg get-datum Sgget-char Tgopen-file-input/output-port Ugflush-output-port Vgmake-custom-textual-output-port Wgcall-with-string-output-port Xg call-with-bytevector-output-port Ygopen-file-output-port Zgopen-string-output-port [gopen-file-input-port \gopen-string-input-port ]gcall-with-port ^gport-has-set-port-position!? _gport-has-port-position? `gset-port-position! ag port-position bgtranscoded-port cg textual-port? dg binary-port? egport-transcoder fg port-eof? gg utf-16-codec hg utf-8-codec ig latin-1-codec jgnative-transcoder kgtranscoder-error-handling-mode lgtranscoder-eol-style mgtranscoder-codec ngmake-transcoder ogerror-handling-mode pgnative-eol-style qg eol-style rg buffer-mode? sg buffer-mode tg file-options uABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrst4 vgmodule-re-export! wv xv ygi/o-error-port zgmake-i/o-port-error {gi/o-port-error? |g &i/o-port }g"make-i/o-file-does-not-exist-error ~gi/o-file-does-not-exist-error? g&i/o-file-does-not-exist g"make-i/o-file-already-exists-error gi/o-file-already-exists-error? g&i/o-file-already-exists g make-i/o-file-is-read-only-error gi/o-file-is-read-only-error? g&i/o-file-is-read-only gmake-i/o-file-protection-error gi/o-file-protection-error? g&i/o-file-protection gi/o-error-filename gmake-i/o-filename-error gi/o-filename-error? g &i/o-filename gmake-i/o-invalid-position-error gi/o-invalid-position-error? g&i/o-invalid-position gmake-i/o-write-error gi/o-write-error? g &i/o-write gmake-i/o-read-error gi/o-read-error? g &i/o-read gmake-i/o-error g i/o-error? g&i/o gcurrent-error-port gcurrent-output-port gcurrent-input-port g get-string-n! gput-bytevector gput-u8 gmake-custom-binary-output-port gopen-bytevector-output-port gget-bytevector-all gget-bytevector-some gget-bytevector-n! gget-bytevector-n g lookahead-u8 gget-u8 gmake-custom-binary-input-port gopen-bytevector-input-port g close-port g output-port? g input-port? gport? g eof-object? g eof-object yz{|}~6 gmodule-replace!   gmake-syntax-transformer   g file-option gmacro g $sc-dispatch   gany  g syntax->datum ' ' g no-create gno-fail g no-truncate g syntax-object gquote g m-d35b14d-24 gtop  gribcage gsym    f l-d35b14d-29 f l-d35b14d-2a    gs   f l-d35b14d-26   gshift gdummy g type-name gsymbol gconstructor-syntax  g m-bfa5881-18   f l-bfa5881-1d f l-bfa5881-1e f l-bfa5881-1f f l-bfa5881-20   gx   f l-bfa5881-1a    gprivate &  gsyntax-violation ' ' gsymbol->string ' ' fnot a member of the set   f-source expression failed to match any pattern g_ geach-any  g datum->syntax ' '  gevery ' ' gmemq fnot a subset of the universe genum-set-constructor g t-d35b14d-43  g t-d35b14d-44     g m-d35b14d-45        f l-d35b14d-49 f l-d35b14d-4a     g quoted-syms  f l-d35b14d-3b   gquoted-universe  f l-d35b14d-39   gsyms  f l-d35b14d-36    !guniverse "! #f l-d35b14d-34 $# %"$ & 'f l-d35b14d-31 (' )&( *f l-d35b14d-2e +* ,+ - %), .- /gmake-enumeration 0/- 1gnone 2gline 3gblock 4g m-d35b14d-4d 54 6s 75 8f l-d35b14d-52 9f l-d35b14d-53 :89 ;67: <5 =f l-d35b14d-4f >= ?<> @5;? A@ Bg buffer-modes C123 Dg t-d35b14d-6c Eg t-d35b14d-6d FDE Gg m-d35b14d-6e HG IHH Jf l-d35b14d-72 Kf l-d35b14d-73 LJK MFIL Nf l-d35b14d-64 ON P<O Qf l-d35b14d-62 RQ S<R Tf l-d35b14d-5f UT V<U Wf l-d35b14d-5d XW Y"<X Zf l-d35b14d-5a [Z \&<[ ]f l-d35b14d-57 ^] _<^ `5MPSVY\_ a` b/` cgenum-set-member? dgenum-set-universe e' f' g'/ h'/ iglf jgcr kgcrlf lgnel mgcrnel ngls og m-d35b14d-76 po qq rp sf l-d35b14d-7b tf l-d35b14d-7c ust vqru wp xf l-d35b14d-78 yx zwy {pvz |{ }g eol-styles ~ijklmn1 g t-d35b14d-95 g t-d35b14d-96  g m-d35b14d-97   f l-d35b14d-9b f l-d35b14d-9c   f l-d35b14d-8d  w f l-d35b14d-8b  w f l-d35b14d-88  w f l-d35b14d-86  "w f l-d35b14d-83  &w f l-d35b14d-80  w p  / gignore greplace g m-d35b14d-9f  o  f l-d35b14d-a4 f l-d35b14d-a5    f l-d35b14d-a1     gerror-handling-modes 7 g t-d35b14d-be g t-d35b14d-bf  g m-d35b14d-c0   f l-d35b14d-c4 f l-d35b14d-c5   f l-d35b14d-b6   f l-d35b14d-b4   f l-d35b14d-b1   f l-d35b14d-af  " f l-d35b14d-ac  & f l-d35b14d-a9     / gmake-record-type-descriptor * * g transcoder g immutable gcodec  q o  grecord-constructor * * g"make-record-constructor-descriptor * * g%make-transcoder gregister-record-type * * grecord-predicate * * g transcoder? grecord-accessor * * g%default-port-encoding f ISO-8859-1 fUTF-8 fUTF-16 gwith-throw-handler g system-error gsystem-error-errno gEACCES gEEXIST gENOENT gEROFS gwith-i/o-filename-conditions gmemv gEIO gEFBIG gENOSPC gEPIPE g condition gthrow gwith-i/o-port-error gwith-textual-output-conditions    gport gbody0 gbody  g m-d35b14d-cb    f l-d35b14d-d0  f l-d35b14d-d1  f l-d35b14d-d2  f l-d35b14d-d3          f l-d35b14d-cd       glambda  gwith-i/o-encoding-error  gwith-textual-input-conditions g m-d35b14d-d9   f l-d35b14d-de  f l-d35b14d-df !f l-d35b14d-e0 "f l-d35b14d-e1 # !" $# % &f l-d35b14d-db '& (%' )$( *) +) ,) -gwith-i/o-decoding-error .-) /g port-encoding 0gport-conversion-strategy 1gerror 2g substitute 3funsupported error handling mode 4g%make-transcoded-port 54 64 7gset-port-encoding! 8gset-port-conversion-strategy! 9gseek :gSEEK_CUR ;gSEEK_SET < ?gopen-input-string @gopen Ag r6rs-open BgO_CREAT CgO_TRUNC DgO_EXCL Egfile-options->mode FgO_RDONLY GgO_RDWR Hgopen-output-string Igget-output-string JgO_WRONLY Kgmake-soft-port Lgstring Mg string-length Nfw Og force-output P. Q. Rg &i/o-encoding Sg list->vector T.S U.S Vgchar WVA X. Y. Z. [. \gcondition-predicate ].\ ^.\ _gcondition-accessor `._ a._ b. c. d eg m-d35b14d-114 fe gf hf l-d35b14d-119 if l-d35b14d-11a jhi kdgj lf mf l-d35b14d-116 nm oln pko qp rp sgencoding-error tsp urt vp wgbegin xwp ygkey zyp {gsubr |{p }gmessage ~}p gerrno p p gchr p z|~ 7p Bp   v  g write-char gwrite gstring? gsubstring/shared fexpected string g guile:display g &i/o-decoding g m-d35b14d-148   f l-d35b14d-14d f l-d35b14d-14e  d  f l-d35b14d-14a      gdecoding-error    w y { }    7 E     g read-char gread g read-line gtrim g read-string g make-string g peek-char g dup->inport g dup->outportC5h@Z]4     54>"G454 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4%54 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4'54 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4*54 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4,54 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4.54 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4054 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4354 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4554 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4954 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4=54 hC]45L6;gfilenamefrnrs/io/ports.scm     CO>"G4@ uhC]456;gfilenamefrnrs/io/ports.scm    C>"G4x hC]456;gfilenamefrnrs/io/ports.scm    C>"G4 hC]456;gfilenamefrnrs/io/ports.scm    C>"G4 hH~] 45&"&"$C45 6vg file-option  Ggsym  Ggt  -gfilenamefrnrs/io/ports.scm  }   G Ch(c] 45$@6[gs  "gtmp "gfilenamefrnrs/io/ports.scm }   " C5R4thS]6Kgx  gfilenamefrnrs/io/ports.scm }   Ct.0hN]CFg t-d35b14d-43  g t-d35b14d-44     Ch])454L54L545$"44 5 >"G4  5$ @6gsym  gsyms gquoted-universe   g quoted-syms  ) gt  4 ]gtmp  d gtmp  o gfilenamefrnrs/io/ports.scm  }   Ch(c] 45$ O@6[gs  'gtmp 'gfilenamefrnrs/io/ports.scm }   ' C5tR4s123As hH] 45&"&"$C45 6wg buffer-mode  Ggsym  Ggt  -gfilenamefrnrs/io/ports.scm    G Ch(d] 45$@6\gs  "gtmp "gfilenamefrnrs/io/ports.scm   " C5sR4BCChT]6Lgx  gfilenamefrnrs/io/ports.scm   CBabhN]CFg t-d35b14d-6c  g t-d35b14d-6d     Ch])454L54L545$"44 5 >"G4  5$ @6gsym  gsyms gquoted-universe   g quoted-syms  ) gt  4 ]gtmp  d gtmp  o gfilenamefrnrs/io/ports.scm    Ch(d] 45$ O@6\gs  'gtmp 'gfilenamefrnrs/io/ports.scm   ' C5BRcdfhCh r]444455556jgsymbol  gfilenamefrnrs/io/ports.scm    gnameg buffer-mode?CrR4qijklmn1|qh}] 45&"F&"9&",&"&"&"$ C 4  5 6ug eol-style  {gsym  {gt  agfilenamefrnrs/io/ports.scm    { Ch(d] 45$@6\gs  "gtmp "gfilenamefrnrs/io/ports.scm   " C5qR4}~~hT]6Lgx  gfilenamefrnrs/io/ports.scm   C}hN]CFg t-d35b14d-95  g t-d35b14d-96     Ch])454L54L545$"44 5 >"G4  5$ @6gsym  gsyms gquoted-universe   g quoted-syms  ) gt  4 ]gtmp  d gtmp  o gfilenamefrnrs/io/ports.scm    Ch(d] 45$ O@6\gs  'gtmp 'gfilenamefrnrs/io/ports.scm   ' C5}R1ha]CYgfilenamefrnrs/io/ports.scm    gnamegnative-eol-styleCpR4o7o hH] 45&"&"$C45 6gerror-handling-mode  Ggsym  Ggt  -gfilenamefrnrs/io/ports.scm    G Ch(d] 45$@6\gs  "gtmp "gfilenamefrnrs/io/ports.scm   " C5oR4hT]6Lgx  gfilenamefrnrs/io/ports.scm   ChN]CFg t-d35b14d-be  g t-d35b14d-bf     Ch])454L54L545$"44 5 >"G4  5$ @6gsym  gsyms gquoted-universe   g quoted-syms  ) gt  4 ]gtmp  d gtmp  o gfilenamefrnrs/io/ports.scm    Ch(d] 45$ O@6\gs  'gtmp 'gfilenamefrnrs/io/ports.scm   ' C5R45R44i55R4i4i5>"GR4i5R4i 5kR4i 5lR4i 5mRph0-.,3#45#6gcodec -g eol-style -g handling-mode  -gfilenamefrnrs/io/ports.scm  - gnamegmake-transcoderCnRnih r][$"456jgt  gfilenamefrnrs/io/ports.scm    gnamegnative-transcoderCjRhg]C_gfilenamefrnrs/io/ports.scm     gnameg latin-1-codecCiRhe]C]gfilenamefrnrs/io/ports.scm     gnameg utf-8-codecChRhf]C^gfilenamefrnrs/io/ports.scm     gnameg utf-16-codecCgR}7 h`a-1345$"/$" $"$ "  4L56Ygargs ]gerrno  ]gconstruct-condition  P ] ] Ch]O6gfilename  gthunk  gfilenamefrnrs/io/ports.scm    gnamegwith-i/o-filename-conditionsCR7z hH@-134545$44L54 L556 @8gargs Cgerrno  C C Ch]O6gport  gmake-primary-condition  gthunk   gfilenamefrnrs/io/ports.scm    gnamegwith-i/o-port-errorCR4h d]C\gdummy  gport  gbody0   gbody      Ch(] 45$@6gx  "gtmp "  " g macro-typeg syntax-rulesgpatternsgportgbody0gbodyg...C5R4*+,.h d]C\gdummy  gport  gbody0   gbody      Ch(] 45$@6gx  "gtmp "  " g macro-typeg syntax-rulesgpatternsgportgbody0gbodyg...C5R/np0172$e3 hX]45$>4545$"$" 4   56C gport  Qgt Qgkey  ! Mgfilenamefrnrs/io/ports.scm H '  Q gnamegport-transcoderg documentationfdReturn the transcoder object associated with @var{port}, or @code{#f} if the port has no transcoder.CeR/h]45Cgport  gfilenamefrnrs/io/ports.scm   gnameg binary-port?g documentationfZReturns @code{#t} if @var{port} does not have an associated encoding, @code{#f} otherwise.CdRh]Cgport  gfilenamefrnrs/io/ports.scm    gnameg textual-port?g documentationfLAlways returns @code{#t}, as all ports can be used for textual I/O in Guile.CcRdNh(m]45$ 45"456egport  #gfilenamefrnrs/io/ports.scm   # gnameg port-eof?CfR67mk781213 hr]45445>"G45$4>"G":$4 >"G"4  45>"GCjgport  g transcoder  gresult  gkey  + gfilenamefrnrs/io/ports.scm t    gnamegtranscoded-portg documentationfReturn a new textual port based on @var{port}, using @var{transcoder} to encode and decode data written to or read from its underlying binary port @var{port}.CbR9:h] 6gport  gfilenamefrnrs/io/ports.scm    gnameg port-positiong documentationfjReturn the offset (an integer) indicating where the next octet will be read from/written to in @var{port}.CaR9;h]6gport  goffset  gfilenamefrnrs/io/ports.scm    gnamegset-port-position!g documentationfNSet the position where the next octet will be read from/written to @var{port}.C`R>ah]L6   Ch.-13C&gargs  Ch ]4O5$CCgport  gfilenamefrnrs/io/ports.scm     gnamegport-has-port-position?g documentationf=Return @code{#t} is @var{port} supports @code{port-position}.C_R>`ah]L4L56   Ch.-13C&gargs  Ch ]4O5$CCgport  gfilenamefrnrs/io/ports.scm     gnamegport-has-set-port-position!?g documentationfBReturn @code{#t} is @var{port} supports @code{set-port-position!}.C^Rh(+] 4> G4>"GE#gport  (gproc  (gvals  (gfilenamefrnrs/io/ports.scm #   ( gnamegcall-with-portg documentationfCall @var{proc}, passing it @var{port} and closing @var{port} upon exit of @var{proc}. Return the return values of @var{proc}.C]R]h@-.,3#4> G4>"G6gproc ?g transcoder ?gport  ?gextract  ?gfilenamefrnrs/io/ports.scm ,  ? gnameg call-with-bytevector-output-portCXR?h]Y4>ZCZFgstr  gfilenamefrnrs/io/ports.scm 1  3 (   gnamegopen-string-input-portg documentationf1Open an input port that will read from @var{str}.C\R@h]Y4LL>ZCZF   C7mh@] 4O5$445>"G"Cgfilename  :gmode  :g buffer-mode   :g transcoder   :gport   :gfilenamefrnrs/io/ports.scm 6   : gnameg r6rs-openCARcBCDhH]45$ "45$ "45$ "Cg file-options  Dg base-mode  Dgfilenamefrnrs/io/ports.scm ?   D gnamegfile-options->modeCERfh3AFhH-.,3#444555##6 gfilename Cg file-options Cg buffer-mode  Cg transcoder  Cgfilenamefrnrs/io/ports.scm K  C gnamegopen-file-input-portg documentationf5Return an input port for reading from @var{filename}.C[Rfh3AEGhP"-.,3#444555##456gfilename Jg file-options Jg buffer-mode  Jg transcoder  Jgfilenamefrnrs/io/ports.scm S  J gnamegopen-file-input/output-portg documentationf=Return a port for reading from and writing to @var{filename}.CTRHIh]L6   Ch 5]Y45ZOD-gport  gfilenamefrnrs/io/ports.scm ^  a 4   gnamegopen-string-output-portg documentationfReturn two values: an output port that will collect characters written to it as a string, and a thunk to retrieve the characters associated with that port.CZRfh3AEJhP-.,3#444555##456gfilename Jg file-options Jg buffer-mode  Jgmaybe-transcoder  Jgfilenamefrnrs/io/ports.scm f  J gnamegopen-file-output-portg documentationf4Return an output port for writing to @var{filename}.CYRHIh(!] 454>"G6gproc  !gport  !gfilenamefrnrs/io/ports.scm q   ! gnamegcall-with-string-output-portg documentationfzCall @var{proc}, passing it a string output port. When @var{proc} returns, return the characters accumulated in that port.CWRKLh)]L45 6!gc     CMh)]L 456!gs     CNh ]OO6gid  gwrite!  g get-position   g set-position!   gclose   gfilenamefrnrs/io/ports.scm x      gnamegmake-custom-textual-output-portCVROhu]6mgport  gfilenamefrnrs/io/ports.scm     gnamegflush-output-portCUR4QR|i4UW55RR4Y4[Ri55BR4^Ri5CR4aRi4cRi 55AR4quvxh?]C7gdummy  gbody     Ch(] 45$@6gx  "gtmp "  " g documentationfBConvert Guile throws to `encoding-error' to `&i/o-encoding-error'.g macro-typeg syntax-rulesgpatternsgbodyg...C5Rsh]LL6  C7Bh]456gkey  gsubr  gmessage   gerrno   gport   gchr      Ch]LLO6   Ch~]O6vgport  gchar  gfilenamefrnrs/io/ports.scm     gnamegput-charCMRsh]LL6  C7Bh]456gkey  gsubr  gmessage   gerrno   gport   gchr      Ch]LLO6   Ch]O6xgport  gdatum  gfilenamefrnrs/io/ports.scm     gnameg put-datumCLRs8M$KhXF]4L5$>L$0L$4LLLL5L64LL4L55L6LL6L6>gfilenamefrnrs/io/ports.scm Q  +  U C7Bh]456gkey  gsubr  gmessage   gerrno   gport   gchr      Ch]LLLLO6   Ch8-.,3##O6gport 3gs 3gstart  3gcount  3gfilenamefrnrs/io/ports.scm   3  gnameg put-stringCKRsh]LL6  C7Bh]456gkey  gsubr  gmessage   gerrno   gport   gchr      Ch]LLO6   Ch0-.,3#45O6wgobject *gport *gfilenamefrnrs/io/ports.scm   * gnamegdisplayC8R4Q|i4U55R4Y4[i55ER4^i5FR4-h?]C7gdummy  gbody     Ch(] 45$@6gx  "gtmp "  " g documentationfBConvert Guile throws to `decoding-error' to `&i/o-decoding-error'.g macro-typeg syntax-rulesgpatternsgbodyg...C5-Rh]L6   C7Ehw]456ogkey  gsubr  gmessage   gerrno   gport     Ch]LO6   Chl]O6dgport  gfilenamefrnrs/io/ports.scm     gnamegget-charCSRh]L6   C7Ehw]456ogkey  gsubr  gmessage   gerrno   gport     Ch]LO6   Chm]O6egport  gfilenamefrnrs/io/ports.scm     gnameg get-datumCRRh]L6  C7Ehw]456ogkey  gsubr  gmessage   gerrno   gport     Ch]LO6   Chl]O6dgport  gfilenamefrnrs/io/ports.scm     gnamegget-lineCQRh]L6   C7Ehw]456ogkey  gsubr  gmessage   gerrno   gport     Ch]LO6   Chr]O6jgport  gfilenamefrnrs/io/ports.scm     gnamegget-string-allCPRh@]454 545$C$C 6gport  <gcount  <gs  <grv   <gfilenamefrnrs/io/ports.scm    < gnameg get-string-ng documentationfRead up to @var{count} characters from @var{port}. If no characters could be read before encountering the end of file, return the end-of-file object, otherwise return a string containing the characters read.CORh]L6   C7Ehw]456ogkey  gsubr  gmessage   gerrno   gport     Ch]LO6   Chr]O6jgport  gfilenamefrnrs/io/ports.scm     gnameglookahead-charCNRhd]Y4 >ZCZF\gfilenamefrnrs/io/ports.scm     gnamegstandard-input-portCJRhe]Y4 >ZCZF]gfilenamefrnrs/io/ports.scm     gnamegstandard-output-portCIRhd]Y4 >ZCZF\gfilenamefrnrs/io/ports.scm     gnamegstandard-error-portCHRCgm  +giface 2 giface 8giface ? giface  Hgiface O giface  Xgiface _ giface  hgiface o giface  xgiface   gfilenamefrnrs/io/ports.scm    <   E  P  ! # ' ( ) *P , -  .  09  1  3> # 4V , 5T 1 6 6 7 ? 9F K : S < ^ > f ?t q A) x A  A  E  Gs  J  L  L  O  QX  S  T  V  Xu  Y  Y  Z7  0  Z9 C6PK!Lconsole/size.rbnu[# frozen_string_literal: false # fallback to console window size def IO.default_console_size [ ENV["LINES"].to_i.nonzero? || 25, ENV["COLUMNS"].to_i.nonzero? || 80, ] end begin require 'io/console' rescue LoadError class << IO alias console_size default_console_size end else # returns console window size def IO.console_size console.winsize rescue NoMethodError default_console_size end end PK!\0p0p console.sonuȯELF>"@0i@8 @xVxV ZZ Z H ([([ ([ 888$$XVXVXV StdXVXVXV PtdJJJQtdRtdZZ Z HPGNU~B0z M~Y+TH!@TVXBE|qX/Do>' `uP.9pS6:ofU$ UH""hhy U, Bq9, {F"r[#` X` `  Bp @G__gmon_start___ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalizerb_check_typeddatacfmakerawrb_data_typed_object_zallocrb_funcallvrb_default_rsrb_io_write__errno_locationtcsetattrrb_num2uintrb_sprintfrb_io_taint_checkrb_io_check_closedrb_sys_fail_str__stack_chk_failtcgetattrtcflushrb_string_value_cstrrb_io_get_write_iorb_ensurerb_stdinrb_stderrrb_error_arityrb_str_new_staticrb_str_catfrb_io_flushrb_convert_typerb_eArgErrorrb_raiserb_cIOrb_cFilerb_const_definedrb_cloexec_openrb_update_max_fdrb_class_new_instancerb_obj_freezerb_const_setrb_unexpected_typerb_const_getrb_const_removerb_id2symrb_io_closerb_check_idrb_keyword_given_prb_funcallv_kwstrlenrb_io_getbyterb_ary_newrb_ary_pushrb_str_newrb_str_new_cstrioctlrb_assoc_newrb_fix2intrb_num2intrb_Arrayrb_ary_detransientrb_protectrb_syserr_failrb_jump_tagrb_io_getsrb_yieldrb_hash_duprb_hash_arefrb_funcallv_publicrb_ary_resizerb_ary_ptr_use_startrb_ary_ptr_use_endrb_debug_rstring_null_ptrrb_obj_classInitVM_consolerb_f_notimplementrb_define_module_underrb_cObjectrb_define_class_underrb_define_alloc_funcrb_undef_methodInit_consolerb_internrb_define_methodrb_define_singleton_methodlibruby.so.3.1libm.so.6libc.so.6_edata__bss_startGLIBC_2.4GLIBC_2.2.5/opt/alt/ruby31/lib64ii ui Z P#Z #Z Z Z 2J_ _  _  _ _ "_ *_ +_ 5_ >_ L_ M_ N_ O_ SP] X] `] h] p] x] ] ]  ]  ]  ] ] ] ] ] ] ] ] ] ] ] ] ^ ^ ^ ^  ^ (^  0^ !8^ #@^ $H^ %P^ &X^ '`^ (h^ )p^ ,x^ -^ .^ /^ 0^ 1^ 2^ 3^ 4^ 6^ 7^ 8^ 9^ :^ ;^ <^ =^ ?_ @_ A_ B_ C _ D(_ W0_ E8_ F@_ GH_ HP_ IX_ J`_ Kh_ Op_ Px_ Q_ RHH9F HtH5C %C hhhhhhhhqhah Qh Ah 1h !h hhhhhhhhhhqhahQhAh1h!hhhh h!h"h#h$h%h&h'qh(ah)Qh*Ah+1h,!h-h.h/h0h1h2h3h4h5h6h7qh8ah9Qh:Ah;1h<!h=h>h?h@hAhBhChDhEhF%5? D%-? D%%? D%? D%? D% ? D%? D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%> D%}> D%u> D%m> D%e> D%]> D%U> D%M> D%E> D%=> D%5> D%-> D%%> D%> D%> D% > D%> D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%= D%}= D%u= D%m= D%e= D%]= D%U= D%M= D%E= D%== D%5= D%-= D%%= D%= D%= D% = D%= DH=&% f.H=Y= HR= H9tH< Ht H=)= H5"= H)HHH?HHtH< HtfD=< u+UH=< Ht H=7 d< ]wH"O {H g HHwH ff.@UHH5!7 SHH4HtH xHH[]D` HH[]f.ATIH56 UHSLH56 HooHKoP S HP0HS0@8C8H[]A\DUHSHHC ωC Ht.UxSUxSUtC HH H[]H6 <{ff.SH5 H<[foHP foKJfoS R HK0HJ0K8J8[ff.HH5; H׉fDH5: 11ff.H-: H0ff.fUSHH 8u&1HډuH[]f.H1[]SHH0H="p1HH4H[ff.@ATIUHHSLHSH=!p1HHH[]A\UHH5a4 SHHHXdH%(HD$H1aHo)$oH)L$oP )T$ HP0HT$0@8D$8HXH{HtHL$HdH3 %(HuHX[]H{ Of.USHXdH%(HD$H1H.HXH2{H'u&H=8 HtHT$HdH3%(uHX[]H{ ff.@SHPdH%(HD$H1HXH{Hu)D$ HHHЃHT$HdH3%(uHP[H{ U AVIAUATUHSHPdH%(HD$H1I2HXH6DcLD'uLD$ Iu6D$ LDt)HT$HdH3%(HuHP[]A\A]A^ÃxD$ H{ yfAUATUHSHXdH%(HD$H1IHXHDcLD|uCLDH"L$ {H $gtHT$HdH3%(HuHX[]A\A]H{ UHSHHXH{1u HH[]H{ SHdH%(HD$1HHtHHH$cH4$HgHD$dH3%(uH[DH0 у1AVAUATUSHHdH%(HD$1HHDn@HtyHH umHuL`LyMt$XHMHA|$HHHu`AD$u$HHHlHu9fDHL$dH3 %(H[]A\A]A^f.E1HH7uHH=u*1IDHHt+HJ;tEPЃ w-THߍlP]HuHL\Et#A9uE1롐HcLHt-1~@HcLD$Ht-dH|${LHLff.ATUHSHXHH{XHu{u"H[]A\fL`LA|$H{ off.@ATUHS`HXHdH{XHu+{H5Hx*H[]A\f.L`LA|$H{ ff.@USHdH%(HD$1HXHH{XHuL{1HT uQD$Ht$H|HL$dH3 %(u$H[]kHhHo}H{ D7I{zO}R5נN7t"wxGWjZcYڙ>e,֛^jvrSb W?¼eܞ{o05bPҎyN=A->nuf (rC-QͭTErNHCV߀ol4w=@!N)5*@=* ś PI4g3/oCoCT(9zNInAUq^30+/ifr-0g;L7 O.rp* -GSgYZ.shstrtab.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.plt.sec.text.fini.rodata.eh_frame_hdr.eh_frame.note.gnu.property.init_array.fini_array.data.rel.ro.dynamic.got.bss.gnu.build.attributes.gnu_debuglink.gnu_debugdata 88$o``8( X0 ;8o,,Eo0T^Bhhhcnpw""|%}GG HHJJLL XVXV Z ZZ ZZ Zh ([ ([8] 8]` _XX``_H@b(hbh"PK!n^buffer.hnu[#ifndef RUBY_IO_BUFFER_H #define RUBY_IO_BUFFER_H /** * @file * @author Samuel Williams * @date Fri 2 Jul 2021 16:29:01 NZST * @copyright Copyright (C) 2021 Samuel Williams * @copyright This file is a part of the programming language Ruby. * Permission is hereby granted, to either redistribute and/or * modify this file, provided that the conditions mentioned in the * file COPYING are met. Consult the file for details. */ #pragma once #include "ruby/ruby.h" #include "ruby/internal/config.h" RBIMPL_SYMBOL_EXPORT_BEGIN() // WARNING: This entire interface is experimental and may change in the future! #define RB_IO_BUFFER_EXPERIMENTAL 1 #define RUBY_IO_BUFFER_VERSION 2 // The `IO::Buffer` class. RUBY_EXTERN VALUE rb_cIOBuffer; // The operating system page size. RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE; // The default buffer size, usually a (small) multiple of the page size. // Can be overridden by the RUBY_IO_BUFFER_DEFAULT_SIZE environment variable. RUBY_EXTERN size_t RUBY_IO_BUFFER_DEFAULT_SIZE; // Represents the internal state of the buffer. // More than one flag can be set at a time. enum rb_io_buffer_flags { // The memory in the buffer is owned by someone else. // More specifically, it means that someone else owns the buffer and we shouldn't try to resize it. RB_IO_BUFFER_EXTERNAL = 1, // The memory in the buffer is allocated internally. RB_IO_BUFFER_INTERNAL = 2, // The memory in the buffer is mapped. // A non-private mapping is marked as external. RB_IO_BUFFER_MAPPED = 4, // A mapped buffer that is also shared. RB_IO_BUFFER_SHARED = 8, // The buffer is locked and cannot be resized. // More specifically, it means we can't change the base address or size. // A buffer is typically locked before a system call that uses the data. RB_IO_BUFFER_LOCKED = 32, // The buffer mapping is private and will not impact other processes or the underlying file. RB_IO_BUFFER_PRIVATE = 64, // The buffer is read-only and cannot be modified. RB_IO_BUFFER_READONLY = 128, // The buffer is backed by a file. RB_IO_BUFFER_FILE = 256, }; // Represents the endian of the data types. enum rb_io_buffer_endian { // The least significant units are put first. RB_IO_BUFFER_LITTLE_ENDIAN = 4, RB_IO_BUFFER_BIG_ENDIAN = 8, #if defined(WORDS_BIGENDIAN) RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN, #else RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN, #endif RB_IO_BUFFER_NETWORK_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN }; VALUE rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags); VALUE rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags flags); VALUE rb_io_buffer_lock(VALUE self); VALUE rb_io_buffer_unlock(VALUE self); int rb_io_buffer_try_unlock(VALUE self); VALUE rb_io_buffer_free(VALUE self); VALUE rb_io_buffer_free_locked(VALUE self); // Access the internal buffer and flags. Validates the pointers. // The points may not remain valid if the source buffer is manipulated. // Consider using rb_io_buffer_lock if needed. enum rb_io_buffer_flags rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size); void rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size); void rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size); VALUE rb_io_buffer_transfer(VALUE self); void rb_io_buffer_resize(VALUE self, size_t size); void rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length); // The length is the minimum required length. VALUE rb_io_buffer_read(VALUE self, VALUE io, size_t length, size_t offset); VALUE rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset); VALUE rb_io_buffer_write(VALUE self, VALUE io, size_t length, size_t offset); VALUE rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset); RBIMPL_SYMBOL_EXPORT_END() #endif /* RUBY_IO_BUFFER_H */ PK!ףdumb.rbnu[require 'io/wait' class Reline::Dumb < Reline::IO RESET_COLOR = '' # Do not send color reset sequence def initialize(encoding: nil) @input = STDIN @buf = [] @pasting = false @encoding = encoding @screen_size = [24, 80] end def dumb? true end def encoding if @encoding @encoding elsif RUBY_PLATFORM =~ /mswin|mingw/ Encoding::UTF_8 else Encoding::default_external end end def set_default_key_bindings(_) end def input=(val) @input = val end def with_raw_input yield end def getc(_timeout_second) unless @buf.empty? return @buf.shift end c = nil loop do Reline.core.line_editor.handle_signal result = @input.wait_readable(0.1) next if result.nil? c = @input.read(1) break end c&.ord end def ungetc(c) @buf.unshift(c) end def get_screen_size @screen_size end def cursor_pos Reline::CursorPos.new(1, 1) end def hide_cursor end def show_cursor end def move_cursor_column(val) end def move_cursor_up(val) end def move_cursor_down(val) end def erase_after_cursor end def scroll_down(val) end def clear_screen end def set_screen_size(rows, columns) @screen_size = [rows, columns] end def set_winch_handler(&handler) end def in_pasting? @pasting end def prep end def deprep(otio) end end PK!%DCDC windows.rbnu[require 'fiddle/import' class Reline::Windows < Reline::IO def initialize @input_buf = [] @output_buf = [] @output = STDOUT @hsg = nil @getwch = Win32API.new('msvcrt', '_getwch', [], 'I') @kbhit = Win32API.new('msvcrt', '_kbhit', [], 'I') @GetKeyState = Win32API.new('user32', 'GetKeyState', ['L'], 'L') @GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L') @SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L') @GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L') @FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L') @ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L') @hConsoleHandle = @GetStdHandle.call(STD_OUTPUT_HANDLE) @hConsoleInputHandle = @GetStdHandle.call(STD_INPUT_HANDLE) @GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L') @ReadConsoleInputW = Win32API.new('kernel32', 'ReadConsoleInputW', ['L', 'P', 'L', 'P'], 'L') @GetFileType = Win32API.new('kernel32', 'GetFileType', ['L'], 'L') @GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I') @FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L') @SetConsoleCursorInfo = Win32API.new('kernel32', 'SetConsoleCursorInfo', ['L', 'P'], 'L') @GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['L', 'P'], 'L') @SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['L', 'L'], 'L') @WaitForSingleObject = Win32API.new('kernel32', 'WaitForSingleObject', ['L', 'L'], 'L') @legacy_console = getconsolemode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 end def encoding Encoding::UTF_8 end def win? true end def win_legacy_console? @legacy_console end def set_default_key_bindings(config) { [224, 72] => :ed_prev_history, # ↑ [224, 80] => :ed_next_history, # ↓ [224, 77] => :ed_next_char, # → [224, 75] => :ed_prev_char, # ← [224, 83] => :key_delete, # Del [224, 71] => :ed_move_to_beg, # Home [224, 79] => :ed_move_to_end, # End [ 0, 41] => :ed_unassigned, # input method on/off [ 0, 72] => :ed_prev_history, # ↑ [ 0, 80] => :ed_next_history, # ↓ [ 0, 77] => :ed_next_char, # → [ 0, 75] => :ed_prev_char, # ← [ 0, 83] => :key_delete, # Del [ 0, 71] => :ed_move_to_beg, # Home [ 0, 79] => :ed_move_to_end # End }.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) config.add_default_key_binding_by_keymap(:vi_insert, key, func) config.add_default_key_binding_by_keymap(:vi_command, key, func) end { [27, 32] => :em_set_mark, # M- [24, 24] => :em_exchange_mark, # C-x C-x }.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) end # Emulate ANSI key sequence. { [27, 91, 90] => :completion_journey_up, # S-Tab }.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) config.add_default_key_binding_by_keymap(:vi_insert, key, func) end end if defined? JRUBY_VERSION require 'win32api' else class Win32API DLL = {} TYPEMAP = {"0" => Fiddle::TYPE_VOID, "S" => Fiddle::TYPE_VOIDP, "I" => Fiddle::TYPE_LONG} POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*' WIN32_TYPES = "VPpNnLlIi" DL_TYPES = "0SSI" def initialize(dllname, func, import, export = "0", calltype = :stdcall) @proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1') import = @proto.chars.map {|win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)]} export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)] calltype = Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[calltype] handle = DLL[dllname] ||= begin Fiddle.dlopen(dllname) rescue Fiddle::DLError raise unless File.extname(dllname).empty? Fiddle.dlopen(dllname + ".dll") end @func = Fiddle::Function.new(handle[func], import, export, calltype) rescue Fiddle::DLError => e raise LoadError, e.message, e.backtrace end def call(*args) import = @proto.split("") args.each_with_index do |x, i| args[i], = [x == 0 ? nil : +x].pack("p").unpack(POINTER_TYPE) if import[i] == "S" args[i], = [x].pack("I").unpack("i") if import[i] == "I" end ret, = @func.call(*args) return ret || 0 end end end VK_RETURN = 0x0D VK_MENU = 0x12 # ALT key VK_LMENU = 0xA4 VK_CONTROL = 0x11 VK_SHIFT = 0x10 VK_DIVIDE = 0x6F KEY_EVENT = 0x01 WINDOW_BUFFER_SIZE_EVENT = 0x04 CAPSLOCK_ON = 0x0080 ENHANCED_KEY = 0x0100 LEFT_ALT_PRESSED = 0x0002 LEFT_CTRL_PRESSED = 0x0008 NUMLOCK_ON = 0x0020 RIGHT_ALT_PRESSED = 0x0001 RIGHT_CTRL_PRESSED = 0x0004 SCROLLLOCK_ON = 0x0040 SHIFT_PRESSED = 0x0010 VK_TAB = 0x09 VK_END = 0x23 VK_HOME = 0x24 VK_LEFT = 0x25 VK_UP = 0x26 VK_RIGHT = 0x27 VK_DOWN = 0x28 VK_DELETE = 0x2E STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 FILE_TYPE_PIPE = 0x0003 FILE_NAME_INFO = 2 ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 # Calling Win32API with console handle is reported to fail after executing some external command. # We need to refresh console handle and retry the call again. private def call_with_console_handle(win32func, *args) val = win32func.call(@hConsoleHandle, *args) return val if val != 0 @hConsoleHandle = @GetStdHandle.call(STD_OUTPUT_HANDLE) win32func.call(@hConsoleHandle, *args) end private def getconsolemode mode = "\000\000\000\000" call_with_console_handle(@GetConsoleMode, mode) mode.unpack1('L') end private def setconsolemode(mode) call_with_console_handle(@SetConsoleMode, mode) end #if @legacy_console # setconsolemode(getconsolemode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING) # @legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0) #end def msys_tty?(io = @hConsoleInputHandle) # check if fd is a pipe if @GetFileType.call(io) != FILE_TYPE_PIPE return false end bufsize = 1024 p_buffer = "\0" * bufsize res = @GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2) return false if res == 0 # get pipe name: p_buffer layout is: # struct _FILE_NAME_INFO { # DWORD FileNameLength; # WCHAR FileName[1]; # } FILE_NAME_INFO len = p_buffer[0, 4].unpack1("L") name = p_buffer[4, len].encode(Encoding::UTF_8, Encoding::UTF_16LE, invalid: :replace) # Check if this could be a MSYS2 pty pipe ('\msys-XXXX-ptyN-XX') # or a cygwin pty pipe ('\cygwin-XXXX-ptyN-XX') name =~ /(msys-|cygwin-).*-pty/ ? true : false end KEY_MAP = [ # It's treated as Meta+Enter on Windows. [ { control_keys: :CTRL, virtual_key_code: 0x0D }, "\e\r".bytes ], [ { control_keys: :SHIFT, virtual_key_code: 0x0D }, "\e\r".bytes ], # It's treated as Meta+Space on Windows. [ { control_keys: :CTRL, char_code: 0x20 }, "\e ".bytes ], # Emulate getwch() key sequences. [ { control_keys: [], virtual_key_code: VK_UP }, [0, 72] ], [ { control_keys: [], virtual_key_code: VK_DOWN }, [0, 80] ], [ { control_keys: [], virtual_key_code: VK_RIGHT }, [0, 77] ], [ { control_keys: [], virtual_key_code: VK_LEFT }, [0, 75] ], [ { control_keys: [], virtual_key_code: VK_DELETE }, [0, 83] ], [ { control_keys: [], virtual_key_code: VK_HOME }, [0, 71] ], [ { control_keys: [], virtual_key_code: VK_END }, [0, 79] ], # Emulate ANSI key sequence. [ { control_keys: :SHIFT, virtual_key_code: VK_TAB }, [27, 91, 90] ], ] def process_key_event(repeat_count, virtual_key_code, virtual_scan_code, char_code, control_key_state) # high-surrogate if 0xD800 <= char_code and char_code <= 0xDBFF @hsg = char_code return end # low-surrogate if 0xDC00 <= char_code and char_code <= 0xDFFF if @hsg char_code = 0x10000 + (@hsg - 0xD800) * 0x400 + char_code - 0xDC00 @hsg = nil else # no high-surrogate. ignored. return end else # ignore high-surrogate without low-surrogate if there @hsg = nil end key = KeyEventRecord.new(virtual_key_code, char_code, control_key_state) match = KEY_MAP.find { |args,| key.matches?(**args) } unless match.nil? @output_buf.concat(match.last) return end # no char, only control keys return if key.char_code == 0 and key.control_keys.any? @output_buf.push("\e".ord) if key.control_keys.include?(:ALT) and !key.control_keys.include?(:CTRL) @output_buf.concat(key.char.bytes) end def check_input_event num_of_events = 0.chr * 8 while @output_buf.empty? Reline.core.line_editor.handle_signal if @WaitForSingleObject.(@hConsoleInputHandle, 100) != 0 # max 0.1 sec # prevent for background consolemode change @legacy_console = getconsolemode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 next end next if @GetNumberOfConsoleInputEvents.(@hConsoleInputHandle, num_of_events) == 0 or num_of_events.unpack1('L') == 0 input_records = 0.chr * 20 * 80 read_event = 0.chr * 4 if @ReadConsoleInputW.(@hConsoleInputHandle, input_records, 80, read_event) != 0 read_events = read_event.unpack1('L') 0.upto(read_events) do |idx| input_record = input_records[idx * 20, 20] event = input_record[0, 2].unpack1('s*') case event when WINDOW_BUFFER_SIZE_EVENT @winch_handler.() when KEY_EVENT key_down = input_record[4, 4].unpack1('l*') repeat_count = input_record[8, 2].unpack1('s*') virtual_key_code = input_record[10, 2].unpack1('s*') virtual_scan_code = input_record[12, 2].unpack1('s*') char_code = input_record[14, 2].unpack1('S*') control_key_state = input_record[16, 2].unpack1('S*') is_key_down = key_down.zero? ? false : true if is_key_down process_key_event(repeat_count, virtual_key_code, virtual_scan_code, char_code, control_key_state) end end end end end end def with_raw_input yield end def getc(_timeout_second) check_input_event @output_buf.shift end def ungetc(c) @output_buf.unshift(c) end def in_pasting? not empty_buffer? end def empty_buffer? if not @output_buf.empty? false elsif @kbhit.call == 0 true else false end end def get_console_screen_buffer_info # CONSOLE_SCREEN_BUFFER_INFO # [ 0,2] dwSize.X # [ 2,2] dwSize.Y # [ 4,2] dwCursorPositions.X # [ 6,2] dwCursorPositions.Y # [ 8,2] wAttributes # [10,2] srWindow.Left # [12,2] srWindow.Top # [14,2] srWindow.Right # [16,2] srWindow.Bottom # [18,2] dwMaximumWindowSize.X # [20,2] dwMaximumWindowSize.Y csbi = 0.chr * 22 return if call_with_console_handle(@GetConsoleScreenBufferInfo, csbi) == 0 csbi end def get_screen_size unless csbi = get_console_screen_buffer_info return [1, 1] end csbi[0, 4].unpack('SS').reverse end def cursor_pos unless csbi = get_console_screen_buffer_info return Reline::CursorPos.new(0, 0) end x = csbi[4, 2].unpack1('s') y = csbi[6, 2].unpack1('s') Reline::CursorPos.new(x, y) end def move_cursor_column(val) call_with_console_handle(@SetConsoleCursorPosition, cursor_pos.y * 65536 + val) end def move_cursor_up(val) if val > 0 y = cursor_pos.y - val y = 0 if y < 0 call_with_console_handle(@SetConsoleCursorPosition, y * 65536 + cursor_pos.x) elsif val < 0 move_cursor_down(-val) end end def move_cursor_down(val) if val > 0 return unless csbi = get_console_screen_buffer_info screen_height = get_screen_size.first y = cursor_pos.y + val y = screen_height - 1 if y > (screen_height - 1) call_with_console_handle(@SetConsoleCursorPosition, (cursor_pos.y + val) * 65536 + cursor_pos.x) elsif val < 0 move_cursor_up(-val) end end def erase_after_cursor return unless csbi = get_console_screen_buffer_info attributes = csbi[8, 2].unpack1('S') cursor = csbi[4, 4].unpack1('L') written = 0.chr * 4 call_with_console_handle(@FillConsoleOutputCharacter, 0x20, get_screen_size.last - cursor_pos.x, cursor, written) call_with_console_handle(@FillConsoleOutputAttribute, attributes, get_screen_size.last - cursor_pos.x, cursor, written) end def scroll_down(val) return if val < 0 return unless csbi = get_console_screen_buffer_info buffer_width, buffer_lines, x, y, attributes, window_left, window_top, window_bottom = csbi.unpack('ssssSssx2s') screen_height = window_bottom - window_top + 1 val = screen_height if val > screen_height if @legacy_console || window_left != 0 # unless ENABLE_VIRTUAL_TERMINAL, # if srWindow.Left != 0 then it's conhost.exe hosted console # and puts "\n" causes horizontal scroll. its glitch. # FYI irb write from culumn 1, so this gives no gain. scroll_rectangle = [0, val, buffer_width, buffer_lines - val].pack('s4') destination_origin = 0 # y * 65536 + x fill = [' '.ord, attributes].pack('SS') call_with_console_handle(@ScrollConsoleScreenBuffer, scroll_rectangle, nil, destination_origin, fill) else origin_x = x + 1 origin_y = y - window_top + 1 @output.write [ (origin_y != screen_height) ? "\e[#{screen_height};H" : nil, "\n" * val, (origin_y != screen_height or !x.zero?) ? "\e[#{origin_y};#{origin_x}H" : nil ].join end end def clear_screen if @legacy_console return unless csbi = get_console_screen_buffer_info buffer_width, _buffer_lines, attributes, window_top, window_bottom = csbi.unpack('ss@8S@12sx2s') fill_length = buffer_width * (window_bottom - window_top + 1) screen_topleft = window_top * 65536 written = 0.chr * 4 call_with_console_handle(@FillConsoleOutputCharacter, 0x20, fill_length, screen_topleft, written) call_with_console_handle(@FillConsoleOutputAttribute, attributes, fill_length, screen_topleft, written) call_with_console_handle(@SetConsoleCursorPosition, screen_topleft) else @output.write "\e[2J" "\e[H" end end def set_screen_size(rows, columns) raise NotImplementedError end def hide_cursor size = 100 visible = 0 # 0 means false cursor_info = [size, visible].pack('Li') call_with_console_handle(@SetConsoleCursorInfo, cursor_info) end def show_cursor size = 100 visible = 1 # 1 means true cursor_info = [size, visible].pack('Li') call_with_console_handle(@SetConsoleCursorInfo, cursor_info) end def set_winch_handler(&handler) @winch_handler = handler end def prep # do nothing nil end def deprep(otio) # do nothing end class KeyEventRecord attr_reader :virtual_key_code, :char_code, :control_key_state, :control_keys def initialize(virtual_key_code, char_code, control_key_state) @virtual_key_code = virtual_key_code @char_code = char_code @control_key_state = control_key_state @enhanced = control_key_state & ENHANCED_KEY != 0 (@control_keys = []).tap do |control_keys| # symbols must be sorted to make comparison is easier later on control_keys << :ALT if control_key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) != 0 control_keys << :CTRL if control_key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) != 0 control_keys << :SHIFT if control_key_state & SHIFT_PRESSED != 0 end.freeze end def char @char_code.chr(Encoding::UTF_8) end def enhanced? @enhanced end # Verifies if the arguments match with this key event. # Nil arguments are ignored, but at least one must be passed as non-nil. # To verify that no control keys were pressed, pass an empty array: `control_keys: []`. def matches?(control_keys: nil, virtual_key_code: nil, char_code: nil) raise ArgumentError, 'No argument was passed to match key event' if control_keys.nil? && virtual_key_code.nil? && char_code.nil? (control_keys.nil? || [*control_keys].sort == @control_keys) && (virtual_key_code.nil? || @virtual_key_code == virtual_key_code) && (char_code.nil? || char_code == @char_code) end end end PK!F''ansi.rbnu[require 'io/console' require 'io/wait' class Reline::ANSI < Reline::IO CAPNAME_KEY_BINDINGS = { 'khome' => :ed_move_to_beg, 'kend' => :ed_move_to_end, 'kdch1' => :key_delete, 'kpp' => :ed_search_prev_history, 'knp' => :ed_search_next_history, 'kcuu1' => :ed_prev_history, 'kcud1' => :ed_next_history, 'kcuf1' => :ed_next_char, 'kcub1' => :ed_prev_char, } ANSI_CURSOR_KEY_BINDINGS = { # Up 'A' => [:ed_prev_history, {}], # Down 'B' => [:ed_next_history, {}], # Right 'C' => [:ed_next_char, { ctrl: :em_next_word, meta: :em_next_word }], # Left 'D' => [:ed_prev_char, { ctrl: :ed_prev_word, meta: :ed_prev_word }], # End 'F' => [:ed_move_to_end, {}], # Home 'H' => [:ed_move_to_beg, {}], } if Reline::Terminfo.enabled? Reline::Terminfo.setupterm(0, 2) end def initialize @input = STDIN @output = STDOUT @buf = [] @old_winch_handler = nil end def encoding Encoding.default_external end def set_default_key_bindings(config, allow_terminfo: true) set_bracketed_paste_key_bindings(config) set_default_key_bindings_ansi_cursor(config) if allow_terminfo && Reline::Terminfo.enabled? set_default_key_bindings_terminfo(config) else set_default_key_bindings_comprehensive_list(config) end { [27, 91, 90] => :completion_journey_up, # S-Tab }.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) config.add_default_key_binding_by_keymap(:vi_insert, key, func) end { # default bindings [27, 32] => :em_set_mark, # M- [24, 24] => :em_exchange_mark, # C-x C-x }.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) end end def set_bracketed_paste_key_bindings(config) [:emacs, :vi_insert, :vi_command].each do |keymap| config.add_default_key_binding_by_keymap(keymap, START_BRACKETED_PASTE.bytes, :bracketed_paste_start) end end def set_default_key_bindings_ansi_cursor(config) ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)| bindings = [["\e[#{char}", default_func]] # CSI + char if modifiers[:ctrl] # CSI + ctrl_key_modifier + char bindings << ["\e[1;5#{char}", modifiers[:ctrl]] end if modifiers[:meta] # CSI + meta_key_modifier + char bindings << ["\e[1;3#{char}", modifiers[:meta]] # Meta(ESC) + CSI + char bindings << ["\e\e[#{char}", modifiers[:meta]] end bindings.each do |sequence, func| key = sequence.bytes config.add_default_key_binding_by_keymap(:emacs, key, func) config.add_default_key_binding_by_keymap(:vi_insert, key, func) config.add_default_key_binding_by_keymap(:vi_command, key, func) end end end def set_default_key_bindings_terminfo(config) key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding| begin key_code = Reline::Terminfo.tigetstr(capname) [ key_code.bytes, key_binding ] rescue Reline::Terminfo::TerminfoError # capname is undefined end end.compact.to_h key_bindings.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) config.add_default_key_binding_by_keymap(:vi_insert, key, func) config.add_default_key_binding_by_keymap(:vi_command, key, func) end end def set_default_key_bindings_comprehensive_list(config) { # xterm [27, 91, 51, 126] => :key_delete, # kdch1 [27, 91, 53, 126] => :ed_search_prev_history, # kpp [27, 91, 54, 126] => :ed_search_next_history, # knp # Console (80x25) [27, 91, 49, 126] => :ed_move_to_beg, # Home [27, 91, 52, 126] => :ed_move_to_end, # End # KDE # Del is 0x08 [27, 71, 65] => :ed_prev_history, # ↑ [27, 71, 66] => :ed_next_history, # ↓ [27, 71, 67] => :ed_next_char, # → [27, 71, 68] => :ed_prev_char, # ← # urxvt / exoterm [27, 91, 55, 126] => :ed_move_to_beg, # Home [27, 91, 56, 126] => :ed_move_to_end, # End # GNOME [27, 79, 72] => :ed_move_to_beg, # Home [27, 79, 70] => :ed_move_to_end, # End # Del is 0x08 # Arrow keys are the same of KDE [27, 79, 65] => :ed_prev_history, # ↑ [27, 79, 66] => :ed_next_history, # ↓ [27, 79, 67] => :ed_next_char, # → [27, 79, 68] => :ed_prev_char, # ← }.each_pair do |key, func| config.add_default_key_binding_by_keymap(:emacs, key, func) config.add_default_key_binding_by_keymap(:vi_insert, key, func) config.add_default_key_binding_by_keymap(:vi_command, key, func) end end def input=(val) @input = val end def output=(val) @output = val end def with_raw_input if @input.tty? @input.raw(intr: true) { yield } else yield end end def inner_getc(timeout_second) unless @buf.empty? return @buf.shift end until @input.wait_readable(0.01) timeout_second -= 0.01 return nil if timeout_second <= 0 Reline.core.line_editor.handle_signal end c = @input.getbyte (c == 0x16 && @input.tty? && @input.raw(min: 0, time: 0, &:getbyte)) || c rescue Errno::EIO # Maybe the I/O has been closed. nil end START_BRACKETED_PASTE = String.new("\e[200~", encoding: Encoding::ASCII_8BIT) END_BRACKETED_PASTE = String.new("\e[201~", encoding: Encoding::ASCII_8BIT) def read_bracketed_paste buffer = String.new(encoding: Encoding::ASCII_8BIT) until buffer.end_with?(END_BRACKETED_PASTE) c = inner_getc(Float::INFINITY) break unless c buffer << c end string = buffer.delete_suffix(END_BRACKETED_PASTE).force_encoding(encoding) string.valid_encoding? ? string : '' end # if the usage expects to wait indefinitely, use Float::INFINITY for timeout_second def getc(timeout_second) inner_getc(timeout_second) end def in_pasting? not empty_buffer? end def empty_buffer? unless @buf.empty? return false end !@input.wait_readable(0) end def ungetc(c) @buf.unshift(c) end def retrieve_keybuffer begin return unless @input.wait_readable(0.001) str = @input.read_nonblock(1024) str.bytes.each do |c| @buf.push(c) end rescue EOFError end end def get_screen_size s = @input.winsize return s if s[0] > 0 && s[1] > 0 s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i] return s if s[0] > 0 && s[1] > 0 [24, 80] rescue Errno::ENOTTY, Errno::ENODEV [24, 80] end def set_screen_size(rows, columns) @input.winsize = [rows, columns] self rescue Errno::ENOTTY, Errno::ENODEV self end def cursor_pos if both_tty? res = +'' m = nil @input.raw do |stdin| @output << "\e[6n" @output.flush loop do c = stdin.getc next if c.nil? res << c m = res.match(/\e\[(?\d+);(?\d+)R/) break if m end (m.pre_match + m.post_match).chars.reverse_each do |ch| stdin.ungetc ch end end column = m[:column].to_i - 1 row = m[:row].to_i - 1 else begin buf = @output.pread(@output.pos, 0) row = buf.count("\n") column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0 rescue Errno::ESPIPE, IOError # Just returns column 1 for ambiguous width because this I/O is not # tty and can't seek. row = 0 column = 1 end end Reline::CursorPos.new(column, row) end def both_tty? @input.tty? && @output.tty? end def move_cursor_column(x) @output.write "\e[#{x + 1}G" end def move_cursor_up(x) if x > 0 @output.write "\e[#{x}A" elsif x < 0 move_cursor_down(-x) end end def move_cursor_down(x) if x > 0 @output.write "\e[#{x}B" elsif x < 0 move_cursor_up(-x) end end def hide_cursor seq = "\e[?25l" if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported? begin seq = Reline::Terminfo.tigetstr('civis') rescue Reline::Terminfo::TerminfoError # civis is undefined end end @output.write seq end def show_cursor seq = "\e[?25h" if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported? begin seq = Reline::Terminfo.tigetstr('cnorm') rescue Reline::Terminfo::TerminfoError # cnorm is undefined end end @output.write seq end def erase_after_cursor @output.write "\e[K" end # This only works when the cursor is at the bottom of the scroll range # For more details, see https://github.com/ruby/reline/pull/577#issuecomment-1646679623 def scroll_down(x) return if x.zero? # We use `\n` instead of CSI + S because CSI + S would cause https://github.com/ruby/reline/issues/576 @output.write "\n" * x end def clear_screen @output.write "\e[2J" @output.write "\e[1;1H" end def set_winch_handler(&handler) @old_winch_handler = Signal.trap('WINCH', &handler) @old_cont_handler = Signal.trap('CONT') do @input.raw!(intr: true) if @input.tty? # Rerender the screen. Note that screen size might be changed while suspended. handler.call end rescue ArgumentError # Signal.trap may raise an ArgumentError if the platform doesn't support the signal. end def prep # Enable bracketed paste @output.write "\e[?2004h" if Reline.core.config.enable_bracketed_paste && both_tty? retrieve_keybuffer nil end def deprep(otio) # Disable bracketed paste @output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste && both_tty? Signal.trap('WINCH', @old_winch_handler) if @old_winch_handler Signal.trap('CONT', @old_cont_handler) if @old_cont_handler end end PK!h?n$n$LC_MESSAGES/iso_3166-1.monu[\    *2 8B JU ]hqy  &.7@GVotz    ' 0>]bjq      !) /9> FRY_gmt {        ) 4>FMU\ e p{     !*07HQl q}   * 0; Q^f m x        )27?EYa hu   &-6E ?JR Zfmt|     + 4B&Kr      %+3<QYaj|     %/8 ?LSY blu}       " * 0 > G S ^ e n v {             ! !! !! .!8!>!F!K! Z!h!q!v!!!!!!!!!! !!!" """ 0"<"S"m" s"~" """" """""" " # # #### +#6#=#D# X#c#l#u#z##### ####### $ $ $ $ ($2$:$Q$W$^$g$QAl%{5VGh (z 8+9f^Uqig\O_C`)] PEJk0,21D*yc'jF/oe>~4v;WX 3t:}&rb7N=!pxSK.|T[#Z6mR <suY ?L@"Iw$naB-MHdAfghanistanAlbaniaAlgeriaAmerican SamoaAndorraAngolaAnguillaAntigua and BarbudaArgentinaArmeniaArubaAustraliaAustriaAzerbaijanBahrainBangladeshBarbadosBelarusBelgiumBelizeBeninBermudaBhutanBoliviaBosnia and HerzegovinaBotswanaBouvet IslandBrazilBritish Indian Ocean TerritoryBritish Virgin IslandsBulgariaBurkina FasoBurundiCambodiaCameroonCanadaCayman IslandsCentral African RepublicChadChileColombiaComorosCook IslandsCosta RicaCroatiaCubaCyprusCzech RepublicDenmarkDjiboutiDominicaDominican RepublicEcuadorEgyptEl SalvadorEquatorial GuineaEritreaEthiopiaFaroe IslandsFederated States of MicronesiaFijiFinlandFranceFrench PolynesiaGabonGeorgiaGermanyGhanaGibraltarGreeceGreenlandGrenadaGuadeloupeGuamGuatemalaGuernseyGuineaGuinea-BissauGuyanaHaitiHondurasHong KongHungaryIcelandIndiaIndonesiaIraqIrelandIsle of ManIsraelItalyJamaicaJapanJerseyJordanKazakhstanKenyaKiribatiKuwaitKyrgyzstanLatviaLebanonLesothoLiberiaLibyaLiechtensteinLithuaniaLuxembourgMadagascarMalawiMalaysiaMaldivesMaliMaltaMartiniqueMauritaniaMauritiusMayotteMexicoMoldovaMonacoMongoliaMontenegroMontserratMoroccoMozambiqueMyanmarNamibiaNauruNepalNetherlandsNew CaledoniaNew ZealandNicaraguaNigerNigeriaNiueNorfolk IslandNorthern Mariana IslandsNorwayOmanPakistanPalauPanamaPapua New GuineaParaguayPeople's Republic of ChinaPeruPhilippinesPolandPortugalPuerto RicoQatarRepublic of the CongoRomaniaRwandaRéunionSaint Kitts and NevisSaint LuciaSaint Pierre and MiquelonSaint Vincent and the GrenadinesSamoaSan MarinoSao Tome and PrincipeSaudi ArabiaSenegalSerbiaSeychellesSierra LeoneSingaporeSlovakiaSloveniaSolomon IslandsSomaliaSouth AfricaSouth SudanSpainSri LankaSudanSurinameSwazilandSwedenSwitzerlandTaiwanTajikistanTanzaniaThailandTogoTokelauTongaTrinidad and TobagoTunisiaTurkeyTurkmenistanTurks and Caicos IslandsTuvaluUgandaUkraineUnited Arab EmiratesUnited KingdomUnited States of AmericaUruguayUzbekistanVanuatuVenezuelaVietnamWallis and FutunaYemenZambiaZimbabweÅland IslandsProject-Id-Version: iso_3166-1 Report-Msgid-Bugs-To: https://salsa.debian.org/iso-codes-team/iso-codes/issues POT-Creation-Date: 2018-01-17 22:10+0100 PO-Revision-Date: 2017-12-29 07:00+0000 Last-Translator: Chris Leonard Language-Team: Ido Language: io MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; X-Generator: Weblate 2.19-dev AfganistanAlbaniaAljeriaUsana SamoaAndoraAngolaAnguilaAntigua e BarbudaArjentiniaArmeniaArubaAustraliaAustriaAzerbaijanBahrainBangladeshBarbadosBielorusiaBelgiaBelizeBeninBermudaBhutanBoliviaBosnia e HerzegovinaBotswanaBouvet InsuloBraziliaBritaniana teritorio en Indiana OceanoVirgin-Insuli BritanaBulgariaBurkina FasoBurundiKambodjaKamerunKanadaKaiman-InsuliCentrafrikaChadChiliKolumbiaKomoriCook-InsuliKosta RikaKroatiaKubaChiproChekiaDaniaDjibutiDominikaDominikana RepublikoEquadorEgiptiaSalvadorEquatorala GuineaEritreaEtiopiaFaeroFederata Stati di MikroneziaFidjiFinlandoFranciaFranca PolineziaGabonGruziaGermaniaGhanaGibraltarGrekiaGrenlandoGrenadaGuadelupaGuamGuatemalaGuernseyGuineaGuinea BisauGuyanaHaitiHondurasHong KongHungariaIslandoIndiaIndoneziaIrakRepubliko di IrlandoMan-InsuloIsraelItaliaJamaikaJaponiaJerseyJordaniaKazakstanKeniaKiribatiKuwaitKirgizistanLatviaLibanoLesothoLiberiaLibiaLiechtensteinLituaniaLuxemburgiaMadagaskarMalawiMalaiziaMaldiviMaliMaltaMartinikMauritaniaMauricoMayotteMexikiaMoldovaMonakoMongoliaMontenegroMontserratMarokoMozambikMyanmarNamibiaNauruNepalNederlandoNova-KaledoniaNova-ZelandoNikaraguaNijerNigeriaNiueNorfolk-insuloNorda MarianiNorvegiaOmanPakistanPalauPanamaPapua-Nova-GuineaParaguayPopulala Republiko di ChiniaPeruFilipiniPoloniaPortugalPortuo RikoKatarRepubliko KongoRumaniaRuandaReunionSanta Kitts e NevisSanta LuciaSanta Pierre e MikelonSanta Vincent e GrenadiniSamoaSan-MarinoSan-Tome e PrincipeSaudi-ArabiaSenegalSerbiaSeycheliSierra LeoneSingapurSlovakiaSloveniaInsuli SalomonSomaliaSudafrikaSud-SudanHispaniaSri-LankaSudanSurinamSwazilandoSuediaSuisiaRepubliko di ChiniaTajikistanTanzaniaTailandoTogoTokelauTongaTrinidad e TobagoTuniziaTurkiaTurkmenistanTurks e Kaikos-InsuliTuvaluUgandaUkrainiaUnionita Araba EmiratiUnionita RejioUsaUruguayUzbekistanVanuatuVenezuelaVietnamWallis e Futuna InsuliYemenZambiaZimbabweAlandoPK!I.X.XLC_MESSAGES/gtk20.monu[] 8F9"",  $ + 6 @7a)4=6;'D$l()  "# !D 0f 9 6 !$!3-!a!z!!!!!!! !"!""";"C" J"U"[" k" w" " """""""*")#+I#u###$##1#-.$\$"r$$$$$$%% %*% 2% ?%K%S% \%&j%%%%%%$%&;&[& {&&&N&&&'1'E'#c''''"''(3(M(m(((8(8(1)I) N)Z)n) t)~)))) ) )))))) )**5*K*`* u* * *****+ +++3+:+B+_+h+l+t+++>+++, ,, , $,/,>, C, Q, \, f, p,z, ,=, , ,,!, -/- 7-B-R-d-u- {- - - -- -- - --- . . !. ..9.?. N. \.i... ....../ ./:/ O/Y/`/t/|///// //L/"040G0N0/S0000 00>0"151T1i1~11111'12&2=2S2h26}222!h333 v4 44 4 44 4!4"451585U5 \5 h5%r55 55555566-626D6L6S6 \6h6q6z6 6 666666 666 66 6 67 7 !7.7 67 A7K7Q7Y7k7 s7777 777 777777788 8(8 >8 J8U8Z8]8 b8l8{{8F9!>:!`:*:: : :: : :$;0';X;6t;@;;;.;.'<3V<3< <<!<"<!=-?=m= v=;=6===4=3>J>P> W>c>j>'s>$>%> >?&? .? 8?D?K? ^?j?z? ? ?? ? ???5?6-@/d@@@@#@A0$A)UAA"A AA!A B3BJBRBiB}BBB B BB&BB$B##CGCcC.wC&C)C*C "D-DGDNMD+DDDD"E8E!RE tE"EEEE)F$-FRFnF;F;FF GG0G IGSG [G hGtG{G G GGGGGGGHH8HPHiH H HHHHHII#I2I8IUI[IbI|IIIIII@I#J (J3JO1GOyOOO OO7O&O!P?PVPmPPPPP)P Q#Q *)UJIE6[0.7/&]Q+N'#Ai9:y c5;N ?G .ubD 3n)R _SO!%z=sI\74"SV-3X~oYWP&EqK(;r(0Q$K4'9Pfw=1[>tXBLTxBHJWV]D8*#gZ@eCML1/"{, "%s" could not be converted to a value of type "%s" for attribute "%s""%s" is not a valid attribute name"%s" is not a valid attribute type"%s" is not a valid value for attribute "%s""Deepness" of the color.%1$s on %2$s%s job #%d(None)(disabled)(unknown)<%s> element has invalid id "%s"<%s> element has neither a "name" nor an "id" attributeA <%s> element has already been specifiedA element can't occur before a elementA file named "%s" already exists. Do you want to replace it?A_t:About %sAdd the current folder to the bookmarksAdd the folder '%s' to the bookmarksAdd the selected folder to the BookmarksAdd the selected folders to the bookmarksAll sheetsAmharic (EZ+)Amount of blue light in the color.Amount of green light in the color.Amount of red light in the color.Anonymous tag found and tags can not be created.ApplicationArtwork byAttribute "%s" is invalid on <%s> element in this contextAttribute "%s" repeated twice on the same <%s> elementAxesBe_fore:Both "id" and "name" were found on the <%s> elementBrightness of the color.CLASSCOLORSC_ollateC_reateC_reditsCache file created successfully. Cannot allocate colormap entriesCannot allocate colormap structureCannot allocate new pixbufCannot read XPM colormapCedillaCl_earClassifiedColorColor SelectionColor WheelColor _name:Command LineConfidentialCopie_s:CopiesCopy URLCopy _LocationCould not add a bookmarkCould not clear listCould not get image height (bad TIFF file)Could not get image width (bad TIFF file)Could not get information for file '%s': %sCould not mount %sCould not remove bookmarkCould not remove itemCould not rename %s back to %s: %s. Could not rename %s to %s: %s Could not rename %s to %s: %s, removing %s then. Could not retrieve information about the fileCould not select fileCould not start the search processCouldn't convert filenameCouldn't create new pixbufCouldn't write to BMP fileCreate Fo_lderCreate in _folder:CreditsCustom Size %dCustom sizeDISPLAYDe_lete FileDelete FileDesktopDisabledDocumented byElement <%s> is not allowed below <%s>EmptyError creating folder '%s': %sError deleting file '%s': %sError loading icon: %sError printingError renaming file "%s" to "%s": %sError renaming file "%s": %sError renaming file to "%s": %sError writing to image file: %sEven sheetsExcess data in fileFLAGSFailed to close '%s' while writing image, all data may not have been saved: %sFailed to load RGB data from TIFF fileFailed to load TIFF imageFailed to load iconFailed to load image '%s': %sFailed to open '%s' for writing: %sFailed to open TIFF imageFailed to open file '%s': %sFailed to open temporary fileFailed to read from temporary fileFailed to rewrite header Failed to save TIFF imageFailed to write TIFF dataFailed to write cache file: %s Failed to write folder index Failed to write hash table Failed to write header Failed to write to temporary file when loading XBM imageFailed to write to temporary file when loading XPM imageFailure reading GIF: %sFileFile SystemFile not found: %s FilesFinishingFol_dersFoldersFontFont SelectionFull VolumeGTK+ OptionsGammaGeneralHighIcon has zero heightIcon has zero widthImage QualityImage format unknownImage has unsupported bppImage has zero heightImage has zero widthImage header corruptImage type '%s' is not supportedInvalid URIInvalid UTF-8Invalid XBM fileInvalid file nameInvalid header in animationInvalid header in iconJobJob DetailsKeysLRM _Left-to-right markLayoutLicenseLoad additional GTK+ modulesLocationLowMODULESManage Custom SizesManage Custom Sizes...Margins from Printer...Margins: Left: %s %s Right: %s %s Top: %s %s Bottom: %s %sMediumModifiedMutedNAMENameName too longNew FolderNo items foundNoneNot availableOdd sheetsOne SidedOp_acity:Open '%s'Other...Out of paperOutermost element in text must be not <%s>Output TrayOutput t_ray:PDFPNM file has an image height of 0PNM file has an image width of 0Page %uPage SetupPages Per SheetPages per _sheet:Pages per _side:PaperPaper MarginsPaper SizePaper SourcePaper TypePaper _source:Paper _type:PausedPick a ColorPick a FontPlacesPosition on the color wheel.PostscriptPreparingPreparing %dPri_ority:PrintPrint DocumentPrint to FilePrint to LPRPrint to Test PrinterPrinterPrinter offlinePrinting %dRLM _Right-to-left markReally delete file "%s"?Received invalid color data RemoveRemove the bookmark '%s'Remove the selected bookmarkRename FileRename file "%s" to:Rename...SCREENSame as --no-wintabSans 12Save in _folder:Sc_ale:ScreenSearchSecretSelect A FileSerialized data is malformedSerialized data is malformed. First section isn't GTKTEXTBUFFERCONTENTS-0001Show GTK+ OptionsShow _Hidden FilesSi_ze:SizeSpecify one or more page ranges, e.g. 1-3,7,11StandardStatusTIFFClose operation failedT_wo-sided:Tag "%s" already definedTag "%s" does not exist in buffer and tags can not be created.Tag "%s" has invalid priority "%s"Tag "%s" has not been defined.The ANI image formatThe BMP image formatThe GIF image formatThe ICO image formatThe JPEG image formatThe PCX image formatThe PNG image formatThe PNM/PBM/PGM/PPM image format familyThe TIFF image formatThe Targa image formatThe WBMP image formatThe XBM image formatThe XPM image formatThe attribute "%s" was found twice on the <%s> elementThe folder could not be createdThe folder could not be created, as a file with the same name already exists. Try using a different name for the folder, or rename the file first.The generated cache was invalid. The license of the programThe previously-selected color, for comparison to the color you're selecting now. You can drag this color to a palette entry, or select this color as current by dragging it to the other color swatch alongside.Top SecretTranslated byTransparency of the color.Two SidedUnclassifiedUnknownUnknown itemUnsupported JPEG color space (%s)Unsupported depth for ICO file: %dUnsupported icon typeUrgentValidate existing icon cacheVolumeVolume DownVolume UpWidth or height of TIFF image is zeroWindowWritten byX _tilt:X display to useX screen to useXPM file has image height <= 0XPM file has image width <= 0Y t_ilt:Yesterday at %H:%M_Add_Add to Bookmarks_After:_Blue:_Bottom:_Clear List_Device:_Family:_Files_Folder name:_Gamma value_Green:_Height:_Hue:_Left:_License_Location:_Mode:_Name:_New Folder_Now_Only print:_Orientation:_Output format_Palette:_Paper size:_Places_Pressure:_Preview:_Red:_Remove_Remove From List_Rename_Rename File_Replace_Reverse_Right:_Saturation:_Save color here_Save in folder:_Selection: _Style:_Top:_Value:_Wheel:_Width:_X:_Y:abcdefghijk ABCDEFGHIJKcalendar:MYcalendar:week_start:0default:LTRdefault:mminchmmnoneoutput.%stest-output.%sProject-Id-Version: gtk+ 2.12.1 Report-Msgid-Bugs-To: POT-Creation-Date: 2010-06-10 11:56-0400 PO-Revision-Date: 2007-09-22 14:13-0500 Last-Translator: Michael Terry Language-Team: Ido Language: io MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; "%s" ne povis esar konvertita ad valoro de tipo "%s" por atributo "%s""%s" ne es valida atributala nomo"%s" ne es valida atributala tipo"%s" ne es valida valoro por atributo "%s""Profundeso" di la koloro.%1$s an %2$s%s tasko #%d(Nula)(nekapabla)(nekonocata)<%s>-elemento havas invalida id "%s"<%s>-elemento havas nek "name" nek "id" atributo<%s>-elemento ja specigabas-elemento ne povas eventar avane -elementoDokumento nomizita "%s" ja existas. Ka vu deziras remplasar ol?A_d:Pri %sAdjuntez la nuna dokumentuyo a la markorubandiAdjuntez la dokumentuyo '%s' a la markorubandiAdjuntez la selektata dokumentuyo a la MarkorubandiAdjuntez la selektata dokumentuyi a la markorubandiOmna foliiAmharala (EZ+)Quanto de blua lumo en la koloro.Quanto de verda lumo en la koloro.Quanto de reda lumo en la koloro.Anomima tago trovis ed tagi ne povas kreesar.ProgramoArtaji daAtributo "%s" es nevalida sur <%s>-elemento en ica kuntextoAtributo "%s" repetis duople sur la sama <%s>-elementoAxi_Avan:Due "id" ed "name" esis trovita sur la <%s>-elementoLumozeso di la koloro.KLASOKOLORIK_olacionezK_reezK_reditiTrovajarala dokumento kreis sucesante. Ne povas asignar koloromapa elementiNe povas asignar koloromapa strukturoNe povas asignar nova imajobufroNe povas lektar XPM-koloromapoCedilio_VakuigezKlasifikitaKoloroKolorala SelektajoKolora RotoKolorala _nomo:Imperala LineoKonfidencala_Kopiuri:KopiuriKopiez URLKopiez _LokoNe povis adjuntar markorubandoNe povis vakuigez listoNe povis aquirar imajala alteso (mala TIFF dokumento)Ne povis aquirar imajala larjeso (mala TIFF dokumento)Ne povis aquirar informo pri dokumento '%s': %sNe povis acensar %sNe povis forigar markorubandoNe povis forigar elementoNe povis retronomizar %s a %s: %s. Ne povis rinomizar %s a %s: %s No povis rinomizar %s ad %s: %s, do forigas %s. Ne povis aquirar informo pri la dokumentoNe povis selektar dokumentoNe povis startar la sercha procedoNe povis konvertar dokumentonomoNe povis krear nova imajobufroNe povis skribar ad BMP-dokumentoKreez _DokumentuyoKreez en _dokumentuyo:KreditiDesnormala Grandeso %dDesnormala grandesoVIDIGILO_Efacez DokumentoEfacez DokumentoPupitrosuproNekapablaDokumentizita daElemento <%s> ne es permisata sub <%s>VakuaEroro dum kreas dokumentuyo '%s': %sEroro dum efacas dokumento '%s': %sEroro dum charjas ikono: %sEroro dum imprimadoEroro dum rinomizas dokumento "%s" ad "%s": %sEroro dum rinomizas dokumento "%s": %sEroro dum rinomizas dokumento ad "%s": %sEroro dum skribas ad imajala dokumento: %sPara foliiEcesa donaji en dokumentoFLAGIFaliis klozar '%s' dum skribas imajo, omna donaji forsan ne esabas salvita: %sFaliis charjar RVB-donaji de TIFF-dokumentoFaliis charjar TIFF-imajoFaliis charjar ikonoFaliis apertar imajo '%s': %sFaliis apertar '%s' por skribo: %sFaliis apertar TIFF-imajoFaliis apertar dokumento '%s': %sFaliis apertar tempala dokumentoFaliis lektar de tempala dokumentoFaliis riskribar kapo Faliis salvar TIFF-imajoFaliis skribar TIFF-donajiFaliis skribar trovajarala dokumento: %s Faliis skribar dokumentuyala indexo Faliis skribar hachotabelo Faliis skribar kapo Faliis skribar a tempala dokumento dum ke charjis XBM-imajoFaliis skribar a tempala dokumento dum ke charjis XPM-imajoEroro dum lektas GIF: %sDokumentoDokumenta SistemoDokumento netrovita: %s DokumentiFinanta_DokumentuyiDokumentuyiTiparoTiparala SelektajoPlena LautesoGTK+ SelektiLumozesoGeneralaAltaIkono havas zera altesoIkono havas zera larjesoImajala QualesoImajala formato nekonocataImajo havas nesuportata bppImajo havas zera altesoImajo havas zera larjesoImajala kapo es koruptitaImajala tipo '%s' es nesuportataNevalida URINevalida UTF-8Nevalida XBM-dokumentoNevalida dokumenta nomoNevalida kapo en animoNevalida kapo en ikonoTaskoTaskala DetaliKlaviLRM _Sinistra-a-dextra markoTrasoYurizoCharjez plusa GTK+-moduliLokoBasaMODULIDirektez Desnormala GrandesiDirektez Desnormala Grandesi...Marjini de Imprimilo...Marjini: Sinistra: %s %s Dextra: %s %s Supra: %s %s Infra: %s %sMezaModifikitaTacigataNOMONomoNomo tro longaNova DokumentuyoNula elemteni trovitaNulaNedisponeblaNepara foliiUnlateraOp_akeso:Apertez '%s'Altra...Ne plusa paperoMaxim extera elemento en texto mustas esar ne <%s>Produkturala PletoProdukturala _pleto:PDFPNM dokumento havas imajala alteso de 0PNM dokumento havas imajala larjeso de 0Pagino %uPagina EstablisoPagini Po FolioPagini po _folio:Pagini po _latero:PaperoPaperala MarjiniPaperala GrandesoPaperala FontoPaperala TipoPaperala _fonto:Paperala _tipo:PauzitaSelektez KoloroSelektez TiparoLokiLoko en la kolora roto.PosskribajoPreparasPreparas %dPri_oreso:ImprimezImprimez DokumentoImprimez a DokumentoImprimez a LPRImprimez a Testa ImprimiloImprimiloImprimilo es deskonectataImprimas %dRLM _Dextra-a-sinistra markoReale efacar dokumento "%s"?Recevis nevalida kolorala donaji ForigezForigez la markorubando '%s'Forigez la selektata markorubandoRinomizez DokumentoRinomizez dokumento "%s" ad:Rinomizez...SKRENOSama kam --no-wintabSen 12Salvez en _dokumentuyo:Sk_alo:SkrenoSerchezSekretaSelektez DokumentoSeriigata donaji es misformaSeriigata donaji es misforma. Unesma seciono ne es GTKTEXTBUFFERCONTENTS-0001Montrez GTK+ SelectiMontrez _Celita Dokumenti_Grandeso:GrandesoSpecigez un o plu pagina rangi, exemple 1-3,7,11NormalaStandoTIFFClose-operaco faliis_Dulatera:Tago "%s" ja definitaTago "%s" ne existas en bufro ed tagi ne povas kreesar.Tago "%s" havas nevalida prioreso "%s"Tago "%s" ne esabas definita.La ANI imajala formatoLa BMP imajala formatoLa GIF imajala formatoLa ICO imajala formatoLa JPEG imajala formatoLa PCX imajala formatoLa PNG imajala formatoLa PNM/PBM/PGM/PPM-imajoformatala familioLa TIFF imajala formatoLa Targa imajala formatoLa WBMP imajala formatoLa XBM imajala formatoLa XPM imajala formatoLa atributo "%s" esis trovita duople sur la <%s>-elementoLa dokumentuyo ne povis kreesarLa dokumentuyo ne povis kreesar, pro ke dokumento kun la sama nomo ja existas. Esforcez uzar diferanta nomo por la dokumentuyo, od rinomizez la dokumento unesme.La genitita trovajaro esis nevalida. La yurizo di la programoLa exselektita koloro, por komparado a la koloro ke vu selectas nun. Vu povas tranar ica koloro a piktoplanketa elemento, o selectez ica koloro kom nuna per tranas ol a la altra koloromakulo flanke.Maxim SekretaTradukita daDiafaneso di la koloro.DulateraNeklasifikitaNekonocataNekonocata elementoNesuportat JPEG-kolorospaco (%s)Nesuportata profundeso por ICO-dokumento: %dNesuportata ikonala tipoUrjantaValidigez existanta ikonala trovajaroLautesoLauteso InfreLauteso SupreLarjeso od alteso di TIFF imajo es zeroFenestroSkribita da_X-inklino:X-vidigilo uzotaX-skreno uzotaXPM dokumento havas imajala alteso <= 0XPM dokumento havas imajala larjeso <= 0_Y-inklino:Hiere ad %H:%M_Adjuntez_Adjuntez a markorubandi_Dop:_Bluo:_Bazo:_Vakuigez Listo_Aparato:_Familio:_Dokumenti_Dokumentuya nomo:_Lumozesa valoro_Verdo:_Alteso:_Kolornuanco:_Sinistra:_Yurizo_Loko:_Modo:_Nomo:_Nova Dokumentuyo_Nun_Nur imprimez:_Orientizeso:_Produkturala formato_Piktoplanketo:_Paperala grandeso:_Loki_Presado:_Prevido:_Redo:_Forigez_Forigez de Listo_Rinomizez_Rinomizez Dokumento_Remplasez_Inversigez_Dextra:_Saturajo:_Salvez koloro hike_Salvez en dokumentuyo:_Selektajo:_Stilo:_Suprajo:_Valoro:_Roto:_Largeso:_X:_Y:abcdefghijk ABCDEFGHIJKcalendar:YMcalendar:week_start:1default:LTRdefault:mminchmmnulaprodukturo.%stesta-produkturo.%sPK!ooLC_MESSAGES/gdk-pixbuf.monu[:O "=X*q)N0&#9"Wz88 8Mav   !5 W x        '' O e |   ! "  % = \ z $0 %U {  5 6 (!G*iN+)C"a! ";8;t1Ib |'( 3Lcz)0Iax ,''(F ,0.1+!()564& 83 "' : -/%79$#2*Cannot allocate colormap entriesCannot allocate colormap structureCannot allocate new pixbufCannot read XPM colormapCould not get image height (bad TIFF file)Could not get image width (bad TIFF file)Couldn't create new pixbufCouldn't write to BMP fileError writing to image file: %sExcess data in fileFailed to close '%s' while writing image, all data may not have been saved: %sFailed to load RGB data from TIFF fileFailed to load TIFF imageFailed to load image '%s': %sFailed to open '%s' for writing: %sFailed to open TIFF imageFailed to open file '%s': %sFailed to open temporary fileFailed to read from temporary fileFailed to save TIFF imageFailed to write TIFF dataFailed to write to temporary file when loading XBM imageFailed to write to temporary file when loading XPM imageFailure reading GIF: %sIcon has zero heightIcon has zero widthImage format unknownImage has unsupported bppImage has zero heightImage has zero widthImage header corruptImage type '%s' is not supportedInvalid XBM fileInvalid header in animationInvalid header in iconPNM file has an image height of 0PNM file has an image width of 0TIFFClose operation failedThe ANI image formatThe BMP image formatThe GIF image formatThe ICO image formatThe JPEG image formatThe PCX image formatThe PNG image formatThe PNM/PBM/PGM/PPM image format familyThe TIFF image formatThe Targa image formatThe WBMP image formatThe XBM image formatThe XPM image formatUnsupported JPEG color space (%s)Unsupported depth for ICO file: %dUnsupported icon typeWidth or height of TIFF image is zeroXPM file has image height <= 0XPM file has image width <= 0Project-Id-Version: gtk+ 2.12.1 Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gdk-pixbuf POT-Creation-Date: 2012-02-04 18:44-0500 PO-Revision-Date: 2007-09-22 14:13-0500 Last-Translator: Michael Terry Language-Team: Ido Language: io MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; Ne povas asignar koloromapa elementiNe povas asignar koloromapa strukturoNe povas asignar nova imajobufroNe povas lektar XPM-koloromapoNe povis aquirar imajala alteso (mala TIFF dokumento)Ne povis aquirar imajala larjeso (mala TIFF dokumento)Ne povis krear nova imajobufroNe povis skribar ad BMP-dokumentoEroro dum skribas ad imajala dokumento: %sEcesa donaji en dokumentoFaliis klozar '%s' dum skribas imajo, omna donaji forsan ne esabas salvita: %sFaliis charjar RVB-donaji de TIFF-dokumentoFaliis charjar TIFF-imajoFaliis apertar imajo '%s': %sFaliis apertar '%s' por skribo: %sFaliis apertar TIFF-imajoFaliis apertar dokumento '%s': %sFaliis apertar tempala dokumentoFaliis lektar de tempala dokumentoFaliis salvar TIFF-imajoFaliis skribar TIFF-donajiFaliis skribar a tempala dokumento dum ke charjis XBM-imajoFaliis skribar a tempala dokumento dum ke charjis XPM-imajoEroro dum lektas GIF: %sIkono havas zera altesoIkono havas zera larjesoImajala formato nekonocataImajo havas nesuportata bppImajo havas zera altesoImajo havas zera larjesoImajala kapo es koruptitaImajala tipo '%s' es nesuportataNevalida XBM-dokumentoNevalida kapo en animoNevalida kapo en ikonoPNM dokumento havas imajala alteso de 0PNM dokumento havas imajala larjeso de 0TIFFClose-operaco faliisLa ANI imajala formatoLa BMP imajala formatoLa GIF imajala formatoLa ICO imajala formatoLa JPEG imajala formatoLa PCX imajala formatoLa PNG imajala formatoLa PNM/PBM/PGM/PPM-imajoformatala familioLa TIFF imajala formatoLa Targa imajala formatoLa WBMP imajala formatoLa XBM imajala formatoLa XPM imajala formatoNesuportat JPEG-kolorospaco (%s)Nesuportata profundeso por ICO-dokumento: %dNesuportata ikonala tipoLarjeso od alteso di TIFF imajo es zeroXPM dokumento havas imajala alteso <= 0XPM dokumento havas imajala larjeso <= 0PK!,:<< __init__.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # fix xmlplus to be compatible with the python xml sax parser and python 3 # by adding __contains__ to xml.sax.xmlreader.AttributesImpl import xml if "_xmlplus" in xml.__file__: from xml.sax.xmlreader import AttributesImpl if not hasattr(AttributesImpl, "__contains__"): # this is missing: def __AttributesImpl__contains__(self, name): return name in getattr(self, "_attrs") # add it using the name __contains__ setattr(AttributesImpl, "__contains__", __AttributesImpl__contains__) from xml.sax.saxutils import XMLGenerator if not hasattr(XMLGenerator, "_write"): # this is missing: def __XMLGenerator_write(self, text): getattr(self, "_out").write(text) # add it using the name _write setattr(XMLGenerator, "_write", __XMLGenerator_write) PK!/ helper.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # __all__ = [ "Helper", "helper_reader", "helper_writer" ] import xml.sax as sax import os import io import shutil from firewall import config from firewall.functions import u2b_if_py2 from firewall.core.io.io_object import PY2, IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \ check_tcpudp from firewall.core.logger import log from firewall import errors from firewall.errors import FirewallError class Helper(IO_Object): IMPORT_EXPORT_STRUCTURE = ( ( "version", "" ), # s ( "short", "" ), # s ( "description", "" ), # s ( "family", "", ), # s ( "module", "", ), # s ( "ports", [ ( "", "" ), ], ), # a(ss) ) DBUS_SIGNATURE = '(sssssa(ss))' ADDITIONAL_ALNUM_CHARS = [ "-", "." ] PARSER_REQUIRED_ELEMENT_ATTRS = { "short": None, "description": None, "helper": [ "module" ], } PARSER_OPTIONAL_ELEMENT_ATTRS = { "helper": [ "name", "version", "family" ], "port": [ "port", "protocol" ], } def __init__(self): super(Helper, self).__init__() self.version = "" self.short = "" self.description = "" self.module = "" self.family = "" self.ports = [ ] def cleanup(self): self.version = "" self.short = "" self.description = "" self.module = "" self.family = "" del self.ports[:] def encode_strings(self): """ HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.""" self.version = u2b_if_py2(self.version) self.short = u2b_if_py2(self.short) self.description = u2b_if_py2(self.description) self.module = u2b_if_py2(self.module) self.family = u2b_if_py2(self.family) self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports] def check_ipv(self, ipv): ipvs = [ 'ipv4', 'ipv6' ] if ipv not in ipvs: raise FirewallError(errors.INVALID_IPV, "'%s' not in '%s'" % (ipv, ipvs)) def _check_config(self, config, item, all_config): if item == "ports": for port in config: check_port(port[0]) check_tcpudp(port[1]) elif item == "module": if not config.startswith("nf_conntrack_"): raise FirewallError( errors.INVALID_MODULE, "'%s' does not start with 'nf_conntrack_'" % config) if len(config.replace("nf_conntrack_", "")) < 1: raise FirewallError(errors.INVALID_MODULE, "Module name '%s' too short" % config) # PARSER class helper_ContentHandler(IO_Object_ContentHandler): def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) self.item.parser_check_element_attrs(name, attrs) if name == "helper": if "version" in attrs: self.item.version = attrs["version"] if "family" in attrs: self.item.check_ipv(attrs["family"]) self.item.family = attrs["family"] if "module" in attrs: if not attrs["module"].startswith("nf_conntrack_"): raise FirewallError( errors.INVALID_MODULE, "'%s' does not start with 'nf_conntrack_'" % \ attrs["module"]) if len(attrs["module"].replace("nf_conntrack_", "")) < 1: raise FirewallError( errors.INVALID_MODULE, "Module name '%s' too short" % attrs["module"]) self.item.module = attrs["module"] elif name == "short": pass elif name == "description": pass elif name == "port": check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (attrs["port"], attrs["protocol"]) if entry not in self.item.ports: self.item.ports.append(entry) else: log.warning("Port '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) def helper_reader(filename, path): helper = Helper() if not filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % filename) helper.name = filename[:-4] helper.check_name(helper.name) helper.filename = filename helper.path = path helper.builtin = False if path.startswith(config.ETC_FIREWALLD) else True helper.default = helper.builtin handler = helper_ContentHandler(helper) parser = sax.make_parser() parser.setContentHandler(handler) name = "%s/%s" % (path, filename) with open(name, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_HELPER, "not a valid helper file: %s" % \ msg.getException()) del handler del parser if PY2: helper.encode_strings() return helper def helper_writer(helper, path=None): _path = path if path else helper.path if helper.filename: name = "%s/%s" % (_path, helper.filename) else: name = "%s/%s.xml" % (_path, helper.name) if os.path.exists(name): try: shutil.copy2(name, "%s.old" % name) except Exception as msg: log.error("Backup of file '%s' failed: %s", name, msg) dirpath = os.path.dirname(name) if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath): if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) os.mkdir(dirpath, 0o750) f = io.open(name, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start helper element attrs = {} attrs["module"] = helper.module if helper.version and helper.version != "": attrs["version"] = helper.version if helper.family and helper.family != "": attrs["family"] = helper.family handler.startElement("helper", attrs) handler.ignorableWhitespace("\n") # short if helper.short and helper.short != "": handler.ignorableWhitespace(" ") handler.startElement("short", { }) handler.characters(helper.short) handler.endElement("short") handler.ignorableWhitespace("\n") # description if helper.description and helper.description != "": handler.ignorableWhitespace(" ") handler.startElement("description", { }) handler.characters(helper.description) handler.endElement("description") handler.ignorableWhitespace("\n") # ports for port in helper.ports: handler.ignorableWhitespace(" ") handler.simpleElement("port", { "port": port[0], "protocol": port[1] }) handler.ignorableWhitespace("\n") # end helper element handler.endElement('helper') handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!Cc=== direct.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import xml.sax as sax import os import io import shutil from firewall import config from firewall.fw_types import LastUpdatedOrderedDict from firewall.functions import splitArgs, joinArgs, u2b_if_py2 from firewall.core.io.io_object import IO_Object, IO_Object_ContentHandler, \ IO_Object_XMLGenerator from firewall.core.logger import log from firewall.core import ipXtables from firewall.core import ebtables from firewall import errors from firewall.errors import FirewallError class direct_ContentHandler(IO_Object_ContentHandler): def __init__(self, item): IO_Object_ContentHandler.__init__(self, item) self.direct = False def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) self.item.parser_check_element_attrs(name, attrs) if name == "direct": if self.direct: raise FirewallError(errors.PARSE_ERROR, "More than one direct tag.") self.direct = True elif name == "chain": if not self.direct: log.error("Parse Error: chain outside of direct") return ipv = attrs["ipv"] table = attrs["table"] chain = attrs["chain"] self.item.add_chain(u2b_if_py2(ipv), u2b_if_py2(table), u2b_if_py2(chain)) elif name == "rule": if not self.direct: log.error("Parse Error: rule outside of direct") return ipv = attrs["ipv"] if ipv not in [ "ipv4", "ipv6", "eb" ]: raise FirewallError(errors.INVALID_IPV, "'%s' not from {'ipv4'|'ipv6'|'eb'}" % ipv) table = attrs["table"] chain = attrs["chain"] try: priority = int(attrs["priority"]) except ValueError: log.error("Parse Error: %s is not a valid priority" % attrs["priority"]) return self._rule = [ u2b_if_py2(ipv), u2b_if_py2(table), u2b_if_py2(chain), priority ] elif name == "passthrough": if not self.direct: log.error("Parse Error: command outside of direct") return ipv = attrs["ipv"] self._passthrough = [ u2b_if_py2(ipv) ] else: log.error('Unknown XML element %s' % name) return def endElement(self, name): IO_Object_ContentHandler.endElement(self, name) if name == "rule": if self._element: # add arguments self._rule.append([ u2b_if_py2(x) for x in splitArgs(self._element) ]) self.item.add_rule(*self._rule) else: log.error("Error: rule does not have any arguments, ignoring.") self._rule = None elif name == "passthrough": if self._element: # add arguments self._passthrough.append([ u2b_if_py2(x) for x in splitArgs(self._element) ]) self.item.add_passthrough(*self._passthrough) else: log.error("Error: passthrough does not have any arguments, " + "ignoring.") self._passthrough = None class Direct(IO_Object): """ Direct class """ IMPORT_EXPORT_STRUCTURE = ( # chain: [ ipv, table, [ chain ] ] ( "chains", [ ( "", "", "" ), ], ), # a(sss) # rule: [ ipv, table, chain, [ priority, [ arg ] ] ] ( "rules", [ ( "", "", "", 0, [ "" ] ), ], ), # a(sssias) # passthrough: [ ipv, [ [ arg ] ] ] ( "passthroughs", [ ( "", [ "" ]), ], ), # a(sas) ) DBUS_SIGNATURE = '(a(sss)a(sssias)a(sas))' PARSER_REQUIRED_ELEMENT_ATTRS = { "direct": None, "chain": [ "ipv", "table", "chain" ], "rule": [ "ipv", "table", "chain", "priority" ], "passthrough": [ "ipv" ] } PARSER_OPTIONAL_ELEMENT_ATTRS = { } def __init__(self, filename): super(Direct, self).__init__() self.filename = filename self.chains = LastUpdatedOrderedDict() self.rules = LastUpdatedOrderedDict() self.passthroughs = LastUpdatedOrderedDict() def _check_config(self, conf, item, all_conf): pass # check arg lists def export_config(self): ret = [ ] x = [ ] for key in self.chains: for chain in self.chains[key]: x.append(tuple(list(key) + list([chain]))) ret.append(x) x = [ ] for key in self.rules: for rule in self.rules[key]: x.append(tuple((key[0], key[1], key[2], rule[0], list(rule[1])))) ret.append(x) x = [ ] for key in self.passthroughs: for rule in self.passthroughs[key]: x.append(tuple((key, list(rule)))) ret.append(x) return tuple(ret) def import_config(self, conf): self.cleanup() self.check_config(conf) for i,(element,dummy) in enumerate(self.IMPORT_EXPORT_STRUCTURE): if element == "chains": for x in conf[i]: self.add_chain(*x) if element == "rules": for x in conf[i]: self.add_rule(*x) if element == "passthroughs": for x in conf[i]: self.add_passthrough(*x) def cleanup(self): self.chains.clear() self.rules.clear() self.passthroughs.clear() def output(self): print("chains") for key in self.chains: print(" (%s, %s): %s" % (key[0], key[1], ",".join(self.chains[key]))) print("rules") for key in self.rules: print(" (%s, %s, %s):" % (key[0], key[1], key[2])) for (priority,args) in self.rules[key]: print(" (%d, ('%s'))" % (priority, "','".join(args))) print("passthroughs") for key in self.passthroughs: print(" %s:" % (key)) for args in self.passthroughs[key]: print(" ('%s')" % ("','".join(args))) def _check_ipv(self, ipv): ipvs = ['ipv4', 'ipv6', 'eb'] if ipv not in ipvs: raise FirewallError(errors.INVALID_IPV, "'%s' not in '%s'" % (ipv, ipvs)) def _check_ipv_table(self, ipv, table): self._check_ipv(ipv) tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in ['ipv4', 'ipv6'] \ else ebtables.BUILT_IN_CHAINS.keys() if table not in tables: raise FirewallError(errors.INVALID_TABLE, "'%s' not in '%s'" % (table, tables)) # chains def add_chain(self, ipv, table, chain): self._check_ipv_table(ipv, table) key = (ipv, table) if key not in self.chains: self.chains[key] = [ ] if chain not in self.chains[key]: self.chains[key].append(chain) else: log.warning("Chain '%s' for table '%s' with ipv '%s' " % \ (chain, table, ipv) + "already in list, ignoring") def remove_chain(self, ipv, table, chain): self._check_ipv_table(ipv, table) key = (ipv, table) if key in self.chains and chain in self.chains[key]: self.chains[key].remove(chain) if len(self.chains[key]) == 0: del self.chains[key] else: raise ValueError( \ "Chain '%s' with table '%s' with ipv '%s' not in list" % \ (chain, table, ipv)) def query_chain(self, ipv, table, chain): self._check_ipv_table(ipv, table) key = (ipv, table) return (key in self.chains and chain in self.chains[key]) def get_chains(self, ipv, table): self._check_ipv_table(ipv, table) key = (ipv, table) if key in self.chains: return self.chains[key] else: raise ValueError("No chains for table '%s' with ipv '%s'" % \ (table, ipv)) def get_all_chains(self): return self.chains # rules def add_rule(self, ipv, table, chain, priority, args): self._check_ipv_table(ipv, table) key = (ipv, table, chain) if key not in self.rules: self.rules[key] = LastUpdatedOrderedDict() value = (priority, tuple(args)) if value not in self.rules[key]: self.rules[key][value] = priority else: log.warning("Rule '%s' for table '%s' and chain '%s' " % \ ("',".join(args), table, chain) + "with ipv '%s' and priority %d " % (ipv, priority) + "already in list, ignoring") def remove_rule(self, ipv, table, chain, priority, args): self._check_ipv_table(ipv, table) key = (ipv, table, chain) value = (priority, tuple(args)) if key in self.rules and value in self.rules[key]: del self.rules[key][value] if len(self.rules[key]) == 0: del self.rules[key] else: raise ValueError("Rule '%s' for table '%s' and chain '%s' " % \ ("',".join(args), table, chain) + \ "with ipv '%s' and priority %d not in list" % (ipv, priority)) def remove_rules(self, ipv, table, chain): self._check_ipv_table(ipv, table) key = (ipv, table, chain) if key in self.rules: for value in self.rules[key].keys(): del self.rules[key][value] if len(self.rules[key]) == 0: del self.rules[key] def query_rule(self, ipv, table, chain, priority, args): self._check_ipv_table(ipv, table) key = (ipv, table, chain) value = (priority, tuple(args)) return (key in self.rules and value in self.rules[key]) def get_rules(self, ipv, table, chain): self._check_ipv_table(ipv, table) key = (ipv, table, chain) if key in self.rules: return self.rules[key] else: raise ValueError("No rules for table '%s' and chain '%s' " %\ (table, chain) + "with ipv '%s'" % (ipv)) def get_all_rules(self): return self.rules # # passthrough # def add_passthrough(self, ipv, args): self._check_ipv(ipv) if ipv not in self.passthroughs: self.passthroughs[ipv] = [ ] if args not in self.passthroughs[ipv]: self.passthroughs[ipv].append(args) else: log.warning("Passthrough '%s' for ipv '%s'" % \ ("',".join(args), ipv) + "already in list, ignoring") def remove_passthrough(self, ipv, args): self._check_ipv(ipv) if ipv in self.passthroughs and args in self.passthroughs[ipv]: self.passthroughs[ipv].remove(args) if len(self.passthroughs[ipv]) == 0: del self.passthroughs[ipv] else: raise ValueError("Passthrough '%s' for ipv '%s'" % \ ("',".join(args), ipv) + "not in list") def query_passthrough(self, ipv, args): self._check_ipv(ipv) return ipv in self.passthroughs and args in self.passthroughs[ipv] def get_passthroughs(self, ipv): self._check_ipv(ipv) if ipv in self.passthroughs: return self.passthroughs[ipv] else: raise ValueError("No passthroughs for ipv '%s'" % (ipv)) def get_all_passthroughs(self): return self.passthroughs # read def read(self): self.cleanup() if not self.filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % self.filename) handler = direct_ContentHandler(self) parser = sax.make_parser() parser.setContentHandler(handler) with open(self.filename, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_TYPE, "Not a valid file: %s" % \ msg.getException()) def write(self): if os.path.exists(self.filename): try: shutil.copy2(self.filename, "%s.old" % self.filename) except Exception as msg: raise IOError("Backup of '%s' failed: %s" % (self.filename, msg)) if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) f = io.open(self.filename, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start whitelist element handler.startElement("direct", { }) handler.ignorableWhitespace("\n") # chains for key in self.chains: (ipv, table) = key for chain in self.chains[key]: handler.ignorableWhitespace(" ") handler.simpleElement("chain", { "ipv": ipv, "table": table, "chain": chain }) handler.ignorableWhitespace("\n") # rules for key in self.rules: (ipv, table, chain) = key for (priority, args) in self.rules[key]: if len(args) < 1: continue handler.ignorableWhitespace(" ") handler.startElement("rule", { "ipv": ipv, "table": table, "chain": chain, "priority": "%d" % priority }) handler.ignorableWhitespace(sax.saxutils.escape(joinArgs(args))) handler.endElement("rule") handler.ignorableWhitespace("\n") # passthroughs for ipv in self.passthroughs: for args in self.passthroughs[ipv]: if len(args) < 1: continue handler.ignorableWhitespace(" ") handler.startElement("passthrough", { "ipv": ipv }) handler.ignorableWhitespace(sax.saxutils.escape(joinArgs(args))) handler.endElement("passthrough") handler.ignorableWhitespace("\n") # end zone element handler.endElement("direct") handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!mifcfg.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # """ifcfg file parser""" __all__ = [ "ifcfg" ] import os.path import io import tempfile import shutil from firewall.core.logger import log from firewall.functions import b2u, u2b, PY2 class ifcfg(object): def __init__(self, filename): self._config = { } self._deleted = [ ] self.filename = filename self.clear() def clear(self): self._config = { } self._deleted = [ ] def cleanup(self): self._config.clear() def get(self, key): return self._config.get(key.strip()) def set(self, key, value): _key = b2u(key.strip()) self._config[_key] = b2u(value.strip()) if _key in self._deleted: self._deleted.remove(_key) def __str__(self): s = "" for (key, value) in self._config.items(): if s: s += '\n' s += '%s=%s' % (key, value) return u2b(s) if PY2 else s # load self.filename def read(self): self.clear() try: f = open(self.filename, "r") except Exception as msg: log.error("Failed to load '%s': %s", self.filename, msg) raise for line in f: if not line: break line = line.strip() if len(line) < 1 or line[0] in ['#', ';']: continue # get key/value pair pair = [ x.strip() for x in line.split("=", 1) ] if len(pair) != 2: continue if len(pair[1]) >= 2 and \ pair[1].startswith('"') and pair[1].endswith('"'): pair[1] = pair[1][1:-1] if pair[1] == '': continue elif self._config.get(pair[0]) is not None: log.warning("%s: Duplicate option definition: '%s'", self.filename, line.strip()) continue self._config[pair[0]] = pair[1] f.close() def write(self): if len(self._config) < 1: # no changes: nothing to do return # handled keys done = [ ] try: temp_file = tempfile.NamedTemporaryFile( mode='wt', prefix="%s." % os.path.basename(self.filename), dir=os.path.dirname(self.filename), delete=False) except Exception as msg: log.error("Failed to open temporary file: %s" % msg) raise modified = False empty = False try: f = io.open(self.filename, mode='rt', encoding='UTF-8') except Exception as msg: if os.path.exists(self.filename): log.error("Failed to open '%s': %s" % (self.filename, msg)) raise else: f = None else: for line in f: if not line: break # remove newline line = line.strip("\n") if len(line) < 1: if not empty: temp_file.write(u"\n") empty = True elif line[0] == '#': empty = False temp_file.write(line) temp_file.write(u"\n") else: p = line.split("=", 1) if len(p) != 2: empty = False temp_file.write(line+u"\n") continue key = p[0].strip() value = p[1].strip() if len(value) >= 2 and \ value.startswith('"') and value.endswith('"'): value = value[1:-1] # check for modified key/value pairs if key not in done: if key in self._config and self._config[key] != value: empty = False temp_file.write(u'%s=%s\n' % (key, self._config[key])) modified = True elif key in self._deleted: modified = True else: empty = False temp_file.write(line+u"\n") done.append(key) else: modified = True # write remaining key/value pairs if len(self._config) > 0: for (key, value) in self._config.items(): if key in done: continue if not empty: empty = True temp_file.write(u'%s=%s\n' % (key, value)) modified = True if f: f.close() temp_file.close() if not modified: # not modified: remove tempfile os.remove(temp_file.name) return # make backup if os.path.exists(self.filename): try: shutil.copy2(self.filename, "%s.bak" % self.filename) except Exception as msg: os.remove(temp_file.name) raise IOError("Backup of '%s' failed: %s" % (self.filename, msg)) # copy tempfile try: shutil.move(temp_file.name, self.filename) except Exception as msg: os.remove(temp_file.name) raise IOError("Failed to create '%s': %s" % (self.filename, msg)) else: os.chmod(self.filename, 0o600) PK!5 icmptype.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # __all__ = [ "IcmpType", "icmptype_reader", "icmptype_writer" ] import xml.sax as sax import os import io import shutil from firewall import config from firewall.functions import u2b_if_py2 from firewall.core.io.io_object import PY2, IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator from firewall.core.logger import log from firewall import errors from firewall.errors import FirewallError class IcmpType(IO_Object): IMPORT_EXPORT_STRUCTURE = ( ( "version", "" ), # s ( "short", "" ), # s ( "description", "" ), # s ( "destination", [ "", ], ), # as ) DBUS_SIGNATURE = '(sssas)' ADDITIONAL_ALNUM_CHARS = [ "_", "-" ] PARSER_REQUIRED_ELEMENT_ATTRS = { "short": None, "description": None, "icmptype": None, } PARSER_OPTIONAL_ELEMENT_ATTRS = { "icmptype": [ "name", "version" ], "destination": [ "ipv4", "ipv6" ], } def __init__(self): super(IcmpType, self).__init__() self.version = "" self.short = "" self.description = "" self.destination = [ ] def cleanup(self): self.version = "" self.short = "" self.description = "" del self.destination[:] def encode_strings(self): """ HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.""" self.version = u2b_if_py2(self.version) self.short = u2b_if_py2(self.short) self.description = u2b_if_py2(self.description) self.destination = [u2b_if_py2(m) for m in self.destination] def _check_config(self, config, item, all_config): if item == "destination": for destination in config: if destination not in [ "ipv4", "ipv6" ]: raise FirewallError(errors.INVALID_DESTINATION, "'%s' not from {'ipv4'|'ipv6'}" % \ destination) # PARSER class icmptype_ContentHandler(IO_Object_ContentHandler): def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) self.item.parser_check_element_attrs(name, attrs) if name == "icmptype": if "name" in attrs: log.warning("Ignoring deprecated attribute name='%s'" % attrs["name"]) if "version" in attrs: self.item.version = attrs["version"] elif name == "short": pass elif name == "description": pass elif name == "destination": for x in [ "ipv4", "ipv6" ]: if x in attrs and \ attrs[x].lower() in [ "yes", "true" ]: self.item.destination.append(str(x)) def icmptype_reader(filename, path): icmptype = IcmpType() if not filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "%s is missing .xml suffix" % filename) icmptype.name = filename[:-4] icmptype.check_name(icmptype.name) icmptype.filename = filename icmptype.path = path icmptype.builtin = False if path.startswith(config.ETC_FIREWALLD) else True icmptype.default = icmptype.builtin handler = icmptype_ContentHandler(icmptype) parser = sax.make_parser() parser.setContentHandler(handler) name = "%s/%s" % (path, filename) with open(name, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_ICMPTYPE, "not a valid icmptype file: %s" % \ msg.getException()) del handler del parser if PY2: icmptype.encode_strings() return icmptype def icmptype_writer(icmptype, path=None): _path = path if path else icmptype.path if icmptype.filename: name = "%s/%s" % (_path, icmptype.filename) else: name = "%s/%s.xml" % (_path, icmptype.name) if os.path.exists(name): try: shutil.copy2(name, "%s.old" % name) except Exception as msg: log.error("Backup of file '%s' failed: %s", name, msg) dirpath = os.path.dirname(name) if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath): if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) os.mkdir(dirpath, 0o750) f = io.open(name, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start icmptype element attrs = {} if icmptype.version and icmptype.version != "": attrs["version"] = icmptype.version handler.startElement("icmptype", attrs) handler.ignorableWhitespace("\n") # short if icmptype.short and icmptype.short != "": handler.ignorableWhitespace(" ") handler.startElement("short", { }) handler.characters(icmptype.short) handler.endElement("short") handler.ignorableWhitespace("\n") # description if icmptype.description and icmptype.description != "": handler.ignorableWhitespace(" ") handler.startElement("description", { }) handler.characters(icmptype.description) handler.endElement("description") handler.ignorableWhitespace("\n") # destination if icmptype.destination: handler.ignorableWhitespace(" ") attrs = { } for x in icmptype.destination: attrs[x] = "yes" handler.simpleElement("destination", attrs) handler.ignorableWhitespace("\n") # end icmptype element handler.endElement('icmptype') handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!z! *__pycache__/functions.cpython-36.opt-1.pycnu[3 Yjy@sddlZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZdd lmZdd lmZdd lmZdd lmZdd lmZddZdS)N)config) FirewallError)FirewallConfig) zone_reader)service_reader) ipset_reader)icmptype_reader) helper_reader) policy_reader)Direct)LockdownWhitelist)firewalld_confc -Cs|t|}t|jtjtjgdt|jtjtj gdt |j tj tj gdt|jtjtjgdt|jtjtjgdt|jtjtjgdd}x |jD]}x||dD]}tjj|sqxttj|D]}|j dryD||d||}|d kr||_!|j"|j#||d|Wqt$k rT}zt$|j%d ||j&fWYdd}~Xqt'k r}zt'd ||fWYdd}~XqXqWqWqWtjj(tj)r:y$t*tj)}|j+|j,|j-Wnpt$k r}zt$|j%d tj)|j&fWYdd}~Xn6t'k r8}zt'd tj)|fWYdd}~XnXtjj(tj.ry$t/tj.}|j+|j,|j-Wnpt$k r}zt$|j%d tj.|j&fWYdd}~Xn6t'k r}zt'd tj.|fWYdd}~XnXtjj(tj0rxyt1tj0}|j+Wnpt$k rB}zt$|j%d tj0|j&fWYdd}~Xn6t'k rv}zt'd tj0|fWYdd}~XnXdS) N)readeradddirs)ZipsethelperZicmptypeZservicezonepolicyrz.xmlrrrrz'%s': %s)rr)2rrZ add_ipsetrZFIREWALLD_IPSETSZETC_FIREWALLD_IPSETSr Z add_helperZFIREWALLD_HELPERSZETC_FIREWALLD_HELPERSrZ add_icmptypeZFIREWALLD_ICMPTYPESZETC_FIREWALLD_ICMPTYPESrZ add_serviceZFIREWALLD_SERVICESZETC_FIREWALLD_SERVICESrZadd_zoneZFIREWALLD_ZONESZETC_FIREWALLD_ZONESr Zadd_policy_objectZFIREWALLD_POLICIESZETC_FIREWALLD_POLICIESkeysospathisdirsortedlistdirendswith fw_configZcheck_config_dictZexport_config_dictrcodemsg ExceptionisfileZFIREWALLD_DIRECTr read check_configZ export_configZLOCKDOWN_WHITELISTr ZFIREWALLD_CONFr ) fwrZreadersrZ_dirfileobjerrorrr&/usr/lib/python3.6/functions.pyr!&sz   &. ($ ($  (r!)rZfirewallrZfirewall.errorsrZfirewall.core.fw_configrZfirewall.core.io.zonerZfirewall.core.io.servicerZfirewall.core.io.ipsetrZfirewall.core.io.icmptyperZfirewall.core.io.helperr Zfirewall.core.io.policyr Zfirewall.core.io.directr Z#firewall.core.io.lockdown_whitelistr Zfirewall.core.io.firewalld_confr r!r&r&r&r's            PK!?xR`/`/$__pycache__/io_object.cpython-36.pycnu[3 Yj5@sdZddddddddgZd d ljZd d ljjZd d lZd d lZd d lm Z d d l m Z d d l m Z d dl mZd dlmZejdkZGdddeZGdddeZGdddeZGdddeZGdddejjZGdddejZddZddZddZ ddZ!d S)z5Generic io_object handler, io specific check methods.PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudpcheck_protocol check_addressN) OrderedDict) functions)b2u)errors) FirewallError3c@s|eZdZdZfZdZgZiZiZddZ ddZ ddZ d d Z d d Z d dZddZddZddZddZddZdS)rz; Abstract IO_Object as base for icmptype, service and zone z()cCs"d|_d|_d|_d|_d|_dS)NF)filenamepathnamedefaultZbuiltin)selfr/usr/lib/python3.6/io_object.py__init__2s zIO_Object.__init__cCs6g}x(|jD]}|jtjt||dq Wt|S)Nr )IMPORT_EXPORT_STRUCTUREappendcopydeepcopygetattrtuple)rretxrrr export_config9s zIO_Object.export_configcCsXi}tdd|jD}x:|D]2}t||sAsz0IO_Object.export_config_dict..)dictrr isinstanceboolrr)rconf type_formatskeyrrrexport_config_dict?s  zIO_Object.export_config_dictcCs|j|xt|jD]~\}\}}t||tr~g}t}x,||D] }||krD|j||j|qDW~t||t j |qt||t j ||qWdS)N) check_config enumeraterr&listsetraddsetattrrr)rr(ielementZdummyZ_confZ_setr rrr import_configGs  zIO_Object.import_configc Cs~|j|xn|D]f}t||s0ttjdj|t||tr`t||tt j t j ||qt||t j ||qWdS)Nz-Internal error. '{}' is not a valid attribute) check_config_dicthasattrrr Z UNKNOWN_ERRORformatr&r.r1r fromkeysrr)rr(r*rrrimport_config_dictWs   "zIO_Object.import_config_dictcCszt|ts(ttjd|tdt|ft|dkr@ttjdx4|D],}|j rF||j krFttjd||fqFWdS)Nz'%s' not of type %s, but %srr"zname can't be emptyz'%s' is not allowed in '%s') r&strrr INVALID_TYPEtypelenZ INVALID_NAMEisalnumADDITIONAL_ALNUM_CHARS)rrcharrrr check_namecs     zIO_Object.check_namecCsjt|t|jkr0ttjdt|t|jfi}x&t|jD]\}\}}||||<q@W|j|dS)Nz structure size mismatch %d != %d)r=rrr r;r-r5)rr(Z conf_dictr2r yrrrr,pszIO_Object.check_configcCsrtdd|jD}xX|D]P}|dd|jDkrDttjdj||j|||||j||||qWdS)NcSsg|]}|d|dfqS)r r"r)r#r rrrr$|sz/IO_Object.check_config_dict..cSsg|] \}}|qSrr)r#r rBrrrr$~szoption '{}' is not valid)r%rrr ZINVALID_OPTIONr7_check_config_structure _check_config)rr(r)r*rrrr5{s  zIO_Object.check_config_dictcCsdS)Nr)rZdummy1Zdummy2Zdummy3rrrrDszIO_Object._check_configc Cs`t|t|s,ttjd|t|t|ft|trrt|dkrRttjd|x|D]}|j||dqXWnt|trt|t|krttjd|t|fxt |D]\}}|j|||qWnt|t r\t|j d\}}xn|j D]b\}}t|t|s,ttjd|t|t|ft|t|sttjd|t|t|fqWdS)Nz'%s' not of type %s, but %sr"zlen('%s') != 1r zlen('%s') != %d) r&r<rr r;r.r=rCrr-r%items) rr(Z structurer r2valueZskeyZsvaluer*rrrrCs8      z!IO_Object._check_config_structurecCs|j}d}||jkrdd}|j|dk rdx:|j|D],}||krL|j|q4ttjd||fq4W||jkrd}x$|j|D]}||kr~|j|q~W|sttjd|x |D]}ttjd||fqWdS)NFTzMissing attribute %s for %szUnexpected element %sz%s: Unexpected attribute %s)ZgetNamesPARSER_REQUIRED_ELEMENT_ATTRSremoverr Z PARSE_ERRORPARSER_OPTIONAL_ELEMENT_ATTRS)rrattrsZ_attrsfoundr rrrparser_check_element_attrss,     z$IO_Object.parser_check_element_attrsN)__name__ __module__ __qualname____doc__rZDBUS_SIGNATUREr?rGrIrr!r+r4r9rAr,r5rDrCrLrrrrr)s"   !cs$eZdZfddZddZZS)UnexpectedElementErrorcstt|j||_dS)N)superrQrr)rr) __class__rrrszUnexpectedElementError.__init__cCs d|jS)NzUnexpected element '%s')r)rrrr__str__szUnexpectedElementError.__str__)rMrNrOrrT __classcell__rr)rSrrQs rQcs$eZdZfddZddZZS)MissingAttributeErrorcstt|j||_||_dS)N)rRrVrr attribute)rrrW)rSrrrszMissingAttributeError.__init__cCsd|j|jfS)Nz$Element '%s': missing '%s' attribute)rrW)rrrrrTszMissingAttributeError.__str__)rMrNrOrrTrUrr)rSrrVs rVcs$eZdZfddZddZZS)UnexpectedAttributeErrorcstt|j||_||_dS)N)rRrXrrrW)rrrW)rSrrrsz!UnexpectedAttributeError.__init__cCsd|j|jfS)Nz'Element '%s': unexpected attribute '%s')rrW)rrrrrTsz UnexpectedAttributeError.__str__)rMrNrOrrTrUrr)rSrrXs rXc@s4eZdZddZddZddZddZd d Zd S) rcCs||_d|_dS)Nr)item_element)rrYrrrrsz!IO_Object_ContentHandler.__init__cCs d|_dS)Nr)rZ)rrrr startDocumentsz&IO_Object_ContentHandler.startDocumentcCs d|_dS)Nr)rZ)rrrJrrr startElementsz%IO_Object_ContentHandler.startElementcCs*|dkr|j|j_n|dkr&|j|j_dS)Nshort description)rZrYr]r^)rrrrr endElements z#IO_Object_ContentHandler.endElementcCs|j|jdd7_dS)N  )rZreplace)rcontentrrr characterssz#IO_Object_ContentHandler.charactersN)rMrNrOrr[r\r_rdrrrrrs c@s<eZdZddZddZddZddZd d Zd d Zd S)rcCsNtjjj||j|_|j|_ig|_|jd|_ g|_ d|_ d|_ d|_ dS)Nr"zutf-8F)saxhandlerContentHandlerrwrite_writeflushZ_flushZ _ns_contextsZ_current_contextZ_undeclared_ns_mapsZ _encodingZ_pending_start_elementZ_short_empty_elements)routrrrrs zIO_Object_XMLGenerator.__init__cCs*trdd|jD}tjj|||dS)a saxutils.XMLGenerator.startElement() expects name and attrs to be unicode and bad things happen if any of them is (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. cSsi|]\}}t|t|qSr)r )r#rrFrrr sz7IO_Object_XMLGenerator.startElement..N)rrEsaxutils XMLGeneratorr\)rrrJrrrr\sz#IO_Object_XMLGenerator.startElementcCstrX|jdt|x4|jD](\}}|jdt|tjt|fq W|jdnF|jd|x,|jD] \}}|jd|tj|fqpW|jddS)z* slightly modified startElement() N)rrjr rErnZ quoteattr)rrrJrFrrr simpleElements  z$IO_Object_XMLGenerator.simpleElementcCstjj|t|dS)z saxutils.XMLGenerator.endElement() expects name to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. N)rnror_r )rrrrrr_sz!IO_Object_XMLGenerator.endElementcCstjj|t|dS)z saxutils.XMLGenerator.characters() expects content to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. N)rnrordr )rrcrrrrd%sz!IO_Object_XMLGenerator.characterscCstjj|t|dS)a saxutils.XMLGenerator.ignorableWhitespace() expects content to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. N)rnroignorableWhitespacer )rrcrrrrr-sz*IO_Object_XMLGenerator.ignorableWhitespaceN) rMrNrOrr\rqr_rdrrrrrrrs  cCstj|}|dkr$ttjd|n`|dkr>ttjd|nF|dkrXttjd|n,t|dkr|d|dkrttjd|dS) Nzport number in '%s' is too bigr"z'%s' is invalid port rangezport range '%s' is ambiguousr re)r Z getPortRangerr Z INVALID_PORTr=)ZportZ port_rangerrrr5s    cCs|dkrttjd|dS)Ntcpudpsctpdccpz)'%s' not from {'tcp'|'udp'|'sctp'|'dccp'})rurvrwrx)rr INVALID_PROTOCOL)protocolrrrrDscCstj|sttj|dS)N)r Z checkProtocolrr ry)rzrrrrJs cCs$tj||s ttjd||fdS)Nz'%s' is not valid %s address)r rrr Z INVALID_ADDR)ZipvZaddrrrrrNs )"rP__all__Zxml.saxrfZxml.sax.saxutilsrnrsys collectionsr Zfirewallr Zfirewall.functionsr r Zfirewall.errorsrversionrobjectr ExceptionrQrVrXrgrhrrorrrrrrrrrs0           CPK!g22%__pycache__/zone.cpython-36.opt-1.pycnu[3 YjM@sdddgZddljZddlZddlZddlZddlmZddlm Z m Z m Z m Z m Z mZmZddlmZmZddlmZmZmZmZdd lmZmZmZmZdd lmZdd lm Z dd lm!Z!dd l"m#Z#GdddeZ$GdddeZ%dddZ&dddZ'dS)Zone zone_reader zone_writerN)config) checkIPnMask checkIP6nMaskcheckInterfaceuniqifymax_zone_name_len u2b_if_py2 check_mac)DEFAULT_ZONE_TARGET ZONE_TARGETS)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)common_startElementcommon_endElementcommon_check_config common_writer)rich)log)errors) FirewallErrorcsfeZdZdZd@dAdBdCdDd dgfd dEgfd dgfdFd dGgfddgfddgfddgfddgfddHgfdIdJfZdddgZddddgddgdgdgdddgdgddddgddgddddddgdgddZddddgd gd!d"gd#d$gd%d&d'd#d(gd%d'd(gd)d*gd+gd,gd- Zed.d/Z fd0d1Z d2d3Z d4d5Z fd6d7Z fd8d9Zd:d;Zfdd?ZZS)Krz Zone class versionshort descriptionUNUSEDFtargetservicesports icmp_blocks masquerade forward_ports interfacessources rules_str protocols source_portsicmp_block_inversionforward_-/Nnameportprotocolvalueset)rrzoneservicer1z icmp-blockz icmp-typer,z forward-port interfacerulesource destinationr2z source-portrZauditZacceptrejectZdropZmarklimitzicmp-block-inversion immutableZenabledzto-portzto-addrfamilyZpriorityaddressmacinvertipsetprefixleveltypeZburst) r5r$z forward-portr8r9r:rr;r<cCs8x&ttjD]\}\}}||kr |Sq WttjddS)Nz index_of()) enumeraterIMPORT_EXPORT_STRUCTURErrZ UNKNOWN_ERROR)elementiZelZdummyrJ/usr/lib/python3.6/zone.pyindex_ofdsz Zone.index_ofcstt|jd|_d|_d|_d|_t|_g|_ g|_ g|_ g|_ d|_ d|_g|_g|_g|_g|_d|_g|_g|_d|_d|_d|_dS)NrF)superr__init__rrrrr r r!r"r)r#r,r$r%r*r&r' fw_configrulesr(r+combinedapplied)self) __class__rJrKrNks,z Zone.__init__cCsd|_d|_d|_d|_t|_|jdd=|jdd=|jdd=|j dd=d|_ d|_ |j dd=|j dd=|jdd=|jdd=d|_|jdd=|jdd=d|_d|_d|_dS)NrF)rrrrr r r!r"r)r#r,r$r%r*r&r'rOrPr(r+rQrR)rSrJrJrKcleanups*          z Zone.cleanupcCst|j|_t|j|_t|j|_t|j|_dd|jD|_dd|jD|_dd|jD|_dd|jD|_dd|j D|_ dd|j D|_ dd|j D|_ d d|j D|_ d d|j D|_ d d|jD|_d S) z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsg|] }t|qSrJ)r ).0srJrJrK sz'Zone.encode_strings..cSs g|]\}}t|t|fqSrJ)r )rVpoprrJrJrKrXscSsg|] }t|qSrJ)r )rVrZrJrJrKrXscSsg|] }t|qSrJ)r )rVrIrJrJrKrXscSs0g|](\}}}}t|t|t|t|fqSrJ)r )rVZp1Zp2Zp3Zp4rJrJrKrXscSs g|]\}}t|t|fqSrJ)r )rVrYrZrJrJrKrXscSsg|] }t|qSrJ)r )rVrIrJrJrKrXscSsg|] }t|qSrJ)r )rVrWrJrJrKrXscSsg|] }t|qSrJ)r )rVrWrJrJrKrXscSsg|] }t|qSrJ)r )rVrWrJrJrKrXsN)r rrrr r!r"r)r#r%r*r&r'rPr()rSrJrJrKencode_stringss     zZone.encode_stringscsN|dkr8dd|D|_tt|j|dd|jDntt|j||dS)Nr(cSsg|]}tj|dqS))Zrule_str)rZ Rich_Rule)rVrWrJrJrKrXsz$Zone.__setattr__..cSsg|] }t|qSrJ)str)rVrWrJrJrKrXs)rPrMr __setattr__)rSr0r3)rTrJrKr]s zZone.__setattr__cstt|j}|d=|S)Nr)rMrexport_config_dict)rSZconf)rTrJrKr^szZone.export_config_dictcCsLt|||||dkr.|tkr*ttj|n|dkrxl|D]d}t|sTttj||jr}||j krq||jj |jkrttjdj ||qWqWdS)Nr r&z)interface '{}' already bound to zone '{}'r'zipset:z&source '{}' already bound to zone '{}')rrrrINVALID_TARGETrZINVALID_INTERFACErOZ get_zonesr0Zget_zoner&formatrrr startswith INVALID_ADDRr')rSritemZ all_configr7r5r9rJrJrK _check_configs6       zZone._check_configcstt|j||jdr,ttjd|n|jdrHttjd|n|jddkrhttjd|nnd|kr|d|j d}n|}t |t krttjd|t |t |j f|j r||j jkrttjddS)Nr/z'%s' can't start with '/'z'%s' can't end with '/'zmore than one '/' in '%s'z'Zone of '%s' has %d chars, max is %d %sz+Zones can't have the same name as a policy.)rMr check_namerarr INVALID_NAMEendswithcountfindlenr rQrOZget_policy_objectsZ NAME_CONFLICT)rSr0Z checked_name)rTrJrKrfs,      zZone.check_namec Csd|_d|_d|_d|_d|_x$|jD]}||jkr&|jj|q&Wx$|jD]}||jkrL|jj|qLWx$|jD]}||jkrr|jj|qrWx$|j D]}||j kr|j j|qWx$|j D]}||j kr|j j|qWx$|j D]}||j kr|j j|qW|j rd|_ |j rd|_ x(|jD]}||jkr&|jj|q&Wx(|jD]}||jkrP|jj|qPWx,|jD]"} |jj| |jjt| qzW|jrd|_dS)NTr)rQfilenamerrrr&appendr'r!r"r)r#r,r$r%r*rPr(r\r+) rSr5r7r9r6r1protoZicmpr,r8rJrJrKcombinesL                  z Zone.combine)rr)rr)rr)rF)r r)rr)r$F)rrrr)rr)r+F)r,F)__name__ __module__ __qualname____doc__rGZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRS staticmethodrLrNrUr[r]r^rdrfro __classcell__rJrJ)rTrKr(sx         c@s$eZdZddZddZddZdS)zone_ContentHandlercCs"tj||d|_d|_d|_dS)NF)rrN_rule _rule_errorZ _limit_ok)rSrcrJrJrKrN s zzone_ContentHandler.__init__c Cstj||||jrdS|jj||t|||r6dS|dkrd|krVtjd|dd|krj|d|j_d|krtjd|dd|kr|d}|t krt t j ||dkr|t kr||j_n|d kr|jjrtjd nd |j_n|d krh|jrtjd d |_dSd|kr.tjdd |_dS|d|jjkrT|jjj|dntjd|dn8|dkrf|jr |jjrtjdt|jd |_dSd}d|kr|djd$krd }d}}}d|kr|d}d|kr|d}d|kr|d}tj||||d|j_dSd|krBd|krBtjddSd|krdd|krdtjddSd|kr~tjd|dd|krtjddSd|krt|d rt|d rt|d rt t j|dd|kr$d|d}||jjkr|jjj|ntjd |dd|kr|d}||jjkrT|jjj|ntjd |dn:|d!kr|jjrtjd"nd |j_ntjd#|dSdS)%Nr5r0z'Ignoring deprecated attribute name='%s'rr=z,Ignoring deprecated attribute immutable='%s'r rr,zForward already set, ignoring.Tr7z$Invalid rule: interface use in rule.z Invalid interface: Name missing.z%Interface '%s' already set, ignoring.r9z:Invalid rule: More than one source in rule '%s', ignoring.FrAyestruer?r@rB)rAz$Invalid source: No address no ipset.z"Invalid source: Address and ipset.r>z)Ignoring deprecated attribute family='%s'z+Invalid source: Invertion not allowed here.zipset:%sz"Source '%s' already set, ignoring.zicmp-block-inversionz+Icmp-Block-Inversion already set, ignoring.zUnknown XML element '%s')ryrz)r startElementrxrcZparser_check_element_attrsrrZwarningrrrrr_r r r,rwr&rmr9r\lowerrZ Rich_Sourcerrr rbr'r+) rSr0attrsr rAZaddrr@rBentryrJrJrKr{&s                                       z zone_ContentHandler.startElementcCstj||t||dS)N)r endElementr)rSr0rJrJrKrs zzone_ContentHandler.endElementN)rprqrrrNr{rrJrJrJrKrvsprvFc Cst}|jds ttjd||dd |_|s>|j|j||_||_|j t j rZdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r} zttjd| jWYdd} ~ XnXWdQRX~~tr|j|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid zone file: %s)rrhrrrgr0rfrlpathrar ETC_FIREWALLDZbuiltindefaultrvsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZ INVALID_ZONEZ getExceptionrr[) rlrZ no_check_namer5handlerparserr0fr9msgrJrJrKrs:        (c Cs\|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|jtkr*|j|d <|jd ||jd t||x8t|jD]*} |jd|jdd| i|jd qVWx\t|jD]N} |jdd| kr|jdd| ddin|jdd| i|jd qW|jr |jd|jdi|jd |jr2|jd|jdi|jd |jd |jd |j |j!~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingrrr r5 z r7r0zipset:r9rBr?zicmp-block-inversionr,)"rrlr0osexistsshutilZcopy2 ExceptionrerrordirnamerarrmkdiriorrZ startDocumentrr r r{ZignorableWhitespacerr r&Z simpleElementr'r+r,rZ endDocumentclose) r5r_pathr0rdirpathrrr}r7r9rJrJrKrs`                     )F)N)(__all__Zxml.saxrrrrZfirewallrZfirewall.functionsrrrr r r r Zfirewall.core.baser rZfirewall.core.io.io_objectrrrrZfirewall.core.io.policyrrrrZ firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrrvrrrJrJrJrKs$   $    x| PK!qޝ#__pycache__/icmptype.cpython-36.pycnu[3 Yj@sdddgZddljZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZddlmZdd lmZdd lmZGd dde ZGd d d e ZddZdddZdS)IcmpTypeicmptype_readericmptype_writerN)config) u2b_if_py2)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)log)errors) FirewallErrorcspeZdZdddddgffZdZddgZd d d d Zd dgd d gdZfddZddZ ddZ ddZ Z S)rversionshort description destinationz(sssas)_-N)rricmptypenameipv4ipv6)rrcs*tt|jd|_d|_d|_g|_dS)Nr)superr__init__rrrr)self) __class__/usr/lib/python3.6/icmptype.pyr8s zIcmpType.__init__cCs"d|_d|_d|_|jdd=dS)Nr)rrrr)rrrrcleanup?szIcmpType.cleanupcCs:t|j|_t|j|_t|j|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsg|] }t|qSr)r).0mrrr Lsz+IcmpType.encode_strings..N)rrrrr)rrrrencode_stringsEs   zIcmpType.encode_stringscCs2|dkr.x$|D]}|dkrttjd|qWdS)Nrrrz'%s' not from {'ipv4'|'ipv6'})rr)r r ZINVALID_DESTINATION)rritemZ all_configrrrr _check_configNs  zIcmpType._check_config)rr)rr)rr) __name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrrr#r% __classcell__rr)rrr%s    c@seZdZddZdS)icmptype_ContentHandlercCstj||||jj|||dkrTd|kr>tjd|dd|kr|d|j_nT|dkr^nJ|dkrhn@|dkrx6d D].}||krv||jd krv|jjj t |qvWdS)Nrrz'Ignoring deprecated attribute name='%s'rrrrrryestrue)rr)r+r,) r startElementr$Zparser_check_element_attrsr Zwarningrlowerrappendstr)rrattrsxrrrr-Ys"  z$icmptype_ContentHandler.startElementN)r&r'r(r-rrrrr*Xsr*c Cst}|jds ttjd||dd |_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~tr|j|S) Nz.xmlz%s is missing .xml suffixFTz%s/%srbznot a valid icmptype file: %s)rendswithr r Z INVALID_NAMErZ check_namefilenamepath startswithr ETC_FIREWALLDZbuiltindefaultr*saxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_ICMPTYPEZ getExceptionrr#) r7r8rhandlerparserrfsourcemsgrrrrms8        (c Cs.|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|jd ||jd |jrt|jd krt|jd |jdi|j|j|jd|jd |jr|jd kr|jd |jdi|j|j|jd|jd |jr|jd i}x|jD]} d|| <qW|jd||jd |jd |jd |j|j~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingrrr z rrr+r)r8r7rosexistsshutilZcopy2 Exceptionr errordirnamer9rr:mkdirior=r Z startDocumentrr-ZignorableWhitespacerZ charactersZ endElementrrZ simpleElementZ endDocumentclose) rr8_pathrrCdirpathrAr?r1r2rrrrs\                       )N)__all__Zxml.saxr<rGrNrIZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr r Zfirewall.core.loggerr r Zfirewall.errorsr rr*rrrrrrs       3PK!@*/__pycache__/firewalld_conf.cpython-36.opt-1.pycnu[3 Yj5 @s~ddlZddlZddlZddlZddlmZddlmZddl m Z m Z m Z ddddd d d d d ddddg Z GdddeZdS)N)config)log)b2uu2bPY2 DefaultZone MinimalMark CleanupOnExitCleanupModulesOnExitLockdown IPv6_rpfilterIndividualCalls LogDeniedAutomaticHelpersFirewallBackendFlushAllOnReload RFC3964_IPv4AllowZoneDriftingc@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS)firewalld_confcCsi|_g|_||_|jdS)N)_config_deletedfilenameclear)selfrr$/usr/lib/python3.6/firewalld_conf.py__init__&szfirewalld_conf.__init__cCsi|_g|_dS)N)rr)rrrrr,szfirewalld_conf.clearcCs|jjg|_dS)N)rrr)rrrrcleanup0s zfirewalld_conf.cleanupcCs|jj|jS)N)rgetstrip)rkeyrrrr4szfirewalld_conf.getcCs8t|j}t|j|j|<||jkr4|jj|dS)N)rrrrremove)rr valueZ_keyrrrset7s  zfirewalld_conf.setcCsHd}x2|jjD]$\}}|r$|d7}|d||f7}qWtrDt|S|S)N z%s=%s)ritemsrr)rsr r"rrr__str__=s zfirewalld_conf.__str__cCs|jyt|jd}Wn8tk rR}ztjd|j||jdtj|jdt tj |jdtj rpdnd|jdtj rdnd|jd tj rdnd|jd tjrdnd|jd tjrdnd|jd tj|jd tj|jdtj|jdtjr dnd|jdtjr"dnd|jdtjr:dndWYdd}~XnXx|D]}|shP|j}t|dks\|dd.krq\dd|jdD}t|dkrtjd|jq\nr|dtkrtjd|jq\nN|ddkrtjd|jq\n*|jj|ddk r:tjd|jq\|d|j|d<q\W|j|jdstjdtj|jdt tj|jd}y t|WnPttfk r|dk rtj d |r|ndtj |jdt tj YnX|jd}| s|j!d/krJ|dk r2tj d#|r(|ndtj |jdtj rDdnd|jd}| sj|j!d0kr|dk rtj d$|r|ndtj |jdtj rdnd|jd }| s|j!d1kr|dk rtj d%|r|ndtj |jd tj rdnd|jd }| s"|j!d2kr^|dk rFtj d&|r<|ndtj|jd tjrXdnd|jd }| s~|j!d3kr|dk rtj d'|r|ndtj|jd tjrdnd|jd }| s|tj"kr|dk rtj d(|tj|jd t tj|jd }| s&|j!tj#kr\|dk rJtj d)|r@|ndtj|jd t tj|jd}| s~|j!tj$kr|dk rtj d*|r|ndtj|jdt tj|jd}| s|j!d4kr |dk rtj d+|r|ndtj|jdt tj|jd}| s*|j!d5kr`|dk rNtj d,|rD|ndtj|jdt tj|jd}| s|j!d6kr|dk rtj d-|r|ndtj|jdt tjdS)7NrzFailed to load '%s': %srrr yesnor r r r rrrrrrr#;cSsg|] }|jqSr)r).0xrrr bsz'firewalld_conf.read..=zInvalid option definition: '%s'zInvalid option: '%s'r$zMissing value: '%s'z!Duplicate option definition: '%s'z0DefaultZone is not set, using default value '%s'z7MinimalMark '%s' is not valid, using default value '%d'falsetruez7CleanupOnExit '%s' is not valid, using default value %sz>CleanupModulesOnExit '%s' is not valid, using default value %sz2Lockdown '%s' is not valid, using default value %sz7IPv6_rpfilter '%s' is not valid, using default value %sz9IndividualCalls '%s' is not valid, using default value %sz3LogDenied '%s' is invalid, using default value '%s'z:AutomaticHelpers '%s' is not valid, using default value %sz9FirewallBackend '%s' is not valid, using default value %sz:FlushAllOnReload '%s' is not valid, using default value %sz6RFC3964_IPv4 '%s' is not valid, using default value %sz;AllowZoneDrifting '%s' is not valid, using default value %s)r-r.)r+r4r*r5)r+r4r*r5)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)%ropenr Exceptionrerrorr#rZ FALLBACK_ZONEstrZFALLBACK_MINIMAL_MARKZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTINGrlensplit valid_keysrrcloseint ValueError TypeErrorZwarninglowerZLOG_DENIED_VALUESZAUTOMATIC_HELPERS_VALUESZFIREWALL_BACKEND_VALUES)rfmsglineZpairr"rrrreadFs                                       zfirewalld_conf.readc :Cst|jdkrdSg}tjjtjs2tjtjdy.tj ddtjj |j tjj |j dd}Wn2t k r}ztjd|WYdd}~XnXd}d}ytj|j dd d }WnPt k r}z0tjj|j rtjd |j |fnd}WYdd}~Xn6Xx0|D]&}|sP|jd }t|dkrH|s2|jd d }n|ddkrpd}|j||jd n|jd}t|dkrd}|j|d q |dj} |dj} | |kr.| |jkr|j| | krd}|jd| |j| fd }n$| |jkrd }nd}|j|d |j| nd }q Wt|jdkrx^|jjD]P\} } | |krjqT| dkrxqT|s|jd d }|jd| | fd }qTW|r|j|j|stj|jdStjj|j r@ytj|j d|j WnBt k r>}z$tj|jtd|j |fWYdd}~XnXytj|j|j WnBt k r}z$tj|jtd|j |fWYdd}~XnXtj|j ddS)Nr,iZwtz%s.F)modeprefixdirdeletez!Failed to open temporary file: %sZrtzUTF-8)rFencodingzFailed to open '%s': %sr%Trr-r2r3z%s=%s rrz%s.oldzBackup of '%s' failed: %szFailed to create '%s': %si)rr) r:rospathexistsrZ ETC_FIREWALLDmkdirtempfileZNamedTemporaryFilebasenamerdirnamer7rr8ior6rwriter;rappendr&r=r!nameshutilZcopy2IOErrorZmovechmod) rdoneZ temp_filerCZmodifiedemptyrBrDpr r"rrrrSs                  $ $zfirewalld_conf.writeN) __name__ __module__ __qualname__rrrrr#r(rErSrrrrr%s r)Zos.pathrKrRrOrVZfirewallrZfirewall.core.loggerrZfirewall.functionsrrrr<objectrrrrrs  PK!qޝ)__pycache__/icmptype.cpython-36.opt-1.pycnu[3 Yj@sdddgZddljZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZddlmZdd lmZdd lmZGd dde ZGd d d e ZddZdddZdS)IcmpTypeicmptype_readericmptype_writerN)config) u2b_if_py2)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)log)errors) FirewallErrorcspeZdZdddddgffZdZddgZd d d d Zd dgd d gdZfddZddZ ddZ ddZ Z S)rversionshort description destinationz(sssas)_-N)rricmptypenameipv4ipv6)rrcs*tt|jd|_d|_d|_g|_dS)Nr)superr__init__rrrr)self) __class__/usr/lib/python3.6/icmptype.pyr8s zIcmpType.__init__cCs"d|_d|_d|_|jdd=dS)Nr)rrrr)rrrrcleanup?szIcmpType.cleanupcCs:t|j|_t|j|_t|j|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsg|] }t|qSr)r).0mrrr Lsz+IcmpType.encode_strings..N)rrrrr)rrrrencode_stringsEs   zIcmpType.encode_stringscCs2|dkr.x$|D]}|dkrttjd|qWdS)Nrrrz'%s' not from {'ipv4'|'ipv6'})rr)r r ZINVALID_DESTINATION)rritemZ all_configrrrr _check_configNs  zIcmpType._check_config)rr)rr)rr) __name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrrr#r% __classcell__rr)rrr%s    c@seZdZddZdS)icmptype_ContentHandlercCstj||||jj|||dkrTd|kr>tjd|dd|kr|d|j_nT|dkr^nJ|dkrhn@|dkrx6d D].}||krv||jd krv|jjj t |qvWdS)Nrrz'Ignoring deprecated attribute name='%s'rrrrrryestrue)rr)r+r,) r startElementr$Zparser_check_element_attrsr Zwarningrlowerrappendstr)rrattrsxrrrr-Ys"  z$icmptype_ContentHandler.startElementN)r&r'r(r-rrrrr*Xsr*c Cst}|jds ttjd||dd |_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~tr|j|S) Nz.xmlz%s is missing .xml suffixFTz%s/%srbznot a valid icmptype file: %s)rendswithr r Z INVALID_NAMErZ check_namefilenamepath startswithr ETC_FIREWALLDZbuiltindefaultr*saxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_ICMPTYPEZ getExceptionrr#) r7r8rhandlerparserrfsourcemsgrrrrms8        (c Cs.|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|jd ||jd |jrt|jd krt|jd |jdi|j|j|jd|jd |jr|jd kr|jd |jdi|j|j|jd|jd |jr|jd i}x|jD]} d|| <qW|jd||jd |jd |jd |j|j~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingrrr z rrr+r)r8r7rosexistsshutilZcopy2 Exceptionr errordirnamer9rr:mkdirior=r Z startDocumentrr-ZignorableWhitespacerZ charactersZ endElementrrZ simpleElementZ endDocumentclose) rr8_pathrrCdirpathrAr?r1r2rrrrs\                       )N)__all__Zxml.saxr<rGrNrIZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr r Zfirewall.core.loggerr r Zfirewall.errorsr rr*rrrrrrs       3PK!(# (__pycache__/service.cpython-36.opt-1.pycnu[3 Yj2@sdddgZddljZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZmZmZmZmZddlmZdd lmZdd lmZGd dde ZGd d d e ZddZdddZdS)Serviceservice_readerservice_writerN)config) u2b_if_py2)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudpcheck_protocol check_address)log)errors) FirewallErrorc seZdZd d!d"dd#gfddgfdddifddgfd d$gfd dgfd dgff Zd d gZddddZddgddgdgdgddgddgdgdgdZfddZddZddZ ddZ Z S)%rversionshort descriptionportsmodules destination protocols source_portsincludeshelpers_-N)rrservicenameportprotocolvalueipv4ipv6r)rr!r"modulerz source-portincludehelpercsNtt|jd|_d|_d|_g|_g|_g|_i|_ g|_ g|_ g|_ dS)Nr) superr__init__rrrrrrrrrr)self) __class__/usr/lib/python3.6/service.pyr*DszService.__init__cCshd|_d|_d|_|jdd=|jdd=|jdd=|jj|jdd=|j dd=|j dd=dS)Nr) rrrrrrrclearrrr)r+r-r-r.cleanupQs      zService.cleanupcCst|j|_t|j|_t|j|_dd|jD|_dd|jD|_dd|jjD|_dd|jD|_dd|j D|_ dd|j D|_ d d|j D|_ d S) z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSs g|]\}}t|t|fqSr-)r).0poprr-r-r. dsz*Service.encode_strings..cSsg|] }t|qSr-)r)r1mr-r-r.r4escSsi|]\}}t|t|qSr-)r)r1kvr-r-r. fsz*Service.encode_strings..cSsg|] }t|qSr-)r)r1r3r-r-r.r4gscSs g|]\}}t|t|fqSr-)r)r1r2r3r-r-r.r4hscSsg|] }t|qSr-)r)r1sr-r-r.r4jscSsg|] }t|qSr-)r)r1r9r-r-r.r4ksN) rrrrrrritemsrrrr)r+r-r-r.encode_strings]s    zService.encode_stringscCs:|dkrJx>|D]6}|ddkr8t|dt|dqt|dqWn|dkrjx|D] }t|qXWn|dkrx|D]}t|dt|dqxWn|dkrx|D]*}|dkrttjd |t|||qWn^|d kr6xR|D]J}|jd r|jd d}d |kr|jd d}t |dkrttj |qWdS)Nrrrrrrr$r%z'%s' not in {'ipv4'|'ipv6'}r nf_conntrack_rr)r$r%) r r r rrZINVALID_DESTINATIONr startswithreplacelenZINVALID_MODULE)r+ritemZ all_configr!protorr&r-r-r. _check_configms8              zService._check_config)rr)rr)rr)rr)rr) __name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr*r0r;rD __classcell__r-r-)r,r.r&s4     c@seZdZddZdS)service_ContentHandlercCs0tj||||jj|||dkrTd|krxRdD]J}||krt|||||jjkr&tjd|n|||jj|<qWn|dkr|d}|jdr~|jdd}d|kr~|jdd}||jjkr|jjj |n tjd|n|dkr|d|jjkr|jjj |dntjd|dn@|dkr,|d|jjkr|jjj |dntjd|ddS)Nrr z'Ignoring deprecated attribute name='%s'rrrr!rr"z#Port '%s/%s' already set, ignoring.z$Protocol '%s' already set, ignoring.r#z source-portz)SourcePort '%s/%s' already set, ignoring.rr$r%z2Destination address for '%s' already set, ignoringr&r=rrz"Module '%s' already set, ignoring.r'z#Include '%s' already set, ignoring.r(z"Helper '%s' already set, ignoring.)r$r%)r startElementrBZparser_check_element_attrsrZwarningrr r rappendr rrrrr?r@rrr)r+r attrsentryxr&r-r-r.rJs                       z#service_ContentHandler.startElementN)rErFrGrJr-r-r-r.rIsrIc Cst}|jds ttjd||dd |_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~tr|j|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid service file: %s)rendswithrrZ INVALID_NAMEr Z check_namefilenamepathr?r ETC_FIREWALLDZbuiltindefaultrIsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_SERVICEZ getExceptionrr;) rSrTrhandlerparserr fsourcemsgr-r-r.rs8        (cCsr|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|jd ||jd |jrt|jd krt|jd |jdi|j|j|jd|jd |jr|jd kr|jd |jdi|j|j|jd|jd x>|jD]4} |jd |jd| d| dd|jd qWx4|jD]*} |jd |jdd| i|jd qWx>|jD]4} |jd |jd| d| dd|jd qs    (   mQPK!))'__pycache__/helper.cpython-36.opt-1.pycnu[3 Yj @sdddgZddljZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZmZmZddlmZdd lmZdd lmZGd dde ZGd d d e ZddZdddZdS)Helper helper_reader helper_writerN)config) u2b_if_py2)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudp)log)errors) FirewallErrorcseZdZddddddd gffZdZd d gZd d dgd Zd ddgddgdZfddZddZ ddZ ddZ ddZ Z S)!rversionshort descriptionfamilymoduleportsz (sssssa(ss))-.N)rrhelpernameportprotocol)rrcs6tt|jd|_d|_d|_d|_d|_g|_dS)Nr) superr__init__rrrrrr)self) __class__/usr/lib/python3.6/helper.pyr;szHelper.__init__cCs.d|_d|_d|_d|_d|_|jdd=dS)Nr)rrrrrr)rr!r!r"cleanupDs zHelper.cleanupcCsRt|j|_t|j|_t|j|_t|j|_t|j|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSs g|]\}}t|t|fqSr!)r).0ZpoZprr!r!r" Usz)Helper.encode_strings..N)rrrrrrr)rr!r!r"encode_stringsLs      zHelper.encode_stringscCs(ddg}||kr$ttjd||fdS)NZipv4Zipv6z'%s' not in '%s')rrZ INVALID_IPV)rZipvZipvsr!r!r" check_ipvWszHelper.check_ipvcCsz|dkr0xl|D]}t|dt|dqWnF|dkrv|jdsRttjd|t|jdddkrvttjd|dS) Nrrr nf_conntrack_z('%s' does not start with 'nf_conntrack_'rzModule name '%s' too short)r r startswithrrINVALID_MODULElenreplace)rritemZ all_configrr!r!r" _check_config]s    zHelper._check_config)rr)rr)rr)rr)rr)rr)__name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr#r&r'r/ __classcell__r!r!)r r"r&s$     c@seZdZddZdS)helper_ContentHandlercCs>tj||||jj|||dkrd|kr8|d|j_d|kr\|jj|d|d|j_d|kr|djdstt j d|dt |dj dddkrtt j d |d|d|j_ nz|d krnp|d krnf|d kr:t|d t|d |d |d f}||jjkr$|jjj|ntjd|d |d dS)Nrrrrr)z('%s' does not start with 'nf_conntrack_'rr(zModule name '%s' too shortrrrrz#Port '%s/%s' already set, ignoring.)r startElementr.Zparser_check_element_attrsrr'rr*rrr+r,r-rr r rappendr Zwarning)rrattrsentryr!r!r"r5ns>      z"helper_ContentHandler.startElementN)r0r1r2r5r!r!r!r"r4msr4c Cst}|jds ttjd||dd |_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~tr|j|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid helper file: %s)rendswithrrZ INVALID_NAMErZ check_namefilenamepathr*r ETC_FIREWALLDZbuiltindefaultr4saxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_HELPERZ getExceptionrr&) r=r>rhandlerparserrfsourcemsgr!r!r"rs8        (c CsP|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|j|d <|jr|jd kr|j|d <|jr<|jd kr<|j|d <|jd ||jd|jr|jd kr|jd|jdi|j|j|jd|jd|jr|jd kr|jd|jdi|j|j|jd|jdx>|jD]4} |jd|jd| d| dd|jdqW|jd |jd|j|j~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingrrrrr z rrrrr()rr) r>r=rosexistsshutilZcopy2 Exceptionr errordirnamer*rr?mkdiriorBr Z startDocumentrrrr5ZignorableWhitespacerZ charactersZ endElementrrZ simpleElementZ endDocumentclose) rr>_pathrrHdirpathrFrDr7rr!r!r"rs\                       )N)__all__Zxml.saxrArLrSrNZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr r r r Zfirewall.core.loggerr rZfirewall.errorsrrr4rrr!r!r!r"s        G#PK! h%h%3__pycache__/lockdown_whitelist.cpython-36.opt-1.pycnu[3 Yj1@sddljZddlZddlZddlZddlmZddlmZm Z m Z m Z ddl m Z ddlmZmZmZmZmZmZddlmZddlmZGdd d e ZGd d d e ZdS) N)config)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)log)uniqify checkUsercheckUid checkCommand checkContext u2b_if_py2)errors) FirewallErrorc@seZdZddZddZdS)!lockdown_whitelist_ContentHandlercCstj||d|_dS)NF)r__init__ whitelist)selfitemr(/usr/lib/python3.6/lockdown_whitelist.pyr%s z*lockdown_whitelist_ContentHandler.__init__c CsVtj||||jj|||dkr@|jr6ttjdd|_n|dkrr|js\tj ddS|d}|jj |n|dkr|jstj ddSd |kryt |d }Wn&t k rtj d |d dSX|jj |nd|kr|jj|dn\|d kr@|jstj d dSd |kr.tj ddS|jj|d ntj d|dSdS)NrzMore than one whitelist.Tcommandz)Parse Error: command outside of whitelistnameuserz&Parse Error: user outside of whitelistidz"Parse Error: %s is not a valid uidselinuxz)Parse Error: selinux outside of whitelistcontextzParse Error: no contextzUnknown XML element %s)r startElementrZparser_check_element_attrsrrrZ PARSE_ERRORrerror add_commandint ValueErroradd_uidadd_user add_context)rrZattrsruidrrrr)sJ        z.lockdown_whitelist_ContentHandler.startElementN)__name__ __module__ __qualname__rrrrrrr$srcs4eZdZdZddgfddgfddgfddgffZdZd gZd d gd d gd Zddd giZfddZ ddZ ddZ ddZ ddZ ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z d@dAZ!dBdCZ"Z#S)DLockdownWhitelistz LockdownWhitelist class commandscontextsusersuidsrz (asasasai)_Nrr)rrrrrrcs6tt|j||_d|_g|_g|_g|_g|_dS)N) superr)rfilenameparserr*r,r-r.)rr1) __class__rrrnszLockdownWhitelist.__init__cCs|d kr.x|D]}|j||dd |qWnv|dkrLt|sttj|nX|dkrjt|sttj|n:|dkrt|sttj|n|d krt |sttj |dS) Nr*r,r-r.rrrr%)r*r,r-r.) _check_configr rrINVALID_COMMANDr INVALID_CONTEXTr INVALID_USERr INVALID_UID)rrrZ all_configxrrrr6ys zLockdownWhitelist._check_configcCs4|jdd=|jdd=|jdd=|jdd=dS)N)r*r,r-r.)rrrrcleanups   zLockdownWhitelist.cleanupcCs:dd|jD|_dd|jD|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsg|] }t|qSr)r ).0r;rrr sz4LockdownWhitelist.encode_strings..cSsg|] }t|qSr)r )r=r;rrrr>scSsg|] }t|qSr)r )r=r;rrrr>sN)r*r,r-)rrrrencode_stringssz LockdownWhitelist.encode_stringscCs@t|sttj|||jkr,|jj|nttjd|dS)Nz!Command "%s" already in whitelist)r rrr7r*appendALREADY_ENABLED)rrrrrrs   zLockdownWhitelist.add_commandcCs,||jkr|jj|nttjd|dS)NzCommand "%s" not in whitelist.)r*removerr NOT_ENABLED)rrrrrremove_commands z LockdownWhitelist.remove_commandcCs ||jkS)N)r*)rrrrr has_commandszLockdownWhitelist.has_commandcCsBx<|jD]2}|jdr.|j|ddr:dSq||krdSqWdS)N*r4TFr5)r*endswith startswith)rrZ_commandrrr match_commands  zLockdownWhitelist.match_commandcCs|jS)N)r*)rrrr get_commandsszLockdownWhitelist.get_commandscCsDt|sttjt|||jkr0|jj|nttjd|dS)NzUid "%s" already in whitelist)r rrr:strr.r@rA)rr%rrrr"s  zLockdownWhitelist.add_uidcCs,||jkr|jj|nttjd|dS)NzUid "%s" not in whitelist.)r.rBrrrC)rr%rrr remove_uids zLockdownWhitelist.remove_uidcCs ||jkS)N)r.)rr%rrrhas_uidszLockdownWhitelist.has_uidcCs ||jkS)N)r.)rr%rrr match_uidszLockdownWhitelist.match_uidcCs|jS)N)r.)rrrrget_uidsszLockdownWhitelist.get_uidscCs@t|sttj|||jkr,|jj|nttjd|dS)NzUser "%s" already in whitelist)r rrr9r-r@rA)rrrrrr#s   zLockdownWhitelist.add_usercCs,||jkr|jj|nttjd|dS)NzUser "%s" not in whitelist.)r-rBrrrC)rrrrr remove_users zLockdownWhitelist.remove_usercCs ||jkS)N)r-)rrrrrhas_userszLockdownWhitelist.has_usercCs ||jkS)N)r-)rrrrr match_userszLockdownWhitelist.match_usercCs|jS)N)r-)rrrr get_usersszLockdownWhitelist.get_userscCs@t|sttj|||jkr,|jj|nttjd|dS)Nz!Context "%s" already in whitelist)r rrr8r,r@rA)rrrrrr$"s   zLockdownWhitelist.add_contextcCs,||jkr|jj|nttjd|dS)NzContext "%s" not in whitelist.)r,rBrrrC)rrrrrremove_context,s z LockdownWhitelist.remove_contextcCs ||jkS)N)r,)rrrrr has_context3szLockdownWhitelist.has_contextcCs ||jkS)N)r,)rrrrr match_context6szLockdownWhitelist.match_contextcCs|jS)N)r,)rrrr get_contexts9szLockdownWhitelist.get_contextscCs|j|jjds&ttjd|jt|}tj}|j |y|j |jWn8tj k r}zttj d|j WYdd}~XnX~~tr|jdS)Nz.xmlz'%s' is missing .xml suffixzNot a valid file: %s)r<r1rGrrZ INVALID_NAMErsaxZ make_parserZsetContentHandlerparseZSAXParseExceptionZ INVALID_TYPEZ getExceptionrr?)rhandlerr2msgrrrread>s"   zLockdownWhitelist.readcCstjj|jr\ytj|jd|jWn4tk rZ}ztd|j|fWYdd}~XnXtjjtj sxtj tj dt j |jddd}t |}|j|jdi|jdx6t|jD](}|jd |jd d |i|jdqWx:t|jD],}|jd |jd d t|i|jdqWx8t|jD]*}|jd |jd d |i|jdq0Wx8t|jD]*}|jd |jdd|i|jdqjW|jd|jd|j|j~dS)Nz%s.oldzBackup of '%s' failed: %siZwtzUTF-8)modeencodingr z rrrrrr)ospathexistsr1shutilZcopy2 ExceptionIOErrorrZ ETC_FIREWALLDmkdirioopenrZ startDocumentrZignorableWhitespacerr*Z simpleElementr.rKr-r,Z endElementZ endDocumentclose)rr[frZrr%rrrrrwriteQsB$         zLockdownWhitelist.write)$r&r'r(__doc__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr6r<r?rrDrErIrJr"rLrMrNrOr#rPrQrRrSr$rTrUrVrWr\rk __classcell__rr)r3rr)WsL         1 r))Zxml.saxrXr`rgrcZfirewallrZfirewall.core.io.io_objectrrrrZfirewall.core.loggerrZfirewall.functionsrr r r r r rZfirewall.errorsrrr)rrrrs      3PK!FmRR!__pycache__/policy.cpython-36.pycnu[3 YjϢ@s dddgZddljZddlZddlZddlZddlmZddlm Z m Z ddlm Z m Z m Z ddlmZmZmZdd lmZmZmZmZmZmZdd lmZdd lmZdd lmZdd lmZddZ ddZ!ddZ"ddZ#ddZ$GdddeZ%GdddeZ&dddZ'dddZ(dS) Policy policy_reader policy_writerN)config)checkIPcheckIP6)uniqifymax_policy_name_lenportStr)DEFAULT_POLICY_TARGETPOLICY_TARGETSDEFAULT_POLICY_PRIORITY) IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudpcheck_protocol)rich)log)errors) FirewallErrorc Cs|dkr n|dkrn|dkr|jr`|jjrJtjdt|jd|_dStj|d|j_dS|d|jj kr|jj j |dntjd|dn|dkrN|jr|jjrtjdt|jd|_dStj |d|d |j_dSt |dt |d t|dd |d f}||jjkr4|jjj |ntjd |d|d nN|d kr|jr|jjrtjdt|jd|_dStj|d |j_nBt|d |d |jjkr|jjj |d ntjd |d n|dkrh|jr.|jjrtjdt|jd|_dStj|d|j_dS|d|jjkrT|jjj |dntjd|dn4|dkr|jr|jjrtjdt|jd|_dStj|d|j_dStjd|dn|dkr2|jr|jjrtjdt|jd|_dStj|j_n|jjr&tjdnd|j_nj|dkrd}d|krR|d}d}d|krh|d}|jr|jjrtjdt|jd|_dStj|d|d |||j_dSt |dt |d |rt ||r t| r t| r ttjd|t|dd |d t|d t|f}||jjkrL|jjj |n6tjd|d|d |rld|nd|r|d|ndn|dkr@|jr|jjrtjdt|jd|_dStj|d|d |j_dSt |dt |d t|dd |d f}||jj kr&|jj j |ntjd|d|d n\|dkr|jsftjdd|_dS|jj!rtjd t|jdSd!}d}d"|kr|d"}d}d#|kr|d#}d$|kr|d$j"dLkrd}tj#||||j_!n|dMkr|jstjd+d|_dS|jj$r0tjd,d|_dS|d'krHtj%|j_$nh|d(krxd} d-|krh|d-} tj&| |j_$n8|d)krtj'|j_$n |d*kr|d.} tj(| |j_$|jj$|_)n|d/kr^|jstjd0dS|jjrtjd1dSd} d2|kr*|d2} | dNkr*tjd;d|_dSd<|kr<|d<nd} tj*| | |j_|jj|_)n>|d=kr|js~tjd>dS|jj+rtjd?t|jd|_dStj,|j_+|jj+|_)n|d@kr,d} dA}dB|kr|dB} | dOkrtjdE|dBd|_dSdF|krt-|dF}tj.| |dG|_np|dHkr|j)sRtjdId|_dS|j)j/rxtjdJt|jd|_dS|d }tj0||j1dK|j)_/nd!SdS)PNshort descriptionservicez;Invalid rule: More than one element in rule '%s', ignoring.Tnamez#Service '%s' already set, ignoring.portprotocol-z#Port '%s/%s' already set, ignoring.valuez$Protocol '%s' already set, ignoring.z icmp-blockz&icmp-block '%s' already set, ignoring.z icmp-typez-Invalid rule: icmp-block '%s' outside of rule masqueradez!Masquerade already set, ignoring.z forward-portzto-portzto-addrz#to-addr '%s' is not a valid addressz-Forward port %s/%s%s%s already set, ignoring.z >%sz @%sz source-portz*Source port '%s/%s' already set, ignoring. destinationz)Invalid rule: Destination outside of rulez?Invalid rule: More than one destination in rule '%s', ignoring.Faddressipsetinvertyestrueacceptrejectdropmarkz$Invalid rule: Action outside of rulez"Invalid rule: More than one actiontypesetrz!Invalid rule: Log outside of rulezInvalid rule: More than one loglevelemergalertcriterrorwarningnoticeinfodebugzInvalid rule: Invalid log levelprefixauditz#Invalid rule: Audit outside of rulez9Invalid rule: More than one audit in rule '%s', ignoring.rulerfamilyipv4ipv6z&Invalid rule: Rule family "%s" invalidpriority)r:r=limitz4Invalid rule: Limit outside of action, log and auditz9Invalid rule: More than one limit in rule '%s', ignoring.burst)r&r')r(r)r*r+)r/r0r1r2r3r4r5r6)r;r<)2_ruleelementrr3str _rule_errorr Rich_Serviceitemservicesappend Rich_Portrrr ports Rich_Protocolr protocolsRich_IcmpBlock icmp_blocks Rich_IcmpTypeRich_Masquerader Rich_ForwardPortrrrr INVALID_ADDR forward_portsRich_SourcePort source_portsr"lowerZRich_Destinationaction Rich_Accept Rich_Reject Rich_Drop Rich_Mark _limit_okZRich_Logr8Z Rich_Auditint Rich_Ruler>Z Rich_Limitget)objrattrsentryto_portZto_addrr%r#r$Z_typeZ_setr.r7r:r=rrc/usr/lib/python3.6/policy.pycommon_startElements                                                                            recCs|dkr|jsy|jjWn6tk rR}ztjd|t|jWYdd}~XnLXt|j|jjkr|jj j |j|jjj t|jntjdt|jd|_d|_n|d krd|_ dS) Nr9z%s: %sz Rule '%s' already set, ignoring.Fr(r)r*r+rr8)r(r)r*r+rr8) rCr@Zcheck Exceptionrr3rBrE rules_strrulesrGr[)r_rercrcrdcommon_endElements& rjcCst|trdnd}|dkrT|jrT|jj}x$|D]}||kr0ttjd|q0Wn|dkrx$|D]}t|dt|dqbWnb|dkrx|D] }t |qWn@|d kr|jr|jj } x$|D]} | | krttj d | qWn|d krx|D]} t| dt| d| d  r>| d  r>ttj d| | d rTt| d | d rt | d  rt| d  rttjd| d qWnT|dkrx&|D]}t|dt|dqWn|dkrx|D]} tj| d} |jr| jrt| jtjst| jtjr|jj } | jj| krLttj d | jjnH| jr|jj| jj}|jr| j|jkrttj d| j| jjfnL|jrt| jtjr|jj}| jj|krttjdj||j| jjqWdS)NrZZonerFz '%s' not among existing servicesrIrrKrMz"'%s' not among existing icmp typesrRz$'%s' is missing to-port AND to-addr z#to-addr '%s' is not a valid addressrTrg rich_rules)rule_strz3rich rule family '%s' conflicts with icmp type '%s'z){} '{}': '{}' not among existing services)rgrn) isinstancer fw_configZ get_servicesrrZINVALID_SERVICErrrZ get_icmptypesZINVALID_ICMPTYPEINVALID_FORWARDrrrQrr]rArLrNrr:Z get_icmptyper"rDformat)r_rrE all_configZobj_typeZexisting_servicesrrprotoZexisting_icmptypesZicmptypefwd_portr9Zobj_richZictrcrcrdcommon_check_config2s                      rwcCs0d|ji}|j}|dk r ||d<|jd|dS)Nrr?r>)rr? simpleElement)handlerr>dr?rcrcrd_handler_add_rich_limitxs  r{c Cs|jrF|jdkrF|jd|jdi|j|j|jd|jd|jr|jdkr|jd|jdi|j|j|jd|jdx6t|jD](}|jd|jdd|i|jdqWx@t|j D]2}|jd|jd|d |d d |jdqWx8t|j D]*}|jd|jd d |i|jdqWx8t|j D]*}|jd|jdd|i|jdqLW|j r|jd|jdi|jdxt|j D]}|jd|d |d d }|dr|ddkr|d|d<|dr|ddkr|d|d<|jd||jdqWxBt|jD]4}|jd|jd|d |d d |jdq>WxT|jD]H}i}|jr|j|d<|jd krt|j|d<|jd|jd||jd|jrVi}|jjr|jj|d<|jjr|jj|d<|jjr$|jj|d<|jjr6d|d<|jd|jd||jd|jri}|jjrx|jj|d<|jjr|jj|d<|jjrd|d<|jd|jd ||jd|jrxd} i}t|jtjkrd} |jj|d<nbt|jtjkr(d} |jj|d<|jj |d <n0t|jtj!krNd } |jj"|d <n t|jtj#krfd} nt|jtj$krd} |jj|d<nt|jtj%krd!} |jj|d<nt|jtj&krd} |jj|d<|jj |d <|jj'dkr|jj'|d<|jj(dkrX|jj(|d<nFt|jtj)krBd} |jj|d<|jj |d <nt*t+j,d"t|j|jd|j| ||jd|j-ri}|j-j.r|j-j.|d#<|j-j/r|j-j/|d$<|j-j0r|jd|jd%||jd&t1||j-j0|jd'|jd%n|jd|jd%||jd|j2ri}|j2j0rx|jd|jd(i|jd&t1||j2j0|jd'|jd(n|jd|jd(||jd|j3rd} i}t|j3tj4krd)} n|t|j3tj5krd*} |j3jr<|j3j|d+<nNt|j3tj6krd,} n6t|j3tj7kr*d-} |j3j8|d.<nt-j9d/t|j3|j3j0r|jd|j| ||jd&t1||j3j0|jd'|j| n|jd|j| ||jd|jd|jd|jdqWdS)0Nr!z r rrrrrrk)rrrrz icmp-blockr rlzto-portrmzto-addrz forward-portz source-portr:r=r9r#macr$Truer%z sourcer"z icmp-typez"Unknown element '%s' in obj_writerr7r.rz z r8r(r)r,r*r+r-zUnknown action '%s'):rignorableWhitespace startElementZ characters endElementrrrFrxrIrKrMr rRrTrhr:r=rBraddrr}r$r%r"rAr,rrDrrHrrrJrrOrLrNrPrb to_addressrSrrZINVALID_OBJECTrr7r.r>r{r8rVrWrXrYrZr-r3) r_ryrrrZicmpZforwardr`r9rArVrcrcrd common_writers\                                                                                        rcsPeZdZd7ZdZeZdgZd8d9d:d;d dgfd dgfddgfddgfdd?gfd@ddgfddgffZdddgZ dddgdgddgdgdgdddgddddgddgddddddgdgdgdgdZ ddgdd gd!dgd"d#d$d!d%gd"d$d%gd&d'gd(gd)gd*Z fd+d,Z d-d.Z fd/d0Zfd1d2Zd3d4Zfd5d6ZZS)Ariirversionr!rrtargetrFrIrMr FrRrnrKrTr= ingress_zones egress_zones_r/Nrrrrr-)rrpolicyrrz icmp-blockz icmp-typer z forward-portr9rr"rz source-portrr8r(r)r*r+r>z ingress-zonez egress-zonezto-portzto-addrr:r#r}r%r$r7r.r,r?)rz forward-portr9rr"rr)r>cstt|jd|_d|_d|_t|_g|_g|_ g|_ g|_ d|_ g|_ g|_d|_g|_g|_d|_|j|_d|_g|_g|_dS)Nr!F)superr__init__rrrr rrFrIrKrMr rRrTrqrhrgappliedpriority_defaultr=Zderived_from_zonerr)self) __class__rcrdrs(zPolicy.__init__cCsd|_d|_d|_t|_|jdd=|jdd=|jdd=|jdd=d|_ |j dd=|j dd=d|_ |j dd=|jdd=d|_|j|_|jdd=|jdd=dS)Nr!F)rrrr rrFrIrKrMr rRrTrqrhrgrrr=rr)rrcrcrdcleanups$         zPolicy.cleanupcs"|dkr|jSttt||SdS)Nrn)rggetattrrr)rr)rrcrd __getattr__szPolicy.__getattr__csB|dkr,dd|D|_dd|jD|_ntt|j||dS)NrncSsg|]}tj|dqS))ro)rr]).0srcrcrd sz&Policy.__setattr__..cSsg|] }t|qSrc)rB)rrrcrcrdrs)rhrgrr __setattr__)rrr)rrcrdrszPolicy.__setattr__c Cst|||||dkr2|tkr.ttjd|n|dkrz||jksX||jksX||jkrvttjd||j|j|jfn|dkrhddg}|j r||j j 7}x|D]}||krttj d ||dkrt ddgt |@s|dkrt |t |grttj d ||dkr|dkr8d|kr8d|dksT|dkrd|krd|dkrttj d qWn|d kr|rd|krd|dkrttj d nxd|krd|dkrttj dxR|dD]F}|dkrސq|j j |}|j rd|j j|krttj dqWn|dkr4x|D]}tj|d}|jrt|jtjrd|kr|d|dkr|ttj d nxd|kr,d|dkrttj dxR|dD]F}|dkrq|j j |}|j rd|j j|krttj dqWq,|jrt|jtjrd|kr,d|dkr@|jjrttjdnt|dr,|jjs`ttjdd|dkr,x|dD]8}|j j |}|j rxd|j j|krxttj dqxWnv|jr,t|jtjr,d|kr,xR|dD]F}|dkrq|j j |}|j rd|j j|krttj dqWq,Wn|dkrx|D]} d|krnd|dkrnttj dnd|krDd|dkr| drttjdnt|drD| dsttjdd|dkrDxD|dD]8}|j j |}|j rd|j j|krttj dqWqDWdS)Nrz'%s' is invalid targetr=zQ%d is invalid priority. Must be in range [%d, %d]. The following are reserved: %srrANYHOSTz'%s' not among existing zonesz>'%s' may only contain one of: many regular zones, ANY, or HOSTzF'HOST' can only appear in either ingress or egress zones, but not bothr z.'masquerade' is invalid for egress zone 'HOST'z/'masquerade' is invalid for ingress zone 'HOST'Z interfaceszR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesrn)rozAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesrRz1'forward-port' is invalid for ingress zone 'HOST'rm)rr)rr)rr)rr)rwr rrINVALID_TARGETpriority_reserved priority_max priority_minZINVALID_PRIORITYrq get_zonesZ INVALID_ZONEr-Zget_zoneZget_zone_config_dictrr]rArprOrPrrrrVrZ) rrrErtZexisting_zoneszoneZz_objr9r_rvrcrcrd _check_configs       "                           zPolicy._check_configcstt|j||jdr,ttjd|n|jdrHttjd|n|jddkrhttjd|njd|kr|d|j d}n|}t |t krttjd|t |t f|j r||j j krttjddS)Nrz'%s' can't start with '/'z'%s' can't end with '/'rkzmore than one '/' in '%s'z&Policy of '%s' has %d chars, max is %dz,Policies can't have the same name as a zone.)rr check_name startswithrr INVALID_NAMEendswithcountfindlenr rqrZ NAME_CONFLICT)rrZ checked_name)rrcrdr,s*      zPolicy.check_namei)rr!)rr!)rr!)rr!)r!r!)r F)r!r!r!r!)r!r!)r=r)__name__ __module__ __qualname__rrr rrZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrrrrrr __classcell__rcrc)rrdrZsr        ^c@s$eZdZddZddZddZdS)policy_ContentHandlercCs"tj||d|_d|_d|_dS)NF)rrr@rCr[)rrErcrcrdrHs zpolicy_ContentHandler.__init__cCstj||||jrdS|jj||t|||r6dS|dkrd|krR|d|j_d|krjt|d|j_d|kr|d}|t krt t j ||r||j_ n^|dkr|d|jjkr|jjj|dntjd|dn|dkr |d|jjkr|jjj|dntjd |dn|d kr|jsFtjd d |_dS|jjrltjd t|jd |_dSd}d|kr|djdkrd }d}}}d|kr|d}d|kr|d}d|kr|d}tj||||d|j_dStjd|dSdS)Nrrr=rz ingress-zonerz(Ingress zone '%s' already set, ignoring.z egress-zonez'Egress zone '%s' already set, ignoring.rz$Invalid rule: Source outside of ruleTz:Invalid rule: More than one source in rule '%s', ignoring.Fr%r&r'r#r}r$)r%zUnknown XML element '%s')r&r')rrrCrEZparser_check_element_attrsrerr\r=r rrrrrrGrr3rr@rrBrUrZ Rich_Source)rrr`rr%rr}r$rcrcrdrNsf                 z"policy_ContentHandler.startElementcCstj||t||dS)N)rrrj)rrrcrcrdrs z policy_ContentHandler.endElementN)rrrrrrrcrcrcrdrGs@rFc Cst}|jds ttjd||dd |_|s>|j|j||_||_|j t j rZdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r} zttjd| jWYdd} ~ XnXWdQRX~~|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid policy file: %s)rrrrrrrfilenamepathrr ETC_FIREWALLDZbuiltindefaultrsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_POLICYZ getException) rrZ no_check_namerryparserrfrmsgrcrcrdrs6        (c Cs|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|j|jkr0t|j|d <|j|d <|jd ||jdt||x8t|jD]*} |jd|jdd| i|jdqfWx8t|jD]*} |jd|jdd| i|jdqW|jd |jd|j |j!~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingr!rr=rrr|z z ingress-zonerz egress-zone)"rrrosexistsshutilZcopy2rfrr2dirnamerrrmkdiriorrZ startDocumentrr=rrBrrrrrrrxrrZ endDocumentclose) rr_pathrrdirpathrryr`rrcrcrdrsN             )F)N))__all__Zxml.saxrrrrZfirewallrZfirewall.functionsrrrr r Zfirewall.core.baser r r Zfirewall.core.io.io_objectrrrrrrZ firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrerjrwr{rrrrrrcrcrcrds4        F[nL PK!@*)__pycache__/firewalld_conf.cpython-36.pycnu[3 Yj5 @s~ddlZddlZddlZddlZddlmZddlmZddl m Z m Z m Z ddddd d d d d ddddg Z GdddeZdS)N)config)log)b2uu2bPY2 DefaultZone MinimalMark CleanupOnExitCleanupModulesOnExitLockdown IPv6_rpfilterIndividualCalls LogDeniedAutomaticHelpersFirewallBackendFlushAllOnReload RFC3964_IPv4AllowZoneDriftingc@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS)firewalld_confcCsi|_g|_||_|jdS)N)_config_deletedfilenameclear)selfrr$/usr/lib/python3.6/firewalld_conf.py__init__&szfirewalld_conf.__init__cCsi|_g|_dS)N)rr)rrrrr,szfirewalld_conf.clearcCs|jjg|_dS)N)rrr)rrrrcleanup0s zfirewalld_conf.cleanupcCs|jj|jS)N)rgetstrip)rkeyrrrr4szfirewalld_conf.getcCs8t|j}t|j|j|<||jkr4|jj|dS)N)rrrrremove)rr valueZ_keyrrrset7s  zfirewalld_conf.setcCsHd}x2|jjD]$\}}|r$|d7}|d||f7}qWtrDt|S|S)N z%s=%s)ritemsrr)rsr r"rrr__str__=s zfirewalld_conf.__str__cCs|jyt|jd}Wn8tk rR}ztjd|j||jdtj|jdt tj |jdtj rpdnd|jdtj rdnd|jd tj rdnd|jd tjrdnd|jd tjrdnd|jd tj|jd tj|jdtj|jdtjr dnd|jdtjr"dnd|jdtjr:dndWYdd}~XnXx|D]}|shP|j}t|dks\|dd.krq\dd|jdD}t|dkrtjd|jq\nr|dtkrtjd|jq\nN|ddkrtjd|jq\n*|jj|ddk r:tjd|jq\|d|j|d<q\W|j|jdstjdtj|jdt tj|jd}y t|WnPttfk r|dk rtj d |r|ndtj |jdt tj YnX|jd}| s|j!d/krJ|dk r2tj d#|r(|ndtj |jdtj rDdnd|jd}| sj|j!d0kr|dk rtj d$|r|ndtj |jdtj rdnd|jd }| s|j!d1kr|dk rtj d%|r|ndtj |jd tj rdnd|jd }| s"|j!d2kr^|dk rFtj d&|r<|ndtj|jd tjrXdnd|jd }| s~|j!d3kr|dk rtj d'|r|ndtj|jd tjrdnd|jd }| s|tj"kr|dk rtj d(|tj|jd t tj|jd }| s&|j!tj#kr\|dk rJtj d)|r@|ndtj|jd t tj|jd}| s~|j!tj$kr|dk rtj d*|r|ndtj|jdt tj|jd}| s|j!d4kr |dk rtj d+|r|ndtj|jdt tj|jd}| s*|j!d5kr`|dk rNtj d,|rD|ndtj|jdt tj|jd}| s|j!d6kr|dk rtj d-|r|ndtj|jdt tjdS)7NrzFailed to load '%s': %srrr yesnor r r r rrrrrrr#;cSsg|] }|jqSr)r).0xrrr bsz'firewalld_conf.read..=zInvalid option definition: '%s'zInvalid option: '%s'r$zMissing value: '%s'z!Duplicate option definition: '%s'z0DefaultZone is not set, using default value '%s'z7MinimalMark '%s' is not valid, using default value '%d'falsetruez7CleanupOnExit '%s' is not valid, using default value %sz>CleanupModulesOnExit '%s' is not valid, using default value %sz2Lockdown '%s' is not valid, using default value %sz7IPv6_rpfilter '%s' is not valid, using default value %sz9IndividualCalls '%s' is not valid, using default value %sz3LogDenied '%s' is invalid, using default value '%s'z:AutomaticHelpers '%s' is not valid, using default value %sz9FirewallBackend '%s' is not valid, using default value %sz:FlushAllOnReload '%s' is not valid, using default value %sz6RFC3964_IPv4 '%s' is not valid, using default value %sz;AllowZoneDrifting '%s' is not valid, using default value %s)r-r.)r+r4r*r5)r+r4r*r5)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)r*r5r+r4)%ropenr Exceptionrerrorr#rZ FALLBACK_ZONEstrZFALLBACK_MINIMAL_MARKZFALLBACK_CLEANUP_ON_EXITZ FALLBACK_CLEANUP_MODULES_ON_EXITZFALLBACK_LOCKDOWNZFALLBACK_IPV6_RPFILTERZFALLBACK_INDIVIDUAL_CALLSZFALLBACK_LOG_DENIEDZFALLBACK_AUTOMATIC_HELPERSZFALLBACK_FIREWALL_BACKENDZFALLBACK_FLUSH_ALL_ON_RELOADZFALLBACK_RFC3964_IPV4ZFALLBACK_ALLOW_ZONE_DRIFTINGrlensplit valid_keysrrcloseint ValueError TypeErrorZwarninglowerZLOG_DENIED_VALUESZAUTOMATIC_HELPERS_VALUESZFIREWALL_BACKEND_VALUES)rfmsglineZpairr"rrrreadFs                                       zfirewalld_conf.readc :Cst|jdkrdSg}tjjtjs2tjtjdy.tj ddtjj |j tjj |j dd}Wn2t k r}ztjd|WYdd}~XnXd}d}ytj|j dd d }WnPt k r}z0tjj|j rtjd |j |fnd}WYdd}~Xn6Xx0|D]&}|sP|jd }t|dkrH|s2|jd d }n|ddkrpd}|j||jd n|jd}t|dkrd}|j|d q |dj} |dj} | |kr.| |jkr|j| | krd}|jd| |j| fd }n$| |jkrd }nd}|j|d |j| nd }q Wt|jdkrx^|jjD]P\} } | |krjqT| dkrxqT|s|jd d }|jd| | fd }qTW|r|j|j|stj|jdStjj|j r@ytj|j d|j WnBt k r>}z$tj|jtd|j |fWYdd}~XnXytj|j|j WnBt k r}z$tj|jtd|j |fWYdd}~XnXtj|j ddS)Nr,iZwtz%s.F)modeprefixdirdeletez!Failed to open temporary file: %sZrtzUTF-8)rFencodingzFailed to open '%s': %sr%Trr-r2r3z%s=%s rrz%s.oldzBackup of '%s' failed: %szFailed to create '%s': %si)rr) r:rospathexistsrZ ETC_FIREWALLDmkdirtempfileZNamedTemporaryFilebasenamerdirnamer7rr8ior6rwriter;rappendr&r=r!nameshutilZcopy2IOErrorZmovechmod) rdoneZ temp_filerCZmodifiedemptyrBrDpr r"rrrrSs                  $ $zfirewalld_conf.writeN) __name__ __module__ __qualname__rrrrr#r(rErSrrrrr%s r)Zos.pathrKrRrOrVZfirewallrZfirewall.core.loggerrZfirewall.functionsrrrr<objectrrrrrs  PK!))!__pycache__/helper.cpython-36.pycnu[3 Yj @sdddgZddljZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZmZmZddlmZdd lmZdd lmZGd dde ZGd d d e ZddZdddZdS)Helper helper_reader helper_writerN)config) u2b_if_py2)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudp)log)errors) FirewallErrorcseZdZddddddd gffZdZd d gZd d dgd Zd ddgddgdZfddZddZ ddZ ddZ ddZ Z S)!rversionshort descriptionfamilymoduleportsz (sssssa(ss))-.N)rrhelpernameportprotocol)rrcs6tt|jd|_d|_d|_d|_d|_g|_dS)Nr) superr__init__rrrrrr)self) __class__/usr/lib/python3.6/helper.pyr;szHelper.__init__cCs.d|_d|_d|_d|_d|_|jdd=dS)Nr)rrrrrr)rr!r!r"cleanupDs zHelper.cleanupcCsRt|j|_t|j|_t|j|_t|j|_t|j|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSs g|]\}}t|t|fqSr!)r).0ZpoZprr!r!r" Usz)Helper.encode_strings..N)rrrrrrr)rr!r!r"encode_stringsLs      zHelper.encode_stringscCs(ddg}||kr$ttjd||fdS)NZipv4Zipv6z'%s' not in '%s')rrZ INVALID_IPV)rZipvZipvsr!r!r" check_ipvWszHelper.check_ipvcCsz|dkr0xl|D]}t|dt|dqWnF|dkrv|jdsRttjd|t|jdddkrvttjd|dS) Nrrr nf_conntrack_z('%s' does not start with 'nf_conntrack_'rzModule name '%s' too short)r r startswithrrINVALID_MODULElenreplace)rritemZ all_configrr!r!r" _check_config]s    zHelper._check_config)rr)rr)rr)rr)rr)rr)__name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr#r&r'r/ __classcell__r!r!)r r"r&s$     c@seZdZddZdS)helper_ContentHandlercCs>tj||||jj|||dkrd|kr8|d|j_d|kr\|jj|d|d|j_d|kr|djdstt j d|dt |dj dddkrtt j d |d|d|j_ nz|d krnp|d krnf|d kr:t|d t|d |d |d f}||jjkr$|jjj|ntjd|d |d dS)Nrrrrr)z('%s' does not start with 'nf_conntrack_'rr(zModule name '%s' too shortrrrrz#Port '%s/%s' already set, ignoring.)r startElementr.Zparser_check_element_attrsrr'rr*rrr+r,r-rr r rappendr Zwarning)rrattrsentryr!r!r"r5ns>      z"helper_ContentHandler.startElementN)r0r1r2r5r!r!r!r"r4msr4c Cst}|jds ttjd||dd |_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~tr|j|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid helper file: %s)rendswithrrZ INVALID_NAMErZ check_namefilenamepathr*r ETC_FIREWALLDZbuiltindefaultr4saxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_HELPERZ getExceptionrr&) r=r>rhandlerparserrfsourcemsgr!r!r"rs8        (c CsP|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|j|d <|jr|jd kr|j|d <|jr<|jd kr<|j|d <|jd ||jd|jr|jd kr|jd|jdi|j|j|jd|jd|jr|jd kr|jd|jdi|j|j|jd|jdx>|jD]4} |jd|jd| d| dd|jdqW|jd |jd|j|j~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingrrrrr z rrrrr()rr) r>r=rosexistsshutilZcopy2 Exceptionr errordirnamer*rr?mkdiriorBr Z startDocumentrrrr5ZignorableWhitespacerZ charactersZ endElementrrZ simpleElementZ endDocumentclose) rr>_pathrrHdirpathrFrDr7rr!r!r"rs\                       )N)__all__Zxml.saxrArLrSrNZfirewallrZfirewall.functionsrZfirewall.core.io.io_objectrrr r r r Zfirewall.core.loggerr rZfirewall.errorsrrr4rrr!r!r!r"s        G#PK!Vq/&__pycache__/ifcfg.cpython-36.opt-1.pycnu[3 Yj@s^dZdgZddlZddlZddlZddlZddlmZddl m Z m Z m Z Gddde ZdS)zifcfg file parserifcfgN)log)b2uu2bPY2c@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS)rcCsi|_g|_||_|jdS)N)_config_deletedfilenameclear)selfr r /usr/lib/python3.6/ifcfg.py__init__#szifcfg.__init__cCsi|_g|_dS)N)rr)r r r r r )sz ifcfg.clearcCs|jjdS)N)rr )r r r r cleanup-sz ifcfg.cleanupcCs|jj|jS)N)rgetstrip)r keyr r r r0sz ifcfg.getcCs8t|j}t|j|j|<||jkr4|jj|dS)N)rrrrremove)r rvalueZ_keyr r r set3s  z ifcfg.setcCsHd}x2|jjD]$\}}|r$|d7}|d||f7}qWtrDt|S|S)N z%s=%s)ritemsrr)r srrr r r __str__9s z ifcfg.__str__cCsB|jyt|jd}Wn4tk rL}ztjd|j|WYdd}~XnXx|D]}|s^P|j}t|dksT|ddkrqTdd|jd dD}t|d krqTt|dd kr|dj d r|dj d r|ddd|d<|dd krqTn,|j j |ddk r tj d |j|jqT|d|j |d<qTW|jdS)NrzFailed to load '%s': %sr#;cSsg|] }|jqSr )r).0xr r r Qszifcfg.read..="rz%%s: Duplicate option definition: '%s')rr)r openr Exceptionrerrorrlensplit startswithendswithrrZwarningclose)r fmsglineZpairr r r readBs2   z ifcfg.readc :Cst|jdkrdSg}y.tjddtjj|jtjj|jdd}Wn2t k rv}zt j d|WYdd}~XnXd}d}yt j |jddd }WnNt k r}z0tjj|jrt j d |j|fnd}WYdd}~XndXx^|D]T}|sP|jd }t|dkr(|sD|jd d }q|d dkrPd}|j||jd q|jdd}t|dkr~d}|j|d q|d j} |dj} t| dkr| jdr| jdr| dd} | |kr@| |jkr|j| | krd}|jd| |j| fd }n$| |jkr"d }nd}|j|d |j| qd }qWt|jd krxF|jjD]8\} } | |krzqd|sd }|jd| | fd }qdW|r|j|j|stj|jdStjj|jr8ytj|jd|jWnBt k r6}z$tj|jtd|j|fWYdd}~XnXytj|j|jWnBt k r}z$tj|jtd|j|fWYdd}~XnXtj|jddS)NrZwtz%s.F)modeprefixdirdeletez!Failed to open temporary file: %sZrtzUTF-8)r2encodingzFailed to open '%s': %srTrrr"r#r$z%s=%s z%s.bakzBackup of '%s' failed: %szFailed to create '%s': %sir%)r)rtempfileZNamedTemporaryFileospathbasenamer dirnamer'rr(ior&existsrwriter*r+r,rappendrr-rnameshutilZcopy2IOErrorZmovechmod) r doneZ temp_filer/Zmodifiedemptyr.r0prrr r r r>_s               $ $z ifcfg.writeN) __name__ __module__ __qualname__rr rrrrr1r>r r r r r"s )__doc____all__Zos.pathr8r<r7rAZfirewall.core.loggerrZfirewall.functionsrrrobjectrr r r r s PK!9),), __pycache__/ipset.cpython-36.pycnu[3 YjU@sdZdddgZddljZddlZddlZddlZddlmZddl m Z m Z m Z m Z mZmZmZmZmZddlmZmZmZmZdd lmZmZdd lmZmZmZmZdd l m!Z!dd lm"Z"dd l#m$Z$GdddeZ%GdddeZ&ddZ'dddZ(dS)z$ipset io XML handler, reader, writerIPSet ipset_reader ipset_writerN)config) checkIPcheckIP6 checkIPnMask checkIP6nMask u2b_if_py2 check_mac check_portcheckInterface checkProtocol)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator) IPSET_TYPESIPSET_CREATE_OPTIONS)check_icmp_namecheck_icmp_type_codecheck_icmpv6_namecheck_icmpv6_type_code)log)errors) FirewallErrorcseZdZddd d!dddifddgffZdZd d d d gZd d dgdgd dZdgdgdZfddZddZ ddZ e ddZ ddZ fddZZS)"rversionshort descriptiontypeoptionsentriesz (ssssa{ss}as)_-:.Nname)rripsetoptionentryvalue)r(r)cs<tt|jd|_d|_d|_d|_g|_i|_d|_ dS)NrF) superr__init__rrrr r"r!applied)self) __class__/usr/lib/python3.6/ipset.pyr-CszIPSet.__init__cCs8d|_d|_d|_d|_|jdd=|jjd|_dS)NrF)rrrr r"r!clearr.)r/r1r1r2cleanupMs  z IPSet.cleanupcCs\t|j|_t|j|_t|j|_t|j|_dd|jjD|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsi|]\}}t|t|qSr1)r ).0kvr1r1r2 ^sz(IPSet.encode_strings..cSsg|] }t|qSr1)r )r5er1r1r2 `sz(IPSet.encode_strings..N)r rrrr r!itemsr")r/r1r1r2encode_stringsVs    zIPSet.encode_stringscCsrd}d|kr|ddkrd}|jds6ttjd||ddjd}|jd}t|t|ksnt|d krttjd ||fxtt|D]}||}||}|d krd |ko|dkrh|d krttjd |||f|jd } t| dkrttjd||||fx| D]J} |dkr2t|  sH|dkrt |  rttjd| |||fqWnh|dkr|dkrttjd||||f|dkrt } nt} nt } | |sjttjd||||fq|dkr@d |kr|jd } t| dkrttjd||||f|dkr0t| d sJ|dkrft | d rfttjd| d|||f|dkrt | d  s|dkr>t | d  r>ttjd| d |||fn|j dr|dko|dko|dksttjd||||f|dkrt | s&|dkrjt | rjttjd||||fq|dkrvt | s`|dkrjttjd||fq|dkrld|krL|jd} t| dkrttjd|| ddkrP|dkrttjd||ft| d  rd| d krttjd| d |fn6| d jd\} } t| | sJttjd| d |fqj| dd2kr|dkr|ttjd||ft| d  rd| d krttjd"| d |fn6| d jd\} } t| | sJttjd"| d |fn^| dd3kr$t| d r$ttjd'| d|fn&t| d sjttjd(| d |fnt|sjttjd)||fq|d*kr |jd+ryt|d,}Wn*tk rttjd-||fYnXn8y t|}Wn*tk rttjd-||fYnX|dks |d.krjttjd-||fq|d/krZt| sDt|d0krjttjd1||fqttjd|qWdS)4NZipv4familyinet6Zipv6zhash:zipset type '%s' not usable,z)entry '%s' does not match ipset type '%s'Zipr$z invalid address '%s' in '%s'[%d]z.invalid address range '%s' in '%s' for %s (%s)z(invalid address '%s' in '%s' for %s (%s)z0.0.0.0rZnetz/0zhash:net,ifaceZmacz00:00:00:00:00:00z invalid mac address '%s' in '%s'Zportr%zinvalid port '%s'Zicmpz(invalid protocol for family '%s' in '%s'/zinvalid icmp type '%s' in '%s'icmpv6 ipv6-icmpz invalid icmpv6 type '%s' in '%s'tcpsctpudpudplitezinvalid protocol '%s' in '%s'zinvalid port '%s'in '%s'zinvalid port '%s' in '%s'ZmarkZ0xzinvalid mark '%s' in '%s'lZifacezinvalid interface '%s' in '%s')rDrE)rFrGrHrI) startswithrr INVALID_IPSETsplitlenZ INVALID_ENTRYrangerrrr endswithr rrrrrr int ValueErrorr )r*r!Z ipset_typer=flagsr;iflagitemZsplitsZ_splitZip_checkZ_type_codeZint_valr1r1r2 check_entrybsT                                  zIPSet.check_entrycCs|dkr |tkr ttjd||dkrx|jD]}|tkrNttjd||dkryt||}Wn,tk rttj d|||fYnX|d krttj d |||fq2|d kr2||dkr2ttj ||q2WdS)Nr z'%s' is not valid ipset typer!zipset invalid option '%s'timeouthashsizemaxelemz)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer=inetr>)rZr[r\)r]r>) rrr INVALID_TYPEkeysrrMrRrS INVALID_VALUEINVALID_FAMILY)r/rrWZ all_configkey int_valuer1r1r2 _check_config&s2   zIPSet._check_configcsrd|dkr6|dddkr6t|ddkr6ttjx&|dD]}tj||d|dq@Wtt|j|dS)NrZ0r?r)rOrrZIPSET_WITH_TIMEOUTrrYr, import_config)r/rr*)r0r1r2rhAs  zIPSet.import_config)rr)rr)rr)r r)__name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr-r4r< staticmethodrYrdrh __classcell__r1r1)r0r2r,s,       Ec@seZdZddZddZdS)ipset_ContentHandlerc Cstj||||jj|||dkrpd|krX|dtkrLttjd|d|d|j_d|krl|d|j_ nz|dkr|nn|dkrnb|dkrd}d |kr|d }|d dkrttj d|d |jjdko|d dkrttj d|d |jjf|d dkr&| r&ttj d|d |d dkry t |}Wn.t k rnttj d|d |fYnX|dkrttj d|d |f|d d kr|dkrttj||d |jjkr||jj|d <ntjd|d dS)Nr(r z%srrrr)rr+r'r=rZr[r\zUnknown option '%s'zhash:macz%Unsupported option '%s' for type '%s'z&Missing mandatory value of option '%s'z)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer]r>z Option %s already set, ignoring.)r=rZr[r\)r=)r=rZr[r\)rZr[r\)r]r>)r startElementrWZparser_check_element_attrsrrrr^r rZINVALID_OPTIONrRrSr`rar!rwarning)r/r'attrsr+rcr1r1r2roLsd      z!ipset_ContentHandler.startElementcCs(tj|||dkr$|jjj|jdS)Nr*)r endElementrWr"appendZ_element)r/r'r1r1r2rrs zipset_ContentHandler.endElementN)rirjrkrorrr1r1r1r2rnKs7rnc %Cst}|jds ttjd||dd|_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~d |jkrF|jd d krFt|jd krFtjd |j|jdd=d } t} x| t|jkr|j| | krtjd |j| |jj| nry|j |j| |j|j!Wn<tk r} ztjd| |jj| WYdd} ~ XnX| j"|j| | d7} qRW~ t#r|j$|S)Nz.xmlz'%s' is missing .xml suffixreFTz%s/%srbznot a valid ipset file: %srZrfrz6ipset '%s': timeout option is set, entries are ignoredzEntry %s already set, ignoring.z %s, ignoring.rA)%rrQrrZ INVALID_NAMEr'Z check_namefilenamepathrLr ETC_FIREWALLDZbuiltindefaultrnsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionrMZ getExceptionr!rOr"rrpsetpoprYr addrr<) rvrwr(handlerparserr'fsourcemsgrUZ entries_setr9r1r1r2rs^        (  c Cs|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|jd |ji}|jr|jd kr|j|d <|jd ||jd |jrz|jd krz|jd|jdi|j|j|jd|jd |jr|jd kr|jd|jdi|j|j|jd|jd xZ|jjD]L\} } |jd| d kr|jd| | dn|jdd| i|jd qWxD|jD]:} |jd|jdi|j| |jd|jd q(W|jd |jd |j|j ~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingr rrr( z rrr))r'r+r'r*)!rwrvr'osexistsshutilZcopy2 ExceptionrerrordirnamerLrrxmkdirior{rZ startDocumentr rroZignorableWhitespacerZ charactersrrrr!r;Z simpleElementr"Z endDocumentclose) r(rw_pathr'rdirpathrrrqrbr+r*r1r1r2rsf                           )N))__doc____all__Zxml.saxrzrrrZfirewallrZfirewall.functionsrrrr r r r r rZfirewall.core.io.io_objectrrrrZfirewall.core.ipsetrrZfirewall.core.icmprrrrZfirewall.core.loggerrrZfirewall.errorsrrrnrrr1r1r1r2s&   ,   !=5PK!z! $__pycache__/functions.cpython-36.pycnu[3 Yjy@sddlZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZdd lmZdd lmZdd lmZdd lmZdd lmZddZdS)N)config) FirewallError)FirewallConfig) zone_reader)service_reader) ipset_reader)icmptype_reader) helper_reader) policy_reader)Direct)LockdownWhitelist)firewalld_confc -Cs|t|}t|jtjtjgdt|jtjtj gdt |j tj tj gdt|jtjtjgdt|jtjtjgdt|jtjtjgdd}x |jD]}x||dD]}tjj|sqxttj|D]}|j dryD||d||}|d kr||_!|j"|j#||d|Wqt$k rT}zt$|j%d ||j&fWYdd}~Xqt'k r}zt'd ||fWYdd}~XqXqWqWqWtjj(tj)r:y$t*tj)}|j+|j,|j-Wnpt$k r}zt$|j%d tj)|j&fWYdd}~Xn6t'k r8}zt'd tj)|fWYdd}~XnXtjj(tj.ry$t/tj.}|j+|j,|j-Wnpt$k r}zt$|j%d tj.|j&fWYdd}~Xn6t'k r}zt'd tj.|fWYdd}~XnXtjj(tj0rxyt1tj0}|j+Wnpt$k rB}zt$|j%d tj0|j&fWYdd}~Xn6t'k rv}zt'd tj0|fWYdd}~XnXdS) N)readeradddirs)ZipsethelperZicmptypeZservicezonepolicyrz.xmlrrrrz'%s': %s)rr)2rrZ add_ipsetrZFIREWALLD_IPSETSZETC_FIREWALLD_IPSETSr Z add_helperZFIREWALLD_HELPERSZETC_FIREWALLD_HELPERSrZ add_icmptypeZFIREWALLD_ICMPTYPESZETC_FIREWALLD_ICMPTYPESrZ add_serviceZFIREWALLD_SERVICESZETC_FIREWALLD_SERVICESrZadd_zoneZFIREWALLD_ZONESZETC_FIREWALLD_ZONESr Zadd_policy_objectZFIREWALLD_POLICIESZETC_FIREWALLD_POLICIESkeysospathisdirsortedlistdirendswith fw_configZcheck_config_dictZexport_config_dictrcodemsg ExceptionisfileZFIREWALLD_DIRECTr read check_configZ export_configZLOCKDOWN_WHITELISTr ZFIREWALLD_CONFr ) fwrZreadersrZ_dirfileobjerrorrr&/usr/lib/python3.6/functions.pyr!&sz   &. ($ ($  (r!)rZfirewallrZfirewall.errorsrZfirewall.core.fw_configrZfirewall.core.io.zonerZfirewall.core.io.servicerZfirewall.core.io.ipsetrZfirewall.core.io.icmptyperZfirewall.core.io.helperr Zfirewall.core.io.policyr Zfirewall.core.io.directr Z#firewall.core.io.lockdown_whitelistr Zfirewall.core.io.firewalld_confr r!r&r&r&r's            PK!?xR`/`/*__pycache__/io_object.cpython-36.opt-1.pycnu[3 Yj5@sdZddddddddgZd d ljZd d ljjZd d lZd d lZd d lm Z d d l m Z d d l m Z d dl mZd dlmZejdkZGdddeZGdddeZGdddeZGdddeZGdddejjZGdddejZddZddZddZ ddZ!d S)z5Generic io_object handler, io specific check methods.PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudpcheck_protocol check_addressN) OrderedDict) functions)b2u)errors) FirewallError3c@s|eZdZdZfZdZgZiZiZddZ ddZ ddZ d d Z d d Z d dZddZddZddZddZddZdS)rz; Abstract IO_Object as base for icmptype, service and zone z()cCs"d|_d|_d|_d|_d|_dS)NF)filenamepathnamedefaultZbuiltin)selfr/usr/lib/python3.6/io_object.py__init__2s zIO_Object.__init__cCs6g}x(|jD]}|jtjt||dq Wt|S)Nr )IMPORT_EXPORT_STRUCTUREappendcopydeepcopygetattrtuple)rretxrrr export_config9s zIO_Object.export_configcCsXi}tdd|jD}x:|D]2}t||sAsz0IO_Object.export_config_dict..)dictrr isinstanceboolrr)rconf type_formatskeyrrrexport_config_dict?s  zIO_Object.export_config_dictcCs|j|xt|jD]~\}\}}t||tr~g}t}x,||D] }||krD|j||j|qDW~t||t j |qt||t j ||qWdS)N) check_config enumeraterr&listsetraddsetattrrr)rr(ielementZdummyZ_confZ_setr rrr import_configGs  zIO_Object.import_configc Cs~|j|xn|D]f}t||s0ttjdj|t||tr`t||tt j t j ||qt||t j ||qWdS)Nz-Internal error. '{}' is not a valid attribute) check_config_dicthasattrrr Z UNKNOWN_ERRORformatr&r.r1r fromkeysrr)rr(r*rrrimport_config_dictWs   "zIO_Object.import_config_dictcCszt|ts(ttjd|tdt|ft|dkr@ttjdx4|D],}|j rF||j krFttjd||fqFWdS)Nz'%s' not of type %s, but %srr"zname can't be emptyz'%s' is not allowed in '%s') r&strrr INVALID_TYPEtypelenZ INVALID_NAMEisalnumADDITIONAL_ALNUM_CHARS)rrcharrrr check_namecs     zIO_Object.check_namecCsjt|t|jkr0ttjdt|t|jfi}x&t|jD]\}\}}||||<q@W|j|dS)Nz structure size mismatch %d != %d)r=rrr r;r-r5)rr(Z conf_dictr2r yrrrr,pszIO_Object.check_configcCsrtdd|jD}xX|D]P}|dd|jDkrDttjdj||j|||||j||||qWdS)NcSsg|]}|d|dfqS)r r"r)r#r rrrr$|sz/IO_Object.check_config_dict..cSsg|] \}}|qSrr)r#r rBrrrr$~szoption '{}' is not valid)r%rrr ZINVALID_OPTIONr7_check_config_structure _check_config)rr(r)r*rrrr5{s  zIO_Object.check_config_dictcCsdS)Nr)rZdummy1Zdummy2Zdummy3rrrrDszIO_Object._check_configc Cs`t|t|s,ttjd|t|t|ft|trrt|dkrRttjd|x|D]}|j||dqXWnt|trt|t|krttjd|t|fxt |D]\}}|j|||qWnt|t r\t|j d\}}xn|j D]b\}}t|t|s,ttjd|t|t|ft|t|sttjd|t|t|fqWdS)Nz'%s' not of type %s, but %sr"zlen('%s') != 1r zlen('%s') != %d) r&r<rr r;r.r=rCrr-r%items) rr(Z structurer r2valueZskeyZsvaluer*rrrrCs8      z!IO_Object._check_config_structurecCs|j}d}||jkrdd}|j|dk rdx:|j|D],}||krL|j|q4ttjd||fq4W||jkrd}x$|j|D]}||kr~|j|q~W|sttjd|x |D]}ttjd||fqWdS)NFTzMissing attribute %s for %szUnexpected element %sz%s: Unexpected attribute %s)ZgetNamesPARSER_REQUIRED_ELEMENT_ATTRSremoverr Z PARSE_ERRORPARSER_OPTIONAL_ELEMENT_ATTRS)rrattrsZ_attrsfoundr rrrparser_check_element_attrss,     z$IO_Object.parser_check_element_attrsN)__name__ __module__ __qualname____doc__rZDBUS_SIGNATUREr?rGrIrr!r+r4r9rAr,r5rDrCrLrrrrr)s"   !cs$eZdZfddZddZZS)UnexpectedElementErrorcstt|j||_dS)N)superrQrr)rr) __class__rrrszUnexpectedElementError.__init__cCs d|jS)NzUnexpected element '%s')r)rrrr__str__szUnexpectedElementError.__str__)rMrNrOrrT __classcell__rr)rSrrQs rQcs$eZdZfddZddZZS)MissingAttributeErrorcstt|j||_||_dS)N)rRrVrr attribute)rrrW)rSrrrszMissingAttributeError.__init__cCsd|j|jfS)Nz$Element '%s': missing '%s' attribute)rrW)rrrrrTszMissingAttributeError.__str__)rMrNrOrrTrUrr)rSrrVs rVcs$eZdZfddZddZZS)UnexpectedAttributeErrorcstt|j||_||_dS)N)rRrXrrrW)rrrW)rSrrrsz!UnexpectedAttributeError.__init__cCsd|j|jfS)Nz'Element '%s': unexpected attribute '%s')rrW)rrrrrTsz UnexpectedAttributeError.__str__)rMrNrOrrTrUrr)rSrrXs rXc@s4eZdZddZddZddZddZd d Zd S) rcCs||_d|_dS)Nr)item_element)rrYrrrrsz!IO_Object_ContentHandler.__init__cCs d|_dS)Nr)rZ)rrrr startDocumentsz&IO_Object_ContentHandler.startDocumentcCs d|_dS)Nr)rZ)rrrJrrr startElementsz%IO_Object_ContentHandler.startElementcCs*|dkr|j|j_n|dkr&|j|j_dS)Nshort description)rZrYr]r^)rrrrr endElements z#IO_Object_ContentHandler.endElementcCs|j|jdd7_dS)N  )rZreplace)rcontentrrr characterssz#IO_Object_ContentHandler.charactersN)rMrNrOrr[r\r_rdrrrrrs c@s<eZdZddZddZddZddZd d Zd d Zd S)rcCsNtjjj||j|_|j|_ig|_|jd|_ g|_ d|_ d|_ d|_ dS)Nr"zutf-8F)saxhandlerContentHandlerrwrite_writeflushZ_flushZ _ns_contextsZ_current_contextZ_undeclared_ns_mapsZ _encodingZ_pending_start_elementZ_short_empty_elements)routrrrrs zIO_Object_XMLGenerator.__init__cCs*trdd|jD}tjj|||dS)a saxutils.XMLGenerator.startElement() expects name and attrs to be unicode and bad things happen if any of them is (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. cSsi|]\}}t|t|qSr)r )r#rrFrrr sz7IO_Object_XMLGenerator.startElement..N)rrEsaxutils XMLGeneratorr\)rrrJrrrr\sz#IO_Object_XMLGenerator.startElementcCstrX|jdt|x4|jD](\}}|jdt|tjt|fq W|jdnF|jd|x,|jD] \}}|jd|tj|fqpW|jddS)z* slightly modified startElement() N)rrjr rErnZ quoteattr)rrrJrFrrr simpleElements  z$IO_Object_XMLGenerator.simpleElementcCstjj|t|dS)z saxutils.XMLGenerator.endElement() expects name to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. N)rnror_r )rrrrrr_sz!IO_Object_XMLGenerator.endElementcCstjj|t|dS)z saxutils.XMLGenerator.characters() expects content to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. N)rnrordr )rrcrrrrd%sz!IO_Object_XMLGenerator.characterscCstjj|t|dS)a saxutils.XMLGenerator.ignorableWhitespace() expects content to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. N)rnroignorableWhitespacer )rrcrrrrr-sz*IO_Object_XMLGenerator.ignorableWhitespaceN) rMrNrOrr\rqr_rdrrrrrrrs  cCstj|}|dkr$ttjd|n`|dkr>ttjd|nF|dkrXttjd|n,t|dkr|d|dkrttjd|dS) Nzport number in '%s' is too bigr"z'%s' is invalid port rangezport range '%s' is ambiguousr re)r Z getPortRangerr Z INVALID_PORTr=)ZportZ port_rangerrrr5s    cCs|dkrttjd|dS)Ntcpudpsctpdccpz)'%s' not from {'tcp'|'udp'|'sctp'|'dccp'})rurvrwrx)rr INVALID_PROTOCOL)protocolrrrrDscCstj|sttj|dS)N)r Z checkProtocolrr ry)rzrrrrJs cCs$tj||s ttjd||fdS)Nz'%s' is not valid %s address)r rrr Z INVALID_ADDR)ZipvZaddrrrrrNs )"rP__all__Zxml.saxrfZxml.sax.saxutilsrnrsys collectionsr Zfirewallr Zfirewall.functionsr r Zfirewall.errorsrversionrobjectr ExceptionrQrVrXrgrhrrorrrrrrrrrs0           CPK! h%h%-__pycache__/lockdown_whitelist.cpython-36.pycnu[3 Yj1@sddljZddlZddlZddlZddlmZddlmZm Z m Z m Z ddl m Z ddlmZmZmZmZmZmZddlmZddlmZGdd d e ZGd d d e ZdS) N)config)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)log)uniqify checkUsercheckUid checkCommand checkContext u2b_if_py2)errors) FirewallErrorc@seZdZddZddZdS)!lockdown_whitelist_ContentHandlercCstj||d|_dS)NF)r__init__ whitelist)selfitemr(/usr/lib/python3.6/lockdown_whitelist.pyr%s z*lockdown_whitelist_ContentHandler.__init__c CsVtj||||jj|||dkr@|jr6ttjdd|_n|dkrr|js\tj ddS|d}|jj |n|dkr|jstj ddSd |kryt |d }Wn&t k rtj d |d dSX|jj |nd|kr|jj|dn\|d kr@|jstj d dSd |kr.tj ddS|jj|d ntj d|dSdS)NrzMore than one whitelist.Tcommandz)Parse Error: command outside of whitelistnameuserz&Parse Error: user outside of whitelistidz"Parse Error: %s is not a valid uidselinuxz)Parse Error: selinux outside of whitelistcontextzParse Error: no contextzUnknown XML element %s)r startElementrZparser_check_element_attrsrrrZ PARSE_ERRORrerror add_commandint ValueErroradd_uidadd_user add_context)rrZattrsruidrrrr)sJ        z.lockdown_whitelist_ContentHandler.startElementN)__name__ __module__ __qualname__rrrrrrr$srcs4eZdZdZddgfddgfddgfddgffZdZd gZd d gd d gd Zddd giZfddZ ddZ ddZ ddZ ddZ ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z d@dAZ!dBdCZ"Z#S)DLockdownWhitelistz LockdownWhitelist class commandscontextsusersuidsrz (asasasai)_Nrr)rrrrrrcs6tt|j||_d|_g|_g|_g|_g|_dS)N) superr)rfilenameparserr*r,r-r.)rr1) __class__rrrnszLockdownWhitelist.__init__cCs|d kr.x|D]}|j||dd |qWnv|dkrLt|sttj|nX|dkrjt|sttj|n:|dkrt|sttj|n|d krt |sttj |dS) Nr*r,r-r.rrrr%)r*r,r-r.) _check_configr rrINVALID_COMMANDr INVALID_CONTEXTr INVALID_USERr INVALID_UID)rrrZ all_configxrrrr6ys zLockdownWhitelist._check_configcCs4|jdd=|jdd=|jdd=|jdd=dS)N)r*r,r-r.)rrrrcleanups   zLockdownWhitelist.cleanupcCs:dd|jD|_dd|jD|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsg|] }t|qSr)r ).0r;rrr sz4LockdownWhitelist.encode_strings..cSsg|] }t|qSr)r )r=r;rrrr>scSsg|] }t|qSr)r )r=r;rrrr>sN)r*r,r-)rrrrencode_stringssz LockdownWhitelist.encode_stringscCs@t|sttj|||jkr,|jj|nttjd|dS)Nz!Command "%s" already in whitelist)r rrr7r*appendALREADY_ENABLED)rrrrrrs   zLockdownWhitelist.add_commandcCs,||jkr|jj|nttjd|dS)NzCommand "%s" not in whitelist.)r*removerr NOT_ENABLED)rrrrrremove_commands z LockdownWhitelist.remove_commandcCs ||jkS)N)r*)rrrrr has_commandszLockdownWhitelist.has_commandcCsBx<|jD]2}|jdr.|j|ddr:dSq||krdSqWdS)N*r4TFr5)r*endswith startswith)rrZ_commandrrr match_commands  zLockdownWhitelist.match_commandcCs|jS)N)r*)rrrr get_commandsszLockdownWhitelist.get_commandscCsDt|sttjt|||jkr0|jj|nttjd|dS)NzUid "%s" already in whitelist)r rrr:strr.r@rA)rr%rrrr"s  zLockdownWhitelist.add_uidcCs,||jkr|jj|nttjd|dS)NzUid "%s" not in whitelist.)r.rBrrrC)rr%rrr remove_uids zLockdownWhitelist.remove_uidcCs ||jkS)N)r.)rr%rrrhas_uidszLockdownWhitelist.has_uidcCs ||jkS)N)r.)rr%rrr match_uidszLockdownWhitelist.match_uidcCs|jS)N)r.)rrrrget_uidsszLockdownWhitelist.get_uidscCs@t|sttj|||jkr,|jj|nttjd|dS)NzUser "%s" already in whitelist)r rrr9r-r@rA)rrrrrr#s   zLockdownWhitelist.add_usercCs,||jkr|jj|nttjd|dS)NzUser "%s" not in whitelist.)r-rBrrrC)rrrrr remove_users zLockdownWhitelist.remove_usercCs ||jkS)N)r-)rrrrrhas_userszLockdownWhitelist.has_usercCs ||jkS)N)r-)rrrrr match_userszLockdownWhitelist.match_usercCs|jS)N)r-)rrrr get_usersszLockdownWhitelist.get_userscCs@t|sttj|||jkr,|jj|nttjd|dS)Nz!Context "%s" already in whitelist)r rrr8r,r@rA)rrrrrr$"s   zLockdownWhitelist.add_contextcCs,||jkr|jj|nttjd|dS)NzContext "%s" not in whitelist.)r,rBrrrC)rrrrrremove_context,s z LockdownWhitelist.remove_contextcCs ||jkS)N)r,)rrrrr has_context3szLockdownWhitelist.has_contextcCs ||jkS)N)r,)rrrrr match_context6szLockdownWhitelist.match_contextcCs|jS)N)r,)rrrr get_contexts9szLockdownWhitelist.get_contextscCs|j|jjds&ttjd|jt|}tj}|j |y|j |jWn8tj k r}zttj d|j WYdd}~XnX~~tr|jdS)Nz.xmlz'%s' is missing .xml suffixzNot a valid file: %s)r<r1rGrrZ INVALID_NAMErsaxZ make_parserZsetContentHandlerparseZSAXParseExceptionZ INVALID_TYPEZ getExceptionrr?)rhandlerr2msgrrrread>s"   zLockdownWhitelist.readcCstjj|jr\ytj|jd|jWn4tk rZ}ztd|j|fWYdd}~XnXtjjtj sxtj tj dt j |jddd}t |}|j|jdi|jdx6t|jD](}|jd |jd d |i|jdqWx:t|jD],}|jd |jd d t|i|jdqWx8t|jD]*}|jd |jd d |i|jdq0Wx8t|jD]*}|jd |jdd|i|jdqjW|jd|jd|j|j~dS)Nz%s.oldzBackup of '%s' failed: %siZwtzUTF-8)modeencodingr z rrrrrr)ospathexistsr1shutilZcopy2 ExceptionIOErrorrZ ETC_FIREWALLDmkdirioopenrZ startDocumentrZignorableWhitespacerr*Z simpleElementr.rKr-r,Z endElementZ endDocumentclose)rr[frZrr%rrrrrwriteQsB$         zLockdownWhitelist.write)$r&r'r(__doc__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr6r<r?rrDrErIrJr"rLrMrNrOr#rPrQrRrSr$rTrUrVrWr\rk __classcell__rr)r3rr)WsL         1 r))Zxml.saxrXr`rgrcZfirewallrZfirewall.core.io.io_objectrrrrZfirewall.core.loggerrZfirewall.functionsrr r r r r rZfirewall.errorsrrr)rrrrs      3PK!(# "__pycache__/service.cpython-36.pycnu[3 Yj2@sdddgZddljZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZmZmZmZmZddlmZdd lmZdd lmZGd dde ZGd d d e ZddZdddZdS)Serviceservice_readerservice_writerN)config) u2b_if_py2)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudpcheck_protocol check_address)log)errors) FirewallErrorc seZdZd d!d"dd#gfddgfdddifddgfd d$gfd dgfd dgff Zd d gZddddZddgddgdgdgddgddgdgdgdZfddZddZddZ ddZ Z S)%rversionshort descriptionportsmodules destination protocols source_portsincludeshelpers_-N)rrservicenameportprotocolvalueipv4ipv6r)rr!r"modulerz source-portincludehelpercsNtt|jd|_d|_d|_g|_g|_g|_i|_ g|_ g|_ g|_ dS)Nr) superr__init__rrrrrrrrrr)self) __class__/usr/lib/python3.6/service.pyr*DszService.__init__cCshd|_d|_d|_|jdd=|jdd=|jdd=|jj|jdd=|j dd=|j dd=dS)Nr) rrrrrrrclearrrr)r+r-r-r.cleanupQs      zService.cleanupcCst|j|_t|j|_t|j|_dd|jD|_dd|jD|_dd|jjD|_dd|jD|_dd|j D|_ dd|j D|_ d d|j D|_ d S) z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSs g|]\}}t|t|fqSr-)r).0poprr-r-r. dsz*Service.encode_strings..cSsg|] }t|qSr-)r)r1mr-r-r.r4escSsi|]\}}t|t|qSr-)r)r1kvr-r-r. fsz*Service.encode_strings..cSsg|] }t|qSr-)r)r1r3r-r-r.r4gscSs g|]\}}t|t|fqSr-)r)r1r2r3r-r-r.r4hscSsg|] }t|qSr-)r)r1sr-r-r.r4jscSsg|] }t|qSr-)r)r1r9r-r-r.r4ksN) rrrrrrritemsrrrr)r+r-r-r.encode_strings]s    zService.encode_stringscCs:|dkrJx>|D]6}|ddkr8t|dt|dqt|dqWn|dkrjx|D] }t|qXWn|dkrx|D]}t|dt|dqxWn|dkrx|D]*}|dkrttjd |t|||qWn^|d kr6xR|D]J}|jd r|jd d}d |kr|jd d}t |dkrttj |qWdS)Nrrrrrrr$r%z'%s' not in {'ipv4'|'ipv6'}r nf_conntrack_rr)r$r%) r r r rrZINVALID_DESTINATIONr startswithreplacelenZINVALID_MODULE)r+ritemZ all_configr!protorr&r-r-r. _check_configms8              zService._check_config)rr)rr)rr)rr)rr) __name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr*r0r;rD __classcell__r-r-)r,r.r&s4     c@seZdZddZdS)service_ContentHandlercCs0tj||||jj|||dkrTd|krxRdD]J}||krt|||||jjkr&tjd|n|||jj|<qWn|dkr|d}|jdr~|jdd}d|kr~|jdd}||jjkr|jjj |n tjd|n|dkr|d|jjkr|jjj |dntjd|dn@|dkr,|d|jjkr|jjj |dntjd|ddS)Nrr z'Ignoring deprecated attribute name='%s'rrrr!rr"z#Port '%s/%s' already set, ignoring.z$Protocol '%s' already set, ignoring.r#z source-portz)SourcePort '%s/%s' already set, ignoring.rr$r%z2Destination address for '%s' already set, ignoringr&r=rrz"Module '%s' already set, ignoring.r'z#Include '%s' already set, ignoring.r(z"Helper '%s' already set, ignoring.)r$r%)r startElementrBZparser_check_element_attrsrZwarningrr r rappendr rrrrr?r@rrr)r+r attrsentryxr&r-r-r.rJs                       z#service_ContentHandler.startElementN)rErFrGrJr-r-r-r.rIsrIc Cst}|jds ttjd||dd |_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~tr|j|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid service file: %s)rendswithrrZ INVALID_NAMEr Z check_namefilenamepathr?r ETC_FIREWALLDZbuiltindefaultrIsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_SERVICEZ getExceptionrr;) rSrTrhandlerparserr fsourcemsgr-r-r.rs8        (cCsr|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|jd ||jd |jrt|jd krt|jd |jdi|j|j|jd|jd |jr|jd kr|jd |jdi|j|j|jd|jd x>|jD]4} |jd |jd| d| dd|jd qWx4|jD]*} |jd |jdd| i|jd qWx>|jD]4} |jd |jd| d| dd|jd qs    (   mQPK!g22__pycache__/zone.cpython-36.pycnu[3 YjM@sdddgZddljZddlZddlZddlZddlmZddlm Z m Z m Z m Z m Z mZmZddlmZmZddlmZmZmZmZdd lmZmZmZmZdd lmZdd lm Z dd lm!Z!dd l"m#Z#GdddeZ$GdddeZ%dddZ&dddZ'dS)Zone zone_reader zone_writerN)config) checkIPnMask checkIP6nMaskcheckInterfaceuniqifymax_zone_name_len u2b_if_py2 check_mac)DEFAULT_ZONE_TARGET ZONE_TARGETS)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)common_startElementcommon_endElementcommon_check_config common_writer)rich)log)errors) FirewallErrorcsfeZdZdZd@dAdBdCdDd dgfd dEgfd dgfdFd dGgfddgfddgfddgfddgfddHgfdIdJfZdddgZddddgddgdgdgdddgdgddddgddgddddddgdgddZddddgd gd!d"gd#d$gd%d&d'd#d(gd%d'd(gd)d*gd+gd,gd- Zed.d/Z fd0d1Z d2d3Z d4d5Z fd6d7Z fd8d9Zd:d;Zfdd?ZZS)Krz Zone class versionshort descriptionUNUSEDFtargetservicesports icmp_blocks masquerade forward_ports interfacessources rules_str protocols source_portsicmp_block_inversionforward_-/Nnameportprotocolvalueset)rrzoneservicer1z icmp-blockz icmp-typer,z forward-port interfacerulesource destinationr2z source-portrZauditZacceptrejectZdropZmarklimitzicmp-block-inversion immutableZenabledzto-portzto-addrfamilyZpriorityaddressmacinvertipsetprefixleveltypeZburst) r5r$z forward-portr8r9r:rr;r<cCs8x&ttjD]\}\}}||kr |Sq WttjddS)Nz index_of()) enumeraterIMPORT_EXPORT_STRUCTURErrZ UNKNOWN_ERROR)elementiZelZdummyrJ/usr/lib/python3.6/zone.pyindex_ofdsz Zone.index_ofcstt|jd|_d|_d|_d|_t|_g|_ g|_ g|_ g|_ d|_ d|_g|_g|_g|_g|_d|_g|_g|_d|_d|_d|_dS)NrF)superr__init__rrrrr r r!r"r)r#r,r$r%r*r&r' fw_configrulesr(r+combinedapplied)self) __class__rJrKrNks,z Zone.__init__cCsd|_d|_d|_d|_t|_|jdd=|jdd=|jdd=|j dd=d|_ d|_ |j dd=|j dd=|jdd=|jdd=d|_|jdd=|jdd=d|_d|_d|_dS)NrF)rrrrr r r!r"r)r#r,r$r%r*r&r'rOrPr(r+rQrR)rSrJrJrKcleanups*          z Zone.cleanupcCst|j|_t|j|_t|j|_t|j|_dd|jD|_dd|jD|_dd|jD|_dd|jD|_dd|j D|_ dd|j D|_ dd|j D|_ d d|j D|_ d d|j D|_ d d|jD|_d S) z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsg|] }t|qSrJ)r ).0srJrJrK sz'Zone.encode_strings..cSs g|]\}}t|t|fqSrJ)r )rVpoprrJrJrKrXscSsg|] }t|qSrJ)r )rVrZrJrJrKrXscSsg|] }t|qSrJ)r )rVrIrJrJrKrXscSs0g|](\}}}}t|t|t|t|fqSrJ)r )rVZp1Zp2Zp3Zp4rJrJrKrXscSs g|]\}}t|t|fqSrJ)r )rVrYrZrJrJrKrXscSsg|] }t|qSrJ)r )rVrIrJrJrKrXscSsg|] }t|qSrJ)r )rVrWrJrJrKrXscSsg|] }t|qSrJ)r )rVrWrJrJrKrXscSsg|] }t|qSrJ)r )rVrWrJrJrKrXsN)r rrrr r!r"r)r#r%r*r&r'rPr()rSrJrJrKencode_stringss     zZone.encode_stringscsN|dkr8dd|D|_tt|j|dd|jDntt|j||dS)Nr(cSsg|]}tj|dqS))Zrule_str)rZ Rich_Rule)rVrWrJrJrKrXsz$Zone.__setattr__..cSsg|] }t|qSrJ)str)rVrWrJrJrKrXs)rPrMr __setattr__)rSr0r3)rTrJrKr]s zZone.__setattr__cstt|j}|d=|S)Nr)rMrexport_config_dict)rSZconf)rTrJrKr^szZone.export_config_dictcCsLt|||||dkr.|tkr*ttj|n|dkrxl|D]d}t|sTttj||jr}||j krq||jj |jkrttjdj ||qWqWdS)Nr r&z)interface '{}' already bound to zone '{}'r'zipset:z&source '{}' already bound to zone '{}')rrrrINVALID_TARGETrZINVALID_INTERFACErOZ get_zonesr0Zget_zoner&formatrrr startswith INVALID_ADDRr')rSritemZ all_configr7r5r9rJrJrK _check_configs6       zZone._check_configcstt|j||jdr,ttjd|n|jdrHttjd|n|jddkrhttjd|nnd|kr|d|j d}n|}t |t krttjd|t |t |j f|j r||j jkrttjddS)Nr/z'%s' can't start with '/'z'%s' can't end with '/'zmore than one '/' in '%s'z'Zone of '%s' has %d chars, max is %d %sz+Zones can't have the same name as a policy.)rMr check_namerarr INVALID_NAMEendswithcountfindlenr rQrOZget_policy_objectsZ NAME_CONFLICT)rSr0Z checked_name)rTrJrKrfs,      zZone.check_namec Csd|_d|_d|_d|_d|_x$|jD]}||jkr&|jj|q&Wx$|jD]}||jkrL|jj|qLWx$|jD]}||jkrr|jj|qrWx$|j D]}||j kr|j j|qWx$|j D]}||j kr|j j|qWx$|j D]}||j kr|j j|qW|j rd|_ |j rd|_ x(|jD]}||jkr&|jj|q&Wx(|jD]}||jkrP|jj|qPWx,|jD]"} |jj| |jjt| qzW|jrd|_dS)NTr)rQfilenamerrrr&appendr'r!r"r)r#r,r$r%r*rPr(r\r+) rSr5r7r9r6r1protoZicmpr,r8rJrJrKcombinesL                  z Zone.combine)rr)rr)rr)rF)r r)rr)r$F)rrrr)rr)r+F)r,F)__name__ __module__ __qualname____doc__rGZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRS staticmethodrLrNrUr[r]r^rdrfro __classcell__rJrJ)rTrKr(sx         c@s$eZdZddZddZddZdS)zone_ContentHandlercCs"tj||d|_d|_d|_dS)NF)rrN_rule _rule_errorZ _limit_ok)rSrcrJrJrKrN s zzone_ContentHandler.__init__c Cstj||||jrdS|jj||t|||r6dS|dkrd|krVtjd|dd|krj|d|j_d|krtjd|dd|kr|d}|t krt t j ||dkr|t kr||j_n|d kr|jjrtjd nd |j_n|d krh|jrtjd d |_dSd|kr.tjdd |_dS|d|jjkrT|jjj|dntjd|dn8|dkrf|jr |jjrtjdt|jd |_dSd}d|kr|djd$krd }d}}}d|kr|d}d|kr|d}d|kr|d}tj||||d|j_dSd|krBd|krBtjddSd|krdd|krdtjddSd|kr~tjd|dd|krtjddSd|krt|d rt|d rt|d rt t j|dd|kr$d|d}||jjkr|jjj|ntjd |dd|kr|d}||jjkrT|jjj|ntjd |dn:|d!kr|jjrtjd"nd |j_ntjd#|dSdS)%Nr5r0z'Ignoring deprecated attribute name='%s'rr=z,Ignoring deprecated attribute immutable='%s'r rr,zForward already set, ignoring.Tr7z$Invalid rule: interface use in rule.z Invalid interface: Name missing.z%Interface '%s' already set, ignoring.r9z:Invalid rule: More than one source in rule '%s', ignoring.FrAyestruer?r@rB)rAz$Invalid source: No address no ipset.z"Invalid source: Address and ipset.r>z)Ignoring deprecated attribute family='%s'z+Invalid source: Invertion not allowed here.zipset:%sz"Source '%s' already set, ignoring.zicmp-block-inversionz+Icmp-Block-Inversion already set, ignoring.zUnknown XML element '%s')ryrz)r startElementrxrcZparser_check_element_attrsrrZwarningrrrrr_r r r,rwr&rmr9r\lowerrZ Rich_Sourcerrr rbr'r+) rSr0attrsr rAZaddrr@rBentryrJrJrKr{&s                                       z zone_ContentHandler.startElementcCstj||t||dS)N)r endElementr)rSr0rJrJrKrs zzone_ContentHandler.endElementN)rprqrrrNr{rrJrJrJrKrvsprvFc Cst}|jds ttjd||dd |_|s>|j|j||_||_|j t j rZdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r} zttjd| jWYdd} ~ XnXWdQRX~~tr|j|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid zone file: %s)rrhrrrgr0rfrlpathrar ETC_FIREWALLDZbuiltindefaultrvsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZ INVALID_ZONEZ getExceptionrr[) rlrZ no_check_namer5handlerparserr0fr9msgrJrJrKrs:        (c Cs\|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|jtkr*|j|d <|jd ||jd t||x8t|jD]*} |jd|jdd| i|jd qVWx\t|jD]N} |jdd| kr|jdd| ddin|jdd| i|jd qW|jr |jd|jdi|jd |jr2|jd|jdi|jd |jd |jd |j |j!~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingrrr r5 z r7r0zipset:r9rBr?zicmp-block-inversionr,)"rrlr0osexistsshutilZcopy2 ExceptionrerrordirnamerarrmkdiriorrZ startDocumentrr r r{ZignorableWhitespacerr r&Z simpleElementr'r+r,rZ endDocumentclose) r5r_pathr0rdirpathrrr}r7r9rJrJrKrs`                     )F)N)(__all__Zxml.saxrrrrZfirewallrZfirewall.functionsrrrr r r r Zfirewall.core.baser rZfirewall.core.io.io_objectrrrrZfirewall.core.io.policyrrrrZ firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrrvrrrJrJrJrKs$   $    x| PK!Vq/ __pycache__/ifcfg.cpython-36.pycnu[3 Yj@s^dZdgZddlZddlZddlZddlZddlmZddl m Z m Z m Z Gddde ZdS)zifcfg file parserifcfgN)log)b2uu2bPY2c@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS)rcCsi|_g|_||_|jdS)N)_config_deletedfilenameclear)selfr r /usr/lib/python3.6/ifcfg.py__init__#szifcfg.__init__cCsi|_g|_dS)N)rr)r r r r r )sz ifcfg.clearcCs|jjdS)N)rr )r r r r cleanup-sz ifcfg.cleanupcCs|jj|jS)N)rgetstrip)r keyr r r r0sz ifcfg.getcCs8t|j}t|j|j|<||jkr4|jj|dS)N)rrrrremove)r rvalueZ_keyr r r set3s  z ifcfg.setcCsHd}x2|jjD]$\}}|r$|d7}|d||f7}qWtrDt|S|S)N z%s=%s)ritemsrr)r srrr r r __str__9s z ifcfg.__str__cCsB|jyt|jd}Wn4tk rL}ztjd|j|WYdd}~XnXx|D]}|s^P|j}t|dksT|ddkrqTdd|jd dD}t|d krqTt|dd kr|dj d r|dj d r|ddd|d<|dd krqTn,|j j |ddk r tj d |j|jqT|d|j |d<qTW|jdS)NrzFailed to load '%s': %sr#;cSsg|] }|jqSr )r).0xr r r Qszifcfg.read..="rz%%s: Duplicate option definition: '%s')rr)r openr Exceptionrerrorrlensplit startswithendswithrrZwarningclose)r fmsglineZpairr r r readBs2   z ifcfg.readc :Cst|jdkrdSg}y.tjddtjj|jtjj|jdd}Wn2t k rv}zt j d|WYdd}~XnXd}d}yt j |jddd }WnNt k r}z0tjj|jrt j d |j|fnd}WYdd}~XndXx^|D]T}|sP|jd }t|dkr(|sD|jd d }q|d dkrPd}|j||jd q|jdd}t|dkr~d}|j|d q|d j} |dj} t| dkr| jdr| jdr| dd} | |kr@| |jkr|j| | krd}|jd| |j| fd }n$| |jkr"d }nd}|j|d |j| qd }qWt|jd krxF|jjD]8\} } | |krzqd|sd }|jd| | fd }qdW|r|j|j|stj|jdStjj|jr8ytj|jd|jWnBt k r6}z$tj|jtd|j|fWYdd}~XnXytj|j|jWnBt k r}z$tj|jtd|j|fWYdd}~XnXtj|jddS)NrZwtz%s.F)modeprefixdirdeletez!Failed to open temporary file: %sZrtzUTF-8)r2encodingzFailed to open '%s': %srTrrr"r#r$z%s=%s z%s.bakzBackup of '%s' failed: %szFailed to create '%s': %sir%)r)rtempfileZNamedTemporaryFileospathbasenamer dirnamer'rr(ior&existsrwriter*r+r,rappendrr-rnameshutilZcopy2IOErrorZmovechmod) r doneZ temp_filer/Zmodifiedemptyr.r0prrr r r r>_s               $ $z ifcfg.writeN) __name__ __module__ __qualname__rr rrrrr1r>r r r r r"s )__doc____all__Zos.pathr8r<r7rAZfirewall.core.loggerrZfirewall.functionsrrrobjectrr r r r s PK!I>..'__pycache__/direct.cpython-36.opt-1.pycnu[3 Yj=@sddljZddlZddlZddlZddlmZddlmZddl m Z m Z m Z ddl mZmZmZddlmZddlmZddlmZdd lmZdd lmZGd d d eZGd ddeZdS)N)config)LastUpdatedOrderedDict) splitArgsjoinArgs u2b_if_py2) IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)log) ipXtables)ebtables)errors) FirewallErrorc@s$eZdZddZddZddZdS)direct_ContentHandlercCstj||d|_dS)NF)r__init__direct)selfitemr/usr/lib/python3.6/direct.pyr(s zdirect_ContentHandler.__init__c Cstj||||jj|||dkr@|jr6ttjdd|_n>|dkr|js\tj ddS|d}|d}|d}|jj t |t |t |n|dkr6|jstj d dS|d}|dkrttj d ||d}|d}yt |d}Wn(tk rtj d|ddSXt |t |t ||g|_nH|dkrl|jsVtj ddS|d}t |g|_ntj d|dSdS)NrzMore than one direct tag.Tchainz$Parse Error: chain outside of directipvtablerulez#Parse Error: rule outside of directipv4ipv6ebz"'%s' not from {'ipv4'|'ipv6'|'eb'}priorityz'Parse Error: %s is not a valid priority passthroughz&Parse Error: command outside of directzUnknown XML element %s)rrr)r startElementrZparser_check_element_attrsrrr Z PARSE_ERRORr error add_chainr INVALID_IPVint ValueError_rule _passthrough)rnameZattrsrrrrrrrr,sT          z"direct_ContentHandler.startElementcCstj|||dkrX|jrF|jjddt|jD|jj|jn tj dd|_nJ|dkr|jr|j jddt|jD|jj |j n tj d d|_ dS) NrcSsg|] }t|qSr)r).0xrrr dsz4direct_ContentHandler.endElement..z2Error: rule does not have any arguments, ignoring.rcSsg|] }t|qSr)r)r(r)rrrr*msz0Error: passthrough does not have any arguments, z ignoring.z9Error: passthrough does not have any arguments, ignoring.) r endElementZ_elementr%appendrradd_ruler r r&add_passthrough)rr'rrrr+^s     z direct_ContentHandler.endElementN)__name__ __module__ __qualname__rrr+rrrrr's2rcs<eZdZdZddBgfddddddgfgfdddgfgffZdZdd d d gd d d d gd gd ZiZfddZddZ ddZ ddZ ddZ ddZ ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z d@dAZ!Z"S)CDirectz Direct class chainsrulesr passthroughsz(a(sss)a(sssias)a(sas))Nrrrr)rrrrcs0tt|j||_t|_t|_t|_dS)N)superr2rfilenamerr3r5r6)rr8) __class__rrrs zDirect.__init__cCsdS)Nr)rconfrZall_confrrr _check_configszDirect._check_configc Csg}g}x>|jD]4}x.|j|D] }|jtt|t|gq WqW|j|g}xR|jD]H}xB|j|D]4}|jt|d|d|d|dt|dfqnWq^W|j|g}x8|jD].}x(|j|D]}|jt|t|fqWqW|j|t|S)Nr)r3r,tuplelistr5r6)rretr)keyrrrrr export_configs$ $     zDirect.export_configcCs|j|j|xt|jD]x\}\}}|dkrNx||D]}|j|qr rRrL)rrrrrrMrAvaluerrrr-s     zDirect.add_rulecCs|j|||||f}|t|f}||jkrb||j|krb|j||=t|j|dkr|j|=n$tddj|||fd||fdS)Nrz(Rule '%s' for table '%s' and chain '%s' z',z)with ipv '%s' and priority %d not in list)rQr>r5rTr$rL)rrrrrrMrArYrrr remove_rules     zDirect.remove_rulecCsb|j|||||f}||jkr^x"|j|jD]}|j||=q0Wt|j|dkr^|j|=dS)Nr)rQr5rPrT)rrrrrArYrrr remove_rules"s   zDirect.remove_rulescCs:|j|||||f}|t|f}||jko8||j|kS)N)rQr>r5)rrrrrrMrArYrrr query_rule+s   zDirect.query_rulecCsF|j|||||f}||jkr*|j|Std||fd|dS)Nz'No rules for table '%s' and chain '%s' z with ipv '%s')rQr5r$)rrrrrArrr get_rules1s     zDirect.get_rulescCs|jS)N)r5)rrrr get_all_rules:szDirect.get_all_rulescCs^|j|||jkrg|j|<||j|kr>|j|j|ntjddj||fddS)NzPassthrough '%s' for ipv '%s'z',zalready in list, ignoring)rOr6r,r rRrL)rrrMrrrr.?s   zDirect.add_passthroughcCsl|j|||jkrN||j|krN|j|j|t|j|dkrh|j|=ntddj||fddS)NrzPassthrough '%s' for ipv '%s'z',z not in list)rOr6rSrTr$rL)rrrMrrrremove_passthroughIs  zDirect.remove_passthroughcCs"|j|||jko ||j|kS)N)rOr6)rrrMrrrquery_passthroughSs zDirect.query_passthroughcCs.|j|||jkr|j|Std|dS)NzNo passthroughs for ipv '%s')rOr6r$)rrrrrget_passthroughsWs   zDirect.get_passthroughscCs|jS)N)r6)rrrrget_all_passthroughs^szDirect.get_all_passthroughscCs|j|jjds&ttjd|jt|}tj}|j |t |jdb}tj d}|j |y|j |Wn8tjk r}zttjd|jWYdd}~XnXWdQRXdS)Nz.xmlz'%s' is missing .xml suffixrbzNot a valid file: %s)rCr8endswithrr Z INVALID_NAMErsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZ INVALID_TYPEZ getException)rhandlerparserfsourcemsgrrrreadcs      z Direct.readc CsBtjj|jr\ytj|jd|jWn4tk rZ}ztd|j|fWYdd}~XnXtjjtj sxtj tj dt j |jddd}t |}|j|jdi|jdxR|jD]H}|\}}x:|j|D],}|jd |jd |||d |jdqWqWx|jD]}|\}}}xx|j|D]j\}} t| d kr@q&|jd |jd |||d|d|jtjjt| |jd |jdq&Wq Wx||jD]r}xj|j|D]\} t| d krȐq|jd |jdd|i|jtjjt| |jd|jdqWqW|jd|jd|j|j~dS)Nz%s.oldzBackup of '%s' failed: %siZwtzUTF-8)modeencodingr z r)rrrr<rz%d)rrrrrr)ospathexistsr8shutilZcopy2 ExceptionIOErrorrZ ETC_FIREWALLDmkdiriorfr Z startDocumentrZignorableWhitespacer3Z simpleElementr5rTreZsaxutilsescaperr+r6Z endDocumentclose) rrlrjrhrArrrrrMrrrwriteusZ$                z Direct.write)r4r4r4)#r/r0r1__doc__rEZDBUS_SIGNATUREZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr;rBrHrCrNrOrQr!rUrVrWrXr-rZr[r\r]r^r.r_r`rarbrmr{ __classcell__rr)r9rr2usH            r2)Zxml.saxrerqrxrtZfirewallrZfirewall.fw_typesrZfirewall.functionsrrrZfirewall.core.io.io_objectrrr Zfirewall.core.loggerr Z firewall.corer r r Zfirewall.errorsrrr2rrrrs        NPK!r#__pycache__/__init__.cpython-36.pycnu[3 Yj<@sjddlZdejkrfddlmZeedss      PK!r)__pycache__/__init__.cpython-36.opt-1.pycnu[3 Yj<@sjddlZdejkrfddlmZeedss      PK!9),),&__pycache__/ipset.cpython-36.opt-1.pycnu[3 YjU@sdZdddgZddljZddlZddlZddlZddlmZddl m Z m Z m Z m Z mZmZmZmZmZddlmZmZmZmZdd lmZmZdd lmZmZmZmZdd l m!Z!dd lm"Z"dd l#m$Z$GdddeZ%GdddeZ&ddZ'dddZ(dS)z$ipset io XML handler, reader, writerIPSet ipset_reader ipset_writerN)config) checkIPcheckIP6 checkIPnMask checkIP6nMask u2b_if_py2 check_mac check_portcheckInterface checkProtocol)PY2 IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator) IPSET_TYPESIPSET_CREATE_OPTIONS)check_icmp_namecheck_icmp_type_codecheck_icmpv6_namecheck_icmpv6_type_code)log)errors) FirewallErrorcseZdZddd d!dddifddgffZdZd d d d gZd d dgdgd dZdgdgdZfddZddZ ddZ e ddZ ddZ fddZZS)"rversionshort descriptiontypeoptionsentriesz (ssssa{ss}as)_-:.Nname)rripsetoptionentryvalue)r(r)cs<tt|jd|_d|_d|_d|_g|_i|_d|_ dS)NrF) superr__init__rrrr r"r!applied)self) __class__/usr/lib/python3.6/ipset.pyr-CszIPSet.__init__cCs8d|_d|_d|_d|_|jdd=|jjd|_dS)NrF)rrrr r"r!clearr.)r/r1r1r2cleanupMs  z IPSet.cleanupcCs\t|j|_t|j|_t|j|_t|j|_dd|jjD|_dd|jD|_dS)z HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.cSsi|]\}}t|t|qSr1)r ).0kvr1r1r2 ^sz(IPSet.encode_strings..cSsg|] }t|qSr1)r )r5er1r1r2 `sz(IPSet.encode_strings..N)r rrrr r!itemsr")r/r1r1r2encode_stringsVs    zIPSet.encode_stringscCsrd}d|kr|ddkrd}|jds6ttjd||ddjd}|jd}t|t|ksnt|d krttjd ||fxtt|D]}||}||}|d krd |ko|dkrh|d krttjd |||f|jd } t| dkrttjd||||fx| D]J} |dkr2t|  sH|dkrt |  rttjd| |||fqWnh|dkr|dkrttjd||||f|dkrt } nt} nt } | |sjttjd||||fq|dkr@d |kr|jd } t| dkrttjd||||f|dkr0t| d sJ|dkrft | d rfttjd| d|||f|dkrt | d  s|dkr>t | d  r>ttjd| d |||fn|j dr|dko|dko|dksttjd||||f|dkrt | s&|dkrjt | rjttjd||||fq|dkrvt | s`|dkrjttjd||fq|dkrld|krL|jd} t| dkrttjd|| ddkrP|dkrttjd||ft| d  rd| d krttjd| d |fn6| d jd\} } t| | sJttjd| d |fqj| dd2kr|dkr|ttjd||ft| d  rd| d krttjd"| d |fn6| d jd\} } t| | sJttjd"| d |fn^| dd3kr$t| d r$ttjd'| d|fn&t| d sjttjd(| d |fnt|sjttjd)||fq|d*kr |jd+ryt|d,}Wn*tk rttjd-||fYnXn8y t|}Wn*tk rttjd-||fYnX|dks |d.krjttjd-||fq|d/krZt| sDt|d0krjttjd1||fqttjd|qWdS)4NZipv4familyinet6Zipv6zhash:zipset type '%s' not usable,z)entry '%s' does not match ipset type '%s'Zipr$z invalid address '%s' in '%s'[%d]z.invalid address range '%s' in '%s' for %s (%s)z(invalid address '%s' in '%s' for %s (%s)z0.0.0.0rZnetz/0zhash:net,ifaceZmacz00:00:00:00:00:00z invalid mac address '%s' in '%s'Zportr%zinvalid port '%s'Zicmpz(invalid protocol for family '%s' in '%s'/zinvalid icmp type '%s' in '%s'icmpv6 ipv6-icmpz invalid icmpv6 type '%s' in '%s'tcpsctpudpudplitezinvalid protocol '%s' in '%s'zinvalid port '%s'in '%s'zinvalid port '%s' in '%s'ZmarkZ0xzinvalid mark '%s' in '%s'lZifacezinvalid interface '%s' in '%s')rDrE)rFrGrHrI) startswithrr INVALID_IPSETsplitlenZ INVALID_ENTRYrangerrrr endswithr rrrrrr int ValueErrorr )r*r!Z ipset_typer=flagsr;iflagitemZsplitsZ_splitZip_checkZ_type_codeZint_valr1r1r2 check_entrybsT                                  zIPSet.check_entrycCs|dkr |tkr ttjd||dkrx|jD]}|tkrNttjd||dkryt||}Wn,tk rttj d|||fYnX|d krttj d |||fq2|d kr2||dkr2ttj ||q2WdS)Nr z'%s' is not valid ipset typer!zipset invalid option '%s'timeouthashsizemaxelemz)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer=inetr>)rZr[r\)r]r>) rrr INVALID_TYPEkeysrrMrRrS INVALID_VALUEINVALID_FAMILY)r/rrWZ all_configkey int_valuer1r1r2 _check_config&s2   zIPSet._check_configcsrd|dkr6|dddkr6t|ddkr6ttjx&|dD]}tj||d|dq@Wtt|j|dS)NrZ0r?r)rOrrZIPSET_WITH_TIMEOUTrrYr, import_config)r/rr*)r0r1r2rhAs  zIPSet.import_config)rr)rr)rr)r r)__name__ __module__ __qualname__ZIMPORT_EXPORT_STRUCTUREZDBUS_SIGNATUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSr-r4r< staticmethodrYrdrh __classcell__r1r1)r0r2r,s,       Ec@seZdZddZddZdS)ipset_ContentHandlerc Cstj||||jj|||dkrpd|krX|dtkrLttjd|d|d|j_d|krl|d|j_ nz|dkr|nn|dkrnb|dkrd}d |kr|d }|d dkrttj d|d |jjdko|d dkrttj d|d |jjf|d dkr&| r&ttj d|d |d dkry t |}Wn.t k rnttj d|d |fYnX|dkrttj d|d |f|d d kr|dkrttj||d |jjkr||jj|d <ntjd|d dS)Nr(r z%srrrr)rr+r'r=rZr[r\zUnknown option '%s'zhash:macz%Unsupported option '%s' for type '%s'z&Missing mandatory value of option '%s'z)Option '%s': Value '%s' is not an integerrz#Option '%s': Value '%s' is negativer]r>z Option %s already set, ignoring.)r=rZr[r\)r=)r=rZr[r\)rZr[r\)r]r>)r startElementrWZparser_check_element_attrsrrrr^r rZINVALID_OPTIONrRrSr`rar!rwarning)r/r'attrsr+rcr1r1r2roLsd      z!ipset_ContentHandler.startElementcCs(tj|||dkr$|jjj|jdS)Nr*)r endElementrWr"appendZ_element)r/r'r1r1r2rrs zipset_ContentHandler.endElementN)rirjrkrorrr1r1r1r2rnKs7rnc %Cst}|jds ttjd||dd|_|j|j||_||_|j t j rVdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r}zttjd|jWYdd}~XnXWdQRX~~d |jkrF|jd d krFt|jd krFtjd |j|jdd=d } t} x| t|jkr|j| | krtjd |j| |jj| nry|j |j| |j|j!Wn<tk r} ztjd| |jj| WYdd} ~ XnX| j"|j| | d7} qRW~ t#r|j$|S)Nz.xmlz'%s' is missing .xml suffixreFTz%s/%srbznot a valid ipset file: %srZrfrz6ipset '%s': timeout option is set, entries are ignoredzEntry %s already set, ignoring.z %s, ignoring.rA)%rrQrrZ INVALID_NAMEr'Z check_namefilenamepathrLr ETC_FIREWALLDZbuiltindefaultrnsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionrMZ getExceptionr!rOr"rrpsetpoprYr addrr<) rvrwr(handlerparserr'fsourcemsgrUZ entries_setr9r1r1r2rs^        (  c Cs|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|jd |ji}|jr|jd kr|j|d <|jd ||jd |jrz|jd krz|jd|jdi|j|j|jd|jd |jr|jd kr|jd|jdi|j|j|jd|jd xZ|jjD]L\} } |jd| d kr|jd| | dn|jdd| i|jd qWxD|jD]:} |jd|jdi|j| |jd|jd q(W|jd |jd |j|j ~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingr rrr( z rrr))r'r+r'r*)!rwrvr'osexistsshutilZcopy2 ExceptionrerrordirnamerLrrxmkdirior{rZ startDocumentr rroZignorableWhitespacerZ charactersrrrr!r;Z simpleElementr"Z endDocumentclose) r(rw_pathr'rdirpathrrrqrbr+r*r1r1r2rsf                           )N))__doc____all__Zxml.saxrzrrrZfirewallrZfirewall.functionsrrrr r r r r rZfirewall.core.io.io_objectrrrrZfirewall.core.ipsetrrZfirewall.core.icmprrrrZfirewall.core.loggerrrZfirewall.errorsrrrnrrr1r1r1r2s&   ,   !=5PK!I>..!__pycache__/direct.cpython-36.pycnu[3 Yj=@sddljZddlZddlZddlZddlmZddlmZddl m Z m Z m Z ddl mZmZmZddlmZddlmZddlmZdd lmZdd lmZGd d d eZGd ddeZdS)N)config)LastUpdatedOrderedDict) splitArgsjoinArgs u2b_if_py2) IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator)log) ipXtables)ebtables)errors) FirewallErrorc@s$eZdZddZddZddZdS)direct_ContentHandlercCstj||d|_dS)NF)r__init__direct)selfitemr/usr/lib/python3.6/direct.pyr(s zdirect_ContentHandler.__init__c Cstj||||jj|||dkr@|jr6ttjdd|_n>|dkr|js\tj ddS|d}|d}|d}|jj t |t |t |n|dkr6|jstj d dS|d}|dkrttj d ||d}|d}yt |d}Wn(tk rtj d|ddSXt |t |t ||g|_nH|dkrl|jsVtj ddS|d}t |g|_ntj d|dSdS)NrzMore than one direct tag.Tchainz$Parse Error: chain outside of directipvtablerulez#Parse Error: rule outside of directipv4ipv6ebz"'%s' not from {'ipv4'|'ipv6'|'eb'}priorityz'Parse Error: %s is not a valid priority passthroughz&Parse Error: command outside of directzUnknown XML element %s)rrr)r startElementrZparser_check_element_attrsrrr Z PARSE_ERRORr error add_chainr INVALID_IPVint ValueError_rule _passthrough)rnameZattrsrrrrrrrr,sT          z"direct_ContentHandler.startElementcCstj|||dkrX|jrF|jjddt|jD|jj|jn tj dd|_nJ|dkr|jr|j jddt|jD|jj |j n tj d d|_ dS) NrcSsg|] }t|qSr)r).0xrrr dsz4direct_ContentHandler.endElement..z2Error: rule does not have any arguments, ignoring.rcSsg|] }t|qSr)r)r(r)rrrr*msz0Error: passthrough does not have any arguments, z ignoring.z9Error: passthrough does not have any arguments, ignoring.) r endElementZ_elementr%appendrradd_ruler r r&add_passthrough)rr'rrrr+^s     z direct_ContentHandler.endElementN)__name__ __module__ __qualname__rrr+rrrrr's2rcs<eZdZdZddBgfddddddgfgfdddgfgffZdZdd d d gd d d d gd gd ZiZfddZddZ ddZ ddZ ddZ ddZ ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z d@dAZ!Z"S)CDirectz Direct class chainsrulesr passthroughsz(a(sss)a(sssias)a(sas))Nrrrr)rrrrcs0tt|j||_t|_t|_t|_dS)N)superr2rfilenamerr3r5r6)rr8) __class__rrrs zDirect.__init__cCsdS)Nr)rconfrZall_confrrr _check_configszDirect._check_configc Csg}g}x>|jD]4}x.|j|D] }|jtt|t|gq WqW|j|g}xR|jD]H}xB|j|D]4}|jt|d|d|d|dt|dfqnWq^W|j|g}x8|jD].}x(|j|D]}|jt|t|fqWqW|j|t|S)Nr)r3r,tuplelistr5r6)rretr)keyrrrrr export_configs$ $     zDirect.export_configcCs|j|j|xt|jD]x\}\}}|dkrNx||D]}|j|qr rRrL)rrrrrrMrAvaluerrrr-s     zDirect.add_rulecCs|j|||||f}|t|f}||jkrb||j|krb|j||=t|j|dkr|j|=n$tddj|||fd||fdS)Nrz(Rule '%s' for table '%s' and chain '%s' z',z)with ipv '%s' and priority %d not in list)rQr>r5rTr$rL)rrrrrrMrArYrrr remove_rules     zDirect.remove_rulecCsb|j|||||f}||jkr^x"|j|jD]}|j||=q0Wt|j|dkr^|j|=dS)Nr)rQr5rPrT)rrrrrArYrrr remove_rules"s   zDirect.remove_rulescCs:|j|||||f}|t|f}||jko8||j|kS)N)rQr>r5)rrrrrrMrArYrrr query_rule+s   zDirect.query_rulecCsF|j|||||f}||jkr*|j|Std||fd|dS)Nz'No rules for table '%s' and chain '%s' z with ipv '%s')rQr5r$)rrrrrArrr get_rules1s     zDirect.get_rulescCs|jS)N)r5)rrrr get_all_rules:szDirect.get_all_rulescCs^|j|||jkrg|j|<||j|kr>|j|j|ntjddj||fddS)NzPassthrough '%s' for ipv '%s'z',zalready in list, ignoring)rOr6r,r rRrL)rrrMrrrr.?s   zDirect.add_passthroughcCsl|j|||jkrN||j|krN|j|j|t|j|dkrh|j|=ntddj||fddS)NrzPassthrough '%s' for ipv '%s'z',z not in list)rOr6rSrTr$rL)rrrMrrrremove_passthroughIs  zDirect.remove_passthroughcCs"|j|||jko ||j|kS)N)rOr6)rrrMrrrquery_passthroughSs zDirect.query_passthroughcCs.|j|||jkr|j|Std|dS)NzNo passthroughs for ipv '%s')rOr6r$)rrrrrget_passthroughsWs   zDirect.get_passthroughscCs|jS)N)r6)rrrrget_all_passthroughs^szDirect.get_all_passthroughscCs|j|jjds&ttjd|jt|}tj}|j |t |jdb}tj d}|j |y|j |Wn8tjk r}zttjd|jWYdd}~XnXWdQRXdS)Nz.xmlz'%s' is missing .xml suffixrbzNot a valid file: %s)rCr8endswithrr Z INVALID_NAMErsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZ INVALID_TYPEZ getException)rhandlerparserfsourcemsgrrrreadcs      z Direct.readc CsBtjj|jr\ytj|jd|jWn4tk rZ}ztd|j|fWYdd}~XnXtjjtj sxtj tj dt j |jddd}t |}|j|jdi|jdxR|jD]H}|\}}x:|j|D],}|jd |jd |||d |jdqWqWx|jD]}|\}}}xx|j|D]j\}} t| d kr@q&|jd |jd |||d|d|jtjjt| |jd |jdq&Wq Wx||jD]r}xj|j|D]\} t| d krȐq|jd |jdd|i|jtjjt| |jd|jdqWqW|jd|jd|j|j~dS)Nz%s.oldzBackup of '%s' failed: %siZwtzUTF-8)modeencodingr z r)rrrr<rz%d)rrrrrr)ospathexistsr8shutilZcopy2 ExceptionIOErrorrZ ETC_FIREWALLDmkdiriorfr Z startDocumentrZignorableWhitespacer3Z simpleElementr5rTreZsaxutilsescaperr+r6Z endDocumentclose) rrlrjrhrArrrrrMrrrwriteusZ$                z Direct.write)r4r4r4)#r/r0r1__doc__rEZDBUS_SIGNATUREZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrr;rBrHrCrNrOrQr!rUrVrWrXr-rZr[r\r]r^r.r_r`rarbrmr{ __classcell__rr)r9rr2usH            r2)Zxml.saxrerqrxrtZfirewallrZfirewall.fw_typesrZfirewall.functionsrrrZfirewall.core.io.io_objectrrr Zfirewall.core.loggerr Z firewall.corer r r Zfirewall.errorsrrr2rrrrs        NPK!FmRR'__pycache__/policy.cpython-36.opt-1.pycnu[3 YjϢ@s dddgZddljZddlZddlZddlZddlmZddlm Z m Z ddlm Z m Z m Z ddlmZmZmZdd lmZmZmZmZmZmZdd lmZdd lmZdd lmZdd lmZddZ ddZ!ddZ"ddZ#ddZ$GdddeZ%GdddeZ&dddZ'dddZ(dS) Policy policy_reader policy_writerN)config)checkIPcheckIP6)uniqifymax_policy_name_lenportStr)DEFAULT_POLICY_TARGETPOLICY_TARGETSDEFAULT_POLICY_PRIORITY) IO_ObjectIO_Object_ContentHandlerIO_Object_XMLGenerator check_port check_tcpudpcheck_protocol)rich)log)errors) FirewallErrorc Cs|dkr n|dkrn|dkr|jr`|jjrJtjdt|jd|_dStj|d|j_dS|d|jj kr|jj j |dntjd|dn|dkrN|jr|jjrtjdt|jd|_dStj |d|d |j_dSt |dt |d t|dd |d f}||jjkr4|jjj |ntjd |d|d nN|d kr|jr|jjrtjdt|jd|_dStj|d |j_nBt|d |d |jjkr|jjj |d ntjd |d n|dkrh|jr.|jjrtjdt|jd|_dStj|d|j_dS|d|jjkrT|jjj |dntjd|dn4|dkr|jr|jjrtjdt|jd|_dStj|d|j_dStjd|dn|dkr2|jr|jjrtjdt|jd|_dStj|j_n|jjr&tjdnd|j_nj|dkrd}d|krR|d}d}d|krh|d}|jr|jjrtjdt|jd|_dStj|d|d |||j_dSt |dt |d |rt ||r t| r t| r ttjd|t|dd |d t|d t|f}||jjkrL|jjj |n6tjd|d|d |rld|nd|r|d|ndn|dkr@|jr|jjrtjdt|jd|_dStj|d|d |j_dSt |dt |d t|dd |d f}||jj kr&|jj j |ntjd|d|d n\|dkr|jsftjdd|_dS|jj!rtjd t|jdSd!}d}d"|kr|d"}d}d#|kr|d#}d$|kr|d$j"dLkrd}tj#||||j_!n|dMkr|jstjd+d|_dS|jj$r0tjd,d|_dS|d'krHtj%|j_$nh|d(krxd} d-|krh|d-} tj&| |j_$n8|d)krtj'|j_$n |d*kr|d.} tj(| |j_$|jj$|_)n|d/kr^|jstjd0dS|jjrtjd1dSd} d2|kr*|d2} | dNkr*tjd;d|_dSd<|kr<|d<nd} tj*| | |j_|jj|_)n>|d=kr|js~tjd>dS|jj+rtjd?t|jd|_dStj,|j_+|jj+|_)n|d@kr,d} dA}dB|kr|dB} | dOkrtjdE|dBd|_dSdF|krt-|dF}tj.| |dG|_np|dHkr|j)sRtjdId|_dS|j)j/rxtjdJt|jd|_dS|d }tj0||j1dK|j)_/nd!SdS)PNshort descriptionservicez;Invalid rule: More than one element in rule '%s', ignoring.Tnamez#Service '%s' already set, ignoring.portprotocol-z#Port '%s/%s' already set, ignoring.valuez$Protocol '%s' already set, ignoring.z icmp-blockz&icmp-block '%s' already set, ignoring.z icmp-typez-Invalid rule: icmp-block '%s' outside of rule masqueradez!Masquerade already set, ignoring.z forward-portzto-portzto-addrz#to-addr '%s' is not a valid addressz-Forward port %s/%s%s%s already set, ignoring.z >%sz @%sz source-portz*Source port '%s/%s' already set, ignoring. destinationz)Invalid rule: Destination outside of rulez?Invalid rule: More than one destination in rule '%s', ignoring.Faddressipsetinvertyestrueacceptrejectdropmarkz$Invalid rule: Action outside of rulez"Invalid rule: More than one actiontypesetrz!Invalid rule: Log outside of rulezInvalid rule: More than one loglevelemergalertcriterrorwarningnoticeinfodebugzInvalid rule: Invalid log levelprefixauditz#Invalid rule: Audit outside of rulez9Invalid rule: More than one audit in rule '%s', ignoring.rulerfamilyipv4ipv6z&Invalid rule: Rule family "%s" invalidpriority)r:r=limitz4Invalid rule: Limit outside of action, log and auditz9Invalid rule: More than one limit in rule '%s', ignoring.burst)r&r')r(r)r*r+)r/r0r1r2r3r4r5r6)r;r<)2_ruleelementrr3str _rule_errorr Rich_Serviceitemservicesappend Rich_Portrrr ports Rich_Protocolr protocolsRich_IcmpBlock icmp_blocks Rich_IcmpTypeRich_Masquerader Rich_ForwardPortrrrr INVALID_ADDR forward_portsRich_SourcePort source_portsr"lowerZRich_Destinationaction Rich_Accept Rich_Reject Rich_Drop Rich_Mark _limit_okZRich_Logr8Z Rich_Auditint Rich_Ruler>Z Rich_Limitget)objrattrsentryto_portZto_addrr%r#r$Z_typeZ_setr.r7r:r=rrc/usr/lib/python3.6/policy.pycommon_startElements                                                                            recCs|dkr|jsy|jjWn6tk rR}ztjd|t|jWYdd}~XnLXt|j|jjkr|jj j |j|jjj t|jntjdt|jd|_d|_n|d krd|_ dS) Nr9z%s: %sz Rule '%s' already set, ignoring.Fr(r)r*r+rr8)r(r)r*r+rr8) rCr@Zcheck Exceptionrr3rBrE rules_strrulesrGr[)r_rercrcrdcommon_endElements& rjcCst|trdnd}|dkrT|jrT|jj}x$|D]}||kr0ttjd|q0Wn|dkrx$|D]}t|dt|dqbWnb|dkrx|D] }t |qWn@|d kr|jr|jj } x$|D]} | | krttj d | qWn|d krx|D]} t| dt| d| d  r>| d  r>ttj d| | d rTt| d | d rt | d  rt| d  rttjd| d qWnT|dkrx&|D]}t|dt|dqWn|dkrx|D]} tj| d} |jr| jrt| jtjst| jtjr|jj } | jj| krLttj d | jjnH| jr|jj| jj}|jr| j|jkrttj d| j| jjfnL|jrt| jtjr|jj}| jj|krttjdj||j| jjqWdS)NrZZonerFz '%s' not among existing servicesrIrrKrMz"'%s' not among existing icmp typesrRz$'%s' is missing to-port AND to-addr z#to-addr '%s' is not a valid addressrTrg rich_rules)rule_strz3rich rule family '%s' conflicts with icmp type '%s'z){} '{}': '{}' not among existing services)rgrn) isinstancer fw_configZ get_servicesrrZINVALID_SERVICErrrZ get_icmptypesZINVALID_ICMPTYPEINVALID_FORWARDrrrQrr]rArLrNrr:Z get_icmptyper"rDformat)r_rrE all_configZobj_typeZexisting_servicesrrprotoZexisting_icmptypesZicmptypefwd_portr9Zobj_richZictrcrcrdcommon_check_config2s                      rwcCs0d|ji}|j}|dk r ||d<|jd|dS)Nrr?r>)rr? simpleElement)handlerr>dr?rcrcrd_handler_add_rich_limitxs  r{c Cs|jrF|jdkrF|jd|jdi|j|j|jd|jd|jr|jdkr|jd|jdi|j|j|jd|jdx6t|jD](}|jd|jdd|i|jdqWx@t|j D]2}|jd|jd|d |d d |jdqWx8t|j D]*}|jd|jd d |i|jdqWx8t|j D]*}|jd|jdd|i|jdqLW|j r|jd|jdi|jdxt|j D]}|jd|d |d d }|dr|ddkr|d|d<|dr|ddkr|d|d<|jd||jdqWxBt|jD]4}|jd|jd|d |d d |jdq>WxT|jD]H}i}|jr|j|d<|jd krt|j|d<|jd|jd||jd|jrVi}|jjr|jj|d<|jjr|jj|d<|jjr$|jj|d<|jjr6d|d<|jd|jd||jd|jri}|jjrx|jj|d<|jjr|jj|d<|jjrd|d<|jd|jd ||jd|jrxd} i}t|jtjkrd} |jj|d<nbt|jtjkr(d} |jj|d<|jj |d <n0t|jtj!krNd } |jj"|d <n t|jtj#krfd} nt|jtj$krd} |jj|d<nt|jtj%krd!} |jj|d<nt|jtj&krd} |jj|d<|jj |d <|jj'dkr|jj'|d<|jj(dkrX|jj(|d<nFt|jtj)krBd} |jj|d<|jj |d <nt*t+j,d"t|j|jd|j| ||jd|j-ri}|j-j.r|j-j.|d#<|j-j/r|j-j/|d$<|j-j0r|jd|jd%||jd&t1||j-j0|jd'|jd%n|jd|jd%||jd|j2ri}|j2j0rx|jd|jd(i|jd&t1||j2j0|jd'|jd(n|jd|jd(||jd|j3rd} i}t|j3tj4krd)} n|t|j3tj5krd*} |j3jr<|j3j|d+<nNt|j3tj6krd,} n6t|j3tj7kr*d-} |j3j8|d.<nt-j9d/t|j3|j3j0r|jd|j| ||jd&t1||j3j0|jd'|j| n|jd|j| ||jd|jd|jd|jdqWdS)0Nr!z r rrrrrrk)rrrrz icmp-blockr rlzto-portrmzto-addrz forward-portz source-portr:r=r9r#macr$Truer%z sourcer"z icmp-typez"Unknown element '%s' in obj_writerr7r.rz z r8r(r)r,r*r+r-zUnknown action '%s'):rignorableWhitespace startElementZ characters endElementrrrFrxrIrKrMr rRrTrhr:r=rBraddrr}r$r%r"rAr,rrDrrHrrrJrrOrLrNrPrb to_addressrSrrZINVALID_OBJECTrr7r.r>r{r8rVrWrXrYrZr-r3) r_ryrrrZicmpZforwardr`r9rArVrcrcrd common_writers\                                                                                        rcsPeZdZd7ZdZeZdgZd8d9d:d;d dgfd dgfddgfddgfdd?gfd@ddgfddgffZdddgZ dddgdgddgdgdgdddgddddgddgddddddgdgdgdgdZ ddgdd gd!dgd"d#d$d!d%gd"d$d%gd&d'gd(gd)gd*Z fd+d,Z d-d.Z fd/d0Zfd1d2Zd3d4Zfd5d6ZZS)Ariirversionr!rrtargetrFrIrMr FrRrnrKrTr= ingress_zones egress_zones_r/Nrrrrr-)rrpolicyrrz icmp-blockz icmp-typer z forward-portr9rr"rz source-portrr8r(r)r*r+r>z ingress-zonez egress-zonezto-portzto-addrr:r#r}r%r$r7r.r,r?)rz forward-portr9rr"rr)r>cstt|jd|_d|_d|_t|_g|_g|_ g|_ g|_ d|_ g|_ g|_d|_g|_g|_d|_|j|_d|_g|_g|_dS)Nr!F)superr__init__rrrr rrFrIrKrMr rRrTrqrhrgappliedpriority_defaultr=Zderived_from_zonerr)self) __class__rcrdrs(zPolicy.__init__cCsd|_d|_d|_t|_|jdd=|jdd=|jdd=|jdd=d|_ |j dd=|j dd=d|_ |j dd=|jdd=d|_|j|_|jdd=|jdd=dS)Nr!F)rrrr rrFrIrKrMr rRrTrqrhrgrrr=rr)rrcrcrdcleanups$         zPolicy.cleanupcs"|dkr|jSttt||SdS)Nrn)rggetattrrr)rr)rrcrd __getattr__szPolicy.__getattr__csB|dkr,dd|D|_dd|jD|_ntt|j||dS)NrncSsg|]}tj|dqS))ro)rr]).0srcrcrd sz&Policy.__setattr__..cSsg|] }t|qSrc)rB)rrrcrcrdrs)rhrgrr __setattr__)rrr)rrcrdrszPolicy.__setattr__c Cst|||||dkr2|tkr.ttjd|n|dkrz||jksX||jksX||jkrvttjd||j|j|jfn|dkrhddg}|j r||j j 7}x|D]}||krttj d ||dkrt ddgt |@s|dkrt |t |grttj d ||dkr|dkr8d|kr8d|dksT|dkrd|krd|dkrttj d qWn|d kr|rd|krd|dkrttj d nxd|krd|dkrttj dxR|dD]F}|dkrސq|j j |}|j rd|j j|krttj dqWn|dkr4x|D]}tj|d}|jrt|jtjrd|kr|d|dkr|ttj d nxd|kr,d|dkrttj dxR|dD]F}|dkrq|j j |}|j rd|j j|krttj dqWq,|jrt|jtjrd|kr,d|dkr@|jjrttjdnt|dr,|jjs`ttjdd|dkr,x|dD]8}|j j |}|j rxd|j j|krxttj dqxWnv|jr,t|jtjr,d|kr,xR|dD]F}|dkrq|j j |}|j rd|j j|krttj dqWq,Wn|dkrx|D]} d|krnd|dkrnttj dnd|krDd|dkr| drttjdnt|drD| dsttjdd|dkrDxD|dD]8}|j j |}|j rd|j j|krttj dqWqDWdS)Nrz'%s' is invalid targetr=zQ%d is invalid priority. Must be in range [%d, %d]. The following are reserved: %srrANYHOSTz'%s' not among existing zonesz>'%s' may only contain one of: many regular zones, ANY, or HOSTzF'HOST' can only appear in either ingress or egress zones, but not bothr z.'masquerade' is invalid for egress zone 'HOST'z/'masquerade' is invalid for ingress zone 'HOST'Z interfaceszR'masquerade' cannot be used in a policy if an ingress zone has assigned interfacesrn)rozAA 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'zC'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zonezS'forward-port' cannot be used in a policy if an egress zone has assigned interfaceszR'mark' action cannot be used in a policy if an egress zone has assigned interfacesrRz1'forward-port' is invalid for ingress zone 'HOST'rm)rr)rr)rr)rr)rwr rrINVALID_TARGETpriority_reserved priority_max priority_minZINVALID_PRIORITYrq get_zonesZ INVALID_ZONEr-Zget_zoneZget_zone_config_dictrr]rArprOrPrrrrVrZ) rrrErtZexisting_zoneszoneZz_objr9r_rvrcrcrd _check_configs       "                           zPolicy._check_configcstt|j||jdr,ttjd|n|jdrHttjd|n|jddkrhttjd|njd|kr|d|j d}n|}t |t krttjd|t |t f|j r||j j krttjddS)Nrz'%s' can't start with '/'z'%s' can't end with '/'rkzmore than one '/' in '%s'z&Policy of '%s' has %d chars, max is %dz,Policies can't have the same name as a zone.)rr check_name startswithrr INVALID_NAMEendswithcountfindlenr rqrZ NAME_CONFLICT)rrZ checked_name)rrcrdr,s*      zPolicy.check_namei)rr!)rr!)rr!)rr!)r!r!)r F)r!r!r!r!)r!r!)r=r)__name__ __module__ __qualname__rrr rrZIMPORT_EXPORT_STRUCTUREZADDITIONAL_ALNUM_CHARSZPARSER_REQUIRED_ELEMENT_ATTRSZPARSER_OPTIONAL_ELEMENT_ATTRSrrrrrr __classcell__rcrc)rrdrZsr        ^c@s$eZdZddZddZddZdS)policy_ContentHandlercCs"tj||d|_d|_d|_dS)NF)rrr@rCr[)rrErcrcrdrHs zpolicy_ContentHandler.__init__cCstj||||jrdS|jj||t|||r6dS|dkrd|krR|d|j_d|krjt|d|j_d|kr|d}|t krt t j ||r||j_ n^|dkr|d|jjkr|jjj|dntjd|dn|dkr |d|jjkr|jjj|dntjd |dn|d kr|jsFtjd d |_dS|jjrltjd t|jd |_dSd}d|kr|djdkrd }d}}}d|kr|d}d|kr|d}d|kr|d}tj||||d|j_dStjd|dSdS)Nrrr=rz ingress-zonerz(Ingress zone '%s' already set, ignoring.z egress-zonez'Egress zone '%s' already set, ignoring.rz$Invalid rule: Source outside of ruleTz:Invalid rule: More than one source in rule '%s', ignoring.Fr%r&r'r#r}r$)r%zUnknown XML element '%s')r&r')rrrCrEZparser_check_element_attrsrerr\r=r rrrrrrGrr3rr@rrBrUrZ Rich_Source)rrr`rr%rr}r$rcrcrdrNsf                 z"policy_ContentHandler.startElementcCstj||t||dS)N)rrrj)rrrcrcrdrs z policy_ContentHandler.endElementN)rrrrrrrcrcrcrdrGs@rFc Cst}|jds ttjd||dd |_|s>|j|j||_||_|j t j rZdnd|_ |j |_ t|}tj}|j|d||f}t|db}tjd}|j|y|j|Wn8tjk r} zttjd| jWYdd} ~ XnXWdQRX~~|S) Nz.xmlz'%s' is missing .xml suffixFTz%s/%srbznot a valid policy file: %s)rrrrrrrfilenamepathrr ETC_FIREWALLDZbuiltindefaultrsaxZ make_parserZsetContentHandleropenZ InputSourceZ setByteStreamparseZSAXParseExceptionZINVALID_POLICYZ getException) rrZ no_check_namerryparserrfrmsgrcrcrdrs6        (c Cs|r|n|j}|jr$d||jf}nd||jf}tjj|rytj|d|Wn0tk r}ztj d||WYdd}~XnXtjj |}|j t j rtjj| rtjjt j stjt j dtj|dtj|ddd}t|}|ji}|jr|jd kr|j|d <|j|jkr0t|j|d <|j|d <|jd ||jdt||x8t|jD]*} |jd|jdd| i|jdqfWx8t|jD]*} |jd|jdd| i|jdqW|jd |jd|j |j!~dS)Nz%s/%sz %s/%s.xmlz%s.oldzBackup of file '%s' failed: %siZwtzUTF-8)modeencodingr!rr=rrr|z z ingress-zonerz egress-zone)"rrrosexistsshutilZcopy2rfrr2dirnamerrrmkdiriorrZ startDocumentrr=rrBrrrrrrrxrrZ endDocumentclose) rr_pathrrdirpathrryr`rrcrcrdrsN             )F)N))__all__Zxml.saxrrrrZfirewallrZfirewall.functionsrrrr r Zfirewall.core.baser r r Zfirewall.core.io.io_objectrrrrrrZ firewall.corerZfirewall.core.loggerrrZfirewall.errorsrrerjrwr{rrrrrrcrcrcrds4        F[nL PK!oUUipset.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2015-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # """ipset io XML handler, reader, writer""" __all__ = [ "IPSet", "ipset_reader", "ipset_writer" ] import xml.sax as sax import os import io import shutil from firewall import config from firewall.functions import checkIP, checkIP6, checkIPnMask, \ checkIP6nMask, u2b_if_py2, check_mac, check_port, checkInterface, \ checkProtocol from firewall.core.io.io_object import PY2, IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator from firewall.core.ipset import IPSET_TYPES, IPSET_CREATE_OPTIONS from firewall.core.icmp import check_icmp_name, check_icmp_type_code, \ check_icmpv6_name, check_icmpv6_type_code from firewall.core.logger import log from firewall import errors from firewall.errors import FirewallError class IPSet(IO_Object): IMPORT_EXPORT_STRUCTURE = ( ( "version", "" ), # s ( "short", "" ), # s ( "description", "" ), # s ( "type", "" ), # s ( "options", { "": "", }, ), # a{ss} ( "entries", [ "" ], ), # as ) DBUS_SIGNATURE = '(ssssa{ss}as)' ADDITIONAL_ALNUM_CHARS = [ "_", "-", ":", "." ] PARSER_REQUIRED_ELEMENT_ATTRS = { "short": None, "description": None, "ipset": [ "type" ], "option": [ "name" ], "entry": None, } PARSER_OPTIONAL_ELEMENT_ATTRS = { "ipset": [ "version" ], "option": [ "value" ], } def __init__(self): super(IPSet, self).__init__() self.version = "" self.short = "" self.description = "" self.type = "" self.entries = [ ] self.options = { } self.applied = False def cleanup(self): self.version = "" self.short = "" self.description = "" self.type = "" del self.entries[:] self.options.clear() self.applied = False def encode_strings(self): """ HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.""" self.version = u2b_if_py2(self.version) self.short = u2b_if_py2(self.short) self.description = u2b_if_py2(self.description) self.type = u2b_if_py2(self.type) self.options = { u2b_if_py2(k):u2b_if_py2(v) for k, v in self.options.items() } self.entries = [ u2b_if_py2(e) for e in self.entries ] @staticmethod def check_entry(entry, options, ipset_type): family = "ipv4" if "family" in options: if options["family"] == "inet6": family = "ipv6" if not ipset_type.startswith("hash:"): raise FirewallError(errors.INVALID_IPSET, "ipset type '%s' not usable" % ipset_type) flags = ipset_type[5:].split(",") items = entry.split(",") if len(flags) != len(items) or len(flags) < 1: raise FirewallError( errors.INVALID_ENTRY, "entry '%s' does not match ipset type '%s'" % \ (entry, ipset_type)) for i in range(len(flags)): flag = flags[i] item = items[i] if flag == "ip": if "-" in item and family == "ipv4": # IP ranges only with plain IPs, no masks if i > 1: raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s'[%d]" % \ (item, entry, i)) splits = item.split("-") if len(splits) != 2: raise FirewallError( errors.INVALID_ENTRY, "invalid address range '%s' in '%s' for %s (%s)" % \ (item, entry, ipset_type, family)) for _split in splits: if (family == "ipv4" and not checkIP(_split)) or \ (family == "ipv6" and not checkIP6(_split)): raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (_split, entry, ipset_type, family)) else: # IPs with mask only allowed in the first # position of the type if family == "ipv4": if item == "0.0.0.0": raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (item, entry, ipset_type, family)) if i == 0: ip_check = checkIPnMask else: ip_check = checkIP else: ip_check = checkIP6 if not ip_check(item): raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (item, entry, ipset_type, family)) elif flag == "net": if "-" in item: # IP ranges only with plain IPs, no masks splits = item.split("-") if len(splits) != 2: raise FirewallError( errors.INVALID_ENTRY, "invalid address range '%s' in '%s' for %s (%s)" % \ (item, entry, ipset_type, family)) # First part can only be a plain IP if (family == "ipv4" and not checkIP(splits[0])) or \ (family == "ipv6" and not checkIP6(splits[0])): raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (splits[0], entry, ipset_type, family)) # Second part can also have a mask if (family == "ipv4" and not checkIPnMask(splits[1])) or \ (family == "ipv6" and not checkIP6nMask(splits[1])): raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (splits[1], entry, ipset_type, family)) else: # IPs with mask allowed in all positions, but no /0 if item.endswith("/0"): if not (family == "ipv6" and i == 0 and ipset_type == "hash:net,iface"): raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (item, entry, ipset_type, family)) if (family == "ipv4" and not checkIPnMask(item)) or \ (family == "ipv6" and not checkIP6nMask(item)): raise FirewallError( errors.INVALID_ENTRY, "invalid address '%s' in '%s' for %s (%s)" % \ (item, entry, ipset_type, family)) elif flag == "mac": # ipset does not allow to add 00:00:00:00:00:00 if not check_mac(item) or item == "00:00:00:00:00:00": raise FirewallError( errors.INVALID_ENTRY, "invalid mac address '%s' in '%s'" % (item, entry)) elif flag == "port": if ":" in item: splits = item.split(":") if len(splits) != 2: raise FirewallError( errors.INVALID_ENTRY, "invalid port '%s'" % (item)) if splits[0] == "icmp": if family != "ipv4": raise FirewallError( errors.INVALID_ENTRY, "invalid protocol for family '%s' in '%s'" % \ (family, entry)) if not check_icmp_name(splits[1]) and "/" not in splits[1]: raise FirewallError( errors.INVALID_ENTRY, "invalid icmp type '%s' in '%s'" % \ (splits[1], entry)) else: (_type, _code) = splits[1].split("/") if not check_icmp_type_code(_type, _code): raise FirewallError( errors.INVALID_ENTRY, "invalid icmp type '%s' in '%s'" % (splits[1], entry), ) elif splits[0] in [ "icmpv6", "ipv6-icmp" ]: if family != "ipv6": raise FirewallError( errors.INVALID_ENTRY, "invalid protocol for family '%s' in '%s'" % \ (family, entry)) if not check_icmpv6_name(splits[1]) and "/" not in splits[1]: raise FirewallError( errors.INVALID_ENTRY, "invalid icmpv6 type '%s' in '%s'" % \ (splits[1], entry)) else: (_type, _code) = splits[1].split("/") if not check_icmpv6_type_code(_type, _code): raise FirewallError( errors.INVALID_ENTRY, "invalid icmpv6 type '%s' in '%s'" % (splits[1], entry), ) elif splits[0] not in [ "tcp", "sctp", "udp", "udplite" ] \ and not checkProtocol(splits[0]): raise FirewallError( errors.INVALID_ENTRY, "invalid protocol '%s' in '%s'" % (splits[0], entry)) elif not check_port(splits[1]): raise FirewallError( errors.INVALID_ENTRY, "invalid port '%s'in '%s'" % (splits[1], entry)) else: if not check_port(item): raise FirewallError( errors.INVALID_ENTRY, "invalid port '%s' in '%s'" % (item, entry)) elif flag == "mark": if item.startswith("0x"): try: int_val = int(item, 16) except ValueError: raise FirewallError( errors.INVALID_ENTRY, "invalid mark '%s' in '%s'" % (item, entry)) else: try: int_val = int(item) except ValueError: raise FirewallError( errors.INVALID_ENTRY, "invalid mark '%s' in '%s'" % (item, entry)) if int_val < 0 or int_val > 4294967295: raise FirewallError( errors.INVALID_ENTRY, "invalid mark '%s' in '%s'" % (item, entry)) elif flag == "iface": if not checkInterface(item) or len(item) > 15: raise FirewallError( errors.INVALID_ENTRY, "invalid interface '%s' in '%s'" % (item, entry)) else: raise FirewallError(errors.INVALID_IPSET, "ipset type '%s' not usable" % ipset_type) def _check_config(self, config, item, all_config): if item == "type": if config not in IPSET_TYPES: raise FirewallError(errors.INVALID_TYPE, "'%s' is not valid ipset type" % config) if item == "options": for key in config.keys(): if key not in IPSET_CREATE_OPTIONS: raise FirewallError(errors.INVALID_IPSET, "ipset invalid option '%s'" % key) if key in [ "timeout", "hashsize", "maxelem" ]: try: int_value = int(config[key]) except ValueError: raise FirewallError( errors.INVALID_VALUE, "Option '%s': Value '%s' is not an integer" % \ (key, config[key])) if int_value < 0: raise FirewallError( errors.INVALID_VALUE, "Option '%s': Value '%s' is negative" % \ (key, config[key])) elif key == "family" and \ config[key] not in [ "inet", "inet6" ]: raise FirewallError(errors.INVALID_FAMILY, config[key]) def import_config(self, config): if "timeout" in config[4] and config[4]["timeout"] != "0": if len(config[5]) != 0: raise FirewallError(errors.IPSET_WITH_TIMEOUT) for entry in config[5]: IPSet.check_entry(entry, config[4], config[3]) super(IPSet, self).import_config(config) # PARSER class ipset_ContentHandler(IO_Object_ContentHandler): def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) self.item.parser_check_element_attrs(name, attrs) if name == "ipset": if "type" in attrs: if attrs["type"] not in IPSET_TYPES: raise FirewallError(errors.INVALID_TYPE, "%s" % attrs["type"]) self.item.type = attrs["type"] if "version" in attrs: self.item.version = attrs["version"] elif name == "short": pass elif name == "description": pass elif name == "option": value = "" if "value" in attrs: value = attrs["value"] if attrs["name"] not in \ [ "family", "timeout", "hashsize", "maxelem" ]: raise FirewallError( errors.INVALID_OPTION, "Unknown option '%s'" % attrs["name"]) if self.item.type == "hash:mac" and attrs["name"] in [ "family" ]: raise FirewallError( errors.INVALID_OPTION, "Unsupported option '%s' for type '%s'" % \ (attrs["name"], self.item.type)) if attrs["name"] in [ "family", "timeout", "hashsize", "maxelem" ] \ and not value: raise FirewallError( errors.INVALID_OPTION, "Missing mandatory value of option '%s'" % attrs["name"]) if attrs["name"] in [ "timeout", "hashsize", "maxelem" ]: try: int_value = int(value) except ValueError: raise FirewallError( errors.INVALID_VALUE, "Option '%s': Value '%s' is not an integer" % \ (attrs["name"], value)) if int_value < 0: raise FirewallError( errors.INVALID_VALUE, "Option '%s': Value '%s' is negative" % \ (attrs["name"], value)) if attrs["name"] == "family" and value not in [ "inet", "inet6" ]: raise FirewallError(errors.INVALID_FAMILY, value) if attrs["name"] not in self.item.options: self.item.options[attrs["name"]] = value else: log.warning("Option %s already set, ignoring.", attrs["name"]) # nothing to do for entry and entries here def endElement(self, name): IO_Object_ContentHandler.endElement(self, name) if name == "entry": self.item.entries.append(self._element) def ipset_reader(filename, path): ipset = IPSet() if not filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % filename) ipset.name = filename[:-4] ipset.check_name(ipset.name) ipset.filename = filename ipset.path = path ipset.builtin = False if path.startswith(config.ETC_FIREWALLD) else True ipset.default = ipset.builtin handler = ipset_ContentHandler(ipset) parser = sax.make_parser() parser.setContentHandler(handler) name = "%s/%s" % (path, filename) with open(name, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_IPSET, "not a valid ipset file: %s" % \ msg.getException()) del handler del parser if "timeout" in ipset.options and ipset.options["timeout"] != "0" and \ len(ipset.entries) > 0: # no entries visible for ipsets with timeout log.warning("ipset '%s': timeout option is set, entries are ignored", ipset.name) del ipset.entries[:] i = 0 entries_set = set() while i < len(ipset.entries): if ipset.entries[i] in entries_set: log.warning("Entry %s already set, ignoring.", ipset.entries[i]) ipset.entries.pop(i) else: try: ipset.check_entry(ipset.entries[i], ipset.options, ipset.type) except FirewallError as e: log.warning("%s, ignoring.", e) ipset.entries.pop(i) else: entries_set.add(ipset.entries[i]) i += 1 del entries_set if PY2: ipset.encode_strings() return ipset def ipset_writer(ipset, path=None): _path = path if path else ipset.path if ipset.filename: name = "%s/%s" % (_path, ipset.filename) else: name = "%s/%s.xml" % (_path, ipset.name) if os.path.exists(name): try: shutil.copy2(name, "%s.old" % name) except Exception as msg: log.error("Backup of file '%s' failed: %s", name, msg) dirpath = os.path.dirname(name) if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath): if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) os.mkdir(dirpath, 0o750) f = io.open(name, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start ipset element attrs = { "type": ipset.type } if ipset.version and ipset.version != "": attrs["version"] = ipset.version handler.startElement("ipset", attrs) handler.ignorableWhitespace("\n") # short if ipset.short and ipset.short != "": handler.ignorableWhitespace(" ") handler.startElement("short", { }) handler.characters(ipset.short) handler.endElement("short") handler.ignorableWhitespace("\n") # description if ipset.description and ipset.description != "": handler.ignorableWhitespace(" ") handler.startElement("description", { }) handler.characters(ipset.description) handler.endElement("description") handler.ignorableWhitespace("\n") # options for key,value in ipset.options.items(): handler.ignorableWhitespace(" ") if value != "": handler.simpleElement("option", { "name": key, "value": value }) else: handler.simpleElement("option", { "name": key }) handler.ignorableWhitespace("\n") # entries for entry in ipset.entries: handler.ignorableWhitespace(" ") handler.startElement("entry", { }) handler.characters(entry) handler.endElement("entry") handler.ignorableWhitespace("\n") # end ipset element handler.endElement('ipset') handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK! ϢϢ policy.pynu[# -*- coding: utf-8 -*- # # SPDX-License-Identifier: GPL-2.0-or-later __all__ = [ "Policy", "policy_reader", "policy_writer" ] import xml.sax as sax import os import io import shutil from firewall import config from firewall.functions import checkIP, checkIP6 from firewall.functions import uniqify, max_policy_name_len, portStr from firewall.core.base import DEFAULT_POLICY_TARGET, POLICY_TARGETS, DEFAULT_POLICY_PRIORITY from firewall.core.io.io_object import IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \ check_tcpudp, check_protocol from firewall.core import rich from firewall.core.logger import log from firewall import errors from firewall.errors import FirewallError def common_startElement(obj, name, attrs): if name == "short": pass elif name == "description": pass elif name == "service": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_Service(attrs["name"]) return True if attrs["name"] not in obj.item.services: obj.item.services.append(attrs["name"]) else: log.warning("Service '%s' already set, ignoring.", attrs["name"]) elif name == "port": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_Port(attrs["port"], attrs["protocol"]) return True check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(attrs["port"], "-"), attrs["protocol"]) if entry not in obj.item.ports: obj.item.ports.append(entry) else: log.warning("Port '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) elif name == "protocol": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_Protocol(attrs["value"]) else: check_protocol(attrs["value"]) if attrs["value"] not in obj.item.protocols: obj.item.protocols.append(attrs["value"]) else: log.warning("Protocol '%s' already set, ignoring.", attrs["value"]) elif name == "icmp-block": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_IcmpBlock(attrs["name"]) return True if attrs["name"] not in obj.item.icmp_blocks: obj.item.icmp_blocks.append(attrs["name"]) else: log.warning("icmp-block '%s' already set, ignoring.", attrs["name"]) elif name == "icmp-type": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_IcmpType(attrs["name"]) return True else: log.warning("Invalid rule: icmp-block '%s' outside of rule", attrs["name"]) elif name == "masquerade": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_Masquerade() else: if obj.item.masquerade: log.warning("Masquerade already set, ignoring.") else: obj.item.masquerade = True elif name == "forward-port": to_port = "" if "to-port" in attrs: to_port = attrs["to-port"] to_addr = "" if "to-addr" in attrs: to_addr = attrs["to-addr"] if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_ForwardPort(attrs["port"], attrs["protocol"], to_port, to_addr) return True check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) if to_port: check_port(to_port) if to_addr: if not checkIP(to_addr) and not checkIP6(to_addr): raise FirewallError(errors.INVALID_ADDR, "to-addr '%s' is not a valid address" \ % to_addr) entry = (portStr(attrs["port"], "-"), attrs["protocol"], portStr(to_port, "-"), str(to_addr)) if entry not in obj.item.forward_ports: obj.item.forward_ports.append(entry) else: log.warning("Forward port %s/%s%s%s already set, ignoring.", attrs["port"], attrs["protocol"], " >%s" % to_port if to_port else "", " @%s" % to_addr if to_addr else "") elif name == "source-port": if obj._rule: if obj._rule.element: log.warning("Invalid rule: More than one element in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.element = rich.Rich_SourcePort(attrs["port"], attrs["protocol"]) return True check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (portStr(attrs["port"], "-"), attrs["protocol"]) if entry not in obj.item.source_ports: obj.item.source_ports.append(entry) else: log.warning("Source port '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) elif name == "destination": if not obj._rule: log.warning('Invalid rule: Destination outside of rule') obj._rule_error = True return True if obj._rule.destination: log.warning("Invalid rule: More than one destination in rule '%s', ignoring.", str(obj._rule)) return True invert = False address = None if "address" in attrs: address = attrs["address"] ipset = None if "ipset" in attrs: ipset = attrs["ipset"] if "invert" in attrs and \ attrs["invert"].lower() in [ "yes", "true" ]: invert = True obj._rule.destination = rich.Rich_Destination(address, ipset, invert) elif name in [ "accept", "reject", "drop", "mark" ]: if not obj._rule: log.warning('Invalid rule: Action outside of rule') obj._rule_error = True return True if obj._rule.action: log.warning('Invalid rule: More than one action') obj._rule_error = True return True if name == "accept": obj._rule.action = rich.Rich_Accept() elif name == "reject": _type = None if "type" in attrs: _type = attrs["type"] obj._rule.action = rich.Rich_Reject(_type) elif name == "drop": obj._rule.action = rich.Rich_Drop() elif name == "mark": _set = attrs["set"] obj._rule.action = rich.Rich_Mark(_set) obj._limit_ok = obj._rule.action elif name == "log": if not obj._rule: log.warning('Invalid rule: Log outside of rule') return True if obj._rule.log: log.warning('Invalid rule: More than one log') return True level = None if "level" in attrs: level = attrs["level"] if level not in [ "emerg", "alert", "crit", "error", "warning", "notice", "info", "debug" ]: log.warning('Invalid rule: Invalid log level') obj._rule_error = True return True prefix = attrs["prefix"] if "prefix" in attrs else None obj._rule.log = rich.Rich_Log(prefix, level) obj._limit_ok = obj._rule.log elif name == "audit": if not obj._rule: log.warning('Invalid rule: Audit outside of rule') return True if obj._rule.audit: log.warning("Invalid rule: More than one audit in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True obj._rule.audit = rich.Rich_Audit() obj._limit_ok = obj._rule.audit elif name == "rule": family = None priority = 0 if "family" in attrs: family = attrs["family"] if family not in [ "ipv4", "ipv6" ]: log.warning('Invalid rule: Rule family "%s" invalid', attrs["family"]) obj._rule_error = True return True if "priority" in attrs: priority = int(attrs["priority"]) obj._rule = rich.Rich_Rule(family=family, priority=priority) elif name == "limit": if not obj._limit_ok: log.warning('Invalid rule: Limit outside of action, log and audit') obj._rule_error = True return True if obj._limit_ok.limit: log.warning("Invalid rule: More than one limit in rule '%s', ignoring.", str(obj._rule)) obj._rule_error = True return True value = attrs["value"] obj._limit_ok.limit = rich.Rich_Limit(value, attrs.get("burst")) else: return False return True def common_endElement(obj, name): if name == "rule": if not obj._rule_error: try: obj._rule.check() except Exception as e: log.warning("%s: %s", e, str(obj._rule)) else: if str(obj._rule) not in obj.item.rules_str: obj.item.rules.append(obj._rule) obj.item.rules_str.append(str(obj._rule)) else: log.warning("Rule '%s' already set, ignoring.", str(obj._rule)) obj._rule = None obj._rule_error = False elif name in [ "accept", "reject", "drop", "mark", "log", "audit" ]: obj._limit_ok = None def common_check_config(obj, config, item, all_config): obj_type = "Policy" if isinstance(obj, Policy) else "Zone" if item == "services" and obj.fw_config: existing_services = obj.fw_config.get_services() for service in config: if service not in existing_services: raise FirewallError(errors.INVALID_SERVICE, "'%s' not among existing services" % \ service) elif item == "ports": for port in config: check_port(port[0]) check_tcpudp(port[1]) elif item == "protocols": for proto in config: check_protocol(proto) elif item == "icmp_blocks" and obj.fw_config: existing_icmptypes = obj.fw_config.get_icmptypes() for icmptype in config: if icmptype not in existing_icmptypes: raise FirewallError(errors.INVALID_ICMPTYPE, "'%s' not among existing icmp types" % \ icmptype) elif item == "forward_ports": for fwd_port in config: check_port(fwd_port[0]) check_tcpudp(fwd_port[1]) if not fwd_port[2] and not fwd_port[3]: raise FirewallError( errors.INVALID_FORWARD, "'%s' is missing to-port AND to-addr " % fwd_port) if fwd_port[2]: check_port(fwd_port[2]) if fwd_port[3]: if not checkIP(fwd_port[3]) and not checkIP6(fwd_port[3]): raise FirewallError( errors.INVALID_ADDR, "to-addr '%s' is not a valid address" % fwd_port[3]) elif item == "source_ports": for port in config: check_port(port[0]) check_tcpudp(port[1]) elif item in ["rules_str", "rich_rules"]: for rule in config: obj_rich = rich.Rich_Rule(rule_str=rule) if obj.fw_config and obj_rich.element and (isinstance(obj_rich.element, rich.Rich_IcmpBlock) or isinstance(obj_rich.element, rich.Rich_IcmpType)): existing_icmptypes = obj.fw_config.get_icmptypes() if obj_rich.element.name not in existing_icmptypes: raise FirewallError(errors.INVALID_ICMPTYPE, "'%s' not among existing icmp types" % \ obj_rich.element.name) elif obj_rich.family: ict = obj.fw_config.get_icmptype(obj_rich.element.name) if ict.destination and obj_rich.family not in ict.destination: raise FirewallError(errors.INVALID_ICMPTYPE, "rich rule family '%s' conflicts with icmp type '%s'" % \ (obj_rich.family, obj_rich.element.name)) elif obj.fw_config and isinstance(obj_rich.element, rich.Rich_Service): existing_services = obj.fw_config.get_services() if obj_rich.element.name not in existing_services: raise FirewallError( errors.INVALID_SERVICE, "{} '{}': '{}' not among existing services".format( obj_type, obj.name, obj_rich.element.name ), ) def _handler_add_rich_limit(handler, limit): d = {"value": limit.value} burst = limit.burst if burst is not None: d["burst"] = burst handler.simpleElement("limit", d) def common_writer(obj, handler): # short if obj.short and obj.short != "": handler.ignorableWhitespace(" ") handler.startElement("short", { }) handler.characters(obj.short) handler.endElement("short") handler.ignorableWhitespace("\n") # description if obj.description and obj.description != "": handler.ignorableWhitespace(" ") handler.startElement("description", { }) handler.characters(obj.description) handler.endElement("description") handler.ignorableWhitespace("\n") # services for service in uniqify(obj.services): handler.ignorableWhitespace(" ") handler.simpleElement("service", { "name": service }) handler.ignorableWhitespace("\n") # ports for port in uniqify(obj.ports): handler.ignorableWhitespace(" ") handler.simpleElement("port", { "port": port[0], "protocol": port[1] }) handler.ignorableWhitespace("\n") # protocols for protocol in uniqify(obj.protocols): handler.ignorableWhitespace(" ") handler.simpleElement("protocol", { "value": protocol }) handler.ignorableWhitespace("\n") # icmp-blocks for icmp in uniqify(obj.icmp_blocks): handler.ignorableWhitespace(" ") handler.simpleElement("icmp-block", { "name": icmp }) handler.ignorableWhitespace("\n") # masquerade if obj.masquerade: handler.ignorableWhitespace(" ") handler.simpleElement("masquerade", { }) handler.ignorableWhitespace("\n") # forward-ports for forward in uniqify(obj.forward_ports): handler.ignorableWhitespace(" ") attrs = { "port": forward[0], "protocol": forward[1] } if forward[2] and forward[2] != "" : attrs["to-port"] = forward[2] if forward[3] and forward[3] != "" : attrs["to-addr"] = forward[3] handler.simpleElement("forward-port", attrs) handler.ignorableWhitespace("\n") # source-ports for port in uniqify(obj.source_ports): handler.ignorableWhitespace(" ") handler.simpleElement("source-port", { "port": port[0], "protocol": port[1] }) handler.ignorableWhitespace("\n") # rules for rule in obj.rules: attrs = { } if rule.family: attrs["family"] = rule.family if rule.priority != 0: attrs["priority"] = str(rule.priority) handler.ignorableWhitespace(" ") handler.startElement("rule", attrs) handler.ignorableWhitespace("\n") # source if rule.source: attrs = { } if rule.source.addr: attrs["address"] = rule.source.addr if rule.source.mac: attrs["mac"] = rule.source.mac if rule.source.ipset: attrs["ipset"] = rule.source.ipset if rule.source.invert: attrs["invert"] = "True" handler.ignorableWhitespace(" ") handler.simpleElement("source", attrs) handler.ignorableWhitespace("\n") # destination if rule.destination: attrs = { } if rule.destination.addr: attrs["address"] = rule.destination.addr if rule.destination.ipset: attrs["ipset"] = rule.destination.ipset if rule.destination.invert: attrs["invert"] = "True" handler.ignorableWhitespace(" ") handler.simpleElement("destination", attrs) handler.ignorableWhitespace("\n") # element if rule.element: element = "" attrs = { } if type(rule.element) == rich.Rich_Service: element = "service" attrs["name"] = rule.element.name elif type(rule.element) == rich.Rich_Port: element = "port" attrs["port"] = rule.element.port attrs["protocol"] = rule.element.protocol elif type(rule.element) == rich.Rich_Protocol: element = "protocol" attrs["value"] = rule.element.value elif type(rule.element) == rich.Rich_Masquerade: element = "masquerade" elif type(rule.element) == rich.Rich_IcmpBlock: element = "icmp-block" attrs["name"] = rule.element.name elif type(rule.element) == rich.Rich_IcmpType: element = "icmp-type" attrs["name"] = rule.element.name elif type(rule.element) == rich.Rich_ForwardPort: element = "forward-port" attrs["port"] = rule.element.port attrs["protocol"] = rule.element.protocol if rule.element.to_port != "": attrs["to-port"] = rule.element.to_port if rule.element.to_address != "": attrs["to-addr"] = rule.element.to_address elif type(rule.element) == rich.Rich_SourcePort: element = "source-port" attrs["port"] = rule.element.port attrs["protocol"] = rule.element.protocol else: raise FirewallError( errors.INVALID_OBJECT, "Unknown element '%s' in obj_writer" % type(rule.element)) handler.ignorableWhitespace(" ") handler.simpleElement(element, attrs) handler.ignorableWhitespace("\n") # rule.element # log if rule.log: attrs = { } if rule.log.prefix: attrs["prefix"] = rule.log.prefix if rule.log.level: attrs["level"] = rule.log.level if rule.log.limit: handler.ignorableWhitespace(" ") handler.startElement("log", attrs) handler.ignorableWhitespace("\n ") _handler_add_rich_limit(handler, rule.log.limit) handler.ignorableWhitespace("\n ") handler.endElement("log") else: handler.ignorableWhitespace(" ") handler.simpleElement("log", attrs) handler.ignorableWhitespace("\n") # audit if rule.audit: attrs = {} if rule.audit.limit: handler.ignorableWhitespace(" ") handler.startElement("audit", { }) handler.ignorableWhitespace("\n ") _handler_add_rich_limit(handler, rule.audit.limit) handler.ignorableWhitespace("\n ") handler.endElement("audit") else: handler.ignorableWhitespace(" ") handler.simpleElement("audit", attrs) handler.ignorableWhitespace("\n") # action if rule.action: action = "" attrs = { } if type(rule.action) == rich.Rich_Accept: action = "accept" elif type(rule.action) == rich.Rich_Reject: action = "reject" if rule.action.type: attrs["type"] = rule.action.type elif type(rule.action) == rich.Rich_Drop: action = "drop" elif type(rule.action) == rich.Rich_Mark: action = "mark" attrs["set"] = rule.action.set else: log.warning("Unknown action '%s'", type(rule.action)) if rule.action.limit: handler.ignorableWhitespace(" ") handler.startElement(action, attrs) handler.ignorableWhitespace("\n ") _handler_add_rich_limit(handler, rule.action.limit) handler.ignorableWhitespace("\n ") handler.endElement(action) else: handler.ignorableWhitespace(" ") handler.simpleElement(action, attrs) handler.ignorableWhitespace("\n") handler.ignorableWhitespace(" ") handler.endElement("rule") handler.ignorableWhitespace("\n") class Policy(IO_Object): priority_min = -32768 priority_max = 32767 priority_default = DEFAULT_POLICY_PRIORITY priority_reserved = [0] IMPORT_EXPORT_STRUCTURE = ( ( "version", "" ), # s ( "short", "" ), # s ( "description", "" ), # s ( "target", "" ), # s ( "services", [ "", ], ), # as ( "ports", [ ( "", "" ), ], ), # a(ss) ( "icmp_blocks", [ "", ], ), # as ( "masquerade", False ), # b ( "forward_ports", [ ( "", "", "", "" ), ], ), # a(ssss) ( "rich_rules", [ "" ] ), # as ( "protocols", [ "", ], ), # as ( "source_ports", [ ( "", "" ), ], ), # a(ss) ( "priority", 0 ), # i ( "ingress_zones", [ "" ] ), # as ( "egress_zones", [ "" ] ), # as ) ADDITIONAL_ALNUM_CHARS = [ "_", "-", "/" ] PARSER_REQUIRED_ELEMENT_ATTRS = { "short": None, "description": None, "policy": ["target"], "service": [ "name" ], "port": [ "port", "protocol" ], "icmp-block": [ "name" ], "icmp-type": [ "name" ], "masquerade": None, "forward-port": [ "port", "protocol" ], "rule": None, "source": None, "destination": None, "protocol": [ "value" ], "source-port": [ "port", "protocol" ], "log": None, "audit": None, "accept": None, "reject": None, "drop": None, "mark": [ "set" ], "limit": [ "value" ], "ingress-zone": [ "name" ], "egress-zone": [ "name" ], } PARSER_OPTIONAL_ELEMENT_ATTRS = { "policy": [ "version", "priority" ], "forward-port": [ "to-port", "to-addr" ], "rule": [ "family", "priority" ], "source": [ "address", "mac", "invert", "family", "ipset" ], "destination": [ "address", "invert", "ipset" ], "log": [ "prefix", "level" ], "reject": [ "type" ], "limit": ["burst"], } def __init__(self): super(Policy, self).__init__() self.version = "" self.short = "" self.description = "" self.target = DEFAULT_POLICY_TARGET self.services = [ ] self.ports = [ ] self.protocols = [ ] self.icmp_blocks = [ ] self.masquerade = False self.forward_ports = [ ] self.source_ports = [ ] self.fw_config = None # to be able to check services and a icmp_blocks self.rules = [ ] self.rules_str = [ ] self.applied = False self.priority = self.priority_default self.derived_from_zone = None self.ingress_zones = [] self.egress_zones = [] def cleanup(self): self.version = "" self.short = "" self.description = "" self.target = DEFAULT_POLICY_TARGET del self.services[:] del self.ports[:] del self.protocols[:] del self.icmp_blocks[:] self.masquerade = False del self.forward_ports[:] del self.source_ports[:] self.fw_config = None # to be able to check services and a icmp_blocks del self.rules[:] del self.rules_str[:] self.applied = False self.priority = self.priority_default del self.ingress_zones[:] del self.egress_zones[:] def __getattr__(self, name): if name == "rich_rules": return self.rules_str else: return getattr(super(Policy, self), name) def __setattr__(self, name, value): if name == "rich_rules": self.rules = [rich.Rich_Rule(rule_str=s) for s in value] # must convert back to string to get the canonical string. self.rules_str = [str(s) for s in self.rules] else: super(Policy, self).__setattr__(name, value) def _check_config(self, config, item, all_config): common_check_config(self, config, item, all_config) if item == "target": if config not in POLICY_TARGETS: raise FirewallError(errors.INVALID_TARGET, "'%s' is invalid target" % (config)) elif item == "priority": if config in self.priority_reserved or \ config > self.priority_max or \ config < self.priority_min: raise FirewallError(errors.INVALID_PRIORITY, "%d is invalid priority. Must be in range [%d, %d]. The following are reserved: %s" % (config, self.priority_min, self.priority_max, self.priority_reserved)) elif item in ["ingress_zones", "egress_zones"]: existing_zones = ["ANY", "HOST"] if self.fw_config: existing_zones += self.fw_config.get_zones() for zone in config: if zone not in existing_zones: raise FirewallError(errors.INVALID_ZONE, "'%s' not among existing zones" % (zone)) if ((zone not in ["ANY", "HOST"] and (set(["ANY", "HOST"]) & set(config))) or \ (zone in ["ANY", "HOST"] and (set(config) - set([zone])))): raise FirewallError(errors.INVALID_ZONE, "'%s' may only contain one of: many regular zones, ANY, or HOST" % (item)) if zone == "HOST" and \ ((item == "ingress_zones" and "egress_zones" in all_config and "HOST" in all_config["egress_zones"]) or \ (item == "egress_zones" and "ingress_zones" in all_config and "HOST" in all_config["ingress_zones"])): raise FirewallError(errors.INVALID_ZONE, "'HOST' can only appear in either ingress or egress zones, but not both") elif item == "masquerade" and config: if "egress_zones" in all_config and "HOST" in all_config["egress_zones"]: raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for egress zone 'HOST'") elif "ingress_zones" in all_config: if "HOST" in all_config["ingress_zones"]: raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for ingress zone 'HOST'") for zone in all_config["ingress_zones"]: if zone == "ANY": continue z_obj = self.fw_config.get_zone(zone) if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj): raise FirewallError(errors.INVALID_ZONE, "'masquerade' cannot be used in a policy if an ingress zone has assigned interfaces") elif item == "rich_rules": for rule in config: obj = rich.Rich_Rule(rule_str=rule) if obj.element and isinstance(obj.element, rich.Rich_Masquerade): if "egress_zones" in all_config and "HOST" in all_config["egress_zones"]: raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for egress zone 'HOST'") elif "ingress_zones" in all_config: if "HOST" in all_config["ingress_zones"]: raise FirewallError(errors.INVALID_ZONE, "'masquerade' is invalid for ingress zone 'HOST'") for zone in all_config["ingress_zones"]: if zone == "ANY": continue z_obj = self.fw_config.get_zone(zone) if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj): raise FirewallError(errors.INVALID_ZONE, "'masquerade' cannot be used in a policy if an ingress zone has assigned interfaces") elif obj.element and isinstance(obj.element, rich.Rich_ForwardPort): if "egress_zones" in all_config: if "HOST" in all_config["egress_zones"]: if obj.element.to_address: raise FirewallError(errors.INVALID_FORWARD, "A 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'") elif all_config["egress_zones"]: if not obj.element.to_address: raise FirewallError(errors.INVALID_FORWARD, "'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zone") if "ANY" not in all_config["egress_zones"]: for zone in all_config["egress_zones"]: z_obj = self.fw_config.get_zone(zone) if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj): raise FirewallError(errors.INVALID_ZONE, "'forward-port' cannot be used in a policy if an egress zone has assigned interfaces") elif obj.action and isinstance(obj.action, rich.Rich_Mark): if "egress_zones" in all_config: for zone in all_config["egress_zones"]: if zone in ["ANY", "HOST"]: continue z_obj = self.fw_config.get_zone(zone) if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj): raise FirewallError(errors.INVALID_ZONE, "'mark' action cannot be used in a policy if an egress zone has assigned interfaces") elif item == "forward_ports": for fwd_port in config: if "ingress_zones" in all_config and "HOST" in all_config["ingress_zones"]: raise FirewallError(errors.INVALID_ZONE, "'forward-port' is invalid for ingress zone 'HOST'") elif "egress_zones" in all_config: if "HOST" in all_config["egress_zones"]: if fwd_port[3]: raise FirewallError(errors.INVALID_FORWARD, "A 'forward-port' with 'to-addr' is invalid for egress zone 'HOST'") elif all_config["egress_zones"]: if not fwd_port[3]: raise FirewallError(errors.INVALID_FORWARD, "'forward-port' requires 'to-addr' if egress zone is 'ANY' or a zone") if "ANY" not in all_config["egress_zones"]: for zone in all_config["egress_zones"]: z_obj = self.fw_config.get_zone(zone) if self.fw_config and "interfaces" in self.fw_config.get_zone_config_dict(z_obj): raise FirewallError(errors.INVALID_ZONE, "'forward-port' cannot be used in a policy if an egress zone has assigned interfaces") def check_name(self, name): super(Policy, self).check_name(name) if name.startswith('/'): raise FirewallError(errors.INVALID_NAME, "'%s' can't start with '/'" % name) elif name.endswith('/'): raise FirewallError(errors.INVALID_NAME, "'%s' can't end with '/'" % name) elif name.count('/') > 1: raise FirewallError(errors.INVALID_NAME, "more than one '/' in '%s'" % name) else: if "/" in name: checked_name = name[:name.find('/')] else: checked_name = name if len(checked_name) > max_policy_name_len(): raise FirewallError(errors.INVALID_NAME, "Policy of '%s' has %d chars, max is %d" % ( name, len(checked_name), max_policy_name_len())) if self.fw_config: if checked_name in self.fw_config.get_zones(): raise FirewallError(errors.NAME_CONFLICT, "Policies can't have the same name as a zone.") # PARSER class policy_ContentHandler(IO_Object_ContentHandler): def __init__(self, item): IO_Object_ContentHandler.__init__(self, item) self._rule = None self._rule_error = False self._limit_ok = None def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) if self._rule_error: return self.item.parser_check_element_attrs(name, attrs) if common_startElement(self, name, attrs): return elif name == "policy": if "version" in attrs: self.item.version = attrs["version"] if "priority" in attrs: self.item.priority = int(attrs["priority"]) if "target" in attrs: target = attrs["target"] if target not in POLICY_TARGETS: raise FirewallError(errors.INVALID_TARGET, target) if target: self.item.target = target elif name == "ingress-zone": if attrs["name"] not in self.item.ingress_zones: self.item.ingress_zones.append(attrs["name"]) else: log.warning("Ingress zone '%s' already set, ignoring.", attrs["name"]) elif name == "egress-zone": if attrs["name"] not in self.item.egress_zones: self.item.egress_zones.append(attrs["name"]) else: log.warning("Egress zone '%s' already set, ignoring.", attrs["name"]) elif name == "source": if not self._rule: log.warning('Invalid rule: Source outside of rule') self._rule_error = True return if self._rule.source: log.warning("Invalid rule: More than one source in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return invert = False if "invert" in attrs and \ attrs["invert"].lower() in [ "yes", "true" ]: invert = True addr = mac = ipset = None if "address" in attrs: addr = attrs["address"] if "mac" in attrs: mac = attrs["mac"] if "ipset" in attrs: ipset = attrs["ipset"] self._rule.source = rich.Rich_Source(addr, mac, ipset, invert=invert) return else: log.warning("Unknown XML element '%s'", name) return def endElement(self, name): IO_Object_ContentHandler.endElement(self, name) common_endElement(self, name) def policy_reader(filename, path, no_check_name=False): policy = Policy() if not filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % filename) policy.name = filename[:-4] if not no_check_name: policy.check_name(policy.name) policy.filename = filename policy.path = path policy.builtin = False if path.startswith(config.ETC_FIREWALLD) else True policy.default = policy.builtin handler = policy_ContentHandler(policy) parser = sax.make_parser() parser.setContentHandler(handler) name = "%s/%s" % (path, filename) with open(name, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_POLICY, "not a valid policy file: %s" % \ msg.getException()) del handler del parser return policy def policy_writer(policy, path=None): _path = path if path else policy.path if policy.filename: name = "%s/%s" % (_path, policy.filename) else: name = "%s/%s.xml" % (_path, policy.name) if os.path.exists(name): try: shutil.copy2(name, "%s.old" % name) except Exception as msg: log.error("Backup of file '%s' failed: %s", name, msg) dirpath = os.path.dirname(name) if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath): if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) os.mkdir(dirpath, 0o750) f = io.open(name, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start policy element attrs = {} if policy.version and policy.version != "": attrs["version"] = policy.version if policy.priority != policy.priority_default: attrs["priority"] = str(policy.priority) attrs["target"] = policy.target handler.startElement("policy", attrs) handler.ignorableWhitespace("\n") common_writer(policy, handler) # ingress-zones for zone in uniqify(policy.ingress_zones): handler.ignorableWhitespace(" ") handler.simpleElement("ingress-zone", { "name": zone }) handler.ignorableWhitespace("\n") # egress-zones for zone in uniqify(policy.egress_zones): handler.ignorableWhitespace(" ") handler.simpleElement("egress-zone", { "name": zone }) handler.ignorableWhitespace("\n") # end policy element handler.endElement("policy") handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!γ11lockdown_whitelist.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import xml.sax as sax import os import io import shutil from firewall import config from firewall.core.io.io_object import PY2, IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator from firewall.core.logger import log from firewall.functions import uniqify, checkUser, checkUid, checkCommand, \ checkContext, u2b_if_py2 from firewall import errors from firewall.errors import FirewallError class lockdown_whitelist_ContentHandler(IO_Object_ContentHandler): def __init__(self, item): IO_Object_ContentHandler.__init__(self, item) self.whitelist = False def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) self.item.parser_check_element_attrs(name, attrs) if name == "whitelist": if self.whitelist: raise FirewallError(errors.PARSE_ERROR, "More than one whitelist.") self.whitelist = True elif name == "command": if not self.whitelist: log.error("Parse Error: command outside of whitelist") return command = attrs["name"] self.item.add_command(command) elif name == "user": if not self.whitelist: log.error("Parse Error: user outside of whitelist") return if "id" in attrs: try: uid = int(attrs["id"]) except ValueError: log.error("Parse Error: %s is not a valid uid" % attrs["id"]) return self.item.add_uid(uid) elif "name" in attrs: self.item.add_user(attrs["name"]) elif name == "selinux": if not self.whitelist: log.error("Parse Error: selinux outside of whitelist") return if "context" not in attrs: log.error("Parse Error: no context") return self.item.add_context(attrs["context"]) else: log.error('Unknown XML element %s' % name) return class LockdownWhitelist(IO_Object): """ LockdownWhitelist class """ IMPORT_EXPORT_STRUCTURE = ( ( "commands", [ "" ] ), # as ( "contexts", [ "" ] ), # as ( "users", [ "" ] ), # as ( "uids", [ 0 ] ) # ai ) DBUS_SIGNATURE = '(asasasai)' ADDITIONAL_ALNUM_CHARS = [ "_" ] PARSER_REQUIRED_ELEMENT_ATTRS = { "whitelist": None, "command": [ "name" ], "user": None, # "group": None, "selinux": [ "context" ], } PARSER_OPTIONAL_ELEMENT_ATTRS = { "user": [ "id", "name" ], # "group": [ "id", "name" ], } def __init__(self, filename): super(LockdownWhitelist, self).__init__() self.filename = filename self.parser = None self.commands = [ ] self.contexts = [ ] self.users = [ ] self.uids = [ ] # self.gids = [ ] # self.groups = [ ] def _check_config(self, config, item, all_config): if item in [ "commands", "contexts", "users", "uids" ]: for x in config: self._check_config(x, item[:-1], all_config) elif item == "command": if not checkCommand(config): raise FirewallError(errors.INVALID_COMMAND, config) elif item == "context": if not checkContext(config): raise FirewallError(errors.INVALID_CONTEXT, config) elif item == "user": if not checkUser(config): raise FirewallError(errors.INVALID_USER, config) elif item == "uid": if not checkUid(config): raise FirewallError(errors.INVALID_UID, config) def cleanup(self): del self.commands[:] del self.contexts[:] del self.users[:] del self.uids[:] # del self.gids[:] # del self.groups[:] def encode_strings(self): """ HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.""" self.commands = [ u2b_if_py2(x) for x in self.commands ] self.contexts = [ u2b_if_py2(x) for x in self.contexts ] self.users = [ u2b_if_py2(x) for x in self.users ] # commands def add_command(self, command): if not checkCommand(command): raise FirewallError(errors.INVALID_COMMAND, command) if command not in self.commands: self.commands.append(command) else: raise FirewallError(errors.ALREADY_ENABLED, 'Command "%s" already in whitelist' % command) def remove_command(self, command): if command in self.commands: self.commands.remove(command) else: raise FirewallError(errors.NOT_ENABLED, 'Command "%s" not in whitelist.' % command) def has_command(self, command): return (command in self.commands) def match_command(self, command): for _command in self.commands: if _command.endswith("*"): if command.startswith(_command[:-1]): return True else: if _command == command: return True return False def get_commands(self): return self.commands # user ids def add_uid(self, uid): if not checkUid(uid): raise FirewallError(errors.INVALID_UID, str(uid)) if uid not in self.uids: self.uids.append(uid) else: raise FirewallError(errors.ALREADY_ENABLED, 'Uid "%s" already in whitelist' % uid) def remove_uid(self, uid): if uid in self.uids: self.uids.remove(uid) else: raise FirewallError(errors.NOT_ENABLED, 'Uid "%s" not in whitelist.' % uid) def has_uid(self, uid): return (uid in self.uids) def match_uid(self, uid): return (uid in self.uids) def get_uids(self): return self.uids # users def add_user(self, user): if not checkUser(user): raise FirewallError(errors.INVALID_USER, user) if user not in self.users: self.users.append(user) else: raise FirewallError(errors.ALREADY_ENABLED, 'User "%s" already in whitelist' % user) def remove_user(self, user): if user in self.users: self.users.remove(user) else: raise FirewallError(errors.NOT_ENABLED, 'User "%s" not in whitelist.' % user) def has_user(self, user): return (user in self.users) def match_user(self, user): return (user in self.users) def get_users(self): return self.users # # group ids # # def add_gid(self, gid): # if gid not in self.gids: # self.gids.append(gid) # # def remove_gid(self, gid): # if gid in self.gids: # self.gids.remove(gid) # else: # raise FirewallError(errors.NOT_ENABLED, # 'Gid "%s" not in whitelist.' % gid) # # def has_gid(self, gid): # return (gid in self.gids) # # def match_gid(self, gid): # return (gid in self.gids) # # def get_gids(self): # return self.gids # # groups # # def add_group(self, group): # if group not in self.groups: # self.groups.append(group) # # def remove_group(self, group): # if group in self.groups: # self.groups.remove(group) # else: # raise FirewallError(errors.NOT_ENABLED, # 'Group "%s" not in whitelist.' % group) # # def has_group(self, group): # return (group in self.groups) # # def match_group(self, group): # return (group in self.groups) # # def get_groups(self): # return self.groups # selinux contexts def add_context(self, context): if not checkContext(context): raise FirewallError(errors.INVALID_CONTEXT, context) if context not in self.contexts: self.contexts.append(context) else: raise FirewallError(errors.ALREADY_ENABLED, 'Context "%s" already in whitelist' % context) def remove_context(self, context): if context in self.contexts: self.contexts.remove(context) else: raise FirewallError(errors.NOT_ENABLED, 'Context "%s" not in whitelist.' % context) def has_context(self, context): return (context in self.contexts) def match_context(self, context): return (context in self.contexts) def get_contexts(self): return self.contexts # read and write def read(self): self.cleanup() if not self.filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % self.filename) handler = lockdown_whitelist_ContentHandler(self) parser = sax.make_parser() parser.setContentHandler(handler) try: parser.parse(self.filename) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_TYPE, "Not a valid file: %s" % \ msg.getException()) del handler del parser if PY2: self.encode_strings() def write(self): if os.path.exists(self.filename): try: shutil.copy2(self.filename, "%s.old" % self.filename) except Exception as msg: raise IOError("Backup of '%s' failed: %s" % (self.filename, msg)) if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) f = io.open(self.filename, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start whitelist element handler.startElement("whitelist", { }) handler.ignorableWhitespace("\n") # commands for command in uniqify(self.commands): handler.ignorableWhitespace(" ") handler.simpleElement("command", { "name": command }) handler.ignorableWhitespace("\n") for uid in uniqify(self.uids): handler.ignorableWhitespace(" ") handler.simpleElement("user", { "id": str(uid) }) handler.ignorableWhitespace("\n") for user in uniqify(self.users): handler.ignorableWhitespace(" ") handler.simpleElement("user", { "name": user }) handler.ignorableWhitespace("\n") # for gid in uniqify(self.gids): # handler.ignorableWhitespace(" ") # handler.simpleElement("user", { "id": str(gid) }) # handler.ignorableWhitespace("\n") # for group in uniqify(self.groups): # handler.ignorableWhitespace(" ") # handler.simpleElement("group", { "name": group }) # handler.ignorableWhitespace("\n") for context in uniqify(self.contexts): handler.ignorableWhitespace(" ") handler.simpleElement("selinux", { "context": context }) handler.ignorableWhitespace("\n") # end whitelist element handler.endElement("whitelist") handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!(55 io_object.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # """Generic io_object handler, io specific check methods.""" __all__ = [ "PY2", "IO_Object", "IO_Object_ContentHandler", "IO_Object_XMLGenerator", "check_port", "check_tcpudp", "check_protocol", "check_address" ] import xml.sax as sax import xml.sax.saxutils as saxutils import copy import sys from collections import OrderedDict from firewall import functions from firewall.functions import b2u from firewall import errors from firewall.errors import FirewallError PY2 = sys.version < '3' class IO_Object(object): """ Abstract IO_Object as base for icmptype, service and zone """ IMPORT_EXPORT_STRUCTURE = ( ) DBUS_SIGNATURE = '()' ADDITIONAL_ALNUM_CHARS = [ ] # additional to alnum PARSER_REQUIRED_ELEMENT_ATTRS = { } PARSER_OPTIONAL_ELEMENT_ATTRS = { } def __init__(self): self.filename = "" self.path = "" self.name = "" self.default = False self.builtin = False def export_config(self): ret = [ ] for x in self.IMPORT_EXPORT_STRUCTURE: ret.append(copy.deepcopy(getattr(self, x[0]))) return tuple(ret) def export_config_dict(self): conf = {} type_formats = dict([(x[0], x[1]) for x in self.IMPORT_EXPORT_STRUCTURE]) for key in type_formats: if getattr(self, key) or isinstance(getattr(self, key), bool): conf[key] = copy.deepcopy(getattr(self, key)) return conf def import_config(self, conf): self.check_config(conf) for i,(element,dummy) in enumerate(self.IMPORT_EXPORT_STRUCTURE): if isinstance(conf[i], list): # remove duplicates without changing the order _conf = [ ] _set = set() for x in conf[i]: if x not in _set: _conf.append(x) _set.add(x) del _set setattr(self, element, copy.deepcopy(_conf)) else: setattr(self, element, copy.deepcopy(conf[i])) def import_config_dict(self, conf): self.check_config_dict(conf) for key in conf: if not hasattr(self, key): raise FirewallError(errors.UNKNOWN_ERROR, "Internal error. '{}' is not a valid attribute".format(key)) if isinstance(conf[key], list): # maintain list order while removing duplicates setattr(self, key, list(OrderedDict.fromkeys(copy.deepcopy(conf[key])))) else: setattr(self, key, copy.deepcopy(conf[key])) def check_name(self, name): if not isinstance(name, str): raise FirewallError(errors.INVALID_TYPE, "'%s' not of type %s, but %s" % (name, type(""), type(name))) if len(name) < 1: raise FirewallError(errors.INVALID_NAME, "name can't be empty") for char in name: if not char.isalnum() and char not in self.ADDITIONAL_ALNUM_CHARS: raise FirewallError( errors.INVALID_NAME, "'%s' is not allowed in '%s'" % ((char, name))) def check_config(self, conf): if len(conf) != len(self.IMPORT_EXPORT_STRUCTURE): raise FirewallError( errors.INVALID_TYPE, "structure size mismatch %d != %d" % \ (len(conf), len(self.IMPORT_EXPORT_STRUCTURE))) conf_dict = {} for i,(x,y) in enumerate(self.IMPORT_EXPORT_STRUCTURE): conf_dict[x] = conf[i] self.check_config_dict(conf_dict) def check_config_dict(self, conf): type_formats = dict([(x[0], x[1]) for x in self.IMPORT_EXPORT_STRUCTURE]) for key in conf: if key not in [x for (x,y) in self.IMPORT_EXPORT_STRUCTURE]: raise FirewallError(errors.INVALID_OPTION, "option '{}' is not valid".format(key)) self._check_config_structure(conf[key], type_formats[key]) self._check_config(conf[key], key, conf) def _check_config(self, dummy1, dummy2, dummy3): # to be overloaded by sub classes return def _check_config_structure(self, conf, structure): if not isinstance(conf, type(structure)): raise FirewallError(errors.INVALID_TYPE, "'%s' not of type %s, but %s" % \ (conf, type(structure), type(conf))) if isinstance(structure, list): # same type elements, else struct if len(structure) != 1: raise FirewallError(errors.INVALID_TYPE, "len('%s') != 1" % structure) for x in conf: self._check_config_structure(x, structure[0]) elif isinstance(structure, tuple): if len(structure) != len(conf): raise FirewallError(errors.INVALID_TYPE, "len('%s') != %d" % (conf, len(structure))) for i,value in enumerate(structure): self._check_config_structure(conf[i], value) elif isinstance(structure, dict): # only one key value pair in structure (skey, svalue) = list(structure.items())[0] for (key, value) in conf.items(): if not isinstance(key, type(skey)): raise FirewallError(errors.INVALID_TYPE, "'%s' not of type %s, but %s" % (\ key, type(skey), type(key))) if not isinstance(value, type(svalue)): raise FirewallError(errors.INVALID_TYPE, "'%s' not of type %s, but %s" % (\ value, type(svalue), type(value))) # check required elements and attributes and also optional attributes def parser_check_element_attrs(self, name, attrs): _attrs = attrs.getNames() found = False if name in self.PARSER_REQUIRED_ELEMENT_ATTRS: found = True if self.PARSER_REQUIRED_ELEMENT_ATTRS[name] is not None: for x in self.PARSER_REQUIRED_ELEMENT_ATTRS[name]: if x in _attrs: _attrs.remove(x) else: raise FirewallError( errors.PARSE_ERROR, "Missing attribute %s for %s" % (x, name)) if name in self.PARSER_OPTIONAL_ELEMENT_ATTRS: found = True for x in self.PARSER_OPTIONAL_ELEMENT_ATTRS[name]: if x in _attrs: _attrs.remove(x) if not found: raise FirewallError(errors.PARSE_ERROR, "Unexpected element %s" % name) # raise attributes[0] for x in _attrs: raise FirewallError(errors.PARSE_ERROR, "%s: Unexpected attribute %s" % (name, x)) # PARSER class UnexpectedElementError(Exception): def __init__(self, name): super(UnexpectedElementError, self).__init__() self.name = name def __str__(self): return "Unexpected element '%s'" % (self.name) class MissingAttributeError(Exception): def __init__(self, name, attribute): super(MissingAttributeError, self).__init__() self.name = name self.attribute = attribute def __str__(self): return "Element '%s': missing '%s' attribute" % \ (self.name, self.attribute) class UnexpectedAttributeError(Exception): def __init__(self, name, attribute): super(UnexpectedAttributeError, self).__init__() self.name = name self.attribute = attribute def __str__(self): return "Element '%s': unexpected attribute '%s'" % \ (self.name, self.attribute) class IO_Object_ContentHandler(sax.handler.ContentHandler): def __init__(self, item): self.item = item self._element = "" def startDocument(self): self._element = "" def startElement(self, name, attrs): self._element = "" def endElement(self, name): if name == "short": self.item.short = self._element elif name == "description": self.item.description = self._element def characters(self, content): self._element += content.replace('\n', ' ') class IO_Object_XMLGenerator(saxutils.XMLGenerator): def __init__(self, out): # fix memory leak in saxutils.XMLGenerator.__init__: # out = _gettextwriter(out, encoding) # creates unbound object results in garbage in gc # # saxutils.XMLGenerator.__init__(self, out, "utf-8") # replaced by modified saxutils.XMLGenerator.__init__ code: sax.handler.ContentHandler.__init__(self) self._write = out.write self._flush = out.flush self._ns_contexts = [{}] # contains uri -> prefix dicts self._current_context = self._ns_contexts[-1] self._undeclared_ns_maps = [] self._encoding = "utf-8" self._pending_start_element = False self._short_empty_elements = False def startElement(self, name, attrs): """ saxutils.XMLGenerator.startElement() expects name and attrs to be unicode and bad things happen if any of them is (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. """ if PY2: attrs = { b2u(name):b2u(value) for name, value in attrs.items() } saxutils.XMLGenerator.startElement(self, name, attrs) def simpleElement(self, name, attrs): """ slightly modified startElement() """ if PY2: self._write(u'<' + b2u(name)) for (name, value) in attrs.items(): self._write(u' %s=%s' % (b2u(name), saxutils.quoteattr(b2u(value)))) self._write(u'/>') else: self._write('<' + name) for (name, value) in attrs.items(): self._write(' %s=%s' % (name, saxutils.quoteattr(value))) self._write('/>') def endElement(self, name): """ saxutils.XMLGenerator.endElement() expects name to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. """ saxutils.XMLGenerator.endElement(self, b2u(name)) def characters(self, content): """ saxutils.XMLGenerator.characters() expects content to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. """ saxutils.XMLGenerator.characters(self, b2u(content)) def ignorableWhitespace(self, content): """ saxutils.XMLGenerator.ignorableWhitespace() expects content to be unicode and bad things happen if it's (utf-8) encoded. We override the method here to sanitize this case. Can be removed once we drop Python2 support. """ saxutils.XMLGenerator.ignorableWhitespace(self, b2u(content)) def check_port(port): port_range = functions.getPortRange(port) if port_range == -2: raise FirewallError(errors.INVALID_PORT, "port number in '%s' is too big" % port) elif port_range == -1: raise FirewallError(errors.INVALID_PORT, "'%s' is invalid port range" % port) elif port_range is None: raise FirewallError(errors.INVALID_PORT, "port range '%s' is ambiguous" % port) elif len(port_range) == 2 and port_range[0] >= port_range[1]: raise FirewallError(errors.INVALID_PORT, "'%s' is invalid port range" % port) def check_tcpudp(protocol): if protocol not in [ "tcp", "udp", "sctp", "dccp" ]: raise FirewallError(errors.INVALID_PROTOCOL, "'%s' not from {'tcp'|'udp'|'sctp'|'dccp'}" % \ protocol) def check_protocol(protocol): if not functions.checkProtocol(protocol): raise FirewallError(errors.INVALID_PROTOCOL, protocol) def check_address(ipv, addr): if not functions.check_address(ipv, addr): raise FirewallError(errors.INVALID_ADDR, "'%s' is not valid %s address" % (addr, ipv)) PK!*yy functions.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2018 Red Hat, Inc. # # Authors: # Eric Garver # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os from firewall import config from firewall.errors import FirewallError from firewall.core.fw_config import FirewallConfig from firewall.core.io.zone import zone_reader from firewall.core.io.service import service_reader from firewall.core.io.ipset import ipset_reader from firewall.core.io.icmptype import icmptype_reader from firewall.core.io.helper import helper_reader from firewall.core.io.policy import policy_reader from firewall.core.io.direct import Direct from firewall.core.io.lockdown_whitelist import LockdownWhitelist from firewall.core.io.firewalld_conf import firewalld_conf def check_config(fw): fw_config = FirewallConfig(fw) readers = { "ipset": {"reader": ipset_reader, "add": fw_config.add_ipset, "dirs": [config.FIREWALLD_IPSETS, config.ETC_FIREWALLD_IPSETS], }, "helper": {"reader": helper_reader, "add": fw_config.add_helper, "dirs": [config.FIREWALLD_HELPERS, config.ETC_FIREWALLD_HELPERS], }, "icmptype": {"reader": icmptype_reader, "add": fw_config.add_icmptype, "dirs": [config.FIREWALLD_ICMPTYPES, config.ETC_FIREWALLD_ICMPTYPES], }, "service": {"reader": service_reader, "add": fw_config.add_service, "dirs": [config.FIREWALLD_SERVICES, config.ETC_FIREWALLD_SERVICES], }, "zone": {"reader": zone_reader, "add": fw_config.add_zone, "dirs": [config.FIREWALLD_ZONES, config.ETC_FIREWALLD_ZONES], }, "policy": {"reader": policy_reader, "add": fw_config.add_policy_object, "dirs": [config.FIREWALLD_POLICIES, config.ETC_FIREWALLD_POLICIES], }, } for reader in readers.keys(): for _dir in readers[reader]["dirs"]: if not os.path.isdir(_dir): continue for file in sorted(os.listdir(_dir)): if file.endswith(".xml"): try: obj = readers[reader]["reader"](file, _dir) if reader in ["zone", "policy"]: obj.fw_config = fw_config obj.check_config_dict(obj.export_config_dict()) readers[reader]["add"](obj) except FirewallError as error: raise FirewallError(error.code, "'%s': %s" % (file, error.msg)) except Exception as msg: raise Exception("'%s': %s" % (file, msg)) if os.path.isfile(config.FIREWALLD_DIRECT): try: obj = Direct(config.FIREWALLD_DIRECT) obj.read() obj.check_config(obj.export_config()) except FirewallError as error: raise FirewallError(error.code, "'%s': %s" % (config.FIREWALLD_DIRECT, error.msg)) except Exception as msg: raise Exception("'%s': %s" % (config.FIREWALLD_DIRECT, msg)) if os.path.isfile(config.LOCKDOWN_WHITELIST): try: obj = LockdownWhitelist(config.LOCKDOWN_WHITELIST) obj.read() obj.check_config(obj.export_config()) except FirewallError as error: raise FirewallError(error.code, "'%s': %s" % (config.LOCKDOWN_WHITELIST, error.msg)) except Exception as msg: raise Exception("'%s': %s" % (config.LOCKDOWN_WHITELIST, msg)) if os.path.isfile(config.FIREWALLD_CONF): try: obj = firewalld_conf(config.FIREWALLD_CONF) obj.read() except FirewallError as error: raise FirewallError(error.code, "'%s': %s" % (config.FIREWALLD_CONF, error.msg)) except Exception as msg: raise Exception("'%s': %s" % (config.FIREWALLD_CONF, msg)) PK!8MMzone.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # __all__ = [ "Zone", "zone_reader", "zone_writer" ] import xml.sax as sax import os import io import shutil from firewall import config from firewall.functions import checkIPnMask, checkIP6nMask, checkInterface, uniqify, max_zone_name_len, u2b_if_py2, check_mac from firewall.core.base import DEFAULT_ZONE_TARGET, ZONE_TARGETS from firewall.core.io.io_object import PY2, IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator from firewall.core.io.policy import common_startElement, common_endElement, common_check_config, common_writer from firewall.core import rich from firewall.core.logger import log from firewall import errors from firewall.errors import FirewallError class Zone(IO_Object): """ Zone class """ IMPORT_EXPORT_STRUCTURE = ( ( "version", "" ), # s ( "short", "" ), # s ( "description", "" ), # s ( "UNUSED", False ), # b ( "target", "" ), # s ( "services", [ "", ], ), # as ( "ports", [ ( "", "" ), ], ), # a(ss) ( "icmp_blocks", [ "", ], ), # as ( "masquerade", False ), # b ( "forward_ports", [ ( "", "", "", "" ), ], ), # a(ssss) ( "interfaces", [ "" ] ), # as ( "sources", [ "" ] ), # as ( "rules_str", [ "" ] ), # as ( "protocols", [ "", ], ), # as ( "source_ports", [ ( "", "" ), ], ), # a(ss) ( "icmp_block_inversion", False ), # b ( "forward", False ), # b ) ADDITIONAL_ALNUM_CHARS = [ "_", "-", "/" ] PARSER_REQUIRED_ELEMENT_ATTRS = { "short": None, "description": None, "zone": None, "service": [ "name" ], "port": [ "port", "protocol" ], "icmp-block": [ "name" ], "icmp-type": [ "name" ], "forward": None, "forward-port": [ "port", "protocol" ], "interface": [ "name" ], "rule": None, "source": None, "destination": None, "protocol": [ "value" ], "source-port": [ "port", "protocol" ], "log": None, "audit": None, "accept": None, "reject": None, "drop": None, "mark": [ "set" ], "limit": [ "value" ], "icmp-block-inversion": None, } PARSER_OPTIONAL_ELEMENT_ATTRS = { "zone": [ "name", "immutable", "target", "version" ], "masquerade": [ "enabled" ], "forward-port": [ "to-port", "to-addr" ], "rule": [ "family", "priority" ], "source": [ "address", "mac", "invert", "family", "ipset" ], "destination": [ "address", "invert", "ipset" ], "log": [ "prefix", "level" ], "reject": [ "type" ], "limit": ["burst"], } @staticmethod def index_of(element): for i, (el, dummy) in enumerate(Zone.IMPORT_EXPORT_STRUCTURE): if el == element: return i raise FirewallError(errors.UNKNOWN_ERROR, "index_of()") def __init__(self): super(Zone, self).__init__() self.version = "" self.short = "" self.description = "" self.UNUSED = False self.target = DEFAULT_ZONE_TARGET self.services = [ ] self.ports = [ ] self.protocols = [ ] self.icmp_blocks = [ ] self.forward = False self.masquerade = False self.forward_ports = [ ] self.source_ports = [ ] self.interfaces = [ ] self.sources = [ ] self.fw_config = None # to be able to check services and a icmp_blocks self.rules = [ ] self.rules_str = [ ] self.icmp_block_inversion = False self.combined = False self.applied = False def cleanup(self): self.version = "" self.short = "" self.description = "" self.UNUSED = False self.target = DEFAULT_ZONE_TARGET del self.services[:] del self.ports[:] del self.protocols[:] del self.icmp_blocks[:] self.forward = False self.masquerade = False del self.forward_ports[:] del self.source_ports[:] del self.interfaces[:] del self.sources[:] self.fw_config = None # to be able to check services and a icmp_blocks del self.rules[:] del self.rules_str[:] self.icmp_block_inversion = False self.combined = False self.applied = False def encode_strings(self): """ HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.""" self.version = u2b_if_py2(self.version) self.short = u2b_if_py2(self.short) self.description = u2b_if_py2(self.description) self.target = u2b_if_py2(self.target) self.services = [u2b_if_py2(s) for s in self.services] self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports] self.protocols = [u2b_if_py2(pr) for pr in self.protocols] self.icmp_blocks = [u2b_if_py2(i) for i in self.icmp_blocks] self.forward_ports = [(u2b_if_py2(p1),u2b_if_py2(p2),u2b_if_py2(p3),u2b_if_py2(p4)) for (p1,p2,p3,p4) in self.forward_ports] self.source_ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.source_ports] self.interfaces = [u2b_if_py2(i) for i in self.interfaces] self.sources = [u2b_if_py2(s) for s in self.sources] self.rules = [u2b_if_py2(s) for s in self.rules] self.rules_str = [u2b_if_py2(s) for s in self.rules_str] def __setattr__(self, name, value): if name == "rules_str": self.rules = [rich.Rich_Rule(rule_str=s) for s in value] # must convert back to string to get the canonical string. super(Zone, self).__setattr__(name, [str(s) for s in self.rules]) else: super(Zone, self).__setattr__(name, value) def export_config_dict(self): conf = super(Zone, self).export_config_dict() del conf["UNUSED"] return conf def _check_config(self, config, item, all_config): common_check_config(self, config, item, all_config) if item == "target": if config not in ZONE_TARGETS: raise FirewallError(errors.INVALID_TARGET, config) elif item == "interfaces": for interface in config: if not checkInterface(interface): raise FirewallError(errors.INVALID_INTERFACE, interface) if self.fw_config: for zone in self.fw_config.get_zones(): if zone == self.name: continue if interface in self.fw_config.get_zone(zone).interfaces: raise FirewallError(errors.INVALID_INTERFACE, "interface '{}' already bound to zone '{}'".format(interface, zone)) elif item == "sources": for source in config: if not checkIPnMask(source) and not checkIP6nMask(source) and \ not check_mac(source) and not source.startswith("ipset:"): raise FirewallError(errors.INVALID_ADDR, source) if self.fw_config: for zone in self.fw_config.get_zones(): if zone == self.name: continue if source in self.fw_config.get_zone(zone).sources: raise FirewallError(errors.INVALID_ADDR, "source '{}' already bound to zone '{}'".format(source, zone)) def check_name(self, name): super(Zone, self).check_name(name) if name.startswith('/'): raise FirewallError(errors.INVALID_NAME, "'%s' can't start with '/'" % name) elif name.endswith('/'): raise FirewallError(errors.INVALID_NAME, "'%s' can't end with '/'" % name) elif name.count('/') > 1: raise FirewallError(errors.INVALID_NAME, "more than one '/' in '%s'" % name) else: if "/" in name: checked_name = name[:name.find('/')] else: checked_name = name if len(checked_name) > max_zone_name_len(): raise FirewallError(errors.INVALID_NAME, "Zone of '%s' has %d chars, max is %d %s" % ( name, len(checked_name), max_zone_name_len(), self.combined)) if self.fw_config: if checked_name in self.fw_config.get_policy_objects(): raise FirewallError(errors.NAME_CONFLICT, "Zones can't have the same name as a policy.") def combine(self, zone): self.combined = True self.filename = None self.version = "" self.short = "" self.description = "" for interface in zone.interfaces: if interface not in self.interfaces: self.interfaces.append(interface) for source in zone.sources: if source not in self.sources: self.sources.append(source) for service in zone.services: if service not in self.services: self.services.append(service) for port in zone.ports: if port not in self.ports: self.ports.append(port) for proto in zone.protocols: if proto not in self.protocols: self.protocols.append(proto) for icmp in zone.icmp_blocks: if icmp not in self.icmp_blocks: self.icmp_blocks.append(icmp) if zone.forward: self.forward = True if zone.masquerade: self.masquerade = True for forward in zone.forward_ports: if forward not in self.forward_ports: self.forward_ports.append(forward) for port in zone.source_ports: if port not in self.source_ports: self.source_ports.append(port) for rule in zone.rules: self.rules.append(rule) self.rules_str.append(str(rule)) if zone.icmp_block_inversion: self.icmp_block_inversion = True # PARSER class zone_ContentHandler(IO_Object_ContentHandler): def __init__(self, item): IO_Object_ContentHandler.__init__(self, item) self._rule = None self._rule_error = False self._limit_ok = None def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) if self._rule_error: return self.item.parser_check_element_attrs(name, attrs) if common_startElement(self, name, attrs): return elif name == "zone": if "name" in attrs: log.warning("Ignoring deprecated attribute name='%s'", attrs["name"]) if "version" in attrs: self.item.version = attrs["version"] if "immutable" in attrs: log.warning("Ignoring deprecated attribute immutable='%s'", attrs["immutable"]) if "target" in attrs: target = attrs["target"] if target not in ZONE_TARGETS: raise FirewallError(errors.INVALID_TARGET, target) if target != "" and target != DEFAULT_ZONE_TARGET: self.item.target = target elif name == "forward": if self.item.forward: log.warning("Forward already set, ignoring.") else: self.item.forward = True elif name == "interface": if self._rule: log.warning('Invalid rule: interface use in rule.') self._rule_error = True return # zone bound to interface if "name" not in attrs: log.warning('Invalid interface: Name missing.') self._rule_error = True return if attrs["name"] not in self.item.interfaces: self.item.interfaces.append(attrs["name"]) else: log.warning("Interface '%s' already set, ignoring.", attrs["name"]) elif name == "source": if self._rule: if self._rule.source: log.warning("Invalid rule: More than one source in rule '%s', ignoring.", str(self._rule)) self._rule_error = True return invert = False if "invert" in attrs and \ attrs["invert"].lower() in [ "yes", "true" ]: invert = True addr = mac = ipset = None if "address" in attrs: addr = attrs["address"] if "mac" in attrs: mac = attrs["mac"] if "ipset" in attrs: ipset = attrs["ipset"] self._rule.source = rich.Rich_Source(addr, mac, ipset, invert=invert) return # zone bound to source if "address" not in attrs and "ipset" not in attrs: log.warning('Invalid source: No address no ipset.') return if "address" in attrs and "ipset" in attrs: log.warning('Invalid source: Address and ipset.') return if "family" in attrs: log.warning("Ignoring deprecated attribute family='%s'", attrs["family"]) if "invert" in attrs: log.warning('Invalid source: Invertion not allowed here.') return if "address" in attrs: if not checkIPnMask(attrs["address"]) and \ not checkIP6nMask(attrs["address"]) and \ not check_mac(attrs["address"]): raise FirewallError(errors.INVALID_ADDR, attrs["address"]) if "ipset" in attrs: entry = "ipset:%s" % attrs["ipset"] if entry not in self.item.sources: self.item.sources.append(entry) else: log.warning("Source '%s' already set, ignoring.", attrs["address"]) if "address" in attrs: entry = attrs["address"] if entry not in self.item.sources: self.item.sources.append(entry) else: log.warning("Source '%s' already set, ignoring.", attrs["address"]) elif name == "icmp-block-inversion": if self.item.icmp_block_inversion: log.warning("Icmp-Block-Inversion already set, ignoring.") else: self.item.icmp_block_inversion = True else: log.warning("Unknown XML element '%s'", name) return def endElement(self, name): IO_Object_ContentHandler.endElement(self, name) common_endElement(self, name) def zone_reader(filename, path, no_check_name=False): zone = Zone() if not filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % filename) zone.name = filename[:-4] if not no_check_name: zone.check_name(zone.name) zone.filename = filename zone.path = path zone.builtin = False if path.startswith(config.ETC_FIREWALLD) else True zone.default = zone.builtin handler = zone_ContentHandler(zone) parser = sax.make_parser() parser.setContentHandler(handler) name = "%s/%s" % (path, filename) with open(name, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_ZONE, "not a valid zone file: %s" % \ msg.getException()) del handler del parser if PY2: zone.encode_strings() return zone def zone_writer(zone, path=None): _path = path if path else zone.path if zone.filename: name = "%s/%s" % (_path, zone.filename) else: name = "%s/%s.xml" % (_path, zone.name) if os.path.exists(name): try: shutil.copy2(name, "%s.old" % name) except Exception as msg: log.error("Backup of file '%s' failed: %s", name, msg) dirpath = os.path.dirname(name) if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath): if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) os.mkdir(dirpath, 0o750) f = io.open(name, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start zone element attrs = {} if zone.version and zone.version != "": attrs["version"] = zone.version if zone.target != DEFAULT_ZONE_TARGET: attrs["target"] = zone.target handler.startElement("zone", attrs) handler.ignorableWhitespace("\n") common_writer(zone, handler) # interfaces for interface in uniqify(zone.interfaces): handler.ignorableWhitespace(" ") handler.simpleElement("interface", { "name": interface }) handler.ignorableWhitespace("\n") # source for source in uniqify(zone.sources): handler.ignorableWhitespace(" ") if "ipset:" in source: handler.simpleElement("source", { "ipset": source[6:] }) else: handler.simpleElement("source", { "address": source }) handler.ignorableWhitespace("\n") # icmp-block-inversion if zone.icmp_block_inversion: handler.ignorableWhitespace(" ") handler.simpleElement("icmp-block-inversion", { }) handler.ignorableWhitespace("\n") # forward if zone.forward: handler.ignorableWhitespace(" ") handler.simpleElement("forward", { }) handler.ignorableWhitespace("\n") # end zone element handler.endElement("zone") handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!9155firewalld_conf.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2012 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os.path import io import tempfile import shutil from firewall import config from firewall.core.logger import log from firewall.functions import b2u, u2b, PY2 valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "CleanupModulesOnExit", "Lockdown", "IPv6_rpfilter", "IndividualCalls", "LogDenied", "AutomaticHelpers", "FirewallBackend", "FlushAllOnReload", "RFC3964_IPv4", "AllowZoneDrifting" ] class firewalld_conf(object): def __init__(self, filename): self._config = { } self._deleted = [ ] self.filename = filename self.clear() def clear(self): self._config = { } self._deleted = [ ] def cleanup(self): self._config.clear() self._deleted = [ ] def get(self, key): return self._config.get(key.strip()) def set(self, key, value): _key = b2u(key.strip()) self._config[_key] = b2u(value.strip()) if _key in self._deleted: self._deleted.remove(_key) def __str__(self): s = "" for (key,value) in self._config.items(): if s: s += '\n' s += '%s=%s' % (key, value) return u2b(s) if PY2 else s # load self.filename def read(self): self.clear() try: f = open(self.filename, "r") except Exception as msg: log.error("Failed to load '%s': %s", self.filename, msg) self.set("DefaultZone", config.FALLBACK_ZONE) self.set("MinimalMark", str(config.FALLBACK_MINIMAL_MARK)) self.set("CleanupOnExit", "yes" if config.FALLBACK_CLEANUP_ON_EXIT else "no") self.set("CleanupModulesOnExit", "yes" if config.FALLBACK_CLEANUP_MODULES_ON_EXIT else "no") self.set("Lockdown", "yes" if config.FALLBACK_LOCKDOWN else "no") self.set("IPv6_rpfilter","yes" if config.FALLBACK_IPV6_RPFILTER else "no") self.set("IndividualCalls", "yes" if config.FALLBACK_INDIVIDUAL_CALLS else "no") self.set("LogDenied", config.FALLBACK_LOG_DENIED) self.set("AutomaticHelpers", config.FALLBACK_AUTOMATIC_HELPERS) self.set("FirewallBackend", config.FALLBACK_FIREWALL_BACKEND) self.set("FlushAllOnReload", "yes" if config.FALLBACK_FLUSH_ALL_ON_RELOAD else "no") self.set("RFC3964_IPv4", "yes" if config.FALLBACK_RFC3964_IPV4 else "no") self.set("AllowZoneDrifting", "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no") raise for line in f: if not line: break line = line.strip() if len(line) < 1 or line[0] in ['#', ';']: continue # get key/value pair pair = [ x.strip() for x in line.split("=") ] if len(pair) != 2: log.error("Invalid option definition: '%s'", line.strip()) continue elif pair[0] not in valid_keys: log.error("Invalid option: '%s'", line.strip()) continue elif pair[1] == '': log.error("Missing value: '%s'", line.strip()) continue elif self._config.get(pair[0]) is not None: log.error("Duplicate option definition: '%s'", line.strip()) continue self._config[pair[0]] = pair[1] f.close() # check default zone if not self.get("DefaultZone"): log.error("DefaultZone is not set, using default value '%s'", config.FALLBACK_ZONE) self.set("DefaultZone", str(config.FALLBACK_ZONE)) # check minimal mark value = self.get("MinimalMark") try: int(value) except (ValueError, TypeError): if value is not None: log.warning("MinimalMark '%s' is not valid, using default " "value '%d'", value if value else '', config.FALLBACK_MINIMAL_MARK) self.set("MinimalMark", str(config.FALLBACK_MINIMAL_MARK)) # check cleanup on exit value = self.get("CleanupOnExit") if not value or value.lower() not in [ "no", "false", "yes", "true" ]: if value is not None: log.warning("CleanupOnExit '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_CLEANUP_ON_EXIT) self.set("CleanupOnExit", "yes" if config.FALLBACK_CLEANUP_ON_EXIT else "no") # check module cleanup on exit value = self.get("CleanupModulesOnExit") if not value or value.lower() not in [ "no", "false", "yes", "true" ]: if value is not None: log.warning("CleanupModulesOnExit '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_CLEANUP_MODULES_ON_EXIT) self.set("CleanupModulesOnExit", "yes" if config.FALLBACK_CLEANUP_MODULES_ON_EXIT else "no") # check lockdown value = self.get("Lockdown") if not value or value.lower() not in [ "yes", "true", "no", "false" ]: if value is not None: log.warning("Lockdown '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_LOCKDOWN) self.set("Lockdown", "yes" if config.FALLBACK_LOCKDOWN else "no") # check ipv6_rpfilter value = self.get("IPv6_rpfilter") if not value or value.lower() not in [ "yes", "true", "no", "false" ]: if value is not None: log.warning("IPv6_rpfilter '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_IPV6_RPFILTER) self.set("IPv6_rpfilter","yes" if config.FALLBACK_IPV6_RPFILTER else "no") # check individual calls value = self.get("IndividualCalls") if not value or value.lower() not in [ "yes", "true", "no", "false" ]: if value is not None: log.warning("IndividualCalls '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_INDIVIDUAL_CALLS) self.set("IndividualCalls", "yes" if config.FALLBACK_INDIVIDUAL_CALLS else "no") # check log denied value = self.get("LogDenied") if not value or value not in config.LOG_DENIED_VALUES: if value is not None: log.warning("LogDenied '%s' is invalid, using default value '%s'", value, config.FALLBACK_LOG_DENIED) self.set("LogDenied", str(config.FALLBACK_LOG_DENIED)) # check automatic helpers value = self.get("AutomaticHelpers") if not value or value.lower() not in config.AUTOMATIC_HELPERS_VALUES: if value is not None: log.warning("AutomaticHelpers '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_AUTOMATIC_HELPERS) self.set("AutomaticHelpers", str(config.FALLBACK_AUTOMATIC_HELPERS)) value = self.get("FirewallBackend") if not value or value.lower() not in config.FIREWALL_BACKEND_VALUES: if value is not None: log.warning("FirewallBackend '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_FIREWALL_BACKEND) self.set("FirewallBackend", str(config.FALLBACK_FIREWALL_BACKEND)) value = self.get("FlushAllOnReload") if not value or value.lower() not in [ "yes", "true", "no", "false" ]: if value is not None: log.warning("FlushAllOnReload '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_FLUSH_ALL_ON_RELOAD) self.set("FlushAllOnReload", str(config.FALLBACK_FLUSH_ALL_ON_RELOAD)) value = self.get("RFC3964_IPv4") if not value or value.lower() not in [ "yes", "true", "no", "false" ]: if value is not None: log.warning("RFC3964_IPv4 '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_RFC3964_IPV4) self.set("RFC3964_IPv4", str(config.FALLBACK_RFC3964_IPV4)) value = self.get("AllowZoneDrifting") if not value or value.lower() not in [ "yes", "true", "no", "false" ]: if value is not None: log.warning("AllowZoneDrifting '%s' is not valid, using default " "value %s", value if value else '', config.FALLBACK_ALLOW_ZONE_DRIFTING) self.set("AllowZoneDrifting", str(config.FALLBACK_ALLOW_ZONE_DRIFTING)) # save to self.filename if there are key/value changes def write(self): if len(self._config) < 1: # no changes: nothing to do return # handled keys done = [ ] if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) try: temp_file = tempfile.NamedTemporaryFile(mode='wt', prefix="%s." % os.path.basename(self.filename), dir=os.path.dirname(self.filename), delete=False) except Exception as msg: log.error("Failed to open temporary file: %s" % msg) raise modified = False empty = False try: f= io.open(self.filename, mode='rt', encoding='UTF-8') except Exception as msg: if os.path.exists(self.filename): log.error("Failed to open '%s': %s" % (self.filename, msg)) raise else: f = None else: for line in f: if not line: break # remove newline line = line.strip("\n") if len(line) < 1: if not empty: temp_file.write(u"\n") empty = True elif line[0] == '#': empty = False temp_file.write(line) temp_file.write(u"\n") else: p = line.split("=") if len(p) != 2: empty = False temp_file.write(line+u"\n") continue key = p[0].strip() value = p[1].strip() # check for modified key/value pairs if key not in done: if (key in self._config and \ self._config[key] != value): empty = False temp_file.write(u'%s=%s\n' % (key, self._config[key])) modified = True elif key in self._deleted: modified = True else: empty = False temp_file.write(line+u"\n") done.append(key) else: modified = True # write remaining key/value pairs if len(self._config) > 0: for (key,value) in self._config.items(): if key in done: continue if key in ["MinimalMark", "AutomaticHelpers"]: # omit deprecated from new config continue if not empty: temp_file.write(u"\n") empty = True temp_file.write(u'%s=%s\n' % (key, value)) modified = True if f: f.close() temp_file.close() if not modified: # not modified: remove tempfile os.remove(temp_file.name) return # make backup if os.path.exists(self.filename): try: shutil.copy2(self.filename, "%s.old" % self.filename) except Exception as msg: os.remove(temp_file.name) raise IOError("Backup of '%s' failed: %s" % (self.filename, msg)) # copy tempfile try: shutil.move(temp_file.name, self.filename) except Exception as msg: os.remove(temp_file.name) raise IOError("Failed to create '%s': %s" % (self.filename, msg)) else: os.chmod(self.filename, 0o600) PK!mL22 service.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2011-2016 Red Hat, Inc. # # Authors: # Thomas Woerner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # __all__ = [ "Service", "service_reader", "service_writer" ] import xml.sax as sax import os import io import shutil from firewall import config from firewall.functions import u2b_if_py2 from firewall.core.io.io_object import PY2, IO_Object, \ IO_Object_ContentHandler, IO_Object_XMLGenerator, check_port, \ check_tcpudp, check_protocol, check_address from firewall.core.logger import log from firewall import errors from firewall.errors import FirewallError class Service(IO_Object): IMPORT_EXPORT_STRUCTURE = ( ( "version", "" ), ( "short", "" ), ( "description", "" ), ( "ports", [ ( "", "" ), ], ), ( "modules", [ "", ], ), ( "destination", { "": "", }, ), ( "protocols", [ "", ], ), ( "source_ports", [ ( "", "" ), ], ), ( "includes", [ "" ], ), ( "helpers", [ "", ], ), ) ADDITIONAL_ALNUM_CHARS = [ "_", "-" ] PARSER_REQUIRED_ELEMENT_ATTRS = { "short": None, "description": None, "service": None, } PARSER_OPTIONAL_ELEMENT_ATTRS = { "service": [ "name", "version" ], "port": [ "port", "protocol" ], "protocol": [ "value" ], "module": [ "name" ], "destination": [ "ipv4", "ipv6" ], "source-port": [ "port", "protocol" ], "include": [ "service" ], "helper": [ "name" ], } def __init__(self): super(Service, self).__init__() self.version = "" self.short = "" self.description = "" self.ports = [ ] self.protocols = [ ] self.modules = [ ] self.destination = { } self.source_ports = [ ] self.includes = [ ] self.helpers = [ ] def cleanup(self): self.version = "" self.short = "" self.description = "" del self.ports[:] del self.protocols[:] del self.modules[:] self.destination.clear() del self.source_ports[:] del self.includes[:] del self.helpers[:] def encode_strings(self): """ HACK. I haven't been able to make sax parser return strings encoded (because of python 2) instead of in unicode. Get rid of it once we throw out python 2 support.""" self.version = u2b_if_py2(self.version) self.short = u2b_if_py2(self.short) self.description = u2b_if_py2(self.description) self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports] self.modules = [u2b_if_py2(m) for m in self.modules] self.destination = {u2b_if_py2(k):u2b_if_py2(v) for k,v in self.destination.items()} self.protocols = [u2b_if_py2(pr) for pr in self.protocols] self.source_ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.source_ports] self.includes = [u2b_if_py2(s) for s in self.includes] self.helpers = [u2b_if_py2(s) for s in self.helpers] def _check_config(self, config, item, all_config): if item == "ports": for port in config: if port[0] != "": check_port(port[0]) check_tcpudp(port[1]) else: # only protocol check_protocol(port[1]) elif item == "protocols": for proto in config: check_protocol(proto) elif item == "source_ports": for port in config: check_port(port[0]) check_tcpudp(port[1]) elif item == "destination": for destination in config: if destination not in [ "ipv4", "ipv6" ]: raise FirewallError(errors.INVALID_DESTINATION, "'%s' not in {'ipv4'|'ipv6'}" % \ destination) check_address(destination, config[destination]) elif item == "modules": for module in config: if module.startswith("nf_conntrack_"): module = module.replace("nf_conntrack_", "") if "_" in module: module = module.replace("_", "-") if len(module) < 2: raise FirewallError(errors.INVALID_MODULE, module) # PARSER class service_ContentHandler(IO_Object_ContentHandler): def startElement(self, name, attrs): IO_Object_ContentHandler.startElement(self, name, attrs) self.item.parser_check_element_attrs(name, attrs) if name == "service": if "name" in attrs: log.warning("Ignoring deprecated attribute name='%s'", attrs["name"]) if "version" in attrs: self.item.version = attrs["version"] elif name == "short": pass elif name == "description": pass elif name == "port": if attrs["port"] != "": check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (attrs["port"], attrs["protocol"]) if entry not in self.item.ports: self.item.ports.append(entry) else: log.warning("Port '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) else: check_protocol(attrs["protocol"]) if attrs["protocol"] not in self.item.protocols: self.item.protocols.append(attrs["protocol"]) else: log.warning("Protocol '%s' already set, ignoring.", attrs["protocol"]) elif name == "protocol": check_protocol(attrs["value"]) if attrs["value"] not in self.item.protocols: self.item.protocols.append(attrs["value"]) else: log.warning("Protocol '%s' already set, ignoring.", attrs["value"]) elif name == "source-port": check_port(attrs["port"]) check_tcpudp(attrs["protocol"]) entry = (attrs["port"], attrs["protocol"]) if entry not in self.item.source_ports: self.item.source_ports.append(entry) else: log.warning("SourcePort '%s/%s' already set, ignoring.", attrs["port"], attrs["protocol"]) elif name == "destination": for x in [ "ipv4", "ipv6" ]: if x in attrs: check_address(x, attrs[x]) if x in self.item.destination: log.warning("Destination address for '%s' already set, ignoring", x) else: self.item.destination[x] = attrs[x] elif name == "module": module = attrs["name"] if module.startswith("nf_conntrack_"): module = module.replace("nf_conntrack_", "") if "_" in module: module = module.replace("_", "-") if module not in self.item.modules: self.item.modules.append(module) else: log.warning("Module '%s' already set, ignoring.", module) elif name == "include": if attrs["service"] not in self.item.includes: self.item.includes.append(attrs["service"]) else: log.warning("Include '%s' already set, ignoring.", attrs["service"]) elif name == "helper": if attrs["name"] not in self.item.helpers: self.item.helpers.append(attrs["name"]) else: log.warning("Helper '%s' already set, ignoring.", attrs["name"]) def service_reader(filename, path): service = Service() if not filename.endswith(".xml"): raise FirewallError(errors.INVALID_NAME, "'%s' is missing .xml suffix" % filename) service.name = filename[:-4] service.check_name(service.name) service.filename = filename service.path = path service.builtin = False if path.startswith(config.ETC_FIREWALLD) else True service.default = service.builtin handler = service_ContentHandler(service) parser = sax.make_parser() parser.setContentHandler(handler) name = "%s/%s" % (path, filename) with open(name, "rb") as f: source = sax.InputSource(None) source.setByteStream(f) try: parser.parse(source) except sax.SAXParseException as msg: raise FirewallError(errors.INVALID_SERVICE, "not a valid service file: %s" % \ msg.getException()) del handler del parser if PY2: service.encode_strings() return service def service_writer(service, path=None): _path = path if path else service.path if service.filename: name = "%s/%s" % (_path, service.filename) else: name = "%s/%s.xml" % (_path, service.name) if os.path.exists(name): try: shutil.copy2(name, "%s.old" % name) except Exception as msg: log.error("Backup of file '%s' failed: %s", name, msg) dirpath = os.path.dirname(name) if dirpath.startswith(config.ETC_FIREWALLD) and not os.path.exists(dirpath): if not os.path.exists(config.ETC_FIREWALLD): os.mkdir(config.ETC_FIREWALLD, 0o750) os.mkdir(dirpath, 0o750) f = io.open(name, mode='wt', encoding='UTF-8') handler = IO_Object_XMLGenerator(f) handler.startDocument() # start service element attrs = {} if service.version and service.version != "": attrs["version"] = service.version handler.startElement("service", attrs) handler.ignorableWhitespace("\n") # short if service.short and service.short != "": handler.ignorableWhitespace(" ") handler.startElement("short", { }) handler.characters(service.short) handler.endElement("short") handler.ignorableWhitespace("\n") # description if service.description and service.description != "": handler.ignorableWhitespace(" ") handler.startElement("description", { }) handler.characters(service.description) handler.endElement("description") handler.ignorableWhitespace("\n") # ports for port in service.ports: handler.ignorableWhitespace(" ") handler.simpleElement("port", { "port": port[0], "protocol": port[1] }) handler.ignorableWhitespace("\n") # protocols for protocol in service.protocols: handler.ignorableWhitespace(" ") handler.simpleElement("protocol", { "value": protocol }) handler.ignorableWhitespace("\n") # source ports for port in service.source_ports: handler.ignorableWhitespace(" ") handler.simpleElement("source-port", { "port": port[0], "protocol": port[1] }) handler.ignorableWhitespace("\n") # modules for module in service.modules: handler.ignorableWhitespace(" ") handler.simpleElement("module", { "name": module }) handler.ignorableWhitespace("\n") # destination if len(service.destination) > 0: handler.ignorableWhitespace(" ") handler.simpleElement("destination", service.destination) handler.ignorableWhitespace("\n") # includes for include in service.includes: handler.ignorableWhitespace(" ") handler.simpleElement("include", { "service": include }) handler.ignorableWhitespace("\n") # helpers for helper in service.helpers: handler.ignorableWhitespace(" ") handler.simpleElement("helper", { "name": helper }) handler.ignorableWhitespace("\n") # end service element handler.endElement('service') handler.ignorableWhitespace("\n") handler.endDocument() f.close() del handler PK!G nonblock.rbnu[require "fcntl" class IO def nonblock? (fcntl(Fcntl::F_GETFL) & File::NONBLOCK) != 0 end def nonblock=(nb) f = fcntl(Fcntl::F_GETFL) if nb f |= File::NONBLOCK else f &= ~File::NONBLOCK end fcntl(Fcntl::F_SETFL, f) end def nonblock(nb = true) nb, self.nonblock = nonblock?, nb yield ensure self.nonblock = nb end end if defined?(Fcntl::F_GETFL) PK!k7 simple.gonu[PK!;2ports.gonu[PK!Lconsole/size.rbnu[PK!\0p0p pconsole.sonuȯPK!n^ buffer.hnu[PK!ף0dumb.rbnu[PK!%DCDC 6windows.rbnu[PK!F''Nzansi.rbnu[PK!h?n$n$ LC_MESSAGES/iso_3166-1.monu[PK!I.X.XLC_MESSAGES/gtk20.monu[PK!oo2LC_MESSAGES/gdk-pixbuf.monu[PK!,:<< 3__init__.pynu[PK!/ a:helper.pynu[PK!Cc=== M[direct.pynu[PK!mfifcfg.pynu[PK!5 icmptype.pynu[PK!z! *b__pycache__/functions.cpython-36.opt-1.pycnu[PK!?xR`/`/$j__pycache__/io_object.cpython-36.pycnu[PK!g22%__pycache__/zone.cpython-36.opt-1.pycnu[PK!qޝ#:;__pycache__/icmptype.cpython-36.pycnu[PK!@*/*O__pycache__/firewalld_conf.cpython-36.opt-1.pycnu[PK!qޝ)m__pycache__/icmptype.cpython-36.opt-1.pycnu[PK!(# ( __pycache__/service.cpython-36.opt-1.pycnu[PK!))'d__pycache__/helper.cpython-36.opt-1.pycnu[PK! h%h%3__pycache__/lockdown_whitelist.cpython-36.opt-1.pycnu[PK!FmRR!__pycache__/policy.cpython-36.pycnu[PK!@*)2__pycache__/firewalld_conf.cpython-36.pycnu[PK!))!qP__pycache__/helper.cpython-36.pycnu[PK!Vq/&g__pycache__/ifcfg.cpython-36.opt-1.pycnu[PK!9),), x__pycache__/ipset.cpython-36.pycnu[PK!z! $__pycache__/functions.cpython-36.pycnu[PK!?xR`/`/*__pycache__/io_object.cpython-36.opt-1.pycnu[PK! h%h%-G__pycache__/lockdown_whitelist.cpython-36.pycnu[PK!(# " __pycache__/service.cpython-36.pycnu[PK!g22]&__pycache__/zone.cpython-36.pycnu[PK!Vq/ sY__pycache__/ifcfg.cpython-36.pycnu[PK!I>..'i__pycache__/direct.cpython-36.opt-1.pycnu[PK!r#__pycache__/__init__.cpython-36.pycnu[PK!r)__pycache__/__init__.cpython-36.opt-1.pycnu[PK!9),),&x__pycache__/ipset.cpython-36.opt-1.pycnu[PK!I>..!__pycache__/direct.cpython-36.pycnu[PK!FmRR'__pycache__/policy.cpython-36.opt-1.pycnu[PK!oUULipset.pynu[PK! ϢϢ Ţpolicy.pynu[PK!γ11Elockdown_whitelist.pynu[PK!(55 wio_object.pynu[PK!*yy functions.pynu[PK!8MMzone.pynu[PK!9155s firewalld_conf.pynu[PK!mL22 Cservice.pynu[PK!G vnonblock.rbnu[PK33x