F*EX (Frams' Fast File EXchange) is a service to send big (large, huge, giant,
...) files from a user A to a user B, anywhere on the internet.

The sender uploads the file to the F*EX-server and the recipient automatically
gets a notification e-mail with a download-URL.

Main features of F*EX

  * file transfer of virtually unlimited file size
  * recepient and sender only need an e-mail program and a web browser - of any
    kind, they do not have to install any software
  * RESEND and REGET for resuming after link failures at last sent byte
  * auto-notification of recipient
  * auto-deletion after download
  * auto-deletion after expiration date (default: 5 days)
  * full-users can create sub-users, who can send only to this full-user
  * maintenance-free: no admin interaction necessary besides creating new F*EX
    accounts
  * Sending to multiple recipients needs storage on the server only once
  * F*EX is a HTTP web-service and needs no firewall-tunnels
  * support for streams, too (SEX : Stream EXchange)
  * for real UNIX users, there are the shell programs fexsend and fexget to
    avoid annoying web browser usage
  * protocol and source-code free available (GPL)

The end user normally uses F*EX with his web browser and the URLs
http://YOURFEXSERVER/fup (file upload) and http://YOURFEXSERVER/fop (file
download). 


F*EX is not an anonymous service, the admin must register the user with
his e-mail address and auth-ID string. This task must be done with the CLI
program "fac" (F*EX admin control). You can imagine the auth-ID as some kind 
of low security password.

Alternativly the users can register theirselves with http://YOURFEXSERVER/fur
(F*EX user registration), if the admin allows them to do so. This is done by
setting the variables @local_domains and @local_hosts in
FEXHOME/lib/fex.ph, for example: 
	@local_hosts = qw(127.0.0.1 10.10.100.0-10.10.255.255);
	@local_domains = qw(rus.uni-stuttgart.de flupp.org);

F*EX full users can theirselves register "sub-users" with
http://YOURFEXSERVER/fuc 

sub-users can only fex to their full-user, not to any others, and they
cannot create other sub-users.


The F*EX user is the same as the "sender" in the fup CGI and the "from"
parameter in the F*EX URL. 

The (confusing) naming scheme is historically based :-)


The recipient (normally) does not need any registration. He authenticates
himself with his unique download-URL which he gets in the notification
e-mail.


You do not need to build F*EX URLs manually, they are generated by the
F*EX programs. 


F*EX does not use cookies, the sessions are based on unique URL parameters
or POST variables (FROM, TO, ID). For security reasons the URL parameters
become a MD5-hashed access key link (akey), generated by the CGIs.
Otherwise a third person could easily read the authorization data from the
user webbrowser URL address field. The lookup access keys in
$spooldir/.akeys/ contain the remote ip address for even more security :-)
So, access by the akey parameter is only possible from the same IP
address, others cannot "steal" an akey.


After download the file will be deleted after a grace time of 1 minute.
This allows a recipient to get the file again if he had problems in saving
it. 

With the fexsend client the sender can change this behavior:

option -D means "delay autodelete": do not delete the the file directly
after download, but with the nightly fex_cleanup cronjob. More downloads
are possible only from the same IP.

option -K means "keep file": do not delete the file after download, but
only after expiration date (normally 5 days). More downloads are possible
from any IP.

If you want "delay autodelete" to be the default behaviour for all users
and each transfer then set
	$autodelete = 'DELAY';
in FEXHOME/lib/fex.ph

In addition, you can add to the "Recipient(s)" field of the fup CGI:
"autodelete=delay" or "autodelete=no" or "keep=x" (where x is the number
of days). Example:
Recipient(s): framstag@rus.uni-stuttgart.de keep=10

These options are also possible in the server address book (see CGI fuc).

If you need more security, then set "$fop_auth = 1;" in fex.ph and
force HTTPS (see extra documentation SSL). With fop_auth upload is
restricted to registered users and download requires (HTTP)
authorization. The credentials are the F*EX user e-mail and auth-ID.


By standard installation the base directory FEXHOME is the same as the
login HOME of user fex, but you can move it if you want. FEXHOME is
determined by the full path of fexsrv as configured in
/etc/xinetd.d/fex . Change this when you move FEXHOME!


FEXHOME contains:

	spool/				spool directory and user data 
        htdocs/				directory for generic download files
        bin/				directory for programs
        cgi-bin/			directory for CGI programs
	lib/				directory for library and config files
	

Files in spool:

	cleanup.log			log of daily cleanup cronjob
	dop.log				log of HTTP document output
	error.log			log of errors
	fexsrv.log			log of all HTTP requests
	fop.log				log of file downloads
	fup.log				log of file uploads
	fur.log				log of user self registrations
	sex.log				log of stream exchanges
	$from/@				regular user auth-ID and sub-users IDs
	$from/@ALLOWED_RECIPIENTS	recipients restrictions for this user
	$from/@ADDRESS_BOOK		users recipient address book
	$to/$from/$file/upload		file data in upload progress
	$to/$from/$file/filename	original file name
	$to/$from/$file/size		original file size
	$to/$from/$file/data		file data after complete upload
	$to/$from/$file/keep		keep time (autoexpire) in days
	$to/$from/$file/autodelete	autodelete option: YES NO or DELAY
	$to/$from/$file/notify		notify flag
	$to/$from/$file/error		error message if file has gone
	$to/$from/$file/dkey		download key

As you see, the first directory sometimes means sender and sometimes means
recipient! This is by intention and depends on the case of usage!

A registered full F*EX user is identified by the file $spooldir/$from/@
Only if this file contains his auth-ID this user is able to send files to
others. Otherwise he is just an unpriviledged recipient.

