]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/digest_auth/LDAP/digest_pw_auth.cc
Support concurrency channels in Digest authentication helpers
[thirdparty/squid.git] / helpers / digest_auth / LDAP / digest_pw_auth.cc
1 /*
2 * digest_pw_auth.c
3 *
4 * AUTHOR: Robert Collins. Based on ncsa_auth.c by Arjan de Vet
5 * <Arjan.deVet@adv.iae.nl>
6 * LDAP backend extension by Flavio Pescuma, MARA Systems AB <flavio@marasystems.com>
7 *
8 * Example digest authentication program for Squid, based on the original
9 * proxy_auth code from client_side.c, written by
10 * Jon Thackray <jrmt@uk.gdscorp.com>.
11 *
12 * - comment lines are possible and should start with a '#';
13 * - empty or blank lines are possible;
14 * - file format is username:password
15 *
16 * To build a directory integrated backend, you need to be able to
17 * calculate the HA1 returned to squid. To avoid storing a plaintext
18 * password you can calculate MD5(username:realm:password) when the
19 * user changes their password, and store the tuple username:realm:HA1.
20 * then find the matching username:realm when squid asks for the
21 * HA1.
22 *
23 * This implementation could be improved by using such a triple for
24 * the file format. However storing such a triple does little to
25 * improve security: If compromised the username:realm:HA1 combination
26 * is "plaintext equivalent" - for the purposes of digest authentication
27 * they allow the user access. Password syncronisation is not tackled
28 * by digest - just preventing on the wire compromise.
29 *
30 * Copyright (c) 2003 Robert Collins <robertc@squid-cache.org>
31 */
32 #include "squid.h"
33 #include "digest_common.h"
34 #include "helpers/defines.h"
35 #include "ldap_backend.h"
36
37 #define PROGRAM_NAME "digest_ldap_auth"
38
39 static void
40 GetHHA1(RequestData * requestData)
41 {
42 LDAPHHA1(requestData);
43 }
44
45 static void
46 ParseBuffer(char *buf, RequestData * requestData)
47 {
48 char *p;
49 requestData->parsed = 0;
50 if ((p = strchr(buf, '\n')) != NULL)
51 *p = '\0'; /* strip \n */
52
53 p = NULL;
54 requestData->channelId = strtoll(buf, &p, 10);
55 if (*p != ' ') // not a channel-ID
56 requestData->channelId = -1;
57 else
58 buf = ++p;
59
60 if ((requestData->user = strtok(buf, "\"")) == NULL)
61 return;
62 if ((requestData->realm = strtok(NULL, "\"")) == NULL)
63 return;
64 if ((requestData->realm = strtok(NULL, "\"")) == NULL)
65 return;
66 requestData->parsed = -1;
67 }
68
69 static void
70 OutputHHA1(RequestData * requestData)
71 {
72 requestData->error = 0;
73 GetHHA1(requestData);
74 if (requestData->channelId >= 0)
75 printf("%u ", requestData->channelId);
76 if (requestData->error) {
77 SEND_ERR("message=\"No such user\"");
78 return;
79 }
80 printf("OK ha1=\"%s\"\n", requestData->HHA1);
81 }
82
83 static void
84 DoOneRequest(char *buf)
85 {
86 RequestData requestData;
87 ParseBuffer(buf, &requestData);
88 if (!requestData.parsed) {
89 if (requestData.channelId >= 0)
90 printf("%u ", requestData.channelId);
91 SEND_BH("message=\"Invalid line received\"");
92 return;
93 }
94 OutputHHA1(&requestData);
95 }
96
97 static void
98 ProcessArguments(int argc, char **argv)
99 {
100 int i;
101 i = LDAPArguments(argc, argv);
102 if (i)
103 exit(i);
104 }
105
106 int
107 main(int argc, char **argv)
108 {
109 char buf[HELPER_INPUT_BUFFER];
110 setbuf(stdout, NULL);
111 ProcessArguments(argc, argv);
112 while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL)
113 DoOneRequest(buf);
114 exit(0);
115 }