Code

export the username
[fusedav.git] / src / session.c
1 /* $Id$ */
3 /***
4   This file is part of fusedav.
6   fusedav is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10   
11   fusedav is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14   License for more details.
15   
16   You should have received a copy of the GNU General Public License
17   along with fusedav; if not, write to the Free Software Foundation,
18   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ***/
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <stdio.h>
26 #include <assert.h>
27 #include <pthread.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <termios.h>
31 #include <unistd.h>
33 #include <ne_uri.h>
34 #include <ne_request.h>
35 #include <ne_basic.h>
36 #include <ne_props.h>
37 #include <ne_utils.h>
38 #include <ne_socket.h>
39 #include <ne_auth.h>
40 #include <ne_dates.h>
41 #include <ne_redirect.h>
43 #include "session.h"
44 #include "fusedav.h"
46 static pthread_once_t session_once = PTHREAD_ONCE_INIT;
47 static pthread_key_t session_tsd_key;
49 ne_uri uri;
50 static int b_uri = 0;
52 char *username = NULL;
53 static char *password = NULL;
54 char *base_directory = NULL;
56 static pthread_mutex_t credential_mutex = PTHREAD_MUTEX_INITIALIZER;
58 static char* ask_user(const char *p, int hidden) {
59     char q[256], *r;
60     struct termios t;
61     int c = 0, l;
63     if (hidden) {
64         if (!isatty(fileno(stdin)))
65             hidden = 0;
66         else {
67             if (tcgetattr(fileno(stdin),  &t) < 0)
68                 hidden = 0;
69             else {
70                 c = t.c_lflag;
71                 t.c_lflag &= ~ECHO;
72                 if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0)
73                     hidden = 0;
74             }
75         }
76     }
77     
78     fprintf(stderr, "%s: ", p);
79     r = fgets(q, sizeof(q), stdin);
80     l = strlen(q);
81     if (l && q[l-1] == '\n')
82         q[l-1] = 0;
84     if (hidden) {
85         t.c_lflag = c;
86         tcsetattr(fileno(stdin), TCSANOW, &t);
87         fprintf(stderr, "\n");
88     }
89     
90     return r ? strdup(r) : NULL;
91 }
93 static int ssl_verify_cb(__unused void *userdata, __unused int failures, __unused const ne_ssl_certificate *cert) {
94     return 0;
95 }
97 static int ne_auth_creds_cb(__unused void *userdata, const char *realm, int attempt, char *u, char *p) {
98     int r = -1;
99     
100     pthread_mutex_lock(&credential_mutex);
102     if (attempt) {
103         fprintf(stderr, "Authentication failure!\n");
104         free((void*) username);
105         free((void*) password);
106         username = password = NULL;
107     }
109     if (!username || !password)
110         fprintf(stderr, "Realm '%s' requires authentication.\n", realm);
111     
112     if (!username)
113         username = ask_user("Username", 0);
114     
115     if (username && !password)
116         password = ask_user("Password", 1);
118     if (username && password) {
119         snprintf(u, NE_ABUFSIZ, "%s", username);
120         snprintf(p, NE_ABUFSIZ, "%s", password);
121         r  = 0;
122     }
124     pthread_mutex_unlock(&credential_mutex);
125     return r;
128 static ne_session *session_open(int with_lock) {
129     const char *scheme = NULL;
130     ne_session *session;
132     extern ne_lock_store *lock_store;
134     if (!b_uri)
135         return NULL;
137     scheme = uri.scheme ? uri.scheme : "http";
138     
139     if (!(session = ne_session_create(scheme, uri.host, uri.port ? uri.port : ne_uri_defaultport(scheme)))) {
140         fprintf(stderr, "Failed to create session\n");
141         return NULL;
142     }
144     ne_ssl_set_verify(session, ssl_verify_cb, NULL);
145     ne_set_server_auth(session, ne_auth_creds_cb, NULL);
146     ne_redirect_register(session);
148     if (with_lock && lock_store)
149         ne_lockstore_register(lock_store, session);
150     
151     return session;
154 static void session_destroy(void *s) {
155     ne_session *session = s;
156     assert(s);
157     ne_session_destroy(session);
160 static void session_tsd_key_init(void) {
161     pthread_key_create(&session_tsd_key, session_destroy);
164 ne_session *session_get(int with_lock) {
165     ne_session *session;
166     
167     pthread_once(&session_once, session_tsd_key_init);
169     if ((session = pthread_getspecific(session_tsd_key)))
170         return session;
172     session = session_open(with_lock);
173     pthread_setspecific(session_tsd_key, session);
175     return session;
178 int session_set_uri(const char *s, const char *u, const char *p) {
179     int l;
180         
181     assert(!b_uri);
182     assert(!username);
183     assert(!password);
185     if (ne_uri_parse(s, &uri)) {
186         fprintf(stderr, "Invalid URI <%s>\n", s);
187         goto finish;
188     }
190     b_uri = 1;
192     if (!uri.host) {
193         fprintf(stderr, "Missing host part in URI <%s>\n", s);
194         goto finish;
195     }
197     base_directory = strdup(uri.path);
198     l = strlen(base_directory);
199     if (base_directory[l-1] == '/')
200         ((char*) base_directory)[l-1] = 0;
202     if (u)
203         username = strdup(u);
205     if (p)
206         password = strdup(p);
208     return 0;
209     
210 finish:
211     
212     if (b_uri) {
213         ne_uri_free(&uri);
214         b_uri = 0;
215     }
217     return -1;
221 void session_free(void) {
222     if (b_uri) {
223         ne_uri_free(&uri);
224         b_uri = 0;
225     }
227     free((char*) username);
228     free((char*) password);
229     free((char*) base_directory);
231     username = password = base_directory = NULL;
234 int session_is_local(const ne_uri *u) {
235     assert(u);
236     assert(b_uri);
238     return
239         strcmp(u->scheme, uri.scheme) == 0 &&
240         strcmp(u->host, uri.host) == 0 &&
241         u->port == uri.port;