netatalk  4.5.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
uams_srp.c File Reference
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <gcrypt.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <atalk/afp.h>
#include <atalk/constant_time.h>
#include <atalk/logger.h>
#include <atalk/uam.h>

Macros

#define SRP_INIT_MARKER   0x0001
#define SRP_CLIENT_PROOF   0x0003
#define SRP_SERVER_PROOF   0x0004
#define SRP_SHA1_LEN   20
#define SRP_SALT_LEN   16
#define SRP_GROUP_INDEX   0x0002 /* RFC 5054 group #2 */
#define SRP_NBYTES   192 /* 1536-bit prime = 192 bytes */
#define SRP_SESSION_KEY_LEN   40
#define SRP_HEX_SALT_LEN   (SRP_SALT_LEN * 2)
#define SRP_HEX_V_LEN   (SRP_NBYTES * 2)
#define SRP_AUTH_FAILURE   (-6754)
#define unhex(x)

Functions

static const unsigned char * strip_leading_zeros (const unsigned char *buf, size_t len, size_t *out_len)
 Strip leading zero bytes from a big-endian integer buffer.
static int mgf1_sha1 (const unsigned char *seed, size_t seed_len, unsigned char *out, size_t out_len)
 MGF1 mask generation function (PKCS#1 v2.1) with SHA-1.
static int sha1_multi (unsigned char *out,...)
 Compute SHA-1 incrementally from multiple buffers.
static void mpi_to_padded_buf (unsigned char *buf, size_t nbytes, gcry_mpi_t m)
 Write an MPI to a buffer as a big-endian integer, zero-padded.
static void write_uint16_be (unsigned char **p, uint16_t val)
 Write a 2-byte big-endian unsigned integer and advance the pointer.
static uint16_t read_uint16_be (unsigned char **p)
 Read a 2-byte big-endian unsigned integer and advance the pointer.
static int srp_lookup_verifier (const char *path, const char *username, unsigned char *salt_out, gcry_mpi_t *v_out)
 Look up a user's salt and verifier from the SRP verifier file.
static void srp_session_free (void)
 Release all per-session SRP state and zero sensitive buffers.
static int srp_setup (void *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 SRP Round 1 setup.
static int srp_login (void *obj, struct passwd **uam_pwd, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 FPLogin handler for SRP UAM.
static int srp_login_ext (void *obj, char *uname, struct passwd **uam_pwd, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 FPLoginExt handler for SRP UAM.
static int srp_logincont (void *obj, struct passwd **uam_pwd, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 SRP Round 2: FPLoginCont handler.
static int uam_setup (void *obj, const char *path)
static void uam_cleanup (void)

Variables

static const unsigned char srp_N_bytes [SRP_NBYTES]
static const unsigned char srp_g_byte = 0x02
static gcry_mpi_t session_N
static gcry_mpi_t session_g
static gcry_mpi_t session_v
static gcry_mpi_t session_b
static gcry_mpi_t session_B
static unsigned char session_salt [SRP_SALT_LEN]
static unsigned char session_B_buf [SRP_NBYTES]
static char session_username [UAM_USERNAMELEN+1]
static struct passwd * srppwd
UAM_MODULE_EXPORT struct uam_export uams_srp

Detailed Description

SRP (Secure Remote Password) User Authentication Method for AFP. Protocol: SRP-6a with SHA-1, MGF1 KDF, RFC 5054 group #2 (1536-bit).

Macro Definition Documentation

◆ SRP_AUTH_FAILURE

#define SRP_AUTH_FAILURE   (-6754)

◆ SRP_CLIENT_PROOF

#define SRP_CLIENT_PROOF   0x0003

◆ SRP_GROUP_INDEX

#define SRP_GROUP_INDEX   0x0002 /* RFC 5054 group #2 */

◆ SRP_HEX_SALT_LEN

#define SRP_HEX_SALT_LEN   (SRP_SALT_LEN * 2)

◆ SRP_HEX_V_LEN

#define SRP_HEX_V_LEN   (SRP_NBYTES * 2)

◆ SRP_INIT_MARKER

#define SRP_INIT_MARKER   0x0001

◆ SRP_NBYTES

#define SRP_NBYTES   192 /* 1536-bit prime = 192 bytes */

◆ SRP_SALT_LEN

#define SRP_SALT_LEN   16

◆ SRP_SERVER_PROOF

#define SRP_SERVER_PROOF   0x0004

◆ SRP_SESSION_KEY_LEN

#define SRP_SESSION_KEY_LEN   40

◆ SRP_SHA1_LEN

#define SRP_SHA1_LEN   20

◆ unhex

#define unhex ( x)
Value:
(isdigit(x) ? (x) - '0' : toupper(x) + 10 - 'A')

Function Documentation

◆ mgf1_sha1()

int mgf1_sha1 ( const unsigned char * seed,
size_t seed_len,
unsigned char * out,
size_t out_len )
static

MGF1 mask generation function (PKCS#1 v2.1) with SHA-1.

Parameters
[in]seedThe seed for the mask generation.
[in]seed_lenThe length of the seed.
[out]outThe output buffer.
[in]out_lenThe length of the output buffer.
Returns
0 on success, -1 on failure.

◆ mpi_to_padded_buf()

void mpi_to_padded_buf ( unsigned char * buf,
size_t nbytes,
gcry_mpi_t m )
static

Write an MPI to a buffer as a big-endian integer, zero-padded.

Parameters
[out]bufOutput buffer (must be at least nbytes).
[in]nbytesTarget length with leading zero padding.
[in]mMPI to serialize.

◆ read_uint16_be()

uint16_t read_uint16_be ( unsigned char ** p)
static

Read a 2-byte big-endian unsigned integer and advance the pointer.

Parameters
[in,out]pPointer to the read position (advanced by 2).
Returns
The decoded 16-bit value.

◆ sha1_multi()

int sha1_multi ( unsigned char * out,
... )
static

Compute SHA-1 incrementally from multiple buffers.

Arguments after out are pairs of (const unsigned char *data, size_t len), terminated by a NULL data pointer.

Parameters
[out]out20-byte buffer for the SHA-1 digest.
Returns
0 on success, -1 on failure.

◆ srp_login()

int srp_login ( void * obj,
struct passwd ** uam_pwd,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )
static

FPLogin handler for SRP UAM.

Parses the username from the non-extended login request, validates the user, and delegates to srp_setup() for Round 1.

◆ srp_login_ext()

int srp_login_ext ( void * obj,
char * uname,
struct passwd ** uam_pwd,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )
static

FPLoginExt handler for SRP UAM.

Parses the UTF-8 username from the extended login request, validates the user, and delegates to srp_setup() for Round 1.

◆ srp_logincont()

int srp_logincont ( void * obj,
struct passwd ** uam_pwd,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )
static

SRP Round 2: FPLoginCont handler.

Parses the client's public ephemeral A and proof M1, computes the server-side shared secret S and session key K, verifies M1, and responds with server proof M2 to complete mutual authentication.

Returns
AFP_OK on success, AFPERR_NOTAUTH on proof mismatch.

◆ srp_lookup_verifier()

int srp_lookup_verifier ( const char * path,
const char * username,
unsigned char * salt_out,
gcry_mpi_t * v_out )
static

Look up a user's salt and verifier from the SRP verifier file.

The file format is one line per user: username:hex_salt:hex_verifier

Parameters
[in]pathPath to the verifier file.
[in]usernameUser to look up.
[out]salt_outBuffer for the salt (SRP_SALT_LEN bytes).
[out]v_outMPI set to the verifier on success.
Returns
0 on success, -1 on failure (user not found or file error).

◆ srp_session_free()

void srp_session_free ( void )
static

Release all per-session SRP state and zero sensitive buffers.

◆ srp_setup()

int srp_setup ( void * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )
static

SRP Round 1 setup.

Looks up the user's verifier from the verifier file, generates the server ephemeral key pair (b, B), and builds the FPLoginExt response containing the SRP group parameters, salt, and server public ephemeral B.

Returns
AFPERR_AUTHCONT on success, AFPERR_NOTAUTH if user not found.

◆ strip_leading_zeros()

const unsigned char * strip_leading_zeros ( const unsigned char * buf,
size_t len,
size_t * out_len )
static

Strip leading zero bytes from a big-endian integer buffer.

Returns
pointer to the first non-zero byte (or last byte if all zeros).

◆ uam_cleanup()

void uam_cleanup ( void )
static

◆ uam_setup()

int uam_setup ( void * obj,
const char * path )
static

◆ write_uint16_be()

void write_uint16_be ( unsigned char ** p,
uint16_t val )
static

Write a 2-byte big-endian unsigned integer and advance the pointer.

Parameters
[in,out]pPointer to the write position (advanced by 2).
[in]valValue to write.

Variable Documentation

◆ session_B

gcry_mpi_t session_B
static

◆ session_b

gcry_mpi_t session_b
static

◆ session_B_buf

unsigned char session_B_buf[SRP_NBYTES]
static

◆ session_g

gcry_mpi_t session_g
static

◆ session_N

gcry_mpi_t session_N
static

◆ session_salt

unsigned char session_salt[SRP_SALT_LEN]
static

◆ session_username

char session_username[UAM_USERNAMELEN+1]
static

◆ session_v

gcry_mpi_t session_v
static

◆ srp_g_byte

const unsigned char srp_g_byte = 0x02
static

◆ srp_N_bytes

const unsigned char srp_N_bytes[SRP_NBYTES]
static
Initial value:
= {
0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A,
0xB1, 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB,
0xDB, 0xA5, 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80,
0xBE, 0xEE, 0xA9, 0x61, 0x4B, 0x19, 0xCC, 0x4D,
0x5F, 0x4F, 0x5F, 0x55, 0x6E, 0x27, 0xCB, 0xDE,
0x51, 0xC6, 0xA9, 0x4B, 0xE4, 0x60, 0x7A, 0x29,
0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0, 0xF8, 0x43,
0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8, 0xDC,
0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14,
0x9B, 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D,
0x47, 0x54, 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC,
0x76, 0x4E, 0x3F, 0x4B, 0x53, 0xDD, 0x9D, 0xA1,
0x15, 0x8B, 0xFD, 0x3E, 0x2B, 0x9C, 0x8C, 0xF5,
0x6E, 0xDF, 0x01, 0x95, 0x39, 0x34, 0x96, 0x27,
0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7, 0xC4, 0x86,
0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F, 0x8C,
0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8,
0x7F, 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E,
0x5A, 0x02, 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E,
0x8C, 0xE7, 0xA2, 0x8C, 0x24, 0x42, 0xC6, 0xF3,
0x15, 0x18, 0x0F, 0x93, 0x49, 0x9A, 0x23, 0x4D,
0xCF, 0x76, 0xE3, 0xFE, 0xD1, 0x35, 0xF9, 0xBB,
}

RFC 5054 group #2: 1536-bit MODP group. N is the safe prime, g = 2.

◆ srppwd

struct passwd* srppwd
static

◆ uams_srp

UAM_MODULE_EXPORT struct uam_export uams_srp
Initial value:
= {
}
#define UAM_MODULE_VERSION
Definition uam.h:21
#define UAM_MODULE_SERVER
Definition uam.h:17
static int uam_setup(void *obj, const char *path)
Definition uams_dhx2_pam.c:1018
static void uam_cleanup(void)
Definition uams_dhx2_pam.c:1040