Logo Search packages:      
Sourcecode: ziproxy version File versions  Download package

auth.c

/* auth.c
 * Part of ziproxy package
 *
 * Copyright (c)2005-2008 Daniel Mealha Cabrita
 *
 * Released subject to GNU General Public License v2 or later version.
 *
 * HTTP proxy authentication routines.
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "txtfiletools.h"
#include "strtables.h"
#include "auth.h"

static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
 
// Decode login:pass pair for HTTP authorization
char *base64_decode (const char *input) {
    unsigned char in[4], out[3], v;
    int r, i, len, str_len;
    char *outstr;
    int outpos=0;

    outstr=(char *)malloc(512);
    str_len = strlen(input);

    r = 0;
    while (input[r] && outpos < 508 ) {
        for (len = 0, i=0; i<4 && input[r]; i++) {
            v = 0;
            while(input[r] && v == 0 ) {
                v = (unsigned char) input[r++];
                v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
                if(v)
              v = (unsigned char) ((v == '$') ? 0 : v - 61);
            }
            if (input[r] || ( (str_len % 4) == 0 && input[str_len-1] != '=' ) ) {
            len++;
            if (v)
            in[i] = (unsigned char) (v - 1);
          } else {
            in[i] = 0;
          }
        }

        if(len) {
        out[0] = (unsigned char) (in[0] << 2 | in[1] >> 4);
        out[1] = (unsigned char) (in[1] << 4 | in[2] >> 2);
        out[2] = (unsigned char) (((in[2] << 6) & 0xc0) | in[3]);
        for (i=0; i<len-1; i++)
          outstr[outpos++] = out[i];

        }
    }
    outstr[outpos]=0;
    return(outstr);
}

/* load auth file into memory */
/* the returned structure must be free'ed manually later */
t_st_strtable *auth_create_populate_from_file (const char *filename)
{
      char *userpasstxt;
      t_st_strtable *userpass;
      char *userpass_pos, *lone_userpass;
      int linelen, useful_linelen;

      if ((userpasstxt = load_textfile_to_memory (filename)) == NULL)
            return (NULL);
      
      if ((userpass = st_create ()) == NULL) {
            free (userpasstxt);
            return (NULL);
      }

      /* preprocess text in order to be more palatable */
      fix_linebreaks_qp (userpasstxt, strlen (userpasstxt), userpasstxt);
      remove_junk_data (userpasstxt, userpasstxt);

      /* this routine assumes there are no empty lines (just LF) */
      userpass_pos = userpasstxt;
      while ((linelen = get_line_len (userpass_pos)) != 0) {
            if (*(userpass_pos + (linelen - 1)) == '\n')
                  useful_linelen = linelen - 1;
            else
                  useful_linelen = linelen;

            lone_userpass = calloc (useful_linelen + 1, sizeof (char));
            strncpy (lone_userpass, userpass_pos, useful_linelen);
            *(lone_userpass + useful_linelen) = '\0';

            /* nometa prevents a '*' being incorrectly treated as a meta-character */
            st_insert_nometa (userpass, lone_userpass);

            free (lone_userpass);
            userpass_pos += linelen;
      }

      free (userpasstxt);
      return (userpass);
}

// TODO: optimize this -- store userpass in base64 encoding and compare base64-to-base64 instead
/* userpass is formated as follow: user:base64-encoded-password */
/* returns: !=0 u/p is valid, ==0 invalid u/p */
int check_authentication (const t_st_strtable *passwd_table, const char *userpass)
{
      char *decoded_userpass;
      int retcode;

      decoded_userpass = base64_decode (userpass);
      retcode = st_check_if_matches_nometa (passwd_table, decoded_userpass);
      free (decoded_userpass);
      return (retcode);
}


Generated by  Doxygen 1.6.0   Back to index