Fix context url and cookie setting
[libisds.git] / src / isds.c
blobc7a3fac162ee26b706cf069c8c5c81bbccd57d92
1 #define _XOPEN_SOURCE 500 /* strdup from string.h */
2 #include <stdlib.h>
3 #include <string.h>
4 #include "isds_priv.h"
5 #include "utils.h"
6 #include "soap.h"
9 /* Initialize ISDS library.
10 * Global function, must be called before other functions. */
11 isds_error isds_init(void) {
12 if (curl_global_init(CURL_GLOBAL_ALL)) {
13 return IE_ERROR;
15 return IE_SUCCESS;
18 /* Deinicialize ISDS library.
19 * Global function, must be called as last library function. */
20 isds_error isds_cleanup(void) {
21 curl_global_cleanup();
22 return IE_SUCCESS;
26 /* Return text description of ISDS error */
27 char *isds_strerror(const isds_error error) {
28 switch (error) {
29 case IE_SUCCESS:
30 return(_("Success")); break;
31 case IE_ERROR:
32 return(_("Unspecified error")); break;
33 case IE_NOTSUP:
34 return(_("Not supported")); break;
35 case IE_INVAL:
36 return(_("Invalid value")); break;
37 case IE_INVALID_CONTEXT:
38 return(_("Invalid context")); break;
39 case IE_NOT_LOGGED_IN:
40 return(_("Not logged in")); break;
41 case IE_CONNECTION_CLOSED:
42 return(_("Connection closed")); break;
43 case IE_TIMED_OUT:
44 return(_("Timed out")); break;
45 case IE_NOEXIST:
46 return(_("Not exist")); break;
47 case IE_NOMEM:
48 return(_("Out of memmory")); break;
49 case IE_NETWORK:
50 return(_("Network problem")); break;
51 default:
52 return(_("Unknown error"));
57 /* Create ISDS context.
58 * Each context can be used for different sessions to (possibly) differnet
59 * ISDS server with different credentials. */
60 struct isds_ctx *isds_ctx_create(void) {
61 struct isds_ctx *context;
62 context = malloc(sizeof(struct isds_ctx));
63 memset(context, 0, sizeof(*context));
64 return context;
68 /* Destroy ISDS context and free memmory.
69 * @context will be NULLed on success. */
70 isds_error isds_ctx_free(struct isds_ctx **context) {
71 if (!context || !*context) {
72 return IE_ERROR;
75 /* Free internal structures */
76 if ((*context)->url) free((*context)->url);
77 if ((*context)->curl) {
78 curl_easy_cleanup((*context)->curl);
79 (*context)->curl = NULL;
82 free(*context);
83 *context = NULL;
84 return IE_SUCCESS;
88 /* Return long message text produced by library fucntion, e.g. detailed error
89 * mesage. Returned pointer is only valid until new library function is
90 * called for the same context. Could be NULL, especially if NULL context is
91 * supplied. */
92 char *isds_long_message(const struct isds_ctx *context) {
93 if (!context) return NULL;
94 return context->long_message;
98 /* Stores message into context' long_message buffer.
99 * Application can pick the message up using isds_long_message().
100 * NULL @message truncates the buffer but does not deallocate it. */
101 _hidden isds_error isds_log_message(struct isds_ctx *context,
102 const char *message) {
103 char *buffer;
104 size_t length;
106 if (!context) return IE_INVALID_CONTEXT;
108 /* FIXME: Check for integer overflow */
109 length = 1 + (message) ? strlen(message) : 0;
110 buffer = realloc(context->long_message, length);
111 if (!buffer) return IE_NOMEM;
113 if (message)
114 strcpy(buffer, message);
115 else
116 *buffer = '\0';
118 context->long_message = buffer;
119 return IE_SUCCESS;
123 /* Appends message into context' long_message buffer.
124 * Application can pick the message up using isds_long_message().
125 * NULL message has void effect. */
126 _hidden isds_error isds_append_message(struct isds_ctx *context,
127 const char *message) {
128 char *buffer;
129 size_t old_length, length;
131 if (!context) return IE_INVALID_CONTEXT;
132 if (!message) return IE_SUCCESS;
133 if (!context->long_message)
134 return isds_log_message(context, message);
136 old_length = strlen(context->long_message);
137 /* FIXME: Check for integer overflow */
138 length = 1 + old_length + strlen(message);
139 buffer = realloc(context->long_message, length);
140 if (!buffer) return IE_NOMEM;
142 strcpy(buffer + old_length, message);
144 context->long_message = buffer;
145 return IE_SUCCESS;
149 /* Connect to given url.
150 * It just makes TCP connection to ISDS server found in @url hostname part. */
151 /*int isds_connect(struct isds_ctx *context, const char *url);*/
153 /* Set timeout in miliseconds for each network job like connecting to server
154 * or sending message. Use 0 to disable timeout limits. */
155 isds_error isds_set_timeout(struct isds_ctx *context, const unsigned int timeout) {
156 return IE_NOTSUP;
160 /* Connect and log in into ISDS server.
161 * @url is address of ISDS web service
162 * @username is user name of ISDS user
163 * @password is user's secret password
164 * @certificate is NULL terminated string with PEM formated client's
165 * certificate. Use NULL if only password autentication should be performed.
166 * @key is private key for client's certificate as (base64 encoded?) NULL
167 * terminated string. Use NULL if only password autentication is desired.
168 * */
169 isds_error isds_login(struct isds_ctx *context, const char *url, const char *username,
170 const char *password, const char *certificate, const char* key) {
171 isds_error err = IE_NOT_LOGGED_IN;
172 isds_error soap_err;
173 void *response = NULL;
174 size_t response_length;
176 if (!context) return IE_INVALID_CONTEXT;
177 if (!url || !username || !password) return IE_INVAL;
178 if (certificate || key) return IE_NOTSUP;
180 free(context->url);
181 context->url = strdup(url);
182 if (!(context->url))
183 return IE_NOMEM;
185 context->curl = curl_easy_init();
186 if (!(context->curl))
187 return IE_ERROR;
189 /* TODO: Pass username and password
190 * Real ISDS login is HTTPS digest authentication with optional X.509 TLS
191 * client authentication. */
192 soap_err = soap(context, "login", NULL, &response, &response_length);
194 if (soap_err) {
195 free(response);
196 curl_easy_cleanup(context->curl);
197 context->curl = NULL;
198 return IE_NETWORK;
201 /* XXX: Dummy authentication */
202 if (response_length == 25 &&
203 !strncmp(response, "<message>Hello</message>\n", 25)) {
204 err = IE_SUCCESS;
205 free(context->cookie);
206 context->cookie = strdup("42");
207 if (!context->cookie)
208 err = IE_NOMEM;
211 free(response);
213 return err;
217 /* Log out from ISDS server and close connection. */
218 isds_error isds_logout(struct isds_ctx *context) {
219 if (!context) return IE_INVALID_CONTEXT;
221 if (context->curl) {
222 curl_easy_cleanup(context->curl);
223 context->curl = NULL;
226 if (!(context->cookie)) return IE_NOT_LOGGED_IN;
227 return IE_NOTSUP;
231 /*int isds_get_message(struct isds_ctx *context, const unsigned int id,
232 struct isds_message **message);
233 int isds_send_message(struct isds_ctx *context, struct isds_message *message);
234 int isds_list_messages(struct isds_ctx *context, struct isds_message **message);
235 int isds_find_recipient(struct isds_ctx *context, const struct address *pattern,
236 struct isds_address **address);
238 int isds_message_free(struct isds_message **message);
239 int isds_address_free(struct isds_address **address);