4f1009b2e24c883fbc7cba4d67c09e0e2f550980
1 #include <stdio.h>
2 #include <assert.h>
3 #include <pthread.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <termios.h>
7 #include <unistd.h>
9 #include <ne_uri.h>
10 #include <ne_request.h>
11 #include <ne_basic.h>
12 #include <ne_props.h>
13 #include <ne_utils.h>
14 #include <ne_socket.h>
15 #include <ne_auth.h>
16 #include <ne_dates.h>
18 #include "session.h"
21 static pthread_once_t session_once = PTHREAD_ONCE_INIT;
22 static pthread_key_t session_tsd_key;
24 static ne_uri uri;
25 static int b_uri = 0;
27 static const char *username = NULL, *password = NULL;
28 const char *base_directory = NULL;
30 static pthread_mutex_t credential_mutex = PTHREAD_MUTEX_INITIALIZER;
33 static char* ask_user(char *p, int hidden) {
34 char q[256], *r;
35 struct termios t;
36 int c = 0, l;
38 if (hidden) {
39 if (!isatty(fileno(stdin)))
40 hidden = 0;
41 else {
42 if (tcgetattr(fileno(stdin), &t) < 0)
43 hidden = 0;
44 else {
45 c = t.c_lflag;
46 t.c_lflag &= ~ECHO;
47 if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0)
48 hidden = 0;
49 }
50 }
51 }
53 fprintf(stderr, "%s: ", p);
54 r = fgets(q, sizeof(q), stdin);
55 l = strlen(q);
56 if (l && q[l-1] == '\n')
57 q[l-1] = 0;
59 if (hidden) {
60 t.c_lflag = c;
61 tcsetattr(fileno(stdin), TCSANOW, &t);
62 fprintf(stderr, "\n");
63 }
65 return r ? strdup(r) : NULL;
66 }
68 static int ssl_verify_cb(void *userdata, int failures, const ne_ssl_certificate *cert) {
69 return 0;
70 }
72 static int ne_auth_creds_cb(void *userdata, const char *realm, int attempt, char *u, char *p) {
73 int r = -1;
76 pthread_mutex_lock(&credential_mutex);
78 if (attempt) {
79 fprintf(stderr, "Authenication failure!\n");
80 free((void*) username);
81 free((void*) password);
82 username = password = NULL;
83 }
85 if (!username)
86 username = ask_user("Username", 0);
88 if (username && !password)
89 password = ask_user("Password", 1);
91 if (username && password) {
92 snprintf(u, NE_ABUFSIZ, "%s", username);
93 snprintf(p, NE_ABUFSIZ, "%s", password);
94 r = 0;
95 }
97 pthread_mutex_unlock(&credential_mutex);
98 return r;
99 }
101 static ne_session *session_open(void) {
102 char *scheme = NULL;
103 ne_session *session;
105 if (!b_uri)
106 return NULL;
108 scheme = uri.scheme ? uri.scheme : "http";
110 if (!(session = ne_session_create(scheme, uri.host, uri.port ? uri.port : ne_uri_defaultport(scheme)))) {
111 fprintf(stderr, "Failed to create session\n");
112 return NULL;
113 }
115 ne_ssl_set_verify(session, ssl_verify_cb, NULL);
116 ne_set_server_auth(session, ne_auth_creds_cb, NULL);
117 return session;
118 }
120 static void session_destroy(void *s) {
121 ne_session *session = s;
122 assert(s);
123 ne_session_destroy(session);
124 }
126 static void session_tsd_key_init(void) {
127 pthread_key_create(&session_tsd_key, session_destroy);
128 }
130 ne_session *session_get(void) {
131 ne_session *session;
133 pthread_once(&session_once, session_tsd_key_init);
135 if ((session = pthread_getspecific(session_tsd_key)))
136 return session;
138 session = session_open();
139 pthread_setspecific(session_tsd_key, session);
141 return session;
142 }
144 int session_set_uri(const char *s, const char *u, const char *p) {
145 assert(!b_uri && !username && !password);
146 int l;
148 if (ne_uri_parse(s, &uri)) {
149 fprintf(stderr, "Invalid URI <%s>\n", s);
150 goto finish;
151 }
153 b_uri = 1;
155 if (!uri.host) {
156 fprintf(stderr, "Missing host part in URI <%s>\n", s);
157 goto finish;
158 }
160 base_directory = strdup(uri.path);
161 l = strlen(base_directory);
162 if (base_directory[l-1] == '/')
163 ((char*) base_directory)[l-1] = 0;
165 if (u)
166 username = strdup(u);
168 if (p)
169 password = strdup(p);
171 return 0;
173 finish:
175 if (b_uri) {
176 ne_uri_free(&uri);
177 b_uri = 0;
178 }
180 return -1;
181 }
184 void session_free(void) {
185 if (b_uri) {
186 ne_uri_free(&uri);
187 b_uri = 0;
188 }
190 free((char*) username);
191 free((char*) password);
192 free((char*) base_directory);
194 username = password = base_directory = NULL;
195 }