Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch odie Excluding Merge-Ins
This is equivalent to a diff from 4522045077 to f819e0bcac
2016-11-21
| ||
20:32 | Added a new command to the coroutine::util namespace: gets_safety. It is intended for http servers which have to read in a line from a socket, but where attackers may attempt to pull off a stack overflow by sending a stream of data with no newline. Modified the http package to utilize the new gets_safety command. Closed-Leaf check-in: f819e0bcac user: hypnotoad tags: odie | |
2016-11-12
| ||
04:53 | Fix syntax error in fumagic/rtcore.tcl. check-in: b5a9ce2f78 user: pooryorick tags: trunk | |
2016-11-09
| ||
15:30 | Pulling changes from trunk check-in: bd97f4c914 user: hypnotoad tags: odie | |
2016-11-08
| ||
10:00 | fumagic/cfront {deal with comments on a mimetype line} check-in: 4522045077 user: pooryorick tags: trunk | |
09:21 | fumagic/cfront.tcl {fix error in filtypes.tcl generation for "name" test types} fumagic/filetypes.tcl {workaround for bad syntax in Magdir/dos} fumagic/rtcore.tcl {fix error message in [use] command} fumagic/fumagic.testsupport {fix Pe test} check-in: 30da0c3db0 user: pooryorick tags: trunk | |
Changes to modules/coroutine/coroutine.tcl.
︙ | ︙ | |||
173 174 175 176 177 178 179 | # builtin gets command with the bogus arguments gives us the # necessary error with the proper message. tailcall ::chan gets {*}$args } # Loop until we have a complete line. Yield to the event loop # where necessary. During | | < | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | # builtin gets command with the bogus arguments gives us the # necessary error with the proper message. tailcall ::chan gets {*}$args } # Loop until we have a complete line. Yield to the event loop # where necessary. During set blocking [::chan configure $chan -blocking] while {1} { ::chan configure $chan -blocking 0 try { set result [::chan gets $chan line] } on error {result opts} { ::chan configure $chan -blocking $blocking return -code $result -options $opts |
︙ | ︙ | |||
200 201 202 203 204 205 206 207 208 209 210 211 212 213 | return $result } else { return $line } } } } # - -- --- ----- -------- ------------- proc ::coroutine::util::read {args} { # Process arguments. # Acceptable syntax: # * read ?-nonewline ? CHAN | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | return $result } else { return $line } } } } proc ::coroutine::util::gets_safety {chan limit varname} { # Process arguments. # Acceptable syntax: # * gets CHAN ?VARNAME? # Loop until we have a complete line. Yield to the event loop # where necessary. During set blocking [::chan configure $chan -blocking] upvar 1 $varname line try { while {1} { ::chan configure $chan -blocking 0 if {[::chan pending input $chan]>= $limit} { error {Too many notes, Mozart. Too many notes} } try { set result [::chan gets $chan line] } on error {result opts} { return -code $result -options $opts } if {[::chan blocked $chan]} { ::chan event $chan readable [list [info coroutine]] yield ::chan event $chan readable {} } else { return $result } } } finally { ::chan configure $chan -blocking $blocking } } # - -- --- ----- -------- ------------- proc ::coroutine::util::read {args} { # Process arguments. # Acceptable syntax: # * read ?-nonewline ? CHAN |
︙ | ︙ |
Changes to modules/coroutine/tcllib_coroutine.man.
︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 | returned. [call [cmd {coroutine::util gets}] [arg chan] [opt [arg varname]]] This command reads a line from the channel [arg chan] and returns it either as its result, or, if a [arg varname] was specified, writes it to the named variable and returns the number of characters read. [call [cmd {coroutine::util global}] [arg varname]...] This command imports the named global variables of the coroutine into the current scope. From the technical point of view these variables reside in level [const #1] of the Tcl stack. I.e. these are not the regular global variable in to the global namespace, and each coroutine | > > > > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | returned. [call [cmd {coroutine::util gets}] [arg chan] [opt [arg varname]]] This command reads a line from the channel [arg chan] and returns it either as its result, or, if a [arg varname] was specified, writes it to the named variable and returns the number of characters read. [call [cmd {coroutine::util gets_safety}] [arg chan] [arg limit] [arg varname]] This command reads a line from the channel [arg chan] up to size [arg limit] and stores the result in [arg varname]. Of [arg limit] is reached before the set first newline, an error is thrown. The command returns the number of characters read. [call [cmd {coroutine::util global}] [arg varname]...] This command imports the named global variables of the coroutine into the current scope. From the technical point of view these variables reside in level [const #1] of the Tcl stack. I.e. these are not the regular global variable in to the global namespace, and each coroutine |
︙ | ︙ |
Changes to modules/httpd/httpd.tcl.
︙ | ︙ | |||
464 465 466 467 468 469 470 | } method connect {sock ip port} { ### # If an IP address is blocked # send a "go to hell" message ### | | | > > > > > > | > | < > | | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | } method connect {sock ip port} { ### # If an IP address is blocked # send a "go to hell" message ### if {[my Validate_Connection $sock $ip]} { catch {close $sock} return } set uuid [::tool::uuid_short] chan configure $sock \ -blocking 0 \ -translation {auto crlf} \ -buffering line set coro [coroutine [namespace current]::CORO$uuid ::apply [list {uuid sock ip} { yield [info coroutine] tailcall my Connect $uuid $sock $ip } [namespace current]] $uuid $sock $ip] chan event $sock readable $coro } method Connect {uuid sock ip} { my counter url_hit set line {} try { set readCount [::coroutine::util::gets_safety $sock 4096 line] dict set query REMOTE_ADDR $ip dict set query REQUEST_METHOD [lindex $line 0] set uriinfo [::uri::split [lindex $line 1]] dict set query REQUEST_URI [lindex $line 1] dict set query REQUEST_PATH [dict get $uriinfo path] dict set query REQUEST_VERSION [lindex [split [lindex $line end] /] end] if {[dict get $uriinfo host] eq {}} { |
︙ | ︙ | |||
508 509 510 511 512 513 514 | set reply [my dispatch $query] if {[llength $reply]} { if {[dict exists $reply class]} { set class [dict get $reply class] } else { set class [my cget reply_class] } | | > > | 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | set reply [my dispatch $query] if {[llength $reply]} { if {[dict exists $reply class]} { set class [dict get $reply class] } else { set class [my cget reply_class] } set pageobj [$class create [namespace current]::reply$uuid [self]] if {[dict exists $reply mixin]} { oo::objdefine $pageobj mixin [dict get $reply mixin] } $pageobj dispatch $sock $reply my log HttpAccess $line } else { try { my log HttpMissing $line chan puts $sock "HTTP/1.0 404 NOT FOUND" dict with query {} set body [subst [my template notfound]] chan puts $sock "Content-length: [string length $body]" chan puts $sock chan puts $sock $body } on error {err errdat} { puts stderr "FAILED ON 404: $err" } finally { catch {chan close $sock} catch {destroy $pageobj} } } } on error {err errdat} { try { puts stderr [dict print $errdat] chan puts $sock "HTTP/1.0 505 INTERNAL ERROR" dict with query {} set body [subst [my template internal_error]] chan puts $sock "Content-length: [string length $body]" chan puts $sock chan puts $sock $body my log HttpError $line } on error {err errdat} { puts stderr "FAILED ON 505: $::errorInfo" } finally { catch {chan close $sock} catch {destroy $pageobj} } } } method counter which { my variable counters incr counters($which) |
︙ | ︙ | |||
672 673 674 675 676 677 678 | } ### # Return true if this IP address is blocked # The socket will be closed immediately after returning # This handler is welcome to send a polite error message ### | | | 681 682 683 684 685 686 687 688 689 690 691 692 693 | } ### # Return true if this IP address is blocked # The socket will be closed immediately after returning # This handler is welcome to send a polite error message ### method Validate_Connection {sock ip} { return 0 } } package provide httpd 4.0.1 |