/* */ htaccfg: CHECKIT=0 /* Change this to 0 if you want to enable REMOTE configuration by SUPERUSERS */ /* background color */ USECOLOR='2dd52f' /* ---------------- DO NOT MODIFY BELOW THIS LINE ------------------ */ parse arg ddir,tempfile,sel,list,verb,uri,user,basedir,workdir,privset, , enmadd,transaction,verbose, , servername,host_nickname,homedir if verb=" " then do say " This SRE-Filter procedure is NOT meant to be run from the command line." exit end /* Do */ list=translate(list, ' ', '+'||'090a0d'x) /* Whitespace, etc. */ /* write results (2nd call */ if pos('WRITETO=',translate(list))>0 then do call writeres return ' Results written ' end who2=extract('CLIENTADDR') saddr2=extract('SERVERADDR') select when checkit=1 then do /* only if user = serveraddress !!! */ if who2<>saddr2 then do call lineout tempfile, '' call lineout tempfile, "SREFILTER ERROR " call lineout tempfile, ' ' call lineout tempfile,' Action not allowed remotely.
'
        call lineout tempfile,'   '
        call lineout tempfile
        'FILE ERASE TYPE text/html NAME' tempfile
        return 'HTACCFG: action not allowed remotely. '
     end
   end
   otherwise do
      if wordpos('SUPERUSER',privset)=0 then do
        'RESPONSE HTTP/1.0 401 Unauthorized '     /* Set HTTP response line */
        'header add WWW-Authenticate: Basic Realm='  /* challenge */

        call lineout tempfile, ''
        call lineout tempfile, "Not authorized "
        call lineout tempfile, ' '

        call lineout tempfile,'  You do not have configuration rights. 
'
        if who2=saddr2 then 
                call lineout tempfile,'
You may want to edit HTACCFG.CMD ' call lineout tempfile,' ' call lineout tempfile iia=dosdir(tempfile,'s') 'FILE ERASE TYPE text/html NAME' tempfile return '401 'iia' HTACCFG: not permitted to configure. ' end end end htfile=' ' ;htacc=' ' list=strip(list) DO UNTIL LIST="" PARSE VAR list a1 '&' list parse var a1 avar '=' aval if translate(avar)='HTFILE' then do htfile=strip(translate(translate(packur(aval),'\','/'))) htfile=strip(htfile,'t','\')||'\' end if translate(avar)='ACCFILE' then htacc=strip(translate(translate(packur(aval),'\','/'))) end /* do */ if left(htfile,1)='\' | pos(':',htfile)>0 then nop else htfile=translate(ddir||htfile,'\','/') if htacc=' ' then htacc=get_value('htaccess_file') if filespec('p',htfile)='\' then do call lineout tempfile,'

' HTFILE ' not permitted

' call lineout tempfile,' Sorry, HTACCESS file can not be in the root' call lineout tempfile, ' ' call lineout tempfile 'file erase type text/html name ' tempfile return 'htaccess not allowed in root ' end if htfile=' '| htacc=' ' then do call lineout tempfile,'

Missing information

' call lineout tempfile,' Sorry, the directory, or the name for the HTACCESS file,' call lineout tempfile,' was not specified.' call lineout tempfile, ' ' call lineout tempfile 'file erase type text/html name ' tempfile return ' missing information ' end /* do */ HTFILE=STRIP(HTFILE); HTFILE=STRIP(HTFILE,'T','\')||'\' tmp1=get_htaccess(0,HTfile,HTACC,ddir,TEMPFILE,2) parse var tmp1 gotlist ',' tmp1 gotlist=strip(gotlist) this1=htfile||htacc is1=stream(this1,'c','query exists') vlist='GOTLIST AUTH.NAME AUTH.TYPE AUTH.USERFILE AUTH.GROUPFILE ' vlist=vlist||'AUTH.INDEX REDIRECTFILE AUTH.LIMIT DIR.BUILD DIR.EXCLUDE ' vlist=vlist||'DIR.INFO DIR.DESCRIBE DIR.FORBID RX.BUILDdir RX.ENABLEPOSTPROCESS' vlist2=' x AuthName AuthType AuthUserFile AuthGroupFile DefaultIndex RedirFile ' vlist2=vlist2||' Limit BuildDir Dir.Exclude Dir.Info Dir.Describe Dir.Forbid ' vlist2=vlist2||' Dir.Builder EnablePostProcess ' gotlist0=gotlist call lineout tempfile, '' call lineout tempfile, "SRE-Filter HTACCESS configurator " call lineout tempfile, ' ' call lineout tempfile, "

