1 #define _XOPEN_SOURCE 500 /* strdup from string.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
)) {
18 /* Deinicialize ISDS library.
19 * Global function, must be called as last library function. */
20 isds_error
isds_cleanup(void) {
21 curl_global_cleanup();
26 /* Return text description of ISDS error */
27 char *isds_strerror(const isds_error error
) {
30 return(_("Success")); break;
32 return(_("Unspecified error")); break;
34 return(_("Not supported")); break;
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;
44 return(_("Timed out")); break;
46 return(_("Not exist")); break;
48 return(_("Out of memmory")); break;
50 return(_("Network problem")); break;
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
));
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
) {
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
;
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
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
) {
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
;
114 strcpy(buffer
, message
);
118 context
->long_message
= buffer
;
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
) {
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
;
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
) {
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.
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
;
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
;
181 context
->url
= strdup(url
);
185 context
->curl
= curl_easy_init();
186 if (!(context
->curl
))
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
);
196 curl_easy_cleanup(context
->curl
);
197 context
->curl
= NULL
;
201 /* XXX: Dummy authentication */
202 if (response_length
== 25 &&
203 !strncmp(response
, "<message>Hello</message>\n", 25)) {
205 free(context
->cookie
);
206 context
->cookie
= strdup("42");
207 if (!context
->cookie
)
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
;
222 curl_easy_cleanup(context
->curl
);
223 context
->curl
= NULL
;
226 if (!(context
->cookie
)) return IE_NOT_LOGGED_IN
;
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);