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
|
#ifndef __CTRLPROXY_LISTENER_H__
#define __CTRLPROXY_LISTENER_H__
#include <netdb.h>
#include "ctrlproxy.h"
#ifdef HAVE_GSSAPI
#ifdef HAVE_GSSAPI_H
#include <gssapi.h>
#endif
#ifdef HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
#endif
#endif
#ifndef G_MODULE_EXPORT
#define G_MODULE_EXPORT
#endif
struct irc_listener;
typedef void (*listener_log_fn) (enum log_level, const struct irc_listener *, const char *);
struct pending_client;
struct irc_listener_ops {
void (*new_client) (struct pending_client *pc);
gboolean (*handle_client_line) (struct pending_client *pc, const struct irc_line *l);
gboolean (*socks_auth_simple) (struct pending_client *pc, const char *username, const char *password,
gboolean (*) (struct pending_client *, gboolean pass_ok));
#ifdef HAVE_GSSAPI
gboolean (*socks_gssapi) (struct pending_client *pc, gss_name_t user_name);
#endif
gboolean (*socks_connect_ipv4) (struct pending_client *pc);
gboolean (*socks_connect_ipv6) (struct pending_client *pc);
gboolean (*socks_connect_fqdn) (struct pending_client *pc, const char *hostname, uint16_t port);
};
/**
* A listener.
*/
struct irc_listener {
int active:1;
GIConv iconv;
gboolean ssl;
gpointer ssl_credentials;
GList *incoming;
GList *pending;
struct listener_config *config;
struct irc_network *network;
struct global *global;
listener_log_fn log_fn;
struct irc_listener_ops *ops;
};
struct socks_method;
enum socks_state {
SOCKS_UNUSED = -1,
SOCKS_UNKNOWN = 0,
SOCKS_STATE_NEW = 1,
SOCKS_STATE_AUTH,
SOCKS_STATE_NORMAL
};
/**
* Client connection that has not been authenticated yet.
*/
struct pending_client {
/** Connection to the client. */
GIOChannel *connection;
/** Username the client has sent. */
char *user;
/** Password the client has sent. */
char *password;
gint watch_id;
struct sockaddr *clientname;
socklen_t clientname_len;
/** The listener used for this pending client. */
struct irc_listener *listener;
struct listener_iochannel *iochannel;
/** Socks state. */
struct {
struct socks_method *method;
enum socks_state state;
void *method_data;
} socks;
/** Private data. */
void *private_data;
#ifdef HAVE_GSSAPI
gss_ctx_id_t gss_ctx;
gss_name_t authn_name;
gss_name_t gss_service;
gss_cred_id_t service_cred;
#endif
};
G_MODULE_EXPORT gboolean listener_start_tcp(struct irc_listener *, const char *address, const char *service);
G_MODULE_EXPORT gboolean listener_stop(struct irc_listener *);
G_MODULE_EXPORT void fini_listeners(struct global *);
G_MODULE_EXPORT void free_listener(struct irc_listener *l);
G_MODULE_EXPORT gboolean init_listeners(struct global *global);
G_MODULE_EXPORT void listener_add_iochannel(struct irc_listener *l, GIOChannel *ioc, const char *host, const char *port);
G_MODULE_EXPORT void listener_log(enum log_level l, const struct irc_listener *listener,
const char *fmt, ...);
G_MODULE_EXPORT gboolean listener_socks_error(struct pending_client *pc, guint8 err);
G_MODULE_EXPORT gboolean listener_socks_reply(struct pending_client *pc, guint8 err, guint8 atyp, guint8 data_len, gchar *data, guint16 port);
G_MODULE_EXPORT struct pending_client *listener_new_pending_client(struct irc_listener *listener, GIOChannel *c);
#ifdef HAVE_GSSAPI
void log_gssapi(struct irc_listener *l, enum log_level level, const char *message, guint32 major_status, guint32 minor_status);
#endif
#endif
|