Back to index

avfs  1.0.1
passwords.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 2000-2001  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 
00009 /*
00010     Taken from FTP code, and renamed.
00011 
00012     Can be used more-or-less verbatim in DAV and HTTP code.
00013 
00014     Reuse in FTP code will require noting that the ftpdata struct
00015     is not passed in; instead the sessions member is used. Also
00016     FTP code will need to pass in NULL for "realm" arguments.
00017 
00018     TODO: more fine-grained locking
00019 */
00020 
00021 #include "remote.h"
00022 #include "filebuf.h"
00023 #include "passwords.h"
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <unistd.h>
00028 #include <fcntl.h>
00029 #include <sys/socket.h>
00030 #include <netdb.h>
00031 #include <netinet/in.h>
00032 
00033 static AV_LOCK_DECL(pass_lock);
00034 
00035 static struct pass_session *pass_find_session(struct pass_session *passd,
00036                                            const char *account)
00037 {
00038     struct pass_session *fts;
00039 
00040     if (passd == NULL) {
00041        return NULL;
00042     }
00043     for(fts = passd->next; fts != NULL && fts != passd; fts = fts->next) {
00044        av_log(AVLOG_DEBUG, "passwords: lookup '%s' == '%s'", account, fts->account);
00045         if(fts->account != NULL && strcmp(account, fts->account) == 0)
00046             return fts;
00047     }
00048     
00049     return NULL;
00050 }
00051 
00052 static struct pass_session *pass_get_session(struct pass_session *passd,
00053                                           const char *account)
00054 {
00055     struct pass_session *fts;
00056     
00057     if (passd == NULL) {
00058        return NULL;
00059     }
00060     fts = pass_find_session(passd, account);
00061     if(fts == NULL) {
00062         struct pass_session *next;
00063         struct pass_session *prev;
00064 
00065         AV_NEW(fts);
00066         fts->account = av_strdup(account);
00067         fts->password = NULL;
00068 
00069         fts->next = next = passd->next;
00070         fts->prev = prev = passd;
00071        if (next != NULL) {
00072            next->prev = fts;
00073        }
00074         prev->next = fts;
00075     }
00076     
00077     return fts;
00078 }
00079 
00080 void pass_remove_session(struct pass_session *fts)
00081 {
00082     struct pass_session *next = fts->next;
00083     struct pass_session *prev = fts->prev;
00084     
00085     next->prev = prev;
00086     prev->next = next;
00087 
00088     av_free(fts->account);
00089     av_free(fts->password);
00090     av_free(fts);
00091 }
00092 
00093 struct pass_session *pass_get_password(struct pass_session *passd,
00094               const char *host, const char *user)
00095 {
00096     struct pass_session *fts = NULL;
00097     char *account;
00098 
00099     if (passd == NULL) {
00100        return NULL;
00101     }
00102     if (fts == NULL) {
00103        account = av_stradd(NULL, user, USER_SEP_STR, host, NULL);
00104        fts = pass_find_session(passd, account);
00105        av_free(account);
00106     }
00107 
00108     if(fts == NULL) {
00109         account = av_stradd(NULL, user, USER_SEP_STR, NULL);
00110         fts = pass_find_session(passd, account);
00111         av_free(account);
00112     }
00113 
00114     if(fts == NULL) {
00115         account = av_stradd(NULL, USER_SEP_STR, host, NULL);
00116         fts = pass_find_session(passd, account);
00117         av_free(account);
00118     }
00119 
00120     av_log(AVLOG_DEBUG, "passwords: fts=%lx", (long) fts);
00121     return fts;
00122 }
00123 
00124 
00125 int pass_username_get(struct entry *ent, const char *param, char **resp)
00126 {
00127     *resp = av_strdup("");
00128     return 0;
00129 }
00130 
00131 int pass_username_set(struct entry *ent, const char *param, const char *val)
00132 {
00133     struct pass_session *fts;
00134     struct statefile *sf = (struct statefile *) av_namespace_get(ent);
00135     struct pass_session *passd = (struct pass_session *) sf->data;
00136     unsigned int len;
00137 
00138     AV_LOCK(pass_lock);
00139     fts = pass_get_session(passd, param);
00140     av_log(AVLOG_DEBUG, "passwords: setting username '%s' %s'", param, val);
00141 
00142     av_free(fts->username);
00143     fts->username = av_strdup(val);
00144     len = strlen(fts->username);
00145     if(fts->username[len - 1] == '\n')
00146         fts->username[len - 1] = '\0';
00147 
00148     AV_UNLOCK(pass_lock);
00149 
00150     return 0;
00151 }
00152 
00153 int pass_password_get(struct entry *ent, const char *param, char **resp)
00154 {
00155     *resp = av_strdup("");
00156     return 0;
00157 }
00158 
00159 int pass_password_set(struct entry *ent, const char *param, const char *val)
00160 {
00161     struct pass_session *fts;
00162     struct statefile *sf = (struct statefile *) av_namespace_get(ent);
00163     struct pass_session *passd = (struct pass_session *) sf->data;
00164     unsigned int len;
00165 
00166     AV_LOCK(pass_lock);
00167     fts = pass_get_session(passd, param);
00168     /* av_log(AVLOG_DEBUG, "passwords: setting password '%s' %s'",
00169      * param, val);*/
00170 
00171     av_free(fts->password);
00172     fts->password = av_strdup(val);
00173     len = strlen(fts->password);
00174     if(fts->password[len - 1] == '\n')
00175         fts->password[len - 1] = '\0';
00176 
00177     AV_UNLOCK(pass_lock);
00178 
00179     return 0;
00180 }
00181 
00182 int pass_loggedin_get(struct entry *ent, const char *param, char **resp)
00183 {
00184     struct pass_session *fts;
00185     struct statefile *sf = (struct statefile *) av_namespace_get(ent);
00186     struct pass_session *passd = (struct pass_session *) sf->data;
00187 
00188     AV_LOCK(pass_lock);
00189     fts = pass_find_session(passd, param);
00190     if(fts == NULL)
00191         *resp = av_strdup("0\n");
00192     else
00193         *resp = av_strdup("1\n");
00194     AV_UNLOCK(pass_lock);
00195 
00196     return 0;
00197 }
00198 
00199 static int pass_loggedin_val(const char *val, int *resp)
00200 {
00201     char *end;
00202     int ival;
00203 
00204     ival = strtol(val, &end, 10);
00205     if(end == val)
00206         return -EINVAL;
00207 
00208     if(*end == '\n')
00209         end++;
00210     if(*end != '\0')
00211         return -EINVAL;
00212 
00213     if(ival < 0 || ival > 1)
00214         return -EINVAL;
00215     
00216     *resp = ival;
00217 
00218     return 0;
00219 }
00220 
00221 int pass_loggedin_set(struct entry *ent, const char *param, const char *val)
00222 {
00223     int res;
00224     struct pass_session *fts;
00225     struct statefile *sf = (struct statefile *) av_namespace_get(ent);
00226     struct pass_session *passd = (struct pass_session *) sf->data;
00227 
00228     AV_LOCK(pass_lock);
00229     fts = pass_find_session(passd, param);
00230     if(fts == NULL)
00231         res = -EACCES;
00232     else {
00233         int ival;
00234 
00235         res = pass_loggedin_val(val, &ival);
00236         if(res == 0 && ival == 0) {
00237             /* FIXME: end connections using this session */
00238             pass_remove_session(fts);
00239         }
00240     }
00241     AV_UNLOCK(pass_lock);
00242 
00243     return res;
00244 }
00245 
00246 // vim:sw=4: