1 /* authd/providers/opm.c - small open proxy monitor
2 * Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice is present in all copies.
8 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18 * POSSIBILITY OF SUCH DAMAGE.
29 #define SELF_PID (opm_provider.id)
31 #define OPM_READSIZE 128
33 typedef enum protocol_t
42 /* Lookup data associated with auth client */
45 rb_dlink_list scans
; /* List of scans */
50 typedef void (*opm_callback_t
)(struct opm_scan
*);
58 bool ssl
; /* Connect to proxy with SSL */
59 bool ipv6
; /* Proxy supports IPv6 */
61 opm_callback_t callback
;
66 /* A listener for proxy replies */
71 struct rb_sockaddr_storage addr
;
75 /* An individual proxy scan */
78 struct auth_client
*auth
;
79 rb_fde_t
*F
; /* fd for scan */
81 struct opm_proxy
*proxy
; /* Associated proxy */
82 struct opm_listener
*listener
; /* Associated listener */
87 /* Proxies that we scan for */
88 static rb_dlink_list proxy_scanners
;
90 static ACCB accept_opm
;
91 static PF read_opm_reply
;
93 static CNCB opm_connected
;
95 static void opm_cancel(struct auth_client
*auth
);
96 static bool create_listener(const char *ip
, uint16_t port
);
98 static int opm_timeout
= OPM_TIMEOUT_DEFAULT
;
99 static bool opm_enable
= false;
109 static struct opm_listener listeners
[LISTEN_LAST
];
111 static inline protocol_t
112 get_protocol_from_string(const char *str
)
114 if(strcasecmp(str
, "socks4") == 0)
116 else if(strcasecmp(str
, "socks5") == 0)
118 else if(strcasecmp(str
, "httpconnect") == 0)
119 return PROTO_HTTP_CONNECT
;
120 else if(strcasecmp(str
, "httpsconnect") == 0)
121 return PROTO_HTTPS_CONNECT
;
126 static inline struct opm_proxy
*
127 find_proxy_scanner(protocol_t proto
, uint16_t port
)
131 RB_DLINK_FOREACH(ptr
, proxy_scanners
.head
)
133 struct opm_proxy
*proxy
= ptr
->data
;
135 if(proxy
->proto
== proto
&& proxy
->port
== port
)
142 /* This is called when an open proxy connects to us */
144 read_opm_reply(rb_fde_t
*F
, void *data
)
147 struct auth_client
*auth
= data
;
148 struct opm_lookup
*lookup
;
149 char readbuf
[OPM_READSIZE
];
152 lrb_assert(auth
!= NULL
);
153 lookup
= get_provider_data(auth
, SELF_PID
);
154 lrb_assert(lookup
!= NULL
);
156 if((len
= rb_read(F
, readbuf
, sizeof(readbuf
))) < 0 && rb_ignore_errno(errno
))
158 rb_setselect(F
, RB_SELECT_READ
, read_opm_reply
, auth
);
168 RB_DLINK_FOREACH(ptr
, proxy_scanners
.head
)
170 struct opm_proxy
*proxy
= ptr
->data
;
172 if(strncmp(proxy
->note
, readbuf
, strlen(proxy
->note
)) == 0)
174 rb_dlink_node
*ptr
, *nptr
;
176 /* Cancel outstanding lookups */
177 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, lookup
->scans
.head
)
179 struct opm_scan
*scan
= ptr
->data
;
185 /* No longer needed, client is going away */
188 reject_client(auth
, SELF_PID
, readbuf
, "Open proxy detected");
197 accept_opm(rb_fde_t
*F
, int status
, struct sockaddr
*addr
, rb_socklen_t len
, void *data
)
199 struct opm_listener
*listener
= data
;
200 struct rb_sockaddr_storage localaddr
;
201 unsigned int llen
= sizeof(struct rb_sockaddr_storage
);
204 if(status
!= 0 || listener
== NULL
)
210 if(getsockname(rb_get_fd(F
), (struct sockaddr
*)&localaddr
, &llen
))
212 /* This can happen if the client goes away after accept */
217 /* Correlate connection with client(s) */
218 RB_DLINK_FOREACH(ptr
, auth_clients
.head
)
220 struct auth_client
*auth
= ptr
->data
;
222 if(GET_SS_FAMILY(&auth
->c_addr
) != GET_SS_FAMILY(&localaddr
))
225 /* Compare the addresses */
226 switch(GET_SS_FAMILY(&localaddr
))
230 struct sockaddr_in
*s
= (struct sockaddr_in
*)&localaddr
, *c
= (struct sockaddr_in
*)&auth
->c_addr
;
232 if(s
->sin_addr
.s_addr
== c
->sin_addr
.s_addr
)
234 /* Match... check if it's real */
235 rb_setselect(F
, RB_SELECT_READ
, read_opm_reply
, auth
);
243 struct sockaddr_in6
*s
= (struct sockaddr_in6
*)&localaddr
, *c
= (struct sockaddr_in6
*)&auth
->c_addr
;
245 if(IN6_ARE_ADDR_EQUAL(&s
->sin6_addr
, &c
->sin6_addr
))
247 rb_setselect(F
, RB_SELECT_READ
, read_opm_reply
, auth
);
254 warn_opers(L_CRIT
, "OPM: unknown address type in listen function");
255 exit(EX_PROVIDER_ERROR
);
259 /* We don't care about the socket if we get here */
266 opm_connected(rb_fde_t
*F
, int error
, void *data
)
268 struct opm_scan
*scan
= data
;
269 struct opm_proxy
*proxy
= scan
->proxy
;
270 struct auth_client
*auth
= scan
->auth
;
271 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
273 if(error
|| !opm_enable
)
275 //notice_client(scan->auth->cid, "*** Scan not connected: %s", proxy->note);
279 switch(GET_SS_FAMILY(&auth
->c_addr
))
282 if(listeners
[LISTEN_IPV4
].F
== NULL
)
283 /* They cannot respond to us */
293 if(listeners
[LISTEN_IPV6
].F
== NULL
)
294 /* They cannot respond to us */
303 proxy
->callback(scan
);
307 rb_dlinkDelete(&scan
->node
, &lookup
->scans
);
312 socks4_connected(struct opm_scan
*scan
)
314 struct auth_client
*auth
= scan
->auth
;
315 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
316 uint8_t sendbuf
[9]; /* Size we're building */
317 uint8_t *c
= sendbuf
;
319 memcpy(c
, "\x04\x01", 2); c
+= 2; /* Socks version 4, connect command */
320 memcpy(c
, &(((struct sockaddr_in
*)&scan
->listener
->addr
)->sin_port
), 2); c
+= 2; /* Port */
321 memcpy(c
, &(((struct sockaddr_in
*)&scan
->listener
->addr
)->sin_addr
.s_addr
), 4); c
+= 4; /* Address */
322 *c
= '\x00'; /* No userid */
325 if(rb_write(scan
->F
, sendbuf
, sizeof(sendbuf
)) < 0)
329 if(rb_write(scan
->F
, scan
->proxy
->note
, strlen(scan
->proxy
->note
) + 1) < 0)
334 socks5_connected(struct opm_scan
*scan
)
336 struct auth_client
*auth
= scan
->auth
;
337 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
338 uint8_t sendbuf
[25]; /* Size we're building */
339 uint8_t *c
= sendbuf
;
342 lookup
= get_provider_data(auth
, SELF_PID
);
344 /* Build the version header and socks request
345 * version header (3 bytes): version, number of auth methods, auth type (0 for none)
346 * connect req (3 bytes): version, command (1 = connect), reserved (0)
348 memcpy(c
, "\x05\x01\x00\x05\x01\x00", 6); c
+= 6;
350 switch(GET_SS_FAMILY(&auth
->c_addr
))
353 *(c
++) = '\x01'; /* Address type (1 = IPv4) */
354 memcpy(c
, &(((struct sockaddr_in
*)&scan
->listener
->addr
)->sin_addr
.s_addr
), 4); c
+= 4; /* Address */
355 memcpy(c
, &(((struct sockaddr_in
*)&scan
->listener
->addr
)->sin_port
), 2); c
+= 2; /* Port */
359 *(c
++) = '\x04'; /* Address type (4 = IPv6) */
360 memcpy(c
, ((struct sockaddr_in6
*)&scan
->listener
->addr
)->sin6_addr
.s6_addr
, 16); c
+= 16; /* Address */
361 memcpy(c
, &(((struct sockaddr_in6
*)&scan
->listener
->addr
)->sin6_port
), 2); c
+= 2; /* Port */
369 if(rb_write(scan
->F
, sendbuf
, (size_t)(sendbuf
- c
)) <= 0)
372 /* Now the note in a separate write */
373 if(rb_write(scan
->F
, scan
->proxy
->note
, strlen(scan
->proxy
->note
) + 1) <= 0)
378 http_connect_connected(struct opm_scan
*scan
)
380 struct auth_client
*auth
= scan
->auth
;
381 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
382 char sendbuf
[128]; /* A bit bigger than we need but better safe than sorry */
385 /* Simple enough to build */
386 snprintf(sendbuf
, sizeof(sendbuf
), "CONNECT %s:%hu HTTP/1.0\r\n\r\n", scan
->listener
->ip
, scan
->listener
->port
);
389 if(rb_write(scan
->F
, sendbuf
, strlen(sendbuf
)) <= 0)
392 /* Now the note in a separate write */
393 if(rb_write(scan
->F
, scan
->proxy
->note
, strlen(scan
->proxy
->note
) + 1) <= 0)
396 /* MiroTik needs this, and as a separate write */
397 if(rb_write(scan
->F
, "\r\n", 2) <= 0)
401 /* Establish connections */
403 establish_connection(struct auth_client
*auth
, struct opm_proxy
*proxy
)
405 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
406 struct opm_scan
*scan
= rb_malloc(sizeof(struct opm_scan
));
407 struct opm_listener
*listener
;
408 struct rb_sockaddr_storage c_a
, l_a
;
411 lrb_assert(lookup
!= NULL
);
414 if(GET_SS_FAMILY(&auth
->c_addr
) == AF_INET6
)
416 if(proxy
->proto
== PROTO_SOCKS4
)
418 /* SOCKS4 doesn't support IPv6 */
422 listener
= &listeners
[LISTEN_IPV6
];
426 listener
= &listeners
[LISTEN_IPV4
];
428 if(listener
->F
== NULL
)
430 /* We can't respond */
435 c_a
= auth
->c_addr
; /* Client */
436 l_a
= listener
->addr
; /* Listener (connect using its IP) */
440 scan
->listener
= listener
;
441 if((scan
->F
= rb_socket(GET_SS_FAMILY(&auth
->c_addr
), SOCK_STREAM
, 0, proxy
->note
)) == NULL
)
443 warn_opers(L_WARN
, "OPM: could not create OPM socket (proto %s): %s", proxy
->note
, strerror(errno
));
448 /* Disable Nagle's algorithim - buffering could affect scans */
449 (void)setsockopt(rb_get_fd(scan
->F
), IPPROTO_TCP
, TCP_NODELAY
, (char *)&opt
, sizeof(opt
));
451 SET_SS_PORT(&l_a
, 0);
452 SET_SS_PORT(&c_a
, htons(proxy
->port
));
454 rb_dlinkAdd(scan
, &scan
->node
, &lookup
->scans
);
457 rb_connect_tcp(scan
->F
,
458 (struct sockaddr
*)&c_a
,
459 (struct sockaddr
*)&l_a
,
460 opm_connected
, scan
, opm_timeout
);
462 rb_connect_tcp_ssl(scan
->F
,
463 (struct sockaddr
*)&c_a
,
464 (struct sockaddr
*)&l_a
,
465 opm_connected
, scan
, opm_timeout
);
469 create_listener(const char *ip
, uint16_t port
)
471 struct opm_listener
*listener
;
472 struct rb_sockaddr_storage addr
;
473 rb_dlink_node
*ptr
, *nptr
;
477 if(!rb_inet_pton_sock(ip
, (struct sockaddr
*)&addr
))
479 warn_opers(L_CRIT
, "OPM: got a bad listener: %s:%hu", ip
, port
);
480 exit(EX_PROVIDER_ERROR
);
483 SET_SS_PORT(&addr
, htons(port
));
486 if(GET_SS_FAMILY(&addr
) == AF_INET6
)
488 struct sockaddr_in6
*a1
, *a2
;
490 listener
= &listeners
[LISTEN_IPV6
];
492 a1
= (struct sockaddr_in6
*)&addr
;
493 a2
= (struct sockaddr_in6
*)&listener
->addr
;
495 if(IN6_ARE_ADDR_EQUAL(&a1
->sin6_addr
, &a2
->sin6_addr
) &&
496 GET_SS_PORT(&addr
) == GET_SS_PORT(&listener
->addr
) &&
499 /* Listener already exists */
506 struct sockaddr_in
*a1
, *a2
;
508 listener
= &listeners
[LISTEN_IPV4
];
510 a1
= (struct sockaddr_in
*)&addr
;
511 a2
= (struct sockaddr_in
*)&listener
->addr
;
513 if(a1
->sin_addr
.s_addr
== a2
->sin_addr
.s_addr
&&
514 GET_SS_PORT(&addr
) == GET_SS_PORT(&listener
->addr
) &&
517 /* Listener already exists */
522 if((F
= rb_socket(GET_SS_FAMILY(&addr
), SOCK_STREAM
, 0, "OPM listener socket")) == NULL
)
524 /* This shouldn't fail, or we have big problems... */
525 warn_opers(L_CRIT
, "OPM: cannot create socket: %s", strerror(errno
));
526 exit(EX_PROVIDER_ERROR
);
529 if(setsockopt(rb_get_fd(F
), SOL_SOCKET
, SO_REUSEADDR
, (char *)&opt
, sizeof(opt
)))
531 /* This shouldn't fail either... */
532 warn_opers(L_CRIT
, "OPM: cannot set options on socket: %s", strerror(errno
));
533 exit(EX_PROVIDER_ERROR
);
536 if(bind(rb_get_fd(F
), (struct sockaddr
*)&addr
, GET_SS_LEN(&addr
)))
538 /* Shit happens, let's not cripple authd over /this/ since it could be user error */
539 warn_opers(L_WARN
, "OPM: cannot bind on socket: %s", strerror(errno
));
544 if(rb_listen(F
, SOMAXCONN
, false)) /* deferred accept could interfere with detection */
546 /* Again, could be user error */
547 warn_opers(L_WARN
, "OPM: cannot listen on socket: %s", strerror(errno
));
552 /* From this point forward we assume we have a listener */
554 if(listener
->F
!= NULL
)
555 /* Close old listener */
556 rb_close(listener
->F
);
560 /* Cancel clients that may be on old listener
561 * XXX - should rescan clients that need it
563 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, auth_clients
.head
)
565 struct auth_client
*auth
= ptr
->data
;
570 rb_strlcpy(listener
->ip
, ip
, sizeof(listener
->ip
));
571 listener
->port
= port
;
572 listener
->addr
= addr
;
574 opm_enable
= true; /* Implicitly set this to true for now if we have a listener */
575 rb_accept_tcp(listener
->F
, NULL
, accept_opm
, listener
);
580 opm_scan(struct auth_client
*auth
)
583 struct opm_lookup
*lookup
;
585 lrb_assert(auth
!= NULL
);
587 lookup
= get_provider_data(auth
, SELF_PID
);
588 set_provider_timeout_relative(auth
, SELF_PID
, opm_timeout
);
590 lookup
->in_progress
= true;
592 RB_DLINK_FOREACH(ptr
, proxy_scanners
.head
)
594 struct opm_proxy
*proxy
= ptr
->data
;
595 //notice_client(auth->cid, "*** Scanning for proxy type %s", proxy->note);
596 establish_connection(auth
, proxy
);
599 notice_client(auth
->cid
, "*** Scanning for open proxies...");
602 /* This is called every time a provider is completed as long as we are marked not done */
604 opm_initiate(struct auth_client
*auth
, uint32_t provider
)
606 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
607 uint32_t rdns_pid
, ident_pid
;
609 lrb_assert(provider
!= SELF_PID
);
610 lrb_assert(!is_provider_done(auth
, SELF_PID
));
611 lrb_assert(rb_dlink_list_length(&proxy_scanners
) > 0);
613 if(lookup
== NULL
|| lookup
->in_progress
)
616 else if((!get_provider_id("rdns", &rdns_pid
) || is_provider_done(auth
, rdns_pid
)) &&
617 (!get_provider_id("ident", &ident_pid
) || is_provider_done(auth
, ident_pid
)))
618 /* Don't start until ident and rdns are finished (or not loaded) */
625 opm_start(struct auth_client
*auth
)
627 uint32_t rdns_pid
, ident_pid
;
629 lrb_assert(get_provider_data(auth
, SELF_PID
) == NULL
);
631 if(!opm_enable
|| rb_dlink_list_length(&proxy_scanners
) == 0)
632 /* Nothing to do... */
635 set_provider_data(auth
, SELF_PID
, rb_malloc(sizeof(struct opm_lookup
)));
637 if((!get_provider_id("rdns", &rdns_pid
) || is_provider_done(auth
, rdns_pid
)) &&
638 (!get_provider_id("ident", &ident_pid
) || is_provider_done(auth
, ident_pid
)))
640 /* Don't start until ident and rdns are finished (or not loaded) */
644 set_provider_running(auth
, SELF_PID
);
649 opm_cancel(struct auth_client
*auth
)
651 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
655 rb_dlink_node
*ptr
, *nptr
;
657 notice_client(auth
->cid
, "*** Did not detect open proxies");
659 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, lookup
->scans
.head
)
661 struct opm_scan
*scan
= ptr
->data
;
669 set_provider_data(auth
, SELF_PID
, NULL
);
670 set_provider_timeout_absolute(auth
, SELF_PID
, 0);
671 provider_done(auth
, SELF_PID
);
678 rb_dlink_node
*ptr
, *nptr
;
680 /* Nuke all opm lookups */
681 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, auth_clients
.head
)
683 struct auth_client
*auth
= ptr
->data
;
690 add_conf_opm_timeout(const char *key __unused
, int parc __unused
, const char **parv
)
692 int timeout
= atoi(parv
[0]);
696 warn_opers(L_CRIT
, "opm: opm timeout < 0 (value: %d)", timeout
);
700 opm_timeout
= timeout
;
704 set_opm_enabled(const char *key __unused
, int parc __unused
, const char **parv
)
706 bool enable
= (*parv
[0] == '1');
710 if(listeners
[LISTEN_IPV4
].F
!= NULL
|| listeners
[LISTEN_IPV6
].F
!= NULL
)
712 rb_dlink_node
*ptr
, *nptr
;
714 /* Close the listening socket */
715 if(listeners
[LISTEN_IPV4
].F
!= NULL
)
716 rb_close(listeners
[LISTEN_IPV4
].F
);
718 if(listeners
[LISTEN_IPV6
].F
!= NULL
)
719 rb_close(listeners
[LISTEN_IPV6
].F
);
721 listeners
[LISTEN_IPV4
].F
= listeners
[LISTEN_IPV6
].F
= NULL
;
723 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, auth_clients
.head
)
725 struct auth_client
*auth
= ptr
->data
;
732 if(listeners
[LISTEN_IPV4
].ip
[0] != '\0' && listeners
[LISTEN_IPV4
].port
!= 0)
734 if(listeners
[LISTEN_IPV4
].F
== NULL
)
735 /* Pre-configured IP/port, just re-establish */
736 create_listener(listeners
[LISTEN_IPV4
].ip
, listeners
[LISTEN_IPV4
].port
);
739 if(listeners
[LISTEN_IPV6
].ip
[0] != '\0' && listeners
[LISTEN_IPV6
].port
!= 0)
741 if(listeners
[LISTEN_IPV6
].F
== NULL
)
742 /* Pre-configured IP/port, just re-establish */
743 create_listener(listeners
[LISTEN_IPV6
].ip
, listeners
[LISTEN_IPV6
].port
);
751 set_opm_listener(const char *key __unused
, int parc __unused
, const char **parv
)
753 const char *ip
= parv
[0];
754 int iport
= atoi(parv
[1]);
756 if(iport
> 65535 || iport
<= 0)
758 warn_opers(L_CRIT
, "OPM: got a bad listener: %s:%s", parv
[0], parv
[1]);
759 exit(EX_PROVIDER_ERROR
);
762 create_listener(ip
, (uint16_t)iport
);
766 create_opm_scanner(const char *key __unused
, int parc __unused
, const char **parv
)
768 int iport
= atoi(parv
[1]);
769 struct opm_proxy
*proxy
= rb_malloc(sizeof(struct opm_proxy
));
771 if(iport
<= 0 || iport
> 65535)
773 warn_opers(L_CRIT
, "OPM: got a bad scanner: %s (port %s)", parv
[0], parv
[1]);
774 exit(EX_PROVIDER_ERROR
);
777 proxy
->port
= (uint16_t)iport
;
779 switch((proxy
->proto
= get_protocol_from_string(parv
[0])))
782 snprintf(proxy
->note
, sizeof(proxy
->note
), "socks4:%hu", proxy
->port
);
784 proxy
->callback
= socks4_connected
;
787 snprintf(proxy
->note
, sizeof(proxy
->note
), "socks5:%hu", proxy
->port
);
789 proxy
->callback
= socks5_connected
;
791 case PROTO_HTTP_CONNECT
:
792 snprintf(proxy
->note
, sizeof(proxy
->note
), "httpconnect:%hu", proxy
->port
);
794 proxy
->callback
= http_connect_connected
;
796 case PROTO_HTTPS_CONNECT
:
797 snprintf(proxy
->note
, sizeof(proxy
->note
), "httpsconnect:%hu", proxy
->port
);
798 proxy
->callback
= http_connect_connected
;
802 warn_opers(L_CRIT
, "OPM: got an unknown proxy type: %s (port %hu)", parv
[0], proxy
->port
);
803 exit(EX_PROVIDER_ERROR
);
806 if(find_proxy_scanner(proxy
->proto
, proxy
->port
) != NULL
)
808 warn_opers(L_CRIT
, "OPM: got a duplicate scanner: %s (port %hu)", parv
[0], proxy
->port
);
809 exit(EX_PROVIDER_ERROR
);
812 rb_dlinkAdd(proxy
, &proxy
->node
, &proxy_scanners
);
816 delete_opm_scanner(const char *key __unused
, int parc __unused
, const char **parv
)
818 struct opm_proxy
*proxy
;
819 protocol_t proto
= get_protocol_from_string(parv
[0]);
820 int iport
= atoi(parv
[1]);
821 rb_dlink_node
*ptr
, *nptr
;
823 if(iport
<= 0 || iport
> 65535)
825 warn_opers(L_CRIT
, "OPM: got a bad scanner to delete: %s (port %s)", parv
[0], parv
[1]);
826 exit(EX_PROVIDER_ERROR
);
829 if(proto
== PROTO_NONE
)
831 warn_opers(L_CRIT
, "OPM: got an unknown proxy type to delete: %s (port %d)", parv
[0], iport
);
832 exit(EX_PROVIDER_ERROR
);
835 if((proxy
= find_proxy_scanner(proto
, (uint16_t)iport
)) == NULL
)
837 warn_opers(L_CRIT
, "OPM: cannot find proxy to delete: %s (port %d)", parv
[0], iport
);
838 exit(EX_PROVIDER_ERROR
);
841 /* Abort remaining clients on this scanner */
842 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, auth_clients
.head
)
844 struct auth_client
*auth
= ptr
->data
;
845 struct opm_lookup
*lookup
= get_provider_data(auth
, SELF_PID
);
851 RB_DLINK_FOREACH(optr
, lookup
->scans
.head
)
853 struct opm_scan
*scan
= optr
->data
;
855 if(scan
->proxy
->port
== proxy
->port
&& scan
->proxy
->proto
== proxy
->proto
)
858 rb_dlinkDelete(&scan
->node
, &lookup
->scans
);
861 if(rb_dlink_list_length(&lookup
->scans
) == 0)
869 rb_dlinkDelete(&proxy
->node
, &proxy_scanners
);
872 if(rb_dlink_list_length(&proxy_scanners
) == 0)
877 delete_opm_scanner_all(const char *key __unused
, int parc __unused
, const char **parv __unused
)
879 rb_dlink_node
*ptr
, *nptr
;
881 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, proxy_scanners
.head
)
884 rb_dlinkDelete(ptr
, &proxy_scanners
);
887 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, auth_clients
.head
)
889 struct auth_client
*auth
= ptr
->data
;
897 delete_opm_listener_all(const char *key __unused
, int parc __unused
, const char **parv __unused
)
899 if(listeners
[LISTEN_IPV4
].F
!= NULL
)
900 rb_close(listeners
[LISTEN_IPV4
].F
);
903 if(listeners
[LISTEN_IPV6
].F
!= NULL
)
904 rb_close(listeners
[LISTEN_IPV6
].F
);
907 memset(&listeners
, 0, sizeof(listeners
));
911 struct auth_opts_handler opm_options
[] =
913 { "opm_timeout", 1, add_conf_opm_timeout
},
914 { "opm_enabled", 1, set_opm_enabled
},
915 { "opm_listener", 2, set_opm_listener
},
916 { "opm_listener_del_all", 0, delete_opm_listener_all
},
917 { "opm_scanner", 2, create_opm_scanner
},
918 { "opm_scanner_del", 2, delete_opm_scanner
},
919 { "opm_scanner_del_all", 0, delete_opm_scanner_all
},
923 struct auth_provider opm_provider
=
927 .destroy
= opm_destroy
,
929 .cancel
= opm_cancel
,
930 .timeout
= opm_cancel
,
931 .completed
= opm_initiate
,
932 .opt_handlers
= opm_options
,