summary refs log blame commit diff stats
path: root/src/common/ssl.h
blob: e722f831b1260a7418ef2035a1676942c7b25fbd (plain) (tree)


















                                                                            

                     

















                            
                    


                    
                                                  









                                                                            
                                                      



























                                                                                                                   

      
/* HexChat
 * Copyright (C) 1998-2010 Peter Zelezny.
 * Copyright (C) 2009-2013 Berke Viktor.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifndef HEXCHAT_SSL_H
#define HEXCHAT_SSL_H

struct cert_info {
    char subject[256];
    char *subject_word[12];
    char issuer[256];
    char *issuer_word[12];
    char algorithm[32];
    int algorithm_bits;
    char sign_algorithm[32];
    int sign_algorithm_bits;
    char notbefore[32];
    char notafter[32];

    int rsa_tmp_bits;
};

struct chiper_info {
    char version[16];
    char chiper[48];
    int chiper_bits;
};

SSL_CTX *_SSL_context_init (void (*info_cb_func));
#define _SSL_context_free(a)	SSL_CTX_free(a);

SSL *_SSL_socket (SSL_CTX *ctx, int sd);
char *_SSL_set_verify (SSL_CTX *ctx, void *(verify_callback), char *cacert);
/*
    int SSL_connect(SSL *);
    int SSL_accept(SSL *);
    int SSL_get_fd(SSL *);
*/
void _SSL_close (SSL * ssl);
int _SSL_check_hostname(X509 *cert, const char *host);
int _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl);
struct chiper_info *_SSL_get_cipher_info (SSL * ssl);

/*char *_SSL_add_keypair (SSL_CTX *ctx, char *privkey, char *cert);*/
/*void _SSL_add_random_keypair(SSL_CTX *ctx, int bits);*/

int _SSL_send (SSL * ssl, char *buf, int len);
int _SSL_recv (SSL * ssl, char *buf, int len);

/* misc */
/*void broke_oneline (char *oneline, char *parray[]);*/

/*char *_SSL_do_cipher_base64(char *buf, int buf_len, char *key, int operation);*/		/* must be freed */

/*void *_SSL_get_sess_obj(SSL *ssl, int type);*/		/* NOT must be freed */
#define	_SSL_get_sess_pkey(a)	_SSL_get_sess_obj(a, 0)
#define	_SSL_get_sess_prkey(a)	_SSL_get_sess_obj(a, 1)
#define	_SSL_get_sess_x509(a)	_SSL_get_sess_obj(a, 2)
/*char *_SSL_get_obj_base64(void *s, int type);*/		/* must be freed */
#define	_SSL_get_pkey_base64(a)		_SSL_get_obj_base64(a, 0)
#define	_SSL_get_prkey_base64(a)	_SSL_get_obj_base64(a, 1)
#define	_SSL_get_x509_base64(a)		_SSL_get_obj_base64(a, 2)
/*char *_SSL_get_ctx_obj_base64(SSL_CTX *ctx, int type);*/	/* must be freed */
#define	_SSL_get_ctx_pkey_base64(a)	_SSL_get_ctx_obj_base64(a, 0)
#define	_SSL_get_ctx_prkey_base64(a)	_SSL_get_ctx_obj_base64(a, 1)
#define	_SSL_get_ctx_x509_base64(a)	_SSL_get_ctx_obj_base64(a, 2)

/*int _SSL_verify_x509(X509 *x509);*/