SRE-Filter: HTACCESS Configurator

" call lineout tempfile,' Review current parameters & files for ' htfile ' ?' this1a=strip(this1,'t','.') foo=wordpos(translate(this1a),translate(gotlist)) if foo>0 then do gotlist=delword(gotlist,foo,1) end /* Do */ call lineout tempfile,'

For directory== ' translate(htfile) '

' call lineout tempfile,'
    ' if is1=' ' then call lineout tempfile,'
  • Currently, there is no HTACCESS file in: ' htfile else call lineout tempfile,'
  • The HTACCESS file for ' htfile ' is: ' this1 '' if gotlist<>' ' then call lineout tempfile,'
  • The set of HTACCESS files in the parent directories are: ' gotlist '' call lineout tempfile,'
' /* get "this files" parameter values (if accessible ) */ if is1 =' ' then do call lineout tempfile,'

Creating: ' this1 '

' /* initialize some variable */ auth.name=' '; auth.type=' ' ; auth.userfile=' ' ; auth.groupfile=' ' auth.index=' '; redirectfile=' '; auth.limit=' '; dir.exclude=' '; dir.info=' ' ; dir.describe=' ' ; dir.forbid=' ' ; rx.builddir=' ' end else do tmp1=get_htaccess(0,HTfile,HTACC,ddir,TEMPFILE,3) do mm=1 to words(vlist) parse var tmp1 aval ',' tmp1 avar=word(vlist,mm) ; aval=strip(aval) call value avar,aval end /* do */ call lineout tempfile,'

Modifying: ' this1 '

' end /* let user fill out form */ CALL LINEOUT TEMPFILE,'
' call lineout tempfile,'

Access control parameters

' ee=makeit('One line comment:','COMMENT',gotlist0,' ') call lineout tempfile,ee ee=makeit('

AuthName: Authorization name (the REALM) ','AuthName',gotlist0,auth.name,10) call lineout tempfile,ee ischeck1=' ' ;IF translate(auth.type)='BASIC' then ischeck1='CHECKED' ischeck2=' ';IF translate(auth.type)='IDENT' then ischeck2='CHECKED' call lineout tempfile,'

AuthType: Authorization type: ' CALL LINEOUT TEMPFILE,' BASIC ||' CALL LINEOUT TEMPFILE,'IDENT ' ee=makeit('AuthUserfile: Userfile (contains usernames and passwords) ','AuthUserFile',gotlist0,auth.userfile) call lineout tempfile,ee ee=makeit('AuthGroupfile: Group file (groups of users) ','AuthGroupFile',gotlist0,auth.groupfile) call lineout tempfile,ee if wordpos('REQUIRE',translate(auth.limit))=1 then auth.limit=delword(auth.limit,1,1) ee=makeit('Limit:Allowed users list','Limit',gotlist0,auth.limit) call lineout tempfile,ee call lineout tempfile, '

Redirection, etc. parameters

' ee=makeit('DefaultIndex: Directory specific default documents ','DefaultIndex',gotlist0,auth.index) call lineout tempfile,ee ee=makeit('ReDirFile: Redirection file ','ReDirFile',gotlist0,REDIRECTFILE) call lineout tempfile,ee call lineout tempfile,'

Parameters used by dynamic directory list processor

' ischeck1=' ' ;IF dir.build=1 then ischeck1='CHECKED' ischeck2=' ';IF dir.build=0 then ischeck2='CHECKED' call lineout tempfile,'

BuildDir:Enable dynamic directory list processor: ' CALL LINEOUT TEMPFILE,' YES (allow) || ' CALL LINEOUT TEMPFILE,'NO (do not allow)' ee=makeit('Dir.Exclude:Exclusion files (these files are not displayed) ', , 'Dir.Exclude',gotlist0,dir.exclude) call lineout tempfile,ee ischeck1=' ' ;IF _diris=1 then ischeck1='CHECKED' ischeck0=' ';IF _diris=0 then ischeck0='CHECKED' call lineout tempfile,'

Reset list of exclusion files ' CALL LINEOUT TEMPFILE,'
  • YES (use _Dir.Exclude) ' CALL LINEOUT TEMPFILE,'
  • NO (use Dir.Exclude)
  • ' ee=makeit('Dir.Info: Directory Info file (displayed at top of document) ', , 'Dir.Info',gotlist0,dir.info) call lineout tempfile,ee ee=makeit('Dir.Describe:File description file (per entry descriptions) ', , 'Dir.Describe',gotlist0,dir.describe) call lineout tempfile,ee ee=makeit('Dir.Builder: Name of dynamic directory list processor ', , 'Dir.Builder',gotlist0,rx.builddir) call lineout tempfile,ee ischeck1=' ' ;IF dir.forbid=1 then ischeck1='CHECKED' ischeck2=' ';IF dir.forbid=0 then ischeck2='CHECKED' call lineout tempfile,'

    Dir.Forbid: Prevent directory list processor from displaying directory:

    ' CALL LINEOUT TEMPFILE,'
  • YES (do NOT allow display) ' CALL LINEOUT TEMPFILE,'
  • NO (allow display)
  • ' ischeck=' '; if rx.enablepostprocess=' ' then ischeck='CHECKED' ischeck0=' ' ;IF rx.enablepostprocess=0 then ischeck0='CHECKED' ischeck1=' ' ;IF rx.enablepostprocess=1 then ischeck1='CHECKED' ischeck2=' ' ;IF rx.enablepostprocess=2 then ischeck2='CHECKED' call lineout tempfile,'
    EnablePostProcessor: Post processing option: ' CALL LINEOUT TEMPFILE,'
  • Disable Post Processing ' CALL LINEOUT TEMPFILE,'
  • Enable for all files' CALL LINEOUT TEMPFILE,'
  • Enable for all files .*HTM* extensions' CALL LINEOUT TEMPFILE,'
  • Enable for ".SHTML" files only' call lineout tempfile,'
  • ' call lineout tempfile,'


    ' if is1=' ' then call lineout tempfile,' ' else do call lineout tempfile,' ' call lineout tempfile,'
    --- Caution: the old copy of ' this1 ' will be deleted! ' end call lineout tempfile,'' CALL LINEOUT TEMPFILE,'

    ' /* ------ TIPS AND HINTS SETCION */ call lineout tempfile,'


    Review: Parameters and Files

    ' call lineout tempfile," Some notes on SRE-Filter's use of HTACCESS files " call lineout tempfile,'
    For the most part, SRE-Filter emulates GOHTTP. ' call lineout tempfile,' The following lists some potential differences: ' call lineout tempfile,'
    • BASIC authorization uses only the "uppermost" HTACCESS file (rather then all of them)' call lineout tempfile,'
    • EnablePostProcess is ignored for non-file transfers (that is, it is ignored when server side processing are recieved)' call lineout tempfile,'
    • Dir.Builder works -- we recommend the "SHOWDIR" variant (see SHOWDIR.DOC for details) ' call lineout tempfile,'
    • To invoke the Dir.Builder "dynamic directory list processsor", put !SHOWDIR at the end of the DefaultIndex list ' call lineout tempfile,'
    • IDENT is a bit flaky (it works reasonably well if you * the portion before the @ )' call lineout tempfile,'
    ' /* parameters from own and parent htaccess files */ tmp1=get_htaccess(0,HTfile,HTACC,ddir,TEMPFILE,2) do mm=1 to words(vlist) parse var tmp1 aval ',' tmp1 avar=word(vlist,mm) ; aval=strip(aval) call value avar,aval end /* do */ call lineout tempfile,'

    Effective parameters values for ' htfile '

    ' call lineout tempfile,' These may include parameters set by HTACCESS files in parent directories
    ' if gotlist0=' ' then do call lineout tempfile,'
    No HTACCESS parameters!
    ' end /* Do */ else do call lineout tempfile,'
    ' do mm=2 to words(vlist) /* dont show gotlist */ avar=word(vlist,mm) ; avar2=word(vlist2,mm) aval=value(avar) call lineout tempfile,'
    ' avar2 '
    ' aval end /* do */ call lineout tempfile,'
    ' end /* ----- USER FILE */ call lineout tempfile,'

    User file

    ' call lineout tempfile,' Username/password file should have entries with the following syntax:
    ' call lineout tempfile,'
    USERNAME:PASSWORD
    ' call lineout tempfile,' For example:
  • John:final1
  • Sam:invidious
  • ; comment
  • wonder:womack
  • ' call lineout tempfile,'

    User file for: ' htfile'

    ' if auth.userfile=' ' then do call lineout tempfile,'
    No user file selected
    ' end else do call lineout tempfile,' Current user file is: ' auth.userfile '

    ' foo=get_lines(auth.userfile) if foo>0 then do call lineout tempfile,' Contents of ' auth.userfile '

      ' do mm=1 to foo alin=strip(somelines.mm) if alin=' ' then iterate if abbrev(alin,';')=1 then call lineout tempfile, '
    • 'alin ' ' else call lineout tempfile, '
    • 'alin end /* do */ call lineout tempfile,'
    ' end else do call lineout tempfile,'
    File does not exist: 'auth.userfile '
    ' end end /* Do */ /* ----- groups FILE */ call lineout tempfile,'

    Groups file

    ' call lineout tempfile,' The user Groups file should have entries with the following syntax:
    ' call lineout tempfile,'
    GROUPNAME: user1 user2 use33r@xx.yy.zz
    ' call lineout tempfile,' For example: ' call lineout tempfile,'
  • Detroit: phil george ' call lineout tempfile,'
  • Boston: joe *@dept1.school.edu ' call lineout tempfile,' ... (note the use of the IDENT style name, and the * wildcard)' call lineout tempfile,'
  • ; comment
  • Miami: Cheryl Ruby Carlos
  • ' call lineout tempfile,'

    Groups file for: ' htfile '

    ' if auth.groupfile=' ' then do call lineout tempfile,'
    No group file selected
    ' end else do call lineout tempfile,' Current group file is: ' auth.groupfile '

    ' foo=get_lines(auth.groupfile) if foo>0 then do call lineout tempfile,' Contents of ' auth.groupfile '

      ' do mm=1 to foo alin=strip(somelines.mm) if alin=' ' then iterate if abbrev(alin,';')=1 then call lineout tempfile, '
    • 'alin ' ' else call lineout tempfile, '
    • 'alin end /* do */ call lineout tempfile,'
    ' end else do call lineout tempfile,'
    File does not exist: 'auth.groupfile '
    ' end end /* Do */ /* ----- redirectFILE */ call lineout tempfile,'

    Redirection file

    ' call lineout tempfile,' The Redirection file should have entries with the following syntax:
    ' call lineout tempfile,'
    old_url : new_url NOTIFY
    ' call lineout tempfile, 'Where NOTIFY is optional (if present, redirection will NOT occur; instead, the client recieves a short notification)

    ' call lineout tempfile,' For example:

    ' call lineout tempfile,'
  • zoo/sched.htm : http://www.newzoo.org/index.htm ' call lineout tempfile,'
  • store/toys/*: http://toys.newstore.com/inventory/* NOTIFY ' call lineout tempfile,' ... (note the use of the * wildcard) ' call lineout tempfile,'
  • !CASE SENSITIVE ... (following entries are case sensitive) ' call lineout tempfile,'
  • candy/VANILLA.HTM : /icecream/vanilla.htm ... ( no http:// in the new_url implies redirect to same site) ' call lineout tempfile,'
  • ' call lineout tempfile,'

    Redirection file for: ' htfile '

    ' if redirectfile=' ' then do call lineout tempfile,'
    No redirection file selected
    ' end else do call lineout tempfile,' Current redirection file is: ' redirectfile '

    ' foo=get_lines(redirectfile) if foo>0 then do call lineout tempfile,' Contents of ' redirectfile '

      ' do mm=1 to foo alin=strip(somelines.mm) if alin=' ' then iterate if abbrev(alin,'!')=1 then call lineout tempfile, '
    • 'alin ' ' else call lineout tempfile, '
    • 'alin end /* do */ call lineout tempfile,'
    ' end else do call lineout tempfile,'
    File does not exist: 'redirectfile '
    ' end end /* Do */ call lineout tempfile,' ' call lineout tempfile 'file erase type text/html name ' tempfile return 'Changes made, now submitting ' /* do mm=1 to words(vlist) parse var tmp1 aval ',' tmp1 avar=word(vlist,mm) ; aval=strip(aval) ; avar2=word(vlist2,mm) if mm=1 then iterate call lineout tempfile,'
    ' avar2 '
    ' aval end call lineout tempfile,'

    ' */ makeit:procedure parse arg message,avar,gotlist0,aval,nshow if nshow=' 'then nshow=28 if gotlist0=' ' then t1=' ' else t1=aval rr='

    '|| message|| ':' rr=rr||' ' return rr /* ----------- */ /* get environment value, possibly host specific */ /* ------------ */ get_value: procedure expose enmadd host_nickname usecolor parse arg vname,hname0 if hname0=0 then hname=' ' else hname=strip(host_nickname) vname=strip(vname) ; if hname<>' ' then do aval=value(enmadd||vname||'.'||hname,,'os2environment') if aval<>' ' Then return aval end aval=value(enmadd||vname,,'os2environment') return aval /* write results routine */ writeres: list0=list do until list="" parse var list a1 '&' list parse upper var a1 avar '=' aval if avar='WRITETO' then do htout=strip(packur(aval)) leave end /* Do */ end /* do */ foo=sysfiledelete(htout) foo=lineout(htout,,1) _diris=0 if pos('_DIRIS=1',upper(list0))>0 then _diris=1 list=list0 do until list="" parse var list a1 '&' list parse var a1 avar '=' aval avar=strip(packur(avar)); aval=strip(packur(aval)); if translate(avar)='_DIRIS' then iterate if translate(avar)='WRITETO' then iterate if translate(avar)='LIMIT' then aval=' require '||aval if translate(avar)='COMMENT' then avar='; ' if translate(avar)='DIR.EXCLUDE' & _diris=1 then avar='_'||avar if aval \=' ' then call lineout htout,avar ':' aval end call lineout htout call lineout tempfile, '' call lineout tempfile, "SRE-Filter HTACCESS configurator " call lineout tempfile, ' ' call lineout tempfile, "

    SRE-Filter: HTACCESS Configurator

    " call lineout tempfile,' Results were written to ' htout call lineout tempfile, ' ' call lineout tempfile 'file erase type text/html name ' tempfile return 0 /* ----------------------------------------------------------------------- */ /* get_HTACCESS --- a modification of Don Meyer's CHECKAUTH & other stuff: This will CHECK all the accessfilenames in the tree underneath file for access privileges, etc. For details on how to set up an accessfile, see http://w3.ag.uiuc.edu/DLM/GOHTTP/Auth.Guide.html ENABLEPOSTPROCESS (use the post_filter stuff), and _DIR.BUILDER When dodirs=2, return ALL parameters (used by htaccess configurator) Dodirs=3, just the "own directory" (if it exists) */ /* ----------------------------------------------------------------------- */ get_htaccess:procedure expose _diris parse arg sel,file,accessfilename,dir,TEMPFILE,dodirs file = translate( file, '/', '\') dir.exclude=' ' PathTo = '' rest = file retCode = 0 gotlist=' ' set=' ' /* initialize some variable */ auth.name=' '; auth.type=' ' ; auth.userfile=' ' ; auth.groupfile=' ' auth.index=' '; redirectfile=' '; auth.limit=' '; dir.exclude=' '; dir.info=' ' ; dir.describe=' ' ; dir.forbid=' ';rx.builddir=' ' _diris=0 rx.enablepostprocess=' ' dir.build=0 ; rx.builddir=' ' owndir=filespec('d',file)||filespec('p',file) owndir=translate(translate(owndir,'/','\')) owndir=strip(owndir,'t','/') /* find htaccess files; and if found, extract the parameters, starting at base of directory tree (thus, own htaccess file is favored */ do while (rest \= '') restdoggy=right(rest,1) parse var rest _dir'/'rest if (right( _dir,1) == ':') then PathTo = _dir else PathTo = PathTo'/'_dir if dodirs==3 then do; if translate(pathto) \= owndir then do iterate end end goofy=rest ; if goofy=' ' & restdoggy='/' then goofy='/' if (left(PathTo,3) == '///') then PathTo = substr(PathTo,2) else if (goofy \= '') & (right( _dir,1) \= ':') then do geek1=pathto'/'accessfilename ACLfile = stream(geek1, 'c', 'query exists') if (ACLfile \= '') then do /* if not, climb up the tree */ gotlist=gotlist' 'aclfile Auth.GroupFile = ' ' Auth.Limit = ' ' rc = stream( ACLfile, 'c', 'OPEN READ') line = linein( ACLfile, 1) do while (line \= '') do while( pos(left(line,1), "2009"x) > 0); line = substr(line, 2); end if ( pos(left(line,1), "#") > 0) then line = substr(line, 2) if ( left(line,1) == ';') then line = ';COMMENT' parse var line key ':' val val = strip(val) key = translate(key) if (key = 'AUTHUSERFILE') | (key = 'AUTHGROUPFILE') | (key = 'REDIRLIST') then do if (pos(':', val ) == 0) then do val = translate(val, '\', '/') if (left(val,1) == '\') then val = substr( val, 2) val = dir || val end end select when (key = 'AUTHNAME') then Auth.Name = val when (key = 'AUTHTYPE') then Auth.Type = translate( strip(val)) when (key = 'AUTHUSERFILE') then Auth.UserFile = val when (key = 'AUTHGROUPFILE') then Auth.GroupFile = val when (key = 'DEFAULTINDEX') then Auth.Index = val when (key = 'REDIRLIST') then RedirectFile = val when (key = 'REDIRFILE') then RedirectFile = val /* bug? in original code */ when (key = 'LIMIT') then Auth.Limit = val when (key = 'BUILDDIR') then Dir.Build = (val \= '0') when (key = 'DIR.EXCLUDE') then Dir.Exclude = Dir.Exclude val when (key = '_DIR.EXCLUDE') then do Dir.Exclude = val _diris=1 end /* Do */ when (key = 'DIR.INFO') then Dir.Info = val when (key = 'DIR.DESCRIBE') then Dir.Describe = val when (key = 'DIR.FORBID') then Dir.Forbid = (val \= '0') when (key = 'DIR.BUILDER') then Rx.BuildDir = val when (key = 'ENABLEPOSTPROCESS') then do v = left(strip(val),1) if (pos(v, '012') > 0) then Rx.EnablePostProcess = v end otherwise end line = linein( ACLfile) end rc = stream( ACLfile, 'c', 'close') end /* this aclfile */ end /* goofy */ end /* climbing up directory tree */ bigone=gotlist', 'auth.name', 'auth.type', 'auth.userfile', 'auth.groupfile bigone=bigone', 'auth.index', 'redirectfile', 'auth.limit', 'dir.build bigone=bigone', 'dir.exclude', 'dir.info', 'dir.describe', 'dir.forbid', 'rx.builddir bigone=bigone', 'rx.enablepostprocess return bigone /* get file line by line . Return in somelines. variable */ get_lines:procedure expose somelines. parse arg afile crlf='0d0a'x mm=0 foo=stream(afile,'c','query exists') if foo=' ' then do somelines.0=0 return 0 end foo=charin(afile,1,chars(afile)) foo=strip(foo,'t','1a'x) a=stream(afile,'c','close') do until foo='' parse var foo aline (crlf) foo mm=mm+1 somelines.mm=aline end somelines.0=mm return mm end /* do */