<?php

/**
 * simple-transfer - a simple web app for asynchronously transferring single files
 * Copyright (c) 2010 rasenplanscher [ github.com/rasenplanscher ]
 */
if (!empty($_POST['username'])) {
    # get data for given user name
    $userdata = db_get_userdata($_POST['username']);
    # if the pass checks out, the client is authenticated
    $authorized = $_POST['pass'] ? $userdata['pass'] == $_POST['pass'] : false;
    # if the list flag is set, the client is allowed to access the list view
    $list_allowed = $authorized && $userdata['list'];
    if ($authorized) {
        # remember the username
        $username = $_POST['username'];
        # have the client reload with a GET request
        header(sprintf('Location: %s', $request_uri));
        exit;
    }
}
# show the login page if the client is not authenticated
if (!$authorized) {
    error(401, empty($_POST['username']) && empty($_POST['pass']) ? array('login, multiuser') : array('login failure', 'login, multiuser'), array('uri' => $_SERVER['REQUEST_URI']));
}
if (isset($nonce) and $_SERVER['PHP_AUTH_DIGEST']) {
    # parse Authentication header as an array
    $authentication = array();
    preg_match_all('/(\\w+)=(?:"([^"]+)"|([^\\s,]+))/', $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
        $authentication[$match[1]] = $match[2] ? $match[2] : $match[3];
    }
    # logs out a client sending a different username after successful authentication
    if (!$username) {
        $username = $authentication['username'];
    }
    # if the nonce is different, either the client is a fraud or there has been an error
    # either way, further processing is futile
    if ($authentication['nonce'] == $nonce and $authentication['username'] == $username) {
        # get data for given username
        $userdata = db_get_userdata($username);
        # determine the hash for the current request
        $request_hash = md5(sprintf('%s:%s', $_SERVER['REQUEST_METHOD'], $request_uri));
        # determine the response hash the authentic client would send
        switch ($authentication['qop']) {
            case '':
                # legacy digest authentication
                $response_hash = md5(sprintf('%s:%s:%s', $userdata['hash'], $nonce, $request_hash));
                break;
            case 'auth':
                # modern digest authentication, without integrity protection
                if ($authentication['nc'] > $nonce_count) {
                    $nonce_count = $authentication['nc'];
                    $response_hash = md5(sprintf('%s:%s:%s:%s:auth:%s', $userdata['hash'], $nonce, $nonce_count, $authentication['cnonce'], $request_hash));
                }
                break;