#endif
n class="p">; pos++) { if ((access1&(1<<pos)) && (access2&(1<<pos))) break; if ((access1&(1<<pos)) && !(access2&(1<<pos))) return -1; if (!(access1&(1<<pos)) && (access2&(1<<pos))) return 1; } } return serv->p_cmp (user1->nick, user2->nick); } int nick_cmp_alpha (struct User *user1, struct User *user2, server *serv) { return serv->p_cmp (user1->nick, user2->nick); } /* insert name in appropriate place in linked list. Returns row number or: -1: duplicate */ static int userlist_insertname (session *sess, struct User *newuser) { if (!sess->usertree) { sess->usertree = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server); } return tree_insert (sess->usertree, newuser); } void userlist_set_away (struct session *sess, char *nick, unsigned int away) { struct User *user; user = userlist_find (sess, nick); if (user) { if (user->away != away) { user->away = away; /* rehash GUI */ fe_userlist_rehash (sess, user); if (away) fe_userlist_update (sess, user); } } } void userlist_set_account (struct session *sess, char *nick, char *account) { struct User *user; user = userlist_find (sess, nick); if (user) { g_free (user->account); if (strcmp (account, "*") == 0) user->account = NULL; else user->account = g_strdup (account); /* gui doesnt currently reflect login status, maybe later fe_userlist_rehash (sess, user); */ } } int userlist_add_hostname (struct session *sess, char *nick, char *hostname, char *realname, char *servername, char *account, unsigned int away) { struct User *user; gboolean do_rehash = FALSE; user = userlist_find (sess, nick); if (user) { if (!user->hostname && hostname) { if (prefs.hex_gui_ulist_show_hosts) do_rehash = TRUE; user->hostname = g_strdup (hostname); } if (!user->realname && realname && *realname) user->realname = g_strdup (realname); if (!user->servername && servername) user->servername = g_strdup (servername); if (!user->account && account && strcmp (account, "0") != 0) user->account = g_strdup (account); if (away != 0xff) { if (user->away != away) do_rehash = TRUE; user->away = away; } fe_userlist_update (sess, user); if (do_rehash) fe_userlist_rehash (sess, user); return 1; } return 0; } static int free_user (struct User *user, gpointer data) { g_free (user->realname); g_free (user->hostname); g_free (user->servername); g_free (user->account); g_free (user); return TRUE; } void userlist_free (session *sess) { tree_foreach (sess->usertree, (tree_traverse_func *)free_user, NULL); tree_destroy (sess->usertree); sess->usertree = NULL; sess->me = NULL; sess->ops = 0; sess->hops = 0; sess->voices = 0; sess->total = 0; } void userlist_clear (session *sess) { fe_userlist_clear (sess); userlist_free (sess); fe_userlist_numbers (sess); } static int find_cmp (const char *name, struct User *user, server *serv) { return serv->p_cmp ((char *)name, user->nick); } struct User * userlist_find (struct session *sess, const char *name) { int pos; if (sess->usertree) return tree_find (sess->usertree, name, (tree_cmp_func *)find_cmp, sess->server, &pos); return NULL; } struct User * userlist_find_global (struct server *serv, char *name) { struct User *user; session *sess; GSList *list = sess_list; while (list) { sess = (session *) list->data; if (sess->server == serv) { user = userlist_find (sess, name); if (user) return user; } list = list->next; } return NULL; } static void update_counts (session *sess, struct User *user, char prefix, int level, int offset) { switch (prefix) { case '@': user->op = level; sess->ops += offset; break; case '%': user->hop = level; sess->hops += offset; break; case '+': user->voice = level; sess->voices += offset; break; } } void userlist_update_mode (session *sess, char *name, char mode, char sign) { int access; int offset = 0; int level; int pos; char prefix; struct User *user; user = userlist_find (sess, name); if (!user) return; /* remove from binary trees, before we loose track of it */ tree_remove (sess->usertree, user, &pos); fe_userlist_remove (sess, user); /* which bit number is affected? */ access = mode_access (sess->server, mode, &prefix); if (sign == '+') { level = TRUE; if (!(user->access & (1 << access))) { offset = 1; user->access |= (1 << access); } } else { level = FALSE; if (user->access & (1 << access)) { offset = -1; user->access &= ~(1 << access); } } /* now what is this users highest prefix? e.g. @ for ops */ user->prefix[0] = get_nick_prefix (sess->server, user->access); /* update the various counts using the CHANGED prefix only */ update_counts (sess, user, prefix, level, offset); /* insert it back into its new place */ tree_insert (sess->usertree, user); fe_userlist_insert (sess, user, FALSE); fe_userlist_numbers (sess); } int userlist_change (struct session *sess, char *oldname, char *newname) { struct User *user = userlist_find (sess, oldname); int pos; if (user) { tree_remove (sess->usertree, user, &pos); fe_userlist_remove (sess, user); safe_strcpy (user->nick, newname, NICKLEN); tree_insert (sess->usertree, user); fe_userlist_insert (sess, user, FALSE); return 1; } return 0; } int userlist_remove (struct session *sess, char *name) { struct User *user; user = userlist_find (sess, name); if (!user) return FALSE; userlist_remove_user (sess, user); return TRUE; } void userlist_remove_user (struct session *sess, struct User *user) { int pos; if (user->voice) sess->voices--; if (user->op) sess->ops--; if (user->hop) sess->hops--; sess->total--; fe_userlist_numbers (sess); fe_userlist_remove (sess, user); if (user == sess->me) sess->me = NULL; tree_remove (sess->usertree, user, &pos); free_user (user, NULL); } void userlist_add (struct session *sess, char *name, char *hostname, char *account, char *realname, const message_tags_data *tags_data) { struct User *user; int row, prefix_chars; unsigned int acc; acc = nick_access (sess->server, name, &prefix_chars); notify_set_online (sess->server, name + prefix_chars, tags_data); user = g_new0 (struct User, 1); user->access = acc; /* assume first char is the highest level nick prefix */ if (prefix_chars) user->prefix[0] = name[0]; /* add it to our linked list */ if (hostname) user->hostname = g_strdup (hostname); safe_strcpy (user->nick, name + prefix_chars, NICKLEN); /* is it me? */ if (!sess->server->p_cmp (user->nick, sess->server->nick)) user->me = TRUE; /* extended join info */ if (sess->server->have_extjoin) { if (account && *account) user->account = g_strdup (account); if (realname && *realname) user->realname = g_strdup (realname); } row = userlist_insertname (sess, user); /* duplicate? some broken servers trigger this */ if (row == -1) { g_free (user->hostname); g_free (user->account); g_free (user->realname); g_free (user); return; } sess->total++; /* most ircds don't support multiple modechars in front of the nickname for /NAMES - though they should. */ while (prefix_chars) { update_counts (sess, user, name[0], TRUE, 1); name++; prefix_chars--; } if (user->me) sess->me = user; fe_userlist_insert (sess, user, FALSE); fe_userlist_numbers (sess); } static int rehash_cb (struct User *user, session *sess) { fe_userlist_rehash (sess, user); return TRUE; } void userlist_rehash (session *sess) { tree_foreach (sess->usertree, (tree_traverse_func *)rehash_cb, sess); } static int flat_cb (struct User *user, GSList **list) { *list = g_slist_prepend (*list, user); return TRUE; } GSList * userlist_flat_list (session *sess) { GSList *list = NULL; tree_foreach (sess->usertree, (tree_traverse_func *)flat_cb, &list); return g_slist_reverse (list); } static int double_cb (struct User *user, GList **list) { *list = g_list_prepend(*list, user); return TRUE; } GList * userlist_double_list(session *sess) { GList *list = NULL; tree_foreach (sess->usertree, (tree_traverse_func *)double_cb, &list); return list; }