-
Notifications
You must be signed in to change notification settings - Fork 5
/
auth_plugin.c
151 lines (128 loc) · 4.2 KB
/
auth_plugin.c
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>
#include <mosquitto_plugin.h>
#include <libpq-fe.h>
#include <md5.h>
typedef char * string;
int mosquitto_auth_plugin_version(void)
{
return MOSQ_AUTH_PLUGIN_VERSION;
}
int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count)
{
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count)
{
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_security_init(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count, bool reload)
{
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count, bool reload)
{
return MOSQ_ERR_SUCCESS;
}
//int mosquitto_auth_acl_check(void *user_data, const char *clientid, const char *username, const char *topic, int access)
int mosquitto_auth_acl_check(void *user_data, const char *username, const char *topic, int access)
{
int ulen = strlen(username);
if(!strcmp(username, "SERVER")) {
// server can read /#/status
if (access == MOSQ_ACL_READ){
string suffix="/status";
// find / in topic
char *pos = strrchr(topic,'/');
// compare
if (!strcmp(suffix, pos)) {
return MOSQ_ERR_SUCCESS;
}
}
else {
// TODO restrict writing to /#/warning
return MOSQ_ERR_SUCCESS;
}
} else {
// NO Server --> client
if(access == MOSQ_ACL_READ){
// users can read topic /<username>/warning
string suffix="/warning";
// name of allowed topic
string t_allowed= malloc(ulen + strlen(suffix)+1) ; /* +1 DFTTZ! */
strcpy(t_allowed,username) ;
strcat(t_allowed,suffix) ;
// compare
if (!strcmp(t_allowed, topic)) {
return MOSQ_ERR_SUCCESS;
}
} else {
// users can write to topic /<username>/status
string suffix="/status";
// name of allowed topic
string t_allowed=malloc(ulen + strlen(suffix)+1) ; /* +1 DFTTZ! */
strcpy(t_allowed,username) ;
strcat(t_allowed,suffix) ;
// compare
if (!strcmp(t_allowed, topic)) {
return MOSQ_ERR_SUCCESS;
}
}
}
return MOSQ_ERR_AUTH;
}
int mosquitto_auth_unpwd_check(void *user_data, const char *username, const char *password)
{
// SERVER
if(!strcmp(username, "SERVER") && password && !strcmp(password, "abc")){
return MOSQ_ERR_SUCCESS;
}
// user
// lookup hashed pw in DB
PGconn *conn;
PGresult *res;
int ulen = strlen(username);
conn = PQconnectdb("dbname=abc host=localhost user=abc password=def");
if (PQstatus(conn) == CONNECTION_BAD) {
puts("Unable to connect to the database");
return MOSQ_ERR_AUTH;
}
// statement to get hash of users pw / token
string stmt = "SELECT * FROM public.\"user\" where username = '";
string stmt_suffix = "'";
// name of allowed topic
// TODO --> prevent SQL injection
string stmt_w_user=malloc(strlen(stmt) + ulen + strlen(stmt_suffix) + 1) ; /* +1 DFTTZ! */
strcpy(stmt_w_user,stmt) ;
strcat(stmt_w_user,username) ;
strcat(stmt_w_user,stmt_suffix) ;
res = PQexec(conn, stmt_w_user);
// got result
if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1) {
// DO MD5()
unsigned char hash_ret[16];
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, password, strlen(password));
MD5_Final(hash_ret, &ctx);
char tmp[3]={'\0'};
char hash[33]={'\0'};
int i=0;
for (; i<16; i++) {
sprintf(tmp, "%2.2x", hash_ret[i]);
strcat(hash, tmp);
}
if(!strcmp(hash, PQgetvalue(res, 0, 2))){
return MOSQ_ERR_SUCCESS;
}
}
PQclear(res);
PQfinish(conn);
return MOSQ_ERR_AUTH;
}
int mosquitto_auth_psk_key_get(void *user_data, const char *hint, const char *identity, char *key, int max_key_len)
{
return MOSQ_ERR_AUTH;
}