the server now does the chroot and change uid.
There is also an option "nopassword" for ftp users. git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@25 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
родитель
ddd650b3bd
Коммит
bcb6bf25fa
@ -136,6 +136,8 @@ int group_callback(const char *shortvar, const char *var, const char *arguments,
|
|||||||
if(!strcasecmp(shortvar,"chroot")){
|
if(!strcasecmp(shortvar,"chroot")){
|
||||||
current_group->chroot=strdup(value);
|
current_group->chroot=strdup(value);
|
||||||
}
|
}
|
||||||
|
if(!strcasecmp(shortvar,"nopassword"))
|
||||||
|
current_group->nopassword=1;
|
||||||
}
|
}
|
||||||
return LC_CBRET_OKAY;
|
return LC_CBRET_OKAY;
|
||||||
}
|
}
|
||||||
@ -278,6 +280,7 @@ int parse_config(char *file){
|
|||||||
r=lc_register_callback("group.uid",0,LC_VAR_UNKNOWN,group_callback,NULL);
|
r=lc_register_callback("group.uid",0,LC_VAR_UNKNOWN,group_callback,NULL);
|
||||||
r=lc_register_callback("group.chroot",0,LC_VAR_UNKNOWN,group_callback,NULL);
|
r=lc_register_callback("group.chroot",0,LC_VAR_UNKNOWN,group_callback,NULL);
|
||||||
r=lc_register_callback("group.group",0,LC_VAR_UNKNOWN,group_callback,NULL);
|
r=lc_register_callback("group.group",0,LC_VAR_UNKNOWN,group_callback,NULL);
|
||||||
|
r=lc_register_callback("group.nopassword",0,LC_VAR_NONE,group_callback,NULL);
|
||||||
// lc_register_var("dir", LC_VAR_SECTION, NULL, 0);
|
// lc_register_var("dir", LC_VAR_SECTION, NULL, 0);
|
||||||
r=lc_register_callback("dir",0,LC_VAR_NONE,dir_callback,NULL);
|
r=lc_register_callback("dir",0,LC_VAR_NONE,dir_callback,NULL);
|
||||||
r=lc_register_callback("dir.list",0,LC_VAR_UNKNOWN,dir_callback,NULL);
|
r=lc_register_callback("dir.list",0,LC_VAR_UNKNOWN,dir_callback,NULL);
|
||||||
@ -291,3 +294,52 @@ int parse_config(char *file){
|
|||||||
list_config();
|
list_config();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list *find_groups(char *user){
|
||||||
|
return list_find(users,user);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *user_chroot(char *user){
|
||||||
|
char *c_grp;
|
||||||
|
list *group=find_groups(user);
|
||||||
|
struct group *grp;
|
||||||
|
while(group){
|
||||||
|
c_grp=group->key;
|
||||||
|
grp=list_find(groups,c_grp);
|
||||||
|
if(grp->chroot)
|
||||||
|
return grp->chroot;
|
||||||
|
group=group->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *user_uid(char *user){
|
||||||
|
char *c_grp;
|
||||||
|
list *group=find_groups(user);
|
||||||
|
struct group *grp;
|
||||||
|
while(group){
|
||||||
|
c_grp=group->key;
|
||||||
|
grp=list_find(groups,c_grp);
|
||||||
|
if(grp->uid)
|
||||||
|
return grp->uid;
|
||||||
|
group=group->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 0 if it's not specified. 1 if the user doesn't need a password */
|
||||||
|
int user_nopassword(char *user){
|
||||||
|
char *c_grp;
|
||||||
|
list *group=find_groups(user);
|
||||||
|
struct group *grp;
|
||||||
|
if(!group)
|
||||||
|
return 0; //user doesn't exist
|
||||||
|
while(group){
|
||||||
|
c_grp=group->key;
|
||||||
|
grp=list_find(groups,c_grp);
|
||||||
|
if(grp->nopassword)
|
||||||
|
return 1;
|
||||||
|
group=group->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@ MA 02111-1307, USA. */
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
@ -81,7 +82,59 @@ int password_conv(int num_msg, const struct pam_message **msg,
|
|||||||
return PAM_SUCCESS;
|
return PAM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* postauth_conf returns -1 on error, else 0 */
|
||||||
|
int postauth_conf(char *user){
|
||||||
|
/* first, find a chroot if any */
|
||||||
|
char *root,*ptr;
|
||||||
|
char *char_uid;
|
||||||
|
char buffer[256];
|
||||||
|
int uid;
|
||||||
|
struct passwd *pw=getpwnam(user);
|
||||||
|
root=user_chroot(user);
|
||||||
|
if(root){
|
||||||
|
if((ptr=strstr(root,"$HOME"))){
|
||||||
|
if(!pw)
|
||||||
|
return -1; // this user has no user directory
|
||||||
|
*ptr=0;
|
||||||
|
snprintf(buffer,sizeof(buffer),"%s%s/%s",
|
||||||
|
root,pw->pw_dir,ptr+strlen("$HOME"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snprintf(buffer,sizeof(buffer),"%s",root);
|
||||||
|
}
|
||||||
|
/* we don't chroot right now because we still need getpwnam() */
|
||||||
|
char_uid=user_uid(user);
|
||||||
|
if(!char_uid){
|
||||||
|
if(!pw)
|
||||||
|
return -1; // user doesn't exist !
|
||||||
|
char_uid=user;
|
||||||
|
}
|
||||||
|
uid=atoi(char_uid);
|
||||||
|
if(uid==0 && char_uid[0]!=0){
|
||||||
|
pw=getpwnam(char_uid);
|
||||||
|
if(!pw)
|
||||||
|
return -1;
|
||||||
|
uid=pw->pw_uid;
|
||||||
|
}
|
||||||
|
if(root && chroot(buffer)){
|
||||||
|
return -1; // cannot chroot
|
||||||
|
}
|
||||||
|
if(root){
|
||||||
|
chdir("/");
|
||||||
|
} else {
|
||||||
|
if(pw)
|
||||||
|
chdir(pw->pw_dir);
|
||||||
|
else
|
||||||
|
chdir("/");
|
||||||
|
}
|
||||||
|
if(setuid(uid)){
|
||||||
|
return -1; // cannot setuid
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct pam_conv pam_conv ={ password_conv, NULL };
|
struct pam_conv pam_conv ={ password_conv, NULL };
|
||||||
/* returns 1 if authenticated, 0 if failed,
|
/* returns 1 if authenticated, 0 if failed,
|
||||||
-1 if you must leave */
|
-1 if you must leave */
|
||||||
@ -101,6 +154,8 @@ int auth_password(char *user, char *password){
|
|||||||
memset(password,0,strlen(password));
|
memset(password,0,strlen(password));
|
||||||
if(ret==PAM_SUCCESS){
|
if(ret==PAM_SUCCESS){
|
||||||
pam_end(pamh,PAM_SUCCESS);
|
pam_end(pamh,PAM_SUCCESS);
|
||||||
|
if(postauth_conf(user))
|
||||||
|
return -1;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
pam_end(pamh,PAM_AUTH_ERR);
|
pam_end(pamh,PAM_AUTH_ERR);
|
||||||
@ -469,13 +524,32 @@ int do_auth(SSH_SESSION *session){
|
|||||||
ssh_say(1,"Auth refused\n");
|
ssh_say(1,"Auth refused\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(auth==1)
|
if(auth==1){
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
}
|
||||||
|
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);
|
if(user_nopassword(ssh_message_auth_user(message))){
|
||||||
//auth=1;
|
if(postauth_conf(ssh_message_auth_user(message))==0){
|
||||||
//break;
|
ssh_message_auth_reply_success(message,0);
|
||||||
|
auth=1;
|
||||||
|
ssh_say(1,"Authentication success for %s(no password)\n",
|
||||||
|
ssh_message_auth_user(message));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ssh_say(1,"Post-auth failed\n");
|
||||||
|
ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
/* server.h */
|
/* server.h */
|
||||||
/* headers for the sftp server project */
|
/* headers for the sftp server project */
|
||||||
int parse_config(char *file);
|
int parse_config(char *file);
|
||||||
|
char *user_chroot(char *user);
|
||||||
|
char *user_uid(char *user);
|
||||||
|
int user_nopassword(char *user);
|
||||||
|
|
||||||
typedef struct list_struct {
|
typedef struct list_struct {
|
||||||
struct list_struct *next;
|
struct list_struct *next;
|
||||||
@ -17,6 +20,7 @@ struct group {
|
|||||||
char *chroot;
|
char *chroot;
|
||||||
char *uid;
|
char *uid;
|
||||||
char *gid;
|
char *gid;
|
||||||
|
int nopassword;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dir {
|
struct dir {
|
||||||
|
@ -8,6 +8,7 @@ Hostkeydsa /etc/ssh/ssh_host_dsa_key
|
|||||||
<group anonymous>
|
<group anonymous>
|
||||||
user ftp, anonymous, anon
|
user ftp, anonymous, anon
|
||||||
uid ftp
|
uid ftp
|
||||||
|
nopassword
|
||||||
chroot /home/ftp
|
chroot /home/ftp
|
||||||
</group>
|
</group>
|
||||||
<group users>
|
<group users>
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user