File: auth-lib.c

package info (click to toggle)
ucspi-proxy 0.98-1
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 268 kB
  • ctags: 185
  • sloc: ansic: 1,159; makefile: 53
file content (106 lines) | stat: -rw-r--r-- 2,594 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <msg/msg.h>
#include <str/str.h>
#include "auth-lib.h"
#include "ucspi-proxy.h"

extern const char* local_name;

str username = {0,0,0};

static bool saw_auth_login = 0;
static bool saw_auth_plain = 0;
static str tmpstr;

void make_username(const char* start, ssize_t len, const char* msgprefix)
{
  str_copyb(&username, start, len);
  if (local_name && str_findfirst(&username, AT) < 0) {
    str_catc(&username, AT);
    str_cats(&username, local_name);
  }
  msg2(msgprefix, username.s);
}

static const char* skipspace(const char* ptr)
{
  while (*ptr == ' ')
    ++ptr;
  return ptr;
}

static int iseol(char ch)
{
  return ch == CR || ch == LF;
}

static void handle_auth_login_response(str* line, ssize_t offset)
{
  saw_auth_login = 0;
  if (!base64decode(line->s + offset, line->len + offset, &tmpstr))
    username.len = 0;
  else {
    make_username(tmpstr.s, tmpstr.len, "AUTH LOGIN ");
    line->len = offset;
    base64encode(username.s, username.len, line);
    str_catb(line, CRLF, 2);
  }
}

static void handle_auth_plain_response(str* line, ssize_t offset)
{
  int start;
  int end;

  saw_auth_plain = 0;
  if (base64decode(line->s + offset, line->len - offset, &tmpstr)) {
    /* tmpstr should now contain "AUTHORIZATION\0AUTHENTICATION\0PASSWORD" */
    if ((start = str_findfirst(&tmpstr, NUL)) >= 0
	&& (end = str_findnext(&tmpstr, NUL, ++start)) > start) {
      make_username(tmpstr.s + start, end - start, "AUTH PLAIN ");
      str_splice(&tmpstr, start, end - start, &username);
      line->len = offset;
      base64encode(tmpstr.s, tmpstr.len, line);
      str_catb(line, CRLF, 2);
    }
  }
}

int handle_auth_response(str* line, ssize_t offset)
{
  if (saw_auth_login)
    handle_auth_login_response(line, offset);
  else if (saw_auth_plain)
    handle_auth_plain_response(line, offset);
  else
    return 0;
  return 1;
}

int handle_auth_parameter(str* line, ssize_t offset)
{
  const char* ptr;

  ptr = skipspace(line->s + offset);
  /* No parameter, so just pass it through. */
  if (iseol(*ptr))
    return 0;
  if (strncasecmp(ptr, "LOGIN", 5) == 0) {
    if (ptr[5] == ' ' && !iseol(*(ptr = skipspace(ptr + 5))))
      handle_auth_login_response(line, ptr - line->s);
    else
      saw_auth_login = 1;
  }
  else if (strncasecmp(ptr, "PLAIN", 5) == 0) {
    if (ptr[5] == ' ' && !iseol(*(ptr = skipspace(ptr + 5))))
      handle_auth_plain_response(line, ptr - line->s);
    else
      saw_auth_plain = 1;
  }
  return 1;
}