]> git.stg.codes - stg.git/blob - projects/rlm_stg/iface.cpp
Implemented rlm_stg.
[stg.git] / projects / rlm_stg / iface.cpp
1 #include "iface.h"
2
3 #include "stg_client.h"
4
5 #include <cstring>
6
7 #include <strings.h>
8
9 namespace
10 {
11
12 struct Response
13 {
14     bool done;
15     pthread_mutex_t mutex;
16     pthread_cond_t cond;
17     RESULT result;
18
19     static bool callback(void* data, const RESULT& res)
20     {
21         Response& resp = *static_cast<Response*>(data);
22         pthread_mutex_lock(&resp.mutex);
23         resp.result = res;
24         resp.done = true;
25         pthread_cond_signal(&resp.cond);
26         pthread_mutex_unlock(&resp.mutex);
27         return true;
28     }
29 } response;
30
31 STG_PAIR* toSTGPairs(const PAIRS& source)
32 {
33     STG_PAIR * pairs = new STG_PAIR[source.size() + 1];
34     for (size_t pos = 0; pos < source.size(); ++pos) {
35         bzero(pairs[pos].key, sizeof(STG_PAIR::key));
36         bzero(pairs[pos].value, sizeof(STG_PAIR::value));
37         strncpy(pairs[pos].key, source[pos].first.c_str(), sizeof(STG_PAIR::key));
38         strncpy(pairs[pos].value, source[pos].second.c_str(), sizeof(STG_PAIR::value));
39         ++pos;
40     }
41     bzero(pairs[source.size()].key, sizeof(STG_PAIR::key));
42     bzero(pairs[source.size()].value, sizeof(STG_PAIR::value));
43
44     return pairs;
45 }
46
47 PAIRS fromSTGPairs(const STG_PAIR* pairs)
48 {
49     const STG_PAIR* pair = pairs;
50     PAIRS res;
51
52     while (!emptyPair(pair)) {
53         res.push_back(std::pair<std::string, std::string>(pair->key, pair->value));
54         ++pair;
55     }
56
57     return res;
58 }
59
60 STG_RESULT toResult(const RESULT& source)
61 {
62     STG_RESULT result;
63     result.modify = toSTGPairs(source.modify);
64     result.reply = toSTGPairs(source.reply);
65     return result;
66 }
67
68 STG_RESULT emptyResult()
69 {
70     STG_RESULT result = {NULL, NULL};
71     return result;
72 }
73
74 std::string toString(const char* value)
75 {
76     if (value == NULL)
77         return "";
78     else
79         return value;
80 }
81
82 STG_RESULT stgRequest(STG_CLIENT::TYPE type, const char* userName, const char* password, const STG_PAIR* pairs)
83 {
84     STG_CLIENT* client = STG_CLIENT::get();
85     if (client == NULL) {
86         // TODO: log "Not configured"
87         return emptyResult();
88     }
89     try {
90         client->request(type, toString(userName), toString(password), fromSTGPairs(pairs));
91         pthread_mutex_lock(&response.mutex);
92         while (!response.done)
93             pthread_cond_wait(&response.cond, &response.mutex);
94         pthread_mutex_unlock(&response.mutex);
95         return toResult(response.result);
96     } catch (const STG_CLIENT::Error& ex) {
97         // TODO: log error
98         return emptyResult();
99     }
100 }
101
102 }
103
104 int stgInstantiateImpl(const char* address)
105 {
106     pthread_mutex_init(&response.mutex, NULL);
107     pthread_cond_init(&response.cond, NULL);
108     response.done = false;
109
110     if (STG_CLIENT::configure(toString(address), &Response::callback, &response))
111         return 1;
112
113     return 0;
114 }
115
116 STG_RESULT stgAuthorizeImpl(const char* userName, const char* password, const STG_PAIR* pairs)
117 {
118     return stgRequest(STG_CLIENT::AUTHORIZE, userName, password, pairs);
119 }
120
121 STG_RESULT stgAuthenticateImpl(const char* userName, const char* password, const STG_PAIR* pairs)
122 {
123     return stgRequest(STG_CLIENT::AUTHENTICATE, userName, password, pairs);
124 }
125
126 STG_RESULT stgPostAuthImpl(const char* userName, const char* password, const STG_PAIR* pairs)
127 {
128     return stgRequest(STG_CLIENT::POST_AUTH, userName, password, pairs);
129 }
130
131 STG_RESULT stgPreAcctImpl(const char* userName, const char* password, const STG_PAIR* pairs)
132 {
133     return stgRequest(STG_CLIENT::PRE_ACCT, userName, password, pairs);
134 }
135
136 STG_RESULT stgAccountingImpl(const char* userName, const char* password, const STG_PAIR* pairs)
137 {
138     return stgRequest(STG_CLIENT::ACCOUNT, userName, password, pairs);
139 }