Update 'es' translation
[siplcs.git] / src / sip-sec.c
blobfdb50e0531bfae632bfa133b609a0bb142879462
1 /**
2 * @file sip-sec.c
4 * pidgin-sipe
6 * Copyright (C) 2009 pier11 <pier11@kinozal.tv>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <glib.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include "debug.h"
29 /* #include "util.h" */
30 #include "sip-sec.h"
31 #include "sip-sec-mech.h"
33 #ifndef _WIN32
34 #include "sip-sec-ntlm.h"
35 #define sip_sec_create_context__NTLM sip_sec_create_context__ntlm
37 #ifdef USE_KERBEROS
38 #include "sip-sec-krb5.h"
39 #define sip_sec_create_context__Kerberos sip_sec_create_context__krb5
40 #else
41 #define sip_sec_create_context__Kerberos sip_sec_create_context__NONE
42 #endif
44 #else /* _WIN32 */
45 #ifdef USE_KERBEROS
46 #include "sip-sec-sspi.h"
47 #define sip_sec_create_context__NTLM sip_sec_create_context__sspi
48 #define sip_sec_create_context__Kerberos sip_sec_create_context__sspi
49 #else /* USE_KERBEROS */
50 #include "sip-sec-ntlm.h"
51 #define sip_sec_create_context__NTLM sip_sec_create_context__ntlm
52 #define sip_sec_create_context__Kerberos sip_sec_create_context__NONE
53 #endif /* USE_KERBEROS */
55 #endif /* _WIN32 */
57 gchar *purple_base64_encode(const guchar *data, gsize len);
58 guchar *purple_base64_decode(const char *str, gsize *ret_len);
60 /* Dummy initialization hook */
61 static SipSecContext
62 sip_sec_create_context__NONE(SIPE_UNUSED_PARAMETER SipSecAuthType type)
64 return(NULL);
67 /* sip_sec API method */
68 char *
69 sip_sec_init_context(SipSecContext *context,
70 int *expires,
71 SipSecAuthType type,
72 const int sso,
73 const char *domain,
74 const char *username,
75 const char *password,
76 const char *target,
77 const char *input_toked_base64)
79 SipSecBuffer in_buff = {0, NULL};
80 SipSecBuffer out_buff = {0, NULL};
81 gchar *out_buff_base64 = NULL;
82 sip_uint32 ret;
84 /* Map authentication type to module initialization hook & name */
85 static const sip_sec_create_context_func const auth_to_hook[] = {
86 sip_sec_create_context__NONE, /* AUTH_TYPE_UNSET */
87 sip_sec_create_context__NONE, /* AUTH_TYPE_DIGEST */
88 sip_sec_create_context__NTLM, /* AUTH_TYPE_NTLM */
89 sip_sec_create_context__Kerberos, /* AUTH_TYPE_KERBEROS */
92 /* @TODO: Can *context != NULL actually happen? */
93 sip_sec_destroy_context(*context);
95 *context = (*(auth_to_hook[type]))(type);
96 if (!*context) return(NULL);
98 (*context)->sso = sso;
100 ret = (*(*context)->acquire_cred_func)(*context, domain, username, password);
101 if (ret != SIP_SEC_E_OK) {
102 purple_debug_info("sipe", "ERROR: sip_sec_init_context failed to acquire credentials.\n");
103 return NULL;
106 /* Type1 (empty) to send */
107 ret = (*(*context)->init_context_func)(*context, in_buff, &out_buff, target);
108 if (ret == SIP_SEC_E_OK) {
109 out_buff_base64 = purple_base64_encode(out_buff.value, out_buff.length);
111 free_bytes_buffer(&out_buff);
113 if (ret == SIP_SEC_I_CONTINUE_NEEDED) {
114 /* Type 2 answer */
115 in_buff.value = purple_base64_decode(input_toked_base64, &(in_buff.length));
116 ret = (*(*context)->init_context_func)(*context, in_buff, &out_buff, target);
117 free_bytes_buffer(&in_buff);
119 /* Type 3 to send */
120 g_free(out_buff_base64);
121 out_buff_base64 = purple_base64_encode(out_buff.value, out_buff.length);
122 free_bytes_buffer(&out_buff);
125 *expires = (*context)->expires;
127 return out_buff_base64;
130 void
131 sip_sec_destroy_context(SipSecContext context)
133 if (context) (*context->destroy_context_func)(context);
136 char * sip_sec_make_signature(SipSecContext context, const char *message)
138 SipSecBuffer signature;
139 char *signature_hex;
141 if(((*context->make_signature_func)(context, message, &signature)) != SIP_SEC_E_OK) {
142 purple_debug_info("sipe", "ERROR: sip_sec_make_signature failed. Unable to sign message!\n");
143 return NULL;
145 signature_hex = bytes_to_hex_str(&signature);
146 free_bytes_buffer(&signature);
147 return signature_hex;
150 int sip_sec_verify_signature(SipSecContext context, const char *message, const char *signature_hex)
152 SipSecBuffer signature;
153 sip_uint32 res;
155 purple_debug_info("sipe", "sip_sec_verify_signature: message is:%s signature to verify is:%s\n",
156 message ? message : "", signature_hex ? signature_hex : "");
158 hex_str_to_bytes(signature_hex, &signature);
159 res = (*context->verify_signature_func)(context, message, signature);
160 free_bytes_buffer(&signature);
161 return res;
165 /* Utility Methods */
167 void hex_str_to_bytes(const char *hex_str, SipSecBuffer *bytes)
169 guint8 *buff;
170 char two_digits[3];
171 size_t i;
173 bytes->length = strlen(hex_str)/2;
174 bytes->value = g_malloc(bytes->length);
176 buff = (guint8 *)bytes->value;
177 for (i = 0; i < bytes->length; i++) {
178 two_digits[0] = hex_str[i * 2];
179 two_digits[1] = hex_str[i * 2 + 1];
180 two_digits[2] = '\0';
181 buff[i] = (guint8)strtoul(two_digits, NULL, 16);
185 void free_bytes_buffer(SipSecBuffer *bytes)
187 g_free(bytes->value);
188 bytes->length = 0;
189 bytes->value = NULL;
192 char *bytes_to_hex_str(SipSecBuffer *bytes)
194 guint8 *buff = (guint8 *)bytes->value;
195 char *res = g_malloc(bytes->length * 2 + 1);
196 size_t i, j;
197 for (i = 0, j = 0; i < bytes->length; i++, j+=2) {
198 sprintf(&res[j], "%02X", buff[i]);
200 res[j] = '\0';
201 return res;
205 Local Variables:
206 mode: c
207 c-file-style: "bsd"
208 indent-tabs-mode: t
209 tab-width: 8
210 End: