mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-01 11:26:52 +03:00
examples: Reformat ssh_server.c
Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Sahana Prasad <sahana@redhat.com> Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
This commit is contained in:
committed by
Sahana Prasad
parent
a001e19882
commit
17a8a8b3c3
@ -135,7 +135,9 @@ static struct argp_option options[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Parse a single option. */
|
/* Parse a single option. */
|
||||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
static error_t
|
||||||
|
parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
|
{
|
||||||
/* Get the input argument from argp_parse, which we
|
/* Get the input argument from argp_parse, which we
|
||||||
* know is a pointer to our arguments structure. */
|
* know is a pointer to our arguments structure. */
|
||||||
ssh_bind sshbind = state->input;
|
ssh_bind sshbind = state->input;
|
||||||
@ -154,7 +156,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
|||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
strncpy(authorizedkeys, arg, DEF_STR_SIZE-1);
|
strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
strncpy(username, arg, sizeof(username) - 1);
|
strncpy(username, arg, sizeof(username) - 1);
|
||||||
@ -163,20 +165,19 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
|||||||
strncpy(password, arg, sizeof(password) - 1);
|
strncpy(password, arg, sizeof(password) - 1);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||||
"3");
|
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (state->arg_num >= 1) {
|
if (state->arg_num >= 1) {
|
||||||
/* Too many arguments. */
|
/* Too many arguments. */
|
||||||
argp_usage (state);
|
argp_usage(state);
|
||||||
}
|
}
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_END:
|
case ARGP_KEY_END:
|
||||||
if (state->arg_num < 1) {
|
if (state->arg_num < 1) {
|
||||||
/* Not enough arguments. */
|
/* Not enough arguments. */
|
||||||
argp_usage (state);
|
argp_usage(state);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -188,7 +189,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
|||||||
/* Our argp parser. */
|
/* Our argp parser. */
|
||||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||||
#else
|
#else
|
||||||
static int parse_opt(int argc, char **argv, ssh_bind sshbind) {
|
static int
|
||||||
|
parse_opt(int argc, char **argv, ssh_bind sshbind)
|
||||||
|
{
|
||||||
int no_default_keys = 0;
|
int no_default_keys = 0;
|
||||||
int rsa_already_set = 0;
|
int rsa_already_set = 0;
|
||||||
int ecdsa_already_set = 0;
|
int ecdsa_already_set = 0;
|
||||||
@ -289,49 +292,74 @@ struct session_data_struct {
|
|||||||
int authenticated;
|
int authenticated;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int data_function(ssh_session session, ssh_channel channel, void *data,
|
static int
|
||||||
uint32_t len, int is_stderr, void *userdata) {
|
data_function(ssh_session session,
|
||||||
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
|
ssh_channel channel,
|
||||||
|
void *data,
|
||||||
|
uint32_t len,
|
||||||
|
int is_stderr,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||||
|
|
||||||
(void) session;
|
(void)session;
|
||||||
(void) channel;
|
(void)channel;
|
||||||
(void) is_stderr;
|
(void)is_stderr;
|
||||||
|
|
||||||
if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) {
|
if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return write(cdata->child_stdin, (char *) data, len);
|
return write(cdata->child_stdin, (char *)data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pty_request(ssh_session session, ssh_channel channel,
|
static int
|
||||||
const char *term, int cols, int rows, int py, int px,
|
pty_request(ssh_session session,
|
||||||
void *userdata) {
|
ssh_channel channel,
|
||||||
|
const char *term,
|
||||||
|
int cols,
|
||||||
|
int rows,
|
||||||
|
int py,
|
||||||
|
int px,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||||
|
int rc;
|
||||||
|
|
||||||
(void) session;
|
(void)session;
|
||||||
(void) channel;
|
(void)channel;
|
||||||
(void) term;
|
(void)term;
|
||||||
|
|
||||||
cdata->winsize->ws_row = rows;
|
cdata->winsize->ws_row = rows;
|
||||||
cdata->winsize->ws_col = cols;
|
cdata->winsize->ws_col = cols;
|
||||||
cdata->winsize->ws_xpixel = px;
|
cdata->winsize->ws_xpixel = px;
|
||||||
cdata->winsize->ws_ypixel = py;
|
cdata->winsize->ws_ypixel = py;
|
||||||
|
|
||||||
if (openpty(&cdata->pty_master, &cdata->pty_slave, NULL, NULL,
|
rc = openpty(&cdata->pty_master,
|
||||||
cdata->winsize) != 0) {
|
&cdata->pty_slave,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
cdata->winsize);
|
||||||
|
if (rc != 0) {
|
||||||
fprintf(stderr, "Failed to open pty\n");
|
fprintf(stderr, "Failed to open pty\n");
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pty_resize(ssh_session session, ssh_channel channel, int cols,
|
static int
|
||||||
int rows, int py, int px, void *userdata) {
|
pty_resize(ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
int cols,
|
||||||
|
int rows,
|
||||||
|
int py,
|
||||||
|
int px,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||||
|
|
||||||
(void) session;
|
(void)session;
|
||||||
(void) channel;
|
(void)channel;
|
||||||
|
|
||||||
cdata->winsize->ws_row = rows;
|
cdata->winsize->ws_row = rows;
|
||||||
cdata->winsize->ws_col = cols;
|
cdata->winsize->ws_col = cols;
|
||||||
@ -345,9 +373,13 @@ static int pty_resize(ssh_session session, ssh_channel channel, int cols,
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exec_pty(const char *mode, const char *command,
|
static int
|
||||||
struct channel_data_struct *cdata) {
|
exec_pty(const char *mode,
|
||||||
switch(cdata->pid = fork()) {
|
const char *command,
|
||||||
|
struct channel_data_struct *cdata)
|
||||||
|
{
|
||||||
|
cdata->pid = fork();
|
||||||
|
switch (cdata->pid) {
|
||||||
case -1:
|
case -1:
|
||||||
close(cdata->pty_master);
|
close(cdata->pty_master);
|
||||||
close(cdata->pty_slave);
|
close(cdata->pty_slave);
|
||||||
@ -368,7 +400,9 @@ static int exec_pty(const char *mode, const char *command,
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exec_nopty(const char *command, struct channel_data_struct *cdata) {
|
static int
|
||||||
|
exec_nopty(const char *command, struct channel_data_struct *cdata)
|
||||||
|
{
|
||||||
int in[2], out[2], err[2];
|
int in[2], out[2], err[2];
|
||||||
|
|
||||||
/* Do the plumbing to be able to talk with the child process. */
|
/* Do the plumbing to be able to talk with the child process. */
|
||||||
@ -382,7 +416,8 @@ static int exec_nopty(const char *command, struct channel_data_struct *cdata) {
|
|||||||
goto stderr_failed;
|
goto stderr_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(cdata->pid = fork()) {
|
cdata->pid = fork();
|
||||||
|
switch (cdata->pid) {
|
||||||
case -1:
|
case -1:
|
||||||
goto fork_failed;
|
goto fork_failed;
|
||||||
case 0:
|
case 0:
|
||||||
@ -424,15 +459,18 @@ stdin_failed:
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exec_request(ssh_session session, ssh_channel channel,
|
static int
|
||||||
const char *command, void *userdata) {
|
exec_request(ssh_session session,
|
||||||
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
|
ssh_channel channel,
|
||||||
|
const char *command,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||||
|
|
||||||
|
(void)session;
|
||||||
|
(void)channel;
|
||||||
|
|
||||||
(void) session;
|
if (cdata->pid > 0) {
|
||||||
(void) channel;
|
|
||||||
|
|
||||||
if(cdata->pid > 0) {
|
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,14 +480,15 @@ static int exec_request(ssh_session session, ssh_channel channel,
|
|||||||
return exec_nopty(command, cdata);
|
return exec_nopty(command, cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shell_request(ssh_session session, ssh_channel channel,
|
static int
|
||||||
void *userdata) {
|
shell_request(ssh_session session, ssh_channel channel, void *userdata)
|
||||||
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
|
{
|
||||||
|
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||||
|
|
||||||
(void) session;
|
(void)session;
|
||||||
(void) channel;
|
(void)channel;
|
||||||
|
|
||||||
if(cdata->pid > 0) {
|
if (cdata->pid > 0) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,8 +499,12 @@ static int shell_request(ssh_session session, ssh_channel channel,
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subsystem_request(ssh_session session, ssh_channel channel,
|
static int
|
||||||
const char *subsystem, void *userdata) {
|
subsystem_request(ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
const char *subsystem,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
/* subsystem requests behave similarly to exec requests. */
|
/* subsystem requests behave similarly to exec requests. */
|
||||||
if (strcmp(subsystem, "sftp") == 0) {
|
if (strcmp(subsystem, "sftp") == 0) {
|
||||||
return exec_request(session, channel, SFTP_SERVER_PATH, userdata);
|
return exec_request(session, channel, SFTP_SERVER_PATH, userdata);
|
||||||
@ -469,11 +512,15 @@ static int subsystem_request(ssh_session session, ssh_channel channel,
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int auth_password(ssh_session session, const char *user,
|
static int
|
||||||
const char *pass, void *userdata) {
|
auth_password(ssh_session session,
|
||||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
const char *user,
|
||||||
|
const char *pass,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
|
||||||
|
|
||||||
(void) session;
|
(void)session;
|
||||||
|
|
||||||
if (strcmp(user, username) == 0 && strcmp(pass, password) == 0) {
|
if (strcmp(user, username) == 0 && strcmp(pass, password) == 0) {
|
||||||
sdata->authenticated = 1;
|
sdata->authenticated = 1;
|
||||||
@ -484,13 +531,14 @@ static int auth_password(ssh_session session, const char *user,
|
|||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int auth_publickey(ssh_session session,
|
static int
|
||||||
|
auth_publickey(ssh_session session,
|
||||||
const char *user,
|
const char *user,
|
||||||
struct ssh_key_struct *pubkey,
|
struct ssh_key_struct *pubkey,
|
||||||
char signature_state,
|
char signature_state,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
|
||||||
ssh_key key = NULL;
|
ssh_key key = NULL;
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
char line[AUTH_KEYS_MAX_LINE_SIZE] = {0};
|
char line[AUTH_KEYS_MAX_LINE_SIZE] = {0};
|
||||||
@ -501,8 +549,8 @@ static int auth_publickey(ssh_session session,
|
|||||||
int i;
|
int i;
|
||||||
enum ssh_keytypes_e type;
|
enum ssh_keytypes_e type;
|
||||||
|
|
||||||
(void) user;
|
(void)user;
|
||||||
(void) session;
|
(void)session;
|
||||||
|
|
||||||
if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
|
if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
|
||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
@ -598,17 +646,21 @@ static int auth_publickey(ssh_session session,
|
|||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssh_channel channel_open(ssh_session session, void *userdata) {
|
static ssh_channel
|
||||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
channel_open(ssh_session session, void *userdata)
|
||||||
|
{
|
||||||
|
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
|
||||||
|
|
||||||
sdata->channel = ssh_channel_new(session);
|
sdata->channel = ssh_channel_new(session);
|
||||||
return sdata->channel;
|
return sdata->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_stdout(socket_t fd, int revents, void *userdata) {
|
static int
|
||||||
|
process_stdout(socket_t fd, int revents, void *userdata)
|
||||||
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
int n = -1;
|
int n = -1;
|
||||||
ssh_channel channel = (ssh_channel) userdata;
|
ssh_channel channel = (ssh_channel)userdata;
|
||||||
|
|
||||||
if (channel != NULL && (revents & POLLIN) != 0) {
|
if (channel != NULL && (revents & POLLIN) != 0) {
|
||||||
n = read(fd, buf, BUF_SIZE);
|
n = read(fd, buf, BUF_SIZE);
|
||||||
@ -620,10 +672,12 @@ static int process_stdout(socket_t fd, int revents, void *userdata) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_stderr(socket_t fd, int revents, void *userdata) {
|
static int
|
||||||
|
process_stderr(socket_t fd, int revents, void *userdata)
|
||||||
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
int n = -1;
|
int n = -1;
|
||||||
ssh_channel channel = (ssh_channel) userdata;
|
ssh_channel channel = (ssh_channel)userdata;
|
||||||
|
|
||||||
if (channel != NULL && (revents & POLLIN) != 0) {
|
if (channel != NULL && (revents & POLLIN) != 0) {
|
||||||
n = read(fd, buf, BUF_SIZE);
|
n = read(fd, buf, BUF_SIZE);
|
||||||
@ -635,7 +689,9 @@ static int process_stderr(socket_t fd, int revents, void *userdata) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_session(ssh_event event, ssh_session session) {
|
static void
|
||||||
|
handle_session(ssh_event event, ssh_session session)
|
||||||
|
{
|
||||||
int n;
|
int n;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
@ -748,7 +804,7 @@ static void handle_session(ssh_event event, ssh_session session) {
|
|||||||
ssh_channel_close(sdata.channel);
|
ssh_channel_close(sdata.channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(ssh_channel_is_open(sdata.channel) &&
|
} while (ssh_channel_is_open(sdata.channel) &&
|
||||||
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
|
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
|
||||||
|
|
||||||
close(cdata.pty_master);
|
close(cdata.pty_master);
|
||||||
@ -782,12 +838,14 @@ static void handle_session(ssh_event event, ssh_session session) {
|
|||||||
|
|
||||||
#ifdef WITH_FORK
|
#ifdef WITH_FORK
|
||||||
/* SIGCHLD handler for cleaning up dead children. */
|
/* SIGCHLD handler for cleaning up dead children. */
|
||||||
static void sigchld_handler(int signo) {
|
static void sigchld_handler(int signo)
|
||||||
(void) signo;
|
{
|
||||||
|
(void)signo;
|
||||||
while (waitpid(-1, NULL, WNOHANG) > 0);
|
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void *session_thread(void *arg) {
|
static void *session_thread(void *arg)
|
||||||
|
{
|
||||||
ssh_session session = arg;
|
ssh_session session = arg;
|
||||||
ssh_event event;
|
ssh_event event;
|
||||||
|
|
||||||
@ -806,9 +864,10 @@ static void *session_thread(void *arg) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv)
|
||||||
ssh_bind sshbind;
|
{
|
||||||
ssh_session session;
|
ssh_bind sshbind = NULL;
|
||||||
|
ssh_session session = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
#ifdef WITH_FORK
|
#ifdef WITH_FORK
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
@ -846,7 +905,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_ARGP_H */
|
#endif /* HAVE_ARGP_H */
|
||||||
|
|
||||||
if(ssh_bind_listen(sshbind) < 0) {
|
rc = ssh_bind_listen(sshbind);
|
||||||
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
||||||
ssh_bind_free(sshbind);
|
ssh_bind_free(sshbind);
|
||||||
ssh_finalize();
|
ssh_finalize();
|
||||||
@ -861,11 +921,13 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Blocks until there is a new incoming connection. */
|
/* Blocks until there is a new incoming connection. */
|
||||||
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
|
rc = ssh_bind_accept(sshbind, session);
|
||||||
|
if (rc != SSH_ERROR) {
|
||||||
#ifdef WITH_FORK
|
#ifdef WITH_FORK
|
||||||
ssh_event event;
|
ssh_event event;
|
||||||
|
|
||||||
switch(fork()) {
|
pid_t pid = fork();
|
||||||
|
switch (pid) {
|
||||||
case 0:
|
case 0:
|
||||||
/* Remove the SIGCHLD handler inherited from parent. */
|
/* Remove the SIGCHLD handler inherited from parent. */
|
||||||
sa.sa_handler = SIG_DFL;
|
sa.sa_handler = SIG_DFL;
|
||||||
|
Reference in New Issue
Block a user