/* read HTTP request from sockfd, parse it into command * and its parameters (for instance, command='udp' and * parameters being '192.168.0.1:5002') */ static int read_command( int sockfd, struct server_ctx *srv) { #define DBUF_SZ 2048 /* max size for raw data with HTTP request */ #define RBUF_SZ 512 /* max size for url-derived request */ char httpbuf[ DBUF_SZ ] = "\0", request[ RBUF_SZ ] = "\0"; ssize_t hlen; size_t rlen; int rc = 0; assert( (sockfd > 0) && srv ); TRACE( (void)tmfprintf( g_flog, "Reading command from socket [%d]\n", sockfd ) ); usleep(50); /* ..workaround VLC behavior: wait for receiving entire HTTP request, one packet per line */ hlen = recv( sockfd, httpbuf, sizeof(httpbuf), 0 ); if( 0>hlen ) { rc = errno; if( !no_fault(rc) ) mperror(g_flog, rc, "%s - recv (%d)", __func__, rc); else { TRACE( mperror(g_flog, rc, "%s - recv (%d)", __func__, rc) ); } return rc; } if (0 == hlen) { (void) tmfprintf (g_flog, "%s: client closed socket [%d]\n", __func__, sockfd); return 1; } /* DEBUG - re-enable if needed */ TRACE( (void)tmfprintf( g_flog, "HTTP buffer [%ld bytes] received\n%s", (long)hlen, httpbuf ) ); /* TRACE( (void) save_buffer( httpbuf, hlen, "/tmp/httpbuf.dat" ) ); */ rlen = sizeof(request); rc = get_request( httpbuf, (size_t)hlen, request, &rlen ); if (rc) return rc; TRACE( (void)tmfprintf( g_flog, "Request=[%s], length=[%lu]\n", request, (u_long)rlen ) ); rc = parse_auth( httpbuf, (size_t)hlen ); TRACE( (void)tmfprintf( g_flog, "Auth result=[%d]\n", rc ) ); if (rc) return rc; (void) memset( &srv->rq, 0, sizeof(srv->rq) ); rc = parse_param( request, rlen, srv->rq.cmd, sizeof(srv->rq.cmd), srv->rq.param, sizeof(srv->rq.param), srv->rq.tail, sizeof(srv->rq.tail) ); if( 0 == rc ) { TRACE( (void)tmfprintf( g_flog, "Command [%s] with params [%s], tail [%s]" " read from socket=[%d]\n", srv->rq.cmd, srv->rq.param, srv->rq.tail, sockfd) ); } return rc; }
// Reads a HMDP request from a client // @param connectionfd the socket descriptor of the client // @param username the client's username // @param password the client's password // @param token the client's token // @param request_list the client's list of files to be synced // @param command the type of HMDP request being made // @return 1 if the read was successful, otherwise -1 int read_request(int connectionfd, char **username, char **password, char** token, csv_record **request_list, char **command) { char buffer[MAX_BUFFER_SIZE]; // The buffer used during recv char *request; // The buffer to hold received messages (Will be altered while reading) char *reference; // The unaltered pointer to the message memory int bytes_read = 0; // The number of bytes read from the request // Check to see if the message was completely read if (receive_all(connectionfd, buffer, &bytes_read) == -1) { syslog(LOG_ERR, "Only read %d bytes\n", bytes_read); return -1; } //end if // Keep a pointer to the memory location so we can free it later request = strdup(buffer); reference = request; *command = strdup(read_command(&request)); // Parse an 'Auth' request if (strcmp(*command, COMMAND_AUTH) == 0) { return parse_auth(&reference, &request, command, username, password); } //end if // Parse a 'List' request else if (strcmp(*command, COMMAND_LIST) == 0) { return parse_list(&reference, &request, command, token, request_list); } //end else if // Found an unrecognized command else { syslog(LOG_ERR, "Incorrect command specified"); free(*command); free(reference); *command = NULL; reference = NULL; return -1; } //end else } //end read_request
/** * @brief Auth handler */ int auth_hd(SSH *ssh) { int ret; /* Parse auth */ ret = parse_auth(ssh); if(ret < 0) { return -1; } /* Build success or fail reply */ if (ret == 1) { build_authfail_response(ssh); } else { build_authsucc_response(ssh); } /* Send reply to client */ if (transportWritePacket(ssh) < 0) { return -1; } return 0; }
int mailpop3_auth(mailpop3 * f, const char * auth_type, const char * server_fqdn, const char * local_ip_port, const char * remote_ip_port, const char * login, const char * auth_name, const char * password, const char * realm) { #ifdef USE_SASL int r; char command[POP3_STRING_SIZE]; sasl_callback_t sasl_callback[5]; const char * sasl_out; unsigned sasl_out_len; const char * mechusing; sasl_secret_t * secret; int res; size_t len; char * encoded; unsigned int encoded_len; unsigned int max_encoded; sasl_callback[0].id = SASL_CB_GETREALM; sasl_callback[0].proc = sasl_getrealm; sasl_callback[0].context = f; sasl_callback[1].id = SASL_CB_USER; sasl_callback[1].proc = sasl_getsimple; sasl_callback[1].context = f; sasl_callback[2].id = SASL_CB_AUTHNAME; sasl_callback[2].proc = sasl_getsimple; sasl_callback[2].context = f; sasl_callback[3].id = SASL_CB_PASS; sasl_callback[3].proc = sasl_getsecret; sasl_callback[3].context = f; sasl_callback[4].id = SASL_CB_LIST_END; sasl_callback[4].proc = NULL; sasl_callback[4].context = NULL; len = strlen(password); secret = malloc(sizeof(* secret) + len); if (secret == NULL) { res = MAILPOP3_ERROR_MEMORY; goto err; } secret->len = len; memcpy(secret->data, password, len + 1); f->pop3_sasl.sasl_server_fqdn = server_fqdn; f->pop3_sasl.sasl_login = login; f->pop3_sasl.sasl_auth_name = auth_name; f->pop3_sasl.sasl_password = password; f->pop3_sasl.sasl_realm = realm; f->pop3_sasl.sasl_secret = secret; /* init SASL */ if (f->pop3_sasl.sasl_conn != NULL) { sasl_dispose((sasl_conn_t **) &f->pop3_sasl.sasl_conn); f->pop3_sasl.sasl_conn = NULL; } else { mailsasl_ref(); } r = sasl_client_new("pop", server_fqdn, local_ip_port, remote_ip_port, sasl_callback, 0, (sasl_conn_t **) &f->pop3_sasl.sasl_conn); if (r != SASL_OK) { res = MAILPOP3_ERROR_BAD_USER; goto free_secret; } r = sasl_client_start(f->pop3_sasl.sasl_conn, auth_type, NULL, &sasl_out, &sasl_out_len, &mechusing); if ((r != SASL_CONTINUE) && (r != SASL_OK)) { res = MAILPOP3_ERROR_BAD_USER; goto free_sasl_conn; } snprintf(command, POP3_STRING_SIZE, "AUTH %s\r\n", auth_type); r = send_command(f, command); if (r == -1) { res = MAILPOP3_ERROR_STREAM; goto free_sasl_conn; } while (1) { char * response; response = read_line(f); r = parse_auth(f, response); switch (r) { case RESPONSE_OK: f->pop3_state = POP3_STATE_TRANSACTION; res = MAILPOP3_NO_ERROR; goto free_sasl_conn; case RESPONSE_ERR: res = MAILPOP3_ERROR_BAD_USER; goto free_sasl_conn; case RESPONSE_AUTH_CONT: { size_t response_len; char * decoded; unsigned int decoded_len; unsigned int max_decoded; int got_response; got_response = 1; if (* f->pop3_response == '\0') got_response = 0; if (got_response) { char * p; p = strchr(f->pop3_response, '\r'); if (p != NULL) { * p = '\0'; } p = strchr(f->pop3_response, '\n'); if (p != NULL) { * p = '\0'; } response_len = strlen(f->pop3_response); max_decoded = response_len * 3 / 4; decoded = malloc(max_decoded + 1); if (decoded == NULL) { res = MAILPOP3_ERROR_MEMORY; goto free_sasl_conn; } r = sasl_decode64(f->pop3_response, response_len, decoded, max_decoded + 1, &decoded_len); if (r != SASL_OK) { free(decoded); res = MAILPOP3_ERROR_MEMORY; goto free_sasl_conn; } r = sasl_client_step(f->pop3_sasl.sasl_conn, decoded, decoded_len, NULL, &sasl_out, &sasl_out_len); free(decoded); if ((r != SASL_CONTINUE) && (r != SASL_OK)) { res = MAILPOP3_ERROR_BAD_USER; goto free_sasl_conn; } } max_encoded = ((sasl_out_len + 2) / 3) * 4; encoded = malloc(max_encoded + 1); if (encoded == NULL) { res = MAILPOP3_ERROR_MEMORY; goto free_sasl_conn; } r = sasl_encode64(sasl_out, sasl_out_len, encoded, max_encoded + 1, &encoded_len); if (r != SASL_OK) { free(encoded); res = MAILPOP3_ERROR_MEMORY; goto free_sasl_conn; } snprintf(command, POP3_STRING_SIZE, "%s\r\n", encoded); r = send_command(f, command); free(encoded); if (r == -1) { res = MAILPOP3_ERROR_STREAM; goto free_sasl_conn; } } break; } } f->pop3_state = POP3_STATE_TRANSACTION; res = MAILPOP3_NO_ERROR; free_sasl_conn: sasl_dispose((sasl_conn_t **) &f->pop3_sasl.sasl_conn); f->pop3_sasl.sasl_conn = NULL; mailsasl_unref(); free_secret: free(f->pop3_sasl.sasl_secret); f->pop3_sasl.sasl_secret = NULL; err: return res; #else return MAILPOP3_ERROR_BAD_USER; #endif }