more ACL on directories. Not already enabled.
First Pam code. looks like it works more or less. it needs a file in /etc/pam.d to be activated git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@22 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
родитель
8510d2abe4
Коммит
0de0dca16d
@ -13,7 +13,7 @@ libdir = $(prefix)/lib/
|
|||||||
mandir = $(prefix)/man/man1
|
mandir = $(prefix)/man/man1
|
||||||
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CFLAGS = @CFLAGS@ -Iinclude/ -Wall -g
|
CFLAGS = @CFLAGS@ -Iinclude/ -Wall
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBS = -lssh -Llibssh/
|
LIBS = -lssh -Llibssh/
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* sftp headers */
|
/* sftp headers */
|
||||||
/*
|
/*
|
||||||
Copyright 2003 Aris Adamantiadis
|
Copyright 2003-2005 Aris Adamantiadis
|
||||||
|
|
||||||
This file is part of the SSH Library
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ libdir = $(prefix)/lib/
|
|||||||
mandir = $(prefix)/man/man1
|
mandir = $(prefix)/man/man1
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -g -O2 -Wall -g -I../include/ -Ilibconfig/
|
CFLAGS = -Wall -g -I../include/ -Ilibconfig/
|
||||||
LDFLAGS = -L../libssh/ -lssh -Llibconfig/
|
LDFLAGS = -L../libssh/ -lssh -Llibconfig/
|
||||||
LIBS = -lz -lcrypto -lconfig
|
LIBS = -lz -lcrypto -lconfig -lpam -lcrypto
|
||||||
INSTALL = /usr/bin/install -c
|
INSTALL = /usr/bin/install -c
|
||||||
DYLIB_EXTENSION = so
|
DYLIB_EXTENSION = so
|
||||||
LIBSSH_LDFLAGS = -shared
|
LIBSSH_LDFLAGS = -shared
|
||||||
|
@ -16,7 +16,7 @@ mandir = $(prefix)/man/man1
|
|||||||
CC = @CC@
|
CC = @CC@
|
||||||
CFLAGS = @CFLAGS@ -Wall -g -I../include/ -Ilibconfig/
|
CFLAGS = @CFLAGS@ -Wall -g -I../include/ -Ilibconfig/
|
||||||
LDFLAGS = -L../libssh/ -lssh -Llibconfig/
|
LDFLAGS = -L../libssh/ -lssh -Llibconfig/
|
||||||
LIBS = @LIBS@ -lconfig
|
LIBS = @LIBS@ -lconfig -lpam -lcrypto
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
DYLIB_EXTENSION = @DYLIB_EXTENSION@
|
DYLIB_EXTENSION = @DYLIB_EXTENSION@
|
||||||
LIBSSH_LDFLAGS = @LIBSSH_LDFLAGS@
|
LIBSSH_LDFLAGS = @LIBSSH_LDFLAGS@
|
||||||
|
@ -23,6 +23,7 @@ MA 02111-1307, USA. */
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
/* shortvar is "port" in "port 22" */
|
/* shortvar is "port" in "port 22" */
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ char *rsa=NULL;
|
|||||||
|
|
||||||
list *groups;
|
list *groups;
|
||||||
list *users;
|
list *users;
|
||||||
|
struct dir *root_dir=NULL;
|
||||||
/* users is a list of users. The key of this list is the user name.
|
/* users is a list of users. The key of this list is the user name.
|
||||||
the data of the list is a list of groups. both data & key from this list
|
the data of the list is a list of groups. both data & key from this list
|
||||||
is the group name */
|
is the group name */
|
||||||
@ -137,17 +139,47 @@ int group_callback(const char *shortvar, const char *var, const char *arguments,
|
|||||||
}
|
}
|
||||||
return LC_CBRET_OKAY;
|
return LC_CBRET_OKAY;
|
||||||
}
|
}
|
||||||
|
struct dir *create_directory(const char *directory);
|
||||||
|
struct dir *current_dir=NULL;
|
||||||
|
int append_groups(list **plist, const char *groups){
|
||||||
|
char *begin=strdup(groups);
|
||||||
|
char *ptr;
|
||||||
|
char *grp=begin;
|
||||||
|
do{
|
||||||
|
ptr=strchr(grp,',');
|
||||||
|
if(ptr){
|
||||||
|
*ptr=0;
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
while(*grp==' ')
|
||||||
|
++grp;
|
||||||
|
if(!list_find(*plist,grp))
|
||||||
|
*plist=list_add(*plist,grp,strdup(grp));
|
||||||
|
grp=ptr;
|
||||||
|
} while (grp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int dir_callback(const char *shortvar, const char *var, const char *arguments, const char *value, lc_flags_t flags, void *extra){
|
int dir_callback(const char *shortvar, const char *var, const char *arguments, const char *value, lc_flags_t flags, void *extra){
|
||||||
switch(flags){
|
switch(flags){
|
||||||
case LC_FLAGS_SECTIONSTART:
|
case LC_FLAGS_SECTIONSTART:
|
||||||
printf("new dir %s\n",arguments);
|
if(current_dir){
|
||||||
|
printf("Cannot define a directory into a directory !\n");
|
||||||
|
return LC_CBRET_ERROR;
|
||||||
|
}
|
||||||
|
current_dir=create_directory(arguments);
|
||||||
break;
|
break;
|
||||||
case LC_FLAGS_SECTIONEND:
|
case LC_FLAGS_SECTIONEND:
|
||||||
printf("end of dir\n\n");
|
current_dir=NULL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("%s - %s\n",shortvar, value);
|
if(!strcasecmp(shortvar,"list"))
|
||||||
|
append_groups(¤t_dir->List,value);
|
||||||
|
if(!strcasecmp(shortvar,"read"))
|
||||||
|
append_groups(¤t_dir->Read,value);
|
||||||
|
if(!strcasecmp(shortvar,"write"))
|
||||||
|
append_groups(¤t_dir->Write,value);
|
||||||
|
// printf("%s - %s\n",shortvar, value);
|
||||||
}
|
}
|
||||||
return LC_CBRET_OKAY;
|
return LC_CBRET_OKAY;
|
||||||
}
|
}
|
||||||
@ -178,6 +210,61 @@ void list_config(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **cut_directory(const char *dir){
|
||||||
|
char *tmp=strdup(dir);
|
||||||
|
char *ptr;
|
||||||
|
char *ret[128];
|
||||||
|
char **answer;
|
||||||
|
int i=0;
|
||||||
|
while(tmp && *tmp && i<128){
|
||||||
|
while(*tmp=='/')
|
||||||
|
++tmp;
|
||||||
|
ptr=strchr(tmp,'/');
|
||||||
|
if(ptr){
|
||||||
|
*ptr=0;
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
ret[i]=strdup(tmp);
|
||||||
|
tmp=ptr;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
answer=malloc((i+1)*sizeof(char *));
|
||||||
|
memcpy(answer,ret,sizeof(char *)*i);
|
||||||
|
answer[i]=NULL;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dir *dir_new(){
|
||||||
|
struct dir *dir=malloc(sizeof(struct dir));
|
||||||
|
memset(dir,0,sizeof(*dir));
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
/* it doesn't really create the directory. it makes the tree to the directory
|
||||||
|
* and returns a link to the last node */
|
||||||
|
struct dir *create_directory(const char *directory){
|
||||||
|
char **tokens=cut_directory(directory);
|
||||||
|
int i=0;
|
||||||
|
struct dir *dir,*ptr;
|
||||||
|
if(!root_dir){
|
||||||
|
root_dir=dir_new();
|
||||||
|
root_dir->name="";
|
||||||
|
}
|
||||||
|
dir=root_dir;
|
||||||
|
for(i=0;tokens[i];++i){
|
||||||
|
ptr=list_find(dir->subdir,tokens[i]);
|
||||||
|
if(!ptr){
|
||||||
|
ptr=dir_new();
|
||||||
|
ptr->name=strdup(tokens[i]);
|
||||||
|
dir->subdir=list_add(dir->subdir,tokens[i],ptr);
|
||||||
|
}
|
||||||
|
dir=ptr;
|
||||||
|
}
|
||||||
|
for(i=0;tokens[i];++i)
|
||||||
|
free(tokens[i]);
|
||||||
|
free(tokens);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
int parse_config(char *file){
|
int parse_config(char *file){
|
||||||
int r;
|
int r;
|
||||||
printf("Parsing configuration file %s\n",file);
|
printf("Parsing configuration file %s\n",file);
|
||||||
|
@ -22,6 +22,8 @@ MA 02111-1307, USA. */
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
list *list_add(list *ptr, const char *key, void *data){
|
list *list_add(list *ptr, const char *key, void *data){
|
||||||
list *new=malloc(sizeof(list));
|
list *new=malloc(sizeof(list));
|
||||||
new->next=ptr;
|
new->next=ptr;
|
||||||
|
@ -33,8 +33,12 @@ MA 02111-1307, USA. */
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <security/pam_appl.h>
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
|
#define SERVICE "sftp"
|
||||||
|
|
||||||
#define TYPE_DIR 1
|
#define TYPE_DIR 1
|
||||||
#define TYPE_FILE 1
|
#define TYPE_FILE 1
|
||||||
struct sftp_handle {
|
struct sftp_handle {
|
||||||
@ -46,12 +50,61 @@ struct sftp_handle {
|
|||||||
FILE *file;
|
FILE *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
char *user_password;
|
||||||
|
int password_conv(int num_msg, const struct pam_message **msg,
|
||||||
|
struct pam_response **resp, void *appdata)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
for(i=0;i<num_msg;++i){
|
||||||
|
resp[i]=malloc(sizeof (struct pam_response));
|
||||||
|
resp[i]->resp_retcode=0;
|
||||||
|
switch(msg[i]->msg_style){
|
||||||
|
case PAM_PROMPT_ECHO_ON:
|
||||||
|
//printf("PAM: %s",msg[i]->msg);
|
||||||
|
resp[i]->resp=strdup(user_password);
|
||||||
|
break;
|
||||||
|
case PAM_PROMPT_ECHO_OFF:
|
||||||
|
//printf("PAM: %s",msg[i]->msg);
|
||||||
|
resp[i]->resp=strdup(user_password);
|
||||||
|
break;
|
||||||
|
case PAM_ERROR_MSG:
|
||||||
|
//printf("PAM_ERROR: %s",msg[i]->msg);
|
||||||
|
break;
|
||||||
|
case PAM_TEXT_INFO:
|
||||||
|
//printf("PAM TEXT: %s",msg[i]->msg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct pam_conv pam_conv ={ password_conv, NULL };
|
||||||
|
/* returns 1 if authenticated, 0 if failed,
|
||||||
|
-1 if you must leave */
|
||||||
int auth_password(char *user, char *password){
|
int auth_password(char *user, char *password){
|
||||||
if(strcmp(user,"aris"))
|
pam_handle_t *pamh;
|
||||||
|
int ret;
|
||||||
|
static int tries=0;
|
||||||
|
if(tries>3)
|
||||||
|
return -1;
|
||||||
|
tries++;
|
||||||
|
user_password=password;
|
||||||
|
ret=pam_start(SERVICE,user,&pam_conv,&pamh);
|
||||||
|
if(ret==PAM_SUCCESS)
|
||||||
|
ret=pam_authenticate(pamh,0);
|
||||||
|
if(ret==PAM_SUCCESS)
|
||||||
|
ret=pam_acct_mgmt(pamh,0);
|
||||||
|
memset(password,0,strlen(password));
|
||||||
|
if(ret==PAM_SUCCESS){
|
||||||
|
pam_end(pamh,PAM_SUCCESS);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
pam_end(pamh,PAM_AUTH_ERR);
|
||||||
return 0;
|
return 0;
|
||||||
if(strcmp(password,"lala"))
|
}
|
||||||
return 0;
|
|
||||||
return 1; // authenticated
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int reply_status(SFTP_CLIENT_MESSAGE *msg){
|
int reply_status(SFTP_CLIENT_MESSAGE *msg){
|
||||||
@ -388,7 +441,7 @@ int sftploop(SSH_SESSION *session, SFTP_SESSION *sftp){
|
|||||||
|
|
||||||
int do_auth(SSH_SESSION *session){
|
int do_auth(SSH_SESSION *session){
|
||||||
SSH_MESSAGE *message;
|
SSH_MESSAGE *message;
|
||||||
int auth=0;
|
int auth=-1;
|
||||||
do {
|
do {
|
||||||
message=ssh_message_get(session);
|
message=ssh_message_get(session);
|
||||||
if(!message)
|
if(!message)
|
||||||
@ -397,20 +450,31 @@ int do_auth(SSH_SESSION *session){
|
|||||||
case SSH_AUTH_REQUEST:
|
case SSH_AUTH_REQUEST:
|
||||||
switch(ssh_message_subtype(message)){
|
switch(ssh_message_subtype(message)){
|
||||||
case SSH_AUTH_PASSWORD:
|
case SSH_AUTH_PASSWORD:
|
||||||
printf("User %s wants to auth with pass %s\n",
|
ssh_say(1,"User %s wants to auth by password\n",
|
||||||
ssh_message_auth_user(message),
|
ssh_message_auth_user(message));
|
||||||
ssh_message_auth_password(message));
|
auth=auth_password(ssh_message_auth_user(message),
|
||||||
if(auth_password(ssh_message_auth_user(message),
|
ssh_message_auth_password(message));
|
||||||
ssh_message_auth_password(message))){
|
switch(auth){
|
||||||
auth=1;
|
case 1:
|
||||||
ssh_message_auth_reply_success(message,0);
|
ssh_say(1,"Authentication success\n");
|
||||||
break;
|
ssh_message_auth_reply_success(message,0);
|
||||||
}
|
break;
|
||||||
|
case -1:
|
||||||
|
ssh_say(1,"Too much tries\n");
|
||||||
|
// too much auth tried
|
||||||
|
ssh_disconnect(session);
|
||||||
|
exit(1);
|
||||||
|
case 0:
|
||||||
|
ssh_say(1,"Auth refused\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(auth==1)
|
||||||
|
break;
|
||||||
// not authenticated, send default message
|
// not authenticated, send default message
|
||||||
case SSH_AUTH_NONE:
|
case SSH_AUTH_NONE:
|
||||||
ssh_message_auth_reply_success(message,0);
|
//ssh_message_auth_reply_success(message,0);
|
||||||
auth=1;
|
//auth=1;
|
||||||
break;
|
//break;
|
||||||
default:
|
default:
|
||||||
ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
|
ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
|
||||||
ssh_message_reply_default(message);
|
ssh_message_reply_default(message);
|
||||||
@ -421,7 +485,7 @@ int do_auth(SSH_SESSION *session){
|
|||||||
ssh_message_reply_default(message);
|
ssh_message_reply_default(message);
|
||||||
}
|
}
|
||||||
ssh_message_free(message);
|
ssh_message_free(message);
|
||||||
} while (!auth);
|
} while (auth!=1);
|
||||||
return auth;
|
return auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,7 +556,7 @@ int main(int argc, char **argv){
|
|||||||
printf("ssh_accept : %s\n",ssh_get_error(session));
|
printf("ssh_accept : %s\n",ssh_get_error(session));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(do_auth(session)<=0){
|
if(do_auth(session)<0){
|
||||||
printf("error : %s\n",ssh_get_error(session));
|
printf("error : %s\n",ssh_get_error(session));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -18,3 +18,12 @@ struct group {
|
|||||||
char *uid;
|
char *uid;
|
||||||
char *gid;
|
char *gid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dir {
|
||||||
|
char *name;
|
||||||
|
list *subdir;
|
||||||
|
list *List;
|
||||||
|
list *Read;
|
||||||
|
list *Write;
|
||||||
|
};
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user