You can customize the upload CGI fup by editing FEXHOME/lib/fup.pl .

Additional directories in spool:

        .dkeys/				download keys lookup directory
        .ukeys/				upload keys lookup directory
        .akeys/				authentification keys lookup directory
        .skeys/				subuser keys lookup directory
        .debug/				directory for debug output (optional)
        .reg/				temporary data for user selfregistration


If you need to trace a F*EX request, then set 
	$debug = 1;
in lin/fex.ph and look in ~/spool/.debug/ for the correspondening files.

Also the user fex gets a Bcc e-mail of all sent notification e-mails. This
helps for debugging purposes. If you do not like this feature, then add to
/home/fex/.procmailrc :

	:0
        * ^From:.*via F\*EX service
        /dev/null


F*EX comes with its own web server: fexsrv
Standard web servers like apache have been proven problematic, either in
speed or because of a 2-GB-limit. 

It is not possible to use the F*EX CGIs with an alternative web server,
because the F*EX CGIs need special fexsrv features.

fexsrv starts the CGIs fup (file upload), fop (file output), fuc (fex user
control) and sex (stream exchange).

SEX has the opposite authorization model of FEX: The sender does not
need any registration. He can send a stream to any registered SEX user,
who must identify himself with his auth-ID. This is because a stream does
not cost resources when it is not bound to a recipient. It will block
otherwise.


fexsrv also can do generic document output like a normal web server.
For this, your files must be under FEXHOME/htdocs and they must not have
the same name as the CGIs under FEXHOME/cgi-bin, because the CGIs have
priority.

*.html files may contain $VARIABLES$ which will be substituted with the
value of the corresponding environment variable. See example
$SERVER_ADMIN$ in FEXHOME/htdocs/index.html


cronjob fex_cleanup is run once a day and deletes expired uploads and does
some other spool houskeeping.


The clients fexsend, schwuppdiwupp and F*IX can encrypt the auth-ID
together with a session-ID with MD5. The session-ID itself is provided by
the server after a "GET SID" HTTP request. 


To understand and trace the F*EX protokoll you can use fexsend with the -v
option. 

Example (indented lines are responses from the server):

framstag@fex:~: fexsend -v X.png framstag@rus.uni-stuttgart.de     
TCPCONNECT to fex.rus.uni-stuttgart.de
GET SID HTTP/1.1
        HTTP/1.1 201 QulRzD7u

HEAD /fop/framstag@rus.uni-stuttgart.de/framstag/X.png??&ID=MD5H:ddca20d650e88f34dc04a6e60e555bf0 HTTP/1.1
        HTTP/1.1 200 OK
        Content-Length: 0

POST /fup HTTP/1.1
Host: fex.rus.uni-stuttgart.de
User-Agent: fexsend
Content-Length: 850200
Content-Type: multipart/form-data; boundary=wCQviRTU3NKurJdAGa9XfHBLT3jHO8GQft4rq6pUQDrEkuGv

--wCQviRTU3NKurJdAGa9XfHBLT3jHO8GQft4rq6pUQDrEkuGv
Content-Disposition: form-data; name="FROM"

framstag@rus.uni-stuttgart.de
--wCQviRTU3NKurJdAGa9XfHBLT3jHO8GQft4rq6pUQDrEkuGv
Content-Disposition: form-data; name="TO"

framstag@rus.uni-stuttgart.de
--wCQviRTU3NKurJdAGa9XfHBLT3jHO8GQft4rq6pUQDrEkuGv
Content-Disposition: form-data; name="ID"

MD5H:ddca20d650e88f34dc04a6e60e555bf0
--wCQviRTU3NKurJdAGa9XfHBLT3jHO8GQft4rq6pUQDrEkuGv
Content-Disposition: form-data; name="FILE"; filename="X.png"
Content-Type: application/octet-stream
Content-Length: 849590

(file content)
--wCQviRTU3NKurJdAGa9XfHBLT3jHO8GQft4rq6pUQDrEkuGv--
transfered: 829 kB in 1 s (829 kB/s)
        HTTP/1.1 200 OK
        Server: fexsrv
        Expires: 0
        Cache-Control: no-cache
        Connection: close
        Content-Type: text/html; charset=UTF-8
        Location: http://fex.rus.uni-stuttgart.de/fop/CVlBy2Nm/X.png
        X-Recipient: framstag@rus.uni-stuttgart.de

        <html>
          <meta http-equiv="expires" content="0">
          <title>fex.rus.uni-stuttgart.de F*EX upload</title>
        </head>
        <body bgcolor="pink">
        <h1>fex.rus.uni-stuttgart.de <a href="/">F*EX</a> upload</h1>
        X.png (829 kB) received and saved<p>
        Using F*EX for less than 1 MB: ever heard of MIME e-mail? :-)<p>
        framstag@rus.uni-stuttgart.de notified<p>
        <a href="/fup?akey=&to=framstag@rus.uni-stuttgart.de">send another file</a>
        </body></html>


Comment on the HEAD request above:
The client fexsend sends it to request whether the file has been sent
before and if it was successful or not. On the later case, the server
would reply how many bytes has been already received and the client then
can send only the missing part. Normally the answer to the HEAD request is
0 (see above), which means: nothing of this file has been received so far.


Default character set for F*EX is UTF-8, because most clients seem to use
it. The problem is, that it is nowhere defined which character set HTTP
itself uses.

Important for programmers: The perl variables of the F*EX CGI's (fup, fop,
etc) have their UTF-8 flag turned off. This means, they contain UTF-8 data
in binary representation.
